thinkphp本身不支持二级域名日志自动分离,需通过动态设置log.path按子域名隔离写入,logstash用dissect从路径提取subdomain打标,kibana据此字段实现多域名筛选与趋势对比。

ThinkPHP 本身不直接支持二级域名日志的自动分离,要实现 ELK(Elasticsearch + Logstash + Kibana)对多个二级域名(如 user.example.com、admin.example.com)的日志进行独立采集与可视化分析,关键在于让日志文件按域名区分写入,并在 Logstash 中正确解析和打标。以下是可落地的操作路径。
1. ThinkPHP 日志按二级域名分离写入
默认情况下,ThinkPHP 将所有请求日志写入同一个文件(如 runtime/log/2024/xx.log),无法区分来源域名。需在应用初始化阶段动态设置日志目录或文件名:
- 在
app/common.php或app/middleware.php中获取当前请求的 Host:$host = $_SERVER['HTTP_HOST'] ?? 'default';
提取二级域名前缀(如user.example.com→user):$subdomain = explode('.', $host)[0] ?? 'default'; - 重写日志驱动配置(以 File 驱动为例):
Log::setConfig(['path' => runtime_path() . 'log/' . $subdomain . '/']);
或更精细地指定文件名:Log::setConfig(['file' => runtime_path() . 'log/' . $subdomain . '_'.date('Y-m-d').'.log']); - 确保
runtime/log/下各子目录有写入权限,且 Nginx/Apache 日志用户(如 www-data)能读取这些文件。
2. Logstash 按域名目录采集并打标
Logstash 不支持直接“识别二级域名”,但可通过文件路径反推来源。配置示例(logstash.conf):
- 使用
file插件监听多个子目录:path => "/var/www/example.com/runtime/log/*/2024-*.log" - 用
dissect或grok从文件路径提取 subdomain:dissect { mapping => { "path" => "/var/www/example.com/runtime/log/%{subdomain}/%{+date}.log" } } - 添加字段便于 Kibana 过滤:
mutate { add_field => { "domain_type" => "%{subdomain}" } } - 输出到 Elasticsearch 时,可将
domain_type作为索引前缀(如logs-%{subdomain}-%{+YYYY.MM.dd}),或统一索引 + 字段过滤。
3. Kibana 中按二级域名筛选与对比
日志进入 ES 后,domain_type 字段即可用于多维度分析:
- 创建 Dashboard 时,添加 Filter 控件,选择
domain_type字段,支持多选(如同时看 user 和 api 的错误率) - 用 TSVB 或 Lens 图表,X 轴为时间,Y 轴为 count,Split series 选
domain_type,直观对比各子站请求量/5xx 错误趋势 - 保存常用搜索:例如
domain_type: "admin" AND level: "error",一键跳转排查后台异常
4. 补充建议:避免日志混杂与性能干扰
实际部署中容易忽略的细节:
- ThinkPHP 日志等级建议设为
notice或warn,避免 debug 级别淹没关键信息;可在不同子域启用不同等级(如 admin 域开启 debug,user 域只记 error) - Logstash 的
sincedb_path需为每个子目录单独配置,防止跨目录位点错乱;推荐用sincedb_path => "/var/lib/logstash/.sincedb_${subdomain}" - 若使用 Docker 部署 ELK,确保 Logstash 容器挂载了完整的
runtime/log/目录,且路径映射一致
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











