基于 Django + Celery 的应用程序的动态(即运行时可配置)日志配置
Posted
技术标签:
【中文标题】基于 Django + Celery 的应用程序的动态(即运行时可配置)日志配置【英文标题】:Dynamic (i.e. Runtime Configurable) Log Configuration for Django + Celery based application 【发布时间】:2013-04-24 23:08:13 【问题描述】:我们需要在运行时自定义服务器上的日志级别。我们正在使用 Django 构建一个 SAAS 应用程序,我们最终必须能够为每个租户启用日志记录。我正在努力寻找最好的方法。
作为第一步,我创建了一种动态更改日志级别的方法(针对整个应用程序)。我看到没有这样做的例子。我注意到到目前为止是否有人尝试过这样的事情,我应该注意哪些陷阱。
到目前为止,这是我的代码。感谢是否有人可以阐明我将遇到的特定陷阱。还要感谢有关如何控制每个租户和模块的日志记录的任何输入,除了为每个模块的每个租户创建记录器:
import threading
import logging.config
import time
import os
import traceback
class LogConfigWatcher(threading.Thread):
def __init__(self, storage, location):
self.last_known_time = None
self.storage = storage
self.location = location
threading.Thread.__init__(self)
def run(self):
while True:
mod_time = os.path.getmtime(self.location)
if(mod_time != self.last_known_time):
try:
with file(self.location) as f:
print("Configuring logging . . .")
config = eval(f.read())
logging.config.dictConfig(config['handler_config'])
logging.config.dictConfig(config['logger_config'])
self.last_known_time = mod_time
except:
traceback.print_exc()
print "Failed to Configure the log"
pass
time.sleep(5)
class LogConfigHolder(object):
def __init__(self, storage, location):
self.storage = storage
self.location = location
self.initialize(storage, location)
def initialize(self, storage, location):
self.pid = os.getpid()
print "Starting thread for %s" % self.pid
self.thread = LogConfigWatcher(storage, location)
self.thread.setDaemon(True)
self.thread.start()
def is_alive(self):
if os.getpid() != self.pid:
return False
return self.thread.isAlive()
def restart(self):
if not self.is_alive():
self.initialize(self.storage, self.location)
【问题讨论】:
试试这个:docs.python.org/2/howto/… 和这个:docs.python.org/2/howto/logging-cookbook.html#network-logging 我的问题更多是关于如何在进程仍在运行时更改日志级别。我在问问题之前阅读了它们,但在那里找不到任何东西。 【参考方案1】:我很确定您给定的代码与 Logging 模块本身的编写者已经想出的代码很接近。
您在程序中使用一个单独的线程,该线程在每次发生日志记录事件时侦听配置请求。日志服务器反过来保存您可以调整的配置文件。更改将在下一次日志记录事件中生效。
Logger 模块的原作者可能会为您提供更多见解here,请注意本手册有点过时了。用于 Logging 的官方 Python 文档有一个配置此类 Logging 服务器/客户端设置的示例:Logging Cookbook。
而且,随着复杂性的增加,这种设置确实会对性能产生轻微影响。
【讨论】:
【参考方案2】:我写了一个应用程序来解决这个问题。配置在数据库中,可以保存许多配置,在可配置的日期/时间只有一个处于活动状态。
为了解决更改后重新加载新配置的问题,我创建了 3 个策略来传播新配置:
听取配置模型更改的信号并更新配置(在单进程环境中工作) 每分钟使用线程检查一次新配置(如您的代码) 监听配置更改信号,但通过 amqp 消息后端传播事件。 (这是最优化的解决方案)。检查https://github.com/Yupeek/django-dynamic-logging
【讨论】:
以上是关于基于 Django + Celery 的应用程序的动态(即运行时可配置)日志配置的主要内容,如果未能解决你的问题,请参考以下文章
Celery 3 版本 定时执行与 异步执行 | Django 案例