Мониторинг приложений на Rust: полный обзор библиотек и инструментов
Rust — язык системного программирования, который всё чаще используется для создания высоконагруженных веб-сервисов, сетевых демонов и инфраструктурных компонентов. Однако даже самый быстрый код требует наблюдения. В этой статье мы разберём ключевые библиотеки для мониторинга приложений на Rust: tracing, metrics и интеграцию с OpenTelemetry. Вы узнаете, как собирать логи, метрики и трейсы, чтобы держать ваше приложение под контролем.
1. Зачем нужен мониторинг в Rust?
Без мониторинга вы не узнаете о проблемах до тех пор, пока пользователи не начнут жаловаться. Rust-приложения обычно работают в продакшне 24/7, поэтому важно отслеживать:
- потребление памяти и CPU;
- время ответа на запросы;
- количество ошибок и паник;
- состояние соединений с базами данных и внешними API.
Хорошая новость: экосистема Rust предлагает зрелые решения для observability (наблюдаемости).
2. Библиотека tracing — структурированное логирование и трейсинг
tracing — это фреймворк для инструментирования программ на Rust. Он позволяет создавать спаны (span) — единицы работы, которые можно вкладывать друг в друга, и события (event) — точки с информацией.
Установка
[dependencies]
tracing = "0.1"
tracing-subscriber = "0.3"
Пример: базовый трейсинг HTTP-запроса
use tracing::{info, span, Level};
use tracing_subscriber;
fn handle_request(user_id: u64) {
let span = span!(Level::INFO, "handle_request", user_id);
let _guard = span.enter();
info!("Обработка запроса начата");
// ... логика обработки ...
info!("Запрос завершён");
}
fn main() {
tracing_subscriber::fmt::init();
handle_request(42);
}
Вывод в консоль будет содержать структурированные поля, которые легко парсить grep или отправлять в Jaeger.
3. Библиотека metrics — сбор числовых метрик
metrics — это легковесная библиотека для сбора счётчиков, гистограмм и датчиков (gauges). Она идеально подходит для мониторинга в реальном времени.
Установка
[dependencies]
metrics = "0.22"
metrics-exporter-prometheus = "0.14"
Пример: счётчик запросов и гистограмма времени
use metrics::{counter, histogram};
use std::time::Instant;
fn process_request() {
let start = Instant::now();
counter!("requests_total", 1);
// ... эмуляция работы ...
std::thread::sleep(std::time::Duration::from_millis(50));
let duration = start.elapsed().as_secs_f64();
histogram!("request_duration_seconds", duration);
}
Чтобы метрики были доступны по HTTP (для Prometheus), добавьте экспортёр:
use metrics_exporter_prometheus::PrometheusBuilder;
fn setup_metrics() {
let builder = PrometheusBuilder::new();
builder.install().expect("Не удалось установить экспортёр");
// Метрики будут доступны на http://localhost:9000/metrics
}
4. OpenTelemetry — универсальный стандарт observability
OpenTelemetry (OTel) — это вендор-нейтральный фреймворк для сбора трейсов, метрик и логов. Для Rust есть крейт opentelemetry с поддержкой OTLP (OpenTelemetry Protocol).
Установка
[dependencies]
opentelemetry = { version = "0.22", features = ["rt-tokio"] }
opentelemetry-otlp = "0.15"
tracing-opentelemetry = "0.23"
Пример: интеграция tracing с OpenTelemetry
use opentelemetry::global;
use tracing_subscriber::layer::SubscriberExt;
use tracing_subscriber::Registry;
fn init_otel() {
let tracer = opentelemetry_otlp::new_pipeline()
.install_simple()
.expect("Не удалось создать tracer");
let telemetry = tracing_opentelemetry::layer().with_tracer(tracer);
let subscriber = Registry::default().with(telemetry);
tracing::subscriber::set_global_default(subscriber)
.expect("Не удалось установить subscriber");
}
#[tokio::main]
async fn main() {
init_otel();
// Теперь все спаны и события из tracing автоматически отправляются в OTel-коллектор
tracing::info!("Приложение запущено");
}