P7.5.b: flatten JSON event fields for §10 schema compliance

Add `.flatten_event(true)` to tracing-subscriber JSON layers so event
fields (message, index, duration_ms, node_count, estimated_hits,
degraded) appear at the top level of each JSON log line, matching the
flat schema specified in plan §10.

Also add a proper unit test for SearchRequestBody Debug redaction
(previously a placeholder) confirming that query strings and filter
values are replaced with "[redacted]".

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
jedarden 2026-04-23 21:32:04 -04:00
parent 352dfb4698
commit e092164e70
3 changed files with 37 additions and 9 deletions

View file

@ -163,6 +163,7 @@ async fn main() -> anyhow::Result<()> {
if let Some(otel_layer) = otel::init_otel_layer(&config) {
let json_layer = tracing_subscriber::fmt::layer()
.json()
.flatten_event(true)
.with_target(true)
.with_current_span(true)
.with_span_list(false);
@ -175,6 +176,7 @@ async fn main() -> anyhow::Result<()> {
} else {
let json_layer = tracing_subscriber::fmt::layer()
.json()
.flatten_event(true)
.with_target(true)
.with_current_span(true)
.with_span_list(false);

View file

@ -262,3 +262,35 @@ pub fn strip_internal_fields(hit: &mut Value, client_requested_score: bool) {
}
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_search_request_debug_redaction() {
let body = SearchRequestBody {
q: Some("sensitive user query about private data".to_string()),
offset: Some(0),
limit: Some(20),
filter: Some(serde_json::json!({"email": "user@example.com"})),
facets: Some(vec!["category".to_string()]),
ranking_score: Some(false),
rest: serde_json::json!({}),
};
let debug_output = format!("{:?}", body);
assert!(
!debug_output.contains("sensitive"),
"Debug output should not contain raw query text"
);
assert!(
!debug_output.contains("user@example.com"),
"Debug output should not contain filter values"
);
assert!(
debug_output.contains("[redacted]"),
"Debug output should show [redacted] for sensitive fields"
);
}
}

View file

@ -291,15 +291,9 @@ fn test_log_levels_correct() {
#[test]
fn test_search_request_debug_redaction() {
// This test verifies that the Debug impl for SearchRequestBody
// redacts the query string to prevent PII leaks in logs
//
// The actual struct is in routes/search.rs and has:
// field("q", &"[redacted]")
// field("filter", &"[redacted]")
//
// We verify the behavior through the integration test that
// actually makes search requests and checks logs.
// Verified by unit test in routes/search.rs (SearchRequestBody is private).
// That test confirms the Debug impl redacts `q` and `filter` fields.
// This placeholder keeps the integration test file's acceptance criteria visible.
}
// ---------------------------------------------------------------------------