繁体   English   中英

无法创建每个对象的记录器

[英]Unable to create per-object logger

我在每个模块的Python程序中都有日志记录设置。 但是,我也想在子模块中添加按对象记录,这样自定义类的每个实例都有自己的记录器,该记录器记录到文件中。

我已经这样设置了我的应用程序:

app.py

#!/usr/bin/env python
# -*- coding: utf-8 -*-
'''
Demo logging app
'''
import os
import log # the app's logging submodule
# 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
    # set a timestamped log file for debug log
    scriptname = os.path.basename(__file__)
    script_timestamp = log.timestamp()
    log_file = os.path.join(scriptdir, 'logs', '{0}.{1}.log'.format(scriptname, script_timestamp))
    return(log.logpath(logfile = log_file))

config_yaml = os.path.join(scriptdir, 'logging.yml')
logger = log.log_setup(config_yaml = config_yaml, logger_name = "app")

logger.debug("The app is starting...")
logger.debug("Path to the app's log file: {0}".format(log.logger_filepath(logger = logger, handler_name = "main")))

import submodule

log.py

#!/usr/bin/env python
# -*- coding: utf-8 -*-
'''
Functions to set up the program logger
'''

import yaml
import logging
import logging.config
import os

def timestamp():
    '''
    Return a timestamp string
    '''
    import datetime
    return('{:%Y-%m-%d-%H-%M-%S}'.format(datetime.datetime.now()))

def logpath(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
    '''
    return(logging.FileHandler(logfile))

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))

def logger_filepath(logger, handler_name):
    '''
    Get the path to the filehander log file
    '''
    log_file = None
    for h in logger.__dict__['handlers']:
        if h.__class__.__name__ == 'FileHandler':
            logname = h.get_name()
            if handler_name == logname:
                log_file = h.baseFilename
    return(log_file)

submodule.py

#!/usr/bin/env python
# -*- coding: utf-8 -*-
'''
Demo logging app submodule
'''
import log
import logging
logger = logging.getLogger("submodule")

logger.debug("loading submodule..")
logger.debug("Path to the submodule's log file: {0}".format(log.logger_filepath(logger = logger, handler_name = "main")))


class MyClass(object):
    '''
    Basic demo class
    '''
    def __init__(self, id):
        self.id = str(id)
        # using the global logger
        logger.debug("Creating MyClass object with id {0}".format(self.id))
        # creating an object specific logger
        self.logger = logging.getLogger(self.id).setLevel(logging.DEBUG)
        self.logger.debug("Started logging for {0}".format(self.id))

x = MyClass(id = "foo")

logging.yml

version: 1
formatters:
  default:
    format: '%(asctime)s:%(name)s:%(module)s:%(funcName)s:%(lineno)d:%(levelname)s:%(message)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
    level: DEBUG
    formatter: default

loggers:
  app:
    level: DEBUG
    handlers: [console, main]
    propagate: true
  submodule:
    level: DEBUG
    handlers: [console, main]
    propagate: true

当我尝试运行该应用程序时,一切正常,直到尝试在submodule自定义MyClass对象内创建一个logger对象:

$ ./app.py
[2017-08-04 15:41:16] (app:<module>:26:DEBUG) The app is starting...
[2017-08-04 15:41:16] (app:<module>:27:DEBUG) Path to the app's log file: /Users/steve/projects/logging-demo/logs/app.py.2017-08-04-15-41-16.log
[2017-08-04 15:41:16] (submodule:<module>:10:DEBUG) loading submodule..
[2017-08-04 15:41:16] (submodule:<module>:11:DEBUG) Path to the submodule's log file: /Users/steve/projects/logging-demo/logs/app.py.2017-08-04-15-41-16.log
[2017-08-04 15:41:16] (submodule:__init__:21:DEBUG) Creating MyClass object with id foo
Traceback (most recent call last):
  File "./app.py", line 29, in <module>
    import submodule
  File "/Users/steve/projects/logging-demo/submodule.py", line 26, in <module>
    x = MyClass(id = "foo")
  File "/Users/steve/projects/logging-demo/submodule.py", line 24, in __init__
    self.logger.debug("Started logging for {0}".format(self.id))
AttributeError: 'NoneType' object has no attribute 'debug'

关于如何使它起作用的任何想法? 在同一直线上,似乎用这种方法,并尝试使用以下命令创建的任何记录器logger = logging.getLogger(name)其中, name未在预先定义logging.yml YAML文件也有类似的问题。

到目前为止,已在Python 2.7上进行了测试

它在您的代码中:

logging.getLogger(self.id).setLevel(logging.DEBUG)

setLevel方法不返回任何内容,因此您的分配失败,返回“ None”。

此代码应该更好地工作:

self.logger = logging.getLogger(self.id)
self.logger.setLevel(logging.DEBUG)
self.logger.debug("Started logging for {0}".format(self.id))

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM