Spaces:
Sleeping
Sleeping
Upload 2 files
Browse files- aworld/trace/server/routes.py +50 -0
- aworld/trace/server/util.py +32 -0
aworld/trace/server/routes.py
ADDED
@@ -0,0 +1,50 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
from aworld.trace.opentelemetry.memory_storage import TraceStorage
|
2 |
+
from aworld.utils.import_package import import_package
|
3 |
+
from aworld.trace.server.util import build_trace_tree
|
4 |
+
|
5 |
+
import_package('flask') # noqa
|
6 |
+
from flask import Flask, render_template, jsonify # noqa
|
7 |
+
|
8 |
+
app = Flask(__name__, template_folder='../../web/templates')
|
9 |
+
current_storage = None
|
10 |
+
routes_setup = False
|
11 |
+
|
12 |
+
|
13 |
+
def setup_routes(storage: TraceStorage):
|
14 |
+
global current_storage
|
15 |
+
current_storage = storage
|
16 |
+
|
17 |
+
global routes_setup
|
18 |
+
|
19 |
+
if routes_setup:
|
20 |
+
return app
|
21 |
+
|
22 |
+
@app.route('/')
|
23 |
+
def index():
|
24 |
+
return render_template('trace_ui.html')
|
25 |
+
|
26 |
+
@app.route('/api/traces')
|
27 |
+
def traces():
|
28 |
+
trace_data = []
|
29 |
+
for trace_id in current_storage.get_all_traces():
|
30 |
+
spans = current_storage.get_all_spans(trace_id)
|
31 |
+
spans_sorted = sorted(spans, key=lambda x: x.start_time)
|
32 |
+
trace_tree = build_trace_tree(spans_sorted)
|
33 |
+
trace_data.append({
|
34 |
+
'trace_id': trace_id,
|
35 |
+
'root_span': trace_tree,
|
36 |
+
})
|
37 |
+
return jsonify(trace_data)
|
38 |
+
|
39 |
+
@app.route('/api/traces/<trace_id>')
|
40 |
+
def get_trace(trace_id):
|
41 |
+
spans = current_storage.get_all_spans(trace_id)
|
42 |
+
spans_sorted = sorted(spans, key=lambda x: x.start_time)
|
43 |
+
trace_tree = build_trace_tree(spans_sorted)
|
44 |
+
return jsonify({
|
45 |
+
'trace_id': trace_id,
|
46 |
+
'root_span': trace_tree,
|
47 |
+
})
|
48 |
+
|
49 |
+
routes_setup = True
|
50 |
+
return app
|
aworld/trace/server/util.py
ADDED
@@ -0,0 +1,32 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
from aworld.logs.util import logger
|
2 |
+
from aworld.trace.opentelemetry.memory_storage import SpanModel
|
3 |
+
|
4 |
+
|
5 |
+
def build_trace_tree(spans: list[SpanModel]):
|
6 |
+
spans_dict = {span.span_id: span.dict() for span in spans}
|
7 |
+
for span in list(spans_dict.values()):
|
8 |
+
parent_id = span['parent_id'] if span['parent_id'] else None
|
9 |
+
if parent_id:
|
10 |
+
parent_span = spans_dict.get(parent_id)
|
11 |
+
if not parent_span:
|
12 |
+
logger.warning(f"span[{parent_id}] not be exported")
|
13 |
+
parent_span = {
|
14 |
+
'span_id': parent_id,
|
15 |
+
'trace_id': span['trace_id'],
|
16 |
+
'name': 'Pengding-Span',
|
17 |
+
'start_time': span['start_time'],
|
18 |
+
'end_time': span['end_time'],
|
19 |
+
'duration_ms': span['duration_ms'],
|
20 |
+
'attributes': {},
|
21 |
+
'status': {},
|
22 |
+
'parent_id': None,
|
23 |
+
'run_type': 'OTHER'
|
24 |
+
}
|
25 |
+
spans_dict[parent_id] = parent_span
|
26 |
+
if 'children' not in parent_span:
|
27 |
+
parent_span['children'] = []
|
28 |
+
parent_span['children'].append(span)
|
29 |
+
|
30 |
+
root_spans = [span for span in spans_dict.values()
|
31 |
+
if span['parent_id'] is None]
|
32 |
+
return root_spans
|