通过主管和 docker-compose 从 django 输出彩色日志

Posted

技术标签:

【中文标题】通过主管和 docker-compose 从 django 输出彩色日志【英文标题】:Output colored logs from django through supervisor and docker-compose 【发布时间】:2017-04-09 18:39:05 【问题描述】:

我的目标是在 docker-compose logs 中获取我的 Django 网络服务的 colorized 日志。

    我使用 docker-compose 来管理基于 Django 框架的 Web 服务列表。

    每个容器,运行一个 my_init bash 脚本,然后运行一个 runit(这在我的例子中是历史性的)脚本,该脚本运行一个 supervisord em> 进程:

    my_init---runsvdir-+-runsv---run---supervisord-+-gunicorn---gunicorn
                       |                           |-nginx---8*[nginx]
                       |                           |-python---9*[python]
                       |                           |-python---python  (Django)
                       |                           `-redis-server---2*[redis-server]
                       `-runsv
    

    Django 服务器在 WSGI 中与 Gunicorn 接口,并通过 Nginx

    提供服务

    supervisord 配置如下:

    [supervisord]
    http_port=/var/tmp/supervisor.sock ; (default is to run a UNIX domain socket server)
    stdout_logfile=/dev/stdout
    stdout_logfile_maxbytes=0
    stderr_logfile=/dev/stderr
    stderr_logfile_maxbytes=0
    
    [program:gunicorn_core_service]
    #environment=myapp_VENV=/opt/myapp/venv/
    environment=PYTHONPATH=/opt/myapp/myappServer/myappServer
    command = /opt/myapp/venv/bin/gunicorn wsgi -b 0.0.0.0:8000 --timeout 90 --access-logfile /dev/stdout --error-logfile /dev/stderr
    directory = /opt/myapp/myappServer
    user = root
    autostart=true
    autorestart=true
    redirect_stderr=true
    stdout_logfile=/dev/stdout
    stdout_logfile_maxbytes=0
    stderr_logfile=/dev/stderr
    stderr_logfile_maxbytes=0
    
    [program:django-celery]
    command=/opt/myapp/venv/bin/python ./manage.py celery --app=myappServer.celeryapp:app worker -B --loglevel=INFO
    directory=/opt/myapp/myappServer
    numprocs=1
    stdout_logfile=/dev/stdout
    stdout_logfile_maxbytes=0
    stderr_logfile=/dev/stderr
    stderr_logfile_maxbytes=0
    redirect_stderr=true
    autostart=true
    autorestart=true
    startsecs=10
    
    [program:nginx]
    command=nginx -g "daemon off;"
    #user = root
    autostart=true
    autorestart=true
    redirect_stderr=true
    stdout_logfile=/dev/stdout
    stdout_logfile_maxbytes=0
    stderr_logfile=/dev/stderr
    stderr_logfile_maxbytes=0
    

    由于docker只能记录一次进程,所以我的容器所有进程的日志都转发到/dev/stdout/dev/stderr

    我使用colorlog 作为颜色格式化程序来为 Django 日志着色:

    'formatters': 
        'color': 
            '()': 'colorlog.ColoredFormatter',
            'format': '%(log_color)s%(levelname)-8s %(message)s',
            'log_colors': 
                'DEBUG':    'bold_black',
                'INFO':     'white',
                'WARNING':  'yellow',
                'ERROR':    'red',
                'CRITICAL': 'bold_red',
            ,
        
    ,
    
    当我从容器
    ./manage.py runserver
    内运行服务时,日志会被着色。 但是从外部看,docker-compose 日志没有着色。

我尝试添加

tty: true
在我的服务中描述为here,但它似乎不再起作用了。

有什么想法吗?

【问题讨论】:

并且还实现了那家伙的要求 你的 Django LOGGING 设置中有什么?你到底想给什么上色?我假设那些来自 Gunicorn 的人,在这种情况下,您是否更改了 Gunicorn 记录器的日志记录配置?在下面查看我的答案以获取工作示例。 【参考方案1】:

这是一个使用 Gunicorn 服务的 Django 应用程序的最小工作示例。诀窍是确保 Gunicorn 记录器配置为使用使用彩色格式化程序的处理程序。

settings.py

LOGGING = 
    'version': 1,
    'disable_existing_loggers': False,
    'formatters': 
        'colored_verbose': 
            '()': 'colorlog.ColoredFormatter',
            'format': "%(log_color)s%(levelname)-8s%(red)s%(module)-30s%(reset)s %(blue)s%(message)s"
        ,
    ,
    'handlers': 
        'colored_console': 
            'level': 'INFO',
            'class': 'logging.StreamHandler',
            'formatter': 'colored_verbose'
        
    ,
    'loggers': 
        '': 
            'level': 'INFO',
            'handlers': ['colored_console'],
        ,
        'gunicorn.access': 
            'handlers': ['colored_console']
        ,
        'gunicorn.error': 
            'handlers': ['colored_console']
        
    

终端输出

奖金

检查日志配置的最佳方法(根据我的经验)是使用logging_tree。

只需在您的应用程序上下文中执行此操作(例如在 Django shell 中)

import logging_tree
logging_tree.printout()

它应该打印出现有记录器的良好表示。

我更进一步,将其添加到我的urls.py,以便在安装所有记录器后查看日志记录配置。

from django.conf.urls import url
from django.http import HttpResponse
import logging_tree

urlpatterns = [
    url(r'^loggers', loggers),
]

def loggers(request):
    """
    Returns a representation of the existing loggers
    """
    return HttpResponse(logging_tree.format.build_description()[:-1])

它应该返回类似的东西

<--""
   Level INFO
   Handler Stream <_io.TextIOWrapper name='<stderr>' mode='w' encoding='UTF-8'>
     Level INFO
     Formatter <colorlog.colorlog.ColoredFormatter object at 0x1103a1668>
   |
   o<--"django"
   |   Level INFO
   |   Handler Stream <_io.TextIOWrapper name='<stderr>' mode='w' encoding='UTF-8'>
   |     Level INFO
   |     Filter <django.utils.log.RequireDebugTrue object at 0x11047d518>
   |   Handler <AdminEmailHandler (ERROR)>
   |     Level ERROR
   |     Filter <django.utils.log.RequireDebugFalse object at 0x11053a7f0>
   |   |
   |   o<--"django.db"
   |   |   Level NOTSET so inherits level INFO
   |   |   |
   |   |   o<--"django.db.backends"
   |   |       Level NOTSET so inherits level INFO
   |   |       |
   |   |       o<--"django.db.backends.schema"
   |   |           Level NOTSET so inherits level INFO
   |   |
   |   o<--"django.request"
   |   |   Level NOTSET so inherits level INFO
   |   |
   |   o   "django.server"
   |   |   Level INFO
   |   |   Propagate OFF
   |   |   Handler Stream <_io.TextIOWrapper name='<stderr>' mode='w' encoding='UTF-8'>
   |   |     Level INFO
   |   |     Formatter <django.utils.log.ServerFormatter object at 0x11053a630>
   |   |
   |   o<--"django.template"
   |       Level NOTSET so inherits level INFO
   |
   o<--"gunicorn"
       Level NOTSET so inherits level INFO
       |
       o   "gunicorn.access"
       |   Level INFO
       |   Propagate OFF
       |   Handler Stream <_io.TextIOWrapper name='<stderr>' mode='w' encoding='UTF-8'>
       |     Level INFO
       |     Formatter <colorlog.colorlog.ColoredFormatter object at 0x1103a1668>
       |
       o   "gunicorn.error"
       |   Level INFO
       |   Propagate OFF
       |   Handler Stream <_io.TextIOWrapper name='<stderr>' mode='w' encoding='UTF-8'>
       |     Level INFO
       |     Formatter <colorlog.colorlog.ColoredFormatter object at 0x1103a1668>
       |
       o<--"gunicorn.http"
          Level NOTSET so inherits level INFO
           |
           o<--"gunicorn.http.wsgi"
               Level NOTSET so inherits level INFO

【讨论】:

以上是关于通过主管和 docker-compose 从 django 输出彩色日志的主要内容,如果未能解决你的问题,请参考以下文章

无法从 docker-compose 连接到 docker

DJ软件 XYLIO Future DJ Pro v1.5.2.0 MacOSX

docker-compose:无法从我的 LEMP 堆栈访问 phpMyAdmin

Traefik无法通过docker-compose连接到服务器。

从 docker-compose 替换 NGINX 配置中的环境变量

无法从 shell 生成 erlang 主管