我试图使用python日志记录模块创建一个自定义日志文件,记录其他信息,如主机名,并将其添加到我的数据库.下面是我为此创建的类,Handler部分工作得很好,但是现在我添加了一个自定义LogRecord类,它会抛出这个错误:
/src/lib/__init__.py", line 31, in __init__
logging.LogRecord.__init__(self, *args, **kwargs)
exceptions.TypeError: __init__() takes at most 9 arguments (10 given)
Run Code Online (Sandbox Code Playgroud)
以下是我执行它的方式
logging.setLoggerClass(MyLogger)
log = logging.getLogger('testing')
log.addHandler(MyLogHandler())
d = {'host': '192.168.0.1'}
log.warn('Hi', d)
Run Code Online (Sandbox Code Playgroud)
以下是课程.它显然与*args,**kwargs有关,但是当我看它时,*args是空的,而**kwargs只包含d上面指定的变量.我不明白这个问题.
class MyLogRecord(logging.LogRecord):
def __init__(self, *args, **kwargs):
logging.LogRecord.__init__(self, *args, **kwargs) //THIS IS THE LINE IT DIES ON
self.host = 'localhost'
class MyLogFormatter(logging.Formatter):
def __init__(self, fmt, datefmt=None, host=None):
logging.Formatter.__init__(self, fmt, datefmt)
self.host = host
def format(self, record):
return logging.Formatter.format(record)
class MyLogger(logging.getLoggerClass()):
def makeRecord(self, *args, **kwargs):
return MyLogRecord(*args, **kwargs)
class MyLogHandler(logging.Handler): # Inherit from logging.Handler
def __init__(self):
# run the regular Handler __init__
logging.Handler.__init__(self)
# Our custom argument
self.mongo = MongoLogger()
def setupCustomLogger(self, name, this_host):
formatter = MyLogFormatter(fmt='%(asctime)s - %(levelname)s - %(module)s - %(message)s - %(host)s')
handler = logging.StreamHandler()
handler.setFormatter(formatter)
logger = logging.getLogger(name)
logger.setLevel(logging.DEBUG)
logger.addHandler(handler)
return logger
def emit(self, record):
# record.message is the log message
self.mongo.log(record)
class MongoLogger(object):
'''Logs messages to a MongoDB fh_admin log collection.'''
def log(self, message):
#@todo write log to DB
print message
Run Code Online (Sandbox Code Playgroud)
Ada*_*ner 10
错误告诉你到底出了什么问题; 你用太多的参数调用构造函数.要了解我的意思,请查看在默认实现中通常如何构建日志记录makeRecord:
def makeRecord(self, name, level, fn, lno, msg, args, exc_info, func=None, extra=None):
"""
A factory method which can be overridden in subclasses to create
specialized LogRecords.
"""
rv = LogRecord(name, level, fn, lno, msg, args, exc_info, func)
if extra is not None:
for key in extra:
if (key in ["message", "asctime"]) or (key in rv.__dict__):
raise KeyError("Attempt to overwrite %r in LogRecord" % key)
rv.__dict__[key] = extra[key]
return rv
Run Code Online (Sandbox Code Playgroud)
请注意makeRecord如何获取一个extra不直接传递给它的参数LogRecord?另一方面,你将它直接传递给了LogRecord.__init__,这导致了错误.
从这里,你有两个选择; 你可以提供更完整的实现makeRecord,或者你可以尝试使用这个LoggerAdapter类,它可以帮助你用更少的代码实现相同的目标.
这是一个例子:
# Common log info to be added to all logs reported with `log_adapter`
context = {'host': 'localhost'}
log = logging.getLogger('testing')
log.addHandler(logging.StreamHandler())
d = {'host': '192.168.0.1'}
log_adapter = logging.LoggerAdapter(log, context)
log_adapter.warning('Hi', d)
Run Code Online (Sandbox Code Playgroud)
如果您需要在每次记录某些内容时计算"host"的值(例如),您可以创建context一个类似于字典的类的实例.像这样:
class LogContext(object):
def __getitem__(self, key):
if key == 'host':
return 'localhost'
raise KeyError(key)
def __iter__(self):
return iter(['host'])
log_adapter = logging.LoggerAdapter(log, LogContext())
log_adapter.warning('Hi', d)
Run Code Online (Sandbox Code Playgroud)
有一点需要注意LoggingAdapter,它显然没有将所有便捷的快捷方式功能定义为普通的Logger类.这就是我调用warning方法的原因,而不是warn你上面所说的.
有关LoggingAdapter日志的更多信息和添加上下文可以在python文档中找到.
注意 - 我没有包括MyLogHandler,MyLogFormatter或MongoLogger在我的示例中,因为它们与问题/错误无关.
| 归档时间: |
|
| 查看次数: |
6902 次 |
| 最近记录: |