Skip to content

Commit

Permalink
Cleanup
Browse files Browse the repository at this point in the history
  • Loading branch information
j-chmielewski committed Mar 27, 2024
1 parent a3f8cfc commit 2063e2b
Show file tree
Hide file tree
Showing 3 changed files with 102 additions and 90 deletions.
86 changes: 0 additions & 86 deletions src/http_tracing_formatter.rs

This file was deleted.

1 change: 0 additions & 1 deletion src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ mod error;
mod grpc;
mod handlers;
pub mod http;
mod http_tracing_formatter;
pub mod tracing;

pub(crate) mod proto {
Expand Down
105 changes: 102 additions & 3 deletions src/tracing.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,20 @@
use rust_tracing::{Event, Subscriber};
use tracing_subscriber::{
fmt::{
format::{self, FormatEvent, FormatFields, Writer},
time::{FormatTime, SystemTime},
FmtContext, FormattedFields,
},
registry::LookupSpan,
};

use tracing::log::LevelFilter;
use tracing_subscriber::{fmt, layer::SubscriberExt, util::SubscriberInitExt, EnvFilter};

use crate::http_tracing_formatter::HttpFormatter;

// Initializes tracing with the specified log level.
// Allows fine-grained filtering with `EnvFilter` directives.
// The directives are read from `DEFGUARD_PROXY_LOG_FILTER` env variable.
// For more info check: <https://docs.rs/tracing-subscriber/latest/tracing_subscriber/filter/struct.EnvFilter.html>
// For more info read: <https://docs.rs/tracing-subscriber/latest/tracing_subscriber/filter/struct.EnvFilter.html>
pub fn init_tracing(level: &LevelFilter) {
tracing_subscriber::registry()
.with(
Expand All @@ -17,3 +25,94 @@ pub fn init_tracing(level: &LevelFilter) {
.init();
info!("Tracing initialized");
}

/// Implements fail2ban-friendly log format using `tracing_subscriber::fmt::format::FormatEvent` trait.
/// HTTP info (if available) is extracted from the specified tracing span. The format is as follows:
/// TIMESTAMP LEVEL CLIENT_ADDR METHOD URI LOG_MESSAGE || TRACING_DATA
pub(crate) struct HttpFormatter<'a> {
span: &'a str,
timer: SystemTime,
}

impl<'a> Default for HttpFormatter<'a> {
fn default() -> Self {
Self {
span: "http_request",
timer: SystemTime,
}
}
}

impl HttpFormatter<'_> {
fn format_timestamp(&self, writer: &mut Writer<'_>) -> std::fmt::Result {
if self.timer.format_time(writer).is_err() {
writer.write_str("<unknown time>")?;
}
writer.write_char(' ')
}
}

impl<S, N> FormatEvent<S, N> for HttpFormatter<'_>
where
S: Subscriber + for<'a> LookupSpan<'a>,
N: for<'a> FormatFields<'a> + 'static,
{
fn format_event(
&self,
ctx: &FmtContext<'_, S, N>,
mut writer: format::Writer<'_>,
event: &Event<'_>,
) -> std::fmt::Result {
let meta = event.metadata();

// timestamp & level
self.format_timestamp(&mut writer)?;
write!(writer, "{} ", meta.level())?;

// iterate and accumulate spans storing our special span in separate variable if encountered
let mut context_logs: Vec<String> = Vec::new();
let mut http_log: Option<String> = None;
if let Some(scope) = ctx.event_scope() {
let mut seen = false;
for span in scope.from_root() {
let span_name = span.metadata().name();
context_logs.push(span_name.to_string());
seen = true;

if let Some(fields) = span.extensions().get::<FormattedFields<N>>() {
if !fields.is_empty() {
match span_name {
x if x == self.span => http_log = Some(format!("{fields}")),
_ => context_logs.push(format!("{{{fields}}}")),
}
}
}
context_logs.push(":".into());
}
if seen {
context_logs.push(' '.into());
}
};

// write http context log (ip, method, path)
if let Some(log) = http_log {
let split: Vec<&str> = log.split(['=', ' ']).collect();
let method = split.get(1).unwrap_or(&"unknown");
let path = split.get(3).unwrap_or(&"unknown");
let ip = split.get(5).unwrap_or(&"unknown").replace('"', "");
write!(writer, "{ip} {method} {path} ")?;
}

// write actual log message
ctx.format_fields(writer.by_ref(), event)?;

// write span context
if !context_logs.is_empty() {
write!(writer, " || Tracing data: ")?;
for log in context_logs {
write!(writer, "{log}")?
}
}
writeln!(writer)
}
}

0 comments on commit 2063e2b

Please sign in to comment.