fiberphp / log
FiberPHP log package: multi-channel Monolog logger with trace_id injection and sensitive field masking.
Requires
- php: >=8.3
- fiberphp/framework: dev-master
- monolog/monolog: ^3.0
Requires (Dev)
- phpunit/phpunit: ^11.0
This package is auto-updated.
Last update: 2026-08-22 08:11:20 UTC
README
FiberPHP 框架的日志子包。基于 Monolog 实现,提供多通道日志管理、trace_id 自动注入、敏感字段脱敏,并以 PSR-3 LoggerInterface 接入容器,由 framework 的 logger() 全局函数统一调度。
特性
- 多通道:通过
config/log.php声明任意通道(默认 / error / access / db …),按需懒创建。 - PSR-3 契约:实现
LoggerInterface,可直接作为依赖注入;logger()返回本实例。 - Trace 注入:自动写入
trace_id/span_id/app_name到extra字段(依赖 frameworkContext)。 - 敏感字段脱敏:
password/token/secret/mobile/id_card等键值递归脱敏,可配置。 - JSON 行格式:默认
RotatingFileHandler+JsonFormatter,按天轮转,便于采集。 - Master 阶段接管:可选注入
RegisterMasterLoggerbootstrap,让 fork 前的致命错误也走应用配置而非 framework 兜底。
环境要求
- PHP >= 8.3
ext-json/ext-mbstringmonolog/monolog^3.0psr/log^3.0fiberphp/frameworkdev-master
安装
composer require fiberphp/log
安装后 PackageInstaller::discover 会自动把 config/log.php 拷贝到应用 config/log.php(幂等,已存在不覆盖),并通过 PackageManifest 注册 LogProvider,无需手动配置。
配置
config/log.php:
return [
// 默认日志通道
'default' => [
'constructor' => [
'path' => runtime_path() . '/logs/app.log',
'max_files' => 7, // 保留天数
'level' => Level::Info,
],
],
// 按需声明更多通道(error / access / db 等业务通道由应用层定义)
// 'error' => [
// 'constructor' => ['path' => runtime_path() . '/logs/error.log', 'level' => Level::Warning],
// ],
// 脱敏配置
'masking' => [
'enabled' => true,
'fields' => ['password', 'token', 'secret', 'key', 'credential',
'auth', 'passwd', 'mobile', 'phone', 'email',
'id_card', 'bank_card'],
'mask' => '******',
],
];
每个通道键名 = Log::channel($name) 的入参,未命中的通道名回退到 default。
constructor 字段:
path— 日志文件绝对路径,未指定时回退runtime/logs/{channel}.logmax_files—RotatingFileHandler保留天数,默认 7level— MonologLevelenum(如Level::Info),默认Level::Debug
processors 字段(可选):
- 字符串形式:
'processors' => [SomeProcessor::class],要求类有无参构造 - 数组形式:
'processors' => [['class' => SomeProcessor::class, 'constructor' => [/* args */]]]
使用
基本调用
// framework 全局 helper(推荐)
logger()->info('user login', ['user_id' => 123]);
logger()->error('db query failed', ['sql' => $sql]);
// 容器注入
use Psr\Log\LoggerInterface;
class MyService
{
public function __construct(private LoggerInterface $logger) {}
}
trace_id 注入
依赖 framework 的 Context 协程级隔离:
Context::set('trace_id', $requestId);
Context::set('span_id', $spanId);
logger()->info('hello'); // 自动写入 extra.trace_id / extra.span_id
Master 阶段接管(可选)
让 fork 前的致命错误也走应用配置(而非 framework 兜底 Logger::make('app'))。
在 config/app.php 注入 RegisterMasterLogger bootstrap:
return [
'master_bootstrap' => [
'enableErrors',
'loadEnv',
\FiberPHP\Log\Bootstrap\RegisterMasterLogger::class, // 提前绑 Log 单例
'registerMasterErrors',
'setRuntime',
'ensureLogDir',
],
];
注入后 master fatal handler 调用 logger() 时容器已有 Log 单例。
通道运行时切换
// 显式指定通道(需在 config/log.php 声明该通道,否则回退 default)
logger()->channel('http')->info('GET /api/users');
// 未声明的通道名回退到 default
logger()->channel('unknown')->info('fallback'); // 实际写入 app.log
子包日志通道约定
fiberphp/redis、fiberphp/http、fiberphp/event 等子包默认使用 default 通道(与应用日志同文件,靠 trace_id 关联)。
若需将某子包日志独立分文件,在 config/log.php 声明与包名同名的通道即可自动启用:
// config/log.php —— 声明后,redis 子包自动切到该通道
'redis' => [
'constructor' => [
'path' => runtime_path() . '/logs/redis.log',
'level' => Level::Warning,
],
],
子包内部通过 config('log.{包名}') 检测:声明了用独立通道,未声明走 default。无需在子包配置中指定通道名。
脱敏扩展
自定义敏感字段:
// config/log.php
'masking' => [
'enabled' => true,
'fields' => ['password', 'token', 'id_card', 'phone'],
'mask' => '******',
],
运行时清除缓存(如配置热更新后):
\FiberPHP\Log\Log::clearMaskingCache();
与 framework 兜底的对比
| 项 | framework Logger(兜底) | fiberphp/log Log |
|---|---|---|
| 实现层次 | 最小 PSR-3 + 文件 size 轮转 | Monolog 完整生态 |
| 通道 | 单文件 runtime/logs/{channel}.log | 多通道独立配置 + 处理器链 |
| Trace | 不支持 | trace_id / span_id / app_name 自动注入 |
| 脱敏 | 不支持 | 递归敏感字段脱敏 |
| 格式 | 固定 JSON 行 | JsonFormatter(可换) |
| 注入方式 | Logger::make($channel) | 容器 LoggerInterface 绑定 |
只要 LogProvider::register() 执行,framework 的 logger() 会优先返回本包 Log 实例;未安装本包时自动回落 framework Logger,零侵入。
License
MIT