Ga naar inhoud

Rendering observeren met OpenTelemetry

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.

Terminal window
composer require nextpdf/core:^3

Core alleen geeft je het no-op-veilige instrumentatieoppervlak. Voeg de SDK en één exporter toe om live-data te exporteren.

Terminal window
composer require open-telemetry/sdk:^1
composer require open-telemetry/exporter-otlp:^1 # or zipkin / prometheus

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 door AttributeSanitizer. 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 aanbevolen BatchSpanProcessor-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.

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().

<?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');

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)),
));
  • 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() retourneert null wanneer OTel ontbreekt, en endSpan() accepteert null als een no-op. Gebruik ze altijd als paar en vertak nooit op de retourwaarde.
  • Metrics hebben een geregistreerde MeterProvider nodig. Als alleen een TracerProvider is 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 /ID en 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.
  • 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.php plus de bijbehorende tests/Cookbook/Php/ObserveWithOpenTelemetryRecipeTest.php zijn geschreven.
  • Telemetrie mag geen documentinhoud of PII bevatten. De allowlist van de AttributeSanitizer handhaaft 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.
BeweringSpecClausulereference_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.