本文目录导读:

对于PHP项目的微服务日志集中采集、分析和检索,推荐采用 ELK/EFK(Elasticsearch + Logstash/Fluentd + Kibana) 或 Grafana + Loki 这类开源方案,以下是完整的实施指南:
整体架构方案
[PHP微服务A] --日志--> [Filebeat/Logstash]
[PHP微服务B] --日志--> [Filebeat/Logstash]
[PHP微服务C] --日志--> [Filebeat/Logstash]
↓
[消息队列] (可选: Kafka/Redis)
↓
[Logstash/Fluentd] (解析/过滤)
↓
[Elasticsearch] (存储/索引)
↓
[Kibana/Grafana] (可视化/检索)
PHP端日志规范
统一日志格式(推荐JSON)
// 使用 Monolog 库
use Monolog\Logger;
use Monolog\Handler\StreamHandler;
use Monolog\Formatter\JsonFormatter;
$logger = new Logger('order-service');
$handler = new StreamHandler('/var/log/app/order.log');
$handler->setFormatter(new JsonFormatter());
$logger->pushHandler($handler);
// 记录结构化日志
$logger->info('订单创建成功', [
'order_id' => 12345,
'user_id' => 67890,
'amount' => 99.99,
'trace_id' => getenv('TRACE_ID'), // 链路追踪ID
'span_id' => uniqid(),
'service' => 'order-service',
'env' => 'production'
]);
必须包含的字段
{
"@timestamp": "2024-01-15T10:30:00+08:00",
"level": "INFO",
"service": "order-service",
"instance": "pod-instance-1",
"trace_id": "abc123...",
"request_id": "req-001",
"message": "订单创建成功",
"context": {
"order_id": 12345,
"user_id": 67890
},
"exception": null, // 异常堆栈
"duration_ms": 235, // 请求耗时
"method": "POST",
"path": "/api/orders"
}
日志采集方案
方案1:轻量级 - Filebeat + Elasticsearch
# filebeat.yml
filebeat.inputs:
- type: log
enabled: true
paths:
- /var/log/app/*.log
json.keys_under_root: true
json.overwrite_keys: true
fields:
service: order-service
env: production
output.elasticsearch:
hosts: ["http://elasticsearch:9200"]
index: "%{[fields.service]}-%{+yyyy.MM.dd}"
方案2:高吞吐 - Filebeat + Kafka + Logstash
# filebeat.yml
output.kafka:
hosts: ["kafka:9092"]
topic: php-logs
partition.round_robin:
reachable_only: true
# logstash.conf
input {
kafka {
bootstrap_servers => "kafka:9092"
topics => ["php-logs"]
codec => json
}
}
filter {
mutate {
add_field => { "[@metadata][index]" => "%{[service]}-%{+YYYY.MM.dd}" }
}
}
output {
elasticsearch {
hosts => ["http://elasticsearch:9200"]
index => "%{[@metadata][index]}"
}
}
方案3:容器化环境 - 使用Sidecar模式
# docker-compose.yml
services:
php-app:
image: php-app
volumes:
- app-logs:/var/log/app
filebeat:
image: docker.elastic.co/beats/filebeat:8.11.0
user: root
volumes:
- app-logs:/var/log/app
- ./filebeat.yml:/usr/share/filebeat/filebeat.yml:ro
depends_on:
- elasticsearch
volumes:
app-logs:
日志检索与优化
Elasticsearch索引模板
PUT _template/php_logs_template
{
"index_patterns": ["*-*.*.*"],
"settings": {
"number_of_shards": 3,
"number_of_replicas": 1,
"refresh_interval": "5s"
},
"mappings": {
"properties": {
"@timestamp": { "type": "date" },
"level": { "type": "keyword" },
"service": { "type": "keyword" },
"instance": { "type": "keyword" },
"trace_id": {
"type": "text",
"fields": {
"keyword": { "type": "keyword" }
}
},
"message": { "type": "text" },
"duration_ms": { "type": "long" },
"exception": { "type": "text" }
}
}
}
Kibana常用检索
- 按服务查询:
service: "order-service" - 按耗时排序:
duration_ms > 1000 - 错误日志:
level: "ERROR" OR level: "CRITICAL" - 链路追踪:
trace_id: "abc123..." - 时间段:
@timestamp >= "now-1h"
监控与告警
Elasticsearch Watcher告警
{
"trigger": {
"schedule": { "interval": "5m" }
},
"input": {
"search": {
"request": {
"indices": ["*"],
"body": {
"query": {
"bool": {
"must": [
{ "term": { "level": "ERROR" } },
{ "range": { "@timestamp": { "gte": "now-5m" } } }
]
}
}
}
}
}
},
"actions": {
"email_admin": {
"email": {
"to": ["admin@company.com"],
"subject": "错误日志告警",
"body": "最近5分钟产生 {{ctx.payload.hits.total}} 条错误日志"
}
}
}
}
基于Logstash的异常检测
# logstash filter
filter {
if [level] == "ERROR" {
elasticsearch {
hosts => ["http://elasticsearch:9200"]
query => "level:ERROR AND service:%{[service]}"
fields => { "count" => "[hits][total]" }
}
if [count] > 100 {
metrics { meter => { "error_rate" => "%{[service]}" } }
}
}
}
生产环境注意事项
日志安全与合规
-
敏感信息脱敏: 在Monolog中使用处理器过滤密码、手机号等
$processor = new \Monolog\Processor\MaskingProcessor([ 'password', 'credit_card', 'phone' ]); $logger->pushProcessor($processor);
-
日志访问控制: Elasticsearch配置RBAC权限
性能优化
- 异步写日志: 使用Monolog的BufferHandler批量写入
- 日志轮转: 配置logrotate或Docker日志驱动
- 采样策略: 高并发场景下对debug日志采样
成本控制
- 冷热数据分层: 超过7天的日志迁移到冷节点
- 索引生命周期:
PUT _ilm/policy/php_logs_policy { "policy": { "phases": { "hot": { "min_age": "0d", "actions": { "rollover": { "max_size": "50GB" } } }, "warm": { "min_age": "3d", "actions": { "allocate": { "require": { "data": "warm" } } } }, "delete": { "min_age": "30d", "actions": { "delete": {} } } } } }
推荐替代方案
| 方案 | 适用场景 | 优点 | 缺点 |
|---|---|---|---|
| ELK | 复杂检索、大集群 | 功能强大,生态完善 | 资源消耗较高 |
| Loki + Grafana | 轻量级、成本敏感 | 占用资源少,与K8s集成好 | 检索功能较弱 |
| Datadog | 预算充足的企业 | SaaS服务,开箱即用 | 成本高 |
| Graylog | 中小团队 | 比ELK更简单,Web界面友好 | 扩展性不如ELK |
最终建议
- 小规模(<5个服务): 使用 Loki + Promtail + Grafana,最低配置2核4G即可运行
- 中大规模: 采用 ELK 或 EFK,建议加上Kafka做缓冲
- Kubernetes环境: 使用 Loki 的Helm Chart,配置简单
- 必须标准化: PHP端统一使用Monolog输出JSON格式日志
- 优先实现: 链路追踪ID、请求耗时、服务名这三个核心字段
实施时建议先从1-2个服务做试点,验证架构可行性后再推广到全部微服务。
版权声明:NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播