Rendering observeren met OpenTelemetry
In één oogopslag
Sectie met titel “In één oogopslag”NextPDF bevat ingebouwde OpenTelemetry-instrumentatie: 10 trace-spans en 7 metrics voor de volledige generatielevenscyclus van het Portable Document Format (PDF). Het contract is nul overhead en nul configuratie wanneer de OTel-SDK ontbreekt — geen autoload-fout, geen prestatieverlies. Installeer de software development kit (SDK), registreer globaal een TracerProvider/MeterProvider, en dezelfde code exporteert automatisch. Een op een allowlist gebaseerde AttributeSanitizer dwingt een Zero-Trust-databeleid af, zodat telemetrie nooit documentinhoud of persoonlijk identificeerbare informatie (PII) bevat.
Gebruik deze pagina als PHP-native tegenhanger van de transportonafhankelijke OpenTelemetry-concepten. Een uitvoerbaar voorbeeld en een bijbehorende test dekken de flow.
Installeren
Sectie met titel “Installeren”composer require nextpdf/core:^3Core alleen geeft je het no-op-veilige instrumentatieoppervlak. Voeg de SDK en één exporter toe om live-data te exporteren.
composer require open-telemetry/sdk:^1composer require open-telemetry/exporter-otlp:^1 # or zipkin / prometheusConceptueel overzicht
Sectie met titel “Conceptueel overzicht”Gebruik twee toegangspunten:
TelemetryBridge— een statische facade.isAvailable()controleert eenmalig op OTel en bewaart het resultaat in cache.startSpan()/endSpan()/recordMetric()vallen direct terug op een no-op wanneer OTel ontbreekt. Dit is het nul-overhead-contract. Wanneer OTel ontbreekt, zijn deze aanroepen ruim binnen een microseconde klaar.OpenTelemetryInterceptor— het pad dat met de SDK integreert. Het traceert automatisch de 10 bekende spans, registreert de 7 bekende metrics en stuurt elk attribuut doorAttributeSanitizer. Het controleert bij de constructie of de SDK aanwezig is en bewaart het resultaat in cache. Alle verwijzingen naar OTel-klassen staan achter runtime-guards, zodat de klasse zelfs zonder de SDK laadt. De aanbevolenBatchSpanProcessor-limieten (maxQueueSize=2048,maxExportBatchSize=512) worden beschikbaar gesteld als statische accessors.
De 10 spans: document.build, font.resolve, html.parse, writer.serialize, image.decode, layout.pass, barcode.encode, form.build, navigation.build, attachment.embed. De 7 metrics: render.duration, render.page_count, render.warnings, render.memory_peak, render.file_size, render.font_count, render.image_count.
AttributeSanitizer werkt uitsluitend met een allowlist. Het staat structurele metadatasleutels toe zoals pdf.page_count, pdf.file_size_bytes, pdf.output_profile en nextpdf.tier. Het laat ruwe HTML, PDF-bytestreams, base64-blobs en bestandssysteempaden onvoorwaardelijk vallen. Daarmee implementeert dit twee punten uit de richtlijn van NIST SP 800-92: telemetrie mag geen gevoelige inhoud bevatten, en de vertrouwelijkheid van telemetrie is een expliciete maatregel.
API-oppervlak
Sectie met titel “API-oppervlak”Het oppervlak van de application programming interface (API) wordt gegenereerd uit PHPDoc op NextPDF\Telemetry\TelemetryBridge, NextPDF\Telemetry\OpenTelemetryInterceptor en NextPDF\Telemetry\AttributeSanitizer. De belangrijkste members die hieronder worden gebruikt, zijn TelemetryBridge::isAvailable() / startSpan() / endSpan() / recordMetric(); OpenTelemetryInterceptor::knownSpans() / knownMetrics() / maxQueueSize() / maxExportBatchSize(); en AttributeSanitizer::sanitize().
Codevoorbeeld — Snelstart
Sectie met titel “Codevoorbeeld — Snelstart”<?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');Codevoorbeeld — Productie
Sectie met titel “Codevoorbeeld — Productie”Het volledige voorbeeld toont het nul-overhead-no-op-pad aan doordat het draait terwijl de SDK ontbreekt. Het oefent de allowlist van de sanitizer en respecteert het uitvoerkanaal van de harness. De reproduceerbaarheidsharness voert dit script tweemaal uit.
<?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)),));Randgevallen en valkuilen
Sectie met titel “Randgevallen en valkuilen”- Telemetrie verstoort nooit de weergave. Zowel de bridge als de interceptor vangen hun eigen interne fouten af. Een verkeerd geconfigureerde exporter vermindert alleen de observability, nooit de PDF-uitvoer. Verpak weergavecode niet in een catch die een telemetriefout als een weergavefout behandelt.
endSpan(null)is veilig.startSpan()retourneertnullwanneer OTel ontbreekt, enendSpan()accepteertnullals een no-op. Gebruik ze altijd als paar en vertak nooit op de retourwaarde.- Metrics hebben een geregistreerde
MeterProvidernodig. Als alleen eenTracerProvideris geregistreerd, worden spans geëxporteerd maar metrics stilzwijgend overgeslagen. De metrics zijn adviserend. Registreer beide providers voor volledige dekking. - De sanitizer werkt uitsluitend met een allowlist. Een nieuwe attribuutsleutel die niet in de allowlist staat, wordt niet geëxporteerd. Dit gedrag is opzettelijk. Breid de allowlist in de engine uit, en omzeil de sanitizer niet.
- W3C Trace Context-propagatie. Cross-service trace-propagatie gebruikt de W3C Trace Context-headers
traceparent/tracestate. De propagators van de OTel-SDK verwerken ze, niet NextPDF. De W3C Trace Context-Recommendation zit niet in het verificatiecorpus, dus deze propagatieaantekening is RAG-onopgelost en wordt vermeld als richtlijn op integratieniveau in plaats van als normatieve bewering. Zie de sidecar. - Reproduceerbaarheidsvoorbehoud. De weergave produceert een document waarvan de
/IDen wijzigingsdatum bij elke save opnieuw worden gegenereerd (ISO 32000-2 §14.3). De vastgelegde PDF wordt vergeleken met het semantische profiel, dat alleen de structurele abstract syntax tree (AST) en metadata dekt.
Prestaties
Sectie met titel “Prestaties”- Pad zonder OTel:
isAvailable()wordt na de eerste aanroep in cache bewaard. Latere span- en metric-aanroepen voeren één booleaanse controle uit en keren vervolgens terug. Het geïnstrumenteerde voorbeeld draait volledig terwijl de SDK ontbreekt. - Met OTel: de
BatchSpanProcessor-grenzen (maxQueueSize=2048,maxExportBatchSize=512) begrenzen het geheugen onder aanhoudende belasting, en de export blijft buiten het hot path. - Het
performance_budget(wall_ms: 3000,peak_mb: 128) begrenst de harness-run, niet willekeurige documenten. - Dit recipe dekt de §4.3 gap-list voor #33. Voorheen bestond alleen de conceptpagina in MCP-stijl, zonder PHP-native voorbeeld. Een nieuwe
examples/33-opentelemetry-observability.phpplus de bijbehorendetests/Cookbook/Php/ObserveWithOpenTelemetryRecipeTest.phpzijn geschreven.
Beveiligingsaantekeningen
Sectie met titel “Beveiligingsaantekeningen”- Telemetrie mag geen documentinhoud of PII bevatten. De allowlist van de
AttributeSanitizerhandhaaft dit in code. Ruwe HTML, PDF-streams, base64-blobs en bestandssysteempaden worden weggelaten. Dit sluit aan bij de richtlijn van NIST SP 800-92 over het buiten logs en telemetrie houden van gevoelige inhoud, en over het beschermen van de vertrouwelijkheid van telemetrie. - Attributen die je zelf toevoegt, vallen nog steeds onder de allowlist. Je blijft verantwoordelijk voor het niet introduceren van gevoelige waarden onder een toegestane sleutel. Plaats bijvoorbeeld geen gebruikersidentificatie in
pdf.output_profile. - Gestructureerde sleutels dragen diagnostische details, niet vrije-vormpayloads. Dit is dezelfde discipline die PSR-3 §1.2 toepast op de log-context.
Conformiteit
Sectie met titel “Conformiteit”| Bewering | Spec | Clausule | reference_id |
|---|---|---|---|
| Telemetrie mag geen gevoelige inhoud bevatten; PII-verwerking is vereist. | NIST SP 800-92 | §3 | |
| De vertrouwelijkheid van telemetrie/logs is een expliciete maatregel. | NIST SP 800-92 | §3 | |
| Gestructureerde contextsleutels dragen details, geen vrije-vormpayload. | PSR-3 | §1.2 | |
Uitvoer-/ID en datums worden bij elke save opnieuw gegenereerd → semantisch profiel. | ISO 32000-2 | §14.3 |
Dit recipe beschrijft het gedrag van de engineering-instrumentatie. Het doet geen enkele bewering over compliancecertificering. De verwijzingen naar NIST SP 800-92 onderbouwen de ontwerpintentie om geen inhoud in telemetrie op te nemen, niet een conformiteitsbewering.