Quickstart
Quickstart
Want to see the output, not just record it? Spin up a local Grafana+Tempo+Loki+Prometheus stack in one container and watch your first trace land — Local LGTM stack.
Count things
use Cbox\Telemetry\Facades\Telemetry;
Telemetry::counter('orders.created', 'Orders created')->inc();
Telemetry::counter('mail.sent')->inc(3, ['transport' => 'ses']);
Counters are monotonic and live in the shared store — increments from web requests and queue workers land in the same series.
Expose current values
Two gauge shapes, chosen by how the value is obtained:
// Observable gauge: evaluated at scrape time, nothing stored.
Telemetry::gauge('queue.depth', fn () => Queue::size());
// Push gauge: set at event time, stored.
Telemetry::gauge('cache.warmed_keys')->set(1240);
One observable callback can return many series:
Telemetry::gauge('queue.depth', fn () => [
[Queue::size('default'), ['queue' => 'default']],
[Queue::size('mail'), ['queue' => 'mail']],
]);
Measure distributions
Telemetry::histogram('checkout.duration', unit: 'ms')->record($ms);
// Or time a closure directly:
$report = Telemetry::histogram('report.duration', unit: 'ms')
->time(fn () => $generator->build());
Trace work
$result = Telemetry::span('import.customers', function ($span) {
$span->setAttribute('rows', $count);
return $importer->run();
});
Exceptions are recorded on the span and rethrown. Need manual control?
Omit the callback and ->end() yourself:
$span = Telemetry::span('long.running');
// ...
$span->end();
HTTP requests, queue jobs and DB queries are traced automatically (see configuration). Dispatched jobs continue the dispatcher's trace — the job span is a child of the dispatch site, across processes.
Emit events
Telemetry::event('autoscale.decision', [
'workers.current' => 4,
'workers.desired' => 7,
]);
Events are exported as OTLP log records, correlated to the active trace.
Where did it go?
GET /telemetry/metrics— Prometheus text format, rendered on demand.- OTLP backend — spans/events at terminate, metrics via
telemetry:flush.
Agent prompt
Have your AI assistant instrument the app's important flows:
Instrument the business-critical flows of this Laravel app with
cboxdk/laravel-telemetry (already installed; use the
Cbox\Telemetry\Facades\Telemetry facade).
First read vendor/cboxdk/laravel-telemetry/docs/getting-started/api-reference.md
and docs/core-concepts/naming.md. Then:
1. Identify the 3-5 most important domain flows (checkout, imports,
signups, ...) by reading the codebase. Propose the list before coding.
2. For each flow add: a counter for occurrences (OTel-style dot-namespaced
name, e.g. orders.created), a histogram with unit 'ms' for duration
where timing matters (prefer ->time(fn () => ...)), and
Telemetry::event() for decisions worth auditing.
3. Wrap multi-step domain operations in Telemetry::span('domain.op',
fn ($span) => ...) with bounded attributes.
4. Rules: labels must be bounded values (plan, status, queue) — never ids,
emails or URLs; do not wrap calls in try/catch; do not add spans for
HTTP requests, queue jobs or DB queries (auto-instrumented).
5. Write Pest tests using Telemetry::fake() asserting each new metric and
span (assertCounterIncremented, assertSpanRecorded, ...).
6. Run composer test and show me a summary table of every metric/span/event
added: name, type, unit, labels.