Documentation

Observability

Issues

Every error your services report, grouped by root cause and tracked from detection to fix

Monocle groups the exceptions reported by your services into issues. Thousands of occurrences of the same bug become a single issue, with its stack trace, the requests and users it affected, and a status your team can act on.

Issues page listing open issues with their priority, assignees, trend, events, users, and services

How issues are created

There is nothing to set up. When an exception is reported, Monocle computes its fingerprint and attaches it to the matching issue, or opens a new one. The issue is titled after the exception type and message, such as PaymentTimeoutError: Payment provider timed out.

An issue belongs to the project and is shared by all environments: its status, priority, and assignees are the same everywhere. Its statistics (occurrences, users, trend) follow the environment, services, and time range selected in the header.

The issues list

Each row shows the issue, its priority and assignees, a trend of its occurrences, the number of events and affected users, the services that reported it, and when it was last seen.

  • Search by error type, message, or issue title.
  • Filter by status: Open (default), Resolved, Archived, or all statuses.
  • Sort by Recent, Events, or Users.

The Overview also lists open issues by reason: new, regressed, high priority, and unassigned.

Triage an issue

Issue detail page with priority, assignee, and resolve controls, occurrence stats, a chart, and the stack trace of an occurrence

From the header of an issue:

  • Priority: Low, Medium (default), High, or Critical
  • Assignees: any member with access to the project
  • Resolve once the fix is deployed, or Reopen
  • Archive, from the menu, forever or for 1 hour, 1 day, 1 week, or 30 days, to silence an issue you don't plan to fix now
  • External links, from the same menu: create or link a GitHub or Linear issue

The activity panel keeps the history of the issue (status, priority, and assignee changes, regressions) and lets your team discuss it in comments.

Lifecycle

EventWhat happens
A resolved issue gets a new occurrenceIt is reopened and flagged as regressed
An issue appears in a new environmentIt is flagged as first seen in that environment
An archive duration expiresThe issue is reopened silently
An issue is archived foreverIt never comes back and sends no notification
The linked GitHub or Linear issue is closedThe issue is resolved
No occurrence in any environment for 90 daysThe issue is deleted, unless it is archived forever

New and regressed issues are sent by email, and to Slack, Discord, or your own webhooks. See Exception rules.

Investigate an issue

The Overview tab shows the number of occurrences and identified users, when the issue was first and last seen, a chart of its occurrences, the services that reported it, and the entry points (endpoints, jobs, or commands) where it happened, with their service.

Below, the occurrence inspector opens the Best documented occurrence: the one with the most context, such as source code, a trace still available, and an identified user. Switch to Latest, or step through older and newer occurrences. Each occurrence has four tabs:

TabShows
Stack traceEach frame with the surrounding source code, your own code marked In app, and the causes
TraceThe trace of the request, job, or command that failed
ContextThe request, job, or command, the user, tags, and extra data
RawThe exception as it was received

Below the tabs, Other exceptions in this trace lists the exceptions that other spans of the same trace reported, in any service, with a link to their issue. The exceptions raised under the failing span come first. When a call to another service fails, the list shows the error that caused it in that service.

The context of an occurrence comes from the service that reported it. If the browser calls your API and the API fails, the occurrence shows the route and user of the API request, not those of the browser page.

The Occurrences tab lists every occurrence with its service, message, entry point, and user. The Users tab lists the identified users who hit the issue.

How exceptions are grouped

Monocle computes a fingerprint for each exception so that the same bug always lands in the same issue, even when its message contains IDs, dates, or emails.

  • With a stack trace, the fingerprint uses the exception type and the top frames of your own code. Frames from node_modules and Node internals are ignored, so a library upgrade doesn't split your issues.
  • With a cause chain or an AggregateError, the causes are part of the fingerprint.
  • Without a usable stack trace, Monocle falls back to the exception type and the message, with variable parts such as numbers, UUIDs, emails, URLs, and dates replaced by placeholders.

Where exceptions come from

  • With the AdonisJS agent, errors reported by your exception handler are captured automatically. You can also capture errors and messages yourself, see Users & Exceptions.
  • With the browser SDK, uncaught errors and unhandled promise rejections are captured by default.
  • With any OpenTelemetry SDK, exceptions recorded on spans with span.recordException() are picked up. See Semantic conventions.

Search documentation

Search pages and sections of the Monocle documentation