-
Notifications
You must be signed in to change notification settings - Fork 650
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
7c2ceba
commit e3a3619
Showing
10 changed files
with
468 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
Datadog Exporter Example | ||
======================= | ||
|
||
This example shows how to use OpenTelemetry to send tracing data to Datadog. | ||
|
||
Installation | ||
------------ | ||
|
||
.. code-block:: sh | ||
pip install opentelemetry-api | ||
pip install opentelemetry-sdk | ||
pip install opentelemetry-ext-datadog | ||
Run the Example | ||
--------------- | ||
|
||
* Start Datadog Agent | ||
|
||
.. code-block:: sh | ||
docker run -d -v /var/run/docker.sock:/var/run/docker.sock:ro \ | ||
-v /proc/:/host/proc/:ro \ | ||
-v /sys/fs/cgroup/:/host/sys/fs/cgroup:ro \ | ||
-p 127.0.0.1:8126:8126/tcp \ | ||
-e DD_API_KEY="<DATADOG_API_KEY>" \ | ||
-e DD_APM_ENABLED=true \ | ||
datadog/agent:latest | ||
* Run the example | ||
|
||
.. code-block:: sh | ||
python datadog_exporter.py | ||
The traces will be available at http://datadoghq.com/. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
#!/usr/bin/env python3 | ||
# | ||
# Copyright The OpenTelemetry Authors | ||
# | ||
# Licensed under the Apache License, Version 2.0 (the "License"); | ||
# you may not use this file except in compliance with the License. | ||
# You may obtain a copy of the License at | ||
# | ||
# http://www.apache.org/licenses/LICENSE-2.0 | ||
# | ||
# Unless required by applicable law or agreed to in writing, software | ||
# distributed under the License is distributed on an "AS IS" BASIS, | ||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
# See the License for the specific language governing permissions and | ||
# limitations under the License. | ||
import os | ||
|
||
from opentelemetry import trace | ||
from opentelemetry.ext.datadog import DatadogSpanExporter | ||
from opentelemetry.sdk.trace import TracerProvider | ||
from opentelemetry.sdk.trace.export import BatchExportSpanProcessor | ||
|
||
trace.set_tracer_provider(TracerProvider()) | ||
tracer = trace.get_tracer(__name__) | ||
|
||
exporter = DatadogSpanExporter(agent_url="http://localhost:8126") | ||
|
||
span_processor = BatchExportSpanProcessor(exporter) | ||
trace.get_tracer_provider().add_span_processor(span_processor) | ||
|
||
with tracer.start_as_current_span("foo"): | ||
with tracer.start_as_current_span("bar"): | ||
with tracer.start_as_current_span("baz"): | ||
print("Hello world from OpenTelemetry Python!") |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
OpenTelemetry Datadog Exporter | ||
============================== | ||
|
||
This library allows to export tracing data to `Datadog <https://www.datadoghq.com/>`_. | ||
|
||
Installation | ||
------------ | ||
|
||
.. code-block:: sh | ||
pip install opentelemetry-ext-datadog | ||
.. _Datadog: https://www.datadoghq.com/ | ||
.. _OpenTelemetry: https://github.com/open-telemetry/opentelemetry-python/ | ||
|
||
|
||
References | ||
---------- | ||
|
||
* `Datadog <https://www.datadoghq.com/>`_ | ||
* `OpenTelemetry Project <https://opentelemetry.io/>`_ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
# Copyright The OpenTelemetry Authors | ||
# | ||
# Licensed under the Apache License, Version 2.0 (the "License"); | ||
# you may not use this file except in compliance with the License. | ||
# You may obtain a copy of the License at | ||
# | ||
# http://www.apache.org/licenses/LICENSE-2.0 | ||
# | ||
# Unless required by applicable law or agreed to in writing, software | ||
# distributed under the License is distributed on an "AS IS" BASIS, | ||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
# See the License for the specific language governing permissions and | ||
# limitations under the License. | ||
# | ||
[metadata] | ||
name = opentelemetry-ext-datadog | ||
description = Datadog Exporter for OpenTelemetry | ||
long_description = file: README.rst | ||
long_description_content_type = text/x-rst | ||
author = OpenTelemetry Authors | ||
author_email = cncf-opentelemetry-contributors@lists.cncf.io | ||
url = https://github.com/open-telemetry/opentelemetry-python/ext/opentelemetry-ext-datadog | ||
platforms = any | ||
license = Apache-2.0 | ||
classifiers = | ||
Development Status :: 4 - Beta | ||
Intended Audience :: Developers | ||
License :: OSI Approved :: Apache Software License | ||
Programming Language :: Python | ||
Programming Language :: Python :: 3 | ||
Programming Language :: Python :: 3.5 | ||
Programming Language :: Python :: 3.6 | ||
Programming Language :: Python :: 3.7 | ||
Programming Language :: Python :: 3.8 | ||
|
||
[options] | ||
python_requires = >=3.5 | ||
package_dir= | ||
=src | ||
packages=find_namespace: | ||
install_requires = | ||
opentelemetry-api | ||
opentelemetry-sdk | ||
ddtrace | ||
|
||
[options.packages.find] | ||
where = src |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
# Copyright The OpenTelemetry Authors | ||
# | ||
# Licensed under the Apache License, Version 2.0 (the "License"); | ||
# you may not use this file except in compliance with the License. | ||
# You may obtain a copy of the License at | ||
# | ||
# http://www.apache.org/licenses/LICENSE-2.0 | ||
# | ||
# Unless required by applicable law or agreed to in writing, software | ||
# distributed under the License is distributed on an "AS IS" BASIS, | ||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
# See the License for the specific language governing permissions and | ||
# limitations under the License. | ||
import os | ||
|
||
import setuptools | ||
|
||
BASE_DIR = os.path.dirname(__file__) | ||
VERSION_FILENAME = os.path.join( | ||
BASE_DIR, "src", "opentelemetry", "ext", "datadog", "version.py" | ||
) | ||
PACKAGE_INFO = {} | ||
with open(VERSION_FILENAME) as f: | ||
exec(f.read(), PACKAGE_INFO) | ||
|
||
setuptools.setup(version=PACKAGE_INFO["__version__"]) |
153 changes: 153 additions & 0 deletions
153
ext/opentelemetry-ext-datadog/src/opentelemetry/ext/datadog/__init__.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,153 @@ | ||
import logging | ||
import os | ||
from urllib.parse import urlparse | ||
|
||
from ddtrace.encoding import MsgpackEncoder | ||
from ddtrace.internal.writer import AgentWriter | ||
from ddtrace.span import Span as DatadogSpan | ||
|
||
import opentelemetry.trace as trace_api | ||
from opentelemetry.sdk.trace import Span | ||
from opentelemetry.sdk.trace.export import SpanExporter, SpanExportResult | ||
from opentelemetry.trace.status import StatusCanonicalCode | ||
|
||
log = logging.getLogger(__name__) | ||
|
||
|
||
DEFAULT_AGENT_URL = os.environ.get( | ||
"DD_TRACE_AGENT_URL", "http://localhost:8126" | ||
) | ||
|
||
|
||
class DatadogSpanExporter(SpanExporter): | ||
def __init__( | ||
self, agent_url=DEFAULT_AGENT_URL, | ||
): | ||
self.agent_url = agent_url | ||
self._agent_writer = None | ||
|
||
@property | ||
def agent_writer(self): | ||
if self._agent_writer is None: | ||
url_parsed = urlparse(self.agent_url) | ||
if url_parsed.scheme in ("http", "https"): | ||
self._agent_writer = AgentWriter( | ||
hostname=url_parsed.hostname, | ||
port=url_parsed.port, | ||
https=url_parsed.scheme == "https", | ||
) | ||
elif url_parsed.scheme == "unix": | ||
self._agent_writer = AgentWriter(uds_path=url_parsed.path) | ||
else: | ||
raise ValueError( | ||
"Unknown scheme `%s` for agent URL" % url_parsed.scheme | ||
) | ||
return self._agent_writer | ||
|
||
def export(self, spans): | ||
datadog_spans = _translate_to_datadog(spans) | ||
|
||
self.agent_writer.write(spans=datadog_spans) | ||
|
||
return SpanExportResult.SUCCESS | ||
|
||
def shutdown(self): | ||
if self.agent_writer.started: | ||
self.agent_writer.stop() | ||
self.agent_writer.join(self.agent_writer.exit_timeout) | ||
|
||
|
||
def _translate_to_datadog(spans): | ||
datadog_spans = [] | ||
|
||
for span in spans: | ||
trace_id, parent_id, span_id = _get_trace_ids(span) | ||
|
||
span_name = span.name | ||
|
||
# TODO: Handle span service and resource | ||
service = _get_service_name(span) | ||
resource = _get_resource_name(span) | ||
|
||
# TODO: Add span type | ||
_ = _get_span_type(span) | ||
|
||
start_ns = span.start_time | ||
duration_ns = span.end_time - span.start_time | ||
|
||
error = ( | ||
1 | ||
if span.status.canonical_code is not StatusCanonicalCode.OK | ||
else 0 | ||
) | ||
|
||
# TODO: Add span tags | ||
# TODO: Add exception info | ||
|
||
# datadog Span is initialized with a reference to the tracer which is | ||
# used to record the span when it is finished. We can skip ignore this | ||
# because we are not calling the finish method and explictly set the | ||
# duration. | ||
tracer = None | ||
|
||
datadog_span = DatadogSpan( | ||
tracer, | ||
span_name, | ||
service=service, | ||
resource=resource, | ||
trace_id=trace_id, | ||
span_id=span_id, | ||
parent_id=parent_id, | ||
) | ||
datadog_span.start_ns = start_ns | ||
datadog_span.error = error | ||
datadog_span.duration_ns = duration_ns | ||
datadog_spans.append(datadog_span) | ||
|
||
return datadog_spans | ||
|
||
|
||
def _get_trace_ids(span): | ||
ctx = span.get_context() | ||
trace_id = ctx.trace_id | ||
span_id = ctx.span_id | ||
|
||
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 | ||
else: | ||
parent_id = 0 | ||
|
||
trace_id = _convert_trace_id_uint64(trace_id) | ||
|
||
return trace_id, parent_id, span_id | ||
|
||
|
||
def _convert_trace_id_uint64(otel_id): | ||
raw = otel_id.to_bytes(16, "big") | ||
return int.from_bytes(raw[8:], byteorder="big") | ||
|
||
|
||
def _get_service_name(span): | ||
return ( | ||
span.resource.labels.get("service.name") | ||
if getattr(span, "resource") is not None | ||
else "service" | ||
) | ||
|
||
|
||
def _get_resource_name(span): | ||
return ( | ||
span.attributes.get("resource.name") | ||
if span.attributes.get("resource.name") | ||
else span.name | ||
) | ||
|
||
|
||
def _get_span_type(span): | ||
return ( | ||
span.attributes.get("span.type") | ||
if span.attributes.get("span.type") | ||
else span.name | ||
) |
16 changes: 16 additions & 0 deletions
16
ext/opentelemetry-ext-datadog/src/opentelemetry/ext/datadog/version.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
# Copyright 2019, OpenCensus Authors | ||
# Copyright The OpenTelemetry Authors | ||
# | ||
# Licensed under the Apache License, Version 2.0 (the "License"); | ||
# you may not use this file except in compliance with the License. | ||
# You may obtain a copy of the License at | ||
# | ||
# http://www.apache.org/licenses/LICENSE-2.0 | ||
# | ||
# Unless required by applicable law or agreed to in writing, software | ||
# distributed under the License is distributed on an "AS IS" BASIS, | ||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
# See the License for the specific language governing permissions and | ||
# limitations under the License. | ||
|
||
__version__ = "0.7.dev0" |
Empty file.
Oops, something went wrong.