Memantau proses render dengan OpenTelemetry
Sekilas pandang
Bagian berjudul “Sekilas pandang”NextPDF menyertakan instrumentasi OpenTelemetry bawaan: 10 trace span dan 7 metrik sepanjang siklus hidup pembuatan Portable Document Format (PDF). Kontraknya: tanpa overhead dan tanpa konfigurasi saat OTel SDK tidak tersedia — tidak ada kegagalan autoload, tidak ada penalti performa. Instal software development kit (SDK), daftarkan TracerProvider/MeterProvider secara global, dan kode yang sama akan otomatis mengekspor data. AttributeSanitizer berbasis allowlist menegakkan Zero-Trust Data Policy, sehingga telemetri tidak pernah membawa konten dokumen maupun informasi yang dapat mengidentifikasi pribadi (PII).
Gunakan halaman ini sebagai pendamping PHP-native untuk konsep OpenTelemetry yang tidak bergantung pada transport. Contoh yang dapat dijalankan beserta tes pendukung mencakup alur ini.
Pemasangan
Bagian berjudul “Pemasangan”composer require nextpdf/core:^3Core saja sudah memberi Anda permukaan instrumentasi yang aman saat berjalan sebagai no-op (no-op-safe). Untuk mengekspor data secara langsung, tambahkan SDK dan satu exporter.
composer require open-telemetry/sdk:^1composer require open-telemetry/exporter-otlp:^1 # or zipkin / prometheusTinjauan konseptual
Bagian berjudul “Tinjauan konseptual”Gunakan dua titik masuk:
TelemetryBridge— facade statis.isAvailable()memeriksa OTel satu kali dan menyimpan hasilnya ke cache.startSpan()/endSpan()/recordMetric()melakukan short-circuit ke no-op saat OTel tidak tersedia. Inilah kontrak tanpa overhead tersebut. Saat OTel tidak tersedia, panggilan-panggilan ini selesai jauh di bawah satu mikrodetik.OpenTelemetryInterceptor— jalur yang terintegrasi dengan SDK. Ia otomatis membuat trace untuk 10 span yang dikenal, mencatat 7 metrik yang dikenal, dan melewatkan setiap atribut melaluiAttributeSanitizer. Ia memeriksa keberadaan SDK saat konstruksi dan menyimpan hasilnya ke cache. Semua referensi kelas OTel berada di balik runtime guard, sehingga kelas tersebut tetap dapat dimuat bahkan tanpa SDK. Batas yang direkomendasikan untukBatchSpanProcessor(maxQueueSize=2048,maxExportBatchSize=512) diekspos sebagai accessor statis.
Ke-10 span tersebut: document.build, font.resolve, html.parse, writer.serialize, image.decode, layout.pass, barcode.encode, form.build, navigation.build, attachment.embed. Ke-7 metrik tersebut: render.duration, render.page_count, render.warnings, render.memory_peak, render.file_size, render.font_count, render.image_count.
AttributeSanitizer hanya menggunakan allowlist. Ia mengizinkan kunci metadata struktural seperti pdf.page_count, pdf.file_size_bytes, pdf.output_profile, dan nextpdf.tier. Ia membuang HTML mentah, stream byte PDF, blob base64, dan jalur sistem berkas tanpa syarat. Ini menerapkan dua poin dari panduan NIST SP 800-92: telemetri tidak boleh membawa konten sensitif, dan kerahasiaan telemetri merupakan kontrol yang eksplisit.
Permukaan API
Bagian berjudul “Permukaan API”Permukaan API (application programming interface) dihasilkan dari PHPDoc pada NextPDF\Telemetry\TelemetryBridge, NextPDF\Telemetry\OpenTelemetryInterceptor, dan NextPDF\Telemetry\AttributeSanitizer. Member utama yang digunakan di bawah ini adalah TelemetryBridge::isAvailable() / startSpan() / endSpan() / recordMetric(); OpenTelemetryInterceptor::knownSpans() / knownMetrics() / maxQueueSize() / maxExportBatchSize(); dan AttributeSanitizer::sanitize().
Contoh kode — Mulai cepat
Bagian berjudul “Contoh kode — Mulai cepat”<?php
declare(strict_types=1);
require_once __DIR__ . '/vendor/autoload.php';
use NextPDF\Core\Document;use NextPDF\Telemetry\TelemetryBridge;
$span = TelemetryBridge::startSpan('document.build', [ 'pdf.page_count' => 1, 'nextpdf.tier' => 'core',]);
$doc = Document::createStandalone();$doc->addPage();$doc->setFont('helvetica', '', 12);$doc->cell(0, 10, 'Observed render');$pdf = $doc->getPdfData();
TelemetryBridge::recordMetric('render.file_size', strlen($pdf), []);TelemetryBridge::endSpan($span); // null-safe when OTel is absent
$doc->save(getenv('NEXTPDF_COOKBOOK_OUTPUT') ?: __DIR__ . '/out.pdf');Contoh kode — Produksi
Bagian berjudul “Contoh kode — Produksi”Contoh lengkap ini membuktikan jalur no-op tanpa overhead karena berjalan tanpa SDK. Contoh ini menguji allowlist sanitizer dan menghormati saluran keluaran harness. Harness reproduktibilitas menjalankan skrip ini dua kali.
<?php
declare(strict_types=1);
require_once __DIR__ . '/vendor/autoload.php';
use NextPDF\Core\Document;use NextPDF\Telemetry\AttributeSanitizer;use NextPDF\Telemetry\OpenTelemetryInterceptor;use NextPDF\Telemetry\TelemetryBridge;
// Discover the surface — static, dependency-free, SDK-optional.$spans = OpenTelemetryInterceptor::knownSpans();$metrics = OpenTelemetryInterceptor::knownMetrics();
// Zero-Trust Data Policy: the sanitizer drops anything off the allowlist// and anything that looks like a payload.$sanitizer = new AttributeSanitizer();$exported = $sanitizer->sanitize([ 'pdf.page_count' => 1, 'pdf.output_profile' => 'PDF/A-4', 'document.raw_html' => '<html><body>secret</body></html>', // dropped 'source.path' => '/var/secret/invoice.pdf', // dropped]);
$span = TelemetryBridge::startSpan('document.build', [ 'pdf.page_count' => 1, 'nextpdf.tier' => 'core',]);
$doc = Document::createStandalone();$doc->setTitle('Observability demo');$doc->addPage();$doc->setFont('helvetica', 'B', 16);$doc->cell(0, 12, 'Observe rendering with OpenTelemetry', newLine: true);$pdf = $doc->getPdfData();
TelemetryBridge::recordMetric('render.page_count', 1, []);TelemetryBridge::recordMetric('render.file_size', strlen($pdf), []);TelemetryBridge::endSpan($span);
$doc->save(getenv('NEXTPDF_COOKBOOK_OUTPUT') ?: __DIR__ . '/out.pdf');
fwrite(STDERR, sprintf( "spans=%d metrics=%d otel_available=%s sanitized_keys=%s\n", count($spans), count($metrics), TelemetryBridge::isAvailable() ? 'yes' : 'no', implode(',', array_keys($exported)),));Kasus tepi & jebakan
Bagian berjudul “Kasus tepi & jebakan”- Telemetri tidak pernah merusak proses render. Baik bridge maupun interceptor meredam kesalahan internalnya sendiri. Exporter yang salah dikonfigurasi menurunkan observabilitas, tetapi tidak pernah merusak keluaran PDF. Jangan membungkus kode render dalam catch yang memperlakukan kegagalan telemetri sebagai kegagalan render.
endSpan(null)aman.startSpan()mengembalikannullsaat OTel tidak tersedia, danendSpan()menerimanullsebagai no-op. Selalu pasangkan keduanya, dan jangan pernah bercabang berdasarkan nilai yang dikembalikannya.- Metrik memerlukan
MeterProvideryang terdaftar. Jika hanyaTracerProvideryang terdaftar, span akan diekspor tetapi metrik dilewati secara diam-diam. Metrik ini bersifat informatif. Daftarkan kedua provider untuk cakupan penuh. - Sanitizer hanya menggunakan allowlist. Kunci atribut baru yang tidak ada di allowlist tidak akan diekspor. Perilaku ini memang dirancang demikian. Perluas allowlist di dalam engine, dan jangan melewati sanitizer.
- Propagasi W3C Trace Context. Propagasi trace lintas layanan menggunakan header W3C Trace Context
traceparent/tracestate. Yang menanganinya adalah propagator OTel SDK, bukan NextPDF. Rekomendasi W3C Trace Context tidak ada di dalam korpus verifikasi, sehingga catatan propagasi ini bersifat RAG-unresolved dan disajikan sebagai panduan integrasi, bukan sebagai klaim normatif. Lihat sidecar. - Peringatan reproduktibilitas. Proses render menghasilkan dokumen dengan
/IDdan tanggal modifikasi yang dibuat ulang setiap kali disimpan (ISO 32000-2 §14.3). PDF yang ditangkap dibandingkan dengan profil semantik, yang hanya mencakup abstract syntax tree (AST) struktural dan metadata.
Performa
Bagian berjudul “Performa”- Jalur tanpa OTel:
isAvailable()disimpan ke cache setelah panggilan pertama. Panggilan span dan metrik berikutnya hanya melakukan satu pemeriksaan boolean, lalu kembali. Contoh yang terinstrumentasi berjalan hingga selesai tanpa SDK. - Dengan OTel: batas
BatchSpanProcessor(maxQueueSize=2048,maxExportBatchSize=512) membatasi memori di bawah beban berkelanjutan, dan ekspor tetap berada di luar hot path. performance_budget(wall_ms: 3000,peak_mb: 128) membatasi proses harness, bukan dokumen arbitrer.- Resep ini memenuhi cakupan gap-list §4.3 untuk #33. Sebelumnya, hanya halaman konsep bergaya MCP yang tersedia, tanpa contoh PHP-native.
examples/33-opentelemetry-observability.phpbaru besertatests/Cookbook/Php/ObserveWithOpenTelemetryRecipeTest.phppendukungnya telah ditulis.
Catatan keamanan
Bagian berjudul “Catatan keamanan”- Telemetri tidak boleh membawa konten dokumen atau PII. Allowlist
AttributeSanitizermenegakkan hal ini di dalam kode. HTML mentah, stream PDF, blob base64, dan jalur sistem berkas dibuang. Ini selaras dengan panduan NIST SP 800-92 tentang menjaga konten sensitif tetap berada di luar log dan telemetri, serta tentang melindungi kerahasiaan telemetri. - Atribut yang Anda tambahkan sendiri tetap tunduk pada allowlist. Anda tetap bertanggung jawab untuk tidak memasukkan nilai sensitif di bawah kunci yang diizinkan. Misalnya, jangan memasukkan pengenal pengguna ke dalam
pdf.output_profile. - Detail diagnostik dibawa oleh kunci terstruktur, bukan payload bebas bentuk. Ini adalah disiplin yang sama yang diterapkan PSR-3 §1.2 pada konteks log.
Kesesuaian
Bagian berjudul “Kesesuaian”| Pernyataan | Spesifikasi | Klausa | reference_id |
|---|---|---|---|
| Telemetri tidak boleh membawa konten sensitif; penanganan PII diwajibkan. | NIST SP 800-92 | §3 | |
| Kerahasiaan telemetri/log merupakan kontrol yang eksplisit. | NIST SP 800-92 | §3 | |
| Kunci konteks terstruktur membawa detail, bukan payload bebas bentuk. | PSR-3 | §1.2 | |
/ID keluaran dan tanggal dibuat ulang setiap kali disimpan → profil semantik. | ISO 32000-2 | §14.3 |
Resep ini menjelaskan perilaku instrumentasi rekayasa. Ia tidak menegaskan sertifikasi kepatuhan apa pun. Referensi NIST SP 800-92 mendasari maksud desain agar konten tidak masuk ke telemetri, bukan klaim kesesuaian.