Skip to main content

systemprompt_logging/services/
format.rs

1//! Console formatter that filters system fields and renders structured values.
2//!
3//! Copyright (c) systemprompt.io — Business Source License 1.1.
4//! See <https://systemprompt.io> for licensing details.
5
6use std::fmt::{self, Write};
7use tracing::field::{Field, Visit};
8use tracing_subscriber::field::{MakeVisitor, VisitFmt, VisitOutput};
9use tracing_subscriber::fmt::format::Writer;
10
11use crate::sanitize::{REDACTION_PLACEHOLDER, escape_control, is_redacted, is_system_sentinel};
12
13#[derive(Debug, Clone, Copy, Default)]
14pub struct FilterSystemFields;
15
16impl FilterSystemFields {
17    pub const fn new() -> Self {
18        Self
19    }
20}
21
22#[derive(Debug)]
23pub struct FilteringVisitor<'a> {
24    writer: Writer<'a>,
25    is_first: bool,
26    result: fmt::Result,
27}
28
29impl<'a> FilteringVisitor<'a> {
30    const fn new(writer: Writer<'a>) -> Self {
31        Self {
32            writer,
33            is_first: true,
34            result: Ok(()),
35        }
36    }
37
38    fn record_filtered(&mut self, field: &Field, value: &dyn fmt::Debug) {
39        if self.result.is_err() {
40            return;
41        }
42
43        let debug_str = format!("{:?}", value);
44        if is_system_sentinel(&debug_str) {
45            return;
46        }
47
48        self.write_value(field.name(), &debug_str);
49    }
50
51    fn write_scalar(&mut self, field: &Field, value: impl fmt::Display) {
52        if self.result.is_err() {
53            return;
54        }
55        self.result = self.write_field(field.name(), &value.to_string());
56    }
57
58    fn write_value(&mut self, name: &str, rendered: &str) {
59        let safe = if is_redacted(name) {
60            REDACTION_PLACEHOLDER.to_owned()
61        } else {
62            escape_control(rendered)
63        };
64        self.result = self.write_field(name, &safe);
65    }
66
67    fn write_field(&mut self, name: &str, value: &str) -> fmt::Result {
68        if self.is_first {
69            self.is_first = false;
70        } else {
71            self.writer.write_char(' ')?;
72        }
73        write!(self.writer, "{}={}", name, value)
74    }
75}
76
77impl Visit for FilteringVisitor<'_> {
78    fn record_debug(&mut self, field: &Field, value: &dyn fmt::Debug) {
79        self.record_filtered(field, value);
80    }
81
82    fn record_str(&mut self, field: &Field, value: &str) {
83        if self.result.is_err() {
84            return;
85        }
86        if is_system_sentinel(value) {
87            return;
88        }
89        self.write_value(field.name(), &format!("{:?}", value));
90    }
91
92    fn record_i64(&mut self, field: &Field, value: i64) {
93        self.write_scalar(field, value);
94    }
95
96    fn record_u64(&mut self, field: &Field, value: u64) {
97        self.write_scalar(field, value);
98    }
99
100    fn record_i128(&mut self, field: &Field, value: i128) {
101        self.write_scalar(field, value);
102    }
103
104    fn record_u128(&mut self, field: &Field, value: u128) {
105        self.write_scalar(field, value);
106    }
107
108    fn record_f64(&mut self, field: &Field, value: f64) {
109        self.write_scalar(field, value);
110    }
111
112    fn record_bool(&mut self, field: &Field, value: bool) {
113        self.write_scalar(field, value);
114    }
115}
116
117impl VisitOutput<fmt::Result> for FilteringVisitor<'_> {
118    fn finish(self) -> fmt::Result {
119        self.result
120    }
121}
122
123impl VisitFmt for FilteringVisitor<'_> {
124    fn writer(&mut self) -> &mut dyn Write {
125        &mut self.writer
126    }
127}
128
129impl<'a> MakeVisitor<Writer<'a>> for FilterSystemFields {
130    type Visitor = FilteringVisitor<'a>;
131
132    fn make_visitor(&self, target: Writer<'a>) -> Self::Visitor {
133        FilteringVisitor::new(target)
134    }
135}