import logging import os class Log(object):
def __init__(self, name, ):
self.name = name
self.path = os.getcwd() + "/logs/"
self.formatter = logging.Formatter("%(asctime)s - %(filename)s -[line:%(lineno)d] - %(levelname)s: %(message)s",
"%Y-%m-%d %H:%M:%S")
def getLogger(self):
logger = logging.getLogger(self.name)
logger.setLevel(logging.DEBUG)
logger.addHandler(self.get_console_handler())
return logger
def get_console_handler(self):
console_handler = logging.StreamHandler()
console_handler.setLevel(logging.DEBUG)
console_handler.setFormatter(self.formatter)
return console_handler
flask_logger = Log(name="flask").getLogger()
上面是代码。 遇到的情况是在 a.py 和 b.py 文件分别引入了 flask_logger,接口 A 和接口 B 分别是 logger.info(“A start")...logger.info(“A end")和 logger.info(“B start")...logger.info(“B end"),在接口被频繁调用的时候,就会出现 A start B start B end A end 这种混在一起打印的情况。想知道有没有什么办法解决
1
valkyrja 2019-11-19 15:04:48 +08:00 2
用 nginx 的话,可以使用 nginx 的 request id,应用通过 request id 串联请求内的日志: https://www.nginx.com/blog/application-tracing-nginx-plus/
不用 nginx 就自己生成 request id 放到 flask 上下文: https://flask.palletsprojects.com/en/1.0.x/appcontext/ |
2
conn4575 2019-11-19 15:08:53 +08:00 via Android
楼上+1,两个请求本来就是并发的,给每个请求分配一个唯一 ID
|
3
panyanyany 2019-11-19 15:10:10 +08:00
logger 最好是一个模块用一个 logger = logging.getLogger(__name__),不要一个 logger 在不同的模块引用来引用去的
|
4
locoz 2019-11-19 15:11:56 +08:00
我的接口服务在打日志的时候是用的 JSONLogger,然后每个日志里面都带上了一个请求初始化时生成的 request_id,在 Kibana 里查的时候直接搜 request_id 就能看到某一次请求的所有日志了。
|
5
itskingname 2019-11-19 15:26:45 +08:00
使用第三方库 loguru,不要用自带的 logging 模块,就能解决你这个问题。
|
6
forrestchang 2019-11-19 15:28:16 +08:00
日志统一放到一个消息队列里,然后开一个 job 来处理这些日志。
|
7
Roney 2019-11-19 16:21:25 +08:00
@forrestchang 正解
|
8
TypeErrorNone 2019-11-19 16:30:29 +08:00
在中间件里给每个请求加上 request_id,打日志的时候记录 request_id
|
9
flyingghost 2019-11-19 16:39:46 +08:00 1
日志汇总吧,并发请求就会交错起来,不方便跟踪一个请求(一个业务)的日志。
按请求分开吧,日志之间的时序关系就会丢失,不方便观察服务器状态,尤其是一些请求无关的全局的状态和资源。 各有利弊。 我的做法是: 1,默认日志按时序,需要的时候用 requestID 来过滤就可以方便的按照请求来查看日志序列。全局时序也方便日志切割、轮转、储存、查找等大部分场景。 2,关键业务日志独立,按业务来冗余记录。比如一个用户 /一个订单的所有日志。 3,以上两点结合也比较方便。输入还是正常输入,输出独立多个 Adapter,按不同规则去路由到不同文件即可。 |
10
robinlovemaggie 2019-11-19 17:27:43 +08:00
|
11
Varobjs 2019-11-19 17:39:44 +08:00
1. 并发写日志肯定会窜行
2. 可以先把日志写到内存,生命周期结束统一刷到磁盘,减少窜行可能性 3. 最后就是,每个生命周期,完全可以加个 reqId 的静态变量,每行日志加上[reqId] 前缀 |
12
Varobjs 2019-11-19 17:41:45 +08:00
类似这种
``` [2019-11-19 16:45:05 472][DEBUG][7e42d668] logger ``` |
13
tiedan 2019-11-19 17:41:47 +08:00
加 trace_id 想找哪个请求,用 trace_id 过滤即可
|
14
kaid97 2019-11-19 17:42:45 +08:00
并行肯定会的阿。。你要不封装一层加个队列,不然无解
|
15
sunhk25 2019-11-19 17:52:07 +08:00 via Android
学习,顺便问一下这种日志放到文件里好还是放到 db 中好呢
|
16
1462326016 2019-11-19 18:42:00 +08:00
要么单例要么队列
|
17
NeverBelieveMe OP @valkyrja request id 在 logging.Formatter 里面能定义这个字段么?还是自己在打印的时候加上去?
|
18
NeverBelieveMe OP @flyingghost 关键业务日志独立是怎么做到的?
|
19
mxy940127 2019-11-20 10:03:02 +08:00
flask 不是有个 before_request 和 after_request 的钩子么,为什么不在那个钩子里写日志呢. trace_id 或者 request_id 自己建一个 uuid,写入日志就行
|