generated from Patagia/template-nix
parent
da210ffc16
commit
31c8921aca
13 changed files with 246 additions and 36 deletions
trace-request
18
trace-request/Cargo.toml
Normal file
18
trace-request/Cargo.toml
Normal file
|
@ -0,0 +1,18 @@
|
|||
[package]
|
||||
name = "trace-request"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
license = "MPL-2.0"
|
||||
|
||||
[lib]
|
||||
proc-macro = true
|
||||
|
||||
[dependencies]
|
||||
proc-macro2 = "1"
|
||||
quote = "1"
|
||||
syn = { version = "2.0", features = ["full"] }
|
||||
|
||||
[dev-dependencies]
|
||||
dropshot = { workspace = true }
|
||||
http = { workspace = true }
|
||||
tracing = { workspace = true }
|
79
trace-request/src/lib.rs
Normal file
79
trace-request/src/lib.rs
Normal file
|
@ -0,0 +1,79 @@
|
|||
// Original source: https://github.com/oxidecomputer/rfd-api/blob/main/trace-request/src/lib.rs
|
||||
//
|
||||
// This Source Code Form is subject to the terms of the Mozilla Public
|
||||
// License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
// file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
|
||||
#![allow(dead_code, unused_imports)]
|
||||
|
||||
extern crate proc_macro;
|
||||
#[macro_use]
|
||||
extern crate quote;
|
||||
|
||||
use std::result::Iter;
|
||||
|
||||
use proc_macro::TokenStream;
|
||||
use proc_macro2::{Delimiter, Group, Span, TokenTree};
|
||||
use quote::ToTokens;
|
||||
use syn::{
|
||||
bracketed,
|
||||
parse::{Parse, ParseStream, Parser},
|
||||
parse_macro_input,
|
||||
punctuated::Punctuated,
|
||||
Block, DeriveInput, Ident, ItemFn, LitStr, Result, Token, Type,
|
||||
};
|
||||
|
||||
#[proc_macro_attribute]
|
||||
pub fn trace_request(_attr: TokenStream, input: TokenStream) -> TokenStream {
|
||||
let mut input = parse_macro_input!(input as ItemFn);
|
||||
let body_block = input.block;
|
||||
let fn_name = &input.sig.ident;
|
||||
|
||||
let token_stream = quote! {
|
||||
{
|
||||
use tracing::Instrument;
|
||||
|
||||
fn get_status<T>(res: &Result<T, HttpError>) -> http::StatusCode where T: dropshot::HttpCodedResponse {
|
||||
match res {
|
||||
Ok(_) => T::STATUS_CODE,
|
||||
Err(err) => err.status_code.as_status(),
|
||||
}
|
||||
}
|
||||
|
||||
let request_id = &rqctx.request_id;
|
||||
let req = &rqctx.request;
|
||||
|
||||
async {
|
||||
let result = async #body_block.await;
|
||||
let status = get_status(&result);
|
||||
|
||||
let span = tracing::Span::current();
|
||||
span.record("http.status", &status.as_str());
|
||||
if let Err(err) = &result {
|
||||
span.record("error.external", &err.external_message);
|
||||
span.record("error.internal", &err.internal_message);
|
||||
}
|
||||
|
||||
result
|
||||
}.instrument(
|
||||
tracing::info_span!(
|
||||
stringify!(handler.#fn_name),
|
||||
"request.id" = request_id,
|
||||
"http.method" = req.method().as_str(),
|
||||
"http.uri" = req.uri().to_string(),
|
||||
"http.status" = tracing::field::Empty,
|
||||
"error.external" = tracing::field::Empty,
|
||||
"error.internal" = tracing::field::Empty
|
||||
)
|
||||
).await
|
||||
}
|
||||
};
|
||||
let wrapped_body_block: TokenStream = token_stream.into();
|
||||
|
||||
input.block = Box::new(parse_macro_input!(wrapped_body_block as Block));
|
||||
|
||||
quote! {
|
||||
#input
|
||||
}
|
||||
.into()
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue