Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Наблюдаемость

masterror рассматривает телеметрию как часть жизненного цикла ошибки. Каждый AppError отслеживает флаг изменения; телеметрия испускается один раз на каждое изменение состояния — при конструировании, после мутации или когда ошибка пересекает транспортную границу (IntoResponse в Axum, error_response() в Actix, конверсия в Status для tonic). Вручную почти ничего вызывать не нужно.

Флаги функций

ФлагЧто добавляет
tracingСтруктурированное событие tracing на каждую ошибку, trace_id через log-mdc
metricsСчётчик error_total{code,category} через крейт metrics
backtraceЛенивый захват std::backtrace::Backtrace, управляемый RUST_BACKTRACE
coloredANSI-раскраска терминального вывода с детекцией TTY
[dependencies]
masterror = { version = "0.28", features = ["tracing", "metrics", "backtrace"] }

Tracing

С включённым tracing каждая ошибка испускает одно событие уровня ERROR с target masterror::error:

ПолеСодержимое
codeСтрока AppCode, например NOT_FOUND
categoryМетка AppErrorKind, например Database
messageПубличное сообщение, если есть
retry_secondsРекомендация о повторе, если задана
redactableРедактируется ли сообщение на транспортных границах
metadata_lenКоличество присоединённых полей метаданных
www_authenticateВызов аутентификации, если задан
trace_idБерётся из ключа trace_id контекста log-mdc, если присутствует

Испускание учитывает подписчика: если ни один подписчик не заинтересован в событиях уровня ERROR для этого target, событие остаётся в ожидании и повторяется при следующем сбросе, так что ничего не теряется при поздней установке подписчика.

Чтобы соотносить ошибки с запросами, сохраните trace ID в MDC в middleware запроса:

log_mdc::insert("trace_id", request_id);

Каждая ошибка, сконструированная пока ключ установлен, несёт его в событии.

Метрики

С включённым metrics каждая свежеизменённая ошибка инкрементирует:

error_total{code="NOT_FOUND", category="NotFound"}

Обе метки — стабильные строки (AppCode::as_str() и метка AppErrorKind), поэтому дашборды и алерты переживают рефакторинг ваших доменных типов. Подключайте любой recorder metrics (Prometheus, StatsD, …) как обычно; masterror использует только metrics::counter!.

Бэктрейсы

С включённым backtrace снимок Backtrace захватывается лениво в момент сброса телеметрии, а не при каждом конструировании. Захват управляется RUST_BACKTRACE: не задано, пустое, 0, off и false отключают его; любое другое значение включает. Настройка читается один раз и кэшируется на процесс.

#[cfg(feature = "backtrace")] {
use masterror::AppError;

let err = AppError::internal("db down");
if let Some(bt) = err.backtrace() {
    eprintln!("{bt}");
}
}

Можно также присоединить заранее захваченный трейс через AppError::with_backtrace(backtrace) — он имеет приоритет над ленивым захватом.

Ручной сброс через .log()

Конструкторы и конверсии испускают телеметрию автоматически. После мутации ошибки (добавление полей, изменение рекомендации о повторе) можно принудительно испустить её заново:

use masterror::{AppError, field};

let err = AppError::service("upstream degraded")
    .with_field(field::str("upstream", "billing"));
err.log();

log() идемпотентен в рамках состояния: если с последнего испускания ничего не изменилось, он ничего не делает. HTTP/gRPC-адаптеры делают такой же сброс на границе, поэтому ошибка, которая сконструирована, обогащена и затем возвращена из обработчика Axum, испускается один раз на состояние — один раз при конструировании и один раз на границе для обогащённого состояния — и никогда дважды для одного состояния.

Инспекция цепочки

Независимо от флагов, AppError предоставляет инструменты, нужные конвейерам логирования:

#[cfg(feature = "std")] {
use std::io::Error as IoError;
use masterror::AppError;

let err = AppError::internal("db down").with_context(IoError::other("disk offline"));

assert_eq!(err.chain().count(), 2);
let _root = err.root_cause();
assert!(err.metadata().is_empty());
}

metadata().iter_with_redaction() выдаёт тройки (key, value, policy), чтобы слой логирования мог соблюдать редактирование полей — см. Контекст и метаданные.

Цветной терминальный вывод

Флаг colored добавляет masterror::colored::style для CLI-инструментов. Цвета применяются только когда stderr — это TTY, NO_COLOR не задан, TERM не равен dumb и терминал поддерживает ANSI; иначе текст проходит без изменений. Результат детекции кэшируется на процесс.

ФункцияСтильДля чего
error_kind_criticalкрасныйкритические виды сбоев
error_kind_warningжёлтыйвосстановимые виды/предупреждения
error_codeголубоймашинные коды
error_messageярко-белыйосновное сообщение
source_contextприглушённыйвторичная информация об источнике
metadata_keyзелёныйимена структурированных полей
#[cfg(feature = "colored")] {
use masterror::colored::style;

eprintln!(
    "{}: {}",
    style::error_code("ERR_DB_001"),
    style::error_message("Database connection failed")
);
}

Запускаемое демо: examples/colored_cli.rs.

См. также: Флаги возможностей · Контекст и метаданные · Веб-фреймворки · Лучшие практики