Мониторинг приложений на Rust: библиотеки и инструменты для отслеживания производительности

Онлайн-тренажер Python для начинающих

Изучайте Python легко и без перегрузки теорией. Решайте практические задачи с автоматической проверкой, получайте подсказки на русском языке и пишите код прямо в браузере — без необходимости что-либо устанавливать.

Начать курс

Мониторинг приложений на 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!("Приложение запущено");
}

Рекомендаций