#web-request #actix-web #actix-web-middleware #middleware #request-id #actix-middleware #observer

actix-request-hook

Actix 网页中间件请求钩子。允许订阅请求的开始和结束、请求 ID、请求之间的耗时等。

2 个版本

1.0.0-beta.42022年7月6日

#1646 in 网页编程

Download history 693/week @ 2024-03-13 245/week @ 2024-03-20 329/week @ 2024-03-27 276/week @ 2024-04-03 420/week @ 2024-04-10 266/week @ 2024-04-17 177/week @ 2024-04-24 363/week @ 2024-05-01 88/week @ 2024-05-08 219/week @ 2024-05-15 291/week @ 2024-05-22 340/week @ 2024-05-29 563/week @ 2024-06-05 373/week @ 2024-06-12 361/week @ 2024-06-19 310/week @ 2024-06-26

1,686 每月下载量

MIT/Apache

22KB
340

Actix Request Hook 持续集成 cargo-badge license-badge

Actix 网页中间件请求钩子。允许订阅请求的开始和结束、请求 ID、请求之间的耗时等。

示例

代码

struct RequestLogger;

impl Observer for RequestLogger {
    fn on_request_started(&self, data: RequestStartData) {
        println!("started {}", data.uri)
    }
    fn on_request_ended(&self, data: RequestEndData) {
        println!("ended {} after {}ms", data.uri, data.elapsed.as_millis())
    }
}

struct UselessObserver {
    started: RefCell<bool>,
    ended: RefCell<bool>,
}

impl Default for UselessObserver {
    fn default() -> Self {
        Self {
            started: RefCell::new(false),
            ended: RefCell::new(false),
        }
    }
}

impl Observer for UselessObserver {
    fn on_request_started(&self, _data: RequestStartData) {
        *self.started.borrow_mut() = true;
    }

    // testing if request ended receives mutated property
    fn on_request_ended(&self, _data: RequestEndData) {
        let is_started = self.started.borrow();
        if *is_started {
            *self.ended.borrow_mut() = true;
        }
    }
}

async fn index() -> Result<String, Error> {
    Ok("Hi there!".to_string())
}

#[actix_web::main]
async fn main() -> std::io::Result<()> {
    HttpServer::new(|| {
        // You can register many different observers.
        // One could be for logging, other for notifying other parts of the system etc.
        let request_hook = RequestHook::new()
            .exclude("/bye") // bye route shouldn't be logged
            .exclude_regex("^/\\d$") // excludes any numbered route like "/123456"
            .register(Rc::new(RequestLogger {}))
            .register(Rc::new(UselessObserver::default()));
        
        App::new()
            .wrap(request_hook)
            .route("/bye", web::get().to(index))
            .route("/hey", web::get().to(index))
    }).bind("127.0.0.1:0").expect("Can not bind to 127.0.0.1:0")
        .run().await
}

可能的用例

  • 记录请求的开始和结束
  • 使用所有请求数据通知 sentry...

你可以使用什么

在请求开始时,有以下内容

  • request_id - 请求的唯一 ID,在请求开始和结束时相同。
  • req - 借用的 ServiceRequest
  • uri - 请求的 URI。
  • method - 请求体。
  • body - 请求体。在调试客户端请求时很有用,例如可能可以在 Sentry 中使用。

在请求结束时,有以下内容

  • request_id - 请求的唯一 ID,在请求开始和结束时相同。
  • elapsed - 请求开始和结束钩子之间的耗时。
  • uri - 请求的 URI。
  • method - 请求体。
  • status - 响应状态。

注意事项

包含 RequestHook 中间件可能会影响你的 Actix 网页应用程序的性能。观察者在阻塞模式下执行,并且每个请求都会重新打包请求体。

贡献

本项目欢迎各种形式的贡献。任何贡献都不算太小!

如果你想为这个项目做出贡献,但不知道如何开始,或者需要与本项目相关的帮助,请随时发送电子邮件至 https://www.eisberg-labs.com/(底部有联系表单)。

有关贡献的一些提示可以在 Contributing.md 中找到

行为准则

本项目遵循Rust行为准则

许可证

MIT许可证Apache许可证下分发。

依赖项

~17-28MB
~508K SLoC