PHP日志系统支持结构化吗

wen PHP项目 2

本文目录导读:

PHP日志系统支持结构化吗

  1. 使用现代日志库
  2. PHP原生支持(PHP 8.4+)
  3. 自定义结构化日志实现
  4. 框架集成
  5. 结构化日志的优势
  6. 推荐的日志格式(JSON)

是的,PHP日志系统可以支持结构化日志,以下是几种实现方式:

使用现代日志库

Monolog(最流行)

use Monolog\Logger;
use Monolog\Handler\StreamHandler;
use Monolog\Formatter\JsonFormatter;
$log = new Logger('app');
$handler = new StreamHandler('app.log', Logger::WARNING);
$handler->setFormatter(new JsonFormatter());
$log->pushHandler($handler);
// 结构化日志
$log->info('用户登录', [
    'user_id' => 123,
    'ip' => '192.168.1.1',
    'browser' => 'Chrome',
    'timestamp' => date('c')
]);

PHP原生支持(PHP 8.4+)

PHP 8.4 引入了原生结构化日志支持:

// 使用 syslog 的结构化日志
syslog(LOG_INFO, '用户登录', [
    'user_id' => 123,
    'ip' => '192.168.1.1',
    'duration_ms' => 150
]);
// 或者使用 error_log
error_log(json_encode([
    'level' => 'INFO',
    'message' => '用户登录',
    'context' => [
        'user_id' => 123,
        'ip' => '192.168.1.1'
    ]
]));

自定义结构化日志实现

class StructuredLogger {
    private $handler;
    public function log($level, $message, array $context = []) {
        $entry = [
            'timestamp' => date('c'),
            'level' => $level,
            'message' => $message,
            'context' => $context,
            'process_id' => getmypid(),
            'memory_usage' => memory_get_usage(true)
        ];
        // 写入文件
        file_put_contents(
            'app.log',
            json_encode($entry) . PHP_EOL,
            FILE_APPEND | LOCK_EX
        );
    }
    public function info($message, array $context = []) {
        $this->log('INFO', $message, $context);
    }
    public function error($message, array $context = []) {
        $this->log('ERROR', $message, $context);
    }
}

框架集成

Laravel(使用 Monolog)

// config/logging.php
'channels' => [
    'stack' => [
        'driver' => 'stack',
        'channels' => ['daily', 'slack'],
    ],
    'custom' => [
        'driver' => 'single',
        'path' => storage_path('logs/custom.log'),
        'formatter' => Monolog\Formatter\JsonFormatter::class
    ]
]
// 使用
Log::channel('custom')->info('用户操作', [
    'user_id' => auth()->id(),
    'action' => 'update_profile'
]);

Symfony

# config/packages/monolog.yaml
monolog:
    handlers:
        main:
            type: stream
            path: "%kernel.logs_dir%/%kernel.environment%.log"
            formatter: monolog.formatter.json

结构化日志的优势

  • 便于搜索:可以按字段过滤
  • 机器可读:易于 ELK Stack 等工具处理
  • 上下文丰富:包含更多调试信息
  • 性能分析:可以添加执行时间、内存等指标

推荐的日志格式(JSON)

{
    "timestamp": "2024-01-15T10:30:00+08:00",
    "level": "INFO",
    "message": "用户登录成功",
    "channel": "auth",
    "context": {
        "user_id": 123,
        "ip": "192.168.1.1",
        "duration_ms": 150
    },
    "extra": {
        "memory_usage": 8388608,
        "process_id": 12345
    }
}

建议使用 Monolog 这类成熟的库,而不是自己实现,它们提供了更好的性能和更多的功能。

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