Журнал преобразований
Записывать нужно происхождение и результат, а не только сообщение «готово».
Связь между артефактами
Журнал преобразования связывает конкретный вход с конкретным выходом и правилом между ними. Имя файла недостаточно: под тем же именем может появиться другая версия. Хеш входа фиксирует байты, идентификатор преобразования задаёт логику, а хеш выхода позволяет проверить полученный артефакт. Время запуска помогает расследованию, но не заменяет эти связи.
Запись «импорт выполнен» без количества строк и кода версии мало полезна через несколько месяцев. Нельзя понять, использовалась ли новая схема, были ли отклонённые записи и тот ли файл обработан. Лучше небольшой структурированный объект с устойчивыми полями, чем длинный свободный текст, который каждый запуск формирует иначе.
Состояния процесса
Различайте начало, подготовку результата, commit и техническую ошибку. Сообщение success до публикации создаёт ложное доказательство завершения. Если процесс прервался между записью файла и переключением указателя, журнал должен позволять увидеть, какой этап подтверждён. Для маленького локального процесса можно писать отдельные завершённые записи по этапам, связывая их одним run_id.
Append-only журнал удобен для истории, но строка может оказаться оборванной при аварии. Читатель должен обнаружить повреждённую последнюю запись и явно сообщить о ней. Конкурентная запись несколькими процессами требует синхронизации; сам формат JSONL её не обеспечивает. Если нужен строгий учёт транзакций, SQLite иногда проще собственного протокола блокировок.
Что не должно попасть в журнал
Не записывайте реальные токены, строки подключения с паролем и полные значения персональных полей. Ошибка парсера иногда включает фрагмент входа, поэтому бездумное сохранение exception тоже раскрывает данные. Используйте номер записи, имя поля и категорию ошибки. Подробный закрытый диагностический файл, если он нужен, должен иметь отдельную политику доступа и хранения.
Абсолютный локальный путь может раскрыть устройство сервера и имя пользователя. В публичном manifest обычно достаточно относительного имени артефакта. Внутренний журнал допускает больше сведений, но и для него полезно ограничивать объём. Список всех исходных строк превращает журнал в ещё одну копию данных со своими требованиями к резервированию.
Читаемость и хранение
Структурированный журнал должен оставаться удобным для человека. Используйте короткие устойчивые названия статусов и отдельное поле для пояснения, если оно действительно нужно. Не меняйте смысл существующего статуса между версиями. Ограничьте срок хранения наблюдений, которые больше не нужны для восстановления, и сохраните долгосрочные связи между артефактами отдельно. Ротация журнала не должна разрывать незавершённый запуск на неотслеживаемые части. При переносе файлов журнала проверьте, что ссылки на run_id остаются уникальными в пределах всего архива. Если журнал используется как доказательство происхождения, права на его изменение и резервирование становятся частью модели доверия. Обычный текстовый файл без контроля доступа не обеспечивает неизменность истории сам по себе.
Практический состав записи
Минимальный набор включает run_id, версию правила, относительное имя входа, его размер и SHA-256, статус и время с явным UTC. После успешного преобразования добавляют выходной хеш, число принятых и отклонённых записей. Если параметры меняют смысл, сохраните их значения или хеш отдельного проверенного файла конфигурации.
Отделяйте воспроизводимые данные от наблюдений запуска. Время выполнения и timestamp естественно различаются при повторах, а опубликованный пример должен оставаться неизменным. В этом проекте образец журнала содержит фиксированную редакционную дату; реальная команда операции использует часы только при выполнении пользователем. Сборка сайта не выдаёт свою дату за новую проверку материала.
Попробуйте восстановить цепочку только по журналу и сохранённым файлам. Можно ли однозначно выбрать вход, найти версию преобразователя и подтвердить выход? Если нет, добавьте недостающую связь. Затем проверьте неуспешный сценарий: испорченную строку, заполненный диск и конфликт имени. Журнал ценен, когда помогает объяснить не только нормальный результат, но и границу, на которой процесс остановился.