napp/xray-laravel
Napp Xray gives Laravel developers an in-app dashboard for inspecting their application's structure, browsing routes, models, and classes, and quickly debugging how everything fits together without digging through files.
Architecture fit. X-Ray tracing is a genuinely adjacent concern, not a wrapper around first-party Laravel primitives, which is the best possible fit profile for a third-party package: it can be treated as a bounded dependency with a clear seam. The caveat is that the seam is unusually wide. The package instruments by registering global middleware, subscribing to framework events (query, Redis, job, command), and wrapping the HTTP client — meaning its removal touches middleware registration, a service provider, published config, queue listeners, and potentially container bindings. Removal is a one-day job, not a one-hour job, and that should be priced in at adoption. It also means the package sits directly on the request hot path for every request in the application, so its failure characteristics become the application's failure characteristics unless it degrades cleanly.
Integration feasibility. Install mechanics are cheap and conventional: Composer, package auto-discovery, publishable config. The real work is infrastructure, not code. X-Ray requires a daemon reachable over UDP port 2000 — an ECS sidecar, an EKS DaemonSet, or the EC2 agent — plus IAM permissions (xray:PutTraceSegments, xray:PutTelemetryRecords, and xray:GetSamplingRules/GetSamplingTargets if remote sampling is used). That is a platform-team dependency, not a Laravel-team dependency, and it should be sequenced and owned as such. Note that the prior assessment in this repo references 1.7.0 migrations and config-key renames; this package ships no migrations at all, so those specific risks do not apply. The equivalent risks here are daemon availability, sampling configuration, and trace-context propagation.
Technical risk. Three risks dominate. First, subsegment volume and the 64KB segment document limit: instrumenting every database query creates one subsegment per query, so a controller with an N+1 problem produces a segment that can be truncated or rejected — you get partial traces precisely on the endpoints you most wanted to diagnose, and cost scales with query count rather than request count. Second, PII in SQL: if the DB instrumentation records statements with bindings interpolated, literal values (emails, tokens, card fragments) land in a third-party telemetry store. This must be verified before production, not after. Third, bus factor: 61 stars and a single-maintainer release cadence means we should assume we may have to fork. That is acceptable for an additive observability package with an off switch; it would not be acceptable for auth or payments.
Key questions.
X-Amzn-Trace-Id) through SQS/SNS payloads, and does the queue worker resume the trace rather than starting an orphan?enabled: false) that can be flipped by env var without a deploy?Stack fit. The package is a natural fit if and only if we are already committed to AWS-native observability. If our strategic direction is OpenTelemetry with an ADOT Collector fronting X-Ray, then adopting an X-Ray-specific SDK wrapper is a bet against our own roadmap — the collector can ingest OTLP and forward to X-Ray, and OpenTelemetry's PHP auto-instrumentation now covers Laravel. The honest framing for the decision record: this package is the fastest path to service maps and latency percentiles, and it is a deliberate step away from vendor-neutral instrumentation. For a Laravel team with no tracing today, that trade is usually worth making; the tracing capability itself is the priority.
Migration path. It is additive — no schema changes, no data migration, no lock-in at the database layer. Adopt behind a config flag with enabled driven by environment variable so it can be disabled in production without a revert. Land it in the base service provider path but verify a clean uninstall: remove the middleware from the HTTP kernel, remove the provider from config/app.php if not auto-discovered, and delete the published config. Test the uninstall once in staging so the rollback path is proven rather than assumed.
Compatibility. Confirm PHP floor, Laravel major support, and any optional integrations (Horizon for queue trace continuity, Octane, Guzzle version constraints). Guzzle major bumps are the most likely source of a transitive conflict, since the package wraps the HTTP client. If we run multi-tenant or FPM-per-request under a classic load balancer, the daemon must be reachable at 127.0.0.1:2000 from every node — verify per-environment rather than assuming.
Sequencing.
Maintenance. A single-maintainer package with 61 stars is a dependency we should expect to own eventually. That is tolerable here because the surface is bounded and the license permits forking, but it should be recorded as an explicit accepted risk with a named internal owner. Budget a small quarterly review: upstream release diff, Laravel major compatibility check, and a smoke test that traces still arrive after framework upgrades.
Support. MIT with no SLA. There is no security disclosure path to lean on, which matters less than it would for auth or storage, but it does matter because of what the package transmits: SQL statements, Redis commands, queue payload metadata, and HTTP URLs with query strings. Treat the trace store as a data-handling surface that needs the same review as an analytics SDK, and pin the version rather than floating.
Scaling. Cost is the scaling concern, not throughput. X-Ray bills per trace recorded and per segment retrieved, so the effective unit is query count per request — the N+1 endpoints become the expensive ones. Sampling rules are the primary lever and should be set before broad rollout, not after the first invoice. Separately, segment document size caps at 64KB, which in practice limits how many subsegments a single trace can carry; high-query endpoints will produce truncated traces. Consider a per-endpoint sampling policy that favors slow or erroring requests over volume.
Failure modes. The most likely failure is the quiet one: the daemon is unreachable or misconfigured, UDP packets vanish, the application looks perfectly healthy, and nobody notices telemetry is dark until the next incident — when it is missed most. Alert on trace ingest rate dropping to zero, not on application errors. Second: sampling rules defaulting to a rate that starves the reservoir during a traffic spike, so the incident you need to debug is the one that gets sampled away; force-sample-on-error should be configured explicitly. Third: missing trace-context propagation into queued jobs, which silently severs the trace at the async boundary and produces a service map that looks fine but explains nothing. Fourth: Octane state leakage across requests, which shows up as traces from one request appearing to belong to another — verify under Octane before trusting the data.
Ramp-up. Two audiences. The team installing it needs a few hours: Composer, config, daemon. The broader engineering org needs more — annotations versus metadata, trace groups, filter expressions, and how to read a service map without over-indexing on averages. Run one training session using a real slow endpoint from our own stack, and commit a short runbook covering the daemon topology, sampling policy, kill switch, and uninstall steps so this does not become tribal knowledge held by whoever wired it up.
Recommendation: adopt, gated on three verifications — PII behavior in the SQL instrumentation, clean no-op when the daemon is absent, and Octane trace-state isolation. The package itself is low-friction and the capability gap it fills is real; the decision worth escalating is strategic rather than technical, namely whether committing to X-Ray-specific instrumentation now is compatible with where we intend to be on observability in two years.
How can I help you explore Laravel packages today?