当应用程序有多个调用时,Logging config无法加载valueformatter()

2024-03-29 14:45:02 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在使用wsgi框架来创建web服务。我在中配置了记录器应用程序类型(如图所示)应用程序类型)它接收应用程序调用并将输入参数传递给后端.py使用方法get\u output()。我用的是后端.py处理申请的请求。在后端文件中,使用自动记录器对于每个处理器实例(如后端.py文件)

应用程序类型

from bottle import Bottle
import logging.handlers
from backend import Processor

logger = logging.getLogger()
logger.setLevel(logging.DEBUG)

# Logging handler for files
file_handler = logging.handlers.TimedRotatingFileHandler("log.log", when="midnight", interval=1,
                                                         backupCount=10000)
file_handler.setLevel(logging.INFO)

# Logging handler for console
console_handler = logging.StreamHandler()
console_handler.setLevel(logging.DEBUG)

# Formatter's for logging
formatter = logging.Formatter('%(asctime)s %(name)s %(levelname)s %(message)s')
file_handler.setFormatter(formatter)
console_handler.setFormatter(formatter)

# Add handlers to the logger
logger.addHandler(file_handler)
logger.addHandler(console_handler)


class App:

    def __init__(self, host, port, server):
        logger.info("Initializing the app")
        self.processor = Processor()
        self._app = Bottle()
        self._host = host
        self._port = port
        self._server = server

    def _route(self):
        self._app.route('/hello/<attribute>/<number>', method="POST", callback=self.get_output)

    def start(self):
        self._app.run(server=self._server, host=self._host, port=self._port)  ## Starts the service
        logger.info("Web service started.")

    def get_output(self, attribute, number):
        logger.info("Got the input attribute {}".format(attribute))
        result = self.processor.compute(attribute, number)
        return result


if __name__ == '__main__':
    server = App(server='waitress', host='0.0.0.0', port=8080)
    server.start()

后端.py

 import logging


class Processor:

    def __init__(self):
        self.logger = logging.getLogger(__name__)  # Setting the logging config
        self.attribute = None  ############ Setting this variable to None for the instance

    def set_attributes(self, input_attribute):
        self.attribute = input_attribute  ############### Setter to set the attribute

    def compute(self, attribute, number):
        self.set_attributes(attribute)
        self.logger.info("Completed processing the attribute {}".format(self.attribute))
        res = number + 5
        return res

问题是,每当有多个调用时,记录器都会选择存储在共享内存中的前一个请求参数(它选择蓝色表示绿色…等等)应用程序类型文件。

我重新创建了日志语句,如下所示

2019-12-23 15:15:46,992 yoshi INFO Web service started.
Bottle v0.13-dev server starting up (using WaitressServer())...
Listening on http://0.0.0.0:8090/
Hit Ctrl-C to quit.

Serving on http://0.0.0.0:8090

line1: 2019-12-23 15:15:47,327 app.py INFO Got the input attribute Green
line2: 2019-12-23 15:15:47,327 app.py INFO Got the input attribute Blue
line3: 2019-12-23 15:15:47,327 backend.py INFO Completed processing the attribute Green
line4: 2019-12-23 15:15:47,327 app.py INFO Got the input attribute Black
line5: 2019-12-23 15:15:47,327 backend.py INFO Completed processing the attribute Green <<<-----This needs to be Blue, but it is Green again (Is it because self.attribute = None)
line6: 2019-12-23 15:15:47,327 backend.py INFO Completed processing the attribute Black
line7: 2019-12-23 15:15:47,327 backend.py INFO Completed processing the attribute None <<<-----This needs to be Violet, but it is None again (Is it because self.attribute = None)
line8: 2019-12-23 15:15:47,327 app.py INFO Got the input attribute Violet

我总共用Green、Blue、Black和Violet属性对上述应用程序进行了4次并行调用

问题:

我的记录器在第5行和第7行出现故障的原因是什么?使用setter方法将输入参数设置为整个对象是否正确?(如果没有,如何将输入属性设置为一个全新的模块)

是不是因为自我属性??怎么解决这个问题??你知道吗

寻找一个答案来创建一个日志配置,它可以在我的应用程序的所有模块中使用。在这里,我需要使用日志消息中的请求参数,并且logger config don't get failed by multiple input calls to the application


Tags: thetopyselfinfoapp应用程序host
1条回答
网友
1楼 · 发布于 2024-03-29 14:45:02

我认为您可能需要使用线程本地存储来保存您的属性。对代码进行一些修改:

app.py

import logging.handlers
import threading

from bottle import Bottle

from backend import Processor
from storage import storage

logger = logging.getLogger()
logger.setLevel(logging.DEBUG)

# Logging handler for files
file_handler = logging.handlers.TimedRotatingFileHandler("log.log", when="midnight", interval=1,
                                                         backupCount=10000)
file_handler.setLevel(logging.INFO)

# Logging handler for console
console_handler = logging.StreamHandler()
console_handler.setLevel(logging.DEBUG)

# Formatter's for logging
formatter = logging.Formatter('%(asctime)s %(name)s %(levelname)s %(message)s')
file_handler.setFormatter(formatter)
console_handler.setFormatter(formatter)

# Add handlers to the logger
logger.addHandler(file_handler)
logger.addHandler(console_handler)


class App:

    def __init__(self, host, port, server):
        logger.info("Initializing the app")
        self.processor = Processor()
        self._app = Bottle()
        self._host = host
        self._port = port
        self._server = server
        self._app.route('/hello/<attribute>/<number>', method="POST", callback=self.get_output)

    def start(self):
        self._app.run(server=self._server, host=self._host, port=self._port)  ## Starts the service
        logger.info("Web service started.")

    def get_output(self, attribute, number):
        logger.info("Got the input attribute %s", attribute)
        local_storage = storage()
        local_storage.attribute = attribute
        self.processor.compute()
        return f"done for {attribute}"


if __name__ == '__main__':
    server = App(server='waitress', host='0.0.0.0', port=8081)
    server.start()

backend.py

import logging
import threading

from more_backend import do_work
from storage import storage


class Processor:

    def __init__(self):
        self.logger = logging.getLogger(__name__)  # Setting the logging config

    def compute(self):
        local_storage = storage()
        do_work()
        self.logger.info("Completed processing the attribute %s", local_storage.attribute)

more_backend.py

import logging
import threading
import time
import random

from storage import storage

def do_work():
    local_storage = storage()
    logger = logging.getLogger(__name__)
    logger.info("Doing work with attribute %s", local_storage.attribute)
    time.sleep(random.random())

storage.py

from functools import lru_cache
import threading

@lru_cache()
def storage():
    return threading.local()

我想它会做你想做的:attribute每个请求中的所有函数都可以处理该请求,而不需要手动传递,线程之间也不需要争用条件。你知道吗

相关问题 更多 >