可观测性:哈希链式 SIEM 日志与渲染报告
可观测性模块是运行时状态的实现:防篡改的哈希链式 SIEM 事件日志、渲染与试行报告汇总、HSM 审计日志,以及一整套无操作的 metrics 与 trace 实现,让检测接口随时都可调用。
每项主题只有一个正式页面。 可观测性契约——
ContextAwareExceptionInterface、SpectrumInterface、JobNotificationInterface,以及DegradationPolicy枚举——记载于 Contracts / Observability。本页记录具体的运行时状态实现。两者互为补充,而非重复:契约页说明 SPI,本页说明 SIEM 日志、报告与审计接口。
composer require nextpdf/core:^3概念概览
标题为“概念概览”的章节本模块负责将引擎的运行时状态转化为持久且可验证的输出。
HashChainSiemEventLog 是安全级别的接口。它实现 SiemEventEmitter 契约,并写入 JSON-Lines 日志,其中每条记录的哈希值为 SHA-256(prev_hash_bytes || canonical_event_bytes)。这种线性哈希链让日志具备防篡改能力:篡改任何字节、删除某一行或重新排序各行,都会破坏这条链。verifyIntegrity() 会遍历整个文件,并返回第一条不一致记录的索引;如果链完整无缺,则返回 null。readAll() 会以流式方式读取各条记录。每个进程使用的建议性 flock(LOCK_EX) 会围住“读取尾部后再追加”这段临界区,避免同一文件上的并行 PHP 进程交错写入记录。该设计清楚说明了自身边界:它是线性哈希链,而不是 RFC 6962 Merkle 树——足以提供防篡改性,但不足以提供高效的包含性证明。源代码也已如此说明。SiemEvent 通过 toCanonicalJson() 携带类型化事件。SiemEventSeverity 与 SiemEventType 对其进行分类。CorrelationContext 与 CorrelationIdGenerator 会将关联 ID 贯穿相关事件。
RenderReportBuilder、RenderReport、PilotReportAggregator 与 PilotSummary 是报告接口(@since 5.1.0)。汇总器会收集多个 RenderReport,并生成一份 PilotSummary,可渲染为数组、JSON 或 Markdown——也就是运维审查所采用的格式。
HsmAuditLogInterface / HsmAuditEvent 会为安全层记录由 HSM 支撑的签署作业。MetricsCounterInterface、MetricsGaugeInterface、MetricsHistogramInterface 与 TraceSpanInterface 定义 metrics/trace 的形态。NoOp* 实现提供一套完整的惰性后备,让引擎在未配置后端的情况下仍可发出 metrics 与 span。
稳定度:实验性。 SIEM 日志在内部以周期标记, 而非携带冻结的 semver
@since,而报告接口则为@since 5.1.0。这些接口已可运行且经过测试,但 API 形态仍可能演进。请将日志格式(规范 JSON 加哈希链)视为稳定契约,并将 PHP API 视为仍在定形中。
API 接口
标题为“API 接口”的章节| 类别 | 主要成员 | 角色 |
|---|---|---|
HashChainSiemEventLog | emit(SiemEvent)、verifyIntegrity(): ?int、readAll(): Generator | 防篡改的哈希链式 SIEM 日志 |
SiemEvent | toCanonicalJson() | 型别化的 SIEM 事件 |
SiemEventSeverity / SiemEventType(枚举) | 分类 | 事件严重度与类型 |
CorrelationContext / CorrelationIdGenerator | 关联串接 | 关联相关事件 |
RenderReportBuilder / RenderReport | 报告组装 | 单次渲染报告(@since 5.1.0) |
PilotReportAggregator | addReport()、count()、getSummary()、toJson()、toMarkdown()、exportReportsJson() | 汇总渲染报告(@since 5.1.0) |
PilotSummary | toArray()、toJson()、toMarkdown() | 运维审查摘要(@since 5.1.0) |
HsmAuditLogInterface / HsmAuditEvent | HSM 审计记录 | HSM 作业审计日志 |
NoOpSiemEventEmitter、NoOpMetricsCounter、NoOpTraceSpan、… | 惰性后备 | 完整的无操作实现 |
执行 composer docs:generate-api-php -- --module=Observability 以取得完整的 PHPDoc 表格。
代码范例——快速上手
标题为“代码范例——快速上手”的章节发出一个事件,并验证日志完整性。
<?php
declare(strict_types=1);
require_once __DIR__ . '/../vendor/autoload.php';
use NextPDF\Observability\Siem\HashChainSiemEventLog;use NextPDF\Observability\Siem\SiemEvent;
$log = new HashChainSiemEventLog('/var/log/nextpdf/siem.jsonl');$log->emit(new SiemEvent(/* type, severity, payload */));
$firstBroken = $log->verifyIntegrity();echo $firstBroken === null ? "SIEM chain intact.\n" : "Tamper detected at record {$firstBroken}.\n";代码范例——生产环境
标题为“代码范例——生产环境”的章节包装发送器,让签署热路径中的日志写入失败变成本地决策,而不是未被捕获的异常。
<?php
declare(strict_types=1);
require_once __DIR__ . '/../vendor/autoload.php';
use NextPDF\Observability\Siem\HashChainSiemEventLog;use NextPDF\Observability\Siem\Exception\SiemEmitterException;use NextPDF\Observability\Siem\SiemEvent;use Psr\Log\LoggerInterface;
final readonly class AuditedSiemSink{ public function __construct( private HashChainSiemEventLog $log, private LoggerInterface $fallback, ) {}
public function record(SiemEvent $event): void { try { $this->log->emit($event); } catch (SiemEmitterException $e) { // Do not let SIEM I/O abort the signing path; record and continue. $this->fallback->critical('SIEM emit failed; event not chained.', [ 'error' => $e->getMessage(), ]); } }}边界情况与陷阱
标题为“边界情况与陷阱”的章节- 写入发生错误时,
emit()会抛出SiemEmitterException。位于签署热路径的调用方必须加以包装,并在本地决定是吞掉、重试还是中止。发送器不会替你决定。 verifyIntegrity()会返回第一条损坏记录的索引,或返回null。非 null 的结果表示日志自该点起已遭破坏——请勿信任该点及其之后的记录。- 建议性
flock以进程为粒度,并且只作用于同一文件。跨主机并行需要一个带外接收端(转送至 syslog)。请勿假设文件锁能在多台机器之间协调。 - 这是线性哈希链,并非 Merkle 树。它证明的是防篡改性,而不是高效的包含性证明。请勿将其宣传为后者。
NoOp*后备是完整且惰性的。请勿为了“省下工作”而根据后端是否可用来分支——无操作本身已经不耗任何成本。
emit() 会读取前一条记录的哈希值,并在文件锁下追加一行——每个事件为 O(1),外加该锁。verifyIntegrity() 因为要遍历整条链,所以复杂度是记录数的 O(n)。请排程执行它,而不要放在热路径中。报告汇总与报告数量呈线性关系。可重现性特征是 structural(结构性)的:事件与报告携带时间戳和关联 ID,因此两次执行会在这些字段上有所不同,而链结构是确定性的。
安全注意事项
标题为“安全注意事项”的章节SIEM 日志是一项安全控制。它的防篡改性取决于日志文件与验证步骤是否受到保护:请将文件存放在适合追加写入、具备访问控制的存储上,排程执行 verifyIntegrity(),并将记录带外转送,使主机遭入侵时无法悄然改写历史。事件可能携带敏感上下文。请在事件构建之前,而不是链结之后,应用项目的日志清洗要求,因为清洗后的重写会破坏这条链。HSM 审计日志会记录签署作业,本身即与安全相关。请以相同的保护措施对待它。请参阅 /modules/core/security/ 中的引擎威胁模型。
符合性
标题为“符合性”的章节本模块未提出任何 PDF 规范的规范性主张。它实现的日志完整性与可观测性机制,其设计与 NIST SP 800-92 中的日志管理与完整性验证实践一致——这是源代码所记录的控制框架对齐,而不是按区块钉选的 PDF 引用。引擎所生成文件的符合性,则由 /modules/core/conformance/ 所述的 oracle 与黄金套件验证。
另请参阅
标题为“另请参阅”的章节- Contracts / Observability——SPI(结构化异常、Spectrum、降级策略)。
- Telemetry module——将数据馈送至外部后端的 OpenTelemetry 桥接。
- Audit module——与 SIEM 日志搭配的合规证据汇出器。
- Security module——HSM 审计日志所记录的签署作业。
- Conformance overview