Python中Django + Gunicorn + Nginx部署下logging setLevel设置问题请教

有一个 django 项目,日志写入到文件,需求是可以动态修改 logging 的 level.

我写了一个 demo, 在请求中把每个 level 的 log 都打印一下,如果更改了 level, 那么后台打印就会看到。

demo 的前端界面如下:
fs

有 5 个 gunicorn 进程:
gunicorn

我用 ab 命令测试了一下 ,后台打印的 log ,可以看到只有 PID:28763 的 loglevel 是 error ,其它的进程都还是默认的 debug level 。 也就是说设置 level 只对 一个进程生效,我想要的效果是对所有进程重新,大家能帮我找下原因吗,谢谢了。

gunicorn

系统 centos 7.4
Django: 1.11.8
nginx: 1.12
gunicorn: 19.7.1
meinheld: 0.6.1

django 的 log 配置部分:


LOGGING = { ‘version’: 1, ‘disable_existing_loggers’: False, ‘formatters’: { ‘verbose’: { ‘format’: ‘[%(process)d] [%(asctime)s] %(levelname)s [%(filename)s:%(lineno)s] %(message)s’ } }, ‘handlers’: { ‘file’: { ‘level’: ‘DEBUG’, ‘class’: ‘logging.handlers.RotatingFileHandler’, ‘maxBytes’: 1024*1024, ‘backupCount’: 5, ‘filename’: ‘/tmp/run.log’, ‘formatter’: ‘verbose’ }, ‘console’: { ‘level’: ‘DEBUG’, ‘class’: ‘logging.StreamHandler’, ‘formatter’: ‘verbose’ } }, ‘loggers’: { ‘django_docker’: { ‘handlers’: [‘file’, ‘console’], ‘level’: ‘DEBUG’, ‘propagate’: True, }, ‘django.request’: { ‘handlers’: [‘file’], ‘level’: ‘ERROR’, ‘propagate’: False, } }, }

django 中打印 log 的代码:


logger = logging.getLogger('django_docker')

def index(request): level_name = logging.getLevelName(logger.getEffectiveLevel()) logger.critical(’========= Start Logging ================’) logger.debug(’\t\t==> Debug Log’) logger.info(’\t\t==> Info Log’) logger.warning(’\t==> Warning Log’) logger.error(’\t\t==> Error Log’) logger.critical(’\t==> Critical Log’) logger.critical(’========= End Logging ================’) if request.method == ‘POST’: if ‘logLevel’ in request.POST and request.POST[‘logLevel’]: level_name = request.POST[‘logLevel’].upper() logger.critical(’====> %s <===’ % logger.root.name) logger.root.setLevel(level_name) logger.setLevel(level_name) return redirect(‘index’) return render(request, ‘main/index.html’, {‘log_level’: level_name})

gunicorn 配置

import multiprocessing
from logging.config import dictConfig

name = “django_docker” bind = “unix:/var/run/django_docker.sock” worker_class = “egg:meinheld#gunicorn_worker” #workers = multiprocessing.cpu_count() * 2 + 1 workers = 4 reload = True

umask = 0002 user = ‘nginx’ group = ‘nginx’

accesslog = “/tmp/gunicorn.access.log” errorlog = “/tmp/gunicorn.error.log”

raw_env = [“DJANGO_SETTINGS_MODULE=django_docker.settings”] chdir = " /home/tiannpen/workspace/django_docker/" pidfile = “/var/run/gunicorn.pid” daemon = True

capture_output = True

logconfig_dict = { ‘version’:1, ‘disable_existing_loggers’: False, ‘loggers’:{ “root”: {“level”: “INFO”, “handlers”: [“console”]}, “gunicorn.error”: { “level”: “INFO”, “handlers”: [“error_file”], “propagate”: 1, “qualname”: “gunicorn.error” },

    "gunicorn.access": {
        "level": "INFO",
        "handlers": ["access_file"],
        "propagate": 0,
        "qualname": "gunicorn.access"
    }
},
'handlers':{
    "console": {
        "class": "logging.StreamHandler",
        "formatter": "generic",
        "stream": "sys.stdout"
    },
    "error_file": {
        "class": "logging.FileHandler",
        "formatter": "generic",
        "filename": "/tmp/gunicorn.error.log"
    },
    "access_file": {
        "class": "logging.handlers.RotatingFileHandler",
        "maxBytes": 1024*1024,
        "backupCount": 5,
        "formatter": "generic",
        "filename": "/tmp/gunicorn.access.log",
    }
},
'formatters':{
    "generic": {
        "format": "%(asctime)s [%(process)d] [%(levelname)s] %(message)s",
        "datefmt": "[%Y-%m-%d %H:%M:%S %z]",
        "class": "logging.Formatter"
    },
    "access": {
        "format": "%(message)s",
        "class": "logging.Formatter"
    }
}

}


Python中Django + Gunicorn + Nginx部署下logging setLevel设置问题请教

5 回复

看 gunicorn 官方文档呗,应该有 worker 间通信的方式的。
反正 uwsgi 有 signal 来实现 worker 间通信


#1 #1 能否大概讲下 uwsgi worker 之间怎么通信呢?我之前用 uwsgi, 4 个 worker 也是这样的问题

可以把这个设置独立到一个不同进程都能读到的地方,比如丢到缓存里,然后让每个进程读取这个配置

#4 #4 哦,我感觉问题在于 logger, 我是用 logger = logging.getLogger(‘django_docker’) 这样来获取,但是这样获取到的是只是这一个 process 的 logger 实例

回到顶部