private void SendSpanTree(TracerContext tracerContext, MyTree <IClientSpan> spanTree) { var clientSpan = spanTree.Value; var tracer = tracerContext.Current(clientSpan.TracerId); using (var scope = tracer.BuildSpan(clientSpan.OpName) .WithStartTimestamp(clientSpan.StartUtc) .StartActive(false)) { foreach (var bag in clientSpan.Bags) { if (bag.Value == null) { scope.Span.SetTag(bag.Key, null); continue; } scope.Span.SetTag(bag.Key, bag.Value); } var logGroups = clientSpan.Logs.GroupBy(x => x.Value.CreateAt).ToList(); foreach (var logGroup in logGroups) { var createAt = logGroup.Key; var logInfos = logGroup.Select(x => new KeyValuePair <string, object>(x.Key, x.Value.Value)).ToList(); scope.Span.Log(createAt, logInfos); } foreach (var tag in clientSpan.Tags) { if (tag.Value == null) { scope.Span.SetTag(tag.Key, null); continue; } if (tag.Value is bool boolValue) { scope.Span.SetTag(tag.Key, boolValue); } else if (tag.Value is int intValue) { scope.Span.SetTag(tag.Key, intValue); } else if (tag.Value is double doubleValue) { scope.Span.SetTag(tag.Key, doubleValue); } scope.Span.SetTag(tag.Key, tag.Value.ToString()); } //cascade process children foreach (var childTree in spanTree.Children) { SendSpanTree(tracerContext, childTree); } if (clientSpan.FinishUtc != null) { //throw ex? scope.Span.Finish(clientSpan.FinishUtc.Value); } } }