Skip to content

Repository files navigation

lookout

Self-hosted, Sentry-compatible error tracking — small enough to read in an afternoon.

Your services already use @sentry/node? Change one line (the DSN) and errors flow into your own server. No SDK to swap, no vendor account, no per-seat pricing.

  • Sentry SDK compatible — speaks the Sentry envelope protocol (/api/<project>/envelope/) and the legacy store endpoint. Tested with @sentry/node v7.
  • Issue grouping — events are fingerprinted by exception type + stack frames (line-number agnostic, so redeploys don't split issues) and grouped into issues with first/last seen and counts.
  • Web dashboard — issue list with search and status tabs, stack trace viewer with source context, breadcrumbs, tags, event history, 24h frequency chart. Works on a phone: triage from bed without pinch-zooming.
  • Webhook alerts — new issues and regressions post Slack-compatible JSON to a per-project webhook.
  • Boring stack — Node + Fastify + PostgreSQL. One container plus Postgres.

Quick start

git clone https://github.com/datamaker/lookout.git
cd lookout
docker compose up -d --build

Open http://localhost:9000 — the first visit walks you through creating the admin account. Then create a project and copy its DSN into your app:

const Sentry = require('@sentry/node');

Sentry.init({
  dsn: 'http://<public-key>@localhost:9000/1', // from the project settings page
  environment: process.env.NODE_ENV,
});

That's it — Sentry.captureException(err) and unhandled errors now land in lookout.

No Sentry SDK? Use @datasee/lookout

If you'd rather not pull in the full Sentry SDK, @datasee/lookout is a zero-dependency client (~6 kB) that lives in sdk/:

npm install @datasee/lookout
const lookout = require('@datasee/lookout');
lookout.init({ dsn: 'http://<public-key>@localhost:9000/1' });
lookout.captureException(new Error('boom'));

Uncaught exceptions and unhandled rejections are captured automatically; breadcrumbs, tags, user context, source context lines, and an Express error handler are included. See sdk/README.md.

Configuration

Env var Default Description
PORT 9000 HTTP port
DATABASE_URL postgres://lookout:lookout@localhost:5434/lookout PostgreSQL connection string
JWT_SECRET (auto-generated, persisted in DB) Session token signing secret. Set it only if you rotate DBs.
LOOKOUT_PUBLIC_URL (empty) Public base URL, used for DSNs shown in the UI and links in alerts, e.g. https://lookout.example.com
LOOKOUT_RETENTION_DAYS 90 Raw events older than this are deleted hourly. Issues are kept.

What it accepts

Endpoint Behavior
POST /api/<project>/envelope/ Sentry envelope (gzip/deflate ok). event items are stored; transactions, sessions, and client reports are accepted and dropped.
POST /api/<project>/store/ Legacy single-event JSON.

Authentication uses the DSN public key (X-Sentry-Auth header or sentry_key query param), so any Sentry SDK that can target a custom DSN should work — @sentry/node, @sentry/browser, sentry-python, etc. Only v7-style error events are officially tested.

Development

npm install
docker compose -f docker-compose.dev.yml up -d   # postgres on :5434
npm run dev        # API server on :9000 (runs migrations on boot)
npm run dev:web    # Vite dev server on :5180, proxies /api

npm run build builds the dashboard into web/dist and the server into server/dist; the server serves the dashboard statically when web/dist exists.

Design notes

  • Grouping: default fingerprint is sha256(exception type + (module:function) of up to 8 innermost in-app frames). Custom fingerprint arrays on the event are respected, including {{ default }}.
  • Regressions: an event arriving for a resolved issue reopens it and fires the webhook again.
  • Auth model: email/password accounts with two roles — admin (manage projects, webhooks, members) and member (view and triage issues). The first visit creates the admin account; admins add members from the dashboard. Sessions are 7-day JWTs (bcrypt-hashed passwords). Ingestion is authenticated per-project by DSN key, independent of user accounts.

Non-goals (for now)

Performance tracing, session replay, source map processing, multi-user/teams, SSO. If you need those, use Sentry — this project exists for the "I just want error tracking on my own box" case.

License

MIT © JungBin Kwon

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages