Перейти к содержимому
Назад в Академию

Мониторинг S2S: как заметить, что события перестали доходить

13.10Server-side и API-интеграции
Содержание статьи

Пятница, 10:00, магазин бытовой техники из урока про S2S-трекинг оплаты (цифры в уроке условные). Утром ушла рассылка со скидкой, и с 09:20 пришло пять оплат картой на сайте. Сервер магазина отвечает на проверку доступности, ошибок отправки в Meta ни одной, но ни одна из пяти покупок в Meta не ушла: в 09:15 разработчик выкатил обновление, и обработчик outbox после него не запустился. Старейший заказ ждёт в очереди 40 минут, а ошибок ноль, потому что не было ни одной попытки.

Сервер отвечает, отправок нет

Сбой в магазине, пятница 10:00
СигналНаблюдение
Проверка доступностиСервер отвечает
Новые оплаты картой с 09:205
Попытки отправки0
Ошибки отправки0
Возраст старейшей строки40 минут
Обработчик outboxНе запустился после обновления

При нуле отправок доля успеха не определена. Сигнал остановки - возраст неотправленной строки.

Снимок сбоя: пять оплат, ноль попыток и ошибок, старейшая строка ждёт 40 минут при отвечающем сервере.

Мониторинг S2S отвечает на вопрос, дошли ли до получателей события по всем оплатам. Для этого нужны журнал отправок, утренняя сверка с CRM, оповещения с ответственным и инструменты самих получателей.

Сервер жив - это ещё не доставка

Проверка доступности говорит только, что сервер отвечает. Для серверного GTM это адрес /healthy, его настраивают вместе с инфраструктурой sGTM. У сервера магазина такая проверка своя, но говорит она то же самое. Счётчик ошибок молчит, если попыток не было. А доля успешных отправок при нуле отправок не определена, и рисовать вместо неё 100% нельзя.

В книге Google SRE предлагают следить за четырьмя сигналами: задержкой, трафиком, ошибками и насыщением (мониторинг распределённых систем). Для серверных событий магазина они выглядят так:

СигналЧто смотреть
ТрафикСколько оплат картой появилось в базе и сколько строк outbox ушло получателям
ЗадержкаВозраст старейшей неотправленной строки и время от оплаты до ответа получателя
ОшибкиОтветы получателей с ошибкой, по кодам и по событиям
НасыщениеРастёт ли очередь, хватает ли обработчиков, не упирается ли сервер в свои пределы

В пятницу остановку показали бы два сигнала: оплаты в базе есть, а отправок нет, и старейшая строка стареет с каждой минутой. Ошибки и насыщение молчали. Но в обычный день у магазина три-четыре оплаты картой на сайте, и час без отправок ничего не значит, поэтому главный показатель для него - возраст старейшей неотправленной строки. Задержку в SRE советуют считать и для неудачных запросов: медленная ошибка, по их словам, хуже быстрой.

Что писать в журнал отправок

Журнал отвечает на вопрос «что стало с этим заказом» и через неделю после оплаты. У магазина это таблица outbox, к которой добавлены попытки и ответы. Вот запись для T-310 из урока про S2S-трекинг: оплата в 14:05, первая попытка закончилась тайм-аутом, вторая прошла.

{
"event_id": "T-310",
"order_id": "T-310",
"recipient": "meta_capi",
"event_name": "Purchase",
"schema_version": "v1",
"event_time": "2026-10-09T14:05:00+05:00",
"queued_at": "2026-10-09T14:05:01+05:00",
"attempts": [
{"n": 1, "sent_at": "2026-10-09T14:05:02+05:00", "result": "timeout"},
{"n": 2, "sent_at": "2026-10-09T14:05:41+05:00", "response_code": 200, "result": "accepted"}
],
"status": "accepted"
}
  • event_id и order_id связывают запись с заказом в CRM и с событием у получателя.
  • event_time - время оплаты, queued_at - когда событие встало в очередь. От них до последней попытки и считают задержку доставки.
  • В attempts каждая попытка: когда ушла и чем закончилась, с кодом и текстом ответа. Если повторов вдруг стало много, это видно раньше, чем события начнут теряться.
  • В status одно из пяти значений: accepted (принято), pending (ждёт отправки), failed (в очереди разбора), expired (слишком старое) и skipped (не отправляется по правилу, например без согласия на рекламные cookies). skipped нужен, чтобы в сверке не спутать правило с потерей.

Хешей email и телефона из user_data, токена доступа и секретов из адресов в журнале быть не должно. Для разбора хватает ID, времени и ответа.

Если часть событий идёт через серверный GTM на Stape, его логи запросов хранятся несколько дней, в зависимости от тарифа (подробно в уроке о том, где хостить sGTM), так что итог по каждому заказу надёжнее держать в своей базе.

Что значит ответ получателя

Код 200 у разных получателей значит разное, поэтому в журнал пишут и код, и текст ответа.

Meta возвращает 2xx, если данные события корректны, и 4xx с коротким описанием ошибки, если нет (поддержка Conversions API). Ошибка относится ко всему запросу: если хотя бы одно событие в пачке неправильное или старше семи дней, Meta отклоняет всю пачку (отправка событий через API). Поэтому в журнале должно быть видно, какие события ушли одним запросом: при ошибке в разбор идут все они.

GA4 Measurement Protocol не возвращает ошибку, даже если событие собрано неправильно или в нём нет обязательных параметров (проверка событий Measurement Protocol). Ответ 2xx от GA4 говорит только о том, что запрос дошёл. Новые события поэтому сначала отправляют на сервер проверки /debug/mp/collect. Он отвечает списком validationMessages, где у каждой ошибки есть путь к полю и описание. В отчёты такие события не попадают, а api_secret и measurement_id сервер проверки не смотрит, их сверяют глазами.

Сверка с CRM каждое утро

Журнал показывает, что случилось с отправленным. Что не ушло вовсе, видно только при сравнении с CRM. Поэтому каждое утро кто-то из команды или скрипт сводит вчерашний день в одну строку: сколько заказов оплачено картой по данным CRM, сколько из них можно отправлять по правилу, сколько ушло и сколько принял получатель.

Три дня магазина:

ДеньОплачено картойМожно отправлятьОтправленоПринято Meta
Среда4332
Четверг3333
Пятница7666

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

В среду Meta отклонила одно событие. В четверг утром оно уже в сверке, а в журнале у него ответ 4xx с текстом ошибки, и разработчику есть с чего начать. Если ошибку исправили в течение недели, событие отправляют снова с тем же event_id и исходным event_time. Если не успели, Meta его уже не примет. Из таких событий и складывается разница 80 - 78 в месячной сверке из урока про S2S-трекинг: 100 заказов, оплаченных картой, 80 можно отправлять, 78 принято, 50 приписано рекламе.

Пятничную остановку утренняя сверка не заметит: после исправления в 10:15 очередь разошлась, и к субботе строка за пятницу сходится. Такую остановку ловит только оповещение о возрасте очереди.

Четвёртое число месячной сверки, покупки, приписанные рекламе, по утрам не сверяют: это атрибуция, и за вчерашний день число ещё будет меняться, пока не закроется окно атрибуции.

Числа для сверки берут из своего журнала, а не из Events Manager. Общие счётчики на странице набора данных складывают браузерные и серверные события без дедупликации (различия в подсчёте событий), и покупка, пришедшая из пикселя Meta и с сервера, посчитана там дважды.

В день распродажи ждать утра слишком долго. Ту же таблицу тогда заполняют по часам, как в уроке о том, где хостить sGTM.

Оповещения: на что и кому

Оповещение полезно, только если тот, кто его получил, знает, что делать. В SRE это правило сформулировано так: на каждое оповещение должно быть действие. Магазину хватает четырёх правил:

УсловиеКто получаетПервый шаг
Старейшая неотправленная строка outbox старше 30 минутРазработчик магазинаПроверить, работает ли обработчик outbox
Получатель вернул ошибку 4xxТот, кто отвечает за схему событийПрочитать текст ошибки в журнале и исправить поле
Проверка доступности не отвечаетТот, кто ведёт серверПерезапустить сервер и проверить хостинг
Утренняя сверка нашла застрявшие или отклонённые событияТот, кто отвечает за схему событийНайти в журнале ID этих заказов и причину

30 минут здесь порог для примера, в уроке про S2S-трекинг для начала взяли час. Чем быстрее строка уходит в обычный день, тем ниже можно ставить порог, а у магазина она уходит через секунду после оплаты. А правило «ноль отправок за час» магазину не подходит: при трёх-четырёх оплатах картой в день такое оповещение срабатывало бы каждую ночь, и его быстро перестали бы читать.

С таким правилом в пятницу в 09:50 пришло бы оповещение: «Отправка покупок в Meta стоит. В очереди 4 оплаченных заказа, старейший ждёт 30 минут, последняя успешная отправка в 09:05. Ответственный: разработчик магазина. Первый шаг: проверить, запустился ли обработчик outbox после утреннего обновления». В нём есть всё, что нужно человеку: что сломалось, с какого времени, сколько затронуто, кто отвечает и с чего начать.

Если серверный GTM работает на Stape, оповещения по нему даёт Stape Monitoring, он доступен с тарифа Business (мониторинг Stape). Он проверяет логи по вашим правилам, например «меньше одной покупки за 24 часа», и пишет на почту, до десяти адресов. На вкладке General он же показывает по каждой платформе, сколько запросов ушло и какая доля вернулась с ответом 2xx. Письмо приходит один раз, когда правило сработало, а следующее только после того, как всё вернулось в норму. Пропущенное первое письмо не повторится, поэтому получателей лучше указать двоих.

Для сервера магазина оповещения строят на инструментах облака или на отдельном стеке логов и метрик. Если в найденной инструкции логи собирает Promtail, ищите другую: Grafana прекратила его поддержку 2 марта 2026 года и предлагает переходить на Alloy (статус Promtail).

Оповещение, которое ни разу не срабатывало, тоже надо испытать. Перед крупной кампанией остановите обработчик на тестовом потоке и посмотрите, придёт ли письмо и кто на него ответит.

Проверка у получателя

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

Meta

  • «Тестирование событий» в Events Manager показывает отдельные события. Серверные события попадают туда, если отправить их с test_event_code (проверка событий сервера).
  • «Диагностика» показывает проблемы с событиями, найденные за последние 24 часа, с описанием и инструкцией. Критические отмечены красным, предупреждения жёлтым. Если проблему три дня не трогать, она уходит в «Ранее обнаруженные», и инструкция исчезает (о диагностике в Events Manager). Поэтому вкладку открывают хотя бы пару раз в неделю.
  • В сведениях о серверных событиях есть вкладки «Дедупликация событий» с ключами, которые вы передаёте, и «Охват событий», где серверные события сравниваются с уникальными событиями пикселя: оптимальным Meta считает охват 75%. Ещё одна вкладка (Data freshness) показывает задержку между событием и его получением (контроль работы Conversions API).

GA4

До запуска события проходят через сервер проверки, о нём выше. После запуска события Measurement Protocol обычно видны в отчёте «В реальном времени» через несколько секунд (проверка настройки Measurement Protocol). Чтобы рассмотреть одно событие подробно, его отправляют с параметрами debug_mode и engagement_time_msec и находят в DebugView.

TikTok

В TikTok Events Manager у источника данных есть вкладки «Обзор», «Тестовые события» и «Диагностика» (мониторинг и диагностика в TikTok Events Manager). «Диагностика» собирает проблемы с событиями: что не так, насколько это серьёзно, какой набор данных и какие объявления затронуты. В «Обзоре» есть поле «Последнее полученное», но TikTok предупреждает, что данные о событиях там показываются не в реальном времени. Отправку событий в TikTok с сервера настраивают через TikTok Events API.

Восстановление после сбоя

После исправления очередь разбирают с теми же event_id и исходным event_time: повтор с тем же ключом получатель узнает, а время покупки остаётся временем покупки. Ограничения у получателей разные:

  • Meta принимает события не старше семи дней, и одно старое событие отклоняет всю пачку. Такие строки до отправки помечают expired и убирают из пачки.
  • GA4 через Measurement Protocol принимает события, сдвинутые в прошлое не больше чем на 72 часа. Более старое событие по умолчанию примется, но получит время «72 часа назад» (отправка событий Measurement Protocol), и покупка тихо окажется не в своём дне.

Итог сбоя записывают: сколько событий застряло, сколько ушло после исправления, сколько просрочено. Досылать покупки с новыми ID, чтобы график выглядел ровно, нельзя: получатель примет их за новые покупки.

Упражнение: неделя доставки вашего проекта

Возьмите проект с серверными событиями, свой или клиента.

Выполнено 0 из 4

Если столбец «Отправлено» заполнить нечем, это первая находка: у проекта нет журнала отправок, и работа начинается с него. Если нечем заполнить «Принято», ответы получателей нигде не записываются. И то и другое стоит сказать клиенту в отчёте за первую неделю: пока этих данных нет, на вопрос «все ли покупки доходят до рекламы» ответить нечем.

Вторая часть - вопрос клиента. Он присылает скриншот вкладки General в Stape Monitoring: за сутки у запросов в GA4 и Meta 100% успешных ответов. Клиент спрашивает, значит ли это, что все покупки доходят. Напишите ему ответ в два-три предложения, а потом сравните с разбором.

Нет, не значит. Доля считается по ответам 2xx среди отправленных запросов, а GA4 отвечает 2xx и на событие без обязательных параметров. Заказы, которые застряли в очереди или не ушли вовсе, в эту долю не попадают. Дошли ли все покупки, покажет утренняя сверка с CRM: оплачено, можно отправлять, отправлено, принято.

Мини-тест: Server-side и API-интеграции

Закрепление модуля

Проверьте, как применить идеи модуля в рабочей ситуации. Сначала ответьте самостоятельно, затем прочитайте разбор.

3 вопроса. После проверки - объяснение каждого варианта и ссылки на уроки. В вопросах с несколькими ответами нужен полный набор: частичный ответ не засчитывается. Ограничения по времени нет.

Прогресс сохраняется только в этом браузере. Очистка данных сайта удалит его; на другое устройство он не переносится.

Нужна помощь с аналитикой вашего проекта?