Skip to content

Latest commit

 

History

1,107 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Rustrak is a self-hosted error tracker that also takes logs, transactions, release health and AI-agent traces.

It speaks the Sentry protocol rather than a lookalike of it, so the SDK you already have points at Rustrak by changing one string. No new agent to install, no vendor library to swap, no code to rewrite. It runs as a single process with SQLite by default, which means the whole install is one compose file and nothing to provision.

wp-overview

Why Rustrak

Error tracking usually comes two ways: a SaaS bill that scales with your worst day, or a self-hosted stack that wants its own machine. Rustrak is the third option: the same protocol, on hardware you already have.

Two design decisions do most of that work. The dashboard is static files the server hands out, so one small process answers both the API and the UI, and an image built without the dashboard is a complete product on its own. And ingestion is two-phase. The endpoint parses the envelope, writes it to disk and returns 200; a spawned task then does the database work. Accepting an event never waits on the database, which is what stops a traffic spike from becoming a timeout inside your app. On a 4-core box with SQLite, a burst of 20,000 events is accepted at about 5k events per second with the server peaking under 60 MB of memory.

numbers

No per-event pricing, no sampling you did not ask for, and no seat you have to justify to anyone.

Quickstart

SQLite is the default, so this is the whole install. There is no database to provision and no broker to run.

This is the repository's docker-compose.yml:

services:
  server:
    image: rustrak/rustrak-server:latest
    ports: ["8080:8080"]
    volumes: [rustrak_data:/data]
    environment:
      - SESSION_SECRET_KEY=${SESSION_SECRET_KEY}
      - CREATE_SUPERUSER=${CREATE_SUPERUSER}
    restart: unless-stopped

volumes:
  rustrak_data:
export SESSION_SECRET_KEY=$(openssl rand -hex 32)
export CREATE_SUPERUSER=admin@example.com:changeme123
docker compose up -d

Open http://localhost:8080 and sign in with those credentials. One container answers both the dashboard and the API, so there is no second port and no address to tell one half about the other. Want the dashboard on a different host from your data? rustrak/rustrak-ui is the same dashboard behind nginx; see the production guide.

Running at scale? docker-compose.postgres.yml runs the :postgres image next to a PostgreSQL service. The installation guide has both setups and the production notes.

Point your SDK at it

Rustrak accepts the standard Sentry envelope, so migrating is a configuration change rather than a project. Create a project, copy its DSN, and change one line. Your SDK never learns it is talking to something else.

dsn
# Python
import sentry_sdk
sentry_sdk.init(dsn="http://<key>@localhost:8080/<project_id>")
// JavaScript
import * as Sentry from "@sentry/browser";
Sentry.init({ dsn: "http://<key>@localhost:8080/<project_id>" });
// Go
sentry.Init(sentry.ClientOptions{Dsn: "http://<key>@localhost:8080/<project_id>"})

Any Sentry SDK works, in any language. If you are already sending to Sentry, you can point a second DSN at Rustrak and compare the two before committing.

What's inside

Errors

Events are grouped into issues by a deterministic fingerprint: the one your SDK sent if it sent one, otherwise exception type plus the first line of the message plus the transaction. Same input, same group, every time, so an issue does not split in two after a deploy.

From the list you can triage in bulk, filter by status, and read each issue's 24-hour trend without opening anything. Upload source maps and a minified frame resolves back to the line you actually wrote.

wp-issues

AI agent traces

Turn on your SDK's AI integration and agent runs appear on their own page: runs over time, duration percentiles, top models by calls and by tokens, top tools, and a per-trace waterfall of every LLM call, tool call and handoff in order.

Rustrak reads Sentry's Spans Protocol v2, the batched format the real SDKs use for AI spans, verified against @sentry/node with the Vercel AI SDK. It also takes standalone OTel-style spans that have no parent transaction. When one agent hands off to another mid-run, the trace lists every agent involved, not just the first.

wp-agents

There is no server-side setup. One integration in Sentry.init is the whole change:

import * as Sentry from '@sentry/node';

Sentry.init({
  dsn: 'http://<key>@localhost:8080/<project_id>',
  integrations: [Sentry.vercelAIIntegration()],
});

And there is deliberately no spend widget. Per-model pricing goes stale faster than we could ship it, so Rustrak reports exact token counts and leaves the multiplication to you.

Performance

Transactions and spans flow through a processor pipeline onto a performance dashboard, ranked by p95. Latency is coloured against thresholds rather than left as raw numbers: green under a second, amber under three, red beyond. The row that needs attention is the one that looks wrong.

Open a transaction for its span waterfall and its measurements.

wp-performance

Logs

Errors tell you what broke. Logs tell you what your app was doing when it did not. Rustrak stores structured logs as a first-class event type on the same envelope endpoint, with six severities from trace to fatal, their own filter, and per-row attributes that keep their types.

A log emitted inside an active span carries the trace_id, so it links back to the request it came from.

wp-logs

Logging is off by default in Sentry SDKs. Opt in once, then use the logger:

Sentry.init({
  dsn: 'http://<key>@localhost:8080/<project_id>',
  enableLogs: true,
});

Sentry.logger.info('User signed up', { userId: 4172, plan: 'pro' });

Release health

Sessions are tracked with full Sentry SDK compatibility and aggregated per release, which turns "is this deploy worse than the last one" into two numbers: crash-free sessions and crash-free users.

Both are tiered rather than printed flat: green at 99% or above, amber at 95%, red below. A release at 96% is not fine and should not read as if it were.

wp-releases

Alerts

Alert rules fire on three events, and each rule chooses its own destination:

Trigger When it fires
new_issue A new issue is detected for the first time
regression A resolved issue reappears
unmute A muted issue is unmuted

Destinations are Slack (incoming webhook or bot token), SMTP email, or a plain JSON webhook. Credentials belong to the instance and are configured once; routing belongs to the rule.

wp-alerts

Teams, storage and retention

Projects carry three roles, Admin, Member and Viewer, with invitations, so a contractor can be given one project and nothing else.

The server also reports its own storage usage and enforces configurable retention, with manual cleanup and source-map garbage collection on demand. That matters more on a self-hosted instance than on a hosted one: nobody else is going to notice the disk filling up.

Getting around

⌘K opens a command bar over any screen. Projects and settings are two fixed sections, with the highlighted project's pages in a preview column, so Enter on a project goes to the project and its pages stay one keystroke away. Typing flattens everything into one relevance-ordered list.

From code, and from your editor

The REST API has a typed client, and the client has an MCP server over it, so an assistant can triage your instance in the same session it is writing the fix.

npm install @rustrak/client   # the REST API, typed
npx @rustrak/mcp              # Claude, Cursor, Continue
Package Version What it is
@rustrak/client npm TypeScript client. Every method returns Result<T, RustrakError> and never throws, so a call that can fail says so in its type
@rustrak/mcp npm MCP server over that client, so an assistant can read and manage your instance

The OpenAPI spec is browsable in the API reference.

Telemetry

The server sends one anonymous report every six hours: version, platform, memory, and counters such as "how many ingests were rejected" or "which routes returned 500". Never IPs, names, URLs, events or messages. It is what lets a memory regression or a new panic show up across installations after a release, and it costs one atomic increment per request.

RUSTRAK_TELEMETRY=off   # or DO_NOT_TRACK=1; either one is enough

Every field is listed in the telemetry page, and GET /api/telemetry/preview shows the exact document before it leaves.

Documentation

Getting started What Rustrak is and how it fits together
Installation Self-hosting, PostgreSQL, production notes
Configuration Every environment variable
API reference Endpoints and schemas
Architecture Two-phase ingestion, grouping, storage

Contributors

People who have contributed code, translations or documentation to Rustrak.

CONTRIBUTING.md covers the local setup, the test suite and the quality gate. Issues tagged good first issue are a reasonable place to start.

Sponsors

Rustrak has no paid tier and no hosted plan. Development is funded through GitHub Sponsors.

Scorewarrior
Scorewarrior

License

GPL-3.0. See LICENSE. Copyright © 2026 Abian Suarez.

Releases

Sponsor this project

Used by

Contributors

Languages