- половина потока (50 доставок из 104) не несёт metrics вовсе и до сих пор числилась parsed: ретеншен, поверив статусу, срезал бы тела stateOfMind, которых в экспорте Apple нет - разбор перечисляет верхнеуровневые ключи data, непокрытые проглатываются декодированием: тело 40 МиБ из непокрытой секции удерживает 0 МиБ - статус partial и колонка delivery.uncovered_sections; миграция переводит прежние parsed в pending — им верить нельзя - витрина не изменилась: отпечаток совпал с прогоном до изменения
7.9 KiB
ADDED Requirements
Requirement: Учёт частично разобранной доставки
Система SHALL отличать доставку, разобранную целиком, от доставки, в теле
которой остались непокрытые разбором секции. Доставка с непустым списком
непокрытых ключей MUST получать статус partial, а не parsed.
Статусы разбора:
pending этим разбором ещё не смотрели
parsed разобрано всё, что в теле было
partial разобрано покрытое; в теле остались непокрытые секции
failed разобрать не удалось, точек нет
Источник истины — список непокрытых ключей; статус производен от него и от
факта отказа, в порядке failed → partial → parsed. Приоритет назван явно,
чтобы читатели (ретеншен, статистика) спрашивали статус, а не сравнивали список
со строкой.
Список непокрытых ключей SHALL сохраняться рядом с доставкой — именами ключей,
без содержимого секций. Он же ответ на вопрос «что останется потерянным, если
тело удалить»: для stateOfMind доставки HAE единственный источник, в экспорте
Apple его нет (находка 46). Поэтому список MUST сохраняться и при отказе
разбора, если разбор успел его собрать: failed с непустым списком — законное
состояние.
Запись списка MUST замещать прежнее значение целиком, включая замещение пустым:
иначе доставка, все секции которой стали покрытыми, осталась бы partial
навсегда.
Список — снимок покрытия на момент свёртки. Задача, которая начинает
разбирать секцию, тем же изменением SHALL переводить partial-строки с этим
ключом в pending; ретеншену позволено смотреть на partial только при
соблюдении этого правила.
Статусы, поставленные разбором, который частичного исхода не различал, доверия
не заслуживают: под parsed у них лежат и полностью разобранные доставки, и
доставки без метрик вовсе. Такие строки MUST переводиться в pending — «этим
разбором ещё не смотрели». Число точек у них до пересвёртки остаётся прежним: оно
производно от объектов витрины, которые никуда не делись.
Scenario: Доставка с непокрытой секцией отмечается частичной
- WHEN разбор доставки вернул непустой список непокрытых ключей
- THEN
parse_statusдоставки равенpartial - AND список непокрытых ключей сохранён вместе с доставкой
- AND точки покрытой секции сохранены как обычно
Scenario: Доставка без непокрытых секций остаётся parsed
- WHEN разбор доставки не дал непокрытых ключей
- THEN
parse_statusравенparsed - AND сохранённый список непокрытых ключей пуст
Scenario: Отказ разбора сильнее частичности
- WHEN разбор доставки завершился ошибкой
- THEN
parse_statusравенfailed - AND список непокрытых ключей сохранён, если разбор успел его собрать
Scenario: Пересвёртка после того, как секция стала покрытой
- WHEN доставка со статусом
partialсворачивается повторно разбором, который эту секцию уже покрывает - THEN её статус становится
parsed - AND сохранённый список непокрытых ключей пуст
Scenario: Строки прежнего разбора переводятся в неразобранные
- WHEN база содержит доставки со статусом
parsed, свёрнутые до появления частичного статуса - THEN после миграции их статус равен
pending - AND тела остаются в архиве, а повторная свёртка даёт то же состояние
MODIFIED Requirements
Requirement: Значения точек не попадают в логи
Данные о здоровье чувствительнее токенов. Система MUST NOT писать значения
точек и тела доставок в записи лога уровня выше DEBUG.
Непокрытые секции называются в логе именами ключей: имя секции — это форма
пакета, а не измерение. Содержимое секции в лог не попадает ни при каком уровне
выше DEBUG. Имена идут структурным атрибутом, а не склейкой в текст сообщения:
кодировщик экранирует управляющие символы, и имя из чужого тела не разрывает
построчный разбор логов.
Частичный разбор уровня записи не повышает: partial — установившееся состояние
половины потока (48 доставок из 99), и постоянный WARN обесценил бы уровень.
Повышает уровень другое — срабатывание границ списка: тело с сотнями секций или
с именем длиннее предела на HAE не похоже вовсе.
Scenario: Разбор доставки логируется без значений
- WHEN доставка разобрана
- THEN запись лога содержит счётчики (метрик, точек, объектов) и идентификатор доставки
- AND не содержит ни значений точек, ни имён устройств
Scenario: Непокрытые секции названы именами ключей
- WHEN доставка содержит непокрытую секцию
- THEN запись лога содержит имена непокрытых ключей отдельным атрибутом
- AND не содержит ничего из содержимого этих секций
- AND уровень записи из-за одной лишь частичности не повышается
Scenario: Границы списка сработали
- WHEN список непокрытых ключей усечён по числу имён или по длине имени
- THEN запись лога имеет уровень
WARN - AND содержит число отброшенных имён