Flask日志记录 - 无法将其写入文件

fle*_*lem 46 python logging flask python-2.7

好的,这是我设置所有内容的代码:

if __name__ == '__main__':
    app.debug = False

    applogger = app.logger

    file_handler = FileHandler("error.log")
    file_handler.setLevel(logging.DEBUG)

    applogger.setLevel(logging.DEBUG)
    applogger.addHandler(file_handler)

    app.run(host='0.0.0.0')
Run Code Online (Sandbox Code Playgroud)

会发生什么

  1. error.log被创建
  2. 什么都没有写到它
  3. 尽管没有添加StreamHandler并将debug设置为false,我仍然可以获得所有STDOUT(这可能是正确的,但仍然看起来很奇怪)

我完全离开这里或者发生了什么事吗?

Hol*_*rig 82

为什么不这样做:

if __name__ == '__main__':
    init_db()  # or whatever you need to do

    import logging
    logging.basicConfig(filename='error.log',level=logging.DEBUG)

    app.run(host="0.0.0.0")
Run Code Online (Sandbox Code Playgroud)

如果您现在启动应用程序,您将看到error.log包含:

INFO:werkzeug: * Running on http://0.0.0.0:5000/
Run Code Online (Sandbox Code Playgroud)

有关详细信息,请访问http://docs.python.org/2/howto/logging.html

好的,因为你坚持认为你不能使用我向你展示的方法使用两个处理程序,我将添加一个使这一点非常清楚的例子.首先,将此日志记录代码添加到您的main:

import logging, logging.config, yaml
logging.config.dictConfig(yaml.load(open('logging.conf')))
Run Code Online (Sandbox Code Playgroud)

现在还添加一些调试代码,以便我们看到我们的设置工作:

logfile    = logging.getLogger('file')
logconsole = logging.getLogger('console')
logfile.debug("Debug FILE")
logconsole.debug("Debug CONSOLE")
Run Code Online (Sandbox Code Playgroud)

剩下的就是"logging.conf"程序.让我们用它:

version: 1
formatters:
  hiformat:
    format: 'HI %(asctime)s - %(name)s - %(levelname)s - %(message)s'
  simple:
    format: '%(asctime)s - %(name)s - %(levelname)s - %(message)s'
handlers:
  console:
    class: logging.StreamHandler
    level: DEBUG
    formatter: hiformat
    stream: ext://sys.stdout
  file:
    class: logging.FileHandler
    level: DEBUG
    formatter: simple
    filename: errors.log
loggers:
  console:
    level: DEBUG
    handlers: [console]
    propagate: no
  file:
    level: DEBUG
    handlers: [file]
    propagate: no
root:
  level: DEBUG
  handlers: [console,file]
Run Code Online (Sandbox Code Playgroud)

此配置比需要的更复杂,但它还显示了日志记录模块的一些功能.

现在,当我们运行我们的应用程序时,我们会看到此输出(werkzeug-和console-logger):

HI 2013-07-22 16:36:13,475 - console - DEBUG - Debug CONSOLE
HI 2013-07-22 16:36:13,477 - werkzeug - INFO -  * Running on http://0.0.0.0:5000/
Run Code Online (Sandbox Code Playgroud)

另请注意,使用了带有"HI"的自定义格式化程序.

现在看一下"errors.log"文件.它包含:

2013-07-22 16:36:13,475 - file - DEBUG - Debug FILE
2013-07-22 16:36:13,477 - werkzeug - INFO -  * Running on http://0.0.0.0:5000/
Run Code Online (Sandbox Code Playgroud)

  • 这并没有真正使用烧瓶提供的app.logger. (11认同)
  • 因为我实际上的目标是实现几个在不同级别登录的处理程序,而这种方法不会让我走得更远 (2认同)
  • `app.logger` 的问题在于它是完全硬编码的。至少从`Flask 0.12.2` 开始,Flask 的记录器设置(日志级别、日志格式和日志输出流)被硬编码在flask/logging.py 中,并且在不覆盖`app.logger` 属性和编写自定义实现的情况下无法更改. (2认同)

fle*_*lem 13

好吧,我的失败源于两个错误观念:

1)Flask显然会忽略所有自定义日志记录,除非它在生产模式下运行

2)debug = False不足以让它在生产模式下运行.您必须将应用程序包装在任何类型的WSGI服务器中才能执行此操作

我从gevent的WSGI服务器启动应用程序(并将日志记录初始化移动到更合适的位置)一切似乎都工作正常

  • 你的结论是错误的.我向你建议的代码运行a)内置服务器,b)使用测试和/或调试模式,c)使用多个处理程序.此外,您的问题最初是"无法将其写入文件",这个问题已由我解决.不幸的是,你在中途扩大了你的问题,想要一些不同的东西......下次,我建议你更准确地描述你的问题. (4认同)
  • 没有"烧瓶内部记录器".Flask在Python的日志记录模块中使用(并配置)记录器.我实际上发现了关于记录混乱的Flask文档,直到我在flask/logging.py中看到"from logging import getLogger,..."语句.从那时起,它很容易,因为Python的日志记录模块已经很好地记录了下来.所以不,我不会绕过Flask的记录器.如果我愿意,Flask的日志输出怎么可能最终出现在errors.log中? (3认同)
  • 我不完全同意.我问,为什么flask的内部记录器不会写入文件,你提供了绕过该记录器的解决方案.是的它有效,但我不认为这是一个确切的答案.我同意,我说我的问题很糟糕.我将两个都打开,所以任何发现这个的人都可以在这两个中找到任何帮助 (2认同)

Ask*_*way 9

您在应用程序控制台中看到的输出来自底层的Werkzeug记录器,可通过logging.getLogger('werkzeug')访问.

通过向该记录器和Flask添加处理程序,您的日志记录也可以在开发和发布中运行.

更多信息和示例代码:将Flask请求写入访问日志.

  • 花了一段时间才发现这个我自己的,'werkzeug'记录器是所有实际的http layed记录发生的地方.不幸的是,它没有格式化日志,而是将''%s - - [%s]%s \n'%`预格式化到记录器中.因此,如果您想要相同的样式日志,则需要在本地重新创建该格式或调用`werkzeug._internal._log`方法. (2认同)

nic*_*nez 5

这有效:

if __name__ == '__main__':
    import logging
    logFormatStr = '[%(asctime)s] p%(process)s {%(pathname)s:%(lineno)d} %(levelname)s - %(message)s'
    logging.basicConfig(format = logFormatStr, filename = "global.log", level=logging.DEBUG)
    formatter = logging.Formatter(logFormatStr,'%m-%d %H:%M:%S')
    fileHandler = logging.FileHandler("summary.log")
    fileHandler.setLevel(logging.DEBUG)
    fileHandler.setFormatter(formatter)
    streamHandler = logging.StreamHandler()
    streamHandler.setLevel(logging.DEBUG)
    streamHandler.setFormatter(formatter)
    app.logger.addHandler(fileHandler)
    app.logger.addHandler(streamHandler)
    app.logger.info("Logging is set up.")
    app.run(host='0.0.0.0', port=8000, threaded=True)
Run Code Online (Sandbox Code Playgroud)


Dav*_*vid 5

我不喜欢其他答案,所以我坚持下去,似乎我必须在 Flask 完成自己的设置后进行日志配置。

@app.before_first_request
def initialize():

    logger = logging.getLogger("your_package_name")
    logger.setLevel(logging.DEBUG)
    ch = logging.StreamHandler()
    ch.setLevel(logging.DEBUG)
    formatter = logging.Formatter(
    """%(levelname)s in %(module)s [%(pathname)s:%(lineno)d]:\n%(message)s"""
    )
    ch.setFormatter(formatter)
    logger.addHandler(ch)
Run Code Online (Sandbox Code Playgroud)

我的应用程序的结构如下

/package_name
    __main__.py <- where I put my logging configuration
    __init__.py <- conveniance for myself, not necessary
    /tests
    /package_name <- Actual flask app
    __init__.py
    /views
    /static
    /templates
    /lib
Run Code Online (Sandbox Code Playgroud)

按照这些指示http://flask.pocoo.org/docs/0.10/patterns/packages/