Skip to content

Commit af1cf41

Browse files
Added tracer viewer server helper script
Script copies files in directory to any desired directory and also added a fetch api in transitions to dynamically serve data
1 parent c103a34 commit af1cf41

File tree

6 files changed

+133
-46
lines changed

6 files changed

+133
-46
lines changed

FWCore/Services/scripts/edmTracerCompactLogViewer.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1289,8 +1289,7 @@ def runTests():
12891289
if args.json:
12901290
print(j)
12911291
if args.web:
1292-
j ='export const data = ' + j
1293-
f=open('data.js', 'w')
1292+
f=open('data.json', 'w')
12941293
f.write(j)
12951294
f.close()
12961295
else:

FWCore/Services/web/README.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,12 @@ This is a simple HTTP server implemented in Python using the `http.server` modul
1414
1. Run the server script (`server.py`) using Python.
1515
2. Access the server in your web browser by navigating to `http://localhost:65432`.
1616

17+
### Specifying the Port
1718

19+
You can specify the port to serve on by using the `--port` argument:
20+
21+
```sh
22+
python server.py --port 8080
1823

1924
## Viewer layout
2025
The viewer is composed to two main areas, the top is the timing viewer and at the bottom shows information about a selected time block. The top time viewer is further divided into three parts. On the left is the macro scoping grouping of framework activity types into Global and Stream activities. If the _module centric_ option was chosen then this area is also divided by each module activity which is sorted based on most time used to least time used. At the bottom is the measurement of time since the start of the job. The main area shows the blocks of time spend doing various work within the Framework.
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
import os
2+
import shutil
3+
import argparse
4+
5+
def copy_directory_content(src, dest):
6+
"""
7+
Copies all content from the source directory to the destination directory.
8+
"""
9+
if not os.path.exists(dest):
10+
os.makedirs(dest)
11+
12+
for item in os.listdir(src):
13+
src_path = os.path.join(src, item)
14+
dest_path = os.path.join(dest, item)
15+
16+
if os.path.isdir(src_path):
17+
shutil.copytree(src_path, dest_path)
18+
else:
19+
shutil.copy2(src_path, dest_path)
20+
21+
def main():
22+
parser = argparse.ArgumentParser(description='Copy contents of a directory to a specified target directory.')
23+
parser.add_argument('target_directory', type=str, help='The target directory where content will be copied.')
24+
25+
args = parser.parse_args()
26+
27+
current_directory = os.path.dirname(os.path.abspath(__file__)) # Get the directory where the script is located
28+
target_directory = args.target_directory
29+
30+
copy_directory_content(current_directory, target_directory)
31+
print(f"All content from {current_directory} has been copied to {target_directory}")
32+
33+
if __name__ == "__main__":
34+
main()

FWCore/Services/web/index.html

Lines changed: 54 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1,31 +1,57 @@
11
<!DOCTYPE html>
22
<html lang="en-US">
3-
<head>
4-
<meta charset="utf-8" />
5-
<link rel="stylesheet" type="text/css" href="transitions.css"></link>
6-
<script type="module" src="transitions.js"></script>
7-
<script type="module" src="data.js"></script>
8-
</head>
9-
<body>
10-
<title>Tracer Output</title>
11-
<div class="container">
12-
<div class="name_div">
13-
<canvas id = "name_view"></canvas>
14-
</div>
15-
<div class="graph_div">
16-
<canvas id="graph_view"></canvas>
17-
</div>
18-
<div class="time_div">
19-
<canvas id = "time_view"></canvas>
20-
</div>
21-
<div class="selected">
22-
<p id="selected_paragraph">Selected:</p>
23-
</div>
24-
<div class="controls">
25-
<button id="zoom_out">--&gt; &lt;--</button>
26-
<button id="zoom_in">&lt;-- --&gt;</button>
27-
<p>&lt;CTRL&gt;+scroll to zoom</p>
28-
</div>
29-
</div>
30-
</body>
3+
<head>
4+
<meta charset="utf-8" />
5+
<title>Tracer Output</title>
6+
<link rel="stylesheet" type="text/css" href="transitions.css">
7+
<style>
8+
body {
9+
font-family: Arial, sans-serif;
10+
}
11+
.regular {
12+
padding: 10px;
13+
border: 1px solid #ccc;
14+
margin-top: 10px;
15+
}
16+
h2 {
17+
margin: 0 0 10px 0;
18+
}
19+
#top-functions {
20+
display: flex;
21+
align-items: center;
22+
}
23+
#function2, #input1 {
24+
margin-right: 10px;
25+
}
26+
.hidden {
27+
display: none;
28+
}
29+
</style>
30+
<script type="module" src="transitions.js"></script>
31+
</head>
32+
<body>
33+
<div class="container">
34+
<div class="name_div">
35+
<canvas id="name_view"></canvas>
36+
</div>
37+
<div class="graph_div">
38+
<canvas id="graph_view"></canvas>
39+
</div>
40+
<div class="time_div">
41+
<canvas id="time_view"></canvas>
42+
</div>
43+
<div class="selected">
44+
<p id="selected_paragraph">Selected:</p>
45+
</div>
46+
<div class="controls">
47+
<button id="zoom_out">--&gt; &lt;--</button>
48+
<button id="zoom_in">&lt;-- --&gt;</button>
49+
<p>&lt;CTRL&gt;+scroll to zoom</p>
50+
</div>
51+
</div>
52+
</body>
3153
</html>
54+
55+
56+
57+

FWCore/Services/web/server.py

Lines changed: 32 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,39 +1,63 @@
1-
from http.server import HTTPServer, BaseHTTPRequestHandler
21
import os
2+
from http.server import HTTPServer, BaseHTTPRequestHandler
33
import mimetypes
4+
import argparse
45

56
class Serv(BaseHTTPRequestHandler):
67
def do_GET(self):
8+
# Default route to serve the index.html file
79
if self.path == '/':
810
self.path = '/index.html'
9-
11+
# Serve the uploaded JavaScript file if requested
12+
if self.path == '/modules_data.json':
13+
self.path = '/modules_data.json'
14+
1015
try:
11-
file_path = self.path[1:]
16+
file_path = self.path[1:] # Remove leading '/' to get the file path
1217

18+
# Read the requested file
1319
with open(file_path, 'rb') as file:
1420
file_to_open = file.read()
1521

22+
# MIME type of the file
1623
mime_type, _ = mimetypes.guess_type(file_path)
1724

25+
# Send the HTTP response
1826
self.send_response(200)
1927
if mime_type:
2028
self.send_header("Content-type", mime_type)
2129
self.end_headers()
2230

31+
# Write the file content to the response
2332
self.wfile.write(file_to_open)
24-
33+
2534
except FileNotFoundError:
35+
# Handle file not found error
2636
self.send_response(404)
2737
self.send_header("Content-type", "text/html")
2838
self.end_headers()
2939
self.wfile.write(bytes("File not found", 'utf-8'))
30-
40+
3141
except Exception as e:
42+
# Handle any other internal server errors
3243
self.send_response(500)
3344
self.send_header("Content-type", "text/html")
3445
self.end_headers()
3546
self.wfile.write(bytes(f"Internal server error: {str(e)}", 'utf-8'))
3647

37-
httpd = HTTPServer(('localhost', 65432), Serv)
38-
print("Server started at http://localhost:65432")
39-
httpd.serve_forever()
48+
def run(server_class=HTTPServer, handler_class=Serv, port=65432):
49+
# Configure and start the HTTP server
50+
server_address = ('localhost', port)
51+
httpd = server_class(server_address, handler_class)
52+
print(f"Server started at http://localhost:{port}")
53+
httpd.serve_forever()
54+
55+
if __name__ == "__main__":
56+
# Parse command-line arguments to set the server port
57+
parser = argparse.ArgumentParser(description='Start a simple HTTP server.')
58+
parser.add_argument('--port', type=int, default=65432, help='Port to serve on (default: 65432)')
59+
args = parser.parse_args()
60+
61+
# Start the server with the specified port
62+
run(port=args.port)
63+

FWCore/Services/web/transitions.js

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,3 @@
1-
import {data} from './data.js';
2-
//import data from './data.json' assert { type: 'json' };
3-
41
const kBoxHeight = 15;
52
const kRowHeight = 20;
63

@@ -89,11 +86,13 @@ const activityToName = [ "prefetch",
8986
"externalWork"]
9087

9188
const activityToColor = ["#FF5F1F", "#CC7722", null, "#FF4433", "#8B4513"];
92-
93-
window.onload = () => {
89+
/* const promiseOfSomeData = fetch("modules_data.json").then(r=>r.json()).then(data => {
90+
return data;
91+
}); */
92+
window.onload = async() => {
9493

95-
//const response = await fetch("./data.json");
96-
//const data = await response.json();
94+
const response = await fetch("modules_data.json");
95+
const data = await response.json();
9796
const left = document.querySelector('.name_div');
9897
const div = document.querySelector('.graph_div');
9998
const bottom = document.querySelector('.time_div');
@@ -564,4 +563,4 @@ window.onload = () => {
564563
event.preventDefault()
565564
}
566565
name_view.addEventListener('wheel', name_onWheel);
567-
}
566+
}

0 commit comments

Comments
 (0)