DarkRiDDeR15 мин

Разбор 502 в поле: собрать цепочку из access и application log

НадёжностьПрактика команд

Проблема полевой заметки о 502 — не в нехватке терминов. Ошибка появляется, когда в неё заносят только внешний статус и сразу называют его причиной: «упал API». Цена такой записи практическая: следующий инженер ищет неисправность в приложении, хотя шлюз мог не установить соединение, или чинит upstream, хотя приложение уже вернуло понятный отказ. Без цепочки событий полевой разбор превращается в пересказ экрана.

Для одного запроса нужны как минимум две записи: access на границе и application в сервисе. Их соединяют request-id или traceparent, а не только время и путь. В каждой записи должны быть timestamp, route, status и длительность; в application log — операция и безопасное описание ошибки. Если второй записи нет, это не повод заполнить пропуск догадкой. Это отдельная ветка: отказ произошёл до приложения или запись потерялась.

Начинаем с внешней границы

RFC 9110 описывает 502 как ситуацию, в которой gateway или proxy получил недействительный ответ от upstream. Для полевой диагностики важен субъект статуса: где именно его увидел клиент. Access log gateway даёт внешний результат, но не раскрывает, был ли запрос принят приложением. Поэтому первой строкой карточки пишем узел и роль: edge.status=502, а не общее «сервер 502».

Затем ищем application event с тем же идентификатором в небольшом окне. Совпадение найдено — проверяем, что время и route согласуются, а статус приложения объясняет внешний ответ. Совпадения нет — проверяем timeout, фильтр коллектора, другой формат id и потерю записи. Такой разбор занимает меньше времени, чем просмотр всего журнала, потому что каждая проверка меняет одну гипотезу.

Петля полевого разбора 502: внешний access event, поиск application event по идентификатору, проверка времени и отдельная ветка для разрыва.
Диаграмма показывает, что отсутствие application записи — результат проверки цепочки, а не разрешение назвать приложение причиной.
Матрица полевой проверки 502
НаблюдениеСледующая проверкаРабочий выводНельзя писать
502 в edge, application не найденtimeout, collector, формат idцепочка разорвана до подтверждения слоя«приложение упало»
502 в edge, app 500 с тем же idстатус и время appошибка дошла до приложениячто найден root cause
502 в edge, app 200retry, cache, proxy mappingграницы преобразуют результатчто app ответил клиенту 200
access не содержит idконфигурация structured fieldsключ корреляции неполонсоединять по ближайшему времени

Учебный сборщик цепочки

Функция ниже принимает два локальных массива и возвращает отдельную карточку на каждый request-id. Входы специально похожи на structured log, но не являются выгрузкой системы. Ожидаемый результат различает «gateway отказал до приложения», «ошибка приложения дошла до клиента» и обычное завершение. Это конкретная операционная техника: она показывает, какие поля нужны для первого прохода и как не потерять разрыв.

import { buildRequestTimeline } from './upgrade-2027-01.mjs';

const edge = [
  { requestId: 'r-1', at: '12:00:01.100', status: 502, message: 'upstream timeout' },
  { requestId: 'r-2', at: '12:00:02.100', status: 502, message: 'bad response' },
];
const app = [
  { requestId: 'r-2', at: '12:00:02.080', status: 500, message: 'db unavailable' },
];

console.log(buildRequestTimeline(edge, app).map(({ requestId, result }) => ({ requestId, result })));
// r-1: gateway-failed-before-app; r-2: app-error-reached-client

Для r-1 нет application event, поэтому функция не называет базу или приложение виновником. Для r-2 есть согласованная запись, но вывод всё ещё ограничен: ошибка приложения достигла внешнего ответа, а почему база недоступна — отдельный вопрос. В реальном коде добавьте проверку схемы, исключите секреты и сохраните raw-поля рядом с нормализованными.

Как читать время и повтор

Время в разных сервисах может иметь разную точность и сдвиг. Если access и application разделены десятками миллисекунд, это повод сверить clock sync и точку записи, а не автоматически отвергнуть связь. Повторный запрос тоже не обязан повторить тот же маршрут: gateway может выбрать другой upstream, а retry — создать новый идентификатор. В карточке держите request-id каждого повтора отдельно.

RFC 5424 полезен здесь не как готовая схема конкретного приложения, а как напоминание о структурированных полях и разделении источника, времени и сообщения. Поле message удобно читать человеку, но для соединения нужен отдельный ключ. Чем больше решений принимается по свободному тексту, тем выше стоимость следующего разбора.

Действия по порядку

  1. Скопировать из edge только одну попытку запроса: timestamp, route, method, status, duration и request-id.
  2. Найти application events по точному id и ограниченному временному окну; сохранить число найденных записей.
  3. Сопоставить status, route и длительность, затем отметить разрыв, retry или преобразование на proxy.
  4. Проверить зависимость только после подтверждения, что приложение действительно получило запрос.
  5. Сформулировать итог как наблюдение и следующий тест: например, «нет app записи; проверить timeout и collector», а не как окончательный root cause.

Ограничения и следующий шаг

Журнал может быть неполным из-за sampling, сбоя коллектора, буферизации или редактирования чувствительных полей. Один request-id может встретиться в retry, если система повторно использует контекст; это надо проверить по span-id и attempt. Нельзя публиковать токены, email, тело формы и сырые заголовки. Для юридически чувствительных систем храните безопасный fingerprint и ссылку на закрытый источник.

Следующий шаг — добавить в runbook три обязательных запроса: найти edge event, найти application event, проверить отсутствие/наличие dependency event. После одного реального разбора измерьте долю карточек, где цепочка собирается без ручного поиска по времени. Это покажет качество полей, а не только удобство инструмента.

Проверяемые источники

  • RFC 9110: HTTP Semantics — версия и дата: Internet Standard, June 2022, DOI 10.17487/RFC9110. Применение: Семантика 502 и место, где gateway сообщает о недействительном ответе upstream. Граница: RFC не определяет топологию edge/application и не подтверждает конкретный отказ.
  • RFC 5424: The Syslog Protocol — версия и дата: Standards Track, March 2009, DOI 10.17487/RFC5424. Применение: Разделение заголовка, structured data и message поддерживает выбор полей для безопасного журнала. Граница: Стандарт не гарантирует полноту, порядок доставки и наличие записей в конкретном collector.
  • Trace Context — W3C Recommendation — версия и дата: Recommendation, 23 November 2021. Применение: Traceparent и request context используются как ключи соединения событий на HTTP-границах. Граница: Наличие идентификатора не доказывает, что цепочка полна или что найденная запись была причиной.