Перейти к содержимому

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

amethystate шлёт структурированные события трассировки через крейт tracing. У всех событий таргет amethystate, так что фильтровать их можно отдельно от остального приложения.

События идут на уровне TRACE. Чтобы увидеть их, настройте подписчика tracing с включённым таргетом amethystate:

tracing_subscriber::fmt()
.with_env_filter("amethystate=trace")
.init();

Или через переменную окружения RUST_LOG:

Окно терминала
RUST_LOG=amethystate=trace cargo run

Каждый field.set() даёт одно событие:

TRACE amethystate: field write path=network.port source=NetworkState
TRACE amethystate: field write path=network.port source=external
Поле Значение
path Ключ поля в store, например network.port
source Короткое имя структуры, чей хендл позвал set(), или external, если хендл не принадлежит никакой структуре (форк, поле из field_with_path)

Каждый вызов колбэка подписки даёт одно событие:

TRACE amethystate: signal emit → subscription fire subscription_id=0 name=PortWatcher location=src/main.rs:42
TRACE amethystate: map signal emit → any subscription fire subscription_id=1 name=None location=src/server.rs:88
Поле Значение
subscription_id Монотонное целое: опознаёт подписку внутри её сигнала
name Метка из .named(), или None
location file:line того места, где позвали .subscribe()

Место вызова подписка запоминает сама, через #[track_caller]. Метку человеческими словами добавляют через .named() — для подписок из обобщённого кода или из кода фреймворка, где файл и строка сами по себе ничего не скажут:

let _sub = state.port()
.subscribe(|p| do_something(p))
.named("PortWatcher");
// ReactiveMap works the same way
let _sub = state.limits()
.subscribe_any(|change| handle(change))
.named("LimitsWatcher");

Дальше она стоит в каждом событии этой подписки.

Запись, за которой сработали два подписчика, выглядит так:

TRACE amethystate: field write path=network.port source=NetworkState
TRACE amethystate: signal emit → subscription fire subscription_id=0 name=PortWatcher location=src/ui.rs:55
TRACE amethystate: signal emit → subscription fire subscription_id=1 name=None location=src/logger.rs:12

source=external — это всё равно set() в этом процессе, только через хендл, которым не владеет никакая структура: форк или поле из field_with_path. Изменение, которое идёт мимо set(), — файл правили снаружи, писал другой процесс, сработал шаг миграции, — события field write не оставляет вовсе.