Conversation
Contributor
There was a problem hiding this comment.
Copilot review overview
🔵 Needs a closer look
It adds a network-facing command-executing service and report-serving pipeline with unresolved security and correctness issues.
Review effort: Lite
Findings: 7
Open (18)
Declare the mcp runtime dependency · New Prevent shell injection in remote command execution · New Sanitize comparison descriptions used as directory names · New Prevent path traversal through app and query identifiers · New Validate application IDs before constructing output paths · New Prevent command injection and SSRF in curl/SSH command · New Enable DNS rebinding protection and host allowlisting · New Align comparison discovery pattern with generated filename · New Handle empty operator values before integer conversion · New Sort runtime gaps by absolute value · New Make diagram rendering configurable and report failures · New Unify file server port and output root configuration · New Resolve usage documentation relative to server.py · New Align comparison report filenames and URLs · New Allow Spark stage 0 to be selected · New Configure the renderer JAR and check failures · New Skip BroadcastQueryStage in text-mode diagrams · New Document the correct configured file-server endpoint · New
What changed in this PR
Adds an MCP-based Spark event-log analysis service under tools/mcp, providing metrics, query-plan visualization, and run comparisons.
Changes:
- Adds FastMCP tools for event-log loading and performance analysis.
- Adds PlantUML generators and HTML/Markdown comparison reports.
- Adds usage documentation, dependencies, indexing, and file serving.
| File | Description |
|---|---|
tools/mcp/server.py |
MCP server and analysis tool implementations |
tools/mcp/script/usage.md |
Tool usage documentation |
tools/mcp/script/requires.txt |
Python dependencies |
tools/mcp/script/plan_text_uml_generator.py |
Text-plan PlantUML generation |
tools/mcp/script/plan_rest_uml_generator.py |
REST-plan PlantUML generation |
tools/mcp/script/generate_operator_comparison.py |
Operator comparison reports |
tools/mcp/script/generate_index.py |
Report index generation |
tools/mcp/script/compare_query_plans_html.py |
Query-plan HTML comparisons |
tools/mcp/script/compare_hottest_stages.py |
Hottest-stage reports |
tools/mcp/bin/pretty_server.py |
Generated-file HTTP server |
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
| duckdb | ||
| itables | ||
| mysql-connector-python | ||
|
|
Comment on lines
+124
to
+133
| get_container_cmd = f'ssh centos@{driver_ip} "docker ps --format \'{{{{.Names}}}}\' | head -1"' | ||
| container_name = _sub.check_output(get_container_cmd, shell=True).decode().strip() | ||
| ssh_cmd = ( | ||
| f'ssh centos@{driver_ip} ' | ||
| f'"docker cp {container_name}:/opt/spark/events/{appid} /tmp/"' | ||
| ) | ||
| _sub.run(ssh_cmd, shell=True, check=True) | ||
| # pull the file to local output/<appid>/<appid> | ||
| scp_cmd = f"scp centos@{driver_ip}:/tmp/{appid} {local_log}" | ||
| _sub.run(scp_cmd, shell=True, check=True) |
Comment on lines
+213
to
+214
| comparison_folder = appname1 + "-" + appname2 | ||
| folder_name = _os.path.join(DEFAULT_OUTPUT_ROOT, comparison_folder) |
Comment on lines
+815
to
+817
| out_folder = os.path.join(_FILE_SERVER_ROOT, appid) | ||
| os.makedirs(out_folder, exist_ok=True) | ||
| puml_path = os.path.join(out_folder, f"{queryid}.puml") |
Comment on lines
+975
to
+977
| out_dir = os.path.join(_FILE_SERVER_ROOT, app_id) | ||
| os.makedirs(out_dir, exist_ok=True) | ||
| plan_file = os.path.join(out_dir, f"{query_id}.plan") |
Comment on lines
+280
to
+282
| base_url = f"http://127.0.0.1:6020/{run1_desc}-{run2_desc}" | ||
| comparison_url = f"{base_url}/comparison_{run1_id}_vs_{run2_id}.md#1-run-information" | ||
| operator_url = f"{base_url}/operator_comparison.md#runtime-summary" |
Comment on lines
+528
to
+529
| if stageid: | ||
| kwargs["stageid"] = stageid |
Comment on lines
+772
to
+775
| os.system( | ||
| f'java -Xmx1024m -DPLANTUML_LIMIT_SIZE=8192 ' | ||
| f'-jar {_PLANTUML_JAR} "{puml_path}"' | ||
| ) |
Comment on lines
+119
to
+127
| SKIP_PATTERNS = [ | ||
| r'^InputAdapter$', | ||
| r'^InputIteratorTransformer$', | ||
| r'^AdaptiveSparkPlan$', | ||
| r'^WholeStageCodegenTransformer\s*\(\d+\)', | ||
| r'^AQEShuffleRead$', | ||
| r'^VeloxResizeBatches$', | ||
| r'^ReusedExchange$', | ||
| ] |
| | `run1_desc` | no | `""` | Short label for run 1 (no spaces). If omitted, call `get_comment_by_appid(run1_id)` first, derive a short description (replace spaces with underscores), and pass it here | | ||
| | `run2_desc` | no | `""` | Short label for run 2 (no spaces). If omitted, call `get_comment_by_appid(run2_id)` first, derive a short description (replace spaces with underscores), and pass it here | | ||
|
|
||
| **Returns:** URL to the generated comparison report, e.g. `http://127.0.0.1:5010/<run1_desc>-<run2_desc>/`. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.



Enhance the benchmark analysis by introducing mcp_server. The mcp server uses a spark connect client to load data from event logs, then generate performance summary and query plan comparisons