mirror of
https://github.com/open-telemetry/opentelemetry-python-contrib.git
synced 2025-07-30 05:32:30 +08:00
Merge pull request #123 from NathanielRN/move-exporter-datadog
Move exporter datadog
This commit is contained in:
@ -2,6 +2,10 @@
|
||||
|
||||
## Unreleased
|
||||
|
||||
## Version 0.15b0
|
||||
|
||||
Released 2020-11-02
|
||||
|
||||
- Make `SpanProcessor.on_start` accept parent Context
|
||||
([#1251](https://github.com/open-telemetry/opentelemetry-python/pull/1251))
|
||||
|
||||
|
@ -40,8 +40,8 @@ package_dir=
|
||||
packages=find_namespace:
|
||||
install_requires =
|
||||
ddtrace>=0.34.0
|
||||
opentelemetry-api == 0.15.dev0
|
||||
opentelemetry-sdk == 0.15.dev0
|
||||
opentelemetry-api == 0.15b0
|
||||
opentelemetry-sdk == 0.15b0
|
||||
|
||||
[options.packages.find]
|
||||
where = src
|
||||
|
@ -23,7 +23,6 @@ from ddtrace.span import Span as DatadogSpan
|
||||
import opentelemetry.trace as trace_api
|
||||
from opentelemetry.sdk.trace import sampling
|
||||
from opentelemetry.sdk.trace.export import SpanExporter, SpanExportResult
|
||||
from opentelemetry.trace.status import StatusCanonicalCode
|
||||
|
||||
# pylint:disable=relative-beyond-top-level
|
||||
from .constants import (
|
||||
@ -145,7 +144,7 @@ class DatadogSpanExporter(SpanExporter):
|
||||
datadog_span.start_ns = span.start_time
|
||||
datadog_span.duration_ns = span.end_time - span.start_time
|
||||
|
||||
if span.status.canonical_code is not StatusCanonicalCode.OK:
|
||||
if not span.status.is_ok:
|
||||
datadog_span.error = 1
|
||||
if span.status.description:
|
||||
exc_type, exc_val = _get_exc_info(span)
|
||||
|
@ -39,25 +39,23 @@ class DatadogFormat(TextMapPropagator):
|
||||
|
||||
def extract(
|
||||
self,
|
||||
get_from_carrier: Getter[TextMapPropagatorT],
|
||||
getter: Getter[TextMapPropagatorT],
|
||||
carrier: TextMapPropagatorT,
|
||||
context: typing.Optional[Context] = None,
|
||||
) -> Context:
|
||||
trace_id = extract_first_element(
|
||||
get_from_carrier(carrier, self.TRACE_ID_KEY)
|
||||
getter.get(carrier, self.TRACE_ID_KEY)
|
||||
)
|
||||
|
||||
span_id = extract_first_element(
|
||||
get_from_carrier(carrier, self.PARENT_ID_KEY)
|
||||
getter.get(carrier, self.PARENT_ID_KEY)
|
||||
)
|
||||
|
||||
sampled = extract_first_element(
|
||||
get_from_carrier(carrier, self.SAMPLING_PRIORITY_KEY)
|
||||
getter.get(carrier, self.SAMPLING_PRIORITY_KEY)
|
||||
)
|
||||
|
||||
origin = extract_first_element(
|
||||
get_from_carrier(carrier, self.ORIGIN_KEY)
|
||||
)
|
||||
origin = extract_first_element(getter.get(carrier, self.ORIGIN_KEY))
|
||||
|
||||
trace_flags = trace.TraceFlags()
|
||||
if sampled and int(sampled) in (
|
||||
|
@ -119,7 +119,8 @@ class DatadogExportSpanProcessor(SpanProcessor):
|
||||
with self.condition:
|
||||
self.condition.wait(timeout)
|
||||
if not self.check_traces_queue:
|
||||
# spurious notification, let's wait again
|
||||
# spurious notification, let's wait again, reset timeout
|
||||
timeout = self.schedule_delay_millis / 1e3
|
||||
continue
|
||||
if self.done:
|
||||
# missing spans will be sent when calling flush
|
||||
|
@ -12,4 +12,4 @@
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
__version__ = "0.15.dev0"
|
||||
__version__ = "0.15b0"
|
||||
|
@ -40,7 +40,7 @@ class MockDatadogSpanExporter(datadog.DatadogSpanExporter):
|
||||
|
||||
def get_spans(tracer, exporter, shutdown=True):
|
||||
if shutdown:
|
||||
tracer.source.shutdown()
|
||||
tracer.span_processor.shutdown()
|
||||
|
||||
spans = [
|
||||
call_args[-1]["spans"]
|
||||
@ -483,6 +483,42 @@ class TestDatadogSpanExporter(unittest.TestCase):
|
||||
|
||||
tracer_provider.shutdown()
|
||||
|
||||
def test_batch_span_processor_reset_timeout(self):
|
||||
"""Test that the scheduled timeout is reset on cycles without spans"""
|
||||
delay = 50
|
||||
# pylint: disable=protected-access
|
||||
exporter = MockDatadogSpanExporter()
|
||||
exporter._agent_writer.write.side_effect = lambda spans: time.sleep(
|
||||
0.05
|
||||
)
|
||||
span_processor = datadog.DatadogExportSpanProcessor(
|
||||
exporter, schedule_delay_millis=delay
|
||||
)
|
||||
tracer_provider = trace.TracerProvider()
|
||||
tracer_provider.add_span_processor(span_processor)
|
||||
tracer = tracer_provider.get_tracer(__name__)
|
||||
with mock.patch.object(span_processor.condition, "wait") as mock_wait:
|
||||
with tracer.start_span("foo"):
|
||||
pass
|
||||
|
||||
# give some time for exporter to loop
|
||||
# since wait is mocked it should return immediately
|
||||
time.sleep(0.1)
|
||||
mock_wait_calls = list(mock_wait.mock_calls)
|
||||
|
||||
# find the index of the call that processed the singular span
|
||||
for idx, wait_call in enumerate(mock_wait_calls):
|
||||
_, args, __ = wait_call
|
||||
if args[0] <= 0:
|
||||
after_calls = mock_wait_calls[idx + 1 :]
|
||||
break
|
||||
|
||||
self.assertTrue(
|
||||
all(args[0] >= 0.05 for _, args, __ in after_calls)
|
||||
)
|
||||
|
||||
span_processor.shutdown()
|
||||
|
||||
def test_span_processor_accepts_parent_context(self):
|
||||
span_processor = mock.Mock(
|
||||
wraps=datadog.DatadogExportSpanProcessor(self.exporter)
|
||||
|
@ -18,13 +18,11 @@ from opentelemetry import trace as trace_api
|
||||
from opentelemetry.exporter.datadog import constants, propagator
|
||||
from opentelemetry.sdk import trace
|
||||
from opentelemetry.trace import get_current_span, set_span_in_context
|
||||
from opentelemetry.trace.propagation.textmap import DictGetter
|
||||
|
||||
FORMAT = propagator.DatadogFormat()
|
||||
|
||||
|
||||
def get_as_list(dict_object, key):
|
||||
value = dict_object.get(key)
|
||||
return [value] if value is not None else []
|
||||
carrier_getter = DictGetter()
|
||||
|
||||
|
||||
class TestDatadogFormat(unittest.TestCase):
|
||||
@ -45,7 +43,7 @@ class TestDatadogFormat(unittest.TestCase):
|
||||
malformed_parent_id_key = FORMAT.PARENT_ID_KEY + "-x"
|
||||
context = get_current_span(
|
||||
FORMAT.extract(
|
||||
get_as_list,
|
||||
carrier_getter,
|
||||
{
|
||||
malformed_trace_id_key: self.serialized_trace_id,
|
||||
malformed_parent_id_key: self.serialized_parent_id,
|
||||
@ -63,7 +61,7 @@ class TestDatadogFormat(unittest.TestCase):
|
||||
FORMAT.PARENT_ID_KEY: self.serialized_parent_id,
|
||||
}
|
||||
|
||||
ctx = FORMAT.extract(get_as_list, carrier)
|
||||
ctx = FORMAT.extract(carrier_getter, carrier)
|
||||
span_context = get_current_span(ctx).get_span_context()
|
||||
self.assertEqual(span_context.trace_id, trace_api.INVALID_TRACE_ID)
|
||||
|
||||
@ -73,7 +71,7 @@ class TestDatadogFormat(unittest.TestCase):
|
||||
FORMAT.TRACE_ID_KEY: self.serialized_trace_id,
|
||||
}
|
||||
|
||||
ctx = FORMAT.extract(get_as_list, carrier)
|
||||
ctx = FORMAT.extract(carrier_getter, carrier)
|
||||
span_context = get_current_span(ctx).get_span_context()
|
||||
self.assertEqual(span_context.span_id, trace_api.INVALID_SPAN_ID)
|
||||
|
||||
@ -81,7 +79,7 @@ class TestDatadogFormat(unittest.TestCase):
|
||||
"""Test the propagation of Datadog headers."""
|
||||
parent_span_context = get_current_span(
|
||||
FORMAT.extract(
|
||||
get_as_list,
|
||||
carrier_getter,
|
||||
{
|
||||
FORMAT.TRACE_ID_KEY: self.serialized_trace_id,
|
||||
FORMAT.PARENT_ID_KEY: self.serialized_parent_id,
|
||||
@ -138,7 +136,7 @@ class TestDatadogFormat(unittest.TestCase):
|
||||
"""Test sampling priority rejected."""
|
||||
parent_span_context = get_current_span(
|
||||
FORMAT.extract(
|
||||
get_as_list,
|
||||
carrier_getter,
|
||||
{
|
||||
FORMAT.TRACE_ID_KEY: self.serialized_trace_id,
|
||||
FORMAT.PARENT_ID_KEY: self.serialized_parent_id,
|
||||
|
Reference in New Issue
Block a user