1. Тема дня

Строим систему, которая после reset отвечает:

text
почему устройство перезапустилось;
какая операция была активна;
какое состояние FSM было последним;
какие события произошли перед аварией;
какой firmware ELF нужен для анализа.

Уровни наблюдаемости:

text
metrics -> structured events -> runtime trace -> crash dump

Главная мысль: текстовый лог показывает только то, что успели напечатать. Postmortem должен сохранять контекст даже при reset, watchdog, panic, занятом UART или поврежденном scheduler.

2. Зачем это нужно

Для EC25 нужно видеть:

text
modem FSM state;
AT transaction_id;
последний URC;
recovery level;
modem_generation;
последний progress;
reset reason.

Для фазовых входов:

c
raw input mask;
confirmed phase;
glitch counters;
queue high water;
ADC/DMA/GPIO-expander state.

Для STM32 HardFault:

text
stacked PC/LR;
CFSR/HFSR;
MMFAR/BFAR;
active task;
последние события.

3. Теория

Метрики

text
mqtt_disconnect_count=14
at_timeout_count=3
phase_queue_high_water=11
minimum_free_heap=38240

Отвечают: сколько раз и насколько плохо.

Структурированные события

text
time=124.180s module=MODEM event=AT_TIMEOUT transaction_id=1842 state=WAIT_PDP

Их можно выводить как текст, отправлять по MQTT, сохранять в RAM ring, проверять в HIL.

c
typedef struct {
    uint64_t mono_us;
    uint32_t sequence;
    uint32_t boot_id;
    uint32_t correlation_id;
    uint16_t module;
    uint16_t event;
    uint8_t severity;
    int32_t arg0;
    int32_t arg1;
    int32_t arg2;
} obs_event_t;

Boot ID, sequence, correlation

  • boot_id отделяет разные запуски;
  • sequence показывает порядок событий;
  • correlation_id связывает события одной операции;
  • generation отделяет поколения EC25/config/network.

Planned restart marker

esp_restart() сам по себе дает SOFTWARE reset, но не объясняет причину. Перед плановым reset сохрани marker:

c
typedef enum {
    APP_RESTART_NONE = 0,
    APP_RESTART_CLI,
    APP_RESTART_CONFIG_APPLY,
    APP_RESTART_OTA,
    APP_RESTART_RECOVERY_EXHAUSTED,
} app_restart_reason_t;

Marker хранится в .noinit, но обязательно имеет magic/version/CRC и очищается после чтения.

Breadcrumb ring

Храни последние N важных событий в RAM:

text
MODEM_STATE_CHANGED
AT_STARTED
AT_TIMEOUT
NETWORK_CHANGED
QUEUE_OVERFLOW
CONFIG_COMMIT_STARTED
POWER_WARNING
WATCHDOG_PROGRESS_MISSED

Не сохраняй каждое событие во Flash. Во Flash/NVS - только fault summary или planned marker.

Core dump ESP32

Core dump сохраняет stacks/TCB/registers задач и анализируется через:

text
idf.py coredump-info
idf.py coredump-debug

Для анализа нужен exact ELF той же сборки.

4. Типичные ошибки

  • Логируется только текст, без структурированных событий.
  • Используется только UTC без monotonic timestamp.
  • Не сохраняется Boot ID.
  • Любой restart называется watchdog.
  • Software reset не имеет planned marker.
  • Каждый event пишется во Flash.
  • .noinit используется без checksum.
  • HardFault handler вызывает обычный logger.
  • ELF release-сборки не сохраняется.
  • Core dump есть, но нет процедуры выгрузки.
  • Trace собирается без лимита.
  • Reboot считается успешной recovery без атрибуции причины.

5. Практическое задание на 30-60 минут

Создай OBSERVABILITY_POLICY.md:

markdown
# Observability policy
1. Every boot has a unique boot ID.
2. Durations and ordering use monotonic time.
3. Important operations have correlation IDs.
4. FSM transitions are recorded as structured events.
5. High-frequency values use counters and min/max statistics.
6. Breadcrumb recording does not allocate memory.
7. Flash is not written for every event.
8. Planned resets have an explicit persistent marker.
9. Retained records are protected by magic, version and checksum.
10. Every release keeps its ELF, map, sdkconfig and partition table.
11. Panic handling does not depend on ordinary logging.
12. Every field failure becomes a regression test.

Добавь diag boot:

text
boot_id=1842
reset_reason=TASK_WDT
planned_restart=no
firmware=1.18.0
git=9ac04be
config_generation=42
healthy_reached=yes
healthy_after=20220ms
previous_last_event=MODEM_AT_TIMEOUT

Добавь diag events 10 с последними breadcrumbs.

6. Что почитать или попробовать дальше

  • ESP-IDF Core Dump, Fatal Errors, Application Level Tracing, SystemView.
  • STM32 Fault Analyzer, Cortex-M fault status registers.
  • Tracealyzer/SystemView для timing/postmortem.
Reset отмечен как SOFTWARE. Какие дополнительные evidence лучше объяснят плановый restart?

Критерии: Разделите механизм reset и причину restart.

Задание

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

Критерии самопроверки: Нужны identity сборки и запуска, порядок событий, связь операции и ограниченное хранение. Текстовый лог не объявлять полным контекстом любого crash.

Показать ответ автора

Сохранить точный соответствующий ELF/build identity, reset reason или проверенный planned marker, boot_id, sequence, correlation_id и ограниченные последние breadcrumbs. Использовать monotonic timestamps. Не подменять ELF другой сборкой и не писать каждый event во Flash.