Search by

koraitech / opentelemetry-php-extras

koraitech

Extra OpenTelemetry auto-instrumentation for PHP: one span per Laravel event and spans for every Redis command (phpredis and Predis).

Package info

github.com/koraitech/opentelemetry-php-extras

pkg:composer/koraitech/opentelemetry-php-extras

Statistics

Installs: 17

Dependents: 0

Suggesters: 0

Stars: 0

Open Issues: 0

v0.4.0 2026-11-14 00:00 UTC

This package is auto-updated.

Last update: 2026-11-14 00:02:16 UTC


README

Extra auto-instrumentation for PHP applications traced with OpenTelemetry. It fills in the parts of a request that the official PHP instrumentation leaves blank:

What Spans Works with
Laravel events One span per event dispatched through Illuminate\Events\Dispatcher that has listeners, named after the event: App\Events\OrderPlaced, eloquent.saving: App\Models\Page, Illuminate\Auth\Events\Login… Listeners run inside the span, so slow listeners and the queries they run are visible. Every event, as Datadog does, with KORAI_OTEL_LARAVEL_EVENTS=all. Laravel 9 to 13
Your own methods One span per call of the methods you list in KORAI_OTEL_TRACE_METHODS (App\Services\Pricing::quote), with no code change. For your own libraries, where time goes into PHP code no instrumentation knows. Any PHP application
Redis commands One client span per command (REDIS GET, REDIS HGETALL, REDIS PCONNECT…), with server address, port and database. phpredis (ext-redis, Redis and RedisCluster, PHP 8.2 or later) and Predis, in any PHP application

Nothing changes in your code: the package registers itself through Composer's autoloader.

Requirements

  • PHP 8.1 or later. Tracing the phpredis extension needs PHP 8.2 or later: older versions cannot hook methods of PHP extensions. Predis and Laravel events work on 8.1. Tested on PHP 8.1, 8.2, 8.3, 8.4 and 8.5, and Laravel 9 to 13.
  • One of:

Without either, the package does nothing.

Install

composer require koraitech/opentelemetry-php-extras

With the OpenTelemetry PHP distro

The distro keeps its own copy of the OpenTelemetry libraries apart from your application's. Enable its bridge so the spans from this package join the distro's traces:

OTEL_PHP_SCOPED_DEPS_BRIDGE_ENABLED=true

Under PHP-FPM, pass environment variables to PHP through the pool (env[NAME] = value, or clear_env = no).

With the PECL extension

Install and configure the OpenTelemetry SDK as usual (OTEL_PHP_AUTOLOAD_ENABLED=true, exporter, service name). No extra setting is needed.

Configuration

All settings are environment variables and all are optional.

Variable Default What it does
OTEL_PHP_DISABLED_INSTRUMENTATIONS Standard OpenTelemetry list. Add korai-laravel-events, korai-redis or korai-methods to turn a part off.
KORAI_OTEL_LARAVEL_EVENTS listeners Which events get a span. listeners: events with at least one listener of the application (listeners that OpenTelemetry registers itself do not count; cache hits and queries are already in the trace). all: every event, including each cache read and each model retrieved. A busy page can then send ten times more spans.
KORAI_OTEL_LARAVEL_EVENTS_EXCLUDE Comma-separated event names to skip. * matches anything: Illuminate\Log\Events\MessageLogged,eloquent.*
KORAI_OTEL_LARAVEL_EVENTS_REQUIRE_PARENT true Only create event spans inside an existing trace. Events fired while the framework boots would otherwise each start a trace of their own.
KORAI_OTEL_TRACE_METHODS Comma-separated Class::method to trace: App\Services\Pricing::quote,Vendor\Cms\Renderer::render. Each call gets an INTERNAL span named Class::method.
KORAI_OTEL_REDIS_MIN_DURATION 0 Milliseconds (2, 0.5ms). Redis commands faster than this get no span; failed commands always do. Use it when a page sends hundreds of fast reads.
KORAI_OTEL_REDIS_KEYS false Record the command and key in db.query.text (GET session:abc). Values are never recorded.

Recommended settings for Laravel

These are settings of the OpenTelemetry PHP distro and SDK, not of this package, but they make the biggest difference together with it:

# Fill time not covered by any span with spans sampled from the PHP stack (distro only)
OTEL_PHP_INFERRED_SPANS_ENABLED=true
OTEL_PHP_INFERRED_SPANS_SAMPLING_INTERVAL=20ms
OTEL_PHP_INFERRED_SPANS_MIN_DURATION=10ms

# Laravel records cache hits as span events; the default limit of 128 per span drops the rest
OTEL_SPAN_EVENT_COUNT_LIMIT=1024

# Each SQL query is traced by both the PDO and the Laravel instrumentation; keep one
OTEL_PHP_DISABLED_INSTRUMENTATIONS=pdo

If you use this package, do not call Redis::enableEvents() only to get Redis spans: with Laravel's own Redis instrumentation also active, each command would be traced twice.

Span volume

A typical Laravel page dispatches hundreds of events (every cache read, every model retrieved). The default only traces the ones your code listens to. With KORAI_OTEL_LARAVEL_EVENTS=all, use KORAI_OTEL_LARAVEL_EVENTS_EXCLUDE for events you don't need. Redis spans follow the commands your code sends: a page that reads 500 keys sends 500 spans. Keep your sampler in mind.

Span reference

Laravel events: kind INTERNAL, name = event name. Attributes: laravel.event.name, code.function.name, laravel.event.halt (for until()).

Redis: kind CLIENT, name REDIS <COMMAND>. Attributes: db.system.name (and the older db.system) = redis, db.operation.name, server.address, server.port, db.namespace (database number), db.query.text (only with KORAI_OTEL_REDIS_KEYS=true), code.function.name.

Spans are created only inside an active trace, and failures record the exception and set the span status to error.

Development

composer install
composer test:unit
# with the opentelemetry and redis extensions loaded and a Redis server on REDIS_HOST:
composer test:integration

Releases

Releases are automatic. When CI passes on main, the next version is worked out from the commit messages since the last release (Conventional Commits: feat: adds a minor version, fix: and others a patch, ! or BREAKING CHANGE a major), tagged, published as a GitHub release and sent to Packagist. Changes that only touch tests, CI or docs don't produce a release.

A daily job also checks php.net and Packagist for new PHP and Laravel versions. When one appears, it runs the full test suite on it and, if it passes, adds it to the tested versions and publishes a new minor release. If the tests fail, it opens an issue instead.

License

Apache-2.0. See LICENSE.