Ga naar inhoud
getnextpdf.com

Enterprise editie

Metering — Diepe referentie

De NextPDF\Enterprise\Metering-namespace levert usage-metering op orchestratieniveau voor billing-zichtbaarheid en audit. Het publieke oppervlak bestaat uit zes symbolen: MeterCollector, MeterEntry, MeteringReporter, MeteringBackendInterface, PrometheusMeteringBackend, en PrometheusPushgatewayException. De collector buffert onveranderlijke entries in het geheugen en flusht ze in batches. De reporter verspreidt elke batch naar een of meer backends met retry en failure-isolatie per backend. Metering is best-effort en niet-fataal: een uitval van een metering-backend degradeert de waarneembaarheid, nooit de documentverwerking. Deze stream is niet de gezaghebbende bron voor quota-handhaving. Zie voor de gids op workflow-niveau Metering.

Deze capaciteit wordt meegeleverd in NextPDF Enterprise (nextpdf/enterprise) en activeert met een licentie-envelope op Enterprise-niveau. Een deployment zonder dat recht laadt de klassen van de capaciteit niet. Vergelijk edities en vraag een licentie aan.

Metering is een basis-Enterprise-capaciteit die beschikbaar is zodra het Enterprise-pakket is geïnstalleerd; er is geen afzonderlijke flag per functie. NextPDF Core (Apache-2.0) en NextPDF Pro hebben geen collector-, reporter- of backend-oppervlak; het contract wordt alleen meegeleverd in nextpdf/enterprise.

SymboolParametersStandaardgedragRetourneertGooit of faalt metNotities
MeterCollector::__constructMeteringReporter $reporter, int $bufferSize = 100Maakt een collector met een lege in-memory bufferNieuwe MeterCollectorGooit niet$bufferSize is gedocumenteerd als positive-int
MeterCollector::recordstring $operation, int $count, string $tenantId, string $licenseId, int $pagesProcessed = 0, float $durationMs = 0.0, array $metadata = []Voegt één onveranderlijke MeterEntry toe, gestempeld met de huidige tijd; flusht automatisch wanneer de buffer $bufferSize bereiktvoidGooit niet; een auto-flush delegeert naar de reporter, die nooit gooitTimestamp wordt genomen op het moment van record
MeterCollector::flushDraagt alle gebufferde entries over aan de reporter; lege buffer is een no-opvoidGooit niet; backend-fouten worden geabsorbeerd door de reporterBuffer wordt verwisseld vóór de overdracht; re-entrant veilig
MeterCollector::bufferCountRetourneert het aantal gebufferde entriesint<0, max>Gooit nietDiagnostiek en back-pressure-beslissingen
MeterCollector::registerShutdownFlushRegistreert flush() via register_shutdown_functionvoidGooit nietRoep één keer aan bij de bootstrap in PHP-FPM-deployments
MeterEntry::__constructstring $operation, int $count, DateTimeImmutable $timestamp, string $tenantId, string $licenseId, int $pagesProcessed = 0, float $durationMs = 0.0, array $metadata = []Slaat de opgegeven waarden letterlijk opNieuwe MeterEntryGeen gedeclareerde @throws; PHP werpt TypeError bij niet-overeenkomende argumenttypen onder strict_typesfinal readonly; alle acht gepromoveerde properties zijn public
MeteringReporter::__constructlist<MeteringBackendInterface> $backends, int $maxRetries = 2, LoggerInterface $logger = new NullLogger()Valideert en bewaart de backend-lijstNieuwe MeteringReporterInvalidArgumentException wanneer $backends leeg is$maxRetries telt het totale aantal leverpogingen per backend
MeteringReporter::reportlist<MeterEntry> $entriesLevert de batch onafhankelijk aan elke backend, met retry per backendvoidGooit niet; uitgeputte pogingen loggen op error-niveau en droppen de batch van die backendLege lijst is een no-op
MeteringBackendInterface::reportlist<MeterEntry> $entriesLevert een batch aan de backendvoidRuntimeException wanneer de backend onbereikbaar isImplementaties MOETEN idempotent zijn (dedupe op timestamp + operation + tenantId)
MeteringBackendInterface::isHealthyBereikbaarheidsprobeboolGeen gedeclareerde @throwsAlleen diagnostiek; de reporter gatet er niet op
MeteringBackendInterface::backendNameDiagnostische backend-naamnon-empty-stringGeen gedeclareerde @throwsBijvoorbeeld "prometheus", "billing-api", "null"
PrometheusMeteringBackend::__constructClientInterface $httpClient, RequestFactoryInterface $requestFactory, StreamFactoryInterface $streamFactory, string $pushgatewayUrl, string $jobName = 'nextpdf_metering'Configureert een Pushgateway-push-targetNieuwe PrometheusMeteringBackendGooit nietPSR-18-client en PSR-17-factories worden geïnjecteerd
PrometheusMeteringBackend::reportlist<MeterEntry> $entriesAggregeert de batch per operation-en-tenant-serie en POST’t expositietekst naar <pushgatewayUrl>/metrics/job/<jobName>voidPrometheusPushgatewayException bij een niet-2xx-status of een PSR-18-transportfoutLege lijst is een no-op
PrometheusMeteringBackend::isHealthyProbeert het Pushgateway-health-endpoint; true alleen bij HTTP 200boolGooit niet; elke fout retourneert falseRead-only GET-probe
PrometheusMeteringBackend::backendNameRetourneert "prometheus"non-empty-stringGooit nietConstant
PrometheusPushgatewayExceptionSignaleert een mislukte Pushgateway-leveringIs de throwablefinal; extends 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 {}

Publieke readonly properties van MeterEntry

PropertyTypeBetekenis
$operationnon-empty-stringOperatietype, bijvoorbeeld "parse", "compress", "embed", "rag_query"
$countpositive-intAantal verbruikte units
$timestampDateTimeImmutableWanneer de operatie plaatsvond; de collector stempelt het op het moment van record
$tenantIdnon-empty-stringTenant-identifier
$licenseIdnon-empty-stringLicentie-identifier
$pagesProcessedint<0, max>Verwerkte PDF-pagina’s; 0 voor niet-PDF-operaties
$durationMsfloatOperatieduur in milliseconden
$metadataarray<string, mixed>Vormvrije operatiespecifieke metadata
  • MeterCollector::record() construeert één onveranderlijke MeterEntry, stempelt deze met de huidige tijd, en voegt deze toe aan de in-memory buffer. Wanneer de buffer $bufferSize entries bereikt, flusht de collector automatisch.
  • flush() is idempotent en re-entrant veilig. Een lege buffer is een no-op. De buffer wordt verwisseld voordat de batch aan de reporter wordt overgedragen, zodat een re-entrante flush niet dubbel kan verzenden.
  • MeteringReporter weigert constructie met een lege backend-lijst. Die InvalidArgumentException is de enige exceptie op het collector-/reporter-pad.
  • MeteringReporter::report() levert elke batch onafhankelijk aan elke backend. Een falende backend verhindert nooit dat een andere backend dezelfde batch ontvangt.
  • $maxRetries telt het totale aantal leverpogingen per backend; de standaard van 2 betekent één initiële poging plus één retry. Elke mislukte poging logt een waarschuwing met de backend-naam, het pogingnummer en het aantal entries.
  • Wanneer de laatste poging voor een backend faalt, logt de reporter aanvullend op error-niveau met het aantal gedropte entries en gaat dan verder. Deze gooit nooit vanuit report(), dus aanroepers mogen levering niet afleiden uit een normale retour.
  • Backends MOETEN idempotent zijn. Het interfacecontract vereist deduplicatie op basis van timestamp, operation en tenant-identifier. De reporter zelf dedupliceert niet.
  • PrometheusMeteringBackend::report() aggregeert de batch in series per operatie en per tenant en POST’t Prometheus-tekstexpositie naar <pushgatewayUrl>/metrics/job/<jobName> met Content-Type text/plain; version=0.0.4. De standaard job-naam is nextpdf_metering.
  • De gepushte payload draagt drie counters — nextpdf_operations_total, nextpdf_pages_processed_total en nextpdf_operation_duration_ms_total — elk gelabeld per operatie en tenant.
  • Deze meteringstream is niet-gezaghebbend. Quota-handhaving en gezaghebbende compute-metering consumeren het afzonderlijke gezaghebbende gebruikscijfer van de deployment, nooit deze buffer. Een gat in de orchestratiemetering is een waarneembaarheidsgat, geen billing-correctheidsgat.
  • Gedupliceerde of opnieuw afgespeelde batch. Geabsorbeerd door backend-idempotentie; de reporter dedupliceert niet. Vertrouw niet op exactly-once-levering.
  • Uitgeputte retries. De batch voor die backend wordt gedropt en gelogd op error-niveau. Een normale retour van report() of flush() impliceert nooit levering.
  • Procesafsluiting vóór flush. De buffer is alleen in het geheugen. Een crash, of een afsluiting zonder geregistreerde shutdown-handler, verliest de gebufferde entries.
  • Worker-model-mismatch. PHP-FPM-deployments roepen registerShutdownFlush() één keer aan bij de bootstrap, zodat de rest flusht aan het einde van de request. Langlopende workers (Octane, Symfony worker, queue worker) moeten in plaats daarvan flushen op een periodieke timer; anders accumuleren entries totdat het worker-proces afsluit.
  • $bufferSize onder 1. Schendt het gedocumenteerde positive-int-contract; het waarneembare resultaat is een flush bij elke record()-aanroep.
  • Gevoelige metadata. $metadata is vormvrij en kan gevoelige operatiecontext dragen. Opslag, bewaring en toegangscontrole zijn de verantwoordelijkheid van de backend-operator.
  • Pushgateway-leveringsfout. Een niet-2xx-respons werpt PrometheusPushgatewayException met de HTTP-status en de responsbody; een PSR-18-transportfout wordt in hetzelfde exceptietype verpakt. De retry-en-isolatielus van de reporter absorbeert beide.
  • Health-probe. PrometheusMeteringBackend::isHealthy() doet een GET tegen <pushgatewayUrl>/-/healthy en retourneert true alleen bij HTTP 200. Elke transportfout retourneert false; de probe gooit nooit.
  • Vijandige labelwaarden. Backslash-, dubbele-aanhalingsteken- en line-feed-tekens in operation- of tenant-waarden worden bij emissie geëscaped, zodat een labelwaarde geen extra expositieregels kan injecteren of het labelblok kan corrumperen.
  • FIPS-modus. De collector en de reporter voeren geen cryptografische bewerkingen uit en hebben geen FIPS-specifiek gedrag. Een backend die in transit ondertekent of versleutelt erft de FIPS-positie van zijn host-crypto-provider.

Geen externe standaard beheerst het in-process collector-, reporter- of backend-contract; er is geen normatieve specificatie om te citeren, dus deze pagina draagt by design geen RAG-citatie. De Prometheus-backend zendt het Prometheus-tekstexpositieformaat uit en pusht met Content-Type text/plain; version=0.0.4; dat formaat is een ecosysteemconventie in plaats van een ISO- of IETF-standaard, en de claim is gegrond in de productbron. NextPDF doet geen conformiteits- of certificeringsclaim voor dit oppervlak.

  • Alle klassen declareren strict_types=1 en zijn final; MeterEntry is final readonly met gepromoveerde public properties. Niet-overeenkomende argumenttypen werpen een PHP TypeError in de aanroeper.
  • De moduleklassen dragen een pakket-@since-annotatie van 2.1.0; PrometheusPushgatewayException draagt @since 3.2.0.
  • De logger van de reporter valt standaard terug op een PSR-3 NullLogger. Injecteer een echte logger in productie, anders laten gedropte batches geen spoor na.
  • Unit-testen: implementeer een nep-MeteringBackendInterface en construeer MeterEntry-waarden direct. De Prometheus-backend neemt PSR-18/PSR-17-abstracties, dus een mock-HTTP-client oefent het volledige push-pad offline uit.
  • Aanbevolen grenstests: buffer exact op $bufferSize, re-entrante flush, flush van lege buffer, één backend die faalt terwijl een tweede slaagt, en logging bij retry-uitputting.
  • Backend-implementeerders werpen RuntimeException (of een subklasse) bij een leveringsfout; de reporter absorbeert deze. Respecteer de idempotentie-eis voordat je verder stroomopwaarts retries toevoegt.

Deze pagina documenteert alleen extern waarneembaar gedrag en het ondersteunde publieke API-oppervlak. Interne namespace-paden, helperklassen, mechanismetabellen, runbook-bestandsnamen en ticketprefixen vallen buiten de scope.