Most production failures are not the ones a team predicted in a dashboard meeting. Laravel observability is the ability to investigate those unknown problems from the signals the system already produces. Logs explain events, metrics show trends, and traces connect work across requests, queues, databases, and external APIs.
Structured logs need consistent context
A prose line such as “payment failed” is hard to search at scale. Use a stable event name and structured fields: request ID, release, environment, safe user or tenant identifier, provider, and error category. Context should answer which workflow failed without exposing secrets or unnecessary personal data.
Log::warning('payment.capture_failed', [
'request_id' => $requestId,
'order_id' => $order->id,
'provider' => 'example',
'error_code' => $result->code(),
]);
Pass the correlation ID into queued jobs and outbound requests. That one field often turns a multi-hour investigation into a straightforward search.
Metrics show health over time
Begin with request rate, error rate, and latency percentiles. Add database pool pressure, slow queries, queue depth and delay, worker failures, cache behaviour, and external API performance. p95 and p99 reveal poor user experiences that an average hides.
Business metrics add meaning. A normal HTTP error rate with a sudden drop in completed checkouts still deserves attention.
Traces explain where the time went
A distributed trace follows one transaction through middleware, SQL, Redis, an HTTP client, and background work. Sampling controls cost; capture more traces for errors and slow requests. Add spans around meaningful application operations, not every trivial method.
Error reporting should be actionable
Group exceptions, attach release and safe context, and distinguish a new regression from a known noisy failure. Alerts need an owner and a response. If every warning pages the team, people learn to ignore all of them.
Build alerts around user impact
Alert on sustained latency, failed payment processing, queue age, error-budget consumption, or backup failure. A CPU spike may be diagnostic context but is not always user impact. Set thresholds from normal baselines and expected traffic patterns.
Queues require their own visibility
Track time waiting before execution, processing duration, retries, failure by job type, and worker saturation. Queue length alone can mislead when job duration changes. Tag jobs with safe business identifiers and include the original request correlation ID.
Protect the observability system
Logs can contain tokens, authorization headers, payloads, and personal data if nobody defines redaction. Restrict access, set retention, and treat telemetry as sensitive production data. Control high-cardinality labels such as user IDs in metric systems; they can create severe cost and performance issues.
Create runbooks from incidents
An alert should link to the relevant dashboard, likely causes, safe diagnostic commands, rollback steps, and escalation path. After an incident, add the missing signal that would have shortened detection or diagnosis. Observability improves through use, not a one-time tool installation.
More telemetry is not automatically more clarity. Collect signals that support a decision someone is prepared to make.
Observability is part of a scalable backend, not a production add-on. The Laravel backend architecture service includes structured errors, logs, and queue monitoring in the delivery design.
Carry one correlation ID through HTTP and queue work
A useful trace begins before application code runs. HTTP middleware can accept a trusted, validated request ID from an upstream proxy or generate a new random value. It then adds the ID to log context and the response header. Validation matters because a caller-controlled value should not become an arbitrary log field or header injection vector. Keep the ID short, printable, and unrelated to a user's identity.
public function handle($request, Closure $next)
{
$incoming = (string) $request->header('X-Request-Id', '');
$requestId = preg_match('/^[A-Za-z0-9._-]{8,64}$/', $incoming)
? $incoming : (string) Str::uuid();
Log::withContext(['request_id' => $requestId]);
$request->attributes->set('request_id', $requestId);
$response = $next($request);
$response->headers->set('X-Request-Id', $requestId);
return $response;
}
Pass that value into a queued job as a constructor argument. At the start of handle(), attach it to the job's log context; do not assume request-scoped state survives serialization or a worker restart. When calling an external provider, send the ID in an agreed header only if the provider permits it. Record the provider's own request ID separately. The pair lets an operator move from a user-facing error to the application log, job log, and provider support conversation.
Choose metric names and dimensions before instrumenting
A compact starting set includes http_requests_total with route, method, and status class; http_request_duration_seconds as a histogram; queue_job_duration_seconds by job type; and queue_oldest_job_age_seconds by queue. Use route templates such as /orders/{order}, not raw URLs with IDs. Avoid user, order, and request IDs as metric labels because their unbounded values can overwhelm a time-series store.
Define what each measurement means. Is request duration measured before or after response serialization? Does queue age start at dispatch or availability after a delay? Is a retried job counted once per attempt or once per business operation? Documenting these definitions prevents dashboards from disagreeing during an incident. An error-rate alert should exclude expected validation failures if they are not service errors, while still making a sudden surge of those failures visible somewhere else.
A trace walkthrough for a slow checkout
Imagine a checkout request that returns slowly. Begin with its correlation ID and inspect the request span. Divide total time among authentication, cart lookup, order transaction, payment request, and response rendering. If the SQL span dominates, inspect query count and execution plan. If the payment span dominates, check provider latency and timeout configuration. If the HTTP response is fast but the confirmation is late, follow the linked queue job and inspect waiting time separately from execution time.
Sampling can hide an ordinary successful request, so keep aggregate metrics even when traces are sampled. Increase sampling for errors or slow paths only when the telemetry cost is understood. Never add full payment payloads, access tokens, or card data to spans. A trace should tell an engineer where to look, not become a second storage system for sensitive business records.
Alert thresholds are starting points, not universal targets
As an initial review exercise, compare current p95 latency to its normal range for the same endpoint and traffic period. Consider paging when a sustained user-facing error rate or a queue delay violates a documented service objective. A threshold such as five minutes of elevated errors is only an example; low-volume systems may need a longer window and a minimum number of requests to avoid noisy alerts. Payment or security failures may need a different response path.
Every page should identify the owner, affected user journey, dashboard, and first safe diagnostic action. Review alert history monthly: which notifications led to action, which were ignored, and which incidents produced no notification? Remove or downgrade noise and add a signal for missed incidents. This feedback loop is more valuable than continually adding charts.
Short incident runbook
- Confirm impact: affected route, tenant cohort if safely available, start time, error rate, and p95 latency.
- Check the most recent release and dependency status. Preserve the correlation IDs of representative failures.
- Follow one request across web logs, queue jobs, SQL timing, and external calls. Distinguish queue waiting from job processing.
- Mitigate with the least risky documented action, such as pausing a faulty job or rolling back a compatible release. Record the change.
- After recovery, record the missing signal, the decision it would have supported, and the owner who will add it.
The deployment guide covers release and rollback preparation; the performance audit service can turn the measurements above into an ordered investigation when latency has multiple causes.
Laravel's official logging guide documents request context and structured fields; its queue guide explains worker and retry behavior.
Frequently asked questions
What should every Laravel log include?
Environment, request or correlation ID, relevant actor or tenant identifiers, event name, and safe structured context. Never log secrets.
What is the difference between monitoring and observability?
Monitoring checks known conditions. Observability gives enough signals to investigate failures you did not predict in advance.