Skip to content

zklrv/logberg

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

4 Commits
 
 
 
 
 
 
 
 
 
 

Repository files navigation

logberg

logberg — удобный структурированный логгер для Rust с минимальным API и “правильной” эргономикой:

  • Макросы уровней: trace!, debug!, info!, warn!, error!
  • Structured fields (поля) прямо в макросах:
    info!("user login"; user_id = 42, ip = "127.0.0.1")
  • Scoped context (контекст на блок):
    with_fields! { request_id = "req-1" => { ... } }
    Все логи внутри блока автоматически получают эти поля.
  • Форматы: Pretty (читаемый) и JSON
  • Фильтрация уровней через RUST_LOG (как env_logger)
  • Опционально: timestamp (feature time), ANSI-раскраска (feature ansi), файл (feature file)

Идея: быстро подключить логирование в приложении без “тяжелой” экосистемы, но сохранить structured-логи и контекст.


Быстрый старт

use logberg::{Logberg, Format};

fn main() {
    Logberg::builder()
        .format(Format::Pretty)
        .level_from_env("RUST_LOG")
        .init()
        .expect("logger init");

    logberg::info!("hello"; user_id = 42, action = "login");
}

Запуск с фильтром:

RUST_LOG=info,my_app=debug cargo run

Инициализация

1) Через builder()

use logberg::{Logberg, Format};

Logberg::builder()
    .format(Format::Pretty)         // или Format::Json
    .level_from_env("RUST_LOG")     // читает env-filter выражение
    .include_file_line(true)        // (опционально) file:line
    .include_thread(true)           // (опционально) имя/ID потока
    .include_target(true)           // (опционально) record.target()
    .include_module(false)          // (опционально) module_path
    .use_stderr_for_errors(true)    // error -> stderr, остальное -> stdout
    .init()
    .unwrap();

2) Быстрый дефолт

logberg::Logberg::init().unwrap();

Дефолты:

  • формат: Pretty
  • уровень: info
  • stderr для ошибок: включено
  • target: включен
  • timestamp зависит от feature time

Логиро��ание

Простое сообщение

logberg::info!("service started");
logberg::warn!("cache miss");
logberg::error!("db unavailable");

Structured fields (поля)

Синтаксис:
level!("message"; key = value, key2 = value2, ...)

logberg::info!("user login";
    user_id = 42,
    ip = "127.0.0.1",
    ok = true,
);

Правила:

  • keyидентификатор (например user_id, request_id)
  • value — любое выражение, форматируется через Display (format!("{}", value))

Если тебе нужно “красиво печатать” сложные структуры, обычно удобно передавать заранее подготовленную строку (например, через format!("{:?}", x)).


Scoped context (контекст на блок)

Иногда нужно добавить одни и те же поля ко всем логам внутри обработки запроса.

logberg::with_fields! { request_id = "req-123", user_id = 42 =>
    {
        logberg::debug!("handling request"; path = "/v1/items");
        logberg::warn!("slow query"; ms = 317);
    }
}

Контекст:

  • работает в текущем потоке (thread-local)
  • вложенные with_fields! накапливают поля (внутренний блок добавляет свои)

Форматы вывода

Pretty (Format::Pretty)

Пример:

2026-04-12T10:20:30Z INFO {my_app}: user login | user_id=42 ip=127.0.0.1 ok=true

Опционально можно включить:

  • include_thread(true) → добавляет [thread]
  • include_file_line(true) → добавляет (file.rs:123)
  • include_module(true) → добавляет module_path

JSON (Format::Json)

Пример:

{
  "ts":"2026-04-12T10:20:30Z",
  "level":"INFO",
  "msg":"user login",
  "target":"my_app",
  "fields":{"user_id":"42","ip":"127.0.0.1","ok":"true"}
}

JSON удобен для сборщиков логов (ELK/Datadog/Loki и т.п.).


Фильтрация уровней (RUST_LOG)

logberg использует формат, совместимый по духу с env_logger:

RUST_LOG=info cargo run
RUST_LOG=debug,my_app=trace cargo run
RUST_LOG=warn,hyper=error cargo run

Feature flags

В Cargo.toml:

logberg = { version = "0.1", features = ["time", "ansi"] }

Доступные фичи:

  • time — добавляет timestamp RFC3339 (UTC)
  • ansi — раскраска уровней в Pretty-формате
  • file — (опционально) запись в файл (если включено в реализации крейта)

Если в твоей версии крейта file feature включен: см. раздел “Лог в файл”.


Лог в файл (если включен feature file)

Cargo.toml:

logberg = { version = "0.1", features = ["file"] }

Код:

use logberg::{Format, Logberg};

Logberg::builder()
    .format(Format::Json)
    .level_from_env("RUST_LOG")
    .file("app.log")
    .init()
    .unwrap();

Поведение:

  • логи пишутся в stdout/stderr (по правилам) и дополнительно в файл
  • файл открывается в режиме append, создается при отсутствии

Совместимость с log

logberg является backend’ом для стандартного crate log, поэтому:

  • макросы log::info! и т.п. тоже будут работать
  • можно использовать сторонние библиотеки, которые логируют через log

Ограничения и дизайн-решения

  • Structured fields хранятся как строки (Display), то есть типы не сохраняются как “настоящие JSON-числа/boolean”.
    Это сделано ради простоты и стабильности API. Если нужно типизированное JSON — скажи, добавим режим “typed json”.
  • Scoped context — thread-local, т.е. не переносится автоматически между потоками и задачами async runtime.
    Для async-мира можно сделать интеграцию через tracing/Span-подобный контекст или через явную передачу контекста.

Рецепты

1) Логи ошибок в stderr, остальное в stdout

Logberg::builder()
  .use_stderr_for_errors(true)
  .init()
  .unwrap();

2) Включить file:line только в debug-сборке

let mut b = logberg::Logberg::builder()
    .level_from_env("RUST_LOG");

if cfg!(debug_assertions) {
    b = b.include_file_line(true);
}

b.init().unwrap();

Лицензия

MIT OR Apache-2.0

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages