CherryPy不尊重所需的日志记录格式

时间:2017-01-26 17:34:47

标签: python logging cherrypy

我正在尝试配置CherryPy的日志记录格式。 CherryPy在python中使用了日志记录模块,所以这很容易做到,但是看起来CherryPy仍然将它自己的时间戳插入到日志的实际“消息”中。 如何让CherryPy不将自己的时间戳插入“消息”

以下是代码的一个小型不完整示例,演示了我正在尝试做的事情和不受欢迎的输出。

main.py
...
cherrypy_logger = logging.getlogger('cherrypy.error')
cherrypy_logger.handlers = [] # remove any previous handlers the logger had
new_handler = logging.streamHandler()
new_formatter = logging.formatter('blah blah blah ....: %(message)s')
new_handler.setformatter(new_formatter)
cherrypy_logger.addhandler(new_handler)
....

然后当CherryPy lib /模块记录某些东西时,我得到以下内容:

“等等等等...... [Jan / 17/07 23:59:59] 引擎启动......”

我可能做错了,但似乎就像CheeryPy在它提交给记录器的字符串中插入一个时间戳,而不考虑开发人员如何在日志中显示时间。我怎样才能解决这个问题?

注意:上面的代码来自内存,并且是我的观点(希望如此)。它不会编译/运行。

提前致谢。

3 个答案:

答案 0 :(得分:1)

回答了我自己的问题:

事实证明,CherryPy实际上是在"消息中插入时间戳"

可以在_cplogging.py

中找到以下代码

self.error_log.log(severity, ' '.join((self.time(), context, msg)), exc_info=exc_info)

由于改变日志记录格式的不灵活性,恕我直言,这是一种将时间戳插入日志的糟糕方式。现在,我已经将这一行改为:

self.error_log.log(severity, ' '.join((context, msg)), exc_info=exc_info)

它解决了我的问题,但是其他一些代码需要进行一些调整才能使其成为一个合适的补丁,如果我能做并提交,我会看到。

PS。 CherryPy访问日志遇到了类似的问题。

无论如何,希望这有助于其他人!

答案 1 :(得分:0)

在不更改源代码的情况下对CherryPy Log进行一些小更改的另一种方法是使用方法或属性黑客,例如:

要修改日期时间fomatter,您可以更改time()方法。

cherrypy._cplogging.LogManager.time = lambda self : \
     datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S,%f")[:23]

要修改access_log的字符串格式化程序,您可以使用:

    cherrypy._cplogging.LogManager.access_log_format = (
       '{t} MYLOG {h} "{r}" {s} {b} "{f}" "{a}"'
       if six.PY3 else
       '%(t)s MYLOG %(h)s "%(r)s" %(s)s %(b)s "%(f)s" "%(a)s"'
    )

最后,您可以使用以下命令修改error_log的字符串格式化程序:

    new_formatter = logging.Formatter("%(asctime)s MYLOG %(message)s")

    for h in cherrypy.log.error_log.handlers:
        h.setFormatter(new_formatter)

希望它有所帮助!!!

答案 2 :(得分:0)

我在查找 access_log_format 模板变量的描述时遇到了一些麻烦,因此为了方便起见,我从 18.6.0 的cherrypy 源代码 (site-packages/cherrypy/_cplogging.py) 中检索了它们。

默认格式:

access_log_format = '{h} {l} {u} {t} "{r}" {s} {b} "{f}" "{a}"'

模板变量默认值:

atoms = {'h': remote.name or remote.ip,
         'l': '-',
         'u': getattr(request, 'login', None) or '-',
         't': self.time(),
         'r': request.request_line,
         's': status,
         'b': dict.get(outheaders, 'Content-Length', '') or '-',
         'f': dict.get(inheaders, 'Referer', ''),
         'a': dict.get(inheaders, 'User-Agent', ''),
         'o': dict.get(inheaders, 'Host', '-'),
         'i': request.unique_id,
         'z': LazyRfc3339UtcTime(),
        }

例如,这是我调用的函数,用于为我的项目配置 CherryPy 日志记录。这个函数在cherrypy.engine.start()和cherrypy.engine.block()之前调用

def configure_logger():
   pst = pytz.timezone("US/Pacific")
   cherrypy._cplogging.LogManager.time = lambda self: datetime.now().astimezone(pst).strftime("%Y-%m-%d %H:%M:%S.%f %Z")

   #Default access_log_format '{h} {l} {u} {t} "{r}" {s} {b} "{f}" "{a}"'
   #h - remote.ip, l - "-", u - login (or "-"), t - time, r - request line, s - status, b - content length
   #f - referer, a - User Agent, o - Host or -, i - request.unique_id, z - UtcTime
   cherrypy._cplogging.LogManager.access_log_format = '{t} ACCESS {s} {r} {h} {b} bytes'