Telemetry:OpenTelemetry 橋接與無操作備援
Telemetry 模組是引擎可選用的 OpenTelemetry 橋接層。安裝 OpenTelemetry SDK 後,模組會發出帶有已清理屬性的 span 與 metric。若未安裝,完整的無操作 tracer 與 meter 物件會讓檢測呼叫持續有效,且不產生成本。因此,你永遠可以安全地把檢測程式碼留在執行路徑中。
composer require nextpdf/core:^3概念總覽
標題為「概念總覽」的區段設計目標是達成「不存在時零成本」的可觀測性。引擎的熱路徑會無條件呼叫 tracer 與 meter。這些呼叫是否真的執行工作,取決於執行階段,而非每個呼叫點上的條件判斷。
OpenTelemetryInterceptor 就是這層橋接。isAvailable() 會回報 OTel SDK 是否存在。startSpan(string $name, array $attributes = []) / endSpan(?object $span) 會包住一次受追蹤的操作,而 recordMetric() 會記錄計數器或量測值。當 OTel 不存在時,攔截器會回報不可用,這些呼叫也會是惰性的(不執行任何動作)。TelemetryBridge 會把攔截器接到引擎的觀測點上。
AttributeSanitizer 是安全防護層。sanitize(array $attributes) 會在屬性對映離開行程前先清理。遙測屬性是典型的意外 PII 外洩管道,因此屬性清理是合約的一部分,而非附加選項。它、攔截器與橋接層同樣都是 @since 2.3.0。
NullTracer、NullSpanBuilder、NullSpan、NullMeter、NullCounter 與 NullHistogram 是無操作備援。它們實作了與 OTel SDK 所揭露的 API 形狀一致——spanBuilder()、setAttribute()(可鏈式呼叫)、startSpan()、end()、createHistogram()、createUpDownCounter()、add()、record()——但不執行任何動作。由於備援是完整的,受檢測的程式碼不需依可用性分支;它直接呼叫 tracer,而無操作實作會吸收這次呼叫。
API 介面
標題為「API 介面」的區段| 類別 | 主要成員 | 角色 |
|---|---|---|
OpenTelemetryInterceptor | isAvailable(), startSpan(), endSpan(), recordMetric() | OTel span/metric 橋接(@since 2.3.0) |
TelemetryBridge | 引擎接線 | 將攔截器連接到觀測點(@since 2.3.0) |
AttributeSanitizer | sanitize(array $attributes): array | PII 安全的屬性清理器(@since 2.3.0) |
NullTracer | spanBuilder(string $name): NullSpanBuilder | 無操作 tracer |
NullSpanBuilder | setAttribute(), startSpan(): NullSpan | 無操作 span builder(可鏈式呼叫) |
NullSpan | end() | 無操作 span |
NullMeter | createHistogram(), createUpDownCounter() | 無操作 meter |
NullCounter / NullHistogram | add(), record() | 無操作儀器 |
請執行 composer docs:generate-api-php -- --module=Telemetry 取得完整的 PHPDoc 表格。
程式碼範例——快速上手
標題為「程式碼範例——快速上手」的區段來源:examples/33-opentelemetry-observability.php。
<?php
declare(strict_types=1);
require_once __DIR__ . '/../vendor/autoload.php';
use NextPDF\Telemetry\OpenTelemetryInterceptor;
$otel = new OpenTelemetryInterceptor(/* optional OTel tracer/meter */);
$span = $otel->startSpan('pdf.render', ['doc.pages' => 12]);// ... render work ...$otel->endSpan($span);
$otel->recordMetric('pdf.render.bytes', 482_113, ['profile' => 'pdfa4']);在 OTel SDK 不存在時,上面每一次呼叫都是無操作——程式碼完全相同,成本為零。
程式碼範例——正式環境
標題為「程式碼範例——正式環境」的區段用已清理的屬性包覆單次渲染,確保呼叫端提供的中繼資料無法洩漏到 span 中。
<?php
declare(strict_types=1);
require_once __DIR__ . '/../vendor/autoload.php';
use NextPDF\Telemetry\AttributeSanitizer;use NextPDF\Telemetry\OpenTelemetryInterceptor;
final readonly class InstrumentedRenderer{ public function __construct( private OpenTelemetryInterceptor $otel, private AttributeSanitizer $sanitizer, ) {}
/** * @param callable():string $render Returns the rendered PDF bytes. * @param array<string, mixed> $attributes Caller-supplied span attributes. */ public function render(callable $render, array $attributes): string { $span = $this->otel->startSpan('pdf.render', $this->sanitizer->sanitize($attributes));
try { return $render(); } finally { $this->otel->endSpan($span); } }}邊界情況與陷阱
標題為「邊界情況與陷阱」的區段- 無操作備援在設計上就是完整。不要為了「省下工作」而用
isAvailable()來防護檢測。無操作原本就是零成本;這道防護會新增一個分支,而此設計的目的正是消除這個分支。 - 務必先讓呼叫端提供的屬性通過
AttributeSanitizer,再進入 span 或 metric。遙測屬性是 PII 意外外洩的管道。 endSpan(null)是有效的——null span 代表無操作情境。每一次startSpan()都要在finally中搭配一次endSpan()。NullSpanBuilder::setAttribute()會回傳static以供鏈式呼叫;在無操作下,這條鏈是惰性的,這是刻意而為,並非錯誤。- 可重現性設定檔為
structural:span 會帶有時間戳記與 trace id,因此兩次執行在這些欄位上會有所不同。
當 OTel 不存在時,成本只是一個無操作方法呼叫——實務上等於零成本。當 OTel 存在時,成本來自 OTel SDK,而非本模組;橋接層額外增加了屬性清理,其成本與屬性數量成線性關係。1500 ms 牆鐘時間/64 MB 峰值的 performance_budget 是引擎的參考值,而非遙測的 SLA。
安全注意事項
標題為「安全注意事項」的區段遙測是一個資料外送面。AttributeSanitizer 是防止機密與 PII 進入 span 與 metric 的控制機制。任何受呼叫端影響的屬性,都應將清理視為必要;這是本專案的安全遙測義務。OTel 匯出器會把資料送往外部後端。這個後端邊界就是一道信任邊界。端點與憑證請來自機密管理器,而不是已提交(committed)的設定檔。你應假設 span 與 metric 資料會抵達某個日誌接收端。請據此清理。請參閱 /modules/core/security/ 中的引擎威脅模型。
符合性
標題為「符合性」的區段本模組不提出任何 PDF 規範的規範性聲明。它橋接的是 OpenTelemetry 資料模型;那是外部的可觀測性規範,而不是 PDF 條款。無操作備援會鏡映 OTel API 介面,讓受檢測的程式碼具備可攜性;這是 API 相容性特性,而非 PDF 符合性聲明。引擎符合性是透過 /modules/core/conformance/ 中所述的 oracle 與 golden 測試套件驗證。
另請參閱
標題為「另請參閱」的區段- Observability 模組——更廣泛的執行階段狀態面。
- Performance 模組——與遙測搭配的記憶體診斷。
- Contracts / Observability——結構化例外與降級合約。
- 引擎安全模型