systemprompt_logging/services/
format.rs1use 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_value(&mut self, name: &str, rendered: &str) {
52 let safe = if is_redacted(name) {
53 REDACTION_PLACEHOLDER.to_owned()
54 } else {
55 escape_control(rendered)
56 };
57 self.result = self.write_field(name, &safe);
58 }
59
60 fn write_field(&mut self, name: &str, value: &str) -> fmt::Result {
61 if self.is_first {
62 self.is_first = false;
63 } else {
64 self.writer.write_char(' ')?;
65 }
66 write!(self.writer, "{}={}", name, value)
67 }
68}
69
70impl Visit for FilteringVisitor<'_> {
71 fn record_debug(&mut self, field: &Field, value: &dyn fmt::Debug) {
72 self.record_filtered(field, value);
73 }
74
75 fn record_str(&mut self, field: &Field, value: &str) {
76 if self.result.is_err() {
77 return;
78 }
79 if is_system_sentinel(value) {
80 return;
81 }
82 self.write_value(field.name(), &format!("{:?}", value));
83 }
84}
85
86impl VisitOutput<fmt::Result> for FilteringVisitor<'_> {
87 fn finish(self) -> fmt::Result {
88 self.result
89 }
90}
91
92impl VisitFmt for FilteringVisitor<'_> {
93 fn writer(&mut self) -> &mut dyn Write {
94 &mut self.writer
95 }
96}
97
98impl<'a> MakeVisitor<Writer<'a>> for FilterSystemFields {
99 type Visitor = FilteringVisitor<'a>;
100
101 fn make_visitor(&self, target: Writer<'a>) -> Self::Visitor {
102 FilteringVisitor::new(target)
103 }
104}