简体   繁体   English

Flask - 如何使用 RotatingFileHandler 将 werkzeug 日志写入日志文件?

[英]Flask - how to write werkzeug logs to log file using RotatingFileHandler?

I've found some somewhat similar questions, but nothing that directly addresses this.我发现了一些类似的问题,但没有直接解决这个问题。

I'm trying to output all Werkzeug logging to a log file.我正在尝试将所有 Werkzeug 日志记录输出到日志文件。 I can get part of the logging to output to the file, but I cannot seem to capture any errors or anything beyond the basic route/request lines.我可以将部分日志记录输出到文件,但我似乎无法捕获任何错误或超出基本路由/请求行的任何内容。

Here is what I have.这就是我所拥有的。 How can I include ALL output from Werkzeug?如何包含 Werkzeug 的所有输出?

if __name__ == '__main__':
    configure_app(app)
    handler=RotatingFileHandler('server_werkzeug.log', maxBytes=10000000, backupCount=5)
    log = logging.getLogger('werkzeug')
    log.setLevel(logging.DEBUG)
    log.addHandler(handler)

This code works perfectly for logging. 此代码非常适合记录日志。 As for the problem of not logging errors it seems, that you have to specify other loggers, besides 'werkzeug'. 至于不记录错误的问题,似乎您必须指定“ werkzeug”之外的其他记录器。 For traceback errors in Flask it's app.logger what you're looking for. 对于Flask中的追溯错误,您要找的是app.logger And don't forget to set the level to WARNING. 并且不要忘记将级别设置为“警告”。

import logging
import logging.handlers

app = Flask(__name__)

handler = logging.handlers.RotatingFileHandler(
        'log.txt',
        maxBytes=1024 * 1024)
logging.getLogger('werkzeug').setLevel(logging.DEBUG)
logging.getLogger('werkzeug').addHandler(handler)
app.logger.setLevel(logging.WARNING)
app.logger.addHandler(handler)

You can add other loggers as well, if your app is using some third party tools for like database queries, cron jobs etc. 如果您的应用程序使用某些第三方工具(例如数据库查询,cron作业等),则也可以添加其他记录器。

logging.getLogger('apscheduler.scheduler').setLevel(logging.DEBUG)
logging.getLogger('apscheduler.scheduler').addHandler(handler)

The name of a logger can be found in the terminal window: 记录器的名称可以在终端窗口中找到:

INFO:werkzeug:127.0.0.1 - - [10/Mar/2018 15:41:15] "GET /file.js HTTP/1.1" 200 -
DEBUG:apscheduler.scheduler:Next wakeup is due at 2018-03-10 16:00:00+03:00 (in 1124.668881 seconds)

Use the dictConfig is a more extendable way. 使用dictConfig是更可扩展的方法。

from logging.config import dictConfig

dictConfig({
    'version': 1,
    'handlers': {
        'file.handler': {
            'class': 'logging.handlers.RotatingFileHandler',
            'filename': 'server_werkzeug.log',
            'maxBytes': 10000000,
            'backupCount': 5,
            'level': 'DEBUG',
        },
    },
    'loggers': {
        'werkzeug': {
            'level': 'DEBUG',
            'handlers': ['file.handler'],
        },
    },
})

If you are interested in separating the access log from other werkzeug logging calls, you can implement the following monkey patch.如果您有兴趣将访问日志与其他werkzeug日志记录调用分开,您可以实现以下猴子补丁。

This is handy for doing development work as access logs are very handy for troubleshooting but having werkzeug printing alongside your other logs is not very helpful for readability.这对于进行开发工作很方便,因为访问日志对于故障排除非常方便,但是将werkzeug打印在您的其他日志旁边对可读性没有多大帮助。

__access_log_enabled__ = False # Override to enable logger (eg when running code outside of wsgi server)

def log_request(self:werkzeug.serving.WSGIRequestHandler, 
                code: typing.Union[int, str] = "-", 
                size: typing.Union[int, str] = "-") -> None:
    if not __access_log_enabled__: return
    _server_.log_request(handler=self, code=code, size=size)
    # where _server_ is your own class for managing the server

werkzeug.serving.WSGIRequestHandler.log_request = log_request

Here is a example consuming this:这是一个使用它的示例:

import werkzeug
import typing
import logging
from logging.handlers import RotatingFileHandler
from datetime import datetime

_server_ = None

class MyServer():
    def __init__(self, in_wsgi:bool):
        global _server_
        _server_ = self
        
        # ...
        log_werkzeug = logging.getLogger('werkzeug')
        log_werkzeug.setLevel(logging.ERROR)
        # This will suppress all logs from werkzeug below Error
        #  with the exception of the redirected access logs

        if not in_wsgi:
            self.acc_log = logging.getLogger('qflask_access_log')
            handler = RotatingFileHandler('./log/access_non_wsgi.log', 
                                          maxBytes=100000, 
                                          backupCount=5)
            handler.setFormatter(logging.Formatter("%(message)s"))
            self.acc_log.addHandler(handler)
            self.acc_log.setLevel(logging.INFO)
            global __access_log_enabled__
            __access_log_enabled__ = True

        # ...
            
    # ...
    def log_request(self, 
                    handler:werkzeug.serving.WSGIRequestHandler, 
                    code: typing.Union[int, str] = "-", 
                    size: typing.Union[int, str] = "-") -> None:
        try:
            path = werkzeug.urls.uri_to_iri(handler.path)
            msg = f"{handler.command} {path} {handler.request_version}"
        except AttributeError:
            # path isn't set if the requestline was bad
            msg = handler.requestline
        code = str(code)

        self.acc_log.warning(
            f"[{datetime.now().strftime('%y%m%d-%H%M%S.%f')}] {code} {msg} {size}")

This is probably a good feature to have built into werkezug.这可能是 werkezug 内置的一个很好的功能。 In fact with access_log_enabled = False, it will make any server a tiny bit faster.事实上,使用access_log_enabled = False,它会让任何服务器都快一点。

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

相关问题 使用 TimedRotatingHandler 时如何将 python flask werkzeug 日志重定向到日志文件? - How to redirect python flask werkzeug logs to a log file when using TimedRotatingHandler? python 如何使用 flask 中的 werkzeug 记录器将错误消息写入错误日志和主日志 - python how to write error massages to error log and to main log using werkzeug logger in flask 如何使用logging.conf文件使用RotatingFileHandler将所有内容记录到文件中? - How to log everything into a file using RotatingFileHandler by using logging.conf file? 如何重置flask / werkzeug中的file.stream? - How to reset the file.stream in flask / werkzeug? 从python使用RotatingFileHandler时无法获取备份日志文件 - Unable to get the backup log file when using RotatingFileHandler from python 在Python中使用RotatingFileHandler按日期旋转日志 - Rotating logs using RotatingFileHandler by date in Python 如何使用werkzeug流式传输文件? - How do I stream a file using werkzeug? Flask werkzeug 日志默认输出奇怪的字符 - Flask werkzeug log outputs weird characters by default 使用 RotatingFileHandler 记录多个进程 - Using RotatingFileHandler to log from multiple processes Python RotatingFileHandler 也在记录存档文件 - 如何将多个进程记录到单个文件 - Python RotatingFileHandler is logging also to archived file - how to log multiple processes to single file
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM