Obserwuj renderowanie za pomocą OpenTelemetry
W skrócie
Dział zatytułowany „W skrócie”NextPDF zawiera wbudowaną instrumentację OpenTelemetry: 10 zakresów śladów i 7 metryk w całym cyklu generowania dokumentu Portable Document Format (PDF). Kontrakt brzmi: zerowy narzut i zerowa konfiguracja, gdy brakuje OTel SDK — bez błędu autoładowania i bez kosztu wydajnościowego. Zainstaluj zestaw narzędzi programistycznych (SDK), zarejestruj globalnie TracerProvider/MeterProvider, a ten sam kod będzie automatycznie eksportować dane. Oparty na liście dozwolonych AttributeSanitizer wymusza politykę danych Zero-Trust, dzięki czemu telemetria nigdy nie przenosi zawartości dokumentu ani informacji umożliwiających identyfikację osoby (PII).
Traktuj tę stronę jako uzupełnienie dla PHP do niezależnych od transportu koncepcji OpenTelemetry. Uruchamialny przykład i towarzyszący mu test obejmują cały przepływ.
Instalacja
Dział zatytułowany „Instalacja”composer require nextpdf/core:^3Sam Core udostępnia powierzchnię instrumentacji bezpieczną w trybie no-op. Aby eksportować dane na żywo, dodaj SDK oraz jeden eksporter.
composer require open-telemetry/sdk:^1composer require open-telemetry/exporter-otlp:^1 # or zipkin / prometheusPrzegląd koncepcyjny
Dział zatytułowany „Przegląd koncepcyjny”Korzystaj z dwóch punktów wejścia:
TelemetryBridge— statyczna fasada.isAvailable()sprawdza obecność OTel jednokrotnie i buforuje wynik.startSpan()/endSpan()/recordMetric()natychmiast przechodzą do trybu no-op, gdy brakuje OTel. To jest kontrakt zerowego narzutu. Przy braku OTel wywołania te kończą się znacznie poniżej jednej mikrosekundy.OpenTelemetryInterceptor— ścieżka zintegrowana z SDK. Automatycznie śledzi 10 znanych zakresów, rejestruje 7 znanych metryk i kieruje każdy atrybut przezAttributeSanitizer. Sprawdza obecność SDK podczas tworzenia obiektu i buforuje wynik. Wszystkie odwołania do klas OTel chronią strażniki czasu wykonania, więc klasa ładuje się nawet bez SDK. Zalecane limityBatchSpanProcessor(maxQueueSize=2048,maxExportBatchSize=512) są udostępniane jako statyczne metody dostępowe.
10 zakresów: document.build, font.resolve, html.parse, writer.serialize, image.decode, layout.pass, barcode.encode, form.build, navigation.build, attachment.embed. 7 metryk: render.duration, render.page_count, render.warnings, render.memory_peak, render.file_size, render.font_count, render.image_count.
AttributeSanitizer działa wyłącznie na liście dozwolonych. Zezwala na klucze metadanych strukturalnych, takie jak pdf.page_count, pdf.file_size_bytes, pdf.output_profile oraz nextpdf.tier. Bezwarunkowo odrzuca surowy HTML, strumienie bajtowe PDF, dane base64 oraz ścieżki systemu plików. Realizuje dwa punkty wytycznych NIST SP 800-92: telemetria nie może przenosić treści wrażliwych, a poufność telemetrii jest jawnym mechanizmem kontroli.
Powierzchnia API
Dział zatytułowany „Powierzchnia API”Powierzchnia API jest generowana z PHPDoc w klasach NextPDF\Telemetry\TelemetryBridge, NextPDF\Telemetry\OpenTelemetryInterceptor oraz NextPDF\Telemetry\AttributeSanitizer. Kluczowe elementy używane poniżej to TelemetryBridge::isAvailable() / startSpan() / endSpan() / recordMetric(); OpenTelemetryInterceptor::knownSpans() / knownMetrics() / maxQueueSize() / maxExportBatchSize(); oraz AttributeSanitizer::sanitize().
Przykład kodu — szybki start
Dział zatytułowany „Przykład kodu — szybki start”<?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');Przykład kodu — środowisko produkcyjne
Dział zatytułowany „Przykład kodu — środowisko produkcyjne”Kompletny przykład potwierdza ścieżkę no-op o zerowym narzucie, ponieważ działa także bez SDK. Sprawdza działanie listy dozwolonych w sanityzerze i respektuje kanał wyjściowy uprzęży testowej. Uprząż powtarzalności uruchamia ten skrypt dwukrotnie.
<?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)),));Przypadki brzegowe i pułapki
Dział zatytułowany „Przypadki brzegowe i pułapki”- Telemetria nigdy nie psuje renderowania. Zarówno mostek, jak i interceptor pochłaniają własne błędy wewnętrzne. Źle skonfigurowany eksporter pogarsza obserwowalność, ale nigdy nie wpływa na wynikowy PDF. Nie opakowuj kodu renderowania w blok catch, który traktuje awarię telemetrii jak awarię renderowania.
endSpan(null)jest bezpieczne.startSpan()zwracanull, gdy brakuje OTel, aendSpan()przyjmujenulljako operację no-op. Zawsze stosuj je parami i nigdy nie rozgałęziaj logiki na podstawie zwracanej wartości.- Metryki wymagają zarejestrowanego
MeterProvider. Jeśli zarejestrowany jest tylkoTracerProvider, zakresy są eksportowane, ale metryki są po cichu pomijane. Metryki mają charakter pomocniczy. Zarejestruj obu dostawców, aby uzyskać pełne pokrycie. - Sanityzer działa wyłącznie na liście dozwolonych. Nowy klucz atrybutu, którego nie ma na liście dozwolonych, nie zostanie wyeksportowany. Takie zachowanie jest zamierzone. Rozszerz listę dozwolonych w silniku i nie omijaj sanityzera.
- Propagacja W3C Trace Context. Propagacja śladu między usługami wykorzystuje nagłówki W3C Trace Context
traceparent/tracestate. Obsługują je propagatory OTel SDK, a nie NextPDF. Rekomendacja W3C Trace Context nie znajduje się w korpusie weryfikacyjnym, więc ta uwaga o propagacji nie została rozstrzygnięta przez RAG i jest podana jako wskazówka integracyjna, a nie twierdzenie normatywne. Zobacz panel boczny. - Zastrzeżenie dotyczące powtarzalności. Renderowanie generuje dokument, którego
/IDi data modyfikacji są generowane na nowo przy każdym zapisie (ISO 32000-2 §14.3). Przechwycony PDF jest porównywany z profilem semantycznym, który obejmuje wyłącznie strukturalne abstrakcyjne drzewo składniowe (AST) i metadane.
Wydajność
Dział zatytułowany „Wydajność”- Ścieżka bez OTel: wynik
isAvailable()jest buforowany po pierwszym wywołaniu. Późniejsze wywołania zakresów i metryk wykonują jedno sprawdzenie logiczne, po czym zwracają sterowanie. Zinstrumentowany przykład wykonuje się do końca przy braku SDK. - Z OTel: limity
BatchSpanProcessor(maxQueueSize=2048,maxExportBatchSize=512) ograniczają zużycie pamięci przy stałym obciążeniu, a eksport pozostaje poza ścieżką krytyczną. - Wartość
performance_budget(wall_ms: 3000,peak_mb: 128) ogranicza przebieg uprzęży, a nie dowolne dokumenty. - Ten przepis zapewnia pokrycie z listy luk §4.3 dla pozycji #33. Wcześniej istniała wyłącznie koncepcyjna strona w stylu MCP, bez przykładu natywnego dla PHP. Utworzono nowy plik
examples/33-opentelemetry-observability.phporaz wspierający gotests/Cookbook/Php/ObserveWithOpenTelemetryRecipeTest.php.
Uwagi dotyczące bezpieczeństwa
Dział zatytułowany „Uwagi dotyczące bezpieczeństwa”- Telemetria nie może przenosić zawartości dokumentu ani PII. Lista dozwolonych
AttributeSanitizerwymusza to w kodzie. Surowy HTML, strumienie PDF, dane base64 oraz ścieżki systemu plików są odrzucane. Jest to zgodne z wytycznymi NIST SP 800-92 dotyczącymi nieumieszczania treści wrażliwych w dziennikach i telemetrii oraz ochrony poufności telemetrii. - Samodzielnie dodane atrybuty nadal podlegają liście dozwolonych. Nadal odpowiadasz za to, aby nie wprowadzać wrażliwych wartości pod dozwolonym kluczem. Na przykład nie umieszczaj identyfikatora użytkownika w
pdf.output_profile. - Szczegóły diagnostyczne są przenoszone przez klucze strukturalne, a nie przez dowolne ładunki danych. Jest to ta sama dyscyplina, którą PSR-3 §1.2 stosuje do kontekstu dziennika.
Zgodność
Dział zatytułowany „Zgodność”| Stwierdzenie | Specyfikacja | Klauzula | reference_id |
|---|---|---|---|
| Telemetria nie może przenosić treści wrażliwych; obsługa PII jest wymagana. | NIST SP 800-92 | §3 | |
| Poufność telemetrii/dzienników jest jawnym mechanizmem kontroli. | NIST SP 800-92 | §3 | |
| Strukturalne klucze kontekstu przenoszą szczegóły, a nie dowolny ładunek danych. | PSR-3 | §1.2 | |
Wyjściowe /ID i daty są generowane na nowo przy każdym zapisie → profil semantyczny. | ISO 32000-2 | §14.3 |
Ten przepis opisuje inżynieryjne zachowanie instrumentacji. Nie stanowi deklaracji żadnej certyfikacji zgodności. Odwołania do NIST SP 800-92 uzasadniają zamysł projektowy nieumieszczania treści w telemetrii, a nie twierdzenie o zgodności.