Getting Started with Rocket Fairings: Implementing a Logger

NishantNishant
2 min read

I am learning Rust web development by building projects, and the current project I am working on is Serac, which is an RBAC system, but I haven’t decided what do add after authenctication in this project. Also, suggest this in comments if wanted to.

Previously, I have implemented a request guard for getting user details at /user/me route for authenticated users only. Now, I wanted to learn some about the Fairings and decided to implement Logger in my project and authentication system for login and register of users.

A Fairing is any type that implements the Fairing trait.

The Fairing trait provides lifecycle hooks such as

  1. Ignite (on_ignite)

  2. Liftoff (on_liftoff)

  3. Request (on_request)

  4. Response(on_response)

  5. Shutdown (on_shutdown)

For more details about them, I have provided references in the end of this blog, and I have implemented both on_request and on_response In this problem, to minimize the use of fairing.

For, fairings/logger.rs

use rocket::fairing::{
    Fairing,
    Info,
    Kind
};

use rocket::{
    Request, 
    Data
};
use rocket::async_trait;


pub struct Logger;

#[async_trait]
impl Fairing for Logger {
    fn info(&self) -> Info {
        Info {
            name: "Request Logger",
            kind: Kind::Request | Kind::Response // Kind controls which hooks are active
        }
    }

    async fn on_request(&self, request: &mut Request<'_>, _: &mut Data<'_>) {
        println!("------> Incoming request: {} {}", request.method(), request.uri());
    }

    async fn on_response<'r>(&self, request: &'r Request<'_>, response: &mut rocket::Response<'r>) {
        println!("------> {} {} -> {}", request.method(), request.uri(), response.status());
    }
}

I have used println! just for demonstration, but real apps should use log or tracing.

For, fairings/mod.rs

pub mod logger;

For, main.rs

#[macro_use] extern crate rocket;

pub mod fairings;

#[get("/ping")]
fn ping() -> &'static str {
    "pong"
}

#[rocket::main]
async fn main() -> Result<(), rocket::Error> {
    rocket::build()
        .attach(fairings::logger::Logger)
        .mount("/", routes![ping])
        .launch()
        .await?;

    Ok(())
}

You can test by checking the logs after hitting on /ping route

curl -X GET http://127.0.0.1:8000/ping

Uses of Logger in a Real World project

  1. Track Login attempts on the server

  2. Debugging and Troubleshooting

  3. Monitoring performance

References

  1. Fairings in Rocket v0.5

  2. Fairing traits

  3. Tracing

0
Subscribe to my newsletter

Read articles from Nishant directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

Nishant
Nishant