为了账号安全,请及时绑定邮箱和手机立即绑定

werkzeug:登录到文件时禁用 bash 颜色

werkzeug:登录到文件时禁用 bash 颜色

慕斯王 2023-10-11 22:51:46
在 Flask 应用程序中,我使用 aRotatingFileLogger将 werkzeug 访问日志记录到文件中,如本问题所示:file_handler_access_log = RotatingFileHandler("access.log",                                              backupCount=5,                                              encoding='utf-8')formatter = logging.Formatter('%(asctime)s %(module)s %(levelname)s: %(message)s', datefmt='%Y-%m-%d %H:%M:%S')file_handler_access_log.setFormatter(formatter)werkzeug_logger.addHandler(file_handler_access_log)werkzeug_logger.setLevel(logging.DEBUG)在该access.log文件中,请求如下所示:2020-10-07 09:43:51 _internal INFO: 127.0.0.1 - - [07/Oct/2020 09:43:51] "[37mGET /api/foo HTTP/1.1[0m" 200 -我想摆脱[37m日志文件中的颜色代码。该工具文档指出:开发服务器可以根据状态代码选择以不同颜色突出显示请求日志。安装 单击以启用此功能。Click 是 Flask 依赖项,所以我无法卸载它。如何禁用彩色日志记录?
查看完整描述

4 回答

?
白板的微信

TA贡献1883条经验 获得超3个赞

好的,所以你要打的是


if click:

    color = click.style


    if code[0] == "1":  # 1xx - Informational

        msg = color(msg, bold=True)

    ...

self.log("info", '"%s" %s %s', msg, code, size)


阻止这种行为并不容易。第二个选项是从消息中删除颜色代码。我会尝试使用日志过滤器来更新消息,例如


import logging


import click

    


class RemoveColorFilter(logging.Filter):

    def filter(self, record):

        if record and record.msg and isinstance(record.msg, str):

            record.msg = click.unstyle(record.msg) 

        return True


remove_color_filter = RemoveColorFilter()

file_handler_access_log.addFilter(remove_color_filter)

查看完整回答
反对 回复 2023-10-11
?
长风秋雁

TA贡献1757条经验 获得超7个赞

更简单 - 它只是完全删除所有“click”模块的样式。


import click

click.style = lambda text, *args, **kwargs: text

编辑:最后,我最终使用过滤器从发送到文件处理程序的日志消息中删除转义序列。由于 werkzeug 将转义序列放入日志消息的 args 列表中,因此这些转义序列也需要被删除。这是基本轮廓:


class NoEscape(logging.Filter):

    def __init__(self):

        self.regex = re.compile(r'(\x9B|\x1B\[)[0-?]*[ -\/]*[@-~]')

    def strip_esc(self, s):

        try: # string-like 

            return self.regex.sub('',s)

        except: # non-string-like

            return s

    def filter(self, record: logging.LogRecord) -> int:

        record.msg = self.strip_esc(record.msg)

        if type(record.args) is tuple:

            record.args = tuple(map(self.strip_esc, record.args))

        return 1

希望这可以帮助!


查看完整回答
反对 回复 2023-10-11
?
吃鸡游戏

TA贡献1829条经验 获得超7个赞

我采用了我认为更简单的解决方案,即简单地丢弃所有样式参数 - 在应用程序启动中类似这样



    old_color = click.style


    def new_color(text, fg=None, bg=None, bold=None, dim=None, underline=None, blink=None, reverse=None, reset=True):

        return old_color(text)


    # replace flask styling with non-colorized styling

    click.style = new_color


查看完整回答
反对 回复 2023-10-11
?
12345678_0001

TA贡献1802条经验 获得超5个赞

我自己遇到了这个问题,但是其他答案中提出的过滤器解决方案修改了发出的所有情况的记录,而我只想删除文件处理程序的样式并将其留给控制台处理程序。


我最终进行了子类化Formatter而不是Filter:


import logging

import click


class AntiColorFormatter(logging.Formatter):

    def format(self, record: logging.LogRecord) -> str:

        return click.unstyle(super().format(record))

然后它适合类似的东西:


logger = logging.getLogger()

FMT = '{asctime} {levelname} {message}'


handler = logging.StreamHandler()

# regular console output gets normal styling

handler.setFormatter(logging.Formatter(FMT, style='{'))

logger.addHandler(handler)


handler = logging.FileHandler('log.log', encoding='utf8')

# file handler gets styling stripped

handler.setFormatter(AntiColorFormatter(FMT, style='{'))

logger.addHandler(handler)


查看完整回答
反对 回复 2023-10-11
  • 4 回答
  • 0 关注
  • 94 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信