【问题标题】:Log only to a file and not to screen for logging.DEBUG只记录到一个文件,而不是记录到屏幕上。DEBUG
【发布时间】:2020-03-25 23:00:24
【问题描述】:

我有以下脚本,我只希望将“DEBUG”日志消息记录到文件中,而不是屏幕上。

from flask import Flask, request, jsonify
from gevent.pywsgi import WSGIServer
import usaddress
app = Flask(__name__)

from logging.handlers import RotatingFileHandler
import logging
#logging.basicConfig(filename='error.log',level=logging.DEBUG)


# create a file to store weblogs
log = open('error.log', 'w'); log.seek(0); log.truncate();
log.write("Web Application Log\n"); log.close();

log_handler = RotatingFileHandler('error.log', maxBytes =1000000, backupCount=1)

formatter = logging.Formatter(
    "[%(asctime)s] {%(pathname)s:%(lineno)d} %(levelname)s - %(message)s"
    )
log_handler.setFormatter(formatter)
app.logger.setLevel(logging.DEBUG)
app.logger.addHandler(log_handler)

@app.route('/')
def hello():
  return "Hello World!"

@app.route("/parseAddress", methods=["POST"])
def parseAddress():
  address = request.form['address']
  return jsonify(usaddress.tag(address)), 200

if __name__ == '__main__':
#  app.run(host='0.0.0.0')
  http_server = WSGIServer(('', 5000), app, log=app.logger)
  http_server.serve_forever()

但现在,甚至“INFO”消息也被记录到文件和屏幕上。我怎样才能只将“DEBUG”消息记录到文件中而没有记录到屏幕上?

【问题讨论】:

  • 您可以为每个处理程序分别设置level。我记得log_handler.setLevel(...)。但可能您必须手动创建控制台处理程序 (StreamHandler) 才能访问此处理程序。
  • Python官方文档:Logging Cookbook

标签: python gevent


【解决方案1】:

我做了一些交互式测试,看起来app.logger 是一个以 python 文件命名的记录器

print(app.logger.name) # filename

它有一个处理程序

print(app.logger.handlers) # [<StreamHandler <stderr> (NOTSET)>]

级别为logging.NOTSET 的处理程序处理所有消息(来自所有日志记录级别)。因此,当您设置 app.logger.setLevel(logging.DEBUG) 时,所有调试日志和更高级别的日志都将传递给处理程序,并且所有这些日志都将出现在 stderr 上。

要在屏幕上完全不记录任何内容,您必须手动删除 StreamHandler:

app.logger.handlers.pop(0)

并将 DEBUG 及更高级别记录到处理程序上的文件集日志记录级别

log_handler.setLevel(logging.DEBUG)

Python 日志记录相当复杂。请参阅此logging flow chart 以更好地了解正在发生的事情:)

编辑:要仅记录一个特定级别,您需要自定义过滤器对象:

class LevelFilter:
    def __init__(self, level):
        self._level = level

    def filter(self, log_record):
        return log_record.levelno == self._level

log_handler.setLevel(logging.DEBUG)
log_handler.addFilter(LevelFilter(logging.DEBUG))

【讨论】:

  • 我不再在屏幕上看到任何内容,但它仍在将 INFO 记录到文件中
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-06-05
  • 1970-01-01
  • 2020-04-11
  • 1970-01-01
  • 2010-11-12
相关资源
最近更新 更多