Lewati ke konten

Telemetri: jembatan OpenTelemetry dan fallback no-op

Modul Telemetry adalah jembatan opsional antara engine dan software development kit (SDK) OpenTelemetry (OTel). Saat SDK terpasang, modul ini memancarkan span dan metrik dengan atribut yang telah dibersihkan. Saat SDK tidak tersedia, sekumpulan lengkap objek tracer dan meter no-op menjaga panggilan instrumentasi tetap valid dan nyaris tanpa biaya. Anda dapat membiarkan instrumentasi tetap berada di jalur kode dengan aman.

Terminal window
composer require nextpdf/core:^3

Tujuan rancangannya adalah menyediakan observabilitas tanpa biaya saat SDK tidak tersedia. Jalur panas engine memanggil tracer dan meter tanpa pemeriksaan lebih dulu. Apakah panggilan tersebut benar-benar menjalankan instrumentasi bergantung pada runtime, bukan pada percabangan kondisional di setiap lokasi panggilan.

OpenTelemetryInterceptor adalah jembatannya. isAvailable() melaporkan apakah OTel SDK tersedia. startSpan(string $name, array $attributes = []) / endSpan(?object $span) membungkus operasi yang dilacak, dan recordMetric() mencatat nilai counter atau gauge. Saat OTel tidak tersedia, interceptor melaporkan ketidaktersediaan, dan panggilan menjadi inert. TelemetryBridge menyambungkan interceptor ke titik observasi engine.

AttributeSanitizer adalah lapisan pengamannya. sanitize(array $attributes) membersihkan peta atribut sebelum keluar dari proses. Atribut telemetri adalah saluran personally identifiable information (PII) yang sering muncul tanpa sengaja, sehingga pembersihan merupakan bagian dari kontrak, bukan tambahan. Sanitizer, interceptor, dan bridge semuanya @since 2.3.0.

NullTracer, NullSpanBuilder, NullSpan, NullMeter, NullCounter, dan NullHistogram adalah fallback no-op. Semuanya mengikuti bentuk panggilan yang dipaparkan OTel SDK: spanBuilder(), setAttribute() (dapat dirantai), startSpan(), end(), createHistogram(), createUpDownCounter(), add(), dan record(). Semuanya tidak melakukan apa pun. Karena fallback-nya lengkap, kode yang diinstrumentasikan tidak perlu bercabang berdasarkan ketersediaan; kode memanggil tracer, dan no-op menyerap panggilan tersebut.

KelasAnggota utamaPeran
OpenTelemetryInterceptorisAvailable(), startSpan(), endSpan(), recordMetric()Jembatan span dan metrik OTel (@since 2.3.0)
TelemetryBridgepenyambungan engineMenghubungkan interceptor ke titik observasi engine (@since 2.3.0)
AttributeSanitizersanitize(array $attributes): arrayMembersihkan atribut demi keamanan PII (@since 2.3.0)
NullTracerspanBuilder(string $name): NullSpanBuilderTracer no-op
NullSpanBuildersetAttribute(), startSpan(): NullSpanPembangun span no-op (dapat dirantai)
NullSpanend()Span no-op
NullMetercreateHistogram(), createUpDownCounter()Meter no-op
NullCounter / NullHistogramadd(), record()Instrumen no-op

Jalankan composer docs:generate-api-php -- --module=Telemetry untuk membuat tabel PHPDoc lengkap.

Sumber: examples/33-opentelemetry-observability.php.

<?php
declare(strict_types=1);
require_once __DIR__ . '/../vendor/autoload.php';
use NextPDF\Telemetry\OpenTelemetryInterceptor;
$otel = new OpenTelemetryInterceptor(/* optional OTel tracer/meter */);
$span = $otel->startSpan('pdf.render', ['doc.pages' => 12]);
// ... render work ...
$otel->endSpan($span);
$otel->recordMetric('pdf.render.bytes', 482_113, ['profile' => 'pdfa4']);

Saat OTel SDK tidak tersedia, setiap panggilan di atas adalah no-op. Kode tetap identik, dan biayanya nol.

Bungkus operasi render dengan atribut yang telah dibersihkan agar metadata dari pemanggil tidak bocor ke dalam span.

<?php
declare(strict_types=1);
require_once __DIR__ . '/../vendor/autoload.php';
use NextPDF\Telemetry\AttributeSanitizer;
use NextPDF\Telemetry\OpenTelemetryInterceptor;
final readonly class InstrumentedRenderer
{
public function __construct(
private OpenTelemetryInterceptor $otel,
private AttributeSanitizer $sanitizer,
) {}
/**
* @param callable():string $render Returns the rendered PDF bytes.
* @param array<string, mixed> $attributes Caller-supplied span attributes.
*/
public function render(callable $render, array $attributes): string
{
$span = $this->otel->startSpan('pdf.render', $this->sanitizer->sanitize($attributes));
try {
return $render();
} finally {
$this->otel->endSpan($span);
}
}
}
  • Fallback no-op sengaja dibuat lengkap. Jangan membungkus instrumentasi dengan isAvailable() “untuk menghemat kerja”. No-op sudah tidak menimbulkan biaya apa pun, dan penjagaan itu justru menambahkan cabang yang dihilangkan oleh rancangan ini.
  • Selalu proses atribut yang dipasok pemanggil melalui AttributeSanitizer sebelum Anda melampirkannya ke span atau metrik. Atribut telemetri adalah saluran PII yang tidak disengaja.
  • endSpan(null) valid: span null adalah kasus no-op. Pasangkan setiap startSpan() dengan endSpan() di dalam blok finally.
  • NullSpanBuilder::setAttribute() mengembalikan static agar dapat dirantai. Dalam mode no-op, rantai tersebut inert secara rancangan.
  • Profil reproduksibilitasnya adalah structural: span membawa timestamp dan pengidentifikasi trace, sehingga dua eksekusi berbeda pada bidang-bidang tersebut.

Saat OTel tidak tersedia, biayanya sebatas panggilan metode ke no-op, praktis tanpa biaya. Saat OTel tersedia, biaya berasal dari OTel SDK; bridge menambahkan pembersihan atribut, yang linear terhadap jumlah atribut. performance_budget sebesar 1500 ms wall / 64 MB peak adalah anggaran referensi engine, bukan service-level agreement (SLA) telemetri.

Telemetri adalah permukaan keluarnya data (data egress). AttributeSanitizer mencegah rahasia dan PII masuk ke span dan metrik. Perlakukan pembersihan sebagai wajib untuk setiap atribut yang dipengaruhi pemanggil; itulah kewajiban proyek ini untuk telemetri yang aman. Eksportir OTel mengirim data ke backend eksternal, dan backend tersebut menjadi batas kepercayaan. Konfigurasikan endpoint dan kredensial melalui secret manager, bukan melalui konfigurasi yang di-commit. Asumsikan data span dan metrik mencapai log sink, lalu bersihkan sesuai kebutuhan. Lihat model ancaman engine di /modules/core/security/.

Modul ini tidak membuat klaim normatif apa pun atas spesifikasi Portable Document Format (PDF). Modul ini menjembatani ke model data OpenTelemetry, sebuah spesifikasi observabilitas eksternal, bukan klausul PDF. Fallback no-op mencerminkan permukaan application programming interface (API) OpenTelemetry agar kode yang diinstrumentasikan tetap portabel. Ini merupakan properti kompatibilitas API, bukan pernyataan kesesuaian PDF. Kesesuaian engine divalidasi oleh suite oracle dan golden yang dijelaskan di /modules/core/conformance/.