RError.com

RError.com Logo RError.com Logo

RError.com Navigation

  • 主页

Mobile menu

Close
  • 主页
  • 系统&网络
    • 热门问题
    • 最新问题
    • 标签
  • Ubuntu
    • 热门问题
    • 最新问题
    • 标签
  • 帮助
主页 / 问题 / 1440662
Accepted
Sazoks
Sazoks
Asked:2022-08-19 14:22:37 +0000 UTC2022-08-19 14:22:37 +0000 UTC 2022-08-19 14:22:37 +0000 UTC

如何使用 RotatingFileHandler 配置 Django + Celery 日志记录?

  • 772

Django (DRF) 上有一项服务,其中配置了日志记录子系统。该服务还有一个执行某些任务的 Celery worker。我想以这样一种方式设置日志记录,即所有日志(Django 和 Celery)都保存在 .log 文件中,同时使用 RotatingFileHandler “滚动”文件,以免阻塞磁盘空间。我必须马上说我是登录 Django 的新手。

settings.py 文件中的 LOGGING 设置:

# Настройки логирования.
LOGGING = {
    'version': 1,
    'disable_existing_loggers': False,
    'formatters': {
        'default': {
            'format': '[{levelname}]-[{asctime}]-[{module}]-[{process:d}]-[{thread:d}]: {message}',
            'style': '{',
        },
    },
    'handlers': {
        'applications_logfile': {
            'level': 'INFO',
            'class': 'logging.handlers.RotatingFileHandler',
            'formatter': 'default',
            'filename': LOGS_DIR / 'applications/applications.log',
            'maxBytes': 300,
            'backupCount': 5,
        },
        'celery_worker_logfile': {
            'level': 'INFO',
            'class': 'logging.handlers.RotatingFileHandler',
            'formatter': 'default',
            'filename': LOGS_DIR / 'celery/worker.log',
            'maxBytes': 300,
            'backupCount': 5,
        },
    },
    'loggers': {
        'celery': {
            'level': 'INFO',
            'handlers': ['celery_worker_logfile'],
        },
        'api.application_handler.views': {
            'level': 'INFO',
            'handlers': ['applications_logfile'],
        },
    },
}

在 celery.py 文件中设置日志记录:

# Настройка логирования для Celery. Используем настройки логирования проекта.
@setup_logging.connect
def config_loggers(*args, **kwargs) -> None:
    from logging.config import dictConfig
    from django.conf import settings

    dictConfig(settings.LOGGING)

我还禁用了 Celery 的根记录器捕获:

# Настройки Celery.
CELERY_BROKER_URL = config('CELERY_BROKER_URL')
CELERYD_HIJACK_ROOT_LOGGER = False

问题是,当任何可滚动的 .log 文件达到其最大大小并且 python 尝试滚动文件时,它会失败并出现以下错误: PermissionError: [WinError 32] Процесс не может получить доступ к файлу, так как этот файл занят другим процессом. 工人中有什么,django中有什么。

原因。在对这种行为进行了长时间的研究之后,我意识到 django 进程保存了一个 .log 文件,celery worker 写入,而 celery worker 保存了 django 进程写入的 .log 文件。.log 文件的“滚动”(旋转)是通过创建一个写入日志的空 .log 文件并重命名旧的 .log 文件来完成的。这就是问题所在。没有进程可以重命名该文件,因为它正被另一个进程使用。

我试图做的事情。我试图将 celery 和 django 日志记录设置完全分开,从 settings.py 中删除 celery 的所有设置并将它们写入 celery.py 中,以便两个进程根本不会接触彼此的文件。

设置.py:

# Настройки логирования.
LOGGING = {
    'version': 1,
    'disable_existing_loggers': False,
    'formatters': {
        'default': {
            'format': '[{levelname}]-[{asctime}]-[{module}]-[{process:d}]-[{thread:d}]: {message}',
            'style': '{',
        },
    },
    'handlers': {
        'applications_logfile': {
            'level': 'INFO',
            'class': 'logging.handlers.RotatingFileHandler',
            'formatter': 'default',
            'filename': LOGS_DIR / 'applications/applications.log',
            'maxBytes': 300,
            'backupCount': 5,
        },
    },
    'loggers': {
        'api.application_handler.views': {
            'level': 'INFO',
            'handlers': ['applications_logfile'],
        },
    },
}

芹菜.py

# Настройка логирования для Celery.
@setup_logging.connect
def config_loggers(*args, **kwargs) -> None:
    logger = logging.getLogger('celery')
    logger.setLevel(logging.INFO)
    formatter = logging.Formatter(
        fmt='[{levelname}]-[{asctime}]-[{module}]-[{process:d}]-[{thread:d}]: {message}',
        style='{',
    )
    handler = handlers.RotatingFileHandler(
        filename=settings.LOGS_DIR / 'celery/worker.log',
        maxBytes=300,
        backupCount=5,
    )
    handler.setFormatter(formatter)
    logger.addHandler(handler)

之后django进程就不再保留worker写入的.log文件了,轮转成功了!但由于某种原因,celery-worker 仍然保留一个 .log 文件,django 进程在其中写入,并且它不会旋转并因错误而崩溃......

我见过很多类似的问题,但没有找到适合我的解决方案。各地的信息不同,到处都有不同的选择,在我看来,任务相当琐碎,肯定有一个好的解决方案。

提前致谢。

UPD.1:我怀疑 celery 以某种方式加载了 LOGGING 中指定的设置。当我os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'company.settings')从 celery.py 中删除该行时,工作进程不再保留 django 进程写入的 .log 文件(当然,任务不是自动找到的,我这样做只是为了检查)。

UPD.2:

启动 django 服务器:python manage.py runserver --noreload.

启动芹菜工人:(celery -A company worker --loglevel=info -P eventlet我使用的是win10)。

django логирование
  • 1 1 个回答
  • 58 Views

1 个回答

  • Voted
  1. Best Answer
    Sazoks
    2022-08-20T19:30:49Z2022-08-20T19:30:49Z

    我找到了我的问题的答案!

    一般来说,重点是当我们os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'company.settings')向 celery.py 写入一行代码时,celery 工作进程会从 settings.py 接收带有所有 django 和 LOGGING 设置的日志记录模块(它是一个单例) 。因此,django 进程和 celery worker 有共同的日志设置(celery 只是添加了自己的)。因此,他们窃取了彼此的日志文件。所以这是实际的解决方案。问题是如果文件被另一个进程占用,Windows 禁止重命名文件(在日志轮换期间),但 Linux 不是:) ohm。

    怎么会有危险

    就我而言,我为每个进程都有自己的日志文件,这是合乎逻辑且正确的。但是,一个进程可以删除/重命名另一个进程当前正在使用的文件。另一个进程不会知道它,并且可能会出现大问题。但是,如果这些进程只处理自己的文件,而不接触其他文件,那么就不会有问题。

    • 0

相关问题

  • Django views.py 如何编写过滤器来显示文章的评论

  • 为什么 Sales 字段没有到达前面,即使它们已添加到序列化程序中

  • 注销而不进入 /exit 页面

  • Django 调试服务器未启动

  • 如果页面长时间打开,则 CSRF cookie 未设置 Django

  • 如何删除通过外键链接到另一个模型的图像

Sidebar

Stats

  • 问题 10021
  • Answers 30001
  • 最佳答案 8000
  • 用户 6900
  • 常问
  • 回答
  • Marko Smith

    我看不懂措辞

    • 1 个回答
  • Marko Smith

    请求的模块“del”不提供名为“default”的导出

    • 3 个回答
  • Marko Smith

    "!+tab" 在 HTML 的 vs 代码中不起作用

    • 5 个回答
  • Marko Smith

    我正在尝试解决“猜词”的问题。Python

    • 2 个回答
  • Marko Smith

    可以使用哪些命令将当前指针移动到指定的提交而不更改工作目录中的文件?

    • 1 个回答
  • Marko Smith

    Python解析野莓

    • 1 个回答
  • Marko Smith

    问题:“警告:检查最新版本的 pip 时出错。”

    • 2 个回答
  • Marko Smith

    帮助编写一个用值填充变量的循环。解决这个问题

    • 2 个回答
  • Marko Smith

    尽管依赖数组为空,但在渲染上调用了 2 次 useEffect

    • 2 个回答
  • Marko Smith

    数据不通过 Telegram.WebApp.sendData 发送

    • 1 个回答
  • Martin Hope
    Alexandr_TT 2020年新年大赛! 2020-12-20 18:20:21 +0000 UTC
  • Martin Hope
    Alexandr_TT 圣诞树动画 2020-12-23 00:38:08 +0000 UTC
  • Martin Hope
    Air 究竟是什么标识了网站访问者? 2020-11-03 15:49:20 +0000 UTC
  • Martin Hope
    Qwertiy 号码显示 9223372036854775807 2020-07-11 18:16:49 +0000 UTC
  • Martin Hope
    user216109 如何为黑客设下陷阱,或充分击退攻击? 2020-05-10 02:22:52 +0000 UTC
  • Martin Hope
    Qwertiy 并变成3个无穷大 2020-11-06 07:15:57 +0000 UTC
  • Martin Hope
    koks_rs 什么是样板代码? 2020-10-27 15:43:19 +0000 UTC
  • Martin Hope
    Sirop4ik 向 git 提交发布的正确方法是什么? 2020-10-05 00:02:00 +0000 UTC
  • Martin Hope
    faoxis 为什么在这么多示例中函数都称为 foo? 2020-08-15 04:42:49 +0000 UTC
  • Martin Hope
    Pavel Mayorov 如何从事件或回调函数中返回值?或者至少等他们完成。 2020-08-11 16:49:28 +0000 UTC

热门标签

javascript python java php c# c++ html android jquery mysql

Explore

  • 主页
  • 问题
    • 热门问题
    • 最新问题
  • 标签
  • 帮助

Footer

RError.com

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

帮助

© 2023 RError.com All Rights Reserve   沪ICP备12040472号-5