簡體   English   中英

django+uwsgi 使用 TimedRotatingFileHandler 進行日志記錄“覆蓋旋轉的日志文件”

[英]django+uwsgi logging with TimedRotatingFileHandler "overwrites rotated log file"

我最近將我的 django 生產 web 應用程序從apache+mod_wsgi切換到emperor modenginx+uwsgi 除了 Time Rotated 日志文件外,一切正常。 我的 web 應用程序使用一個名為appname.log的日志文件來記錄所有請求,對於 apache,它在午夜輪換沒有問題。

使用uwsgi ,文件在午夜旋轉,但一些 uwsgi 進程/工作人員寫入此旋轉文件(示例旋轉文件: appname.log.2017-01-08 )而不是寫入appname.log這導致旋轉文件被覆蓋

一個解決方案似乎涉及 uwsgi.ini 文件(我不完全確定......),但如果用戶仍連接到我的應用程序,我不想重新啟動/重新加載 uwsgi。

有沒有可能或配置我可以用來通知所有 uwsgi 進程日志文件已更改而無需重新啟動 web 應用程序? 如果可能的話,我將擁有與apache+mod_wsgi相同的行為。

ConcurrentLogHandler太舊了,我不想使用 syslog 或 logrotate :)

有人有同樣的問題嗎? 有人有建議嗎?

謝謝

這是我的設置:

LOGGING = {
    'version': 1,
    'disable_existing_loggers': False,
    'formatters': {
        'verbose': {
            'format': '[%(asctime)s];[%(levelname)s];[Proc:%(process)d];[Thread:%(thread)d];%(module)s-%(funcName)s:%(lineno)d;Msg:%(message)s;'
        },
        'simple': {
            'format': '[%(asctime)s] [%(levelname)s] %(message)s'
        },
    },
    'filters': {
        'require_debug_false': {
            '()': 'django.utils.log.RequireDebugFalse'
        }
    },
    'handlers': {
        'file': {
            'level': 'DEBUG',
            'class': 'logging.handlers.TimedRotatingFileHandler',
            'filename': LOG_FILE,
            'when': 'midnight',
            'interval': 1,
            'backupCount': 365,
            'formatter': 'verbose'
        },
        'null': {
            'level': 'DEBUG',
            'class': 'logging.NullHandler',
        },
        'console': {
            'level': 'DEBUG',
            'class': 'logging.StreamHandler',
            'formatter': 'verbose'
        },
        'mail_admins': {
            'level': 'ERROR',
            'class': 'django.utils.log.AdminEmailHandler',
            'filters': ['require_debug_false']
        }
    },
    'loggers': {
        APP_NAME: {
            'handlers': ['console', 'file'],
            'propagate': True,
            'level': 'INFO',
        },
        'django': {
            'handlers': ['mail_admins', 'file'],
            'level': 'ERROR',
            'propagate': True,
        },
    }

我們用nginx+gunicorn也遇到過同樣的問題。 我們有非常相似的設置:

LOGGING = {
    "version": 1,
    "disable_existing_loggers": False,
    "formatters": {
        "verbose": {"format": "%(levelname)s %(asctime)s %(module)s %(process)d %(thread)d %(message)s"},
        "simple": {"format": "%(levelname)s %(asctime)s  %(message)s", "datefmt": "%Y-%m-%d %H:%M"},
    },
    "filters": {
          "require_debug_true": {"()": "django.utils.log.RequireDebugTrue"},
          "require_debug_false": {"()": "django.utils.log.RequireDebugFalse"},
    },
    "handlers": {
        "logfile": {
            "class": "logging.handlers.TimedRotatingFileHandler",
            "when": "D",
            "interval": 10, 
            "backupCount": 100,
            "filename": LOG_FILE,
            "formatter": "simple",
            "level": "DEBUG",
        },
    },
    "loggers": {    
        APP_NAME: {
            "handlers": ["console", "plus_logfile"],
            "propagate": True,
            "level": "DEBUG",
        },
    },
}

根據Python Logging Cookbook - Logging to a single file from multiple processes

盡管日志記錄是線程安全的,並且支持從單個進程中的多個線程記錄到單個文件,但不支持從多個進程記錄到單個文件,因為沒有標准方法可以跨多個序列化對單個文件的訪問Python 中的進程。 如果您需要從多個進程登錄到單個文件,一種方法是讓所有進程登錄到 SocketHandler,並有一個單獨的進程來實現從套接字讀取並記錄到文件的套接字服務器。 (如果您願意,可以在現有進程之一中指定一個線程來執行此功能。)

所以最好的方法是有一個套接字偵聽器,它可以同時偵聽多個 uwsgi 工作線程和日志。

設置如下所示:

"loggers": {    
    APP_NAME: {
        "handlers": ["console", "plus_logfile"],
        "propagate": True,
        "level": "DEBUG",
    },
}, 

您可以在此處找到示例偵聽器代碼。 但是,此代碼寫入控制台。 因此,如果要寫入文件,則需要編輯偵聽器腳本。

完全符合cgl解決方案,但如果您不想構建套接字偵聽器並想要一個生產級解決方案而不丟失日志,那么您可以執行我在當前組織中執行的以下步驟。

  1. Linux/Unix logrotate 與創建選項
  2. 除了 logrotate,您還需要使用Watchedfilehandler 它在每次發出時監視文件 stream,如果文件名更改,它會關閉它並使用文件名重新打開它。

您不需要重新加載/重新啟動您的 Django 應用程序,您也不會錯過日志。 到目前為止,我們還沒有發現這種方法有任何問題。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM