标签: rust-axum

如何使用 Axum 启用日志记录/跟踪?

我正在学习 Axum,我想将日志记录添加到我组装的服务中,但不幸的是我无法让它工作。

我已添加 tower-http 来使用TraceLayer并将其添加到我的应用程序中:

# Cargo.toml
[dependencies]
axum = "0.6.1"
tower-http = { version = "0.3.5", features = ["trace"] }
Run Code Online (Sandbox Code Playgroud)
use tower_http::trace::TraceLayer;

let app = Router::new()
    .route("/:name/path", axum::routing::get(handler))
    .layer(TraceLayer::new_for_http())
Run Code Online (Sandbox Code Playgroud)

但是当我启动应用程序并向端点发出请求时,没有记录任何内容。是否有我可能错过的配置步骤?

rust rust-tracing rust-axum

15
推荐指数
1
解决办法
1万
查看次数

如何使用 Axum 正确过滤请求日志?

我将 Axum 用于相对简单的 Web API,并希望获得类似于 Go Gin、IIS 日志、Python FastAPI 等的传入请求的日志记录/跟踪输出 - 简单的路径和参数输出。

HTTP 层已添加到路由器:

let app = Router::new()
    .route("/hello", get(hello_img))
    .layer(TraceLayer::new_for_http());
Run Code Online (Sandbox Code Playgroud)

这大约导致我正在寻找的内容: 良好的输出

然而,还有很多额外的不需要的日志记录正在发生,所以我添加了一个过滤器来排除这些日志记录。添加过滤器后:

let filter = filter::Targets::new()
    .with_target("tower_http::trace::on_response", Level::TRACE)
    .with_target("tower_http::trace::on_request", Level::TRACE)
    .with_default(Level::INFO);
Run Code Online (Sandbox Code Playgroud)

并将其添加到订阅者:

let tracing_layer = tracing_subscriber::fmt::layer();

tracing_subscriber::registry()
    .with(tracing_layer)
    .with(filter)
    .init();
Run Code Online (Sandbox Code Playgroud)

输出更改为 坏输出

详细信息(方法、URI、参数)都消失了。

即使没有指定格式更改,为什么会发生这种情况?如何在控制台中保留请求/响应跟踪,但过滤掉其他不需要的跟踪?

rust rust-tracing rust-axum

11
推荐指数
1
解决办法
5828
查看次数

如何设计具有测试友好性的 Axum 服务器?

当我尝试使用axum构建应用程序时,我未能将框架与处理程序分开。对于Go,经典的方法是定义一个Interface,实现它并将处理程序注册到框架。通过这种方式,可以很容易地提供一个模拟处理程序来进行测试。然而,我无法让它与 Axum 一起工作。我trait像上面一样定义了 a ,但它不会编译:

use std::net::ToSocketAddrs;
use std::sync::{Arc, Mutex};
use serde_derive::{Serialize, Deserialize};
use serde_json::json;
use axum::{Server, Router, Json};

use axum::extract::Extension;
use axum::routing::BoxRoute;
use axum::handler::get;

#[tokio::main]
async fn main() {
    let app = new_router(
        Foo{}
    );
    axum::Server::bind(&"0.0.0.0:3000".parse().unwrap())
        .serve(app.into_make_service())
        .await
        .unwrap();
}

trait Handler {
    fn get(&self, get: GetRequest) -> Result<GetResponse, String>;
}

struct Foo {}

impl Handler for Foo {
    fn get(&self, req: GetRequest) -> Result<GetResponse, String> {
        Ok(GetResponse{ message: "It works.".to_owned()})
    }
} …
Run Code Online (Sandbox Code Playgroud)

rust rust-axum

9
推荐指数
1
解决办法
4871
查看次数

如何从 axum 服务器路由调用结构方法?

我想实例化一个 struct 实例,然后在 api 路由中调用该实例的方法。这是我想要的示例,但它会导致错误:

use axum::{http::StatusCode, routing::get, Router, Server};

#[derive(Clone)]
struct Api {
    name: String
}

impl Api {
    async fn hello(&self) -> Result<String, StatusCode> {
        Ok(format!("Hello {}!", self.name))
    }
}

#[tokio::main]
async fn main() {
    let api = Api { name: "Alice".to_owned() };

    let app = Router::new()
        .route("/hello-user", get(api.hello));

    Server::bind(&([127, 0, 0, 1], 3000).into())
        .serve(app.into_make_service())
        .await
        .unwrap();
}
Run Code Online (Sandbox Code Playgroud)
use axum::{http::StatusCode, routing::get, Router, Server};

#[derive(Clone)]
struct Api {
    name: String
}

impl Api {
    async fn hello(&self) -> Result<String, …
Run Code Online (Sandbox Code Playgroud)

rust rust-axum

7
推荐指数
1
解决办法
1475
查看次数

如何使 axum 路由器句柄返回不同的内容类型响应?

例如,当用户访问时http://127.0.0.1:8080/hello,如果查询参数id为1,则返回纯文本响应。如果id是2,给出一个json结构。

概括:

id(输入) 状态码 内容类型 身体
1 200 应用程序/json {“名称”:“世界”}
2 400 文本/纯文本 没有这样的人
struct HelloParam {
    id: u16,
}

struct HelloResponse {
    name: String,
}

async fn hello_get(Query(params): Query<HelloParam>) -> Response {
    // how to implement it? 
}

let router= Router::new().route("/hello", get(hello_get));

Run Code Online (Sandbox Code Playgroud)

hyper rust-axum

7
推荐指数
1
解决办法
1万
查看次数

在 rust/axum 中带或不带尾部斜线的路由路径

我想将http://0.0.0.0/foo和路由http://0.0.0.0/foo/到同一个get_foo处理程序。然而,实际上,只有/foo路由和/foo/404。我怀疑我设置/附加的中间件错误:

use axum::http::StatusCode;
use axum::{routing::{get}, Router};
use std::{net::SocketAddr};
use tower_http::normalize_path::NormalizePathLayer;

#[tokio::main]
async fn main() {
    let app = Router::new()
        .route("/foo", get(get_foo))
        .layer(NormalizePathLayer::trim_trailing_slash());

    let port_str = std::env::var("PORT").unwrap_or("8000".to_owned());
    let port = port_str.parse::<u16>().unwrap();
    let addr = SocketAddr::from(([0, 0, 0, 0], port));
    println!("listening on http://{}", addr);
    axum::Server::bind(&addr)
        .serve(app.into_make_service())
        .await
        .unwrap();
}

async fn get_foo() -> Result<String, StatusCode>  {
    Ok("Hello from foo.".to_owned())
}

Run Code Online (Sandbox Code Playgroud)

...以及随附的Cargo.toml

[package]
name = "axum_trailing_slash"
version = "0.1.0"
edition = …
Run Code Online (Sandbox Code Playgroud)

rust rust-axum

7
推荐指数
1
解决办法
2099
查看次数

如何将 axum::extract::Query 和 axum::extract::State 与 Axum 一起使用?

我正在构建一个需要注入状态并且还需要提取查询参数的处理程序。

我一开始只提取状态并且有效。其代码如下所示:

    #[derive(ValueEnum, Clone, Debug, serde::Deserialze, serde::Serialize)]
    pub enum MyParams {
       Normal,
       Verbose,
    }

    #[derive(Debug)]
   pub struct MyState {
      port: u16,
   }
    
    pub async fn serve(self) {
        let port = self.port;
        let app = Router::new()
            .route("/path", axum::routing::get(path))
            .with_state(Arc::new(self));

        let addr = SocketAddr::from(([127, 0, 0, 1], port));
        axum::Server::bind(&addr)
            .serve(app.into_make_service())
            .await
            .unwrap();
    }

async fn path(State(middle_ware): State<Arc<MyState>>) -> impl IntoResponse {
    let result = middle_ware.process().await;
    (StatusCode::OK, Json(result))
}

Run Code Online (Sandbox Code Playgroud)

现在我想提取查询参数,所以我更新了代码如下:

async fn path(State(middle_ware): State<Arc<MyState>>, params: Query<MyParams>) -> impl IntoResponse {
    println!("{:?}", params);
    let …
Run Code Online (Sandbox Code Playgroud)

rust rust-axum

6
推荐指数
1
解决办法
4978
查看次数

reqwest 作为客户端和 axum 作为服务器的问题(axum 在 1k req/s 时爆炸,端口使用错误)

我有问题,为什么发送时出现此错误request

\n
Error: reqwest::Error {\n    kind: Request, \n    url: Url { \n        scheme: "http", \n        cannot_be_a_base: false, \n        username: "", \n        password: None, \n        host: Some(Ipv4(127.0.0.1)), \n        port: Some(3000), \n        path: "/message", \n        query: None, \n        fragment: None \n    }, \n    source: hyper::Error(\n        Connect, \n        ConnectError(\n            "tcp connect error", \n            Os { \n                code: 10048, \n                kind: AddrInUse, \n                message: "Only one usage of each socket address (protocol/network address/port) is normally permitted." \n            }\n        )\n    )\n}\n
Run Code Online (Sandbox Code Playgroud)\n

它以“随机”速率发生,例如 15-45 …

http rust rust-axum

6
推荐指数
0
解决办法
786
查看次数

为什么我收到“Deref 的实现不够通用”?

这是我的最小可重现示例:

use axum::{extract::State, Json, Router};
use diesel::pg::Pg;
use diesel_async::{
    pooled_connection::bb8::Pool,
    AsyncConnection, AsyncPgConnection, RunQueryDsl,
};

fn main() {
    // body omitted for brevity
}

pub type AsyncPool = Pool<AsyncPgConnection>;

fn router() -> Router<AsyncPool> {
    use axum::routing::*;
    Router::new().route("/create", post(create))
}

async fn create(State(db): State<AsyncPool>) -> Result<Json<()>, ()> {
    let mut conn = db.get().await.unwrap();
    let user = create_user(&mut conn).await?;

    Ok(Json(user))
}

// actual return types omitted for brevity
async fn create_user(conn: &mut impl AsyncConnection<Backend = Pg>) -> Result<(), ()> {
    // error doesn't …
Run Code Online (Sandbox Code Playgroud)

rust rust-diesel rust-axum

6
推荐指数
0
解决办法
145
查看次数

Rust Axum 获取完整 URI 请求

尝试获取完整的请求 URI(方案 + 权限 + 路径)

我找到了讨论:https://github.com/tokio-rs/axum/discussions/1149其中说 Request.uri() 应该有它。所以我尝试了以下方法:

use axum::body::Body;
use axum::http::Request;
use axum::routing::get;
use axum::Router;

async fn handler(req: Request<Body>) -> &'static str {
    println!("The request is: {}", req.uri());
    println!("The request is: {}", req.uri().scheme_str().unwrap());
    println!("The request is: {}", req.uri().authority().unwrap());

    "Hello world"
}

#[tokio::main]
async fn main() {
    let app = Router::new().route("/test", get(handler));

    axum::Server::bind(&"0.0.0.0:8080".parse().unwrap())
        .serve(app.into_make_service())
        .await
        .unwrap();
}
Run Code Online (Sandbox Code Playgroud)

运行curl -v "http://localhost:8080/test"但我得到:

The request is: /test
thread 'tokio-runtime-worker' panicked at 'called `Option::unwrap()` on a `None` value', src/main.rs:8:59 …
Run Code Online (Sandbox Code Playgroud)

rust rust-axum

5
推荐指数
1
解决办法
3213
查看次数

标签 统计

rust-axum ×10

rust ×9

rust-tracing ×2

http ×1

hyper ×1

rust-diesel ×1