簡體   English   中英

Python日志記錄:在模式“ w”下不工作但在模式“ a”下的FileHandler正常工作

[英]Python logging: FileHandler when in mode 'w' not working but in mode 'a' works fine

在Windows下的python 2.7.5 ,當FileHandler處於模式'w' (寫入之前截斷文件)時,處理程序不會僅寫入最后一行。 'a'模式下,一切都很好。

我的logging.conf文件:

[loggers]
keys=root

[handlers]
keys=consoleHandler,fileHandler

[formatters]
keys=simpleFormatter

[logger_root]
level=NOTSET
handlers=fileHandler

[handler_consoleHandler]
class=StreamHandler
level=DEBUG
formatter=simpleFormatter
args=(sys.stdout,)

[handler_fileHandler]
class=FileHandler
level=DEBUG
formatter=simpleFormatter
args=('generator.log', 'a', 'utf8', 0)

[formatter_simpleFormatter]
format=[ %(asctime)s ] [ %(name)s ] [ %(levelname)-5s ] - %(message)s
datefmt=

我的oracle.py文件:

__author__ = 'wbar'
import cx_Oracle
from contextlib import closing
import logging


class Connector(object):
    __connection__ = None
    __user_name__ = None
    __password__ = None
    __tns_name__ = None
    __logger__ = None

    def get_connection(self, auto_connect=True):
        if auto_connect and not self.__connection__:
            self.__logger__.info(u'Connecting into Oracle: %s@%s', self.__user_name__, self.__tns_name__)
            self.__connection__ = cx_Oracle.connect(
                u'%s/%s@%s' % (self.__user_name__, self.__password__, self.__tns_name__))
        return self.__connection__

    def __init__(self, user_name, password, tns_name):
        self.__user_name__ = user_name
        self.__password__ = password
        self.__tns_name__ = tns_name
        self.__logger__ = logging.getLogger('OracleConnector')
        self.__logger__.addHandler(logging.NullHandler())

    def __del__(self):
        self.close_connection()

    def close_connection(self):
        connection = self.get_connection(auto_connect=False)
        if connection:
            self.__logger__.info(u'Closing connection with Oracle: %s@%s', self.__user_name__, self.__tns_name__)
            connection.close()

    def execute(self, sql):
        with closing(self.get_connection().cursor()) as cursor:
            self.__logger__.debug(u'Executing: %s', sql)
            cursor.execute(sql)
            return cursor.fetchall()

最后是我的主文件generator.py

__author__ = 'wbar'
import logging
import logging.config

logging.FileHandler
logging.config.fileConfig('logging.conf')

from oracle import Connector as OracleConnector
DATABASE = OracleConnector(user_name=u'foo', password=u'bar', tns_name=u'db_local')

for line in DATABASE.execute('select * from dual'):
    print(line[0])

logger = logging.getLogger('root')

logger.debug('DEBUG')
logger.info('INFO')
logger.error('ERROR')

'a'模式下,日志文件如下所示:

[ 2013-11-13 17:15:25,608 ] [ OracleConnector ] [ INFO  ] - Connecting into Oracle: pms_test@db_impaq_local
[ 2013-11-13 17:15:25,727 ] [ OracleConnector ] [ DEBUG ] - Executing: select * from dual
[ 2013-11-13 17:15:25,730 ] [ root ] [ DEBUG ] - DEBUG
[ 2013-11-13 17:15:25,730 ] [ root ] [ INFO  ] - INFO
[ 2013-11-13 17:15:25,730 ] [ root ] [ ERROR ] - ERROR
[ 2013-11-13 17:15:25,734 ] [ OracleConnector ] [ INFO  ] - Closing connection with Oracle: pms_test@db_impaq_local

'w'模式下,日志文件如下所示:

[ 2013-11-13 17:06:24,239 ] [ OracleConnector ] [ INFO  ] - Closing connection with Oracle: pms_test@db_impaq_local

logging模塊注冊一個atexit關閉鈎子,以關閉所有處理程序。 Python退出時,這將關閉打開的'w'文件對象。

然而,你的oracle.Connector()類有一個__del__方法,Python的退出時其被稱為。 Python在清除全局變量之前調用atexit ,因此此處的確切操作順序為:

  1. loggingatexit掛鈎被調用,文件被關閉。
  2. oracle.Connector().__del__() ,它調用self.__logger__.info() 這將重新打開關閉的文件處理程序以進行日志記錄,從而截斷文件。

為避免這種情況,請退出Python 之前顯式關閉連接器:

DATABASE.close_connection()

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM