本文目录导读:

是的,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 这类成熟的库,而不是自己实现,它们提供了更好的性能和更多的功能。