Example #1
0
    def _extract_logs(
            self, span: ReadableSpan) -> Optional[Sequence[TCollector.Log]]:
        """Returns jaeger logs if events exists, otherwise None.

        Args:
            span: span to extract logs
        """
        if not span.events:
            return None

        logs = []
        for event in span.events:
            fields = []
            for key, value in event.attributes.items():
                tag = _translate_attribute(key, value,
                                           self._max_tag_value_length)
                if tag:
                    fields.append(tag)

            fields.append(
                TCollector.Tag(
                    key="message",
                    vType=TCollector.TagType.STRING,
                    vStr=event.name,
                ))

            event_timestamp_us = _nsec_to_usec_round(event.timestamp)
            logs.append(
                TCollector.Log(timestamp=int(event_timestamp_us),
                               fields=fields))

        return logs
Example #2
0
    def _translate_span(self, span: ReadableSpan) -> TCollector.Span:
        ctx = span.get_span_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 = span.parent.span_id if span.parent else 0

        tags = self._extract_tags(span)
        refs = self._extract_refs(span)
        logs = self._extract_logs(span)

        flags = int(ctx.trace_flags)

        jaeger_span = TCollector.Span(
            traceIdHigh=_get_trace_id_high(trace_id),
            traceIdLow=_get_trace_id_low(trace_id),
            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),
        )
        return jaeger_span
Example #3
0
    def export(self, spans) -> SpanExportResult:
        # Populate service_name from first span
        # We restrict any SpanProcessor to be only associated with a single
        # TracerProvider, so it is safe to assume that all Spans in a single
        # batch all originate from one TracerProvider (and in turn have all
        # the same service.name)
        if spans:
            service_name = spans[0].resource.attributes.get(SERVICE_NAME)
            if service_name:
                self.service_name = service_name
        translator = Translate(spans)
        thrift_translator = ThriftTranslator(self._max_tag_value_length)
        jaeger_spans = translator._translate(thrift_translator)
        batch = jaeger_thrift.Batch(
            spans=jaeger_spans,
            process=jaeger_thrift.Process(serviceName=self.service_name),
        )
        if self._collector_http_client is not None:
            self._collector_http_client.submit(batch)
        else:
            self._agent_client.emit(batch)

        return SpanExportResult.SUCCESS
Example #4
0
    def _extract_refs(
            self,
            span: ReadableSpan) -> Optional[Sequence[TCollector.SpanRef]]:
        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(
                TCollector.SpanRef(
                    refType=TCollector.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
Example #5
0
    def emit(self, batch: jaeger.Batch):
        """
        Args:
            batch: Object to emit Jaeger spans.
        """

        # pylint: disable=protected-access
        self.client._seqid = 0
        #  truncate and reset the position of BytesIO object
        self.buffer._buffer.truncate(0)
        self.buffer._buffer.seek(0)
        self.client.emitBatch(batch)
        buff = self.buffer.getvalue()
        if len(buff) > self.max_packet_size:
            if self.split_oversized_batches and len(batch.spans) > 1:
                packets = math.ceil(len(buff) / self.max_packet_size)
                div = math.ceil(len(batch.spans) / packets)
                for packet in range(packets):
                    start = packet * div
                    end = (packet + 1) * div
                    if start < len(batch.spans):
                        self.emit(
                            jaeger.Batch(
                                process=batch.process,
                                spans=batch.spans[start:end],
                            ))
            else:
                logger.warning(
                    "Data exceeds the max UDP packet size; size %r, max %r",
                    len(buff),
                    self.max_packet_size,
                )
            return

        with socket.socket(socket.AF_INET, socket.SOCK_DGRAM) as udp_socket:
            udp_socket.sendto(buff, self.address)
Example #6
0
def _get_string_tag(key, value: str) -> TCollector.Tag:
    """Returns jaeger string tag."""
    return TCollector.Tag(key=key, vStr=value, vType=TCollector.TagType.STRING)
Example #7
0
def _get_double_tag(key: str, value: float) -> TCollector.Tag:
    """Returns jaeger double tag."""
    return TCollector.Tag(key=key,
                          vDouble=value,
                          vType=TCollector.TagType.DOUBLE)
Example #8
0
def _get_long_tag(key: str, value: int) -> TCollector.Tag:
    """Returns jaeger long tag."""
    return TCollector.Tag(key=key, vLong=value, vType=TCollector.TagType.LONG)
Example #9
0
def _get_bool_tag(key: str, value: bool) -> TCollector.Tag:
    """Returns jaeger boolean tag."""
    return TCollector.Tag(key=key, vBool=value, vType=TCollector.TagType.BOOL)