import math from datetime import datetime as dt from oteldatareplay.common import gen_span_id, gen_trace_id def dt2span_time_nano(t): return str(math.floor(t.timestamp() * 1e9)) def span_start_time(span, key='startTimeUnixNano'): return dt.fromtimestamp(int(span[key]) / 1e9) class ResourceSpanRecord: def __init__(self, record): self.record = record self.parse_stats() self.traces_ids = [] self.span_ids = [] self.span_count = 0 self.first_span_start_time = None self.parse_stats() def get_first_span(self): rs = self.get_first_resource_span() if not rs: return None scope_spans = rs['scopeSpans'] scope_span = scope_spans[0] spans = scope_span['spans'] return spans[0] if len(spans) > 0 else None def get_first_resource_span(self): rss = self.get_resource_spans() return rss[0] if len(rss) > 0 else None def get_resource_spans(self): return self.record['resourceSpans'] def parse_stats(self): rss = self.get_resource_spans() scope_spans = [sc for rs in rss for sc in rs['scopeSpans']] spans = [span for scopeSpan in scope_spans for span in scopeSpan['spans']] self.traces_ids = set([s['traceId'] for s in spans]) self.span_ids = set([s['spanId'] for s in spans]) self.span_count = len(spans) self.first_span_start_time = dt.fromtimestamp(int(spans[0]['startTimeUnixNano']) / 1e9) def iter_spans(self, func): for rs in self.record['resourceSpans']: for sc in rs['scopeSpans']: for span in sc['spans']: func(span) def update_span(self, now, first_record_time, trace_id_map): def update_span_time(span): span_start_dt = span_start_time(span) span_end_dt = span_start_time(span, 'endTimeUnixNano') span_start_dt_sim = (span_start_dt - first_record_time) + now span_end_dt_sim = (span_end_dt - first_record_time) + now trace_id = span['traceId'] if trace_id in trace_id_map: span['traceId'] = trace_id_map[trace_id] else: tid = gen_trace_id() trace_id_map[trace_id] = gen_trace_id() span['traceId'] = tid span['startTimeUnixNano'] = dt2span_time_nano(span_start_dt_sim) span['endTimeUnixNano'] = dt2span_time_nano(span_end_dt_sim) self.iter_spans(update_span_time)