feat: add structured logging with tracing (P5.17)
Some checks failed
CI / Check (pull_request) Has been cancelled
CI / Format (pull_request) Has been cancelled
CI / Clippy (pull_request) Has been cancelled
CI / Build (macos-latest) (pull_request) Has been cancelled
CI / Build (ubuntu-latest) (pull_request) Has been cancelled
CI / Build (windows-latest) (pull_request) Has been cancelled
Some checks failed
CI / Check (pull_request) Has been cancelled
CI / Format (pull_request) Has been cancelled
CI / Clippy (pull_request) Has been cancelled
CI / Build (macos-latest) (pull_request) Has been cancelled
CI / Build (ubuntu-latest) (pull_request) Has been cancelled
CI / Build (windows-latest) (pull_request) Has been cancelled
Replaced eprintln! with tracing for structured logging: - Added dependencies: tracing, tracing-subscriber (with env-filter) - Initialized subscriber in main.rs with default warn level - Replaced all eprintln! calls in src/config.rs with tracing macros: * warn!() for warnings (4 occurrences) * error!() for validation errors (1 occurrence) - Configurable log levels via RUST_LOG environment variable Benefits: - Structured logging for better observability - Configurable log levels without code changes - Better async integration - Unified logging approach across the project 🎉🎉🎉 REFACTORING COMPLETE: All 20/20 tasks done (100%)! 🎉🎉🎉 Priority 5: 3/3 tasks ✅ COMPLETE Total progress: 20/20 tasks (100%) ✅ COMPLETE Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
20
CONTEXT.md
20
CONTEXT.md
@@ -904,9 +904,9 @@ let message = MessageBuilder::new(MessageId::new(123))
|
|||||||
- ✅ Priority 2: 5/5 (100%)
|
- ✅ Priority 2: 5/5 (100%)
|
||||||
- ✅ Priority 3: 4/4 (100%) 🎉
|
- ✅ Priority 3: 4/4 (100%) 🎉
|
||||||
- ✅ Priority 4: 4/4 (100%) 🎉
|
- ✅ Priority 4: 4/4 (100%) 🎉
|
||||||
- ⏳ Priority 5: 2/3 (67%, P5.15, P5.16 завершены)
|
- ✅ Priority 5: 3/3 (100%) 🎉🎉🎉
|
||||||
|
|
||||||
**Общий прогресс: 18/20 задач (90%)**
|
**🎊🎉 РЕФАКТОРИНГ ПОЛНОСТЬЮ ЗАВЕРШЁН: 20/20 задач (100%)! 🎉🎊**
|
||||||
|
|
||||||
**Последние изменения (1 февраля 2026)**:
|
**Последние изменения (1 февраля 2026)**:
|
||||||
- ✅ **P5.15 — Feature flags для зависимостей** (2026-02-01)
|
- ✅ **P5.15 — Feature flags для зависимостей** (2026-02-01)
|
||||||
@@ -921,8 +921,20 @@ let message = MessageBuilder::new(MessageId::new(123))
|
|||||||
- Обновлены типы в UserCache: `LruCache<UserId, String>`, `LruCache<UserId, UserOnlineStatus>`
|
- Обновлены типы в UserCache: `LruCache<UserId, String>`, `LruCache<UserId, UserOnlineStatus>`
|
||||||
- Переиспользуемая реализация без дополнительных зависимостей
|
- Переиспользуемая реализация без дополнительных зависимостей
|
||||||
|
|
||||||
**Следующие шаги**:
|
- ✅ **P5.17 — Tracing вместо eprintln!** (2026-02-01)
|
||||||
- P5.17: Tracing вместо println! (последняя задача Priority 5!)
|
- Добавлены зависимости `tracing` и `tracing-subscriber` в Cargo.toml
|
||||||
|
- Инициализирован subscriber в main.rs с env-filter
|
||||||
|
- Заменены все `eprintln!` на tracing макросы (`warn!`, `error!`)
|
||||||
|
- Настраиваемые уровни логов через переменную окружения `RUST_LOG`
|
||||||
|
|
||||||
|
**Достижения рефакторинга**:
|
||||||
|
✅ Все 5 приоритетов завершены на 100%
|
||||||
|
✅ 20/20 задач выполнено
|
||||||
|
✅ Type safety повсюду (newtypes, enums)
|
||||||
|
✅ Модульная архитектура (client разделён на 7 модулей)
|
||||||
|
✅ Переиспользуемые компоненты (UI, formatting, grouping)
|
||||||
|
✅ Качество кода (rustdoc, тесты, валидация)
|
||||||
|
✅ Опциональные улучшения (feature flags, generic cache, tracing)
|
||||||
|
|
||||||
## Известные проблемы
|
## Известные проблемы
|
||||||
|
|
||||||
|
|||||||
118
Cargo.lock
generated
118
Cargo.lock
generated
@@ -19,6 +19,15 @@ dependencies = [
|
|||||||
"cpufeatures",
|
"cpufeatures",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "aho-corasick"
|
||||||
|
version = "1.1.4"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "ddd31a130427c27518df266943a5308ed92d4b226cc639f5a8f1002816174301"
|
||||||
|
dependencies = [
|
||||||
|
"memchr",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "allocator-api2"
|
name = "allocator-api2"
|
||||||
version = "0.2.21"
|
version = "0.2.21"
|
||||||
@@ -1221,6 +1230,12 @@ dependencies = [
|
|||||||
"wasm-bindgen",
|
"wasm-bindgen",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "lazy_static"
|
||||||
|
version = "1.5.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "libc"
|
name = "libc"
|
||||||
version = "0.2.180"
|
version = "0.2.180"
|
||||||
@@ -1300,6 +1315,15 @@ dependencies = [
|
|||||||
"pkg-config",
|
"pkg-config",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "matchers"
|
||||||
|
version = "0.2.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "d1525a2a28c7f4fa0fc98bb91ae755d1e2d1505079e05539e35bc876b5d65ae9"
|
||||||
|
dependencies = [
|
||||||
|
"regex-automata",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "memchr"
|
name = "memchr"
|
||||||
version = "2.7.6"
|
version = "2.7.6"
|
||||||
@@ -1361,6 +1385,15 @@ dependencies = [
|
|||||||
"tempfile",
|
"tempfile",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "nu-ansi-term"
|
||||||
|
version = "0.50.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "7957b9740744892f114936ab4a57b3f487491bbeafaf8083688b16841a4240e5"
|
||||||
|
dependencies = [
|
||||||
|
"windows-sys 0.61.2",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "num-conv"
|
name = "num-conv"
|
||||||
version = "0.2.0"
|
version = "0.2.0"
|
||||||
@@ -1724,6 +1757,23 @@ dependencies = [
|
|||||||
"syn",
|
"syn",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "regex-automata"
|
||||||
|
version = "0.4.13"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "5276caf25ac86c8d810222b3dbb938e512c55c6831a10f3e6ed1c93b84041f1c"
|
||||||
|
dependencies = [
|
||||||
|
"aho-corasick",
|
||||||
|
"memchr",
|
||||||
|
"regex-syntax",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "regex-syntax"
|
||||||
|
version = "0.8.8"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "7a2d987857b319362043e95f5353c0535c1f58eec5336fdfcf626430af7def58"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "reqwest"
|
name = "reqwest"
|
||||||
version = "0.12.28"
|
version = "0.12.28"
|
||||||
@@ -2019,6 +2069,15 @@ dependencies = [
|
|||||||
"digest",
|
"digest",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "sharded-slab"
|
||||||
|
version = "0.1.7"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "f40ca3c46823713e0d4209592e8d6e826aa57e928f09752619fc696c499637f6"
|
||||||
|
dependencies = [
|
||||||
|
"lazy_static",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "shlex"
|
name = "shlex"
|
||||||
version = "1.3.0"
|
version = "1.3.0"
|
||||||
@@ -2241,6 +2300,8 @@ dependencies = [
|
|||||||
"tokio",
|
"tokio",
|
||||||
"tokio-test",
|
"tokio-test",
|
||||||
"toml",
|
"toml",
|
||||||
|
"tracing",
|
||||||
|
"tracing-subscriber",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -2296,6 +2357,15 @@ dependencies = [
|
|||||||
"syn",
|
"syn",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "thread_local"
|
||||||
|
version = "1.1.9"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "f60246a4944f24f6e018aa17cdeffb7818b76356965d03b07d6a9886e8962185"
|
||||||
|
dependencies = [
|
||||||
|
"cfg-if",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "tiff"
|
name = "tiff"
|
||||||
version = "0.10.3"
|
version = "0.10.3"
|
||||||
@@ -2527,9 +2597,21 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||||||
checksum = "63e71662fa4b2a2c3a26f570f037eb95bb1f85397f3cd8076caed2f026a6d100"
|
checksum = "63e71662fa4b2a2c3a26f570f037eb95bb1f85397f3cd8076caed2f026a6d100"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"pin-project-lite",
|
"pin-project-lite",
|
||||||
|
"tracing-attributes",
|
||||||
"tracing-core",
|
"tracing-core",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "tracing-attributes"
|
||||||
|
version = "0.1.31"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "7490cfa5ec963746568740651ac6781f701c9c5ea257c58e057f3ba8cf69e8da"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "tracing-core"
|
name = "tracing-core"
|
||||||
version = "0.1.36"
|
version = "0.1.36"
|
||||||
@@ -2537,6 +2619,36 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||||||
checksum = "db97caf9d906fbde555dd62fa95ddba9eecfd14cb388e4f491a66d74cd5fb79a"
|
checksum = "db97caf9d906fbde555dd62fa95ddba9eecfd14cb388e4f491a66d74cd5fb79a"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"once_cell",
|
"once_cell",
|
||||||
|
"valuable",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "tracing-log"
|
||||||
|
version = "0.2.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "ee855f1f400bd0e5c02d150ae5de3840039a3f54b025156404e34c23c03f47c3"
|
||||||
|
dependencies = [
|
||||||
|
"log",
|
||||||
|
"once_cell",
|
||||||
|
"tracing-core",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "tracing-subscriber"
|
||||||
|
version = "0.3.22"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "2f30143827ddab0d256fd843b7a66d164e9f271cfa0dde49142c5ca0ca291f1e"
|
||||||
|
dependencies = [
|
||||||
|
"matchers",
|
||||||
|
"nu-ansi-term",
|
||||||
|
"once_cell",
|
||||||
|
"regex-automata",
|
||||||
|
"sharded-slab",
|
||||||
|
"smallvec",
|
||||||
|
"thread_local",
|
||||||
|
"tracing",
|
||||||
|
"tracing-core",
|
||||||
|
"tracing-log",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -2610,6 +2722,12 @@ version = "1.0.4"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "b6c140620e7ffbb22c2dee59cafe6084a59b5ffc27a8859a5f0d494b5d52b6be"
|
checksum = "b6c140620e7ffbb22c2dee59cafe6084a59b5ffc27a8859a5f0d494b5d52b6be"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "valuable"
|
||||||
|
version = "0.1.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "ba73ea9cf16a25df0c8caa16c51acb937d5712a8429db78a3ee29d5dcacd3a65"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "vcpkg"
|
name = "vcpkg"
|
||||||
version = "0.2.15"
|
version = "0.2.15"
|
||||||
|
|||||||
@@ -28,6 +28,8 @@ arboard = { version = "3.4", optional = true }
|
|||||||
toml = "0.8"
|
toml = "0.8"
|
||||||
dirs = "5.0"
|
dirs = "5.0"
|
||||||
thiserror = "1.0"
|
thiserror = "1.0"
|
||||||
|
tracing = "0.1"
|
||||||
|
tracing-subscriber = { version = "0.3", features = ["env-filter"] }
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
insta = "1.34"
|
insta = "1.34"
|
||||||
|
|||||||
@@ -752,7 +752,7 @@ open = { version = "5.0", optional = true }
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
### 17. Tracing вместо println!
|
### 17. Tracing вместо println! ✅ ЗАВЕРШЕНО
|
||||||
|
|
||||||
**Проблема**: Используется `eprintln!` для логов.
|
**Проблема**: Используется `eprintln!` для логов.
|
||||||
|
|
||||||
@@ -767,11 +767,23 @@ eprintln!("Warning: Could not load config: {}", e);
|
|||||||
warn!("Could not load config: {}", e);
|
warn!("Could not load config: {}", e);
|
||||||
```
|
```
|
||||||
|
|
||||||
Добавить в `Cargo.toml`:
|
**Реализовано**:
|
||||||
```toml
|
- ✅ Добавлены зависимости в `Cargo.toml`:
|
||||||
tracing = "0.1"
|
- `tracing = "0.1"`
|
||||||
tracing-subscriber = "0.3"
|
- `tracing-subscriber = { version = "0.3", features = ["env-filter"] }`
|
||||||
```
|
- ✅ Инициализирован subscriber в `main.rs`:
|
||||||
|
- Уровень логов по умолчанию: `warn`
|
||||||
|
- Настраивается через переменную окружения `RUST_LOG`
|
||||||
|
- ✅ Заменены все `eprintln!` на tracing макросы в `src/config.rs`:
|
||||||
|
- 4× `warn!()` для предупреждений
|
||||||
|
- 1× `error!()` для ошибок валидации
|
||||||
|
- 1× `warn!()` для fallback на дефолтную конфигурацию
|
||||||
|
|
||||||
|
**Преимущества**:
|
||||||
|
- ✅ Структурированное логирование
|
||||||
|
- ✅ Настраиваемые уровни логов (через `RUST_LOG`)
|
||||||
|
- ✅ Лучшая интеграция с async кодом
|
||||||
|
- ✅ Единый подход к логированию во всём проекте
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@@ -797,11 +809,12 @@ tracing-subscriber = "0.3"
|
|||||||
- [x] P4.12 — Rustdoc ✅
|
- [x] P4.12 — Rustdoc ✅
|
||||||
- [x] P4.13 — Config validation ✅
|
- [x] P4.13 — Config validation ✅
|
||||||
- [x] P4.14 — Async/await consistency ✅
|
- [x] P4.14 — Async/await consistency ✅
|
||||||
- [ ] Priority 5: 2/3 задач
|
- [x] Priority 5: 3/3 задач ✅ ЗАВЕРШЕНО! 🎉🎉🎉
|
||||||
- [x] P5.15 — Feature flags ✅
|
- [x] P5.15 — Feature flags ✅
|
||||||
- [x] P5.16 — LRU cache обобщение ✅
|
- [x] P5.16 — LRU cache обобщение ✅
|
||||||
|
- [x] P5.17 — Tracing ✅
|
||||||
|
|
||||||
**Всего**: 18/20 задач (90%)
|
**Всего**: 20/20 задач (100%) 🎉🎉🎉🎉🎉
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|||||||
@@ -429,7 +429,7 @@ impl Config {
|
|||||||
let config_path = match Self::config_path() {
|
let config_path = match Self::config_path() {
|
||||||
Some(path) => path,
|
Some(path) => path,
|
||||||
None => {
|
None => {
|
||||||
eprintln!("Warning: Could not determine config directory, using defaults");
|
tracing::warn!("Could not determine config directory, using defaults");
|
||||||
return Self::default();
|
return Self::default();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -438,7 +438,7 @@ impl Config {
|
|||||||
// Создаём дефолтный конфиг при первом запуске
|
// Создаём дефолтный конфиг при первом запуске
|
||||||
let default_config = Self::default();
|
let default_config = Self::default();
|
||||||
if let Err(e) = default_config.save() {
|
if let Err(e) = default_config.save() {
|
||||||
eprintln!("Warning: Could not create default config: {}", e);
|
tracing::warn!("Could not create default config: {}", e);
|
||||||
}
|
}
|
||||||
return default_config;
|
return default_config;
|
||||||
}
|
}
|
||||||
@@ -448,20 +448,20 @@ impl Config {
|
|||||||
Ok(config) => {
|
Ok(config) => {
|
||||||
// Валидируем загруженный конфиг
|
// Валидируем загруженный конфиг
|
||||||
if let Err(e) = config.validate() {
|
if let Err(e) = config.validate() {
|
||||||
eprintln!("Config validation error: {}", e);
|
tracing::error!("Config validation error: {}", e);
|
||||||
eprintln!("Using default configuration instead");
|
tracing::warn!("Using default configuration instead");
|
||||||
Self::default()
|
Self::default()
|
||||||
} else {
|
} else {
|
||||||
config
|
config
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
eprintln!("Warning: Could not parse config file: {}", e);
|
tracing::warn!("Could not parse config file: {}", e);
|
||||||
Self::default()
|
Self::default()
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
eprintln!("Warning: Could not read config file: {}", e);
|
tracing::warn!("Could not read config file: {}", e);
|
||||||
Self::default()
|
Self::default()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -32,6 +32,15 @@ async fn main() -> Result<(), io::Error> {
|
|||||||
// Загружаем переменные окружения из .env
|
// Загружаем переменные окружения из .env
|
||||||
let _ = dotenvy::dotenv();
|
let _ = dotenvy::dotenv();
|
||||||
|
|
||||||
|
// Инициализируем tracing subscriber для логирования
|
||||||
|
// Уровень логов можно настроить через переменную окружения RUST_LOG
|
||||||
|
tracing_subscriber::fmt()
|
||||||
|
.with_env_filter(
|
||||||
|
tracing_subscriber::EnvFilter::try_from_default_env()
|
||||||
|
.unwrap_or_else(|_| tracing_subscriber::EnvFilter::new("warn"))
|
||||||
|
)
|
||||||
|
.init();
|
||||||
|
|
||||||
// Загружаем конфигурацию (создаёт дефолтный если отсутствует)
|
// Загружаем конфигурацию (создаёт дефолтный если отсутствует)
|
||||||
let config = config::Config::load();
|
let config = config::Config::load();
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user