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

القياس عن بُعد: جسر OpenTelemetry والبديل عديم الأثر

وحدة القياس عن بُعد هي الجسر الاختياري بين المحرك ومجموعة أدوات تطوير البرمجيات (⁨SDK⁩) الخاصة بـ ⁨OpenTelemetry⁩ (⁨OTel⁩). عند تثبيت ⁨SDK⁩، يُصدِر المحرك مسارات ومقاييس بسمات منقّاة. وعند غياب ⁨SDK⁩، تُبقي مجموعة كاملة من كائنات المتعقِّب والمقياس عديمة الأثر استدعاءات القياس صالحة ومن دون كلفة فعلية. يمكنك ترك أدوات القياس في مسار الشيفرة بأمان.

Terminal window
composer require nextpdf/core:^3

هدف التصميم هو إتاحة قابلية المراقبة بكلفة صفرية عند غياب ⁨SDK⁩. تستدعي المسارات الساخنة للمحرك متعقِّبًا ومقياسًا دون فحص مسبق. وما إذا كانت تلك الاستدعاءات تؤدي عملًا فعليًا يتوقف على بيئة التشغيل، لا على شرط عند كل موضع استدعاء.

OpenTelemetryInterceptor هو الجسر. يوضّح isAvailable() ما إذا كانت مجموعة ⁨OTel SDK⁩ موجودة. يحدّ startSpan(string $name, array $attributes = []) / endSpan(?object $span) عمليةً متعقَّبة، ويسجّل recordMetric() قيمة عدّاد أو مقياس. عند غياب ⁨OTel⁩، يُبلِّغ المعترِض بأنه غير متاح، وتبقى الاستدعاءات خاملة. يربط TelemetryBridge المعترِض بنقاط الرصد في المحرك.

AttributeSanitizer هو طبقة الأمان. ينظّف sanitize(array $attributes) خريطة السمات قبل أن تغادر العملية. تُعدّ سمات القياس عن بُعد قناةً شائعةً لتسرُّب المعلومات التي تُعرِّف الهوية الشخصية (⁨PII⁩) من غير قصد؛ لذلك فالتنقية جزء من العقد وليست إضافة. المُنقّي والمعترِض والجسر هي @since 2.3.0.

NullTracer، وNullSpanBuilder، وNullSpan، وNullMeter، وNullCounter، وNullHistogram هي البديل عديم الأثر. وهي تطابق أشكال الاستدعاء التي تكشفها مجموعة ⁨OTel SDK⁩: spanBuilder()، وsetAttribute() (قابلة للتسلسل)، وstartSpan()، وend()، وcreateHistogram()، وcreateUpDownCounter()، وadd()، وrecord(). وهي لا تفعل شيئًا. ولأن البديل كامل، لا تحتاج الشيفرة المزوَّدة بأدوات القياس إلى التفرّع بحسب التوافر؛ بل تستدعي المتعقِّب، فيستوعب البديل عديم الأثر الاستدعاء.

الصنفالأعضاء الرئيسيةالدور
OpenTelemetryInterceptorisAvailable()، startSpan()، endSpan()، recordMetric()جسر مسارات ومقاييس ⁨OTel⁩ (@since 2.3.0)
TelemetryBridgeربط المحركيربط المعترِض بنقاط الرصد في المحرك (@since 2.3.0)
AttributeSanitizersanitize(array $attributes): arrayينظّف السمات لحماية المعلومات التي تُعرِّف الهوية الشخصية ⁨PII⁩ (@since 2.3.0)
NullTracerspanBuilder(string $name): NullSpanBuilderمتعقِّب عديم الأثر
NullSpanBuildersetAttribute()، startSpan(): NullSpanباني مسارات عديم الأثر (قابل للتسلسل)
NullSpanend()مسار عديم الأثر
NullMetercreateHistogram()، createUpDownCounter()مقياس عديم الأثر
NullCounter / NullHistogramadd()، record()أدوات قياس عديمة الأثر

شغِّل composer docs:generate-api-php -- --module=Telemetry لتوليد جدول ⁨PHPDoc⁩ الكامل.

مثال على الشيفرة — بداية سريعة

قسم بعنوان «مثال على الشيفرة — بداية سريعة»

المصدر: 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']);

عند غياب مجموعة ⁨OTel SDK⁩، يكون كل استدعاء أعلاه عديم الأثر. تبقى الشيفرة كما هي من دون تغيير، وتكون الكلفة صفرًا.

مثال على الشيفرة — بيئة الإنتاج

قسم بعنوان «مثال على الشيفرة — بيئة الإنتاج»

غلِّف عملية العرض بسمات منقّاة كي لا تتسرّب البيانات الوصفية المقدَّمة من المُستدعي إلى أي مسار.

<?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);
}
}
}
  • البديل عديم الأثر كامل عن قصد في التصميم. لا تَحْمِ أدوات القياس باستخدام isAvailable() “لتوفير العمل”. فالبديل عديم الأثر لا يكلّف شيئًا أصلًا، والحارس يضيف التفرّع الذي يزيله هذا التصميم.
  • مرِّر دائمًا السمات المقدَّمة من المُستدعي عبر AttributeSanitizer قبل إرفاقها بمسار أو مقياس. سمات القياس عن بُعد قناة عَرَضية لتسرُّب المعلومات التي تُعرِّف الهوية الشخصية ⁨PII⁩.
  • endSpan(null) صالح: المسار الفارغ (⁨null⁩) هو حالة عديمة الأثر. اقرِن كل startSpan() بـendSpan() داخل كتلة finally.
  • NullSpanBuilder::setAttribute() يُعيد static لأجل التسلسل. وفي ظل البديل عديم الأثر، يبقى التسلسل خاملًا عن قصد في التصميم.
  • ملف قابلية إعادة الإنتاج structural: تحمل المسارات طوابع زمنية ومعرِّفات تتبُّع، لذلك يختلف تشغيلان في تلك الحقول.

عند غياب ⁨OTel⁩، تكون الكلفة استدعاء دالة إلى بديل عديم الأثر، من دون كلفة فعلية. وعند وجود ⁨OTel⁩، تأتي الكلفة من مجموعة ⁨OTel SDK⁩؛ ويضيف الجسر تنقية السمات، وهي خطّية بدلالة عدد السمات. إن performance_budget البالغ 1500 ⁨ms⁩ للزمن الجداري / 64 ⁨MB⁩ للذروة هو ميزانية المحرك المرجعية، وليس اتفاقية مستوى خدمة (⁨SLA⁩) للقياس عن بُعد.

القياس عن بُعد سطح لخروج البيانات. يُبقي AttributeSanitizer الأسرار والمعلومات التي تُعرِّف الهوية الشخصية ⁨PII⁩ خارج المسارات والمقاييس. عامِل التنقية بوصفها إلزامية لأي سمة متأثرة بالمُستدعي؛ فهذا هو التزام المشروع بالقياس عن بُعد الآمن. يرسل مُصدِّر ⁨OTel⁩ البيانات إلى خلفية خارجية، وتلك الخلفية حدّ ثقة. اضبط نقطة نهايتها وبيانات اعتمادها من مدير أسرار، لا من إعدادات مودَعة في المستودع. افترِض أن بيانات المسارات والمقاييس تصل إلى مَصرِف سجلّات، ونظّفها وفقًا لذلك. راجِع نموذج تهديد المحرك في /modules/core/security/.

لا تقدّم هذه الوحدة أي ادّعاء معياري لمواصفة تنسيق المستندات المحمولة (⁨PDF⁩). فهي تجسر إلى نموذج بيانات ⁨OpenTelemetry⁩، وهو مواصفة قابلية مراقبة خارجية، وليس بندًا من بنود ⁨PDF⁩. يُحاكي البديل عديم الأثر سطح واجهة برمجة التطبيقات (⁨API⁩) الخاصة بـ ⁨OpenTelemetry⁩ كي تبقى الشيفرة المزوَّدة بأدوات القياس قابلة للنقل. وهذه خاصية توافق على مستوى ⁨API⁩، وليست بيان مطابقة لـ ⁨PDF⁩. تُتحقَّق مطابقة المحرك بواسطة مجموعات الأوراكل والمجموعات الذهبية الموصوفة في /modules/core/conformance/.