PHP code example of monkeyscloud / monkeyslegion-telemetry

1. Go to this page and download the library: Download monkeyscloud/monkeyslegion-telemetry library. Choose the download type require.

2. Extract the ZIP file and open the index.php.

3. Add this code to the index.php.
    
        
<?php
require_once('vendor/autoload.php');

/* Start to develop here. Best regards https://php-download.com/ */

    

monkeyscloud / monkeyslegion-telemetry example snippets


use MonkeysLegion\Telemetry\Telemetry;

Telemetry::init([
    'metrics' => ['driver' => 'memory', 'namespace' => 'myapp'],
    'tracing' => ['service_name' => 'myapp', 'exporter' => 'console'],
    'logging' => ['json' => true, 'level' => 'info'],
]);

// Metrics
Telemetry::counter('requests_total');
Telemetry::gauge('active_connections', 42);
Telemetry::histogram('response_time', 0.123);

// Tracing
$result = Telemetry::trace('fetch-user', fn () => $userRepo->find($id));

// Logging (with automatic trace correlation)
Telemetry::log()->info('User fetched', ['user_id' => $id]);

use MonkeysLegion\Telemetry\Telemetry;

// Increment by 1
Telemetry::counter('http_requests_total');

// Increment by N with dimensional labels
Telemetry::counter('http_requests_total', 1, [
    'method' => 'GET',
    'status' => '200',
]);

Telemetry::gauge('active_connections', 42);
Telemetry::gauge('queue_depth', 128, ['queue' => 'emails']);

Telemetry::histogram('response_time_seconds', 0.157);

// Custom buckets
Telemetry::histogram('payload_size_bytes', 4096, [], [
    100, 500, 1000, 5000, 10000, 50000,
]);

$stop = Telemetry::timer('db_query_duration');

$result = $db->query('SELECT ...');

$elapsed = $stop(['query' => 'user_lookup']);
// Records a histogram observation automatically

use MonkeysLegion\Telemetry\Metrics\StatsDMetrics;
use MonkeysLegion\Telemetry\Metrics\PrometheusMetrics;
use MonkeysLegion\Telemetry\Metrics\InMemoryMetrics;
use Prometheus\Storage\InMemory;

// StatsD
$metrics = new StatsDMetrics(
    host: '127.0.0.1',
    port: 8125,
    namespace: 'myapp',
    dogstatsd: true,    // DogStatsD tag format
    sampleRate: 0.5,    // 50% sampling
);

// Prometheus
$metrics = new PrometheusMetrics(
    adapter: new InMemory(),
    namespace: 'myapp',
);

// InMemory (testing)
$metrics = new InMemoryMetrics('myapp');
$metrics->counter('requests', 1, ['method' => 'GET']);
$all = $metrics->getMetrics(); // inspect recorded values

use MonkeysLegion\Telemetry\Telemetry;

$order = Telemetry::trace('create-order', function () use ($cart) {
    // Nested spans are automatically parented
    $items = Telemetry::trace('validate-items', fn () => $cart->validate());
    $payment = Telemetry::trace('charge-payment', fn () => $stripe->charge($cart));

    return new Order($items, $payment);
});

use MonkeysLegion\Telemetry\Telemetry;
use MonkeysLegion\Telemetry\Tracing\SpanKind;
use MonkeysLegion\Telemetry\Tracing\SpanStatus;

$span = Telemetry::startSpan('db.query', SpanKind::CLIENT, [
    'db.system'    => 'mysql',
    'db.statement' => 'SELECT * FROM users WHERE id = ?',
]);

try {
    $result = $db->query($sql, $params);
    $span->setStatus(SpanStatus::OK);
    $span->setAttribute('db.row_count', count($result));
} catch (\Throwable $e) {
    $span->recordException($e);
    $span->setStatus(SpanStatus::ERROR, $e->getMessage());
    throw $e;
} finally {
    $span->end();
}

$span = Telemetry::startSpan('process-order');

$span->addEvent('payment.started', ['amount' => 99.99]);
// ... process payment ...
$span->addEvent('payment.completed', ['transaction_id' => 'txn_123']);

$span->end();

use MonkeysLegion\Telemetry\Factory\TelemetryFactory;

$tracer = TelemetryFactory::createTracer([
    'service_name' => 'api-gateway',
    'exporter'     => 'http',
    'endpoint'     => 'http://jaeger:4318/v1/traces',
]);

// Extract from incoming HTTP headers
$context = $tracer->extract($request->getHeaders());

// Inject into outgoing HTTP headers
$headers = $tracer->inject([]);
// $headers = ['traceparent' => '00-<trace_id>-<span_id>-01']

use MonkeysLegion\Telemetry\Telemetry;

Telemetry::init([
    'tracing' => ['service_name' => 'api'],
    'logging' => ['json' => true, 'stream' => 'php://stderr'],
]);

Telemetry::trace('handle-request', function () {
    // trace_id and span_id injected automatically
    Telemetry::log()->info('Processing request', ['path' => '/api/users']);
    Telemetry::log()->warning('Slow query detected', ['duration_ms' => 450]);
});

// Output (JSON):
// {"level":"info","message":"Processing request","trace_id":"abc123...","span_id":"def456...","path":"/api/users","timestamp":"2026-04-27T20:00:00+00:00"}

use MonkeysLegion\Telemetry\Logging\TelemetryLogger;
use MonkeysLegion\Telemetry\Logging\StreamLogger;
use MonkeysLegion\Telemetry\Logging\JsonFormatter;
use MonkeysLegion\Telemetry\Logging\TracingContextProvider;
use Psr\Log\LogLevel;

$streamLogger = new StreamLogger(
    stream: '/var/log/app.log',
    minLevel: LogLevel::INFO,
    formatter: new JsonFormatter(prettyPrint: false),
);

$logger = new TelemetryLogger(
    logger: $streamLogger,
    contextProvider: new TracingContextProvider($tracer),
);

$logger->info('User created', ['user_id' => 42]);

// With explicit trace context
$logger->logWithTelemetry(
    level: 'info',
    message: 'Payment processed',
    context: ['amount' => 99.99],
    traceId: 'abc123',
    spanId: 'def456',
);

$logger->addProcessor(function (array $record): array {
    $record['context']['hostname'] = gethostname();
    $record['context']['pid'] = getmypid();
    return $record;
});

$logger->setDefaultContext(['app' => 'myapp', 'env' => 'production']);

use MonkeysLegion\Telemetry\Middleware\RequestMetricsMiddleware;

$middleware = new RequestMetricsMiddleware(
    metrics: $metrics,
    pp->pipe($middleware);

use MonkeysLegion\Telemetry\Middleware\RequestTracingMiddleware;

$middleware = new RequestTracingMiddleware(
    tracer: $tracer,
    propagateContext: true,  // inject traceparent in response headers
);

$app->pipe($middleware);

use MonkeysLegion\Telemetry\Attribute\Traced;
use MonkeysLegion\Telemetry\Tracing\SpanKind;

class UserService
{
    #[Traced('fetch-user')]
    public function find(int $id): User { /* ... */ }

    #[Traced(kind: SpanKind::CLIENT, attributes: ['db.system' => 'mysql'])]
    public function query(string $sql): array { /* ... */ }
}

use MonkeysLegion\Telemetry\Attribute\Counted;

class OrderController
{
    #[Counted('api_orders_total')]
    public function create(Request $request): Response { /* ... */ }

    #[Counted(labels: ['type' => 'refund'], countExceptions: true)]
    public function refund(string $orderId): void { /* ... */ }
}

use MonkeysLegion\Telemetry\Attribute\Timed;

class ReportGenerator
{
    #[Timed('report_generation_duration')]
    public function generate(string $type): Report { /* ... */ }

    #[Timed(buckets: [0.1, 0.5, 1.0, 5.0, 10.0])]
    public function export(Report $report): string { /* ... */ }
}

use MonkeysLegion\Telemetry\Factory\TelemetryFactory;

// Create individual components
$metrics = TelemetryFactory::createMetrics([
    'driver'    => 'statsd',
    'namespace' => 'myapp',
    'host'      => '127.0.0.1',
    'port'      => 8125,
    'dogstatsd' => true,
    'sample_rate' => 0.5,
]);

$tracer = TelemetryFactory::createTracer([
    'enabled'      => true,
    'service_name' => 'api',
    'sample_rate'  => 1.0,
    'exporter'     => 'http',
    'endpoint'     => 'http://jaeger:4318/v1/traces',
    'headers'      => ['Authorization' => 'Bearer token'],
]);

$logger = TelemetryFactory::createLogger([
    'stream' => 'php://stderr',
    'level'  => 'info',
    'json'   => true,
    'pretty' => false,
]);

// Or create the full stack in one call
$stack = TelemetryFactory::create([
    'metrics' => ['driver' => 'prometheus'],
    'tracing' => ['service_name' => 'api', 'exporter' => 'http'],
    'logging' => ['json' => true],
]);
// $stack['metrics'], $stack['tracer'], $stack['logger']

use MonkeysLegion\Telemetry\Telemetry;
use MonkeysLegion\Telemetry\Tracing\SpanKind;
use MonkeysLegion\Telemetry\Middleware\RequestMetricsMiddleware;
use MonkeysLegion\Telemetry\Middleware\RequestTracingMiddleware;

// ── Bootstrap ──────────────────────────────────────────────
Telemetry::init([
    'metrics' => [
        'driver'    => 'statsd',
        'namespace' => 'ecommerce',
        'host'      => 'statsd.internal',
    ],
    'tracing' => [
        'service_name' => 'order-service',
        'exporter'     => 'http',
        'endpoint'     => 'http://jaeger:4318/v1/traces',
        'sample_rate'  => 0.1,
    ],
    'logging' => [
        'json'   => true,
        'level'  => 'info',
        'stream' => '/var/log/app.log',
    ],
]);

// ── Middleware Pipeline ────────────────────────────────────
$app->pipe(new RequestTracingMiddleware(Telemetry::tracer()));
$app->pipe(new RequestMetricsMiddleware(Telemetry::metrics()));

// ── Application Code ───────────────────────────────────────
function placeOrder(Cart $cart): Order
{
    return Telemetry::trace('place-order', function () use ($cart) {
        Telemetry::log()->info('Order started', ['items' => count($cart)]);

        // Validate stock (traced)
        $stock = Telemetry::trace('check-inventory', function () use ($cart) {
            $stop = Telemetry::timer('inventory_check_duration');
            $result = InventoryService::check($cart->items());
            $stop(['warehouse' => 'us-east']);
            return $result;
        });

        // Charge payment (traced as CLIENT span)
        $payment = Telemetry::trace(
            'charge-payment',
            fn () => PaymentGateway::charge($cart->total()),
            SpanKind::CLIENT,
            ['payment.provider' => 'stripe'],
        );

        Telemetry::counter('orders_completed_total', 1, ['region' => 'us']);
        Telemetry::log()->info('Order completed', ['order_id' => $payment->orderId]);

        return new Order($stock, $payment);
    });
}

use MonkeysLegion\Telemetry\Metrics\PrometheusMetrics;
use Prometheus\Storage\Redis;
use Prometheus\RenderTextFormat;

// Shared Redis-backed storage for multi-process
$metrics = new PrometheusMetrics(
    adapter: new Redis(['host' => 'redis']),
    namespace: 'myapp',
);

// Exposition route: GET /metrics
$renderer = new RenderTextFormat();
$registry = $metrics->getRegistry();

header('Content-Type', $renderer->getMimeType());
echo $renderer->render($registry->getMetricFamilySamples());