Apache通过mod_rewrite的[E=...]设置ENV变量,再结合LogFormat %{env}e和CustomLog env=条件实现动态日志分类归集,支持按接口类型、灰度标识、渠道等多维分流。

在 Apache 中通过 mod_rewrite 结合 ENV 环境变量实现动态日志分类归集,核心在于:利用重写规则在请求处理早期设置环境变量,再将这些变量注入 CustomLog 的日志格式中,从而让同一份访问日志按业务维度(如接口类型、用户角色、灰度标识、来源渠道等)自动分流到不同文件或打上可筛选标记。
一、启用 mod_rewrite 和环境变量支持
确保以下模块已加载(通常在 httpd.conf 或 mods-enabled 中):
LoadModule rewrite_module modules/mod_rewrite.so-
LoadModule env_module modules/mod_env.so(SetEnvIf和UnsetEnv所需)
注意:RewriteRule 的 [E=...] 标志依赖 mod_rewrite 自身对环境变量的支持,无需额外加载 mod_env 即可使用,但复杂条件判断时建议两者配合。
二、用 RewriteRule 设置带业务语义的 ENV 变量
在 VirtualHost、Directory 或 .htaccess 中编写规则,根据 URL、Header、Query 参数等动态设置环境变量。例如:
RewriteEngine On
<h1>按 API 路径分类:/api/v1/users → api_type=users</h1><p>RewriteRule ^/api/v1/users(?:/.*)?$ - [E=api_type:users]</p><h1>按请求头识别灰度流量(如 X-Release: canary)</h1><p>RewriteCond %{HTTP:X-Release} ^canary$
RewriteRule ^ - [E=traffic_class:canary]</p><h1>按 Referer 渠道归类(简化示例)</h1><p>RewriteCond %{HTTP:Referer} (weixin|qq) [NC]
RewriteRule ^ - [E=channel:social]</p><h1>同时设置多个变量(支持链式)</h1><p>RewriteCond %{REQUEST_URI} .js$ [OR]
RewriteCond %{REQUEST_URI} .css$
RewriteRule ^ - [E=asset_type:static,E=cacheable:true]
</p>
每个 [E=key:value] 会将键值对注入 Apache 的内部环境变量空间,后续可在日志格式中引用。
Apache Superset 是一个广泛采用的开源 BI 平台,用于 SQL 探索、图表构建和仪表板交付。当代理需要查询仓库数据、组装仪表板或使用成熟的分析界面解释指标而不是临时笔记本代码时,此技能非常有用。
三、定义动态日志格式并路由到不同文件
使用 LogFormat 定义含 %{env}e 占位符的格式,再结合 SetEnvIf 或 CustomLog 的条件表达式实现分流:
# 定义通用带 ENV 字段的日志格式
LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\" %{api_type}e %{traffic_class}e %{channel}e" enriched
<h1>方式1:单文件统一记录所有 ENV 字段(便于 ELK 后期解析)</h1><p>CustomLog /var/log/apache2/enriched.log enriched</p><h1>方式2:按 ENV 值分流到不同文件(需提前创建目录并授权)</h1><p>SetEnvIf api_type "^users$" users_log
SetEnvIf api_type "^orders$" orders_log
SetEnvIf traffic_class "^canary$" canary_log</p><p>CustomLog /var/log/apache2/api-users.log enriched env=users_log
CustomLog /var/log/apache2/api-orders.log enriched env=orders_log
CustomLog /var/log/apache2/canary-access.log enriched env=canary_log
</p>
注意:env=xxx 表示仅当环境变量 xxx 被设为非空值时才写入该日志;SetEnvIf 可基于任意请求属性匹配并设置开关变量,适合做“路由决策”。
四、进阶技巧:组合判断与默认兜底
实际场景常需多条件组合,或为未匹配请求设置默认分类:
- 用
RewriteCond多行叠加实现 AND 逻辑(默认行为),用[OR]实现 OR - 用
RewriteRule ^ - [E=category:unknown]在规则末尾兜底,避免 ENV 为空导致日志字段缺失 - 对敏感值(如 token、uid)做脱敏再记录:用
RewriteRule提取后设 ENV,或用SetEnvIfNoCase配合正则捕获组(Apache 2.4.13+ 支持%{ENV:VAR}在后续指令中引用) - 避免循环:ENV 变量在重写过程中可被多次覆盖,确保逻辑顺序合理,必要时用
[NS](non-subrequest)或[L]终止匹配
不复杂但容易忽略。









