Olvery

Документация к платформе «Olvery»

Инструменты пользователя

Инструменты сайта


runbooks:glitchtip-event-observation

GlitchTip: чтение событий после выпуска

Назначение: наблюдение известных issue после выпуска без повторного чтения всей истории. Проверено 22.10.2026 на https://glitchtip.olvery.ru, GlitchTip 6.1.6. Это сервисный рецепт, не изменение collector или сервера.

Поддержка установленного API

У следующих списков нет серверных фильтров release и времени:

  • GET /api/0/issues/{issue_id}/events/;
  • GET /api/0/projects/{organization_slug}/{project_slug}/events/.

Параметры release, query, start, end здесь не применяются. HTTP200, пустая выборка, наличие параметров в следующей Link-ссылке или совместимость SDK с Sentry не доказывают поддержку фильтра.

Рабочий путь — limit и штатный cursor из Link, локальные проверки release/времени. Не конструировать курсор самостоятельно. Для запроса достаточно существующего glitchtip-olv3729 через штатный helper; токен и полный ответ не выводить и не сохранять.

Короткий пример одного GET

Пример читает одну запись известной issue, выводит только HTTP-код, release, времена и наличие следующей страницы. Это не полный observation и не доказательство исправности приложения.

/home/olvr/bin/olvr-secret run glitchtip-olv3729 -- python3 - <<'PY'
import json, os, urllib.parse, urllib.request
url = "https://glitchtip.olvery.ru/api/0/issues/29879/events/"
url += "?" + urllib.parse.urlencode({"limit": 1})
req = urllib.request.Request(url, headers={
    "Authorization": "Bearer " + os.environ["OLVR_SECRET"]})
with urllib.request.urlopen(req, timeout=25) as r:
    rows = json.load(r)
    link = r.headers.get("Link", "")
    print("http", r.status, "rows", len(rows))
    for e in rows:
        tags = e.get("tags") or {}
        if isinstance(tags, list):
            tags = {t.get("key"): t.get("value") for t in tags}
        release = tags.get("release") or e.get("release")
        if isinstance(release, dict):
            release = release.get("version")
        print({"release": release,
               "dateReceived": e.get("dateReceived") or e.get("date_received"),
               "dateCreated": e.get("dateCreated") or e.get("date_created")})
    print("has_next", any('rel="next"' in p and 'results="true"' in p
                          for p in link.split(",")))
PY

Для обычного обхода используется ?limit=100. urllib.parse.urlencode кодирует query-значения; литеральный плюс в 4.6.5+9716 должен стать %2B, а не пробелом. Это правило encoding, не обещание наличия release-фильтра.

Минимальный штатный обход

  • Начать с issue events без самодельного cursor. Читать страницы вперёд по Link с rel=«next» и results=«true»; перед передачей Authorization проверять тот же HTTPS-host glitchtip.olvery.ru и API-путь. limit=100 — размер страницы, не общий предел.
  • Нормализовать dateReceived / date_received как UTC datetime. Это серверное поступление. dateCreated / date_created — время события от клиента; им нельзя заменять границу поступления.
  • Локально сравнивать exact release, без prefix/substrings. Для семантики исходного PSTU observation: release равен com.tpark_it.pstu@4.6.5+9716 ИЛИ app context содержит app_identifier=com.tpark_it.pstu, app_version=4.6.5, app_build=9716. Проверка только release уже этого исходного контракта. Версия/build без app identifier также недостаточны.
  • Для результата «после выпуска» учитывать только события с dateReceived >= 2026-10-22T12:17:07Z. Проверять все события нужного временного диапазона, независимо от release.
  • Списки этой версии упорядочены по -id UUIDv7, что соответствует невозрастанию серверного dateReceived. На странице, пересёкшей cutoff, обработать подходящие события; когда встретилось серверное время строго меньше cutoff, более старые страницы для post-cutoff результата не нужны. Равное cutoff время включается. При отсутствующем/неразбираемом времени или нарушенном порядке не объявлять раннюю остановку полным доказательством: сохранить gap.
  • Если Link закончился раньше cutoff, завершена доступная выдача этого endpoint. Если нужен итог по всей сохранённой истории, а не только после cutoff, раннюю остановку по времени не применять.

Отсутствие событий с ошибкой не доказывает успешные сессии. List endpoint читает свой queryset; полноценность cold-storage-истории этим рецептом не обещается.

Почему фильтрам нельзя доверять

Минимальный read-only control на issue 29879, 22.10.2026 16:20:17Z:

  • ?limit=1 → HTTP200, 1 событие: release com.tpark_it.pstu@4.6.1+7740, received 2026-10-22T08:17:55.915Z;
  • те же limit=1 плюс release=jfVY-no-such-release-2099, start=2099-01-01T00:00:00Z, end=2099-01-02T00:00:00Z, query=release:«jfVY-no-such-release-2099» timestamp:>2099-01-01 → HTTP200, та же запись2026.

Идентичность сравнивалась в памяти; идентификаторы и пользовательский payload не сохранялись. В отличие от пустого ответа, непустой контрпример показывает игнорирование переданных ограничений; точный набор поддержанных параметров установлен исходником.

Версия, evidence и пересмотр

Фактический target: srv-glitchtip.olvr, glitchtip-web-1, glitchtip/glitchtip:6, running. GLITCHTIP_VERSION=6.1.6.

  • Image ID: sha256:8476bbdf291f946850fc6430d2cab62836918638ced34f4791593081bc067128;
  • RepoDigest: glitchtip/glitchtip@sha256:f45485d296697531464b4484ee9bb40a51a774df820f74128a2b2ae0c5a0b00f;
  • /code/apps/issue_events/api/events.py:20–35,77–85,209–226: queryset ограничен доступом и issue/project; оба списка не принимают фильтры и сортируют по -id;
  • SHA256 этого файла: 1eae9be2df11f27cc5bbc29c24a73dce7d875be1f23c22e030507672ecb1eaac;
  • /code/apps/issue_events/schema.py:214–219: created→timestamp, received→received;
  • /code/apps/issue_events/models.py:308–317: received извлекается из серверного UUIDv7 с миллисекундной точностью;
  • /code/glitchtip/api/pagination.py: AsyncLinkHeaderPagination, limit/cursor и Link. Возвращаемый Link сохраняет исходные query-параметры, но это не означает их применение.

GET /api/0/ возвращает API version 0, не версию приложения.

Evidence: Card jfVY, receipts OvtbEO, 0r9VZC, XEu7hX, 4XP9Pe. Безопасные artifacts: /home/BVNq/work/jfVY/installed-api-contract.txt, filter-controls-safe.json и соответствующие диагностические скрипты. Источник исходного observation — 3kfw/0dgUUT; его collector и принятое observation не менялись и не переаттестовывались.

После смены GlitchTip image/version сверять затронутый API-контракт заново. Доработка сервера, новый collector, runner или общий механизм фильтрации в этот рецепт не входят.

runbooks/glitchtip-event-observation.txt · Последнее изменение: — Boris Rudakov

Если не указано иное, содержимое этой вики предоставляется на условиях следующей лицензии: GNU Free Documentation License 1.3
GNU Free Documentation License 1.3 Donate Powered by PHP Valid HTML5 Valid CSS Driven by DokuWiki