Exemple #1
0
    def log_kv(self,
               key_values: Attributes,
               timestamp: float = None) -> "SpanShim":
        """Logs an event for the wrapped OpenTelemetry span.

        Note:
            The OpenTracing API defines the values of *key_values* to be of any
            type. However, the OpenTelemetry API requires that the values be
            any one of the types defined in
            ``opentelemetry.trace.util.Attributes`` therefore, only these types
            are supported as values.

        Args:
            key_values: A dictionary as specified in
                ``opentelemetry.trace.util.Attributes``.
            timestamp: Timestamp of the OpenTelemetry event, will be generated
                automatically if omitted.

        Returns:
            Returns this :class:`SpanShim` instance to allow call chaining.
        """

        if timestamp is not None:
            event_timestamp = util.time_seconds_to_ns(timestamp)
        else:
            event_timestamp = None

        event_name = util.event_name_from_kv(key_values)
        self._otel_span.add_event(event_name, key_values, event_timestamp)
        return self
    def test_time_conversion_precision(self):
        """Verify time conversion from seconds to nanoseconds and vice versa is
        accurate enough.
        """

        time_seconds = 1570484241.9501917
        time_nanoseconds = util.time_seconds_to_ns(time_seconds)
        result = util.time_seconds_from_ns(time_nanoseconds)

        # Tolerate inaccuracies of less than a microsecond.
        # TODO: Put a link to an explanation in the docs.
        # TODO: This seems to work consistently, but we should find out the
        # biggest possible loss of precision.
        self.assertAlmostEqual(result, time_seconds, places=6)
Exemple #3
0
    def finish(self, finish_time: float = None):
        """Ends the OpenTelemetry span wrapped by this :class:`SpanShim`.

        If *finish_time* is provided, the time value is converted to the
        OpenTelemetry time format (number of nanoseconds since the epoch,
        expressed as an integer) and passed on to the OpenTelemetry tracer when
        ending the OpenTelemetry span. If *finish_time* isn't provided, it is
        up to the OpenTelemetry tracer implementation to generate a timestamp
        when ending the span.

        Args:
            finish_time: A value that represents the finish time expressed as
                the number of seconds since the epoch as returned by
                :func:`time.time()`.
        """

        end_time = finish_time
        if end_time is not None:
            end_time = util.time_seconds_to_ns(finish_time)
        self._otel_span.end(end_time=end_time)
Exemple #4
0
    def start_span(
        self,
        operation_name: str = None,
        child_of: Union[SpanShim, SpanContextShim] = None,
        references: list = None,
        tags: Attributes = None,
        start_time: float = None,
        ignore_active_span: bool = False,
    ) -> SpanShim:
        """Implements the ``start_span()`` method from the base class.

        Starts a span. In terms of functionality, this method behaves exactly
        like the same method on a "regular" OpenTracing tracer. See
        :meth:`opentracing.Tracer.start_span` for more details.

        Args:
            operation_name: Name of the operation represented by the new span
                from the perspective of the current service.
            child_of: A :class:`SpanShim` or :class:`SpanContextShim`
                representing the parent in a "child of" reference. If
                specified, the *references* parameter must be omitted.
            references: A list of :class:`opentracing.Reference` objects that
                identify one or more parents of type :class:`SpanContextShim`.
            tags: A dictionary of tags.
            start_time: An explicit start time expressed as the number of
                seconds since the epoch as returned by :func:`time.time()`.
            ignore_active_span: Ignore the currently-active span in the
                OpenTelemetry tracer and make the created span the root span of
                a new trace.

        Returns:
            An already-started :class:`SpanShim` instance.
        """

        # Use active span as parent when no explicit parent is specified.
        if not ignore_active_span and not child_of:
            child_of = self.active_span

        # Use the specified parent or the active span if possible. Otherwise,
        # use a `None` parent, which triggers the creation of a new trace.
        parent = child_of.unwrap() if child_of else None
        if isinstance(parent, OtelSpanContext):
            parent = NonRecordingSpan(parent)

        parent_span_context = set_span_in_context(parent)

        links = []
        if references:
            for ref in references:
                links.append(Link(ref.referenced_context.unwrap()))

        # The OpenTracing API expects time values to be `float` values which
        # represent the number of seconds since the epoch. OpenTelemetry
        # represents time values as nanoseconds since the epoch.
        start_time_ns = start_time
        if start_time_ns is not None:
            start_time_ns = util.time_seconds_to_ns(start_time)

        span = self._otel_tracer.start_span(
            operation_name,
            context=parent_span_context,
            links=links,
            attributes=tags,
            start_time=start_time_ns,
        )

        context = SpanContextShim(span.get_span_context())
        return SpanShim(self, context, span)
    def test_time_seconds_to_ns(self):
        time_seconds = time.time()
        result = util.time_seconds_to_ns(time_seconds)

        self.assertEqual(result, int(time_seconds * 1e9))