又一个Python日志设置

时间:2017-07-24 18:27:07

标签: python logging

我一直在阅读python中的日志记录模块和几个关于如何设置它的博客,但是,没有博客为更复杂的设置提供了方案。

我想:

  1. 使用外部配置文件(见下文)。
  2. 让外部模块处理日志设置(创建日志文件w / mylogfile+datetime(见下文)。
  3. 最后,在类中实例化一个记录器,以便从多个方法记录到输出文件。
  4. 现在,不可否认,我有一些混乱的设置,并希望有一些指示来清理这个混乱: - )。

    我相信外部配置文件加载正常,但没有创建日志文件。

    示例主要:

    #!/bin/env python
    
    import os
    import sys
    import logging.config
    from datetime import datetime
    
    datetime.now().strftime('mylogfile_%H%M%d%m%Y.log')
    
    LOG_CONFIG = '../config/logging.conf'
    #logging.config.fileConfig(LOG_CONFIG)
    #logger = logging.getLogger(datetime.now().strftime('mylogfile_%H%M%d%m%Y.log'))
    
       def setup_logger():
           logging.config.fileConfig(LOG_CONFIG)
           datetime.now().strftime('mylogfile_%H%M%d%m%Y.log')
           logger = logging.getLogger(datetime.now().strftime('mylogfile_%H%M%d%m%Y.log'))
    
    class TestLog(object):
    def __init__(self):
        self.logger = logging.getLogger(__name__)
        self.__sub_test = 0
    
    def add_test(self):
        self.logger.debug('addition')
        a = 1 + 1
        self.logger.debug('result {}'.format(a, 1))
    
    def sub_test(self):
        self.logger.debug('subtraction')
        b = 5 -2
        self.logger.debug('result {}'.format(b, 1))
    
    
    def main():
        # 'application' code
       logger.debug('debug message')
       logger.info('info message')
       logger.warn('warn message')
       logger.error('error message')
       logger.critical('critical message')
       #setup_logger()
       test1 = TestLog()
       print test1.add_test()
       print test1.sub_test()
    
    if __name__ == "__main__":
        sys.exit(main())
    

    配置文件:

    [loggers]
    keys=root
    
    [handlers]
    keys=consoleHandler
    
    [formatters]
    keys=simpleFormatter
    
    [logger_root]
    level=DEBUG
    handlers=consoleHandler
    
    [logger_sLogger]
    level=DEBUG
    handlers=consoleHandler
    qualname=sLogger
    propagate=0
    
    [handler_consoleHandler]
    class=StreamHandler
    level=DEBUG
    formatter=simpleFormatter
    args=(sys.stdout,)
    
    [handler_fileHandler]
    class=FileHandler
    level=DEBUG
    formatter=fileFormatter
    args=('%(logfilename)s',)
    
    [formatter_fileFormatter]
    format=%(asctime)s - %(name)s - %(levelname)s - %(message)s
    datefmt=
    
    [formatter_simpleFormatter]
    format=%(asctime)s - %(name)s - %(levelname)s - %(message)s
    datefmt=
    

    基于user5359531回复更新,我已将脚本修改为以下版本,但是文件处理程序存在问题,其中未创建文件且邮件未附加到文件中。

    utilityLogger:

    #!/usr/bin/env python
    # -*- coding: utf-8 -*-
    
    '''
    My app
    '''
    # ~~~~~ LOGGING SETUP ~~~~~ #
    # set up the first logger for the app
    import os
    import testLogging as vlog
    # path to the current script's dir
    scriptdir = os.path.dirname(os.path.realpath(__file__))
    
    LOG_CONFIG = '../config/logging.conf'
    print scriptdir
    
    def logpath():
         '''
        Return the path to the main log file; needed by the logging.yml
        use this for dynamic output log file paths & names
        '''
        global scriptdir
        return (vlog.logpath(scriptdir = scriptdir, logfile = 'log.txt'))
    
    logger = vlog.log_setup(config_file=LOG_CONFIG, logger_name="app")
    logger.debug("App is starting...")
    

    testLogging:

    #!/usr/bin/env python
    # -*- coding: utf-8 -*-
    '''
    Functions to set up the app logger
    '''
    import logging
    import logging.config
    import os
    
    LOG_CONFIG = '../config/logging.conf'
    
    def logpath(scriptdir, logfile):
        '''
        Return the path to the main log file; needed by the logging.yml
        use this for dynamic output log file paths & names
        '''
       log_file = os.path.join(scriptdir, logfile)
       print log_file
       print scriptdir
       print logfile
       return(logging.FileHandler(log_file))
    
    def log_setup(config_file, logger_name):
        '''
        Set up the logger for the script
        config = path to YAML config file
        '''
    # Config file relative to this file
        logging.config.fileConfig(config_file)
        return(logging.getLogger(logger_name))
    

    logging.conf文件:

    [loggers]
    keys=root
    
    [handlers]
    keys=consoleHandler
    
    [formatters]
    keys=simpleFormatter
    
    [logger_root]
    level=DEBUG
    handlers=consoleHandler
    qualname=app
    
    [logger_app]
    level=DEBUG
    handlers=consoleHandler
    qualname=app
    propagate=true
    
    [handler_consoleHandler]
    class=StreamHandler
    level=DEBUG
    formatter=simpleFormatter
    args=(sys.stdout,)
    
    [handler_fileHandler]
    class=FileHandler
    level=DEBUG
    formatter=fileFormatter
    args=('%(logfilename)s',)
    
    [main]
    ()=__main__.logpath
    level=DEBUG
    formatter=simpleFormatter
    
    [formatter_fileFormatter]
    format=%(asctime)s (%(name)s:%(funcName)s:%(lineno)d:%(levelname)s) %
    (message)s # %(module)s:
    datefmt="%Y-%m-%d %H:%M:%S"
    
    [formatter_simpleFormatter]
    format=%(asctime)s (%(name)s:%(funcName)s:%(lineno)d:%(levelname)s) %(message)s # %(module)s:
    datefmt="%Y-%m-%d %H:%M:%S"
    

1 个答案:

答案 0 :(得分:2)

我正在做类似的事情,这是我如何设置

YAML格式的外部配置文件:

logging.yml

version: 1
formatters:
  default: # default debug logger
    format: '[%(asctime)s] (%(name)s:%(funcName)s:%(lineno)d:%(levelname)s) %(message)s' # %(module)s:
    datefmt: "%Y-%m-%d %H:%M:%S"
  info: # basic info logging, for easier reading
    format: '[%(levelname)-8s] %(message)s'
    datefmt: "%Y-%m-%d %H:%M:%S"
  console:
    format: '[%(asctime)s] (%(name)s:%(funcName)s:%(lineno)d:%(levelname)s) %(message)s'
    datefmt: "%Y-%m-%d %H:%M:%S"

handlers:
  console:
    class: logging.StreamHandler
    level: DEBUG
    formatter: console
    stream: ext://sys.stdout
  main:
    () : __main__.logpath # output file path
    level: DEBUG
    formatter: default

loggers:
  app:
    level: DEBUG
    handlers: [console, main]
    propagate: true
  parse:
    level: DEBUG
    handlers: [console, main]
    propagate: true
  tools:
    level: DEBUG
    handlers: [console, main]
    propagate: true
  data:
    level: DEBUG
    handlers: [console, main]
    propagate: true

注意这里的行() : __main__.logpath,它在主脚本中调用一个名为logpath的函数以获取文件处理程序。我这样做是为了条件设置输出文件名。把你需要的任何文件或其他Filehandler逻辑放在那里。在'main'应用程序Python程序中看到这个:

app.py

!/usr/bin/env python
# -*- coding: utf-8 -*-

'''
My app
'''
# ~~~~~ LOGGING SETUP ~~~~~ #
# set up the first logger for the app
import os
import log as vlog
# path to the current script's dir
scriptdir = os.path.dirname(os.path.realpath(__file__))

def logpath():
    '''
    Return the path to the main log file; needed by the logging.yml
    use this for dynamic output log file paths & names
    '''
    global scriptdir
    return(vlog.logpath(scriptdir = scriptdir, logfile = 'log.txt'))

config_yaml = os.path.join(scriptdir,'logging.yml')
logger = vlog.log_setup(config_yaml = config_yaml, logger_name = "app")
logger.debug("App is starting...")

这伴随着log.py(在我的主应用中导入为vlog);

log.py

#!/usr/bin/env python
# -*- coding: utf-8 -*-
'''
Functions to set up the app logger
'''
import yaml
import logging
import logging.config
import os

def logpath(scriptdir, logfile = 'log.txt'):
    '''
    Return the path to the main log file; needed by the logging.yml
    use this for dynamic output log file paths & names
    '''
    log_file = os.path.join(scriptdir, logfile)
    return(logging.FileHandler(log_file))

def log_setup(config_yaml, logger_name):
    '''
    Set up the logger for the script
    config = path to YAML config file
    '''
    # Config file relative to this file
    loggingConf = open(config_yaml, 'r')
    logging.config.dictConfig(yaml.load(loggingConf))
    loggingConf.close()
    return(logging.getLogger(logger_name))

此外,我在app.py中导入的我自己的任何其他模块(之后设置日志记录)包括在模块开头的此日志记录设置:

data.py

#!/usr/bin/env python
# -*- coding: utf-8 -*-
'''
Module to do data stuff for my app
'''
import logging
logger = logging.getLogger("data")

我认为这涵盖了你所谈论的所有要点。我花了一段时间才弄明白这一点。希望能帮助到你。