跳转到内容

可观测性:哈希链式 SIEM 日志与渲染报告

可观测性模块是运行时状态的实现:防篡改的哈希链式 SIEM 事件日志、渲染与试行报告汇总、HSM 审计日志,以及一整套无操作的 metrics 与 trace 实现,让检测接口随时都可调用。

每项主题只有一个正式页面。 可观测性契约—— ContextAwareExceptionInterfaceSpectrumInterfaceJobNotificationInterface,以及 DegradationPolicy 枚举——记载于 Contracts / Observability。本页记录具体的运行时状态实现。两者互为补充,而非重复:契约页说明 SPI,本页说明 SIEM 日志、报告与审计接口。

Terminal window
composer require nextpdf/core:^3

本模块负责将引擎的运行时状态转化为持久且可验证的输出。

HashChainSiemEventLog 是安全级别的接口。它实现 SiemEventEmitter 契约,并写入 JSON-Lines 日志,其中每条记录的哈希值为 SHA-256(prev_hash_bytes || canonical_event_bytes)。这种线性哈希链让日志具备防篡改能力:篡改任何字节、删除某一行或重新排序各行,都会破坏这条链。verifyIntegrity() 会遍历整个文件,并返回第一条不一致记录的索引;如果链完整无缺,则返回 nullreadAll() 会以流式方式读取各条记录。每个进程使用的建议性 flock(LOCK_EX) 会围住“读取尾部后再追加”这段临界区,避免同一文件上的并行 PHP 进程交错写入记录。该设计清楚说明了自身边界:它是线性哈希链,而不是 RFC 6962 Merkle 树——足以提供防篡改性,但不足以提供高效的包含性证明。源代码也已如此说明。SiemEvent 通过 toCanonicalJson() 携带类型化事件。SiemEventSeveritySiemEventType 对其进行分类。CorrelationContextCorrelationIdGenerator 会将关联 ID 贯穿相关事件。

RenderReportBuilderRenderReportPilotReportAggregatorPilotSummary 是报告接口(@since 5.1.0)。汇总器会收集多个 RenderReport,并生成一份 PilotSummary,可渲染为数组、JSON 或 Markdown——也就是运维审查所采用的格式。

HsmAuditLogInterface / HsmAuditEvent 会为安全层记录由 HSM 支撑的签署作业。MetricsCounterInterfaceMetricsGaugeInterfaceMetricsHistogramInterfaceTraceSpanInterface 定义 metrics/trace 的形态。NoOp* 实现提供一套完整的惰性后备,让引擎在未配置后端的情况下仍可发出 metrics 与 span。

稳定度:实验性。 SIEM 日志在内部以周期标记, 而非携带冻结的 semver @since,而报告接口则为 @since 5.1.0。这些接口已可运行且经过测试,但 API 形态仍可能演进。请将日志格式(规范 JSON 加哈希链)视为稳定契约,并将 PHP API 视为仍在定形中。

类别主要成员角色
HashChainSiemEventLogemit(SiemEvent)verifyIntegrity(): ?intreadAll(): Generator防篡改的哈希链式 SIEM 日志
SiemEventtoCanonicalJson()型别化的 SIEM 事件
SiemEventSeverity / SiemEventType(枚举)分类事件严重度与类型
CorrelationContext / CorrelationIdGenerator关联串接关联相关事件
RenderReportBuilder / RenderReport报告组装单次渲染报告(@since 5.1.0
PilotReportAggregatoraddReport()count()getSummary()toJson()toMarkdown()exportReportsJson()汇总渲染报告(@since 5.1.0
PilotSummarytoArray()toJson()toMarkdown()运维审查摘要(@since 5.1.0
HsmAuditLogInterface / HsmAuditEventHSM 审计记录HSM 作业审计日志
NoOpSiemEventEmitterNoOpMetricsCounterNoOpTraceSpan、…惰性后备完整的无操作实现

执行 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 与黄金套件验证。