phpgo / logging
Execution-scoped structured logging for PHP and Monolog.
Requires
- php: >=8.1
- monolog/monolog: ^3.1
- psr/log: ^3.0
Requires (Dev)
- phpunit/phpunit: ^10.5
Suggests
None
Provides
None
Conflicts
None
Replaces
None
This package is auto-updated.
Last update: 2026-10-09 02:54:07 UTC
README
框架无关的执行上下文与 Monolog 3 Processor。业务层继续使用 Psr\Log\LoggerInterface;本包不定义新的 Logger 接口,也不依赖 Hyperf、Swoole、App\、BASE_PATH 或全局容器。
要求 PHP >= 8.1、Monolog ^3.1、PSR Log ^3.0。
安装
composer require phpgo/logging:^0.1
Hyperf 3.1 项目可直接安装 phpgo/hyperf-logging,它会自动安装本包。
本地安装
把本目录放到目标项目的 packages/logging,合并以下内容到目标项目的 composer.json:
{
"repositories": [
{
"type": "path",
"url": "packages/logging",
"options": {
"symlink": true,
"versions": {"phpgo/logging": "0.1.x-dev"}
}
}
],
"require": {"phpgo/logging": "^0.1@dev"}
}
然后执行 composer update phpgo/logging --no-scripts,提交目标项目的锁文件。部署时使用锁文件安装,确保包目录随代码一同交付;不依赖开发机器上的绝对路径。生产构建可将 path 仓库的 symlink 改为 false,让 Composer 复制源码。
最小示例
<?php declare(strict_types=1); require __DIR__ . '/vendor/autoload.php'; use Monolog\Formatter\JsonFormatter; use Monolog\Handler\StreamHandler; use Monolog\Logger; use PhpGo\Logging\Context\InMemoryContextStorage; use PhpGo\Logging\LogContext; use PhpGo\Logging\LogContextProcessor; $context = new LogContext(new InMemoryContextStorage()); $handler = new StreamHandler('php://stdout', Logger::INFO); $handler->setFormatter(new JsonFormatter(includeStacktraces: true)); $logger = new Logger('billing', [$handler], [ new LogContextProcessor($context, 'invoice-worker', 'production'), ]); $context->run('command', static function () use ($logger): void { $logger->info('invoice.completed', ['invoice_id' => 42]); }, ['task' => 'invoice:generate']);
业务字段保留在 context,公共字段写入 extra。Processor 在每次写入时读取作用域,不缓存单次请求的数据。作用域结束后恢复进入前的上下文;回调异常继续向上传播。
API 与扩展
| 入口 | 职责 |
|---|---|
LogContext::traceId($candidate) |
校验非全零 32 位十六进制 trace ID;无效时生成,小写输出 |
$context->run($type, $callback, $fields) |
建立执行作用域,生成独立 execution ID,返回回调结果并在 finally 中恢复 |
$context->current() |
读取当前作用域;没有作用域时返回空数组 |
$context->enter() / restore() |
用于框架生命周期分散在不同回调中的场景,由适配器配对调用 |
$context->forJob() |
生成仅含 trace_id、job_id 的可序列化元数据 |
Contract\LogAwareJobInterface |
手写任务显式返回日志元数据的契约,不依赖队列实现 |
Attribute\JobLogContext |
标记包含日志元数据的参数,具体队列适配器负责读取 |
扩展方向:
- 切换运行环境:实现
ContextStorageInterface,构造注入LogContext。存储实现负责并发隔离;在 Hyperf 中直接使用 适配包。 - 新增输出渠道:为 Monolog 配置 Handler 或 Formatter,业务层的 PSR-3 调用无需修改。
- 新增公共字段:添加独立 Monolog Processor。内置字段白名单只包含关联信息,不自动导出整个上下文。
InMemoryContextStorage 只用于单执行流、传统同步命令和测试。不要把同一个实例作为协程/Fiber 请求的共享存储;run() 的嵌套恢复不能替代并发隔离。
跨进程传播使用 forJob() 得到的两个 ID。每次任务执行生成新的 execution_id;重试继续使用消息中的 job_id。不得把 Logger、容器、请求对象或连接放入消息。
测试与边界
克隆本包仓库后,在包根目录运行:
composer install
composer test
本包测试不加载 Hyperf 测试引导。使用前述本地 path 仓库开发时,也可在目标项目根目录执行 vendor/bin/phpunit --configuration packages/logging/phpunit.xml.dist。
本包不实现业务异常响应、可靠审计存储、日志传输服务或自动脱敏。Handler 写入失败沿用 Monolog 的异常传播行为。调用方应控制业务 context、异常内容及大小。trace ID 用于日志关联,不等于完整的 OpenTelemetry/W3C Trace Context 实现。
版本变更见 CHANGELOG.md。许可证:MIT。