-
Notifications
You must be signed in to change notification settings - Fork 347
Report OTLP export status in tracer startup log #12062
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,141 @@ | ||
| package datadog.trace.core; | ||
|
|
||
| import static datadog.trace.api.config.OtlpConfig.LOGS_OTEL_ENABLED; | ||
| import static datadog.trace.api.config.OtlpConfig.LOGS_OTEL_EXPORTER; | ||
| import static datadog.trace.api.config.OtlpConfig.METRICS_OTEL_ENABLED; | ||
| import static datadog.trace.api.config.OtlpConfig.METRICS_OTEL_EXPORTER; | ||
| import static datadog.trace.api.config.OtlpConfig.OTEL_TRACES_SPAN_METRICS_ENABLED; | ||
| import static datadog.trace.api.config.OtlpConfig.TRACE_OTEL_EXPORTER; | ||
| import static datadog.trace.api.config.TracerConfig.WRITER_TYPE; | ||
| import static datadog.trace.bootstrap.instrumentation.api.WriterConstants.DD_AGENT_WRITER_TYPE; | ||
| import static org.junit.jupiter.api.Assertions.assertFalse; | ||
| import static org.junit.jupiter.api.Assertions.assertTrue; | ||
|
|
||
| import com.squareup.moshi.Moshi; | ||
| import datadog.trace.api.Config; | ||
| import datadog.trace.test.junit.utils.config.WithConfig; | ||
| import datadog.trace.test.util.DDJavaSpecification; | ||
| import java.io.IOException; | ||
| import java.util.Map; | ||
| import java.util.concurrent.TimeUnit; | ||
| import org.junit.jupiter.api.Test; | ||
| import org.junit.jupiter.api.Timeout; | ||
|
|
||
| @Timeout(value = 10, unit = TimeUnit.SECONDS) | ||
| public class StatusLoggerTest extends DDJavaSpecification { | ||
|
|
||
| @Test | ||
| void otlpExportDisabledByDefault() throws IOException { | ||
| Map<String, Object> startupLog = startupLog(); | ||
|
|
||
| assertFalse(flag(startupLog, "otlp_traces_export_enabled")); | ||
| assertFalse(flag(startupLog, "otlp_metrics_export_enabled")); | ||
| assertFalse(flag(startupLog, "otlp_logs_export_enabled")); | ||
| } | ||
|
|
||
| @Test | ||
| @WithConfig(key = TRACE_OTEL_EXPORTER, value = "otlp") | ||
| @WithConfig(key = METRICS_OTEL_ENABLED, value = "true") | ||
| @WithConfig(key = METRICS_OTEL_EXPORTER, value = "otlp") | ||
| @WithConfig(key = LOGS_OTEL_ENABLED, value = "true") | ||
| @WithConfig(key = LOGS_OTEL_EXPORTER, value = "otlp") | ||
| void otlpExportEnabledWhenConfigured() throws IOException { | ||
| Map<String, Object> startupLog = startupLog(); | ||
|
|
||
| assertTrue(flag(startupLog, "otlp_traces_export_enabled")); | ||
| assertTrue(flag(startupLog, "otlp_metrics_export_enabled")); | ||
| assertTrue(flag(startupLog, "otlp_logs_export_enabled")); | ||
| } | ||
|
|
||
| @Test | ||
| @WithConfig(key = TRACE_OTEL_EXPORTER, value = "otlp") | ||
| @WithConfig(key = METRICS_OTEL_EXPORTER, value = "otlp") | ||
| @WithConfig(key = LOGS_OTEL_EXPORTER, value = "otlp") | ||
| void metricsAndLogsRequireOtelSignalEnabled() throws IOException { | ||
| Map<String, Object> startupLog = startupLog(); | ||
|
|
||
| assertTrue(flag(startupLog, "otlp_traces_export_enabled")); | ||
| assertFalse(flag(startupLog, "otlp_metrics_export_enabled")); | ||
| assertFalse(flag(startupLog, "otlp_logs_export_enabled")); | ||
| } | ||
|
|
||
| @Test | ||
| @WithConfig(key = TRACE_OTEL_EXPORTER, value = "otlp") | ||
| @WithConfig(key = WRITER_TYPE, value = DD_AGENT_WRITER_TYPE) | ||
| void tracesNotExportedWhenWriterTypeOverridesOtlpExporter() throws IOException { | ||
| assertFalse(flag(startupLog(), "otlp_traces_export_enabled")); | ||
| } | ||
|
|
||
| @Test | ||
| @WithConfig(key = WRITER_TYPE, value = "MultiWriter:OtlpWriter,DDAgentWriter") | ||
| void tracesExportedWhenMultiWriterIncludesOtlpWriter() throws IOException { | ||
| assertTrue(flag(startupLog(), "otlp_traces_export_enabled")); | ||
| } | ||
|
|
||
| @Test | ||
| @WithConfig(key = WRITER_TYPE, value = "MultiWriter:DDAgentWriter,MultiWriter:OtlpWriter") | ||
| void tracesExportedWhenMultiWriterPrefixRepeats() throws IOException { | ||
| assertTrue(flag(startupLog(), "otlp_traces_export_enabled")); | ||
| } | ||
|
|
||
| @Test | ||
| @WithConfig(key = WRITER_TYPE, value = "MultiWriter:LoggingWriter,DDAgentWriter") | ||
| void tracesNotExportedWhenMultiWriterExcludesOtlpWriter() throws IOException { | ||
| assertFalse(flag(startupLog(), "otlp_traces_export_enabled")); | ||
| } | ||
|
|
||
| @Test | ||
| @WithConfig(key = WRITER_TYPE, value = "MultiWriter: OtlpWriter") | ||
| void tracesNotExportedWhenMultiWriterSubTypeIsPadded() throws IOException { | ||
| assertFalse(flag(startupLog(), "otlp_traces_export_enabled")); | ||
| } | ||
|
|
||
| @Test | ||
| @WithConfig(key = WRITER_TYPE, value = "MultiWriter:OtlpWriterExtra") | ||
| void tracesNotExportedWhenMultiWriterSubTypeOnlyPrefixesOtlpWriter() throws IOException { | ||
| assertFalse(flag(startupLog(), "otlp_traces_export_enabled")); | ||
| } | ||
|
|
||
| @Test | ||
| @WithConfig(key = WRITER_TYPE, value = "DDAgentWriter,OtlpWriter") | ||
| void tracesNotExportedWhenCommaSeparatedWithoutMultiWriterPrefix() throws IOException { | ||
| assertFalse(flag(startupLog(), "otlp_traces_export_enabled")); | ||
| } | ||
|
|
||
| @Test | ||
| @WithConfig(key = WRITER_TYPE, value = "TraceStructureWriter:/tmp/out,OtlpWriter") | ||
| void tracesNotExportedWhenTraceStructureWriterTakesPrecedence() throws IOException { | ||
| assertFalse(flag(startupLog(), "otlp_traces_export_enabled")); | ||
| } | ||
|
|
||
| @Test | ||
| @WithConfig(key = OTEL_TRACES_SPAN_METRICS_ENABLED, value = "true") | ||
| void metricsExportedWhenSpanMetricsEnabled() throws IOException { | ||
| assertTrue(flag(startupLog(), "otlp_metrics_export_enabled")); | ||
| } | ||
|
|
||
| @Test | ||
| @WithConfig(key = METRICS_OTEL_ENABLED, value = "true") | ||
| @WithConfig(key = METRICS_OTEL_EXPORTER, value = "otlp") | ||
| @WithConfig(key = OTEL_TRACES_SPAN_METRICS_ENABLED, value = "false") | ||
| void metricsExportedWhenOtelMetricsSignalEnabledWithoutSpanMetrics() throws IOException { | ||
| assertTrue(flag(startupLog(), "otlp_metrics_export_enabled")); | ||
| } | ||
|
|
||
| @SuppressWarnings("unchecked") | ||
| private static Map<String, Object> startupLog() throws IOException { | ||
| String json = | ||
| new Moshi.Builder() | ||
| .add(new StatusLogger()) | ||
| .build() | ||
| .adapter(Config.class) | ||
| .toJson(Config.get()); | ||
| return (Map<String, Object>) new Moshi.Builder().build().adapter(Object.class).fromJson(json); | ||
| } | ||
|
|
||
| private static boolean flag(Map<String, Object> startupLog, String name) { | ||
| Object value = startupLog.get(name); | ||
| assertTrue(value instanceof Boolean, name + " should be a boolean, was " + value); | ||
| return (Boolean) value; | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
|
|
@@ -727,6 +727,7 @@ | |||||
| import static datadog.trace.api.config.TracerConfig.WRITER_LINKS_INJECT; | ||||||
| import static datadog.trace.api.config.TracerConfig.WRITER_TYPE; | ||||||
| import static datadog.trace.api.telemetry.LogCollector.SEND_TELEMETRY; | ||||||
| import static datadog.trace.bootstrap.instrumentation.api.WriterConstants.MULTI_WRITER_TYPE; | ||||||
| import static datadog.trace.bootstrap.instrumentation.api.WriterConstants.OTLP_WRITER_TYPE; | ||||||
| import static datadog.trace.util.CollectionUtils.tryMakeImmutableList; | ||||||
| import static datadog.trace.util.CollectionUtils.tryMakeImmutableSet; | ||||||
|
|
@@ -828,6 +829,9 @@ public class Config { | |||||
| private static final int MAX_CODE_COVERAGE_FLAGS = 32; | ||||||
|
|
||||||
| private static final Pattern COLON = Pattern.compile(":"); | ||||||
| private static final Pattern COMMA = Pattern.compile(","); | ||||||
| private static final Pattern MULTI_WRITER_PREFIX = | ||||||
| Pattern.compile(MULTI_WRITER_TYPE + ":", Pattern.LITERAL); | ||||||
|
|
||||||
| // Historical conflating-Batch size; used to translate TRACER_METRICS_MAX_PENDING (configured in | ||||||
| // legacy batch units) into the new per-SpanSnapshot inbox capacity. | ||||||
|
|
@@ -5577,6 +5581,10 @@ public boolean isLogsOtlpExporterEnabled() { | |||||
| return "otlp".equalsIgnoreCase(logsOtelExporter); | ||||||
| } | ||||||
|
|
||||||
| public boolean isOtlpLogsExportEnabled() { | ||||||
| return isLogsOtelEnabled() && isLogsOtlpExporterEnabled(); | ||||||
| } | ||||||
|
|
||||||
| public int getLogsOtelInterval() { | ||||||
| return logsOtelInterval; | ||||||
| } | ||||||
|
|
@@ -5621,6 +5629,11 @@ public boolean isMetricsOtlpExporterEnabled() { | |||||
| return "otlp".equalsIgnoreCase(metricsOtelExporter); | ||||||
| } | ||||||
|
|
||||||
| public boolean isOtlpMetricsExportEnabled() { | ||||||
| return (isMetricsOtelEnabled() && isMetricsOtlpExporterEnabled()) | ||||||
| || isOtelTracesSpanMetricsEnabled(); | ||||||
| } | ||||||
|
|
||||||
| public boolean isMetricsOtelExperimentalEnabled() { | ||||||
| return metricsOtelExperimentalEnabled; | ||||||
| } | ||||||
|
|
@@ -5677,6 +5690,19 @@ public boolean isTraceOtlpExporterEnabled() { | |||||
| return "otlp".equalsIgnoreCase(traceOtelExporter); | ||||||
| } | ||||||
|
|
||||||
| public boolean isOtlpTracesExportEnabled() { | ||||||
| if (!writerType.startsWith(MULTI_WRITER_TYPE)) { | ||||||
| return OTLP_WRITER_TYPE.equals(writerType); | ||||||
| } | ||||||
| String multiWriterConfig = MULTI_WRITER_PREFIX.matcher(writerType).replaceAll(""); | ||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
saves needing the extra regex, which almost all the time will never be used. |
||||||
| for (String subWriterType : COMMA.split(multiWriterConfig)) { | ||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Given that almost all deployments will never reach this code, is it worth pre-compiling the regex and always taking that hit - rather than just using |
||||||
| if (OTLP_WRITER_TYPE.equals(subWriterType)) { | ||||||
| return true; | ||||||
| } | ||||||
| } | ||||||
| return false; | ||||||
| } | ||||||
|
|
||||||
| public String getOtlpTracesEndpoint() { | ||||||
| return otlpTracesEndpoint; | ||||||
| } | ||||||
|
|
||||||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This will never be used for most deployments, and is the same as dropping the same number of characters as the matched string (+ 1) from the string.