Skip to content

Commit 45f0cde

Browse files
authored
chore(otel): collect telemetry for log configs (#14409)
Adds teleemtry collection for the following configs: - OTEL_EXPORTER_OTLP_ENDPOINT - OTEL_EXPORTER_OTLP_HEADERS - OTEL_EXPORTER_OTLP_LOGS_HEADERS - OTEL_EXPORTER_OTLP_LOGS_PROTOCOL - OTEL_EXPORTER_OTLP_LOGS_TIMEOUT - OTEL_EXPORTER_OTLP_PROTOCOL - OTEL_EXPORTER_OTLP_TIMEOUT ## Checklist - [x] PR author has checked that all the criteria below are met - The PR description includes an overview of the change - The PR description articulates the motivation for the change - The change includes tests OR the PR description describes a testing strategy - The PR description notes risks associated with the change, if any - Newly-added code is easy to change - The change follows the [library release note guidelines](https://ddtrace.readthedocs.io/en/stable/releasenotes.html) - The change includes or references documentation updates if necessary - Backport labels are set (if [applicable](https://ddtrace.readthedocs.io/en/latest/contributing.html#backporting)) ## Reviewer Checklist - [x] Reviewer has checked that all the criteria below are met - Title is accurate - All changes are related to the pull request's stated goal - Avoids breaking [API](https://ddtrace.readthedocs.io/en/stable/versioning.html#interfaces) changes - Testing strategy adequately addresses listed risks - Newly-added code is easy to change - Release note makes sense to a user of the library - If necessary, author has acknowledged and discussed the performance implications of this PR as reported in the benchmarks PR comment - Backport labels are set in a manner that is consistent with the [release branch maintenance policy](https://ddtrace.readthedocs.io/en/latest/contributing.html#backporting)
1 parent 8f699cd commit 45f0cde

File tree

3 files changed

+107
-22
lines changed

3 files changed

+107
-22
lines changed

ddtrace/internal/opentelemetry/logs.py

Lines changed: 5 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,7 @@
1010
from ddtrace.internal.logger import get_logger
1111
from ddtrace.internal.telemetry import telemetry_writer
1212
from ddtrace.internal.telemetry.constants import TELEMETRY_NAMESPACE
13-
from ddtrace.settings._agent import get_agent_hostname
14-
from ddtrace.settings._opentelemetry import exporter_config
13+
from ddtrace.settings._opentelemetry import otel_config
1514

1615

1716
log = get_logger(__name__)
@@ -36,7 +35,7 @@ def set_otel_logs_provider() -> None:
3635
if resource is None:
3736
return
3837

39-
protocol = (exporter_config.OTLP_PROTOCOL or exporter_config.OTLP_LOGS_PROTOCOL or DEFAULT_PROTOCOL).lower()
38+
protocol = otel_config.exporter.LOGS_PROTOCOL
4039
exporter_class = _import_exporter(protocol)
4140
if exporter_class is None:
4241
return
@@ -180,13 +179,9 @@ def _initialize_logging(exporter_class, protocol, resource):
180179
try:
181180
from opentelemetry.sdk._configuration import _init_logging
182181

183-
if not exporter_config.OTLP_ENDPOINT and not exporter_config.OTLP_LOGS_ENDPOINT:
184-
if protocol in ("http/json", "http/protobuf"):
185-
endpoint = f"http://{get_agent_hostname()}:{HTTP_PORT}{HTTP_LOGS_ENDPOINT}"
186-
else:
187-
endpoint = f"http://{get_agent_hostname()}:{GRPC_PORT}"
188-
os.environ["OTEL_EXPORTER_OTLP_LOGS_ENDPOINT"] = endpoint
189-
182+
# Ensure logging exporter is configured to send payloads to a Datadog Agent.
183+
# The default endpoint is resolved using the hostname from DD_AGENT.. and DD_TRACE_AGENT_... configs
184+
os.environ["OTEL_EXPORTER_OTLP_LOGS_ENDPOINT"] = otel_config.exporter.LOGS_ENDPOINT
190185
_init_logging({protocol: exporter_class}, resource=resource)
191186
return True
192187
except ImportError as e:

ddtrace/settings/_opentelemetry.py

Lines changed: 59 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,69 @@
11
import typing as t
22

3+
from ddtrace.internal.telemetry import get_config
34
from ddtrace.internal.telemetry import report_configuration
5+
from ddtrace.settings._agent import get_agent_hostname
46
from ddtrace.settings._core import DDConfig
57

68

7-
class OpenTelemetryExporterConfig(DDConfig):
8-
__prefix__ = "otel.exporter"
9+
def _derive_endpoint(config: "ExporterConfig"):
10+
if config.PROTOCOL.lower() in ("http/json", "http/protobuf"):
11+
default_endpoint = (
12+
f"http://{get_agent_hostname()}:{ExporterConfig.HTTP_PORT}{ExporterConfig.HTTP_LOGS_ENDPOINT}"
13+
)
14+
else:
15+
default_endpoint = f"http://{get_agent_hostname()}:{ExporterConfig.GRPC_PORT}"
16+
return get_config("OTEL_EXPORTER_OTLP_ENDPOINT", default_endpoint)
917

10-
# OTLP exporter configuration
11-
OTLP_PROTOCOL = DDConfig.v(t.Optional[str], "otlp.protocol", default=None)
12-
OTLP_LOGS_PROTOCOL = DDConfig.v(t.Optional[str], "otlp.logs.protocol", default=None)
13-
OTLP_ENDPOINT = DDConfig.v(t.Optional[str], "otlp.endpoint", default=None)
14-
OTLP_LOGS_ENDPOINT = DDConfig.v(t.Optional[str], "otlp.logs.endpoint", default=None)
15-
OTLP_HEADERS = DDConfig.v(t.Optional[str], "otlp.headers", default=None)
16-
OTLP_LOGS_HEADERS = DDConfig.v(t.Optional[str], "otlp.logs.headers", default=None)
1718

19+
def _derive_logs_endpoint(config: "ExporterConfig"):
20+
if config.LOGS_PROTOCOL.lower() in ("http/json", "http/protobuf"):
21+
default_endpoint = (
22+
f"http://{get_agent_hostname()}:{ExporterConfig.HTTP_PORT}{ExporterConfig.HTTP_LOGS_ENDPOINT}"
23+
)
24+
else:
25+
default_endpoint = f"http://{get_agent_hostname()}:{ExporterConfig.GRPC_PORT}"
26+
return get_config(["OTEL_EXPORTER_OTLP_LOGS_ENDPOINT", "OTEL_EXPORTER_OTLP_ENDPOINT"], default_endpoint)
1827

19-
exporter_config = OpenTelemetryExporterConfig()
2028

21-
report_configuration(exporter_config)
29+
def _derive_logs_protocol(config: "ExporterConfig"):
30+
return get_config("OTEL_EXPORTER_OTLP_LOGS_PROTOCOL", config.PROTOCOL)
31+
32+
33+
def _derive_logs_headers(config: "ExporterConfig"):
34+
return get_config("OTEL_EXPORTER_OTLP_LOGS_HEADERS", config.HEADERS)
35+
36+
37+
def _derive_logs_timeout(config: "ExporterConfig"):
38+
return get_config("OTEL_EXPORTER_OTLP_LOGS_TIMEOUT", config.DEFAULT_TIMEOUT, int)
39+
40+
41+
class OpenTelemetryConfig(DDConfig):
42+
__prefix__ = "otel"
43+
44+
45+
class ExporterConfig(DDConfig):
46+
__prefix__ = "exporter"
47+
48+
GRPC_PORT: int = 4317
49+
HTTP_PORT: int = 4318
50+
HTTP_LOGS_ENDPOINT: str = "/v1/logs"
51+
DEFAULT_HEADERS: str = ""
52+
DEFAULT_TIMEOUT: int = 10000
53+
54+
PROTOCOL = DDConfig.v(t.Optional[str], "otlp.protocol", default="grpc")
55+
ENDPOINT = DDConfig.d(str, _derive_endpoint)
56+
HEADERS = DDConfig.v(str, "otlp.headers", default=DEFAULT_HEADERS)
57+
TIMEOUT = DDConfig.v(int, "otlp.timeout", default=DEFAULT_TIMEOUT)
58+
59+
LOGS_PROTOCOL = DDConfig.d(str, _derive_logs_protocol)
60+
LOGS_ENDPOINT = DDConfig.d(str, _derive_logs_endpoint)
61+
LOGS_HEADERS = DDConfig.d(str, _derive_logs_headers)
62+
LOGS_TIMEOUT = DDConfig.d(int, _derive_logs_timeout)
63+
64+
65+
OpenTelemetryConfig.include(ExporterConfig, namespace="exporter")
66+
67+
otel_config = OpenTelemetryConfig()
68+
69+
report_configuration(otel_config)

tests/telemetry/test_writer.py

Lines changed: 43 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -270,6 +270,8 @@ def test_app_started_event_configuration_override(test_agent_session, run_python
270270
env["DD_TRACE_WRITER_REUSE_CONNECTIONS"] = "True"
271271
env["DD_TAGS"] = "team:apm,component:web"
272272
env["DD_INSTRUMENTATION_CONFIG_ID"] = "abcedf123"
273+
env["DD_LOGS_OTEL_ENABLED"] = "True"
274+
env["OTEL_EXPORTER_OTLP_ENDPOINT"] = "http://localhost:4317"
273275

274276
file = tmpdir.join("moon_ears.json")
275277
file.write('[{"service":"xy?","name":"a*c"}]')
@@ -424,7 +426,7 @@ def test_app_started_event_configuration_override(test_agent_session, run_python
424426
{"name": "DD_LLMOBS_ML_APP", "origin": "default", "value": None},
425427
{"name": "DD_LLMOBS_SAMPLE_RATE", "origin": "default", "value": 1.0},
426428
{"name": "DD_LOGS_INJECTION", "origin": "env_var", "value": True},
427-
{"name": "DD_LOGS_OTEL_ENABLED", "origin": "default", "value": False},
429+
{"name": "DD_LOGS_OTEL_ENABLED", "origin": "env_var", "value": True},
428430
{"name": "DD_METRICS_OTEL_ENABLED", "origin": "default", "value": False},
429431
{"name": "DD_PROFILING_AGENTLESS", "origin": "default", "value": False},
430432
{"name": "DD_PROFILING_API_TIMEOUT", "origin": "default", "value": 10.0},
@@ -532,6 +534,46 @@ def test_app_started_event_configuration_override(test_agent_session, run_python
532534
{"name": "DD_USER_MODEL_LOGIN_FIELD", "origin": "default", "value": ""},
533535
{"name": "DD_USER_MODEL_NAME_FIELD", "origin": "default", "value": ""},
534536
{"name": "DD_VERSION", "origin": "default", "value": None},
537+
{
538+
"name": "OTEL_EXPORTER_OTLP_ENDPOINT",
539+
"origin": "env_var",
540+
"value": "http://localhost:4317",
541+
},
542+
{
543+
"name": "OTEL_EXPORTER_OTLP_HEADERS",
544+
"origin": "default",
545+
"value": "",
546+
},
547+
{
548+
"name": "OTEL_EXPORTER_OTLP_LOGS_ENDPOINT",
549+
"origin": "env_var",
550+
"value": "http://localhost:4317",
551+
},
552+
{
553+
"name": "OTEL_EXPORTER_OTLP_LOGS_HEADERS",
554+
"origin": "default",
555+
"value": "",
556+
},
557+
{
558+
"name": "OTEL_EXPORTER_OTLP_LOGS_PROTOCOL",
559+
"origin": "default",
560+
"value": "grpc",
561+
},
562+
{
563+
"name": "OTEL_EXPORTER_OTLP_LOGS_TIMEOUT",
564+
"origin": "default",
565+
"value": 10000,
566+
},
567+
{
568+
"name": "OTEL_EXPORTER_OTLP_PROTOCOL",
569+
"origin": "default",
570+
"value": "grpc",
571+
},
572+
{
573+
"name": "OTEL_EXPORTER_OTLP_TIMEOUT",
574+
"origin": "default",
575+
"value": 10000,
576+
},
535577
{"name": "_DD_APPSEC_DEDUPLICATION_ENABLED", "origin": "default", "value": True},
536578
{"name": "_DD_IAST_LAZY_TAINT", "origin": "default", "value": False},
537579
{"name": "_DD_IAST_USE_ROOT_SPAN", "origin": "default", "value": False},

0 commit comments

Comments
 (0)