SDK и интеграции

Gotcha не имеет собственного протокола отправки данных — она принимает события и транзакции по протоколу приёма Sentry, а метрики и профили — по OTLP и pprof соответственно. Это значит, что для подключения приложения не нужен никакой особый «Gotcha SDK»: вы ставите официальный Sentry SDK своего языка и передаёте ему DSN своего проекта Gotcha. Дальше SDK работает ровно так, как описано в его собственной документации — Gotcha просто оказывается на другом конце DSN вместо sentry.io.

Ниже — установка и минимальная инициализация для PHP (в том числе Laravel), JavaScript/Node, JavaScript в браузере, Python и Go, затем — окружение и релиз, отправка производительности (трейсинг), указатели на приём метрик и профилей, и раздел с типичными проблемами подключения.

Где взять DSN

DSN проекта — на странице «Подключение»: после создания проекта вас автоматически перенаправляет туда (URL вида /projects/<id>/setup), а вернуться позже можно кнопкой «Подключение SDK» в списке проектов или из блока «DSN-ключи» на странице «Настройки проекта». DSN выглядит так:

https://<PUBLIC_KEY>@<адрес_gotcha>/<ID_ПРОЕКТА>

Во всех примерах ниже замените <ВАШ_DSN> на эту строку целиком.

Какой DSN куда. У проекта не один DSN, а несколько — по одному на ключ, и ключи различаются по типу. Для JavaScript в браузере берите DSN браузерного ключа; для PHP, Node на сервере, Python и Go — DSN серверного ключа. Полный список того, что каждому типу разрешено, и почему это важно — на странице Ключи приёма.

PHP (обычный проект)

composer require sentry/sentry

Репозиторий: https://github.com/getsentry/sentry-php

<?php
require __DIR__ . '/vendor/autoload.php';

\Sentry\init([
    'dsn' => '<ВАШ_DSN>',
    'environment' => getenv('APP_ENV') ?: 'production',
    'traces_sample_rate' => 0.2, // включает трейсинг производительности; см. раздел ниже
]);

Отправить тестовую ошибку — либо просто бросить необработанное исключение (SDK сам подхватит его через set_exception_handler), либо явно:

try {
    throw new \RuntimeException('Тестовая ошибка Gotcha');
} catch (\Throwable $e) {
    \Sentry\captureException($e);
}

Событие появится в разделе «Проблемы» вашего проекта в течение нескольких секунд.

PHP (Laravel)

composer require sentry/sentry-laravel

Репозиторий: https://github.com/getsentry/sentry-laravel

Опубликуйте конфиг и сразу пропишите DSN (команда добавит переменную в .env и создаст config/sentry.php):

php artisan sentry:publish --dsn=<ВАШ_DSN>

Либо вручную добавьте в .env:

SENTRY_LARAVEL_DSN=<ВАШ_DSN>
SENTRY_TRACES_SAMPLE_RATE=0.2
SENTRY_ENVIRONMENT=production

Пакет сам регистрирует обработчик исключений Laravel — ничего дополнительно инициализировать не нужно. Отправить тестовое событие:

php artisan sentry:test

Событие появится в «Проблемах» проекта, DSN которого вы указали.

PHP (Symfony)

composer require sentry/sentry-symfony

Репозиторий: https://github.com/getsentry/sentry-symfony

Рецепт Flex по умолчанию включает бандл только в prod и без трейсинга. Для self-hosted удобнее держать его активным во всех окружениях, но по наличию DSN (пусто = SDK выключен), и включить трейсинг через env — config/packages/sentry.yaml:

sentry:
    dsn: '%env(SENTRY_DSN)%'
    options:
        traces_sample_rate: '%env(float:SENTRY_TRACES_SAMPLE_RATE)%'
        environment: '%kernel.environment%'
        # 404/405 — обычный веб-шум (сканеры, битые ссылки), а не ошибки приложения
        ignore_exceptions:
            - 'Symfony\Component\HttpKernel\Exception\NotFoundHttpException'
            - 'Symfony\Component\HttpKernel\Exception\MethodNotAllowedHttpException'

Бандл — во всех окружениях (config/bundles.php):

Sentry\SentryBundle\SentryBundle::class => ['all' => true],

Переменные в .env:

SENTRY_DSN=<ВАШ_DSN>
SENTRY_TRACES_SAMPLE_RATE=0.2

Бандл сам ловит необработанные исключения. Тест — \Sentry\captureMessage('проверка') или временный роут, бросающий исключение; событие появится в «Проблемах».

ignore_exceptions важен: без него NotFoundHttpException летит в Gotcha как ошибка, и каждый скан/битая ссылка засоряет issues. Игнор клиентских 404/405 оставляет только реальные ошибки приложения.

CMS: WordPress и Joomla

Для сайтов на CMS писать код не нужно — есть готовые расширения, которые ставятся штатным установщиком и настраиваются одним полем DSN. Внутри у них тот же официальный Sentry SDK, что и в примерах выше, плюс браузерный SDK для Web Vitals.

CMSРасширениеЧто собирает
WordPress 5.9+gotcha-monitoringошибки PHP (включая фатальные), транзакции по типам страниц (single.post, archive.category, rest:/wp/v2/posts, wp-cron), ошибки JS и Web Vitals
Joomla 4.2+, 5, 6pkg_gotchaошибки PHP, транзакции по компонентам (com_content.article), ошибки JS и Web Vitals
1С-Битрикс (Управление сайтом)gotcha.monitoringошибки PHP (через штатный ExceptionHandlerLog ядра), транзакции по скриптам (/catalog/index.php), ошибки JS и Web Vitals
Drupal 10, 11gotcha_monitoringошибки PHP (через штатный logger-канал), транзакции по именам роутов (entity.node.canonical), ошибки JS и Web Vitals
OpenCart 4.xgotcha (ocmod)ошибки PHP (цепочка обработчиков), транзакции по маршрутам (product/product), ошибки JS и Web Vitals
MODX Revolution 3gotcha (transport)ошибки PHP (цепочка обработчиков), транзакции по шаблонам (web:BaseTemplate), ошибки JS и Web Vitals

Установка одинаковая: поставить архив через менеджер расширений, включить, вставить DSN со страницы «Подключение». Пока DSN пуст, расширение не делает ничего — ни одного запроса наружу.

Разбор устройства расширений, включая выбор имён транзакций и изоляцию composer-зависимостей: WordPress, Joomla, 1С-Битрикс, Drupal, OpenCart, MODX.

На SaaS-конструкторах (Tilda и подобных) расширение поставить некуда — сервер чужой. Там доступна браузерная половина: ошибки JavaScript и Web Vitals вставляются блоком в <head>, аптайм и SSL проверяются снаружи и вовсе не требуют кода. Подробнее: мониторинг сайта на Tilda.

JavaScript / Node.js (сервер)

npm install @sentry/node

Репозиторий: https://github.com/getsentry/sentry-javascript

const Sentry = require("@sentry/node");
// или: import * as Sentry from "@sentry/node";

Sentry.init({
  dsn: "<ВАШ_DSN>",
  environment: process.env.NODE_ENV || "production",
  tracesSampleRate: 0.2,
});

Тестовая ошибка:

try {
  throw new Error("Тестовая ошибка Gotcha");
} catch (e) {
  Sentry.captureException(e);
}

Перед завершением короткоживущего процесса (скрипт, serverless-функция, воркер, который сразу выходит) обязательно дождитесь отправки буфера:

await Sentry.close(2000); // ждём до 2с, чтобы событие успело уйти

JavaScript (браузер)

npm install @sentry/browser
import * as Sentry from "@sentry/browser";

Sentry.init({
  dsn: "<ВАШ_DSN>",
  environment: "production",
  tracesSampleRate: 0.2, // трейсинг + автосбор Web Vitals (LCP/INP/CLS/FCP/TTFB)
});

Тестовая ошибка — любое необработанное исключение в коде страницы поймается автоматически; явно:

Sentry.captureException(new Error("Тестовая ошибка Gotcha"));

Если у сайта настроен Content-Security-Policy с директивой connect-src, добавьте туда адрес вашего инстанса Gotcha — иначе браузер молча заблокирует запрос к DSN.

Браузер шлёт события на адрес из DSN — часто это другой домен, чем у самого сайта (сайт на app.example.com, Gotcha на gotcha.example.com). Приёмник Gotcha отвечает CORS-заголовками и обрабатывает preflight (OPTIONS), поэтому браузерный SDK шлёт напрямую, без прокси и туннелей. Public key в DSN публичен по замыслу — приёмник разрешает любой origin.

Python

pip install sentry-sdk

Репозиторий: https://github.com/getsentry/sentry-python

import sentry_sdk

sentry_sdk.init(
    dsn="<ВАШ_DSN>",
    environment="production",
    traces_sample_rate=0.2,
)

Тестовая ошибка:

try:
    raise RuntimeError("Тестовая ошибка Gotcha")
except Exception:
    sentry_sdk.capture_exception()

Для Django/Flask/FastAPI и других фреймворков sentry-sdk поднимает нужную интеграцию автоматически при её обнаружении в окружении — отдельно ничего включать не нужно, sentry_sdk.init(...) в точке входа приложения достаточно.

Go

go get github.com/getsentry/sentry-go

Репозиторий: https://github.com/getsentry/sentry-go

package main

import (
	"errors"
	"time"

	"github.com/getsentry/sentry-go"
)

func main() {
	err := sentry.Init(sentry.ClientOptions{
		Dsn:              "<ВАШ_DSN>",
		Environment:      "production",
		TracesSampleRate: 0.2,
	})
	if err != nil {
		panic(err)
	}
	// ОБЯЗАТЕЛЬНО: без Flush процесс может завершиться раньше, чем
	// буфер событий уйдёт по сети.
	defer sentry.Flush(2 * time.Second)

	sentry.CaptureException(errors.New("тестовая ошибка Gotcha"))
}

Окружение и релиз

environment (environment/Environment в зависимости от языка) и release — два поля, которые стоит проставлять с самого начала: они привязываются к каждому событию, транзакции и метрике и используются для фильтрации почти во всех разделах Gotcha.

\Sentry\init([
    'dsn' => '<ВАШ_DSN>',
    'environment' => 'staging',
    'release' => 'my-app@' . trim(shell_exec('git rev-parse --short HEAD')),
]);

Так продовые ошибки не тонут среди тестового стенда, а по регрессии производительности видно, в каком именно релизе она началась.

Производительность и трейсинг (транзакции)

Параметр traces_sample_rate (tracesSampleRate в JS) включает создание транзакций — единиц измерения производительности, из которых строится раздел Производительность. Значение — доля запросов, для которых создаётся трейс: 1.0 — все запросы, 0.2 — каждый пятый, 0 (по умолчанию) — трейсинг выключен, будут отправляться только ошибки.

Дополнительно на стороне сервера в «Настройках проекта → Performance» можно задать серверную долю семплирования (sample_rate, 0..1) — она применяется поверх того, что уже отправил SDK, и позволяет снизить объём хранимых транзакций без переразвёртывания приложения. В браузере с включённым трейсингом автоматически собираются и Web Vitals (LCP/INP/CLS/FCP/TTFB) — отдельно включать их не нужно.

Метрики (OTLP)

Числовые метрики (counter/gauge/histogram) Gotcha принимает по протоколу OpenTelemetry (OTLP/HTTP), а не через Sentry SDK. Настройте OTLP-экспортёр вашего приложения (или OpenTelemetry Collector) на:

POST https://<адрес_gotcha>/v1/metrics
Authorization: Bearer <PUBLIC_KEY>

<PUBLIC_KEY> — это публичный ключ из DSN проекта (часть между https:// и @), а не DSN целиком. У большинства OTel-экспортёров для заголовков есть штатная опция (headers: в конфиге коллектора, OTEL_EXPORTER_OTLP_METRICS_HEADERS в переменных окружения). Подробнее о типах метрик, агрегациях и оповещениях по порогам: Метрики.

Трейсы (OTLP)

Транзакции и спаны Gotcha принимает не только по протоколу Sentry, но и по OpenTelemetry — тем же способом, что и метрики:

POST https://<адрес_gotcha>/v1/traces
Authorization: Bearer <PUBLIC_KEY>

Это путь для команд, у которых трассировка уже собрана на OpenTelemetry: менять инструментацию на Sentry SDK не нужно, достаточно направить существующий экспортёр (или коллектор) на этот адрес. Спаны попадают в те же «Транзакции» и «Эндпойнты», что и присланные Sentry SDK.

Что стоит знать:

  • имя транзакции берётся из имени корневого спана — те же правила кардинальности, что и везде (идентификатор в имени превращает один эндпойнт в миллионы, см. Кардинальность);
  • вложенность спанов сохраняется, и в водопаде видна та же структура, что в вашем трейсе;
  • профили к OTLP-трейсам не привязываются автоматически: связь профиля с трейсом строится по trace_id, поэтому pprof нужно отправлять с тем же значением.

Профилирование (pprof)

Помимо профилей, которые присылает Sentry SDK вместе с трейсами (profiles_sample_rate в Python/PHP/JS/Go SDK), Gotcha принимает и «сырые» pprof-профили напрямую:

POST https://<адрес_gotcha>/api/v1/profiles/pprof?service=<имя_сервиса>&environment=<окружение>
Authorization: Bearer <PUBLIC_KEY>
Content-Type: application/octet-stream

Тело — обычный gzip’нутый pprof-профиль (например, результат go tool pprof или runtime/pprof). Подробнее о флеймграфах, in-app/system-кадрах и регрессиях: Профилирование.

Если событие не доходит

Если после отправки ошибки в «Проблемах» ничего не появилось за разумное время, по порядку проверьте:

ПричинаКак проверить
Неверный или отозванный DSNСверьте DSN с тем, что показан в «Настройках проекта → DSN-ключи»; ingest отвечает 401/403 на неизвестный или отозванный публичный ключ. Если ключ был перевыпущен — старый DSN перестаёт работать сразу.
DSN от чужого проектаproject_id в DSN должен совпадать с проектом самого ключа — иначе ingest вернёт 403 sentry_key does not match project.
Сеть/файрволПриложение должно уметь достучаться по HTTPS/HTTP до адреса Gotcha (GOTCHA_BASE_URL инстанса) — проверьте curl -i <адрес_gotcha>/readyz с той же машины/контейнера, откуда работает приложение. Корпоративный прокси или egress-файрвол могут молча резать исходящие запросы.
Событие/тело слишком большоеПо умолчанию ingest принимает тело не больше 1 МБ (GOTCHA_MAX_EVENT_BYTES на инстансе); превышение — 413. Актуально для событий с очень длинными стектрейсами или большими breadcrumbs.
Квота организации исчерпанаIngest отвечает 429 с Retry-After, если месячная квота исчерпана; проверьте «Настройки организации → Использование и лимиты». В oss-редакции по умолчанию квоты не ограничены (0), но админ инстанса мог их выставить.
Сработал per-DSN rate limitВторой источник 429: у каждого проекта потолок GOTCHA_INGEST_RATE_PER_SEC запросов в секунду (по умолчанию 500, burst 2×). В отличие от квоты Retry-After здесь около секунды — SDK со встроенным backoff восстанавливаются сами. Постоянные срабатывания обычно означают зацикленную отправку (ошибка на каждый запрос, шторм ретраев).
SDK не успел отправить данныеВ коротких процессах (CLI-скрипты, serverless, воркеры) вызовите Flush/close перед выходом — см. примеры для Go и Node выше; без этого буфер событий может просто не уйти по сети.
CSP блокирует запрос в браузереЕсли на странице задан Content-Security-Policy, добавьте адрес Gotcha в connect-src.

Если ни один пункт не помог — включите отладочный режим SDK (debug: true у большинства Sentry SDK) и посмотрите, что он логирует при попытке отправки: это почти всегда указывает точную причину.