You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

部署在ECS的Django自定义日志无法显示在CloudWatch的问题

问题解决:ECS上Django自定义日志无法显示在CloudWatch

问题背景

部署在ECS的Django项目中,自定义日志记录器ru_profile的日志完全无法在AWS CloudWatch Logs中显示,仅能看到botocore、urllib3及root日志记录器的内容。

当前配置与使用情况

Django日志配置

LOGGING = {
    'version': 1,
    'disable_existing_loggers': False,
    'formatters': {
        'json': {
            'format': '%(levelname)s %(asctime)s %(name)s %(message)s %(lineno)d %(pathname)s',
            'class': 'pythonjsonlogger.jsonlogger.JsonFormatter',
        },
    },
    'handlers': {
        'console': {
            'level': 'DEBUG',
            'class': 'logging.StreamHandler',
            'formatter': 'json',
        },
    },
    'loggers': {
        'django': {
            'handlers': ['console'],
            'level': 'INFO',
            'propagate': True,
        },
        'ru_profile': {
            'handlers': ['console'],
            'level': 'DEBUG',
            'propagate': False,
        },
        '': {
            'handlers': ['console'],
            'level': 'DEBUG',
            'propagate': True,
        },
    },
    'root': {
        'handlers': ['console'],
        'level': 'DEBUG',
    },
}

日志使用示例

import logging

logger = logging.getLogger('ru_profile')

class ForgotPasswordView(CreateView):
    model = User
    template_name = 'user/forgot_password.html'
    form_class = ForgotPasswordForm

    def form_valid(self, form):
        phone = str(form.cleaned_data['phone'])
        user = User.find_by_phone(phone)
        if user is not None:
            user.send_reset_pin()
            logger.info(f"Reset PIN sent successfully to {phone}")
        else:
            logger.error(f"Couldn't reset PIN, user not found for phone '{phone}'")
            django_messages.error(self.request, _("Couldn't reset your PIN. Please try again"))
            return self.form_invalid(form)

        return redirect('reset_pin_view', phone=phone)

额外信息

  • Dockerfile已添加ENV PYTHONUNBUFFERED=1
  • print()语句可正常显示在CloudWatch
  • 测试过不同日志级别,自定义日志均无输出
  • 应用通过uwsgi+supervisord运行

解决步骤

1. 修复Django日志配置冲突

你的配置中同时存在空字符串日志器('')和root日志器,二者本质指向同一个root logger,会导致配置冲突,干扰自定义日志器的输出。删除空字符串日志器配置,修改后的LOGGING如下:

LOGGING = {
    'version': 1,
    'disable_existing_loggers': False,
    'formatters': {
        'json': {
            'format': '%(levelname)s %(asctime)s %(name)s %(message)s %(lineno)d %(pathname)s',
            'class': 'pythonjsonlogger.jsonlogger.JsonFormatter',
        },
    },
    'handlers': {
        'console': {
            'level': 'DEBUG',
            'class': 'logging.StreamHandler',
            'formatter': 'json',
        },
    },
    'loggers': {
        'django': {
            'handlers': ['console'],
            'level': 'INFO',
            'propagate': True,
        },
        'ru_profile': {
            'handlers': ['console'],
            'level': 'DEBUG',
            'propagate': False,
        },
    },
    'root': {
        'handlers': ['console'],
        'level': 'DEBUG',
    },
}

2. 调整uwsgi配置,确保日志输出到stdout

uwsgi默认可能屏蔽或重定向应用日志,需明确配置将日志发送到标准输出。修改uwsgi.ini或启动命令:

# uwsgi.ini示例配置
[uwsgi]
socket = :8000
module = myproject.wsgi:application
master = true
processes = 4
# 关键配置:将日志输出到stdout
stdout-logger = true
disable-logging = false
logto = /dev/stdout

如果用命令行启动,添加参数:

uwsgi --ini uwsgi.ini --logto /dev/stdout --disable-logging false

3. 配置supervisord转发应用日志到控制台

supervisord需要正确捕获应用的stdout和stderr,确保输出能被ECS收集并发送到CloudWatch。修改supervisord程序配置:

[program:django]
command = uwsgi --ini uwsgi.ini
directory = /path/to/your/project
user = root
# 转发stdout和stderr到控制台,不做日志轮转
stdout_logfile = /dev/stdout
stdout_logfile_maxbytes = 0
stderr_logfile = /dev/stderr
stderr_logfile_maxbytes = 0
# 将stderr合并到stdout(可选,方便统一收集)
redirect_stderr = true

4. 容器内测试日志输出,定位问题环节

进入运行中的容器,手动触发日志输出,确认应用本身能正常输出:

# 进入容器
docker exec -it <container-id> /bin/bash
# 启动Django shell
python manage.py shell

在shell中执行:

import logging
logger = logging.getLogger('ru_profile')
logger.info("Test custom log message")

如果控制台能看到这条日志,说明Django日志配置没问题,问题出在uwsgi/supervisord的日志转发;如果看不到,继续检查是否有其他地方覆盖了LOGGING设置。


内容的提问来源于stack exchange,提问作者arturkuchynski

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.23 19:20:00