如何在Django日志中添加环境变量值并传输至Logstash?
在Django日志中添加环境变量并传输到Logstash
要实现给所有日志消息前加上环境变量APP_ENV的值,同时让Logstash能方便地过滤日志,我们可以通过日志过滤器+自定义格式来实现,甚至能给Logstash发送独立的环境字段,让过滤效率更高。下面是具体的修改方案:
步骤1:添加日志过滤器注入环境变量
首先在LOGGING配置里新增filters部分,把APP_ENV注入到每条日志记录的上下文里,这样后续格式化器就能直接引用这个变量:
LOGGING = { # 保留原有基础配置 'version': 1, 'disable_existing_loggers': True, # 新增过滤器 'filters': { 'inject_app_env': { '()': 'django.utils.log.CallbackFilter', 'callback': lambda record: setattr(record, 'app_env', APP_ENV) or True, }, }, # ... 后续保留原有的formatters、handlers、loggers配置 }
这个过滤器会在每条日志生成时,自动给记录添加app_env属性,值就是你从环境变量获取的APP_ENV。
步骤2:修改日志格式化器,添加环境变量前缀
接下来调整现有的formatters,把[%(app_env)s]添加到日志消息的最前面,这样控制台和文本日志里就能直接看到环境标识:
'formatters': { 'verbose': { 'format': '%(levelname)s %(asctime)s %(module)s %(process)d %(thread)d [%(app_env)s] %(message)s' }, 'simple': { 'format': '%(levelname)s [%(app_env)s] %(message)s' }, },
步骤3:给日志处理器应用过滤器
让所有日志处理器(graypy和console)都用上这个过滤器,确保每条日志都能带上环境变量。同时给graypy添加extra_fields,让Logstash能拿到独立的环境字段:
'handlers': { 'graypy': { 'level': 'INFO', 'class': 'graypy.GELFHandler', 'host': 'logstash...', 'port': 12222, # 应用过滤器 'filters': ['inject_app_env'], # 可选但推荐:给Logstash发送独立的APP_ENV字段,方便直接过滤 'extra_fields': {'app_env': APP_ENV}, }, 'console': { 'level': 'INFO', 'class': 'logging.StreamHandler', 'formatter': 'simple', # 应用过滤器 'filters': ['inject_app_env'], }, },
这里的extra_fields是graypy.GELFHandler的专属参数,它会把app_env作为一个独立字段发送到Logstash,而不是和消息文本混在一起——这样你在Logstash里可以直接用app_env: production这类条件过滤日志,比从消息里解析高效得多。
完整配置示例
修改后的完整LOGGING配置如下(给APP_ENV加了默认值避免空值问题):
import os # 给环境变量加默认值,防止未设置时日志出错 APP_ENV = os.getenv("APP_ENV", "development") LOGGING = { 'version': 1, 'disable_existing_loggers': True, 'filters': { 'inject_app_env': { '()': 'django.utils.log.CallbackFilter', 'callback': lambda record: setattr(record, 'app_env', APP_ENV) or True, }, }, 'formatters': { 'verbose': { 'format': '%(levelname)s %(asctime)s %(module)s %(process)d %(thread)d [%(app_env)s] %(message)s' }, 'simple': { 'format': '%(levelname)s [%(app_env)s] %(message)s' }, }, 'handlers': { 'graypy': { 'level': 'INFO', 'class': 'graypy.GELFHandler', 'host': 'logstash...', 'port': 12222, 'filters': ['inject_app_env'], 'extra_fields': {'app_env': APP_ENV}, }, 'console': { 'level': 'INFO', 'class': 'logging.StreamHandler', 'formatter': 'simple', 'filters': ['inject_app_env'], }, }, 'loggers': { 'django': { 'handlers': ['graypy', 'console'], 'level': 'WARNING' }, 'mts_marketplace': { 'handlers': ['graypy', 'console'], 'level': 'INFO', 'propagate': True, }, 'mts_marketplace.processing': { 'handlers': ['graypy', 'console'], 'level': 'INFO', 'propagate': False, }, 'mts_marketplace.internal_api': { 'handlers': ['graypy', 'console'], 'level': 'INFO', 'propagate': False, }, 'mts_marketplace.trustedgoods': { 'handlers': ['graypy', 'console'], 'level': 'INFO', 'propagate': False, }, 'mts_marketplace.fka': { 'handlers': ['graypy', 'console'], 'level': 'INFO', 'propagate': False, }, }, }
方案优势
- 过滤器注入:确保所有日志记录都能获取到环境变量,不会遗漏任何一条日志
- 可视化前缀:控制台和文本日志直接显示环境标识,方便快速区分不同环境的日志
- 独立字段传输:给Logstash发送单独的
app_env字段,让日志过滤、聚合操作更高效,无需从消息文本中解析环境信息
这样修改后,你的日志消息前会带上[production]或[staging]这类环境标识,同时Logstash也能直接通过app_env字段进行精准过滤。
内容的提问来源于stack exchange,提问作者Fyzzy good
相关产品推荐
相关产品推荐

