Авторские материалы
Учебный контракт из одиннадцати полей, три вымышленные записи и четыре проверки, которые не позволяют превратить совпавшие идентификаторы в готовый диагноз.

От клиента до origin: какие поля связывают одну попытку запроса

Три журнала могут говорить об одной попытке запроса и при этом показывать timeout, 504 и 200. Чтобы прочитать их вместе, нужен договор о полях и границах наблюдения. В этом разборе такой договор проверяется на полностью вымышленных данных.

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

Широкие таблицы, схема и код прокручиваются горизонтально. С клавиатуры: раскройте нужный блок, нажмите Tab до области и используйте стрелки влево и вправо.

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

В учебной модели operation_id объединяет операцию, attempt_id отделяет её попытку, event_id обозначает отдельную запись. Идентичность записи задаётся вместе с её источником и областью идентификаторов. Эти названия и правила придуманы для упражнения. Они не являются форматом Cloudflare, OTLP или обязательной схемой для любого приложения.

OWASP рекомендует сохранять контекст взаимодействия и документировать свойства событий. Это поддерживает постановку задачи, но не задаёт наши operation_id и attempt_id. В реальной системе отдельно проверяют, кто формирует идентификатор, где он сохраняется и можно ли доверять значению из другой зоны. Простого совпадения строк для такого доверия недостаточно.

Зафиксируйте смысл каждого поля до объединения

Для одного небольшого упражнения достаточно следующего явно ограниченного контракта. Он содержит одиннадцать полей. Условие модели — доверенное сохранение общего operation_id и attempt_id в трёх точках. Это заданная предпосылка, а не обнаруженная возможность продукта. Точка наблюдения source здесь принимает только client, edge или origin; origin — сервер приложения за промежуточным узлом.

Одиннадцать полей собственного учебного формата
ПолеСмысл в упражненииОграничение
schema_versionВерсия data01.demo.v1Область действия именно этих правил
namespaceПридуманная область data01.syntheticОдинаковые строки вне области не объединяются
event_idИдентификатор отдельной записиIdentity: namespace + source + event_id
sourceclient, edge или originПоказывает, чьё наблюдение записано
operation_idОперация demo-op-001Внутри неё возможны разные попытки
attempt_idПопытка demo-attempt-a либо nullНе восстанавливается по соседним строкам
event_nameЧто именно зафиксированоИмя класса события, не identity экземпляра
event_atВремя события по часам источника либо nullСмещение этих часов неизвестно
observed_atВремя наблюдения записи сборщикомНе время записи в базу данных
response_code_recordedЛокально зафиксированный HTTP-код либо nullСмысл зависит от event_name
duration_msЛокальная длительность в миллисекундах либо nullНужны отдельные границы интервала

Все одиннадцать ключей обязательны в этом формате. attempt_id:null допустим и означает отсутствие значения; физическое удаление ключа attempt_id — ошибка схемы. Это разные случаи. Неизвестное значение остаётся null, нулём его не заменяют. Правило не означает, что любое поле со значением 0 в чужой схеме ошибочно: перед переносом данных требуется прочитать исходную семантику.

Два времени не создают общие часы

В модели журналов OpenTelemetry различаются Timestamp — время события по часам источника — и ObservedTimestamp, когда событие наблюдал код сбора. Это помогает разделить возникновение и наблюдение. Наши event_at и observed_at используют ту же смысловую границу, но JSON ниже не заявлен совместимым с OTLP.

У клиента, edge и origin смещения часов неизвестны. Даже одинаковый формат UTC не подтверждает их синхронизацию. Поэтому сортировка event_at не доказывает порядок событий между компонентами. Единственный вымышленный сборщик даёт только порядок наблюдения записей по observed_at; равные значения не устанавливают порядок между собой.

OWASP отдельно отмечает ситуации, когда синхронизация недоступна, и необходимость учитывать смещение или уверенность во времени. В нашем контракте неизвестный event_at не подменяется observed_at, чтобы не потерять неизвестность. Это правило выбранного упражнения, а не универсальный запрет преобразования данных OpenTelemetry.

Прочитайте три вымышленные записи одной попытки

Три записи — одна заданная попыткаВымышленное упражнение: три источника передают записи одному сборщику. Стрелки обозначают только передачу и наблюдение записей, а не HTTP-путь или причинность. client, e1: timeout · код не зафиксирован; event_name=client_timeout; event_at=2000-01-01T10:00:02.000Z; observed_at=2000-01-01T10:00:02.100Z. edge, e2: записан 504; event_name=edge_response_recorded; event_at=2000-01-01T10:00:02.050Z; observed_at=2000-01-01T10:00:02.200Z. origin, e3: подготовлен 200; event_name=origin_response_prepared; event_at=2000-01-01T10:00:01.700Z; observed_at=2000-01-01T10:00:04.000Z. Сборщик наблюдает поступление e1, затем e2, затем e3. Смещения часов client, edge и origin неизвестны; порядок самих событий, причина отказа, доставка клиенту и бизнес-результат не установлены. Метрики скорости или задержки не рассчитываются. Общая связь задана условием: schema_version=data01.demo.v1, namespace=data01.synthetic, operation_id=demo-op-001, attempt_id=demo-attempt-a. Идентичность отдельной записи: namespace+source+event_id. schema_version относится только к этому редакционному контракту. Учебная схема подготовлена с помощью ИИ. Все записи, идентификаторы и времена вымышлены; схема не описывает инфраструктуру поставщика.Три записи — одна заданная попыткаСИНТЕТИЧЕСКИЙ ПРИМЕРСтрелки показывают передачу записей сборщику — это не HTTP-путь и не причинность.ТРИ ТОЧКИ НАБЛЮДЕНИЯНАБЛЮДЕНИЕ ЗАПИСЕЙclient · e1timeout · код не зафиксированevent_at2000-01-01T10:00:02.000Zobserved_at2000-01-01T10:00:02.100Zedge · e2записан 504event_at2000-01-01T10:00:02.050Zobserved_at2000-01-01T10:00:02.200Zorigin · e3подготовлен 200event_at2000-01-01T10:00:01.700Zobserved_at2000-01-01T10:00:04.000ZОдин вымышленный сборщикПорядок поступления по observed_at1e110:00:02.100Z2e210:00:02.200Z3e310:00:04.000ZПоступление: e1, затем e2, затем e3.Порядок самих событий из этихвремён не установлен.2000-01-01 · все времена вымышленыСвязь задана условием упражненияnamespace=data01.synthetic operation_id=demo-op-001 attempt_id=demo-attempt-aИдентичность отдельной записи: namespace + source + event_id. Это не ключ операции.schema_version=data01.demo.v1 — только редакционный контракт. Смещения часов client / edge / origin: UNKNOWN.Учебная схема подготовлена с помощью ИИ. Все записи, идентификаторы и времена вымышлены;схема не описывает инфраструктуру поставщика.
Учебная схема подготовлена с помощью ИИ. Все записи, идентификаторы и времена вымышлены; схема не описывает инфраструктуру поставщика.
Полное текстовое описание схемы

Вымышленное упражнение: три источника передают записи одному сборщику. Стрелки обозначают только передачу и наблюдение записей, а не HTTP-путь или причинность. client, e1: timeout · код не зафиксирован; event_name=client_timeout; event_at=2000-01-01T10:00:02.000Z; observed_at=2000-01-01T10:00:02.100Z. edge, e2: записан 504; event_name=edge_response_recorded; event_at=2000-01-01T10:00:02.050Z; observed_at=2000-01-01T10:00:02.200Z. origin, e3: подготовлен 200; event_name=origin_response_prepared; event_at=2000-01-01T10:00:01.700Z; observed_at=2000-01-01T10:00:04.000Z. Сборщик наблюдает поступление e1, затем e2, затем e3. Смещения часов client, edge и origin неизвестны; порядок самих событий, причина отказа, доставка клиенту и бизнес-результат не установлены. Метрики скорости или задержки не рассчитываются. Общая связь задана условием: schema_version=data01.demo.v1, namespace=data01.synthetic, operation_id=demo-op-001, attempt_id=demo-attempt-a. Идентичность отдельной записи: namespace+source+event_id. schema_version относится только к этому редакционному контракту. Учебная схема подготовлена с помощью ИИ. Все записи, идентификаторы и времена вымышлены; схема не описывает инфраструктуру поставщика.

Все идентификаторы и значения ниже придуманы. Дата 1 января 2000 года выбрана только для учебного набора; реального инцидента не было. Для трёх строк общими заданы schema_version=data01.demo.v1, namespace=data01.synthetic, operation_id=demo-op-001 и attempt_id=demo-attempt-a. Времена в таблице — UTC в этот вымышленный день.

Полный набор наблюдений: общие четыре поля указаны над таблицей
Запись / источник / событиеevent_atobserved_atКод / duration_ms
e1 · client · client_timeout10:00:02.000Z10:00:02.100Znull / 2000
e2 · edge · edge_response_recorded10:00:02.050Z10:00:02.200Z504 / null
e3 · origin · origin_response_prepared10:00:01.700Z10:00:04.000Z200 / 1700

Клиентская запись сообщает о локальном timeout без полученного кода. Запись edge фиксирует 504. Запись origin — подготовку ответа 200, а не его отправку или получение клиентом. Эти значения могут находиться в одной группе и описывать разные границы наблюдения; выбор одного «правильного» кода уничтожил бы часть сведений.

Нельзя вычесть 1700 из 2000 и назвать разность сетевой задержкой. Первый интервал в модели — ожидание клиентской попытки до timeout, второй — локальная обработка origin до подготовки ответа. Их начала и окончания различаются. Неизвестные смещения часов дополнительно запрещают считать межкомпонентную разность timestamp измеренной задержкой.

Три полные учебные записи; один JSON-объект в строке
{"schema_version":"data01.demo.v1","namespace":"data01.synthetic","event_id":"e1","source":"client","operation_id":"demo-op-001","attempt_id":"demo-attempt-a","event_name":"client_timeout","event_at":"2000-01-01T10:00:02.000Z","observed_at":"2000-01-01T10:00:02.100Z","response_code_recorded":null,"duration_ms":2000}
{"schema_version":"data01.demo.v1","namespace":"data01.synthetic","event_id":"e2","source":"edge","operation_id":"demo-op-001","attempt_id":"demo-attempt-a","event_name":"edge_response_recorded","event_at":"2000-01-01T10:00:02.050Z","observed_at":"2000-01-01T10:00:02.200Z","response_code_recorded":504,"duration_ms":null}
{"schema_version":"data01.demo.v1","namespace":"data01.synthetic","event_id":"e3","source":"origin","operation_id":"demo-op-001","attempt_id":"demo-attempt-a","event_name":"origin_response_prepared","event_at":"2000-01-01T10:00:01.700Z","observed_at":"2000-01-01T10:00:04.000Z","response_code_recorded":200,"duration_ms":1700}

Свяжите записи, сохранив несовпадения

Правило для этого набора: группировать только по полному ненулевому ключу schema_version + namespace + operation_id + attempt_id. Отдельно проверять identity каждой записи: namespace + source + event_id. Одинаковая identity — повод отметить повтор или конфликт значений, а не молча удалить строку.

  1. Проверить версию схемы, наличие всех одиннадцати ключей, типы и область упражнения. Недопустимый вход отметить как ошибку проверки и сохранить его отдельно в рамках учебного разбора; не превращать его в достоверное событие.
  2. Сохранить допустимую строку с attempt_id:null отдельно с причиной отсутствия связи. Не достраивать значение из operation_id, IP-адреса, времени или кода. Отсутствующий JSON-ключ не проходит предшествующую проверку схемы.
  3. Сопоставить только полностью совпавшие ключи. Группировка по одной операции здесь недостаточна.
  4. Внутри выбранной группы оставить три источника, исходные времена и локальные результаты. Повторы identity отметить и сохранить для разбора.

Для базового набора получается одна группа из e1, e2 и e3; неполных ключей и повторов identity нет. По часам сборщика записи наблюдались в порядке e1 → e2 → e3. Позднее поступление e3 не означает, что само событие origin произошло последним.

Результат сопоставления, а не диагноз
ВопросЧто известно в модели
Связь записейОдна вымышленная попытка по заданным доверенным ключам
Порядок наблюдения сборщикомe1, затем e2, затем e3
Порядок событий между компонентамиНе установлен: смещения часов неизвестны
Причина timeout или кода 504Не установлена
Доставка 200 клиенту и результат операцииНе установлены
Сетевая задержкаНе измерена

Измените по одному условию и проверьте вывод

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

Четыре отрицательных контроля
ИзменениеОжидаемый результатНедопустимый вывод
В e3 attempt_id заменить на demo-attempt-bДве группы размером 2 и 1; e3 не относится к попытке aПриписать 200 клиентской попытке a или объявить реальный retry
В e2 attempt_id сделать nulle2 сохранить без связи по выбранному правилу; e1/e3 остаются группойЗаполнить попытку по близкому времени или одному operation_id
Добавить точную копию e2Сохранить все 4 строки, отметить одну повторяющуюся identityПосчитать новый запрос или удалить повтор без проверки контракта
В e3 event_at сделать nullСохранить неизвестное время события; observed_at остаётся временем наблюденияВыдать время сборщика за время origin или восстановить причинный порядок

Для неполного ключа результат «без связи» относится именно к этому правилу. Он не доказывает невозможность другой корреляции при наличии дополнительных данных. При повторяющейся identity отдельно различают одинаковые данные и конфликт значений; ни один случай не исправляется автоматически в этом упражнении.

Поля поставщика читают в его собственной семантике

Документация Cloudflare предупреждает, что Ray ID не гарантированно уникален для каждого запроса. Поэтому его нельзя без проверки области и контекста объявить универсальным уникальным ключом. В ней также отмечена выборка в Security Events: отсутствие строки в таком поиске само по себе не доказывает отсутствия события.

В наборе Cloudflare HTTP Requests различаются EdgeResponseStatus и OriginResponseStatus. Второй относится к ответу upstream; его 0 имеет описанные условия, включая отдельный контекст Workers. Наше origin_response_prepared означает подготовку ответа в учебном приложении и не является переименованием этого поля. Локальный HTTP-код сам по себе не устанавливает причину отказа или защитное действие.

Объявление Cloudflare Log Explorer от 18 июня 2025 года описывало отдельное дополнение и возможности работы с журналами. Исторический материал Qrator о ClickHouse от 4 марта 2019 года объяснял выбранное аналитическое хранилище. Эти тексты дают контекст инструментов, но не подтверждают нашу схему полей, текущий тариф, полноту данных или результат испытаний. База данных и интерфейс поиска не задают смысл записей за автора их контракта.

Результат — проверяемый контракт для выбранной задачи

После упражнения должны остаться три самостоятельных результата: описание полей и их границ, сохранённые исходные записи и результат сопоставления с неизвестными значениями. Для нового источника сначала описывают его условия, затем адаптируют правило. Наличие похожего названия поля ещё не разрешает объединить данные.

  1. Назвать выбранную единицу связи: операция, конкретная попытка или запись. Зафиксировать область и версию идентификаторов.
  2. Указать источник, класс события, смысл каждого локального результата и происхождение доверия к ключу.
  3. Разделить время события и наблюдения, описать часы и неизвестные смещения. Для длительности назвать обе границы интервала.
  4. Отделить нарушение схемы от допустимого null. Явно определить, что делать с отсутствием значения ключа связи, повтором identity и конфликтом значений. Проверить четыре отрицательных контроля.
  5. Записать охват: какие точки, период и виды событий представлены, есть ли выборка или потери. Без этого отсутствие строки остаётся ограниченным свидетельством.
  6. Отдельно перечислить недоказанное: причина, доставка клиенту, завершение бизнес-операции и эффективность защиты. Не заполнять эти строки локальным кодом ответа.

В учебный набор не включены реальные IP-адреса, URL с параметрами, заголовки, cookies, токены, тела запросов, персональные профили или материалы рабочих кабинетов. OWASP перечисляет секреты и чувствительные сведения, которые требуют исключения либо специальной обработки. Для реального журнала состав данных, доступ и хранение определяются отдельно; этот пример не является юридической оценкой или готовой политикой сбора.

Проверьте сопоставление в автономном упражнении

В архиве — три вымышленные записи, контракт из одиннадцати полей, инструкция и Python-программа на стандартной библиотеке. Четыре изменения применяются по отдельности: другая попытка, неизвестный ключ, повтор записи и неизвестное время события.

Распакуйте ZIP и выполните в его папке python3 -B exercise.py. Упражнение читает только соседние файлы, выводит результат в терминал и не обращается к сети. Реальные журналы, токены и данные клиентов ему не нужны.

Скачать упражнение · ZIP · 11 КБ

Откроется публичная страница Яндекс Диска. Версия учебного контракта: data01.demo.v1. Это редакционный пример, не программа расследования реального отказа.

ПРОВЕРИТЬ ФАКТЫ

Первоисточники

  1. Logging Cheat Sheet

    Контекст события, идентификатор взаимодействия, ограничения часов и данные, требующие исключения или специальной обработки.

    OWASP. Дата публикации не указана. Проверено .

    Дата публикации на прочитанной странице не указана.

  2. Logs Data Model

    Различие Timestamp и ObservedTimestamp; источник и класс события. Собственный JSON не заявлен форматом OTLP.

    OpenTelemetry. Дата публикации не указана. Проверено .

    Дата публикации не указана; прочитана спецификация со статусом Stable.

  3. Cloudflare Ray ID

    Ограничение уникальности Ray ID и выборка в Security Events.

    Cloudflare. Дата публикации не указана. Обновлено . Проверено .

    15 октября 2026 — указанная дата обновления, не первоначальной публикации.

  4. HTTP Requests — Logpush dataset

    Отдельная семантика полей статуса edge и upstream. Она не переносится на origin_response_prepared.

    Cloudflare. Дата публикации не указана. Обновлено . Проверено .

    14 сентября 2026 — указанная дата обновления, не первоначальной публикации.

  5. Cloudflare Log Explorer is now GA, providing native observability and forensics

    Контекст работы с журналами и отдельного дополнения на дату объявления; не обещание текущих функций Free.

    Cloudflare. Опубликовано . Проверено .

    Историческое объявление от 18 июня 2025 года.

  6. БД ClickHouse в нейтрализации DDoS

    Описание выбранного аналитического хранилища. Не документация текущей схемы событий, SLA или измеренная сравнительная оценка.

    Curator; исторический текст Qrator Labs. Опубликовано . Проверено .

    Исторический текст от 4 марта 2019 года.

Made on
Tilda