Observer le rendu avec OpenTelemetry
En un coup d’œil
Section intitulée « En un coup d’œil »NextPDF embarque une instrumentation OpenTelemetry intégrée : 10 spans de trace et 7 métriques couvrent tout le cycle de vie de la génération de PDF. Le contrat est clair : zéro surcoût et zéro configuration quand le SDK OTel est absent — aucun échec d’autoload, aucune pénalité de performance. Installe le SDK, enregistre globalement un TracerProvider/MeterProvider, et le même code exporte automatiquement. Un AttributeSanitizer fondé sur une liste d’autorisation applique une politique de données Zero-Trust : la télémétrie ne transporte donc jamais de contenu de document ni de données personnelles.
Cette page est l’équivalent PHP natif du contenu conceptuel OpenTelemetry, indépendamment du transport. Un exemple exécutable et un test de support l’illustrent concrètement.
Installation
Section intitulée « Installation »composer require nextpdf/core:^3À lui seul, le core te donne une surface d’instrumentation sûre, en mode no-op. Pour exporter des données en direct, ajoute le SDK et un exporter.
composer require open-telemetry/sdk:^1composer require open-telemetry/exporter-otlp:^1 # or zipkin / prometheusVue d’ensemble conceptuelle
Section intitulée « Vue d’ensemble conceptuelle »Deux points d’entrée sont disponibles :
TelemetryBridge— une façade statique.isAvailable()vérifie la présence d’OTel une seule fois et met le résultat en cache.startSpan()/endSpan()/recordMetric()basculent immédiatement vers un no-op quand OTel est absent. C’est ce qui garantit le contrat de zéro surcoût. Quand OTel est absent, ces appels s’exécutent largement sous la microseconde.OpenTelemetryInterceptor— le chemin intégré au SDK. Il trace automatiquement les 10 spans connus, enregistre les 7 métriques connues et fait passer chaque attribut parAttributeSanitizer. Il vérifie la présence du SDK à l’instanciation et met le résultat en cache. Toutes les références aux classes OTel sont placées derrière des gardes à l’exécution, si bien que la classe se charge même sans le SDK. Les bornes recommandées duBatchSpanProcessor(maxQueueSize=2048,maxExportBatchSize=512) sont exposées sous forme d’accesseurs statiques.
Les 10 spans : document.build, font.resolve, html.parse, writer.serialize, image.decode, layout.pass, barcode.encode, form.build, navigation.build, attachment.embed. Les 7 métriques : render.duration, render.page_count, render.warnings, render.memory_peak, render.file_size, render.font_count, render.image_count.
AttributeSanitizer repose exclusivement sur une liste d’autorisation. Les clés autorisées sont des métadonnées structurelles telles que pdf.page_count, pdf.file_size_bytes, pdf.output_profile et nextpdf.tier. Le HTML brut, les flux d’octets PDF, les blobs base64 et les chemins de fichiers sont supprimés sans condition. Cela concrétise deux points de la directive NIST SP 800-92 : la télémétrie ne doit pas transporter de contenu sensible, et la confidentialité de la télémétrie est un contrôle explicite.
Surface de l’API
Section intitulée « Surface de l’API »La surface de l’API est générée à partir du PHPDoc de NextPDF\Telemetry\TelemetryBridge, NextPDF\Telemetry\OpenTelemetryInterceptor et NextPDF\Telemetry\AttributeSanitizer. Les principaux membres utilisés ci-dessous sont TelemetryBridge::isAvailable() / startSpan() / endSpan() / recordMetric() ; OpenTelemetryInterceptor::knownSpans() / knownMetrics() / maxQueueSize() / maxExportBatchSize() ; et AttributeSanitizer::sanitize().
Exemple de code — Démarrage rapide
Section intitulée « Exemple de code — Démarrage rapide »<?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');Exemple de code — Production
Section intitulée « Exemple de code — Production »L’exemple complet démontre le chemin no-op à zéro surcoût : il s’exécute en l’absence du SDK. Il met en pratique la liste d’autorisation du sanitizer et respecte le canal de sortie du harnais. Le harnais de reproductibilité exécute ce script deux fois.
<?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)),));Cas limites & pièges
Section intitulée « Cas limites & pièges »- La télémétrie ne casse jamais le rendu. Le bridge et l’interceptor absorbent leurs propres erreurs internes. Un exporter mal configuré dégrade l’observabilité, jamais la sortie PDF. N’enveloppe pas le code de rendu dans un catch qui traiterait un échec de télémétrie comme un échec de rendu.
endSpan(null)est sûr.startSpan()renvoienullquand OTel est absent, etendSpan()acceptenullcomme no-op. Appaire-les toujours, et ne fais jamais de branchement sur la valeur de retour.- Les métriques nécessitent un
MeterProviderenregistré. Si seul unTracerProviderest enregistré, les spans sont exportés, mais les métriques sont silencieusement ignorées. Les métriques sont indicatives. Enregistre les deux fournisseurs pour une couverture complète. - Le sanitizer fonctionne uniquement sur liste d’autorisation. Une nouvelle clé d’attribut absente de la liste d’autorisation ne sera pas exportée. Ce comportement est voulu par conception. Étends la liste d’autorisation dans le moteur, et ne contourne pas le sanitizer.
- Propagation du contexte de trace W3C. La propagation de trace entre services utilise les en-têtes
traceparent/tracestatedu contexte de trace W3C. Ce sont les propagateurs du SDK OTel qui s’en chargent, et non NextPDF. La recommandation W3C Trace Context n’est pas dans le corpus de vérification ; cette note de propagation reste donc non résolue côté RAG et est présentée comme un conseil d’intégration plutôt que comme une assertion normative. Consulte l’encart latéral. - Point d’attention sur la reproductibilité. Le rendu produit un document dont le
/IDet la date de modification sont régénérés à chaque sauvegarde (ISO 32000-2 §14.3). Le PDF capturé est comparé avec le profil sémantique, qui couvre uniquement l’AST structurel et les métadonnées.
Performance
Section intitulée « Performance »- Chemin sans OTel :
isAvailable()est mis en cache après le premier appel. Les appels de span et de métrique suivants se réduisent à un seul contrôle booléen, puis retournent. L’exemple instrumenté s’exécute jusqu’au bout avec le SDK absent. - Avec OTel : les bornes du
BatchSpanProcessor(maxQueueSize=2048,maxExportBatchSize=512) plafonnent la mémoire sous charge soutenue, et l’export reste hors du chemin critique. - Le
performance_budget(wall_ms: 3000,peak_mb: 128) borne l’exécution du harnais, pas celle de documents arbitraires. - Cette recipe couvre l’élément de la liste de lacunes §4.3 pour le #33. Aucun exemple natif PHP n’existait auparavant, seulement la page conceptuelle de style MCP. Un nouveau
examples/33-opentelemetry-observability.phpainsi que letests/Cookbook/Php/ObserveWithOpenTelemetryRecipeTest.phpde support ont été écrits.
Notes de sécurité
Section intitulée « Notes de sécurité »- La télémétrie ne doit pas transporter de contenu de document ni de données personnelles. La liste d’autorisation de
AttributeSanitizerl’applique dans le code. Le HTML brut, les flux PDF, les blobs base64 et les chemins de fichiers sont supprimés. Cela s’aligne sur la directive NIST SP 800-92, qui vise à garder le contenu sensible hors des journaux et de la télémétrie, et à protéger la confidentialité de la télémétrie. - Les attributs que tu ajoutes toi-même restent soumis à la liste d’autorisation. Tu restes responsable de ne pas introduire de valeurs sensibles sous une clé autorisée. Par exemple, ne mets pas d’identifiant utilisateur dans
pdf.output_profile. - Le détail diagnostique passe par des clés structurées, pas par une charge utile en texte libre. C’est la même discipline que celle que PSR-3 §1.2 applique au contexte des journaux.
Conformité
Section intitulée « Conformité »| Énoncé | Spécification | Clause | reference_id |
|---|---|---|---|
| La télémétrie ne doit pas transporter de contenu sensible ; le traitement des données personnelles est obligatoire. | NIST SP 800-92 | §3 | |
| La confidentialité de la télémétrie et des journaux est un contrôle explicite. | NIST SP 800-92 | §3 | |
| Ce sont des clés de contexte structurées qui portent le détail, pas une charge utile en texte libre. | PSR-3 | §1.2 | |
Le /ID de sortie et les dates se régénèrent à chaque sauvegarde → profil sémantique. | ISO 32000-2 | §14.3 |
Cette recipe décrit le comportement de l’instrumentation d’ingénierie. Elle n’affirme aucune certification de conformité. Les références à NIST SP 800-92 fondent l’intention de conception « pas de contenu dans la télémétrie », et non une assertion de conformité.