def _convert_attribute_to_tag(key, attr): """Convert the attributes to jaeger tags.""" if isinstance(attr, bool): return jaeger.Tag(key=key, vBool=attr, vType=jaeger.TagType.BOOL) if isinstance(attr, str): return jaeger.Tag(key=key, vStr=attr, vType=jaeger.TagType.STRING) if isinstance(attr, int): return jaeger.Tag(key=key, vLong=attr, vType=jaeger.TagType.LONG) if isinstance(attr, float): return jaeger.Tag(key=key, vDouble=attr, vType=jaeger.TagType.DOUBLE) logger.warning("Could not serialize attribute %s:%r to tag", key, attr) return None
def export(self, spans): jaeger_spans = _translate_to_jaeger(spans) batch = jaeger.Batch( spans=jaeger_spans, process=jaeger.Process(serviceName=self.service_name), ) if self.collector is not None: self.collector.submit(batch) self.agent_client.emit(batch) return SpanExportResult.SUCCESS
def _translate_to_jaeger(spans: Span): """Translate the spans to Jaeger format. Args: spans: Tuple of spans to convert """ jaeger_spans = [] for span in spans: ctx = span.get_context() trace_id = ctx.trace_id span_id = ctx.span_id start_time_us = _nsec_to_usec_round(span.start_time) duration_us = _nsec_to_usec_round(span.end_time - span.start_time) status = span.status parent_id = 0 if isinstance(span.parent, trace_api.Span): parent_id = span.parent.get_context().span_id elif isinstance(span.parent, trace_api.SpanContext): parent_id = span.parent.span_id tags = _extract_tags(span.attributes) tags.extend([ _get_long_tag("status.code", status.canonical_code.value), _get_string_tag("status.message", status.description), _get_string_tag("span.kind", span.kind.name), ]) # Ensure that if Status.Code is not OK, that we set the "error" tag on the Jaeger span. if status.canonical_code is not StatusCanonicalCode.OK: tags.append(_get_bool_tag("error", True)) refs = _extract_refs_from_span(span) logs = _extract_logs_from_span(span) flags = int(ctx.trace_flags) jaeger_span = jaeger.Span( traceIdHigh=_get_trace_id_high(trace_id), traceIdLow=_get_trace_id_low(trace_id), # generated code expects i64 spanId=_convert_int_to_i64(span_id), operationName=span.name, startTime=start_time_us, duration=duration_us, tags=tags, logs=logs, references=refs, flags=flags, parentSpanId=_convert_int_to_i64(parent_id), ) jaeger_spans.append(jaeger_span) return jaeger_spans
def _extract_logs_from_span(span): if not span.events: return None logs = [] for event in span.events: fields = _extract_tags(event.attributes) fields.append( jaeger.Tag(key="message", vType=jaeger.TagType.STRING, vStr=event.name)) event_timestamp_us = _nsec_to_usec_round(event.timestamp) logs.append( jaeger.Log(timestamp=int(event_timestamp_us), fields=fields)) return logs
def _translate_to_jaeger(spans: Span): """Translate the spans to Jaeger format. Args: spans: Tuple of spans to convert """ jaeger_spans = [] for span in spans: ctx = span.get_context() trace_id = ctx.trace_id span_id = ctx.span_id start_time_us = _nsec_to_usec_round(span.start_time) duration_us = _nsec_to_usec_round(span.end_time - span.start_time) parent_id = 0 if isinstance(span.parent, trace_api.Span): parent_id = span.parent.get_context().span_id elif isinstance(span.parent, trace_api.SpanContext): parent_id = span.parent.span_id tags = _extract_tags(span.attributes) # TODO: status is missing: # https://github.com/open-telemetry/opentelemetry-python/issues/98 refs = _extract_refs_from_span(span) logs = _extract_logs_from_span(span) flags = int(ctx.trace_options) jaeger_span = jaeger.Span( traceIdHigh=_get_trace_id_high(trace_id), traceIdLow=_get_trace_id_low(trace_id), # generated code expects i64 spanId=_convert_int_to_i64(span_id), operationName=span.name, startTime=start_time_us, duration=duration_us, tags=tags, logs=logs, references=refs, flags=flags, parentSpanId=_convert_int_to_i64(parent_id), ) jaeger_spans.append(jaeger_span) return jaeger_spans
def _extract_refs_from_span(span): if not span.links: return None refs = [] for link in span.links: trace_id = link.context.trace_id span_id = link.context.span_id refs.append( jaeger.SpanRef( refType=jaeger.SpanRefType.FOLLOWS_FROM, traceIdHigh=_get_trace_id_high(trace_id), traceIdLow=_get_trace_id_low(trace_id), spanId=_convert_int_to_i64(span_id), )) return refs
def _get_bool_tag(key, val): return jaeger.Tag(key=key, vBool=val, vType=jaeger.TagType.BOOL)
def _get_string_tag(key, val): return jaeger.Tag(key=key, vStr=val, vType=jaeger.TagType.STRING)
def _get_long_tag(key, val): return jaeger.Tag(key=key, vLong=val, vType=jaeger.TagType.LONG)