使用Django,如何确保管理命令具有自定义日志记录?

时间:2019-05-23 16:25:21

标签: python django logging

场景

我想确保(保证)所有管理命令调用都根据名称将日志生成到自定义位置;例如该命令将追加到以该命令命名的文件中:

  

$ bin / django changepassword ...

     

$ ls /var/log/django/changepassword.log

     

$ bin / django shell

     

$ ls /var/log/django/shell.log

选项

我有一个自定义日志记录配置,我正在settings.py中进行注册,但这不是我期望得到这种自定义行为的地方。

猴子打补丁吗?但是什么,在哪里?

1 个答案:

答案 0 :(得分:0)

我决定使用在全球安装的记录器。然后仅在从命令行运行管理命令时启用它。

from django.core.management.base import BaseCommand
from logging.handlers import WatchedFileHandler
from logging import Handler, getLogger

LOG = getLogger(__name__)


class ManageCommandLogger(Handler):
    """
    A logger which only enables when you're running manage commands.
    """
    _instance = None

    def __init__(self, filename, mode='a', encoding=None, delay=0):
        self._kwargs = dict(filename=filename, mode=mode, encoding=encoding, delay=delay)
        self._handler = None
        super(ManageCommandLogger, self).__init__()
        self.__class__._instance = self

    @classmethod
    def enable(cls, name, path=None):
        self = cls._instance
        if self._handler:
            return
        if not path:
            self._kwargs['filename'] %= name
        else:
            self._kwargs['filename'] = path
        self._handler = WatchedFileHandler(**self._kwargs)
        self._handler.setFormatter(self.formatter)
        self._handler.level = self.level
        LOG.info("command logging enabled to %s", self._kwargs['filename'])

    def handle(self, record):
        if not self._handler:
            return
        return super(ManageCommandLogger, self).handle(record)

    def emit(self, record):
        if not self._handler:
            return
        self._handler.emit(record)


def _patch_run_from_argv(self, *args, **kwargs):
    name = args[0][1]
    ManageCommandLogger.enable(name)
    return self._run_from_argv(*args, **kwargs)


BaseCommand._run_from_argv = BaseCommand.run_from_argv
BaseCommand.run_from_argv = _patch_run_from_argv