Skip to content
1 change: 1 addition & 0 deletions docs/platforms/rust/guides/axum/config.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
title: axum
99 changes: 99 additions & 0 deletions docs/platforms/rust/guides/axum/index.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
---
title: axum
description: "Learn about monitoring your axum application with Sentry."
---

The Sentry SDK offers a middleware for the [`axum`](https://github.com/tokio-rs/axum) framework that supports:

- Reporting errors and panics with the correct request correlation.
- Starting a [transaction](https://docs.sentry.io/concepts/key-terms/tracing/) for each request-response cycle.

The integration actually supports any crate based on [`tower`](https://github.com/tower-rs/tower), not just `axum`.

## Install

To add Sentry with the `axum` integration to your Rust project, add a new dependency to your `Cargo.toml`:

```toml {filename:Cargo.toml}
[dependencies]
axum = "0.8.4"
tower = "0.5.2"
tokio = { version = "1.45.0", features = ["full"] }
sentry = { version = "{{@inject packages.version('sentry.rust') }}", features = ["tower-axum-matched-path"] }
```

## Configure

Initialize and configure the Sentry client. This will enable a set of default integrations, such as panic reporting.
Then, initialize `axum` with the Sentry middleware.

<Alert level="warning">

Macros like `#[tokio::main]` are not supported. The Sentry client must be initialized before the async runtime is started, as shown below.

</Alert>

```rust {filename:main.rs}
use axum::{body::Body, http::Request, routing::get, Router};
use sentry::integrations::tower::{NewSentryLayer, SentryHttpLayer};
use std::io;
use tower::ServiceBuilder;

async fn failing() -> () {
panic!("Everything is on fire!")
}

fn main() -> io::Result<()> {
let _guard = sentry::init((
"___PUBLIC_DSN___",
sentry::ClientOptions {
release: sentry::release_name!(),
// Capture all traces and spans. Set to a lower value in production
traces_sample_rate: 1.0,
// Capture user IPs and potentially sensitive headers when using HTTP server integrations
// see https://docs.sentry.io/platforms/rust/data-management/data-collected for more info
send_default_pii: true,
..Default::default()
},
));

let app = Router::new().route("/", get(failing)).layer(
ServiceBuilder::new()
// If you're binding the layers directly on the `Router`, bind them in the opposite order, otherwise you might run into a memory leak
.layer(NewSentryLayer::<Request<Body>>::new_from_top()) // Bind a new Hub per request, to ensure correct error <> request correlation
.layer(SentryHttpLayer::new().enable_transaction()), // Start a transaction (Sentry root span) for each request
);

tokio::runtime::Builder::new_multi_thread()
.enable_all()
.build()?
.block_on(async {
let listener = tokio::net::TcpListener::bind("127.0.0.1:3001")
.await
.unwrap();
axum::serve(listener, app.into_make_service())
.await
.unwrap();
});

Ok(())
}
```

## Verify

The snippet above sets up a service that always panics, so you can test that everything is working as soon as you set it up.

Send a request to the application. The panic will be captured by Sentry.

```bash
curl http://localhost:3001/
```

<Alert>

Learn more about manually capturing an error or message in our <PlatformLink to="/usage/">Usage documentation</PlatformLink>.

</Alert>

To view and resolve the recorded error, log into [sentry.io](https://sentry.io) and select your project. Clicking on the error's title will open a page where you can see detailed information and mark it as resolved.
7 changes: 7 additions & 0 deletions src/components/platformIcon.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,7 @@ import SvelteSVG from 'platformicons/svg/svelte.svg';
import SwiftSVG from 'platformicons/svg/swift.svg';
import SymfonySVG from 'platformicons/svg/symfony.svg';
import TanstackSVG from 'platformicons/svg/tanstack.svg';
import TokioSVG from 'platformicons/svg/tokio.svg';
import TornadoSVG from 'platformicons/svg/tornado.svg';
import TrytonSVG from 'platformicons/svg/tryton.svg';
import UnitySVG from 'platformicons/svg/unity.svg';
Expand Down Expand Up @@ -272,6 +273,7 @@ import SvelteSVGLarge from 'platformicons/svg_80x80/svelte.svg';
import SwiftSVGLarge from 'platformicons/svg_80x80/swift.svg';
import SymfonySVGLarge from 'platformicons/svg_80x80/symfony.svg';
import TanstackSVGLarge from 'platformicons/svg_80x80/tanstack.svg';
import TokioSVGLarge from 'platformicons/svg_80x80/tokio.svg';
import TornadoSVGLarge from 'platformicons/svg_80x80/tornado.svg';
import TrytonSVGLarge from 'platformicons/svg_80x80/tryton.svg';
import UnitySVGLarge from 'platformicons/svg_80x80/unity.svg';
Expand Down Expand Up @@ -346,6 +348,10 @@ const formatToSVG = {
sm: AwslambdaSVG,
lg: AwslambdaSVGLarge,
},
axum: {
sm: TokioSVG,
lg: TokioSVGLarge,
},
'azure-functions': {
sm: AzurefunctionsSVG,
lg: AzurefunctionsSVGLarge,
Expand Down Expand Up @@ -1033,6 +1039,7 @@ export const PLATFORM_TO_ICON = {
'ruby-sinatra': 'sinatra',
rust: 'rust',
'rust-actix-web': 'actix',
'rust-axum': 'axum',
scala: 'scala',
stride3d: 'stride3d',
sql: 'sql',
Expand Down
Loading