Недавно я начал работать над проектом, который использует Actix, я впервые касаюсь этого веб-фреймворка. И у меня есть проблема, что каждый раз, когда я запускаю сервер, мне не показывалось сообщение о том, что сервер работает или когда вызывается конечная точка.

Вероятно, у меня есть эта проблема, потому что я привык использовать другие веб-фреймворки на других языках, которые имеют функцию ведения журнала по умолчанию.

Поэтому я начал писать эту статью только для того, чтобы узнать, как добавить ведение журнала в приложение Actix, и получить ресурс, который можно использовать на случай, если я снова столкнусь с той же проблемой.

Требования

  • Ржавчина установлена

Груз.томл

[dependencies]
actix-web = "4"
tracing-actix-web = "0.7"
tracing = "0.1"
log = "0.4"
env_logger = "0.9"

main.rs

Во-первых, мы начинаем писать минимальный пример веб-сервера, который просто показывает «Hello World!» сообщение. А затем добавьте ведение журнала, чтобы увидеть, когда сервер вызывается.

use actix_web::{get, App, HttpResponse, HttpServer, Responder};

#[get("/")]
async fn hello() -> impl Responder {
    HttpResponse::Ok().body("Hello world!")
}

#[actix_web::main]
async fn main() -> std::io::Result<()> {

    HttpServer::new(|| {
        App::new()
            .service(hello)   
    })
    .bind(("127.0.0.1", 8080))?
    .run()
    .await
}

Теперь мы запускаем команду cargo run для запуска сервера.

use actix_web::{get, App, HttpResponse, HttpServer, Responder};
use actix_web::middleware::Logger;
use env_logger::Env;

#[get("/")]
async fn hello() -> impl Responder {
    HttpResponse::Ok().body("Hello world!")
}

#[get("/hi")]
async fn hi() -> impl Responder {
    HttpResponse::Ok().body("Greetings")
}

#[actix_web::main]
async fn main() -> std::io::Result<()> {

   env_logger::init_from_env(Env::default().default_filter_or("info"));
    HttpServer::new(|| {
        App::new()
            .service(hello)
            .service(hi)
            .wrap(Logger::default())


    })
    .bind(("127.0.0.1", 8080))?
    .run()
    .await
}

Здесь ведение журнала реализовано как промежуточное программное обеспечение. Промежуточное ПО ведения журналов обычно регистрируется как первое промежуточное ПО для приложения. Программное обеспечение промежуточного слоя ведения журналов должно быть зарегистрировано для каждого приложения.

Строка env_logger::init_from_env(Env::default().default_filter_or("info") инициализирует регистратор с уровнем журнала по умолчанию «info», который будет выводить журналы на консоль в стандартном формате.

.wrap(Logger::default()) прикрепляет промежуточное ПО Logger к приложению, которое автоматически регистрирует запросы и ответы.

ПО промежуточного слоя Logger использует стандартный ящик журнала для регистрации информации. Вы должны включить регистратор для пакета actix_web, чтобы видеть журнал доступа (env_logger или аналогичный).

Создайте промежуточное ПО Logger в указанном формате. Регистратор по умолчанию может быть создан методом по умолчанию, он использует формат по умолчанию:

  %a %t "%r" %s %b "%{Referer}i" "%{User-Agent}i" %T

Формат

  • %a Удаленный IP-адрес (IP-адрес прокси при использовании обратного прокси)
  • %t Время начала обработки запроса
  • %P Идентификатор дочернего процесса, обслужившего запрос
  • %b Размер ответа в байтах, включая заголовки HTTP
  • %T Время, затраченное на обслуживание запроса, в секундах с плавающей дробью в формате .06f
  • %D Время, затраченное на обслуживание запроса, в миллисекундах
  • %{FOO}i request.headers['FOO']
  • %{FOO}o response.headers['FOO']

Добавление файлов журналов

Кроме того, просто из любопытства я искал способ генерировать файлы журналов. Но решение немного другое, без промежуточного программного обеспечения Actix.

Мы должны добавить simplelog в файл Cargo.toml

Груз.томл

...
simplelog = "0.6"

main.rs

use log::{info, error};
use simplelog::{CombinedLogger, Config, LevelFilter, WriteLogger};
use std::fs::File;

...

#[actix_web::main]
async fn main() -> std::io::Result<()> {
    let log_file = File::create("./app.log").unwrap();
    CombinedLogger::init(
        vec![
            WriteLogger::new(
                LevelFilter::Debug,
                Config::default(),
                log_file,
            ),

            WriteLogger::new(
                LevelFilter::Debug, 
                Config::default(), 
                std::io::stdout()
           ),
        ]
    ).unwrap();


    HttpServer::new(|| {
        App::new()
            .service(hello)
            .service(hi)

    })
    .bind(("127.0.0.1", 8080))?
    .run()
    .await
}

В этом решении используется крейт simplelog, который представляет собой крейт, не предназначенный ни для предоставления богатого набора функций, ни для обеспечения наилучшего решения для ведения журналов. Он призван быть удобным в обслуживании, простым в интеграции средством для проектов малого и среднего размера, которым env_logger не хватает функций. В этих случаях simplelog должен предоставить легкую альтернативу, согласно его документации.

Мне нужно удалить код, который использует промежуточное ПО Actix для отображения журналов в командной строке. Поскольку он использует env_logger, а основной поток запаниковал, я получил следующее сообщение:

поток 'main', запаниковавший в 'env_logger::init_from_env, не должен вызываться после инициализации регистратора: SetLoggerError()', C:\Users\gate1.cargo\registry\src\ «github.com-1ecc6299db9ec823 \env_logger-0.9.3\src\ lib.rs:1222:10».

Итак, я решил использовать только simplelog для этого примера для создания файлов журналов и отображения журналов в командной строке.

Отслеживание

Чтобы добавить трассировку на веб-сервер Actix, мы будем использовать tracing-actix-web crate.

Tracing-actix-web

Согласно его документации, tracing-actix-web предоставляет TracingLogger промежуточное ПО для сбора данных телеметрии из приложений, построенных поверх фреймворка Actix-web.

main.rs

use actix_web::{get, App, HttpResponse, HttpServer, Responder};
use actix_web::middleware::Logger;
use env_logger::Env;
use tracing_actix_web::TracingLogger;

#[get("/")]
async fn hello() -> impl Responder {
    HttpResponse::Ok().body("Hello world!")
}

#[get("/hi")]
async fn hi() -> impl Responder {
    HttpResponse::Ok().body("Greetings")
}

#[actix_web::main]
async fn main() -> std::io::Result<()> {

   env_logger::init_from_env(Env::default().default_filter_or("trace")); 

    HttpServer::new(|| {
        App::new()
            .wrap(TracingLogger::default())
            .service(hello)
            .service(hi)


    })
    .bind(("127.0.0.1", 8080))?
    .run()
    .await
}

Для трассировки мы просто добавляем TracingLogger::default() и обертываем его с помощью функции wrap(), чтобы использовать его в качестве промежуточного программного обеспечения.

TracingLogger — это промежуточное ПО для получения структурированной диагностики при обработке HTTP-запроса.

TracingLogger разработан как замена 's .

Как видите, я удаляю промежуточное ПО Actix Logger.

Мы можем использовать этот крейт, чтобы добавить инструментарий в наше приложение и получить его с помощью OpenTelemetry для дальнейшего анализа.

Чтобы узнать больше об этом ящике, вы можете прочитать статью «Мы уже наблюдаем?», в которой содержится подробное введение в ящик и проблемы, которые он решает в рамках более широкой картины наблюдаемости.

Заключение

Прежде чем писать эту статью, я просто хочу добавить простые журналы в свое приложение Actix. Но в путешествии мне было больше любопытно, что еще я могу добавить. Я надеялся найти крейт или комплексное решение, но не нашел, это не значит, что этого не существует. Возможно, я найду его, если проведу глубокие исследования или буду лучше разбираться в Rust.

Однако я думаю, что это обеспечивает большую гибкость и настройку. Если мы хотим просто отображать журналы в командной строке, использование промежуточного программного обеспечения Logger прекрасно. Если мы хотим собрать телеметрию для дальнейшего анализа, TracingLogger. Запишите журналы в файл simplelog.

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

Спасибо, что нашли время прочитать эту статью.

Если у вас есть рекомендации по другим пакетам, архитектурам, как улучшить мой код, мой английский или что-то в этом роде; оставьте комментарий или свяжитесь со мной через Twitter или LinkedIn.

Исходный код здесь.

Ресурсы

Документация Actix.

Документация промежуточного программного обеспечения Actix.

tracing-actix-web документация.

документация по крейту simplelog.

Нас уже можно наблюдать? Введение в Rust Telemetry.

Первоначально опубликовано на https://carlosmv.hashnode.dev.