【问题标题】:Logging for a flask app记录烧瓶应用程序
【发布时间】:2018-08-02 18:56:25
【问题描述】:

我正在开发一个带有flask 的webapp,它充当python 库的接口,进行计算(通常很耗时)。

对服务器的每次调用都用一个标识符标识,我想将调用库的日志写入一个依赖于给定标识符的文件。

一个最小的工作示例如下。

计算.py

​​>
import time
import logging

logger = logging.getLogger(__name__)

def long_computation(identifier):
    logger.info('called computation with identifier %s', identifier)
    for i in range(100):
        logger.info('in step %d of identifier %s', i, identifier)
        time.sleep(1)
    logger.info('finished computation with identifier %s')

server.py

​​>
from flask import Flask, request
import logging
import threading
import computations

app = Flask(__name__)

def call_computation(identifier):
    fh = logging.FileHandler("computations-%s.log" % identifier)
    formatter = logging.Formatter('%(asctime)s %(levelname)-8s %(name)s : %(message)s')
    fh.setFormatter(formatter)
    fh.setLevel(logging.INFO)

    computations.logger.setLevel(logging.INFO)
    computations.logger.addHandler(fh)
    computations.long_computation(identifier)
    computations.logger.removeHandler(fh)

@app.route('/node/<identifier>', methods=['GET','POST'])
def serve_node(identifier):
    thread = threading.Thread(target=call_computation, args=(identifier,))
    thread.start()
    return "I will compute it!"

当我调用服务器时,比如http://127.0.0.1:5000/node/A,它会创建日志文件computations-A.log 并正确记录到该文件。但是,如果我在第一次计算结束之前再次调用服务器,比如http://127.0.0.1:5000/node/B,那么它会创建日志文件computations-B.log,但是两个计算的日志,对应于对call_computation 的不同调用去这两个文件.也就是说,computations-A.logcomputations-B.log 两个文件都具有例如以下行:

2018-08-02 20:31:57,524 INFO     computations : in step 56 of identifier B
2018-08-02 20:31:57,799 INFO     computations : in step 97 of identifier A

任何人都可以帮助我以便调用库以转到适当的日志文件吗?请注意,原则上我无法修改进行计算的包,因此我无法在该包中创建更多记录器。

提前致谢!

【问题讨论】:

    标签: python multithreading logging flask


    【解决方案1】:

    解决方法是过滤日志记录。在server.py 文件中创建logging.Filter 的子类:

    class MyFilter(logging.Filter):
        def __init__(self, thread_id):
            super(MyFilter, self).__init__()
            self.thread_id = thread_id
    
        def filter(self, record):
            return record.thread == self.thread_id
    

    并在设置处理程序时,添加此类的实例:

    myfilter = MyFilter(threading.current_thread().ident)
    fh.addFilter(myfilter)
    

    这样,当一条日志记录到达过滤器时,如果创建该日志的线程与创建该过滤器的线程相同,则将其传递到下一级;否则会被过滤掉。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-07-12
      • 2021-12-25
      • 2014-08-10
      • 2012-08-09
      • 1970-01-01
      • 2015-09-07
      • 2013-08-02
      • 2017-06-27
      相关资源
      最近更新 更多