تخطَّ إلى المحتوى

مراقبة عملية التصيير باستخدام OpenTelemetry

يتضمَّن ⁨NextPDF⁩ أدوات قياس ⁨OpenTelemetry⁩ مُدمجة: 10 مقاطع تتبُّع و7 مقاييس عبر دورة حياة إنشاء تنسيق المستند المحمول (⁨PDF⁩). الالتزام هو انعدام العبء وانعدام التهيئة عند غياب ⁨OTel SDK⁩ — بلا فشل في التحميل التلقائي، وبلا خسارة في الأداء. ثبِّت مجموعة أدوات تطوير البرمجيات (⁨SDK⁩)، وسجِّل TracerProvider/MeterProvider عالميًا، وعندها يُصدِّر الكود نفسه تلقائيًا. يفرض AttributeSanitizer القائم على قائمة السماح سياسة بيانات عديمة الثقة، لذلك لا تحمل بيانات القياس عن بُعد محتوى المستند أو معلومات التعريف الشخصية (⁨PII⁩) إطلاقًا.

استخدم هذه الصفحة بوصفها الرفيق الأصلي للغة ⁨PHP⁩ لمفاهيم ⁨OpenTelemetry⁩ المستقلة عن طريقة النقل. يغطي المسار مثالًا قابلًا للتشغيل واختبارًا داعمًا.

Terminal window
composer require nextpdf/core:^3

يمنحك ⁨Core⁩ وحده سطح أدوات القياس الآمن في وضع عدم التنفيذ. لتصدير البيانات المباشرة، أضِف ⁨SDK⁩ ومُصدِّرًا واحدًا فقط.

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

استخدم نقطتي دخول:

  • TelemetryBridge — واجهة ساكنة. يتحقق isAvailable() من وجود ⁨OTel⁩ مرة واحدة ويخزِّن النتيجة مؤقتًا. تختصر startSpan() / endSpan() / recordMetric() المسار إلى عدم تنفيذ عند غياب ⁨OTel.⁩ وهذا هو الالتزام بانعدام العبء. عند غياب ⁨OTel⁩، تكتمل هذه الاستدعاءات في أقل بكثير من ميكروثانية واحدة.
  • OpenTelemetryInterceptor — المسار المتكامل مع ⁨SDK.⁩ يتتبَّع تلقائيًا المقاطع العشرة المعروفة، ويسجِّل المقاييس السبعة المعروفة، ويمرِّر كل سمة عبر AttributeSanitizer. يتحقق من وجود ⁨SDK⁩ عند الإنشاء ويخزِّن النتيجة مؤقتًا. تقع جميع مراجع فئات ⁨OTel⁩ خلف حواجز وقت التشغيل، لذلك تُحمَّل الفئة حتى دون ⁨SDK.⁩ تُتاح حدود BatchSpanProcessor المُوصى بها (maxQueueSize=2048، maxExportBatchSize=512) بوصفها أدوات وصول ساكنة.

المقاطع العشرة: document.build، font.resolve، html.parse، writer.serialize، image.decode، layout.pass، barcode.encode، form.build، navigation.build، attachment.embed. المقاييس السبعة: render.duration، render.page_count، render.warnings، render.memory_peak، render.file_size، render.font_count، render.image_count.

يعتمد AttributeSanitizer على قائمة السماح حصرًا. يسمح بمفاتيح البيانات الوصفية البنيوية مثل pdf.page_count، وpdf.file_size_bytes، وpdf.output_profile، وnextpdf.tier. ويُسقِط بلا قيد أي ⁨HTML⁩ خام، ودفوق بايتات ⁨PDF⁩، وكتل ⁨base64⁩، ومسارات نظام الملفات. يطبِّق هذا نقطتين من إرشادات ⁨NIST SP 800-92⁩: يجب ألا تحمل بيانات القياس عن بُعد محتوى حساسًا، وأن سرية بيانات القياس عن بُعد ضابط صريح.

يُولَّد سطح واجهة برمجة التطبيقات (⁨API⁩) من ⁨PHPDoc⁩ الموجود في NextPDF\Telemetry\TelemetryBridge، وNextPDF\Telemetry\OpenTelemetryInterceptor، وNextPDF\Telemetry\AttributeSanitizer. الأعضاء الأساسية المستخدمة أدناه هي TelemetryBridge::isAvailable() / startSpan() / endSpan() / recordMetric()؛ وOpenTelemetryInterceptor::knownSpans() / knownMetrics() / maxQueueSize() / maxExportBatchSize()؛ و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');

يُثبِت المثال الكامل مسار عدم التنفيذ عديم العبء لأنه يعمل عند غياب ⁨SDK.⁩ كما يختبر قائمة السماح في أداة التنقية ويلتزم بقناة إخراج بيئة الاختبار. تشغِّل بيئة اختبار قابلية إعادة الإنتاج هذا النص البرمجي مرتين.

<?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)),
));
  • لا توقِف بيانات القياس عن بُعد التصيير إطلاقًا. يبتلع كل من الجسر والمعترِض أخطاءه الداخلية. يُضعف المُصدِّر سيِّئ التهيئة قابلية المراقبة، لا مُخرَج ⁨PDF⁩ إطلاقًا. لا تُغلِّف كود التصيير داخل كتلة ⁨catch⁩ تتعامل مع فشل القياس عن بُعد على أنه فشل في التصيير.
  • استدعاء endSpan(null) آمن. يُعيد startSpan() القيمة null عند غياب ⁨OTel⁩، ويقبل endSpan() القيمة null بوصفها عدم تنفيذ. اقرنهما دائمًا، ولا تفرِّع المسار بناءً على القيمة المُعادة إطلاقًا.
  • تحتاج المقاييس إلى MeterProvider مُسجَّل. إذا كان TracerProvider وحده مُسجَّلًا، فتُصدَّر المقاطع لكن تُتجاوَز المقاييس بصمت. المقاييس استرشادية. سجِّل كلا المزوِّدين للحصول على تغطية كاملة.
  • أداة التنقية تعتمد قائمة السماح حصرًا. أي مفتاح سمة جديد غير مُدرَج في قائمة السماح لن يُصدَّر. هذا السلوك مقصود في التصميم. وسِّع قائمة السماح في المحرك، ولا تتجاوز أداة التنقية.
  • نشر ⁨W3C Trace Context.⁩ يستخدم نشر التتبُّع عبر الخدمات ترويسات ⁨W3C Trace Context⁩ وهي traceparent/tracestate. تتولاها أدوات النشر في ⁨OTel SDK⁩، لا ⁨NextPDF.⁩ توصية ⁨W3C Trace Context⁩ ليست ضمن مجموعة التحقق، لذلك تظل ملاحظة النشر هذه غير محسومة عبر ⁨RAG⁩ وتُذكَر بوصفها إرشادًا للتكامل لا ادعاءً معياريًا. راجِع الملف المرافق.
  • تنبيه بشأن قابلية إعادة الإنتاج. يُصدِر التصيير مستندًا يُعاد توليد /ID وتاريخ التعديل فيه مع كل عملية حفظ (⁨ISO 32000-2⁩ §14.3). يُقارَن ملف ⁨PDF⁩ الملتقَط باستخدام ملف التعريف الدلالي، الذي لا يغطي إلا شجرة التركيب المجرَّدة (⁨AST⁩) البنيوية والبيانات الوصفية.
  • مسار غياب ⁨OTel⁩: تُخزَّن نتيجة isAvailable() مؤقتًا بعد الاستدعاء الأول. تُجري استدعاءات المقاطع والمقاييس اللاحقة فحصًا منطقيًا واحدًا، ثم تعود. يكتمل المثال المزوَّد بأدوات القياس حتى عند غياب ⁨SDK.⁩
  • مع ⁨OTel⁩: تحدُّ حدود BatchSpanProcessor ‏(maxQueueSize=2048، maxExportBatchSize=512) من استهلاك الذاكرة تحت الحمل المتواصل، ويبقى التصدير خارج المسار الساخن.
  • تحدُّ قيمة performance_budget ‏(wall_ms: 3000، peak_mb: 128) تشغيل بيئة الاختبار، لا المستندات الاعتباطية.
  • تغطي هذه الوصفة §4.3 من قائمة الثغرات للبند ‎#33. في السابق، لم تكن توجد سوى صفحة المفاهيم بأسلوب ⁨MCP⁩، دون مثال أصلي بلغة ⁨PHP.⁩ جرى تأليف ملف جديد examples/33-opentelemetry-observability.php إضافةً إلى الاختبار الداعم tests/Cookbook/Php/ObserveWithOpenTelemetryRecipeTest.php.
  • يجب ألا تحمل بيانات القياس عن بُعد محتوى المستند أو معلومات التعريف الشخصية (⁨PII⁩). تفرض قائمة سماح AttributeSanitizer هذا في الكود. يجري إسقاط ⁨HTML⁩ الخام، ودفوق ⁨PDF⁩، وكتل ⁨base64⁩، ومسارات نظام الملفات. يتوافق هذا مع إرشادات ⁨NIST SP 800-92⁩ بشأن إبقاء المحتوى الحساس خارج السجلات وبيانات القياس عن بُعد، وبشأن حماية سرية بيانات القياس عن بُعد.
  • تظل السمات التي تضيفها بنفسك خاضعة لقائمة السماح. تبقى مسؤولًا عن عدم إدخال قيم حساسة تحت مفتاح مسموح به. على سبيل المثال، لا تضع معرِّف مستخدم داخل pdf.output_profile.
  • المفاتيح المهيكلة، لا الحمولات الحرة، هي التي تحمل التفاصيل التشخيصية. وهذا هو الانضباط نفسه الذي يطبِّقه ⁨PSR-3⁩ §1.2 على سياق السجل.
العبارةالمواصفةالبند⁨reference_id⁩
يجب ألا تحمل بيانات القياس عن بُعد محتوى حساسًا؛ والتعامل مع معلومات التعريف الشخصية (⁨PII⁩) مطلوب.⁨NIST SP 800-92⁩§3
سرية بيانات القياس عن بُعد/السجلات ضابط صريح.⁨NIST SP 800-92⁩§3
مفاتيح السياق المهيكلة هي التي تحمل التفاصيل، لا الحمولة الحرة.⁨PSR-3⁩§1.2
يُعاد توليد /ID المُخرَج والتواريخ مع كل عملية حفظ ← ملف التعريف الدلالي.⁨ISO 32000-2⁩§14.3

تصف هذه الوصفة سلوك أدوات القياس الهندسية. وهي لا تدّعي أي شهادة امتثال. تُرسِّخ مراجع ⁨NIST SP 800-92⁩ نية التصميم القاضية بعدم وجود محتوى في بيانات القياس عن بُعد، لا ادعاء المطابقة.