Example #1
0
    def translate_to_zipkin(self, span_datas):
        """Translate the opencensus spans to zipkin spans.

        :type span_datas: list of :class:
            `~opencensus.trace.span_data.SpanData`
        :param span_datas:
            SpanData tuples to emit

        :rtype: list
        :returns: List of zipkin format spans.
        """

        local_endpoint = {
            'serviceName': self.service_name,
            'port': self.port,
        }

        if self.ipv4 is not None:
            local_endpoint['ipv4'] = self.ipv4

        if self.ipv6 is not None:
            local_endpoint['ipv6'] = self.ipv6

        zipkin_spans = []

        for span in span_datas:
            # Timestamp in zipkin spans is int of microseconds.
            start_timestamp_mus = timestamp_to_microseconds(span.start_time)
            end_timestamp_mus = timestamp_to_microseconds(span.end_time)
            duration_mus = end_timestamp_mus - start_timestamp_mus

            zipkin_span = {
                'traceId': span.context.trace_id,
                'id': str(span.span_id),
                'name': span.name,
                'timestamp': int(round(start_timestamp_mus)),
                'duration': int(round(duration_mus)),
                'localEndpoint': local_endpoint,
                'tags': _extract_tags_from_span(span.attributes),
                'annotations': _extract_annotations_from_span(span),
            }

            span_kind = span.span_kind
            parent_span_id = span.parent_span_id

            if span_kind is not None:
                kind = SPAN_KIND_MAP.get(span_kind)
                # Zipkin API for span kind only accept
                # enum(CLIENT|SERVER|PRODUCER|CONSUMER|Absent)
                if kind is not None:
                    zipkin_span['kind'] = kind

            if parent_span_id is not None:
                zipkin_span['parentId'] = str(parent_span_id)

            zipkin_spans.append(zipkin_span)

        return zipkin_spans
Example #2
0
def honeycombSpan(span_data):
    start_timestamp_mus = timestamp_to_microseconds(span_data.start_time)
    end_timestamp_mus = timestamp_to_microseconds(span_data.end_time)

    sc = span_data.context
    hcSpan = {
        "trace.trace_id": sc.trace_id,
        "name": span_data.name,
        "trace.span_id": span_data.span_id,
        "duration_ms": round((end_timestamp_mus - start_timestamp_mus) / 1000),
    }
    if span_data.parent_span_id != None:
        hcSpan["trace.parent_id"] = span_data.parent_span_id

    if len(span_data.time_events):
        hcSpan["annotations"] = _extract_annotations_from_span(span_data)

    return hcSpan
Example #3
0
    def emit(self, span_datas):
        """Immediately marshal span data to the tracing backend

        :param span_datas: list of :class:`opencensus.trace.span_data.SpanData`
            to emit
        :type span_datas: list
        """
        spans = []
        for span_data in span_datas:
            start_timestamp_mus = timestamp_to_microseconds(
                span_data.start_time)
            end_timestamp_mus = timestamp_to_microseconds(span_data.end_time)
            duration_mus = end_timestamp_mus - start_timestamp_mus

            start_time_ms = start_timestamp_mus // 1000
            duration_ms = duration_mus // 1000

            span = Span(
                name=span_data.name,
                tags=span_data.attributes,
                guid=span_data.span_id,
                trace_id=span_data.context.trace_id,
                parent_id=span_data.parent_span_id,
                start_time_ms=start_time_ms,
                duration_ms=duration_ms,
            )

            spans.append(span)

        try:
            response = self.client.send_batch(spans, self._common)
        except Exception:
            _logger.exception("New Relic send_spans failed with an exception.")
            return

        if not response.ok:
            _logger.error("New Relic send_spans failed with status code: %r",
                          response.status)

        return response
Example #4
0
def _extract_annotations_from_span(span):
    """Extract and convert time event annotations to zipkin annotations"""
    if span.annotations is None:
        return []

    annotations = []
    for annotation in span.annotations:
        event_timestamp_mus = timestamp_to_microseconds(annotation.timestamp)
        annotations.append({
            'timestamp': int(round(event_timestamp_mus)),
            'value': annotation.description
        })

    return annotations
Example #5
0
def _extract_logs_from_span(span):
    if span.annotations is None:
        return None

    logs = []

    for annotation in span.annotations:
        fields = []
        if annotation.attributes is not None:
            fields = _extract_tags(annotation.attributes.attributes)

        fields.append(
            jaeger.Tag(key='message',
                       vType=jaeger.TagType.STRING,
                       vStr=annotation.description))

        event_timestamp = timestamp_to_microseconds(annotation.timestamp)
        logs.append(
            jaeger.Log(timestamp=int(round(event_timestamp)), fields=fields))
    return logs
Example #6
0
    def translate_to_jaeger(self, span_datas):
        """Translate the spans to Jaeger format.

        :type span_datas: list of :class:
            `~opencensus.trace.span_data.SpanData`
        :param span_datas:
            SpanData tuples to emit
        """

        top_span = span_datas[0]

        trace_id = top_span.context.trace_id if top_span.context is not None \
            else None

        jaeger_spans = []

        for span in span_datas:
            start_timestamp_ms = timestamp_to_microseconds(span.start_time)
            end_timestamp_ms = timestamp_to_microseconds(span.end_time)
            duration_ms = end_timestamp_ms - start_timestamp_ms

            tags = _extract_tags(span.attributes)

            status = span.status
            if status is not None:
                tags.append(
                    jaeger.Tag(key='status.code',
                               vType=jaeger.TagType.LONG,
                               vLong=status.code))

                tags.append(
                    jaeger.Tag(key='status.message',
                               vType=jaeger.TagType.STRING,
                               vStr=status.message))

            refs = _extract_refs_from_span(span)
            logs = _extract_logs_from_span(span)

            context = span.context
            flags = None
            if context is not None:
                flags = int(context.trace_options.trace_options_byte)

            span_id = span.span_id
            parent_span_id = span.parent_span_id

            jaeger_span = jaeger.Span(
                traceIdHigh=_convert_hex_str_to_int(trace_id[0:16]),
                traceIdLow=_convert_hex_str_to_int(trace_id[16:32]),
                spanId=_convert_hex_str_to_int(span_id),
                operationName=span.name,
                startTime=int(round(start_timestamp_ms)),
                duration=int(round(duration_ms)),
                tags=tags,
                logs=logs,
                references=refs,
                flags=flags,
                parentSpanId=_convert_hex_str_to_int(parent_span_id or '0'))

            jaeger_spans.append(jaeger_span)

        return jaeger_spans
Example #7
0
def timestamp_to_duration(start_time, end_time):
    start_time_us = timestamp_to_microseconds(start_time)
    end_time_us = timestamp_to_microseconds(end_time)
    duration_us = int(end_time_us - start_time_us)
    return microseconds_to_duration(duration_us)