ข้ามไปยังเนื้อหา
getnextpdf.com

Enterprise รุ่น

Metering — เอกสารอ้างอิงเชิงลึก

เนมสเปซ NextPDF\Enterprise\Metering จัดส่งการวัดปริมาณการใช้งานระดับการประสานงานเพื่อ visibility ด้านการเรียกเก็บเงินและการตรวจสอบ พื้นผิวสาธารณะมีหกสัญลักษณ์ ได้แก่ MeterCollector, MeterEntry, MeteringReporter, MeteringBackendInterface, PrometheusMeteringBackend และ PrometheusPushgatewayException ตัวเก็บรวบรวมบัฟเฟอร์ entries แบบ immutable ไว้ในหน่วยความจำและ flush เป็นชุด reporter กระจายแต่ละชุดออกไปยัง backend หนึ่งตัวหรือมากกว่า พร้อม retry ต่อ backend และการแยกความล้มเหลว Metering เป็นแบบ best-effort และไม่ร้ายแรง การขัดข้องของ metering-backend ลดทอน observability ไม่เคยลดทอนการประมวลผลเอกสาร stream นี้ไม่ใช่แหล่งที่เป็นทางการสำหรับการบังคับใช้โควตา สำหรับคู่มือระดับเวิร์กโฟลว์ ดู Metering

ความสามารถนี้จัดส่งใน NextPDF Enterprise (nextpdf/enterprise) และเปิดใช้งานด้วย license envelope ระดับ Enterprise การนำไปใช้งานที่ไม่มีสิทธิ์ดังกล่าวจะไม่โหลดคลาสของความสามารถนี้ เปรียบเทียบรุ่นและรับ license

Metering เป็นความสามารถพื้นฐานของ Enterprise ที่พร้อมใช้งานเมื่อแพ็กเกจ Enterprise ถูกติดตั้ง ไม่มีแฟล็กต่อฟีเจอร์แยกต่างหาก NextPDF Core (Apache-2.0) และ NextPDF Pro ไม่มีพื้นผิว collector, reporter หรือ backend สัญญานี้จัดส่งใน nextpdf/enterprise เท่านั้น

สัญลักษณ์พารามิเตอร์พฤติกรรมเริ่มต้นคืนค่าthrow หรือ ล้มเหลวด้วยหมายเหตุ
MeterCollector::__constructMeteringReporter $reporter, int $bufferSize = 100สร้างตัวเก็บรวบรวมพร้อมบัฟเฟอร์ในหน่วยความจำที่ว่างเปล่าMeterCollector ตัวใหม่ไม่ throw$bufferSize มีเอกสารระบุเป็น positive-int
MeterCollector::recordstring $operation, int $count, string $tenantId, string $licenseId, int $pagesProcessed = 0, float $durationMs = 0.0, array $metadata = []ต่อท้าย MeterEntry แบบ immutable หนึ่งรายการที่ประทับเวลาปัจจุบัน flush อัตโนมัติเมื่อบัฟเฟอร์ถึง $bufferSizevoidไม่ throw การ flush อัตโนมัติมอบหมายให้ reporter ซึ่งไม่เคย throwประทับ timestamp ณ เวลาที่บันทึก
MeterCollector::flushส่งมอบ entries ที่บัฟเฟอร์ไว้ทั้งหมดให้ reporter บัฟเฟอร์ว่างเปล่าเป็น no-opvoidไม่ throw ความล้มเหลวของ backend ถูกดูดซับโดย reporterบัฟเฟอร์ถูกสลับออกก่อนส่งมอบ ปลอดภัยแบบ re-entrant
MeterCollector::bufferCountคืนค่าจำนวน entries ที่บัฟเฟอร์ไว้int<0, max>ไม่ throwการวินิจฉัยและการตัดสินใจ back-pressure
MeterCollector::registerShutdownFlushลงทะเบียน flush() ผ่าน register_shutdown_functionvoidไม่ throwเรียกครั้งเดียวที่ bootstrap ในการนำไปใช้งานแบบ PHP-FPM
MeterEntry::__constructstring $operation, int $count, DateTimeImmutable $timestamp, string $tenantId, string $licenseId, int $pagesProcessed = 0, float $durationMs = 0.0, array $metadata = []จัดเก็บค่าที่ให้มาตามเดิมMeterEntry ตัวใหม่ไม่มี @throws ที่ประกาศไว้ PHP จะยก TypeError เมื่อชนิดอาร์กิวเมนต์ไม่ตรงกันภายใต้ strict_typesfinal readonly พรอเพอร์ตี้ที่ promote ทั้งแปดตัวเป็น public
MeteringReporter::__constructlist<MeteringBackendInterface> $backends, int $maxRetries = 2, LoggerInterface $logger = new NullLogger()ตรวจสอบและจัดเก็บรายการ backendMeteringReporter ตัวใหม่InvalidArgumentException เมื่อ $backends ว่างเปล่า$maxRetries นับจำนวนครั้งการส่งมอบทั้งหมดต่อ backend
MeteringReporter::reportlist<MeterEntry> $entriesส่งมอบชุดข้อมูลให้ทุก backend อย่างเป็นอิสระ พร้อม retry ต่อ backendvoidไม่ throw ความพยายามที่หมดลงบันทึกที่ระดับ error และทิ้งชุดข้อมูลของ backend นั้นรายการว่างเปล่าเป็น no-op
MeteringBackendInterface::reportlist<MeterEntry> $entriesส่งมอบชุดข้อมูลให้ backendvoidRuntimeException เมื่อ backend เข้าถึงไม่ได้การนำไปใช้งานต้องเป็น idempotent (dedupe ด้วย timestamp + operation + tenantId)
MeteringBackendInterface::isHealthyprobe การเข้าถึงได้boolไม่มี @throws ที่ประกาศไว้สำหรับการวินิจฉัยเท่านั้น reporter ไม่ใช้เป็นเกต
MeteringBackendInterface::backendNameชื่อ backend สำหรับการวินิจฉัยnon-empty-stringไม่มี @throws ที่ประกาศไว้ตัวอย่างเช่น "prometheus", "billing-api", "null"
PrometheusMeteringBackend::__constructClientInterface $httpClient, RequestFactoryInterface $requestFactory, StreamFactoryInterface $streamFactory, string $pushgatewayUrl, string $jobName = 'nextpdf_metering'กำหนดค่าเป้าหมาย push ของ PushgatewayPrometheusMeteringBackend ตัวใหม่ไม่ throwclient PSR-18 และ factory PSR-17 ถูกฉีดเข้ามา
PrometheusMeteringBackend::reportlist<MeterEntry> $entriesรวมชุดข้อมูลตาม series ของ operation และ tenant และ POST ข้อความ exposition ไปยัง <pushgatewayUrl>/metrics/job/<jobName>voidPrometheusPushgatewayException เมื่อสถานะไม่ใช่ 2xx หรือความล้มเหลวการขนส่ง PSR-18รายการว่างเปล่าเป็น no-op
PrometheusMeteringBackend::isHealthyprobe endpoint สุขภาพของ Pushgateway คืนค่า true เฉพาะเมื่อ HTTP 200boolไม่ throw ความล้มเหลวใด ๆ คืนค่า falseprobe GET แบบอ่านอย่างเดียว
PrometheusMeteringBackend::backendNameคืนค่า "prometheus"non-empty-stringไม่ throwค่าคงที่
PrometheusPushgatewayExceptionส่งสัญญาณการส่งมอบ Pushgateway ที่ล้มเหลวเป็น throwablefinal สืบทอดจาก RuntimeException
public function __construct(
private readonly MeteringReporter $reporter,
private readonly int $bufferSize = 100,
) {}
public function record(
string $operation,
int $count,
string $tenantId,
string $licenseId,
int $pagesProcessed = 0,
float $durationMs = 0.0,
array $metadata = [],
): void
public function flush(): void
public function bufferCount(): int
public function registerShutdownFlush(): void
public function __construct(
public string $operation,
public int $count,
public DateTimeImmutable $timestamp,
public string $tenantId,
public string $licenseId,
public int $pagesProcessed = 0,
public float $durationMs = 0.0,
public array $metadata = [],
) {}
public function report(array $entries): void;
public function isHealthy(): bool;
public function backendName(): string;
public function __construct(
array $backends,
private readonly int $maxRetries = 2,
private readonly LoggerInterface $logger = new NullLogger(),
)
public function report(array $entries): void
public function __construct(
private readonly ClientInterface $httpClient,
private readonly RequestFactoryInterface $requestFactory,
private readonly StreamFactoryInterface $streamFactory,
private readonly string $pushgatewayUrl,
private readonly string $jobName = self::DEFAULT_JOB_NAME,
) {}
final class PrometheusPushgatewayException extends RuntimeException {}

พรอเพอร์ตี้ public readonly ของ MeterEntry

พรอเพอร์ตี้ชนิดความหมาย
$operationnon-empty-stringชนิดของ operation ตัวอย่างเช่น "parse", "compress", "embed", "rag_query"
$countpositive-intจำนวนหน่วยที่ใช้ไป
$timestampDateTimeImmutableเวลาที่ operation เกิดขึ้น ตัวเก็บรวบรวมประทับ ณ เวลาที่บันทึก
$tenantIdnon-empty-stringตัวระบุ tenant
$licenseIdnon-empty-stringตัวระบุ license
$pagesProcessedint<0, max>หน้า PDF ที่ประมวลผล 0 สำหรับ operation ที่ไม่ใช่ PDF
$durationMsfloatระยะเวลา operation เป็นมิลลิวินาที
$metadataarray<string, mixed>metadata เฉพาะ operation แบบ free-form
  • MeterCollector::record() สร้าง MeterEntry แบบ immutable หนึ่งรายการ ประทับเวลาปัจจุบัน และต่อท้ายลงในบัฟเฟอร์ในหน่วยความจำ เมื่อบัฟเฟอร์ถึง $bufferSize entries ตัวเก็บรวบรวมจะ flush อัตโนมัติ
  • flush() เป็น idempotent และปลอดภัยแบบ re-entrant บัฟเฟอร์ว่างเปล่าเป็น no-op บัฟเฟอร์ถูกสลับออกก่อนที่ชุดข้อมูลจะถูกส่งมอบให้ reporter ดังนั้นการ flush แบบ re-entrant จึงไม่สามารถส่งซ้ำ
  • MeteringReporter ปฏิเสธการสร้างด้วยรายการ backend ที่ว่างเปล่า InvalidArgumentException นั้นเป็น exception เดียวบนเส้นทาง collector/reporter
  • MeteringReporter::report() ส่งมอบแต่ละชุดข้อมูลให้ทุก backend อย่างเป็นอิสระ backend ที่ล้มเหลวจะไม่ขัดขวาง backend อื่นไม่ให้รับชุดข้อมูลเดียวกัน
  • $maxRetries นับจำนวนครั้งการส่งมอบทั้งหมดต่อ backend ค่าเริ่มต้น 2 หมายถึงหนึ่งความพยายามแรกบวกกับหนึ่ง retry ทุกความพยายามที่ล้มเหลวบันทึก warning พร้อมชื่อ backend หมายเลขความพยายาม และจำนวน entry
  • เมื่อความพยายามสุดท้ายสำหรับ backend หนึ่งล้มเหลว reporter บันทึกเพิ่มเติมที่ระดับ error พร้อมจำนวน entry ที่ถูกทิ้ง แล้วดำเนินต่อไป มันไม่เคย throw จาก report() ดังนั้นผู้เรียกต้องไม่อนุมานการส่งมอบจากการคืนค่าปกติ
  • backend ต้องเป็น idempotent สัญญาของอินเทอร์เฟซกำหนดให้มี deduplication ที่ใช้คีย์เป็น timestamp, operation และตัวระบุ tenant ตัว reporter เองไม่ทำ deduplication
  • PrometheusMeteringBackend::report() รวมชุดข้อมูลเป็น series ต่อ operation ต่อ tenant และ POST ข้อความ exposition ของ Prometheus ไปยัง <pushgatewayUrl>/metrics/job/<jobName> ด้วย Content-Type text/plain; version=0.0.4 ชื่อ job เริ่มต้นคือ nextpdf_metering
  • payload ที่ push ถือ counter สามตัว — nextpdf_operations_total, nextpdf_pages_processed_total และ nextpdf_operation_duration_ms_total — แต่ละตัวติดป้ายด้วย operation และ tenant
  • stream การ metering นี้ไม่เป็นทางการ การบังคับใช้โควตาและการ metering การประมวลผลที่เป็นทางการใช้ตัวเลขการใช้ที่เป็นทางการแยกต่างหากของการนำไปใช้งาน ไม่เคยใช้บัฟเฟอร์นี้ ช่องว่างใน metering การประสานงานคือช่องว่างด้าน observability ไม่ใช่ช่องว่างด้านความถูกต้องของการเรียกเก็บเงิน
  • ชุดข้อมูลที่ซ้ำซ้อนหรือถูก replay ถูกดูดซับโดย idempotency ของ backend ตัว reporter ไม่ทำ deduplication อย่าพึ่งพาการส่งมอบแบบ exactly-once
  • retry ที่หมดลง ชุดข้อมูลของ backend นั้นถูกทิ้งและบันทึกที่ระดับ error การคืนค่าปกติจาก report() หรือ flush() ไม่เคยหมายความว่ามีการส่งมอบ
  • process ออกก่อน flush บัฟเฟอร์อยู่ในหน่วยความจำเท่านั้น การ crash หรือการออกโดยไม่มี shutdown handler ที่ลงทะเบียนไว้จะสูญเสีย entries ที่บัฟเฟอร์ไว้
  • worker-model ไม่ตรงกัน การนำไปใช้งานแบบ PHP-FPM เรียก registerShutdownFlush() ครั้งเดียวที่ bootstrap เพื่อให้ส่วนที่เหลือ flush ที่ปลายคำขอ worker ที่ทำงานยาวนาน (Octane, Symfony worker, queue worker) ต้อง flush ด้วย timer เป็นระยะแทน มิฉะนั้น entries จะสะสมจนกระทั่ง worker process ออก
  • $bufferSize ต่ำกว่า 1 ละเมิดสัญญา positive-int ที่ระบุไว้ ผลลัพธ์ที่สังเกตได้คือการ flush ในทุกการเรียก record()
  • metadata ที่อ่อนไหว $metadata เป็น free-form และอาจถือบริบทการดำเนินการที่อ่อนไหว การจัดเก็บ การเก็บรักษา และการควบคุมการเข้าถึงเป็นความรับผิดชอบของผู้ปฏิบัติการ backend
  • ความล้มเหลวการส่งมอบ Pushgateway การตอบสนองที่ไม่ใช่ 2xx ยก PrometheusPushgatewayException ที่ถือสถานะ HTTP และเนื้อหาการตอบสนอง ความล้มเหลวการขนส่ง PSR-18 ถูกห่อไว้ในชนิด exception เดียวกัน ลูป retry-and-isolation ของ reporter ดูดซับทั้งสองอย่าง
  • health probe PrometheusMeteringBackend::isHealthy() ออก GET ไปยัง <pushgatewayUrl>/-/healthy และคืนค่า true เฉพาะเมื่อ HTTP 200 ข้อผิดพลาดการขนส่งใด ๆ คืนค่า false probe ไม่เคย throw
  • ค่า label ที่เป็นภัย อักขระ backslash, double-quote และ line-feed ในค่า operation หรือ tenant ถูก escape ตอน emit ดังนั้นค่า label จึงไม่สามารถแทรกบรรทัด exposition เพิ่มเติมหรือทำให้บล็อก label เสียหาย
  • FIPS-mode ตัวเก็บรวบรวมและ reporter ไม่ทำการดำเนินการเชิงการเข้ารหัสลับและไม่มีพฤติกรรมเฉพาะ FIPS backend ที่ลงลายเซ็นหรือเข้ารหัสระหว่างส่งจะสืบทอด FIPS posture ของ host crypto provider ของมัน

ไม่มีมาตรฐานภายนอกใดกำกับสัญญาของ collector, reporter หรือ backend ในกระบวนการ ไม่มีข้อกำหนดเชิงบรรทัดฐานให้อ้างอิง ดังนั้นหน้านี้จึงไม่ถือการอ้างอิง RAG โดยการออกแบบ backend ของ Prometheus emit รูปแบบ Prometheus text exposition และ push ด้วย Content-Type text/plain; version=0.0.4 รูปแบบดังกล่าวเป็นแบบแผนของ ecosystem มากกว่าจะเป็นมาตรฐาน ISO หรือ IETF และคำกล่าวอ้างนี้อ้างอิงจากซอร์สของผลิตภัณฑ์ NextPDF ไม่กล่าวอ้างความสอดคล้องหรือการรับรองใด ๆ สำหรับพื้นผิวนี้

  • คลาสทั้งหมดประกาศ strict_types=1 และเป็น final MeterEntry เป็น final readonly พร้อมพรอเพอร์ตี้ public ที่ promote ชนิดอาร์กิวเมนต์ที่ไม่ตรงกันยก PHP TypeError ในผู้เรียก
  • คลาสของโมดูลถือ annotation @since ของแพ็กเกจเป็น 2.1.0 PrometheusPushgatewayException ถือ @since 3.2.0
  • logger ของ reporter มีค่าเริ่มต้นเป็น NullLogger ของ PSR-3 ฉีด logger จริงในการใช้งานจริง มิฉะนั้นชุดข้อมูลที่ถูกทิ้งจะไม่ทิ้งร่องรอย
  • การทดสอบหน่วย: นำ MeteringBackendInterface ปลอมไปใช้และสร้างค่า MeterEntry โดยตรง backend ของ Prometheus รับ abstraction PSR-18/PSR-17 ดังนั้น mock HTTP client จึงรันเส้นทาง push เต็มรูปแบบแบบออฟไลน์
  • การทดสอบขอบเขตที่แนะนำ: บัฟเฟอร์พอดีที่ $bufferSize, การ flush แบบ re-entrant, การ flush บัฟเฟอร์ว่างเปล่า, backend หนึ่งล้มเหลวขณะที่ตัวที่สองสำเร็จ และการบันทึกการหมด retry
  • ผู้นำ backend ไปใช้ throw RuntimeException (หรือคลาสย่อย) เมื่อการส่งมอบล้มเหลว reporter ดูดซับมัน ปฏิบัติตามข้อกำหนด idempotency ก่อนเพิ่ม retry เพิ่มเติมที่ต้นทาง

หน้านี้บันทึกเฉพาะพฤติกรรมที่สังเกตได้จากภายนอกและพื้นผิว public API ที่รองรับเท่านั้น internal namespace paths, helper classes, ตารางกลไก, ชื่อไฟล์ runbook และ ticket prefixes อยู่นอกขอบเขต