flask系统日志写到文件

前言

在用flask开发一个系统的时候, 由于要做日志分析, 所以想把flask日志写到本地文件中, 然后ELK自动收集本地日志, 开发中遇到系统的日志写不到本地文件, 只有我自己的日志能写进去

原始的方案

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
#!/usr/bin/env python
#-*- coding: UTF-8 -*-
# author:yao.yinfeng
# message: 日志记录模块
# 主要特性:1、单例模式,线程安全
# 2、按照日期备份文件

'''
使用示例:
from ...common import jfmlogging
logger = jfmlogging.JFMlogging().getloger()
logger.error("this is error msg")
logger.info("this is info msg")
logger.debug("this is debug msg")
'''
import os
import os.path
import socket
import logging
import logging.handlers
logging.basicConfig()

def singleton(cls, *args, **kw):
instances = {}
def _singleton():
if cls not in instances:
instances[cls] = cls(*args, **kw)
return instances[cls]
return _singleton

@singleton
class JFMlogging(object):
log = None
def __init__(self):
HOST_NAME = socket.gethostname()
IP = socket.gethostbyname(HOST_NAME)
LOGGING_MSG_FORMAT = '[%(asctime)s] [' + HOST_NAME + '] [' + IP + '] [%(levelname)s] [%(module)s.py] [line:%(lineno)d] %(message)s'
LOGGING_DATE_FORMAT = '%Y-%m-%d %H:%M:%S'
LOG_PATH = 'logs' # 日志存放目录
print2console = True # 是否输出到屏幕,默认(True)输出
logging.basicConfig(level=logging.DEBUG,format=LOGGING_MSG_FORMAT,datefmt=LOGGING_DATE_FORMAT)
self.log = logging.getLogger('JFM')
if not os.path.exists(LOG_PATH):
os.mkdir(LOG_PATH)
log_file = os.path.join(LOG_PATH,'jfm.log')
logger = logging.handlers.TimedRotatingFileHandler(log_file,'midnight',1)
logger.setFormatter(logging.Formatter(LOGGING_MSG_FORMAT))
self.log.addHandler(logger)

if print2console:
console = logging.StreamHandler()
console.setLevel(logging.INFO)
console.setFormatter(logging.Formatter(LOGGING_MSG_FORMAT))
self.log.addHandler(console)

def getloger(self):
return self.log

这样写之后, 日志输出都是正常的, 但是系统的日志, 比如请求http链接都没有打到文件中

修改后

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
HOST_NAME = socket.gethostname()
IP = socket.gethostbyname(HOST_NAME)
LOGGING_MSG_FORMAT = '[%(asctime)s] [' + HOST_NAME + '] [' + IP + '] [%(levelname)s] [%(module)s.py] [line:%(lineno)d] %(message)s'
LOGGING_DATE_FORMAT = '%Y-%m-%d %H:%M:%S'
LOG_PATH = 'logs' # 日志存放目录
logging.basicConfig(level=logging.DEBUG, format=LOGGING_MSG_FORMAT, datefmt=LOGGING_DATE_FORMAT)
logger = logging.getLogger()
logger.setLevel(logging.DEBUG)

if not os.path.exists(LOG_PATH):
os.mkdir(LOG_PATH)
log_file = os.path.join(LOG_PATH, 'jfm.log')

fileHandler = logging.handlers.TimedRotatingFileHandler(log_file, 'midnight', 1)
fileHandler.setFormatter(logging.Formatter(LOGGING_MSG_FORMAT))
logger.addHandler(fileHandler)

对比

其实两个代码除了一行没有其他的区别(后面的代码我是放到另外一个位置而已)
那就是logger = logging.getLogger('JFM')logger = logging.getLogger()

分析

flask 默认使用的是root loggger, 也就是第二种不带参数的logger, 当我们使用了带参数的logger, 系统的日志就不会打到文件中