Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 31 additions & 0 deletions src/parsers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -550,6 +550,36 @@ impl StructuredLogParser for CompilationMetricsParser<'_> {
readable_url: o.readable_url.as_ref().map(|u| remove_prefix(u)),
})
.collect();
let extra_metrics: Vec<ExtraMetricContext> = m
.extra
.iter()
.map(|(key, value)| {
let value_html = match value {
serde_json::Value::String(s) => {
if s.len() > 200 {
format!("<details><summary>(click to expand)</summary><pre>{}</pre></details>",
html_escape::encode_text(s))
} else {
html_escape::encode_text(s).to_string()
}
}
serde_json::Value::Null => "null".to_string(),
other => {
let s = other.to_string();
if s.len() > 200 {
format!("<details><summary>(click to expand)</summary><pre>{}</pre></details>",
html_escape::encode_text(&s))
} else {
html_escape::encode_text(&s).to_string()
}
}
};
ExtraMetricContext {
key: key.clone(),
value_html,
}
})
.collect();
let context = CompilationMetricsContext {
css: crate::CSS,
m: &m,
Expand All @@ -562,6 +592,7 @@ impl StructuredLogParser for CompilationMetricsParser<'_> {
unbacked_symbols: unbacked_symbols,
output_files: &output_files,
compile_id_dir: &self.compile_id_dir,
extra_metrics: extra_metrics,
qps: TEMPLATE_QUERY_PARAM_SCRIPT,
};
let output = self.tt.render(&filename, &context)?;
Expand Down
14 changes: 14 additions & 0 deletions src/templates.rs
Original file line number Diff line number Diff line change
Expand Up @@ -406,6 +406,20 @@ pub static TEMPLATE_COMPILATION_METRICS: &str = r#"
</tr>
{{ endfor }}
</table>
{{ if extra_metrics }}
<h2>Other Metrics</h2>
<table>
<tr>
<th>Key</th> <th>Value</th>
</tr>
{{ for em in extra_metrics }}
<tr>
<td><code>{em.key}</code></td>
<td>{em.value_html | format_unescaped}</td>
</tr>
{{ endfor }}
</table>
{{ endif }}
{qps | format_unescaped}
</body>
</html>
Expand Down
10 changes: 10 additions & 0 deletions src/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -481,6 +481,9 @@ pub struct CompilationMetricsMetadata {
pub compliant_custom_ops: Option<Vec<String>>,
pub restart_reasons: Option<Vec<String>>,
pub dynamo_time_before_restart_s: Option<f64>,
// Capture any additional fields not explicitly listed above
#[serde(flatten)]
pub extra: std::collections::BTreeMap<String, serde_json::Value>,
}

#[derive(Debug, Deserialize, Serialize, Clone)]
Expand Down Expand Up @@ -627,9 +630,16 @@ pub struct CompilationMetricsContext<'e> {
pub output_files: &'e Vec<OutputFile>,
pub compile_id_dir: &'e PathBuf,
pub mini_stack_html: String,
pub extra_metrics: Vec<ExtraMetricContext>,
pub qps: &'static str,
}

#[derive(Debug, Serialize)]
pub struct ExtraMetricContext {
pub key: String,
pub value_html: String,
}

#[derive(Debug, Serialize)]
pub struct SymbolicGuardContext {
pub css: &'static str,
Expand Down
61 changes: 61 additions & 0 deletions tests/integration_test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -390,6 +390,67 @@ fn test_cache_hit_miss() {
}
}

#[test]
fn test_compilation_metrics_extra_fields() {
// cache_hit_miss.log has compilation_metrics entries with extra fields
// not explicitly in CompilationMetricsMetadata (e.g. dynamo_config, is_forward, etc.)
// Verify those extra fields appear in the "Other Metrics" section of the output HTML.
let path = Path::new("tests/inputs/cache_hit_miss.log").to_path_buf();
let config = tlparse::ParseConfig {
strict: true,
..Default::default()
};
let output = tlparse::parse_path(&path, &config);
assert!(output.is_ok());
let map: HashMap<PathBuf, String> = output.unwrap().into_iter().collect();

// Find the compilation_metrics HTML file
let metrics_html = map
.iter()
.find(|(k, _)| {
k.to_str()
.map_or(false, |s| s.contains("compilation_metrics"))
})
.unwrap_or_else(|| {
let keys: Vec<_> = map.keys().map(|k| k.display().to_string()).collect();
panic!(
"compilation_metrics not found in output. Available keys: {:?}",
keys
);
});

let html = metrics_html.1;

// These keys exist in the log's compilation_metrics JSON but are NOT explicit
// fields in CompilationMetricsMetadata, so they should be captured via #[serde(flatten)]
// and rendered in the "Other Metrics" section.
let expected_extra_keys = [
"aot_autograd_cumulative_compile_time_us",
"config_inline_inbuilt_nn_modules",
"config_suppress_errors",
"dynamo_compile_time_before_restart_us",
"dynamo_config",
"dynamo_cumulative_compile_time_us",
"frame_key",
"has_guarded_code",
"is_forward",
"specialize_float",
];

assert!(
html.contains("Other Metrics"),
"Expected 'Other Metrics' section in compilation_metrics.html"
);

for key in expected_extra_keys {
assert!(
html.contains(key),
"Expected extra key '{}' in compilation_metrics.html",
key
);
}
}

#[test]
fn test_export_report() {
let expected_files = [
Expand Down
Loading