java_jfr_summary
Summarize Java Flight Recorder (JFR) files to identify memory-related events and potential leaks. Provides a concise overview of JFR recording data for analysis.
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| jfr_file | Yes |
Output Schema
| Name | Required | Description | Default |
|---|---|---|---|
No arguments | |||
Implementation Reference
- src/heap_seance_mcp/tools.py:205-237 (handler)Main implementation of java_jfr_summary. Validates the JFR file exists, runs 'jfr summary' or 'jcmd JFR.view', parses output, and returns result with metrics and confidence.
def java_jfr_summary(jfr_file: str) -> dict[str, Any]: path = Path(jfr_file) if not path.exists(): return error_result( f"JFR file not found: {jfr_file}", next_recommended_action="Provide a valid .jfr file path from java_jfr_start.", ) try: from .shell_tools import which jfr_bin = which("jfr") if jfr_bin: output = ensure_success(run_command([jfr_bin, "summary", str(path)], timeout_s=120)).stdout else: output = ensure_success(run_command(["jcmd", "JFR.view", str(path)], timeout_s=120)).stdout parsed = parse_jfr_summary(output) except Exception as exc: # noqa: BLE001 return _command_failed(exc) has_object_count = parsed["contains_object_count_after_gc"] confidence = "medium" if has_object_count else "low" return ok_result( evidence=[f"Generated JFR summary for {path}."] + parsed["summary_lines"][:5], metrics={ "contains_object_count_after_gc": has_object_count, "event_counts": parsed["event_counts"], }, confidence=confidence, next_recommended_action="Correlate high-allocation events with histogram growth candidates.", raw_artifact_path=str(path), ) - src/heap_seance_mcp/server.py:53-55 (registration)MCP tool registration: decorates the function with @mcp.tool() and delegates to tools.java_jfr_summary.
@mcp.tool() def java_jfr_summary(jfr_file: str) -> dict[str, Any]: return tools.java_jfr_summary(jfr_file=jfr_file) - Helper parser that extracts event counts and checks for jdk.ObjectCountAfterGC presence from the raw JFR summary output.
def parse_jfr_summary(text: str, *, top_n: int = 15) -> dict[str, Any]: lines = [line.rstrip() for line in text.splitlines() if line.strip()] event_counts: list[dict[str, Any]] = [] for line in lines: parts = line.split() if len(parts) < 3: continue if not parts[-1].isdigit() or not parts[-2].isdigit(): continue event_name = " ".join(parts[:-2]) event_counts.append( { "event": event_name, "count": int(parts[-2]), "size": int(parts[-1]), } ) return { "summary_lines": lines[:top_n], "event_counts": event_counts[:top_n], "contains_object_count_after_gc": any( "jdk.ObjectCountAfterGC" in line for line in lines ), } - src/heap_seance_mcp/workflow.py:24-25 (registration)Import of java_jfr_summary used in the automated workflow.
java_jfr_start, java_jfr_summary,