kaz29/cakephp-otel-plugin
最新稳定版本:0.0.2
Composer 安装命令:
composer require kaz29/cakephp-otel-plugin
包简介
OpenTelemetry instrumentation plugin for CakePHP
README 文档
README
A CakePHP 5 plugin that adds OpenTelemetry instrumentation to your application. It uses ext-opentelemetry's zend_observer hooks to automatically generate spans for Controller and Table operations without any code changes.
Requirements
- PHP 8.3+
- CakePHP 5.x
ext-opentelemetryPECL extension
Installation
composer require kaz29/cakephp-otel-plugin
Load the plugin in config/bootstrap.php or Application::bootstrap():
$this->addPlugin('OtelInstrumentation');
Instrumented Targets
| Target | Span name example |
|---|---|
Controller::invokeAction |
App\Controller\UsersController::index |
Table::find |
Users.find(all) |
Table::save |
Users.save |
Table::delete |
Users.delete |
Excluding Instrumentation
Some endpoints — health checks called every few seconds by load balancers and orchestrators, for example — generate high volumes of low-value spans that bloat your telemetry backend. You can opt out specific Controller/action pairs from instrumentation:
// config/bootstrap.php or config/app_local.php use Cake\Core\Configure; Configure::write('OtelInstrumentation.exclude', [ // Skip every action on HealthController (health/readiness/liveness probes) ['controller' => \App\Controller\HealthController::class, 'action' => '*'], // Skip a specific action while leaving others instrumented ['controller' => \App\Controller\PostsController::class, 'action' => 'ping'], ]);
Matching is exact — controller must be the fully-qualified class name and action must match the action name verbatim. The single exception is 'action' => '*', which matches every action of that controller. '*' is not allowed on controller.
While an excluded action is executing, child Table::find/save/delete calls and custom-hook spans are also suppressed, so a single rule cleans up the whole subtree. Once the action returns, instrumentation resumes for subsequent requests.
This setting only affects HTTP requests dispatched through Controller::invokeAction. CLI commands are not instrumented in the first place.
Custom Instrumentation
You can instrument any class method by registering custom hooks. The plugin uses the same \OpenTelemetry\Instrumentation\hook() mechanism as the built-in Controller/Table instrumentation.
Note:
Controller::invokeAction,Table::find,Table::save, andTable::deleteare already instrumented by the plugin. Do not register them as custom hooks — doing so would create duplicate spans.
Via Configure (simple)
// config/bootstrap.php or config/app_local.php use Cake\Core\Configure; use OpenTelemetry\API\Trace\SpanKind; Configure::write('OtelInstrumentation.hooks', [ // Minimal — span name auto-generated as "App\Service\PaymentService::charge" ['class' => \App\Service\PaymentService::class, 'method' => 'charge'], // With options [ 'class' => \App\Service\PaymentService::class, 'method' => 'refund', 'spanName' => 'payment.refund', 'kind' => SpanKind::KIND_CLIENT, 'attributes' => ['payment.provider' => 'stripe'], ], ]);
Via static registration (advanced)
Use CustomInstrumentation::register() when you need dynamic attributes via callback:
// In Application::bootstrap(), before $this->addPlugin('OtelInstrumentation') use OtelInstrumentation\Instrumentation\CustomInstrumentation; use OpenTelemetry\API\Trace\SpanKind; CustomInstrumentation::register( \App\Service\PaymentService::class, 'charge', spanName: 'payment.charge', kind: SpanKind::KIND_CLIENT, attributes: ['payment.provider' => 'stripe'], attributeCallback: fn($instance, $params, $class, $function) => [ 'payment.amount' => $params[0] ?? null, ], );
Options
| Option | Type | Default | Description |
|---|---|---|---|
class |
string |
(required) | Fully qualified class name |
method |
string |
(required) | Method name to hook |
spanName |
string|null |
FQCN::method |
Custom span name |
kind |
int |
KIND_INTERNAL |
SpanKind constant |
attributes |
array |
[] |
Static span attributes |
attributeCallback |
Closure|null |
null |
fn($instance, $params, $class, $function): array — use register() instead of Configure for this option |
Environment Variables
OTEL_PHP_AUTOLOAD_ENABLED=true OTEL_SERVICE_NAME=my-cakephp-app OTEL_TRACES_EXPORTER=otlp OTEL_EXPORTER_OTLP_PROTOCOL=http/protobuf OTEL_EXPORTER_OTLP_ENDPOINT=http://localhost:4318
OtelErrorLoggingMiddleware
A PSR-15 middleware that catches 500-level exceptions and emits them as OpenTelemetry log records. The log is automatically associated with the current span, so you can view related errors directly in your trace backend (Jaeger, Grafana Tempo, etc.).
HttpExceptionwith status code >= 500: loggedHttpExceptionwith status code < 500 (e.g. 404): not logged- Non-
HttpException(unexpected errors): logged as 500
Setup
Add it after ErrorHandlerMiddleware in your Application::middleware():
use OtelInstrumentation\Middleware\OtelErrorLoggingMiddleware; public function middleware(MiddlewareQueue $middlewareQueue): MiddlewareQueue { $middlewareQueue ->add(new ErrorHandlerMiddleware()) ->add(new OtelErrorLoggingMiddleware()) // ... ; }
TraceAwareLogger
A PSR-3 LoggerInterface decorator that automatically injects trace_id / span_id into log context.
$logger = new \OtelInstrumentation\Log\TraceAwareLogger($existingPsr3Logger);
License
MIT
统计信息
- 总下载量: 25
- 月度下载量: 0
- 日度下载量: 0
- 收藏数: 0
- 点击次数: 2
- 依赖项目数: 0
- 推荐数: 0
其他信息
- 授权协议: MIT
- 更新时间: 2026-03-28