← All posts
Product

LLM Observability: Traces, Spend Logs, and Request Debugging

Inspect end-to-end inference traces, exact-cent spend rows, and multi-provider routing decisions under one request ID, with response headers on every call.

suresh
suresh· Senior SEO Engineer
· 11 min readUpdated
LLM Observability: Traces, Spend Logs, and Request Debugging

Direct answer: Inspect live LLM request traces, multi-provider routing attempts, and 22-column immutable spend logs under a unified request ID on nRouter.

What it does

Every LLM call flowing through nRouter is minted with a canonical request ID that binds edge arrival latency, preflight guardrail checks, provider retry attempts, and exact-cent settlement into a single queryable trace. You inspect the entire execution pipeline in the live dashboard, export request logs as CSV, or read the same identifiers from the response headers in your own code.

The one-paragraph version: if you run language models in production, your observability is usually splintered across three disconnected systems. You have application APM metrics that tell you a route took 850 milliseconds, upstream vendor dashboards that show aggregate token counts hours after the fact, and an internal billing ledger that can never quite explain why last week's invoice jumped by twenty percent. nRouter unifies these three planes at the network edge. Because every call resolves through the gateway, every request receives an authoritative x-nr-request-id header that joins its millisecond-accurate timing waterfall, its fallback route decisions, and its immutable 22-column spend row into a single audit trace.

This post covers how nRouter captures, correlates, and surfaces observability data across your AI fleet. It is deliberately not about configuring individual safety rules (guardrails on every request), not about capping team budgets (predictable AI spend), and not about comparing gateway architectures (LLM gateway buyer's guide). It assumes you are running production inference and shows how to trace every call from client arrival to financial settlement.

The job it does for you

When teams deploy multi-provider AI applications without a unified gateway, debugging production incidents degenerates into manual forensic guesswork. A user reports an intermittent timeout or a malformed completion. The engineer opens Datadog or CloudWatch, searches for an error timestamp, cross-references an internal database record, and then logs into OpenAI or Anthropic console to see if the provider experienced an outage. The timestamps never align, the token totals differ between client and server, and the cost of the failed attempt remains completely unknown.

nRouter replaces that manual triangulation with an automated request lifecycle. By sitting directly on the inference data plane, the gateway measures reality rather than estimation.

Here is how the operational workflow changes before and after implementing unified gateway observability:

Operational DimensionBefore: Fragmented Logging & Vendor ConsolesAfter: nRouter Unified Observability
Request CorrelationDisconnected client logs, proxy logs, and opaque provider request IDs.Single canonical x-nr-request-id minted at the edge and propagated end-to-end.
Upstream FallbacksSilent failovers that mask provider degradation until the primary provider fails completely.Explicit x-nr-routing (fallback:1) and x-nr-attempts headers recorded on every call.
Spend VisibilityMonthly vendor invoices reconciled against approximate token estimations days later.Immutable 22-column spend row recorded at settlement, down to the exact hundredth of a cent.
Latency AttributionCoarse round-trip duration that bundles network transit, gateway preflight, and model generation.Granular breakdown isolating client edge transit, preflight inspection, and upstream time-to-first-token (TTFT).
Data Privacy (PII)Accidental logging of raw user prompts or sensitive customer completions in APM spans.Strict zero-prompt retention in telemetry; all traces redact payload text and credentials by default.

This architectural clarity transforms three critical engineering workflows:

  1. Incident Response During Provider Outages: When an upstream provider experiences elevated latency or HTTP 503 errors, nRouter automatically executes your configured fallback chain. Instead of wondering whether your code broke, your engineers see the exact provider attempt count (x-nr-attempts: 2) and routing outcome (x-nr-routing: fallback:1) directly in response headers and the live dashboard.
  2. FinOps and Margin Auditing: Because settlement happens at the exact list price of the served model with zero token markup, your finance team can attribute every cent of cost to specific teams, virtual keys, and end-user identifiers without waiting for end-of-month cloud bills.
  3. Performance Optimization: You can pinpoint whether latency regressions stem from slow client payloads, preflight safety evaluations, or upstream provider queues.

How it works

nRouter's observability architecture operates as a developer flow and dashboard triad. Rather than requiring developers to install intrusive SDKs or monkey-patch HTTP clients, observability is built directly into the standard HTTP wire contract and the nRouter Enterprise control plane.

Developer flow and dashboard triad in nRouter LLM observability

Developer Flow and Dashboard Triad: Virtual API keys route through the edge gateway, attaching real-time correlation headers that feed the live pipeline canvas and spend ledger.

The triad consists of three tightly coupled components:

1. Edge Gateway & Correlation Headers

When a request arrives at api.nrouter.ai/v1, the gateway's Web Application Firewall (WAF) immediately mints a cryptographically unique request identifier. As the request navigates authentication, model alias resolution, preflight safety scoring, and provider dispatch, the gateway tracks its state across a structured six-stage pipeline:

llm.request -> llm.auth -> llm.preflight -> llm.provider_call -> llm.postflight -> llm.inference.persist

Every served response returns a standardized suite of x-nr-* correlation headers. Your application runtime reads these headers directly from the response object without parsing JSON bodies:

Response HeaderPossible ValuesMeaning & Operational Utility
x-nr-request-idreq_01j7x8k2m9...Canonical identifier binding all traces, spend rows, and audit logs.
x-nr-latency-msInteger (e.g. 248)Total duration in milliseconds from edge arrival until response headers are ready.
x-nr-request-costDecimal (e.g. 0.000425)Exact settled spend for the call in USD at flat provider list rates. Absent when the call is unpriced.
x-nr-cost-statusexact | unpricedWhether the cost above is a settled figure.
x-nr-input-tokens, x-nr-output-tokens, x-nr-total-tokensIntegersToken counts the provider reported for the call.
x-nr-routingdirect | fallback:<n>Indicates whether the primary model served the request or fallback index n was invoked.
x-nr-attemptsInteger (e.g. 1, 2)Total number of provider attempts initiated during the request lifecycle.
x-nr-guardrailsnone, monitor, pass, redacted, blockedOutcome of preflight content safety and prompt-injection inspection.
x-nr-response-cachehit | miss | bypassCache execution outcome; cache hits settle at reduced read rates.
x-nr-compressionapplied | skipped | offReports whether prompt compression reduced token volume before egress.

2. Spend Log and Response Headers

Unlike conventional proxies that dump unstructured text logs to stdout, nRouter records each request in two places you can use:

  • The FinOps & Audit Sink (PostgreSQL SpendLogs): Every completed or refused request writes an immutable row into an append-only PostgreSQL ledger. This row captures 22 structured columns, including tenant organization ID, team ID, virtual key hash, model alias, served model, token counts (prompt, completion, cache read), settled cost, and routing decisions. Rows are isolated with Row-Level Security (RLS) and provide verifiable accounting for per-customer LLM billing.
  • Your own APM, from your own code: nRouter does not export traces or request logs to an external collector (Datadog, Honeycomb, Grafana Tempo, or Dynatrace) today. Your application reads the x-nr-* response headers and attaches them to the spans and logs it already sends, which lets you view LLM calls alongside your database queries and microservice RPCs. Request logs can also be exported as CSV from the dashboard.

3. Live Pipeline Canvas & Request Debugger

In the nRouter management console at app.nrouter.ai, developers can open the Request Debug & Trace Canvas. For any historical or live request, the canvas renders an interactive waterfall diagram showing exactly how many milliseconds were spent in preflight safety checks, which upstream provider was contacted, whether fallback retries occurred, and the exact token breakdown.

If a request fails due to an upstream rate limit, budget ceiling, or policy block, the canvas displays the bounded machine category (RATE_LIMIT_EXCEEDED, CREDIT_EXHAUSTED, POLICY_BLOCK) without exposing customer PII or raw provider credentials.

Set it up

Enabling nRouter observability requires zero code refactoring beyond pointing your standard client to nRouter. Because the gateway is fully OpenAI-compatible, you can use the official OpenAI SDK, Anthropic SDK, LangChain, LlamaIndex, or raw HTTP requests.

Step 1: Initialize the Client with an nRouter Key

Obtain a virtual key from app.nrouter.ai and configure your environment:

import os
from openai import OpenAI

# Initialize the standard OpenAI client pointed at nRouter's gateway
client = OpenAI(
    base_url="https://api.nrouter.ai/v1",
    api_key=os.environ.get("NROUTER_API_KEY"),
)

Step 2: Make Inference Calls and Inspect Headers

When you make a request, capture the raw response headers to access real-time observability metadata directly inside your application:

# Execute chat completion targeting a managed model alias
response = client.chat.completions.with_raw_response.create(
    model="openai/gpt-4o-mini",
    messages=[
        {"role": "system", "content": "You are an enterprise data assistant."},
        {"role": "user", "content": "Summarize the quarterly financial report."},
    ],
    # Tag request for tenant-level cost attribution
    user="customer_tenant_9482",
)

# Extract nRouter correlation and observability headers
headers = response.headers
request_id = headers.get("x-nr-request-id")
latency_ms = headers.get("x-nr-latency-ms")
cost_usd = headers.get("x-nr-request-cost")
routing = headers.get("x-nr-routing")
attempts = headers.get("x-nr-attempts")
guardrails = headers.get("x-nr-guardrails")

print(f"Request ID:    {request_id}")
print(f"Latency:       {latency_ms} ms")
print(f"Settled Cost:  ${cost_usd}")
print(f"Routing Route: {routing} (attempts: {attempts})")
print(f"Guardrails:    {guardrails}")

Step 3: Query Request Traces in the Dashboard

Navigate to https://app.nrouter.ai/logs to inspect the call. You can filter requests by:

  • Request ID: Paste any req_* string to immediately load the full timeline waterfall.
  • Customer Identifier: Filter by user: customer_tenant_9482 to review all spend and requests for that tenant.
  • Routing Status: Filter by x-nr-routing: fallback:* to identify instances where the primary provider degraded and nRouter routed to a secondary model.
  • Cost & Latency Outliers: Sort by duration descending to diagnose P99 latency spikes.

Step 4: Attach the Headers to Your Own Traces (Optional)

nRouter does not push traces to a collector today. If your organization uses an APM tool like Datadog, Grafana, or Honeycomb, attach the header values from Step 2 to the span your own service already emits around the call:

from opentelemetry import trace

# Runs in your application; your existing exporter sends the span.
span = trace.get_current_span()
span.set_attribute("nrouter.request_id", request_id or "")
if cost_usd is not None:  # absent when the call is unpriced; never record 0
    span.set_attribute("nrouter.request_cost_usd", cost_usd)
span.set_attribute("nrouter.routing", routing or "")

The request ID is then searchable in your APM system and on the nRouter Logs page, so one value joins both.

Worked example with numbers

To understand the financial and diagnostic value of unified observability, consider a realistic production workload.

A customer support automation platform processes 500,000 requests per month. Their architecture uses a primary model (openai/gpt-4o-mini) with automatic fallback to an alternative model (claude-3-5-haiku) when OpenAI experiences elevated error rates or throttling. Average prompt size is 800 tokens; average completion size is 250 tokens.

Here is what nRouter's observability pipeline recorded across the 500,000 calls over a 30-day operating period:

Execution CategoryRequest CountAverage LatencySettled Cost / RequestTotal Monthly CostObservability Evidence
Direct Cache Hits85,000 (17.0%)18 ms$0.000030$2.55x-nr-response-cache: hit; settled at cache read rates.
Primary Served (gpt-4o-mini)398,500 (79.7%)340 ms$0.000270$107.60x-nr-routing: direct, x-nr-attempts: 1.
Failover Served (claude-3-5-haiku)14,200 (2.8%)620 ms$0.000800$11.36x-nr-routing: fallback:1, x-nr-attempts: 2.
Policy Blocked (Preflight Injection)2,100 (0.4%)12 ms$0.000000$0.00x-nr-guardrails: blocked; HTTP 400; $0 spent.
Provider 5xx Outages (Billed $0)200 (<0.1%)1,200 ms$0.000000$0.00Upstream 503 error; nonbilling failure row; $0 charged.
Total Operations500,000302 ms (avg)—$121.51100% reconciled to the cent.

Notice the operational insights made immediately visible by this data:

  1. Quantified Cache Savings: 85,000 calls were answered directly from the edge cache in under 20 ms, eliminating upstream provider latency while cutting per-request cost by nearly 90%.
  2. Failover Transparency: During an upstream OpenAI degradation, 14,200 requests were automatically routed to Anthropic. Without nRouter's x-nr-routing: fallback:1 tag, the team would have been blind to the provider disruption and unable to explain why those specific calls took 620 ms instead of 340 ms.
  3. Zero Financial Waste on Blocked Attacks: 2,100 prompt injection attempts were intercepted at Phase 3 preflight before touching any LLM provider. The team spent exactly $0.00 on those malicious requests.
  4. Exact Reconciliation: The total settled invoice is exactly $121.51. The finance team does not need to cross-check estimations or extrapolate token math; every single call has an immutable ledger entry.

What it costs

At nRouter, we believe that observability is fundamental infrastructure, not a luxury feature to be gated behind an enterprise paywall or monetized with a "per-span" telemetry tax.

  • Included on Every Plan: Real-time request headers, the Request Debug & Trace Canvas, and the 22-column spend log are included on every account. Whether you are on the Developer tier or an Enterprise contract, observability features are active by default.
  • Zero Token Markup: nRouter bills inference at the exact list price published by model providers (OpenAI, Anthropic, Google, AWS Bedrock). When you use gpt-4o-mini, you pay official OpenAI rates; when you use claude-3-5-haiku, you pay official Anthropic rates. A predictable 4% platform fee covers routing, observability, guardrails, and key management.
  • Request Log Retention by Plan: Request logs are kept 7 days on pay as you go, 14 days on Pro and 30 days on Max. Export the CSV for anything you need to keep longer.
  • Enterprise Self-Hosting & Dedicated Tenancy: Organizations with strict data residency requirements can deploy nRouter in their own VPC or dedicated cloud tenant via nRouter Enterprise, ensuring that all telemetry, audit rows, and credentials remain within their corporate perimeter.

Review our complete rate cards and platform tiers on Pricing.

Where it fits with the rest of the platform

Observability is the connective tissue that links every major capability in nRouter:

Limits and what it will not do

To maintain enterprise trust and high system throughput, nRouter enforces strict operational boundaries. Here is what gateway observability will not do:

  1. Zero Prompt and Completion Retention: nRouter's telemetry sinks do not store or log raw prompt text or generated completion bodies. Spans and spend logs record metadata, token counts, model aliases, HTTP status codes, and latency measurements. We do not inspect, retain, or train on your customer data.
  2. Zero Credential or Header Leakage: Provider API keys, Authorization headers, session cookies, and internal key vault secrets are strictly redacted before requests reach the logging pipeline. Even in failure logs, only bounded machine tokens (AUTH_FAILED, RATE_LIMIT_EXCEEDED) are persisted.
  3. Not an LLM Eval or Hallucination Detector: nRouter measures infrastructure performance, latency, routing fidelity, and cost. It is not an offline prompt evaluation harness or a factual accuracy scoring platform. For prompt regression testing and model evals, you should pipe nRouter's request IDs into dedicated evaluation frameworks.
  4. No Delivery to External Tools Yet: nRouter does not deliver request logs or traces to Datadog, Langfuse, an OpenTelemetry collector or any other external tool today. Logs are viewable in the dashboard and exportable as CSV; anything further is sent by your own code from the response headers.

Try it

Stop debugging multi-provider LLM applications with fragmented logs and guesswork. Sign up at app.nrouter.ai/signup , load the $5 minimum (the platform fee is charged on top) and test live request tracing today. Explore our supported models on Models, verify flat list pricing on Pricing, or contact our engineering team to discuss dedicated VPC deployments via Enterprise.

See also

Sources

Verified 2026-09-25; every external reference re-checked. Corrected 2026-10-07: an earlier version said nRouter exports OpenTelemetry traces to your collector; it does not. If something has drifted, email hello@nrouter.ai.

See also

Teams comparing gateway governance, provider-key management, and observability can review the nRouter vs Portkey comparison.

Frequently asked questions

How does nRouter correlate requests across provider retries?

When you send a request, nRouter assigns an immutable x-nr-request-id at the edge before any provider resolution occurs. If your primary provider times out or returns an HTTP 503 error, the gateway initiates a secondary attempt against the next model in your fallback list under the same request ID. Both attempts are recorded as nested child spans within the unified trace, and the final response header reports x-nr-attempts: 2 and x-nr-routing: fallback:1.

Are prompt contents or customer PII visible in the observability traces?

No. nRouter enforces a privacy-first data contract. The telemetry engine and spend database record metadata only: model aliases, token counts, millisecond latencies, and financial charges. Neither prompt text nor completion bodies are persisted to database logs. This ensures compliance with GDPR, HIPAA, and SOC 2 requirements without requiring custom redaction scripts.

Can I stream traces directly into Datadog, Grafana, or Honeycomb via OpenTelemetry?

Not today. nRouter does not export traces or request logs to an external collector or APM tool. Read the x-nr-* response headers in your own application and attach them to the spans and logs your services already send, or export request logs as CSV from the dashboard.

Does enabling observability or tracing add latency to inference requests?

No. Header calculation occurs during response streaming, and telemetry persistence is entirely asynchronous. Spend rows are queued and processed by an internal non-blocking worker pool. Even if the database connection pool experiences pressure, inference requests are served without delay.

Share
suresh
Written by suresh· Senior SEO Engineer

Senior SEO engineer at nRouter, focused on search, AEO, and content performance.