Observar el renderizado con OpenTelemetry
En resumen
Sección titulada «En resumen»NextPDF incluye instrumentación de OpenTelemetry integrada: 10 spans de traza y 7 métricas durante todo el ciclo de vida de generación del PDF. El contrato es cero sobrecarga y cero configuración cuando el SDK de OTel está ausente: sin errores de autoload ni penalización de rendimiento. Basta con instalar el SDK, registrar globalmente un TracerProvider/MeterProvider y el mismo código exporta de forma automática. Un AttributeSanitizer basado en una lista de permitidos aplica una política de datos Zero-Trust, de modo que la telemetría nunca transporta contenido del documento ni PII.
Esta página complementa en PHP nativo el material conceptual de OpenTelemetry, que es independiente del transporte. Un ejemplo ejecutable y una prueba de respaldo ejercitan este comportamiento.
Instalación
Sección titulada «Instalación»composer require nextpdf/core:^3El core por sí solo ofrece la superficie de instrumentación segura para la ruta no-op. Para exportar datos en vivo, añadir el SDK y un exportador.
composer require open-telemetry/sdk:^1composer require open-telemetry/exporter-otlp:^1 # or zipkin / prometheusVista conceptual
Sección titulada «Vista conceptual»Hay dos puntos de entrada:
TelemetryBridge— una fachada estática.isAvailable()comprueba la presencia de OTel una sola vez y guarda el resultado en caché.startSpan()/endSpan()/recordMetric()derivan a un no-op cuando OTel está ausente. Este es el contrato de cero sobrecarga. Cuando OTel está ausente, estas llamadas se completan en mucho menos de un microsegundo.OpenTelemetryInterceptor— la ruta integrada con el SDK. Traza automáticamente los 10 spans conocidos, registra las 7 métricas conocidas y enruta cada atributo a través deAttributeSanitizer. Comprueba la presencia del SDK en el momento de la construcción y guarda el resultado en caché. Todas las referencias a clases de OTel quedan detrás de guardas en tiempo de ejecución, de modo que la clase se carga incluso sin el SDK. Los límites recomendados delBatchSpanProcessor(maxQueueSize=2048,maxExportBatchSize=512) se exponen como accesores estáticos.
Los 10 spans: document.build, font.resolve, html.parse, writer.serialize, image.decode, layout.pass, barcode.encode, form.build, navigation.build, attachment.embed. Las 7 métricas: render.duration, render.page_count, render.warnings, render.memory_peak, render.file_size, render.font_count, render.image_count.
AttributeSanitizer funciona solo con una lista de permitidos. Las claves permitidas son metadatos estructurales como pdf.page_count, pdf.file_size_bytes, pdf.output_profile y nextpdf.tier. El HTML sin procesar, los flujos de bytes del PDF, los blobs en base64 y las rutas del sistema de archivos se descartan de forma incondicional. Esto implementa dos puntos de la guía de NIST SP 800-92: la telemetría no debe transportar contenido sensible, y la confidencialidad de la telemetría es un control explícito.
Superficie de la API
Sección titulada «Superficie de la API»La superficie de la API se genera a partir del PHPDoc de NextPDF\Telemetry\TelemetryBridge, NextPDF\Telemetry\OpenTelemetryInterceptor y NextPDF\Telemetry\AttributeSanitizer. Los miembros clave utilizados a continuación son TelemetryBridge::isAvailable() / startSpan() / endSpan() / recordMetric(); OpenTelemetryInterceptor::knownSpans() / knownMetrics() / maxQueueSize() / maxExportBatchSize(); y AttributeSanitizer::sanitize().
Ejemplo de código — Inicio rápido
Sección titulada «Ejemplo de código — Inicio rápido»<?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');Ejemplo de código — Producción
Sección titulada «Ejemplo de código — Producción»El ejemplo completo demuestra la ruta no-op con cero sobrecarga, porque se ejecuta con el SDK ausente. Ejercita la lista de permitidos del sanitizer y respeta el canal de salida del harness. El harness de reproducibilidad ejecuta este script dos veces.
<?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)),));Casos límite y trampas
Sección titulada «Casos límite y trampas»- La telemetría nunca rompe el renderizado. Tanto el bridge como el interceptor absorben sus propios errores internos. Un exportador mal configurado degrada la observabilidad, nunca la salida del PDF. No envolver el código de renderizado en un catch que trate un fallo de telemetría como un fallo de renderizado.
endSpan(null)es seguro.startSpan()devuelvenullcuando OTel está ausente, yendSpan()aceptanullcomo un no-op. Emparejar siempre las dos llamadas y no ramificar nunca según el valor de retorno.- Las métricas necesitan un
MeterProviderregistrado. Si solo hay registrado unTracerProvider, los spans se exportan pero las métricas se omiten en silencio. Las métricas tienen carácter orientativo. Registrar ambos proveedores para obtener cobertura completa. - El sanitizer funciona solo con una lista de permitidos. Una nueva clave de atributo que no esté en la lista de permitidos no se exportará. Este comportamiento es intencionado. Ampliar la lista de permitidos en el motor y no eludir el sanitizer.
- Propagación de W3C Trace Context. La propagación de trazas entre servicios usa las cabeceras
traceparent/tracestatede W3C Trace Context. Los propagadores del SDK de OTel las gestionan, no NextPDF. La Recomendación de W3C Trace Context no está en el corpus de verificación, así que esta nota de propagación no queda resuelta por RAG y se expone como guía de integración en lugar de una afirmación normativa. Consultar el sidecar. - Advertencia sobre reproducibilidad. El renderizado emite un documento cuyo
/IDy fecha de modificación se regeneran en cada guardado (ISO 32000-2 §14.3). El PDF capturado se compara con el perfil semántico, que cubre solo el AST estructural y los metadatos.
Rendimiento
Sección titulada «Rendimiento»- Ruta sin OTel:
isAvailable()se guarda en caché tras la primera llamada. Las llamadas posteriores de span y métrica son una sola comprobación booleana seguida de un retorno. El ejemplo instrumentado se ejecuta hasta el final con el SDK ausente. - Con OTel: los límites del
BatchSpanProcessor(maxQueueSize=2048,maxExportBatchSize=512) acotan la memoria bajo carga sostenida, y la exportación se mantiene fuera de la ruta crítica. - El
performance_budget(wall_ms: 3000,peak_mb: 128) acota la ejecución del harness, no documentos arbitrarios. - Esta recipe cubre la carencia del §4.3 correspondiente al #33. Antes no existía ningún ejemplo nativo de PHP, solo la página conceptual de estilo MCP. Se crearon el nuevo
examples/33-opentelemetry-observability.phpy la prueba de respaldotests/Cookbook/Php/ObserveWithOpenTelemetryRecipeTest.php.
Notas de seguridad
Sección titulada «Notas de seguridad»- La telemetría no debe transportar contenido del documento ni PII. La lista de permitidos de
AttributeSanitizeraplica esto en el código. El HTML sin procesar, los flujos de PDF, los blobs en base64 y las rutas del sistema de archivos se descartan. Esto se alinea con la guía de NIST SP 800-92 sobre mantener el contenido sensible fuera de los registros y la telemetría, y sobre proteger la confidencialidad de la telemetría. - Los atributos que se añadan siguen sujetos a la lista de permitidos. Sigue siendo responsabilidad del integrador no introducir valores sensibles bajo una clave permitida. Por ejemplo, no poner un identificador de usuario en
pdf.output_profile. - Las claves estructuradas, y no la carga útil de forma libre, son las que llevan el detalle de diagnóstico. Esta es la misma disciplina que PSR-3 §1.2 aplica al contexto de los registros.
Conformidad
Sección titulada «Conformidad»| Declaración | Especificación | Cláusula | reference_id |
|---|---|---|---|
| La telemetría no debe transportar contenido sensible; el tratamiento de la PII es obligatorio. | NIST SP 800-92 | §3 | |
| La confidencialidad de la telemetría y los registros es un control explícito. | NIST SP 800-92 | §3 | |
| Las claves de contexto estructuradas llevan el detalle, no la carga útil de forma libre. | PSR-3 | §1.2 | |
El /ID y las fechas de salida se regeneran en cada guardado → perfil semántico. | ISO 32000-2 | §14.3 |
Esta recipe describe el comportamiento de la instrumentación de ingeniería. No afirma ninguna certificación de conformidad. Las referencias a NIST SP 800-92 fundamentan la intención de diseño de no incluir contenido en la telemetría, no una afirmación de conformidad.