Download the PHP package mesh0/sdk without Composer
On this page you can find all versions of the php package mesh0/sdk. It is possible to download/install these versions without Composer. Possible dependencies are resolved automatically.
Informations about the package sdk
mesh0 PHP SDK
Official PHP client for the mesh0 AI telemetry platform. Send logs, custom events, and OTLP traces; query them back with TQL.
- PHP 8.2+ with strict types and readonly DTOs
- PSR-3 logger you can drop into Laravel, Symfony, Slim, …
- PSR-18 HTTP client — bring your own (Guzzle, Symfony HTTP, …) or rely on auto-discovery
- Built-in retries for transient failures with exponential backoff + jitter
- Nested-span instrumentation —
Mesh0\Trace\Tracerfor trees of operations (no-code blocks, request handlers, job pipelines) - Low-latency UDS-DGRAM path —
~5µs/callvia the local mesh0 metrics-agent sidecar - Tested at PHPStan level 9
Installation
If you don't already have a PSR-18 client installed, add Guzzle:
Quick start
Or load configuration from the environment (MESH0_API_KEY, MESH0_BASE_URL):
Sending logs (PSR-3)
The fastest way to start streaming telemetry to mesh0 is the bundled PSR-3
logger. Plug it into any framework that takes a Psr\Log\LoggerInterface:
Context keys that map to wire-level event fields are lifted out; everything
else is merged into attributes:
| Context key | Lifted to top-level wire field |
|---|---|
event_id |
event_id |
trace_id |
trace_id |
span_id |
span_id |
parent_span_id |
parent_span_id |
Plus: exception (Throwable) writes error.type and error.message
into attributes. The interpolated message and log.level always land
in attributes. status and duration_ms are no longer special — pass
them as ordinary context keys ('status' => 'error',
'duration_ms' => 142) and they land in attributes like everything
else. Records are buffered in memory and flushed on flush(), when the
buffer fills, and on shutdown.
If you pass a Tracer to
logger(...), log records emitted inside an active span pick up
trace_id / span_id automatically when you don't supply them yourself.
The logger never throws — delivery failures are swallowed so your
request path stays alive. Pass an optional fallback PSR-3 logger if
you want visibility into why telemetry vanished:
Laravel
Symfony / Monolog
Add a psr handler pointing at the mesh0 logger service:
Sending events directly
The Event builder is fluent and immutable — every with* call returns a
new builder.
OTLP traces
mesh0 accepts OTLP/HTTP JSON at <baseUrl>/v1/traces. Point any
OpenTelemetry exporter at it with the same Bearer token:
The SDK exposes the read side:
Metrics (statsd / DogStatsD over UDS-DGRAM)
For high-frequency counters, gauges, and timings — the kind of telemetry
that shouldn't go through the request-blocking HTTPS path — point at a
co-located mesh0 metrics-agent
sidecar over its Unix datagram socket. UDP support was removed in 1.0;
the SDK speaks udg://<path> exclusively.
Set the agent's bind path once via env or Config:
The socket is opened lazily on the first send, so $mesh0->metrics()
does no I/O. Per-call override:
The agent must be configured with a matching MESH0_LISTEN_ADDR
(unix:///run/mesh0/agent.sock). Calling metrics() (or
events()->agent()) without an agentSocketPath set throws
ConfigurationException — there is no UDP loopback fallback.
Failure semantics
Datagram send failures (peer unreachable, agent not running) are
swallowed — the request path never throws on transport. Pass an optional
PSR-3 logger via new AgentMetricSink($path, $log) to surface a single
warning per state transition (open failure, write failure, oversize
drop). The open-failure latch is terminal for the lifetime of the sink —
long-lived workers that need to recover from a transient agent restart
should construct a fresh sink rather than rely on auto-reopen. Malformed
metric names or tags throw ConfigurationException so programmer errors
fail loudly in development rather than silently disappearing.
sampleRate outside (0, 1] is clamped (≤0 drops, ≥1 always emits)
rather than throwing.
Sending events over UDS-DGRAM (low-latency)
For short-lived processes (PHP request handlers, CLI workers) that can't afford an HTTPS roundtrip per event, fire events at the same metrics-agent sidecar as JSON datagrams (~5µs per call):
The socket is opened lazily on the first send. Datagrams larger than
32KB are dropped with a single warning (pass a PSR-3 logger to observe),
and transport errors are swallowed — send() never throws.
This path is at-most-once: if the local agent is down or the kernel
drops the datagram, the event is gone. For at-least-once durability, use
$mesh0->events->send(...) which POSTs to /v1/events directly.
Instrumenting nested operations (Tracer)
For trees of nested operations — no-code block executions, request → job
pipelines, anything where a parent's wall-clock includes its children —
use Mesh0\Trace\Tracer. It manages a per-execution trace_id and a stack
of span_ids, and emits exactly one event per closed span through any
EventSink (typically the same agent sink shown above):
The Tracer never injects attribute keys for you. By convention (per
the mesh0 data model) callers set attributes["span.name"] and, on the
error path, attributes["status"] / attributes["error.type"] /
attributes["error.message"] — these are normal attribute keys and the
closure form of span() leaves them entirely to you. The Tracer also
no longer auto-stamps a duration; if you want span wall time to be
queryable, write it to attributes["duration_ms"] yourself before
exit (or measure it in the manual form and pass it through).
Each enter/exit pair becomes one independent datagram on the way
out; the metrics-agent forwards them verbatim and ClickHouse reassembles
the trace via trace_id at query time. There is no "session start" or
"session end" — children always close before parents because the parent's
frame is still on the stack while children run.
Long-lived workers (FrankenPHP, RoadRunner, Swoole) must call
$tracer->reset() between requests so trace state doesn't leak across
them. A non-empty stack at reset time logs a warning through the PSR-3
logger you pass to the constructor.
Adopting an incoming trace (W3C traceparent header):
Logs that auto-correlate to the active span: pass the tracer when
building the logger and any record emitted inside a span() will pick
up trace_id / span_id automatically when not supplied in the PSR-3
context:
Querying
Pagination is also available on the events resource:
Control-plane resources
Thin wrappers over the project- and user-scoped admin endpoints. Payloads are passed through as assoc arrays — see the backend route or each method's PHPDoc for accepted fields.
POSTs that create resources without server-side Idempotency-Key
middleware (createScrubber, schema createAlias / promoteAlias /
cancelPromotion, /v1/user/* creates) are not retried — a transient
5xx would otherwise risk minting a duplicate or replaying a destructive
KILL+DROP. PATCH / PUT / DELETE retain the default retry policy.
Configuration
Environment variables
| Variable | Description |
|---|---|
MESH0_API_KEY |
API key (m0_<routing>_<secret>). Required. |
MESH0_BASE_URL |
Override base URL (self-hosted deployments). |
MESH0_AGENT_SOCKET |
Absolute path to the metrics-agent's Unix datagram socket. Required for metrics() / events->agent(). |
Custom HTTP client
Client accepts any PSR-18 client. Bring your own to share connection
pooling, plug in middleware, or run against a fake in tests:
Errors
All exceptions extend Mesh0\Exception\Mesh0Exception. The most common
subclasses are:
| Exception | Status | When |
|---|---|---|
AuthenticationException |
401 / 403 | Missing, malformed, or revoked API key. |
BadRequestException |
4xx | Payload rejected by validation. |
NotFoundException |
404 | Resource doesn't exist. |
RateLimitException |
429 | Inspect ->retryAfter. |
ServerException |
5xx | mesh0 internal error; ->errorId set. |
NetworkException |
— | Transport-level failure (DNS, TLS, …). |
ConfigurationException |
— | Invalid Config. |
The transport retries idempotent failures (5xx, 429, transport errors)
up to Config::maxRetries with exponential backoff and jitter; the
Retry-After header is honored when present.
Development
License
MIT — see LICENSE.
All versions of sdk with dependencies
ext-json Version *
psr/log Version ^2.0 || ^3.0
psr/http-client Version ^1.0
psr/http-factory Version ^1.0
psr/http-message Version ^1.1 || ^2.0
php-http/discovery Version ^1.19