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 ![]() 用 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,默认日志按时序,需要的时候用 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,写入日志就行 |