Traces, logs and metrics

Follow one slow request through every service.

Unhandled stores the spans, logs and metrics your services send over OpenTelemetry and ties them together by trace. Search for the request that went wrong, see where its time went span by span, and read what it logged on the way.

Across services
Spans join one trace through traceparent
Self time
The 5 slowest spans marked on the timeline
Logs on the trace
Each record links to its trace and span
Any OTLP metric
Gauges, sums, histograms and summaries
#custom-spans

Name the work between the queries

The AdonisJS agent traces requests, queries, mail, queue jobs and Ace commands. Wrap your own steps with record and they show up as one block in the waterfall, with the queries they ran nested inside.

  • Queries and HTTP calls made inside the callback become its children
  • A throw records the exception, marks the span as failed and rethrows
  • The span decorator traces a method without touching its body
app/services/invoice_service.ts
import { record } from '@unhandled/agent-adonisjs/helpers'

export default class InvoiceService {
  async issue(order: Order) {
    return record('invoice.issue', async (span) => {
      span.setAttribute('order.id', order.id)
      span.setAttribute('invoice.total_cents', order.totalCents)

      const invoice = await Invoice.createFromOrder(order)
      await invoice.renderPdf()
      return invoice
    })
  }
}
#logs

Logs that know which request wrote them

The AdonisJS agent forwards the Pino logger, so a logger.info() call in a controller or job arrives with the trace and span of the request that made it. Any OpenTelemetry SDK that exports logs works the same way.

  • Same trace lists the lines of one request, Same service the 10 lines either side
  • Patterns group messages once IDs, numbers and quoted strings are masked
  • The trace view lists up to 1,000 of the trace's log records under the waterfall
#metrics

Chart any metric your services send

Every OpenTelemetry metric lands in a catalog grouped by namespace. Open one to chart it with the aggregations its type allows, split by any attribute.

  • Histograms chart as percentiles, rate or sum, and cumulative counters as increases per bucket
  • Group draws the 10 largest series, with their latest, average, min and max in a table
  • Add to dashboard saves the chart with its aggregation, grouping and filters
#dashboards

A page for each kind of work

Requests, queries, external calls, jobs and cache each get a page built from the same spans. Calls are grouped into endpoints, query patterns, hosts or job names, each with its volume, errors and latency.

  • Possible N+1 query shows when a pattern runs 5 or more times in one trace
  • Drag a box on the latency heatmap to see what the slow calls have in common
  • Callers lists the routes and jobs behind a query and their share of its time
#faq

Questions

Try it on your own stack.

Every feature is on every plan, priced by the telemetry you send.