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
|