我在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
当我尝试运行该应用时,一切正常,直到我尝试在logger
中的自定义MyClass
对象内创建submodule
对象:
$ ./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上测试了这个
答案 0 :(得分:1)
它在你的代码中:
logging.getLogger(self.id).setLevel(logging.DEBUG)
setLevel方法不返回任何内容,因此你的赋值失败并返回“无”。
此代码应该更好用:
self.logger = logging.getLogger(self.id)
self.logger.setLevel(logging.DEBUG)
self.logger.debug("Started logging for {0}".format(self.id))