Errors, traces, metrics, logs and uptime — on your own server
Self-hosted observability in one small Go binary. Works with stock Sentry SDKs and OTLP. Open source, Apache-2.0.
$ git clone https://gitflic.ru/project/otezvikentiy/gotcha.git
$ cd gotcha
$ docker compose up -dPoint your Sentry SDK at a new DSN — the first error arrives in seconds.
Gotcha is a self-hosted observability platform in a single Go binary: error tracking, distributed tracing, metrics, logs, profiling, uptime and server monitoring — all on your own server. It works with stock Sentry SDKs and ingests OTLP, so moving off the cloud takes about as long as changing a DSN. The UI, notifications and docs come fully in English and Russian. Open source, Apache-2.0 licensed.
Overview: everything broken on one timeline
The entry point into a project — a single feed of what is broken right now and what recently recovered, gathered from all six sources at once.
- Hosts, uptime monitors, metrics, SLOs, transaction and profile regressions — in one list
- Three status tiles: uptime over the window, hosts over threshold, new issues in the last 24 hours
- A cascading failure collapses into one card with its members instead of scattering across twenty rows
- Deploys in the window sit right beside it, so a regression gets a suspect immediately

Errors and how you dig into them
Event ingestion via the Sentry SDK protocol, automatic grouping into issues, and an issue page that shows everything about one error at once.
- Stack traces, breadcrumbs, tags and contexts; full request details — method, URL, params and headers, PII-scrubbed
- Automatic grouping, filters, assignees and the resolved and ignored states
- On the issue page: frequency chart, first and last seen, event count, copy as Markdown
- Logs around the event — one link from the error page: what the app was writing before and after
- Export the group's events as CSV, JSON or NDJSON straight from the issue card

Logs
Ingestion via OTLP/HTTP and line-delimited JSON — no separate logging stack, and no second UI to switch into.
- Full-text search over the message plus facets: severity, service, environment
- A histogram by level over the period: you see when it started before reading a single line
- Three joins: logs around an error event, logs of a trace, logs of a host
- Its own quota and its own retention — logs do not eat the budget of errors and metrics

Performance and profiles
Distributed traces and transactions, a dependency map and flamegraph profiles. Performance issues are detected by name: N+1, slow query, HTTP flood.
- Detectors name the problem and explain the fix — with the full SQL and code location
- Web Vitals: LCP, INP, CLS, FCP, TTFB
- Dependency map: databases, caches and outbound calls — p50/p95 and error rate from the traces you already collect
- Flamegraphs from Sentry profiles and pprof, plus profile regression detection
- Deploy markers on charts: a regression after a release gets an "after deploy vX" badge

Metrics, hosts and recipes
Application metrics via OTLP, system metrics of your servers, and ready-made recipes for common services: the collector config comes with the project key already filled in.
- Hosts: CPU, memory, disk, network, load average and processes — four built-in thresholds out of the box
- Recipes for PostgreSQL, MariaDB, nginx, Redis and Docker: collector config, a "data is arriving" indicator and recommended thresholds in one click
- Thresholds are overridden by environment and role labels, not only globally: prod and staging live by different rules
- Native agent: a single binary, installed with one command, works in restricted networks
- Cardinality-explosion protection — a runaway label set does not take the storage down

Uptime and status pages
HTTP checks from a built-in local region and remote probes, and every project gets its own public status address.
- Latency broken down by phase: DNS → TCP → TLS → TTFB
- Per-check retries and maintenance windows — no false incidents
- A public status page per project with 90 days of history and an incident feed
- The page address never changes for the life of the page; older links answer with a 301
- Remote probes (--mode=probe) — checks from outside your perimeter

Alerting, SLOs and incident groups
Delivery via email, webhook and Telegram — in English or Russian, the operator's choice. A cascading failure arrives as one incident instead of forty.
- Rules for new issues, spikes, metric thresholds, perf and uptime regressions
- Incident groups: the root failure in the header, what it caused inside, with "silent - root notifies" and "suppressed - parent down" badges
- SLOs and error budgets: a two-window burn-rate alert wakes you only when the budget is really burning
- Step-by-step escalation: the recipient circle widens until the incident is acknowledged
- Project-wide maintenance windows and a one-click channel test — with the failure reason if delivery breaks

Your data and your perimeter
Data never leaves your servers, you can take it out at any moment, and a leaked ingest key gives away no more than its source needs.
- Server-side PII scrubbing is on by default: IP and email zeroing, key-based redaction
- SSRF protection for outbound webhook and uptime requests — also out of the box
- Exports as CSV, JSON and NDJSON: in the background, filtered by time and environment, PII-masked by default
- Every DSN key has a type — browser, server, agent: a publicly exposed browser key cannot register a host or send a deploy marker
- The finished export file arrives by email — the "how do I get my data into my own pipeline" question is closed along with the vendor lock-in one

Access: SSO and RBAC
Multi-tenant organizations, teams and roles; SSO login — each provider is enabled and configured independently.
- OIDC (generic), Yandex ID, VK ID
- Organizations, teams and roles: every member gets their own level of access to projects
- You can keep only the login provider your company actually approves

Operations and the 1.0 contract
From 1.0 the compatibility contract is frozen: what you built on does not move in a patch release. Anything that breaks it waits for a major version.
- Frozen: environment variable names, ingest paths and body formats, the migration schema, the backup format, self-metric names, the outgoing webhook body, the agent contract and the addresses of published status pages
- Deliberately not covered: internal Go packages, the URLs and layout of UI pages, the PostgreSQL and ClickHouse table schema, the column set of exports, and the wording of gotcha's own log messages
- Deploy markers with version, environment, the changes shipped and a link to the CI run
- Release rollback without restoring from a backup; an interrupted migration is recovered with --migrate-force
- Self-monitoring: gotcha_* metrics, separate /healthz and /readyz, quotas and retention per signal type

How it works
One Go binary, PostgreSQL + ClickHouse. --mode=ingest|web|uptime|probe|all flags for scaling out. No Kafka or Redis. Configurable retention per signal type.
System requirements
One server, three processes (the app, PostgreSQL, ClickHouse). The only dependency is Docker and Docker Compose.
OS: Ubuntu 22.04/24.04, Debian 12, or AlmaLinux/Rocky/RHEL 9/10 · x86-64
Paid setup & support
Gotcha is free, but you don't have to spend your team's time: I'll install it turnkey, migrate you off Sentry or GlitchTip, and look after the instance. Consulting is written — no calls.
Frequently asked questions
What is Gotcha?
Gotcha is a self-hosted observability platform in a single Go binary: error tracking, distributed tracing, metrics, logs, profiling, uptime and server monitoring. Everything runs on your own server. Open source, Apache-2.0 licensed.
Does Gotcha work with stock Sentry SDKs?
Yes. Gotcha ingests events over the Sentry protocol, so you just point your existing Sentry SDK at a new DSN — moving off the cloud takes about as long as changing a DSN in an already configured app.
Can I migrate from Sentry to Gotcha without changing code?
Yes. Gotcha ingests over the Sentry protocol, so migration comes down to swapping the DSN in the same official Sentry SDK — no application code rewrite. A step-by-step walkthrough is in the guide "How to migrate from Sentry to self-hosted Gotcha".
Does Gotcha need Kafka or Redis?
No. Gotcha runs as a single Go binary with PostgreSQL and ClickHouse — no Kafka and no Redis. The quickest start is docker compose up -d.
Which observability signals does Gotcha support?
Errors grouped into issues, distributed traces and transactions (including Web Vitals), metrics over OTLP with threshold alerts, structured logs with search and trace linking, system metrics of your servers (hosts), CPU/flame-graph profiles, and uptime monitoring with public status pages. On top of the signals: SLOs with error budgets, a dependency map, deploy markers, and notification escalation.
Can Gotcha monitor the servers themselves — CPU, memory, disk?
Yes. The Hosts section shows CPU, memory, disk, network, load average and process count for every server; four built-in thresholds open incidents out of the box. Data comes from the native gotcha-agent — a single binary installed with one command straight from your instance, working in restricted networks — or from a standard OpenTelemetry Collector.
Can Gotcha collect logs?
Yes. Logs are ingested over OTLP/HTTP and line-delimited JSON, stored with their own quota and retention. The logs screen offers full-text search and filters by severity, service and environment, and cross-linking shows "logs around the event" from an error page, the logs of a trace, and the logs of a host.
Are there ready-made monitoring recipes for PostgreSQL, nginx, Redis?
Yes. The Recipes section gives turnkey monitoring for PostgreSQL, MariaDB, nginx, Redis and Docker: an OpenTelemetry Collector config with your project key already filled in, a live "data is flowing" indicator, preconfigured charts, and recommended thresholds created with one click.
How do I deploy Gotcha?
Gotcha is a single Go binary that needs PostgreSQL and ClickHouse. The quickest start is docker compose up -d. For scaling out there are --mode=ingest|web|uptime|probe|all flags. No Kafka or Redis required.
How do I upgrade Gotcha, and can I roll back?
Upgrading is pulling the new image and restarting; migrations apply automatically. The database schema carries a backward-compatibility marker, so rolling back to the previous release works without restoring from a backup. An interrupted migration is recovered with the --migrate-force flag. Details are on the Upgrading and Backup pages in the docs.
Does Gotcha have a localized UI?
Yes. The UI, alerts and emails (set by GOTCHA_LOCALE), and the entire documentation are fully available in English and Russian.
What license is Gotcha released under?
Apache-2.0. The source code is open and available on GitHub and GitFlic.
What will you break in the next release?
From 1.0 the compatibility contract is frozen: environment variable names, ingest paths and request body formats, the migration schema, the backup format, self-metric names not marked temporary, the outgoing webhook body, the agent contract and the addresses of already published status pages only change in a backward-compatible way. Anything that breaks that waits for a major version. What the promise deliberately leaves out, and the deprecation timelines, are on the versioning policy page.
How do I get my data out?
Background exports of issue groups or raw events as CSV, JSON or NDJSON, with filters by time and environment and PII masking on by default. The finished file arrives by email and can be downloaded from the Exports page.
Gotcha Cloud
The same product and the same data model, except we run the instance. The move works both ways — out of the cloud onto your own server and back — with no integration rewrites: the ingest contract is identical.
- Upgrades, backups and monitoring of the instance itself are on us
- Data stays in Russian jurisdiction
- Move to your own server at any moment: the same backup format
We are not naming a launch date while there isn't one. Write to us and we will tell you when it becomes clear — and take your scenario into account.