Skip to content

Gotcha 1.0

Latest

Choose a tag to compare

@OtezVikentiy OtezVikentiy released this 06 Sep 13:52

The first gotcha tag, 0.1.0, is dated 22 July this year. Today 1.0 ships, and what matters about the number is not how much arrived in two months but what 0.x never had at all: a promise.

What 1.0 means for this product

The number is not a maturity score or a marketing milestone. It is one specific set of commitments to whoever already runs gotcha on their own hardware:

  • environment variable names are not renamed;
  • ingest addresses and request body formats are not broken;
  • migrations only move forward;
  • the backup format stays readable;
  • anything that violates the above waits for 2.0.

Before 1.0 the contract could change between releases, and that was stated out loud. From 1.0 an upgrade stops being an event you prepare for: read the "Upgrade" page, pull the image, go.

What the promise excludes is stated just as plainly: internal packages, the look of the interface, the names of counters marked temporary. The full text is on the versioning policy page in the documentation.

How the product got here

Core (0.1–0.4, July). Error ingestion over the Sentry SDK protocol — the same official SDK you already have, pointed at a new DSN. Alongside it came tracing with Web Vitals, metrics over OTLP, uptime monitoring with public status pages, and profiling. Then came the part usually postponed: twelve 0.4.x patches spent entirely on hardening what was already written. Container and memory limits, three separate open-redirect bypasses, an invitation bypass, the retention model, secrets removed from the notification queue, WCAG accessibility, CI gates — and the ability for a team member to run day-to-day monitoring without being handed organization-admin rights.

Hosts (0.5–0.6, August). System metrics for servers — CPU, memory, disk, network, load average, processes — and four built-in thresholds that work out of the box. First through the OpenTelemetry Collector, then through a native gotcha-agent: a single dependency-free binary, installed with one command straight from your own instance, updating itself. Dependencies moved into vendor/ in the same stretch — the image build stopped reaching for the network — and the binary was rebuilt on Go 1.26.6, closing seven standard library vulnerabilities.

Connections (0.7–0.11). Log ingestion over OTLP and NDJSON, a viewer with facets and search, and — the point of it — cross-links: from an error to the logs around it, from a trace to the logs of its request, from a host to its own logs. A dependency map derived from traces you already collect, with no setup at all: which databases, caches and outbound HTTP calls the service has, what they cost, and how often they fail. Deploy markers: CI reports a release with a single request, the deploy becomes a vertical line on every chart, and a regression that started shortly after it gets a suspect.

Silence (0.12–0.21). The longest line of work and arguably the most important one. Monitoring turns into a noise source easily; nearly everything in these versions works against that. SLOs and error budgets with two-window burn-rate alerting. A seasonal baseline for regression detection — comparing against the same hour of the same weekday rather than yesterday's average, so a nightly traffic drop doesn't look like an outage. Environment and role labels on hosts, with threshold overrides inheriting host → role → environment → project. Maintenance windows that mute every source at once without stopping collection. Escalations: a ladder that widens the circle of recipients until someone acknowledges. Dependency suppression: a downed parent stays quiet on behalf of its children. Incident groups: a cascading outage folds into one card instead of a storm of them.

Recipes (0.19–0.20). Ready-made collector configs, live-data detection, preconfigured charts and recommended thresholds in one click — for PostgreSQL, nginx, Redis, Docker and MariaDB.

Data you can take out and delete (0.22–0.23). Background exports of issue groups and raw events as CSV, JSON and NDJSON — with PII masking on by default. Data-subject rights reached logs in the same stretch: export and erasure now cover every signal, not only events.

Refusal instead of a silent default (0.23–0.28). A line of work barely visible in the interface that decides what it feels like to host this product. The log quota moved into organization settings. The default bind became local. Self-metrics appeared: ingest rejections with a reason, liveness of background workers, buffers and losses. The rate limiter stopped growing in memory on someone else's garbage. The encryption master key learned to rotate without downtime, and the at-rest envelope got a version. Ingest entry points moved into their own /api/v1/* namespace. DSN keys gained a kind: a publicly exposed browser key can no longer register a host or post a deploy marker. And the principle all of it was heading toward: configuration the process cannot honour fails the start with a clear error instead of being silently replaced by a default.

Interface (0.29–0.33). A rebuild of the information architecture: a dedicated "Overview" screen per project, a three-level sidebar, a page listing an organization's projects. Then focused passes: a bulk-action toolbar over the issue list, click-to-zoom on flamegraph frames, data-flow direction on the dependency map, thresholds and rules edited in modals instead of full-page forms.

An upgrade lived through by hand (0.34–0.37). Forty-one environment variables renamed before the freeze — with a start-up that refuses to come up on an old name and tells you the new one, instead of quietly substituting a default. Then an upgrade rehearsal on a copy of production data: the upgrade and the rollback were driven by hand before the release, not after. It found and closed five blockers, including the one where rolling the binary back onto a newer schema went into a crash loop instead of a readable error.

Worth its own line: a full audit before the freeze. The product was read through nine independent lenses — architecture, security, code review, QA, the interface both live and from source, usability, documentation and operations — and everything found was closed in three waves before this release. 1.0 ships not because the ideas ran out but because the known debts did.

The interface, the emails and the entire documentation are available in English and Russian; the language is switchable per user and defaults to an instance setting.

What comes next

Three legacy ingest addresses — /logs, /profiles/pprof and /api/{project}/deployments/ — keep working in 1.0 and are removed only in 2.0. They carry a Deprecation header, every hit is counted separately, and the project settings page says plainly if one of your senders still uses an old address. They were declared deprecated on 31 August, less than a month ago — too short a notice to break someone's integration with a release whose whole point is a promise of stability.

Installing

One binary, PostgreSQL and ClickHouse next to it, docker compose up -d. There is a separate compose overlay for small machines. The data stays with you: gotcha is self-hosted, with no outbound calls and no telemetry. Licensed Apache-2.0, source open.

Documentation lives inside the product at /docs and on getgotcha.ru.


Читать по-русски

Первый тег gotcha — 0.1.0 — датирован 22 июля этого года. Сегодня выходит 1.0, и главное в этом номере не то, сколько всего успело приехать за два месяца, а то, чего в 0.x не было вовсе: обещание.

Что такое 1.0 у этого продукта

Номер 1.0 здесь не оценка зрелости и не маркетинговая веха. Это один конкретный набор обязательств перед тем, кто уже развернул gotcha у себя:

  • имена переменных окружения не переименовываются;
  • адреса приёма и форматы тел запросов не ломаются;
  • миграции едут только вперёд;
  • формат бэкапа остаётся читаемым;
  • всё, что нарушает перечисленное, — только в 2.0.

До 1.0 контракт менялся между релизами свободно, и это было сказано вслух. С 1.0 обновление перестаёт быть событием, к которому надо готовиться: прочитать раздел «Обновление», поднять образ, поехали.

Что в обещание не входит, сказано так же прямо: внутренние пакеты, внешний вид интерфейса, имена временных счётчиков. Полный текст — на странице политики версионирования в документации.

Как продукт пришёл к этому

Ядро (0.1–0.4, июль). Приём ошибок по протоколу Sentry SDK — тот же официальный SDK, который у вас уже стоит, надо только сменить DSN. Рядом приехали трассировка с Web Vitals, метрики по OTLP, аптайм-мониторинг с публичными статус-страницами и профилирование. Затем случилось то, что обычно откладывают: двенадцать патчей 0.4.x, целиком ушедшие на укрепление уже написанного. Ограничения контейнера и памяти, три разные формы обхода open-redirect, байпас приглашения, модель ретеншена, секреты, убранные из очереди уведомлений, доступность интерфейса по WCAG, гейты в CI — и возможность участнику команды вести повседневный мониторинг, не получая прав администратора организации.

Хосты (0.5–0.6, август). Системные метрики серверов — CPU, память, диск, сеть, load average, процессы — и четыре встроенных порога, работающих из коробки. Сначала через OpenTelemetry Collector, затем появился собственный gotcha-agent: один бинарник без зависимостей, ставится одной командой прямо с вашего инстанса и сам себя обновляет. Тогда же зависимости уехали в vendor/ — сборка образа перестала ходить в интернет, — а бинарь был пересобран на Go 1.26.6, закрыв семь уязвимостей стандартной библиотеки.

Связи (0.7–0.11). Приём логов по OTLP и NDJSON, просмотр с фасетами и поиском и — главное — перекрёстные ссылки: от ошибки к логам вокруг неё, от трейса к логам его запроса, от хоста к его логам. Карта зависимостей, выведенная из уже собранных трейсов без всякой настройки: какие базы, кеши и внешние HTTP-вызовы у сервиса есть, сколько они стоят и как часто падают. Маркеры деплоев: CI сообщает о релизе одним запросом, деплой встаёт вертикальной линией на графиках, а регрессия, начавшаяся вскоре после него, получает подозреваемого.

Тишина (0.12–0.21). Самая длинная линия и, пожалуй, главная. Мониторинг легко превратить в источник шума; почти всё, что приехало в этих версиях, работает на обратное. SLO и бюджеты ошибок с двухоконным алертингом по скорости сжигания. Сезонная база для детектора регрессий — сравнение не со вчерашним средним, а с тем же часом того же дня недели, чтобы ночное падение трафика не выглядело аварией. Метки окружения и роли у хостов и переопределения порогов с наследованием «хост → роль → окружение → проект». Окна обслуживания, глушащие оповещения из всех источников разом, не останавливая сбор. Эскалации: лестница, расширяющая круг получателей, пока инцидент не подтверждён. Подавление по зависимостям: упавший родитель молчит за своих детей. Группы инцидентов: каскадная авария сворачивается в одну карточку вместо шторма карточек.

Рецепты (0.19–0.20). Готовые конфиги коллектора, обнаружение живых данных, преднастроенные графики и рекомендованные пороги в один клик — для PostgreSQL, nginx, Redis, Docker и MariaDB.

Данные, которые можно забрать и удалить (0.22–0.23). Фоновые выгрузки групп ошибок и сырых событий в CSV, JSON и NDJSON — с маскированием персональных данных по умолчанию. Тогда же права субъекта данных распространились на логи: выгрузка и удаление охватывают все сигналы, а не только события.

Отказ вместо тихого дефолта (0.23–0.28). Линия, которая почти не видна в интерфейсе, но определяет, каково это — держать продукт у себя. Квота логов переехала в настройки организации. Бинд по умолчанию стал локальным. Появились собственные self-метрики: отказы приёма с причиной, живость фоновых вычислителей, буферы и потери. Лимитер частоты перестал расти в памяти от чужого мусора. Мастер-ключ шифрования научился ротироваться без простоя, а формат шифрования at-rest получил версию. Входы приёма переехали в собственный неймспейс /api/v1/*. У DSN-ключей появился тип: публично раскрытый browser-ключ больше не может зарегистрировать хост или отправить маркер деплоя. И общий принцип, к которому всё это шло: конфигурация, которую процесс не может выполнить, роняет старт с внятной ошибкой, а не подменяется молча дефолтом.

Интерфейс (0.29–0.33). Пересборка информационной архитектуры: отдельный экран «Обзор» у проекта, трёхуровневый сайдбар, страница всех проектов организации. Дальше — точечные проходы: тулбар массовых действий над списком ошибок, зум по клику на фрейм флеймграфа, направление потока данных на карте зависимостей, правка порогов и правил в модалках вместо форм на всю страницу.

Обновление, прожитое руками (0.34–0.37). Сорок одна переменная окружения переименована до заморозки — со стартом, который отказывается подниматься на старом имени и называет новое, вместо тихой подмены значения дефолтом. Затем репетиция обновления на копии продовых данных: апгрейд и откат проехали руками до релиза, а не после. Она нашла и закрыла пять блокеров, включая тот, из-за которого откат бинаря на базу с более новой схемой уходил в цикл падений вместо понятной ошибки.

Отдельной строкой — сплошной аудит перед заморозкой: продукт прочитали девятью независимыми линзами — архитектура, безопасность, ревью кода, QA, интерфейс отдельно вживую и отдельно по исходникам, юзабилити, документация и эксплуатация, — и всё найденное закрыто тремя волнами до этого релиза. 1.0 выходит не потому, что кончились идеи, а потому что кончились известные долги.

Интерфейс, письма и вся документация — на русском и английском; язык переключается пользователем и задаётся по умолчанию настройкой инстанса.

Что дальше

Три старых адреса приёма — /logs, /profiles/pprof и /api/{project}/deployments/ — продолжают работать в 1.0 и удаляются только в 2.0. Они помечены заголовком Deprecation, каждое обращение считается отдельным счётчиком, а страница настроек проекта прямо говорит, если ваш отправитель ещё ходит по старому адресу. Устаревшими они объявлены 31 августа — меньше месяца назад; слишком короткий срок предупреждения, чтобы ломать чужие интеграции релизом, который называется «обещание стабильности».

Установка

Один бинарник, PostgreSQL и ClickHouse рядом, docker compose up -d. Для слабых машин есть отдельный оверлей compose. Данные остаются у вас: gotcha — self-hosted, без внешних вызовов и без телеметрии наружу. Лицензия Apache-2.0, исходный код открыт.

Документация — прямо в продукте по адресу /docs и на getgotcha.ru.


Full list of changes: CHANGELOG.md · CHANGELOG.ru.md
Documentation: getgotcha.ru/docs