确保 actix 按时间顺序记录 // 预处理
ensure actix logging in chronological order // pre-process
我有 actix-web 并且很难调试,因为记录器只在最后写入,如果出现故障,它根本不会写入。
RUST_LOG=actix_web=debug,actix_server=debug
let server = HttpServer::new(move || {
App::new()
.wrap(Logger::default())
.wrap(Logger::new(
"Request Pre",
)
)
.wrap(add_service())
.configure(add_routes)
[2021-02-05T14:29:02Z INFO my_lib::middleware::foo] Foo Middleware Finished
[2021-02-05T14:29:02Z INFO my_lib::middleware::bar] Bar Middleware Finished
[2021-02-05T14:29:01Z INFO actix_web::middleware::logger] Request Pre
[2021-02-05T14:29:01Z INFO actix_web::middleware::logger] 127.0.0.1:54321 "POST /call/me HTTP/1.1"
我如何控制预处理(并在其中添加日志),以确保在请求到达时首先写入日志?
您可以使用跟踪记录器,它会为请求记录两次:到达时和发出响应时。通常在发送响应时记录请求,这样我们就可以将响应的状态代码等上下文添加到日志事件中。但是,如果我们收到有问题的传入请求,我们的服务可能会在记录发生之前崩溃。
在这些情况下,每个请求的 2 个日志事件可用于识别有害的传入工作负载:
use actix_service::Service;
use actix_web::{web, App, HttpServer};
use actix_web_opentelemetry::RequestTracing;
use log;
use tracing::subscriber::set_global_default;
use tracing_actix_web::TracingLogger;
use tracing_bunyan_formatter::{BunyanFormattingLayer, JsonStorageLayer};
use tracing_log::LogTracer;
use tracing_subscriber::{layer::SubscriberExt, EnvFilter, Registry};
const PKG_NAME: &str = env!("CARGO_PKG_NAME");
async fn index() -> &'static str {
"Hello!"
}
#[actix_web::main]
async fn main() -> std::io::Result<()> {
std::env::set_var("RUST_LOG", "info,actix_web=error");
let env_filter = EnvFilter::try_from_default_env().unwrap_or_else(|_| EnvFilter::new("info"));
let formatting_layer = BunyanFormattingLayer::new(PKG_NAME.into(), std::io::stdout);
let subscriber = Registry::default()
.with(env_filter)
.with(JsonStorageLayer)
.with(formatting_layer);
LogTracer::init().expect("Failed to set logger");
set_global_default(subscriber).expect("Failed to set subscriber");
HttpServer::new(|| {
App::new()
.wrap_fn(|req, srv| {
log::info!("hello from middleware!");
srv.call(req)
})
.wrap(RequestTracing::new())
.wrap(TracingLogger)
.service(web::resource("/").to(index))
})
.bind("127.0.0.1:8080")?
.run()
.await
}
在输出中我们看到中间件在 REQUEST - START
和 REQUEST - END
之间记录:
./target/debug/log-test | jq -cr '.msg'
Starting 4 workers
Starting "actix-web-service-127.0.0.1:8080" service on 127.0.0.1:8080
[REQUEST - START]
hello from middleware!
[REQUEST - END]
我有 actix-web 并且很难调试,因为记录器只在最后写入,如果出现故障,它根本不会写入。
RUST_LOG=actix_web=debug,actix_server=debug
let server = HttpServer::new(move || {
App::new()
.wrap(Logger::default())
.wrap(Logger::new(
"Request Pre",
)
)
.wrap(add_service())
.configure(add_routes)
[2021-02-05T14:29:02Z INFO my_lib::middleware::foo] Foo Middleware Finished
[2021-02-05T14:29:02Z INFO my_lib::middleware::bar] Bar Middleware Finished
[2021-02-05T14:29:01Z INFO actix_web::middleware::logger] Request Pre
[2021-02-05T14:29:01Z INFO actix_web::middleware::logger] 127.0.0.1:54321 "POST /call/me HTTP/1.1"
我如何控制预处理(并在其中添加日志),以确保在请求到达时首先写入日志?
您可以使用跟踪记录器,它会为请求记录两次:到达时和发出响应时。通常在发送响应时记录请求,这样我们就可以将响应的状态代码等上下文添加到日志事件中。但是,如果我们收到有问题的传入请求,我们的服务可能会在记录发生之前崩溃。
在这些情况下,每个请求的 2 个日志事件可用于识别有害的传入工作负载:
use actix_service::Service;
use actix_web::{web, App, HttpServer};
use actix_web_opentelemetry::RequestTracing;
use log;
use tracing::subscriber::set_global_default;
use tracing_actix_web::TracingLogger;
use tracing_bunyan_formatter::{BunyanFormattingLayer, JsonStorageLayer};
use tracing_log::LogTracer;
use tracing_subscriber::{layer::SubscriberExt, EnvFilter, Registry};
const PKG_NAME: &str = env!("CARGO_PKG_NAME");
async fn index() -> &'static str {
"Hello!"
}
#[actix_web::main]
async fn main() -> std::io::Result<()> {
std::env::set_var("RUST_LOG", "info,actix_web=error");
let env_filter = EnvFilter::try_from_default_env().unwrap_or_else(|_| EnvFilter::new("info"));
let formatting_layer = BunyanFormattingLayer::new(PKG_NAME.into(), std::io::stdout);
let subscriber = Registry::default()
.with(env_filter)
.with(JsonStorageLayer)
.with(formatting_layer);
LogTracer::init().expect("Failed to set logger");
set_global_default(subscriber).expect("Failed to set subscriber");
HttpServer::new(|| {
App::new()
.wrap_fn(|req, srv| {
log::info!("hello from middleware!");
srv.call(req)
})
.wrap(RequestTracing::new())
.wrap(TracingLogger)
.service(web::resource("/").to(index))
})
.bind("127.0.0.1:8080")?
.run()
.await
}
在输出中我们看到中间件在 REQUEST - START
和 REQUEST - END
之间记录:
./target/debug/log-test | jq -cr '.msg'
Starting 4 workers
Starting "actix-web-service-127.0.0.1:8080" service on 127.0.0.1:8080
[REQUEST - START]
hello from middleware!
[REQUEST - END]