[英]How to save python log in different file by different level in flask
我的日志代碼:
import os
import logging
import logging.handlers
import sys
from logging import raiseExceptions
from logging import Logger
LOG_PATH = '/tmp/'
class AppLogger(Logger):
def __init__(self, name, level=logging.NOTSET):
super(AppLogger, self).__init__(name, level)
def callHandlers(self, record):
"""
Pass a record to all relevant handlers.
Loop through all handlers for this logger and its parents in the
logger hierarchy. If no handler was found, output a one-off error
message to sys.stderr. Stop searching up the hierarchy whenever a
logger with the "propagate" attribute set to zero is found - that
will be the last logger whose handlers are called.
"""
c = self
found = 0
while c:
for hdlr in c.handlers:
found = found + 1
if hdlr.name == 'console':
if record.levelno >= hdlr.level:
hdlr.handle(record)
else:
if record.levelno == hdlr.level:
hdlr.handle(record)
if not c.propagate:
c = None # break out
else:
c = c.parent
if (found == 0) and raiseExceptions and not self.manager.emittedNoHandlerWarning:
sys.stderr.write("No handlers could be found for logger"
" \"%s\"\n" % self.name)
self.manager.emittedNoHandlerWarning = 1
def get_logger(logfile_name=__name__, log_path=LOG_PATH):
'''save log to diffrent file by different log level into the log path
and print all log in console'''
logging.setLoggerClass(AppLogger)
formatter = logging.Formatter(
'%(asctime)s %(name)s %(levelname)s %(message)s',
'%Y-%m-%d %H:%M:%S')
log_files = {
logging.DEBUG: os.path.join(log_path, logfile_name + '-debug.log'),
logging.INFO: os.path.join(log_path, logfile_name + '-info.log'),
logging.WARNING: os.path.join(log_path, logfile_name + '-warning.log'),
logging.ERROR: os.path.join(log_path, logfile_name + '-error.log'),
logging.CRITICAL: os.path.join(log_path, logfile_name + '-critical.log')
}
logger = logging.getLogger()
logger.name = 'app'
logger.setLevel(logging.DEBUG)
for log_level, log_file in log_files.items():
file_handler = logging.handlers.TimedRotatingFileHandler(log_file, 'midnight')
file_handler.setLevel(log_level)
file_handler.setFormatter(formatter)
logger.addHandler(file_handler)
console_handler = logging.StreamHandler()
console_handler.name = "console"
console_handler.setLevel(logging.DEBUG)
console_handler.setFormatter(formatter)
logger.addHandler(console_handler)
return logger
logger = get_logger()
我的燒瓶代碼:
from log import logger
from flask import Flask
app = Flask(__name__)
app.debug = True
@app.route("/")
def hello():
return "Hello World!"
logger.debug('----')
logger.info('----')
logger.error('----')
logger.warning('----')
app.run()
我想將DEBUG級別日志保存在debug.log中,將INFO級別日志保存在info.log中,將WARNING級別日志保存在warning.log中,將ERROR級別日志保存在error.log中,包括flask框架的日志和我的自定義日志,我需要打印所有登錄控制台。
我自定義了AppLogger,但是現在這僅適用於flask框架的日志,我的自定義日志未保存在正確的文件中,info,warning,error全部寫在info.log中,名稱app
是我的自定義日志,它保存了日志一起。
如何使info.log僅保存應用程序的INFO日志?
info.log:
2017-11-08 20:07:31 app INFO ----
2017-11-08 20:07:31 app ERROR ----
2017-11-08 20:07:31 app WARNING ----
2017-11-08 20:07:31 werkzeug INFO * Restarting with stat
2017-11-08 20:07:31 app INFO ----
2017-11-08 20:07:31 app ERROR ----
2017-11-08 20:07:31 app WARNING ----
2017-11-08 20:07:31 werkzeug INFO * Debugger PIN: 971-444-041
2017-11-08 20:07:31 werkzeug INFO * Running on http://127.0.0.1:5000/ (Press CTRL+C to quit)
warning.log
2017-11-08 20:07:31 app ERROR ----
2017-11-08 20:07:31 app WARNING ----
2017-11-08 20:07:31 app ERROR ----
2017-11-08 20:07:31 app WARNING ----
2017-11-08 20:07:31 werkzeug WARNING * Debugger is active!
您只需為每個日志處理程序添加文件名即可 通過從中獲取想法來更改代碼
import logging
class MultiFileHandler(logging.FileHandler):
def __init__(self, filename, mode, encoding=None, delay=0):
logging.FileHandler.__init__(self, filename, mode, encoding, delay)
def emit(self, record):
if self.should_change_file(record):
self.change_file(record.file_id)
logging.FileHandler.emit(self, record)
def should_change_file(self, record):
if not hasattr(record, 'file_id') or record.file_id == self.baseFilename:
return False
return True
def change_file(self, file_id):
self.stream.close()
self.baseFilename = file_id
self.stream = self._open()
if __name__ == '__main__':
logger = logging.getLogger('request_logger')
logger.setLevel(logging.DEBUG)
handler = MultiFileHandler(filename='out.log', mode='a')
handler.setLevel(logging.DEBUG)
logger.addHandler(handler)
# Log some messages to the original file
logger.debug('debug message')
logger.info('info message')
# Log some messages to a different file
logger.debug('debug message', extra={'file_id':'debug.log'})
logger.info('info message', extra={'file_id':'info.log'})
logger.warn('warn message', extra={'file_id':'warn.log'})
logger.error('error message', extra={'file_id':'error.log'})
您可以創建一個過濾器:
import logging
class LevelFilter(object):
def __init__(self, level):
self.level = logging._checkLevel(level)
def filter(self, record):
return record.levelno == self.level
然后將此與每個文件關聯:
(在YAML中):
handlers:
info_handler:
class: logging.handlers.RotatingFileHandler
filename: /tmp/info.log
...
filters: [info_filter]
error_handler:
class: logging.handlers.RotatingFileHandler
filename: /tmp/errors.log
...
filters: [err_filter]
filters:
info_filter:
(): <somelogclassmodule>.LevelFilter
level: INFO
err_filter:
(): <somelogclassmodule>.LevelFilter
level: ERROR
root:
handlers: [info_handler, error_handler]
(在原始python中):
from <somelogclassmodule> import LevelFilter
root = logging.getLogger()
info_handler = logging.handlers.RotatingFileHandler('info.log', ...)
error_handler = logging.handlers.RotatingFileHandler('error.log', ...)
info_filter = LevelFilter('INFO')
err_filter = LevelFilter('ERROR')
info_handler.addFilter(info_filter)
error_handler.addFilter(err_filter)
# set formatters, etc..
...
root.addHandler(info_handler)
root.addHandler(error_handler)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.