Skip to content

Add lazy telemetry instruments#7

Merged
ChiragAgg5k merged 2 commits into
mainfrom
fix/lazy-instruments
May 29, 2026
Merged

Add lazy telemetry instruments#7
ChiragAgg5k merged 2 commits into
mainfrom
fix/lazy-instruments

Conversation

@ChiragAgg5k
Copy link
Copy Markdown
Member

@ChiragAgg5k ChiragAgg5k commented May 29, 2026

Summary

  • Add lazy() factory methods to Counter, Gauge, Histogram, and UpDownCounter.
  • Defer adapter-backed instrument creation until the first add() or record() call.
  • Add test coverage proving lazy instruments are not registered before first use and reuse the same inner instrument afterward.

Why

Some OpenTelemetry SDKs register instruments with the meter as soon as they are created. Periodic export then walks every registered instrument, even if the application never recorded data for it. In downstream packages with many rare/event-driven metrics, that can produce empty metric streams and dropped/filtered output noise for instruments that were only registered eagerly.

The intended behavior for event-driven instruments is different: if an event never happens, the instrument should not be registered or exported at all. A counter for fallback executions, transition events, callback failures, or an event timestamp should appear only after the first matching event is recorded.

This PR adds lazy factories at the instrument abstraction layer instead of changing adapters. Adapters continue to represent telemetry backends such as OpenTelemetry, test, or none. Laziness is an instrument lifecycle policy, so callers can opt into it explicitly while still receiving the same abstract instrument type.

Example usage:

$requests = $telemetry->createCounter('http.requests', '{request}');
$rareEvents = Counter::lazy($telemetry, 'rare.events', '{event}');

This keeps steady-state instruments eager where a zero value is meaningful, while allowing event-driven instruments to avoid registration until they actually emit data.

Testing

  • composer test -- --filter LazyInstrumentTest
  • composer check
  • composer lint

@greptile-apps
Copy link
Copy Markdown

greptile-apps Bot commented May 29, 2026

Greptile Summary

This PR adds lazy() static factory methods to all four instrument types (Counter, Gauge, Histogram, UpDownCounter), completing the pattern uniformly across the telemetry abstraction. Each factory returns an anonymous class that defers adapter instrument creation until the first measurement call, using PHP's ??= operator for thread-safe (single-threaded) one-time initialization.

  • All four instruments share a consistent implementation: the anonymous inner class stores constructor parameters and calls the corresponding Adapter::create*() method only on the first add() or record() invocation, then reuses the same inner instance for all subsequent calls.
  • A new LazyInstrumentTest covers all four types, asserting no adapter registration occurs before first use and that the same inner object is reused on repeated calls.

Confidence Score: 5/5

The change is additive — no existing behaviour is modified, only new lazy() factory methods are introduced alongside well-targeted tests.

All four instruments receive a consistent, minimal implementation with a single null-coalescing assignment guarding deferred creation. Each abstract method is correctly satisfied, all constructor parameters are forwarded faithfully to the adapter, and the test suite validates both the deferred-registration guarantee and inner-instance reuse for every instrument type.

No files require special attention.

Important Files Changed

Filename Overview
src/Telemetry/Counter.php Adds lazy() static factory returning an anonymous class that defers createCounter() until first add() call via ??=
src/Telemetry/Gauge.php Adds lazy() static factory with identical deferred-creation pattern, delegating to createGauge() on first record() call
src/Telemetry/Histogram.php Adds lazy() static factory consistent with other instruments, deferring createHistogram() to first record() call
src/Telemetry/UpDownCounter.php Adds lazy() static factory consistent with other instruments, deferring createUpDownCounter() to first add() call
tests/Telemetry/LazyInstrumentTest.php New test file covering all four lazy instruments: verifies no registration before first use and same inner instance reused on subsequent calls

Reviews (2): Last reviewed commit: "Add lazy factories for remaining instrum..." | Re-trigger Greptile

Comment thread src/Telemetry/Counter.php
@ChiragAgg5k ChiragAgg5k merged commit e0630df into main May 29, 2026
6 checks passed
@ChiragAgg5k ChiragAgg5k deleted the fix/lazy-instruments branch May 29, 2026 11:57
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants