PHP日志收集用ELK怎么配

wen PHP项目 2

本文目录导读:

PHP日志收集用ELK怎么配

  1. 整体架构
  2. PHP 端配置
  3. Logstash 配置
  4. Elasticsearch 配置
  5. Kibana 配置
  6. Docker Compose 部署示例
  7. PHP 日志规范建议
  8. Kibana 查询示例
  9. 性能优化建议

在 PHP 项目中配置 ELK(Elasticsearch + Logstash + Kibana)进行日志收集,我给您一个完整的配置方案:

整体架构

PHP应用 → 日志文件/直接发送 → Filebeat → Logstash → Elasticsearch → Kibana

PHP 端配置

使用 Monolog(推荐)

// composer require monolog/monolog
use Monolog\Logger;
use Monolog\Handler\SocketHandler;
use Monolog\Formatter\JsonFormatter;
// 创建日志实例
$log = new Logger('php_app');
// 使用 TCP Socket 直接发送到 Logstash
$handler = new SocketHandler("tcp://logstash-host:5000");
$handler->setFormatter(new JsonFormatter());
$log->pushHandler($handler);
// 同时写本地文件备份
$log->pushHandler(new \Monolog\Handler\StreamHandler('/var/log/php/app.log', Logger::DEBUG));
// 使用示例
$log->info('用户登录', ['user_id' => 123, 'ip' => '192.168.1.1']);
$log->error('数据库连接失败', ['db' => 'mysql', 'error' => 'connection refused']);

使用 filebeat 收集日志文件

# filebeat.yml
filebeat.inputs:
- type: log
  enabled: true
  paths:
    - /var/log/php/*.log
  fields:
    app: php_app
    env: production
  fields_under_root: true
output.logstash:
  hosts: ["logstash-host:5044"]

Logstash 配置

接收 Filebeat 日志

# logstash-pipeline.conf
input {
  beats {
    port => 5044
    client_inactivity_timeout => 3600
  }
}
filter {
  if [fields][app] == "php_app" {
    # 解析 JSON 日志
    json {
      source => "message"
      target => "php_log"
      remove_field => ["message"]
    }
    # 添加时间戳
    date {
      match => ["timestamp", "ISO8601"]
      target => "@timestamp"
    }
    # 解析 PHP 错误信息
    grok {
      match => { "message" => "\[%{TIMESTAMP_ISO8601:log_time}\] %{LOGLEVEL:log_level} %{GREEDYDATA:log_message}" }
      tag_on_failure => []
    }
    # 解析 IP 地址地理位置
    geoip {
      source => "[php_log][ip]"
      target => "geoip"
      add_field => ["geoip", "geo"]
    }
  }
}
output {
  elasticsearch {
    hosts => ["elasticsearch:9200"]
    index => "php-logs-%{+YYYY.MM.dd}"
    user => "elastic"
    password => "your_password"
  }
}

直接接收 PHP Socket

input {
  tcp {
    port => 5000
    type => "php-json"
    codec => json_lines
  }
}
filter {
  if [type] == "php-json" {
    json {
      source => "message"
      target => "php_log"
    }
  }
}
output {
  elasticsearch {
    hosts => ["elasticsearch:9200"]
    index => "php-logs-%{+YYYY.MM.dd}"
  }
}

Elasticsearch 配置

# elasticsearch.yml
cluster.name: "production-cluster"
node.name: "es-node-1"
network.host: 0.0.0.0
http.port: 9200
discovery.type: single-node
# 安全配置(推荐生产环境启用)
xpack.security.enabled: true
xpack.security.transport.ssl.enabled: true

Kibana 配置

# kibana.yml
server.port: 5601
server.host: "0.0.0.0"
elasticsearch.hosts: ["http://elasticsearch:9200"]
elasticsearch.username: "kibana_system"
elasticsearch.password: "your_password"
# 设置默认索引模式
kibana.defaultAppId: "discover"

Docker Compose 部署示例

# docker-compose.yml
version: '3.8'
services:
  elasticsearch:
    image: docker.elastic.co/elasticsearch/elasticsearch:7.15.0
    environment:
      - discovery.type=single-node
      - ES_JAVA_OPTS=-Xms512m -Xmx512m
    ports:
      - "9200:9200"
    volumes:
      - es_data:/usr/share/elasticsearch/data
  logstash:
    image: docker.elastic.co/logstash/logstash:7.15.0
    volumes:
      - ./logstash/:/usr/share/logstash/pipeline/
    ports:
      - "5044:5044"
      - "5000:5000"
    environment:
      - LS_JAVA_OPTS=-Xms256m -Xmx256m
  kibana:
    image: docker.elastic.co/kibana/kibana:7.15.0
    ports:
      - "5601:5601"
    environment:
      - ELASTICSEARCH_HOSTS=http://elasticsearch:9200
    depends_on:
      - elasticsearch
  filebeat:
    image: docker.elastic.co/beats/filebeat:7.15.0
    volumes:
      - ./filebeat.yml:/usr/share/filebeat/filebeat.yml:ro
      - /var/log/php:/var/log/php:ro
volumes:
  es_data:

PHP 日志规范建议

// 统一日志格式
class LogManager {
    public static function info($message, $context = []) {
        $logData = [
            'timestamp' => date('c'),
            'level' => 'INFO',
            'message' => $message,
            'context' => $context,
            'request_id' => uniqid(),
            'user_agent' => $_SERVER['HTTP_USER_AGENT'] ?? '',
            'request_ip' => $_SERVER['REMOTE_ADDR'] ?? '',
            'request_uri' => $_SERVER['REQUEST_URI'] ?? '',
            'method' => $_SERVER['REQUEST_METHOD'] ?? '',
            'execution_time' => microtime(true) - PHP_APP_START_TIME ?? 0
        ];
        return $logData;
    }
}

Kibana 查询示例

// 查询特定应用日志
{
  "query": {
    "bool": {
      "must": [
        { "match": { "php_log.level": "ERROR" } },
        { "term": { "app": "php_app" } }
      ],
      "filter": [
        { "range": { "@timestamp": { "gte": "now-1h" } } }
      ]
    }
  }
}

性能优化建议

  1. 批量发送:使用 MonologBufferHandler 批量发送日志
  2. 异步记录:使用 消息队列 如 RabbitMQ 做缓冲
  3. 索引管理:设置 ILM(Index Lifecycle Management)策略
  4. 日志分级:生产环境只记录 WARNING 级别以上

这样配置后,你可以:

  • 实时搜索 PHP 应用日志
  • 可视化错误率和请求量
  • 设置告警规则
  • 快速定位问题

需要我详细解释某个部分吗?

抱歉,评论功能暂时关闭!