Skip to content

Commit e12520d

Browse files
Fix Dynatrace Exported to Generate DELTA Temporality (#174)
The Dynatrace OTel metrics API requires DELTA temporality, since CUMULATIVE is currently unsupported. This change will allow configuration of the temporality via `otel.exporter.dynatrace.metrics.temporality.preference` This config now defaults to "delta" instead to the hard-coded "cumulative" before. Usually, no configuration is required. Signed-off-by: Karsten Schnitter <[email protected]> Co-authored-by: Anika Solanka <[email protected]>
1 parent 9c22c17 commit e12520d

File tree

1 file changed

+39
-17
lines changed

1 file changed

+39
-17
lines changed

cf-java-logging-support-opentelemetry-agent-extension/src/main/java/com/sap/hcf/cf/logging/opentelemetry/agent/ext/exporter/DynatraceMetricsExporterProvider.java

Lines changed: 39 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
import io.pivotal.cfenv.core.CfService;
1717

1818
import java.time.Duration;
19+
import java.util.Locale;
1920
import java.util.function.Function;
2021
import java.util.logging.Logger;
2122

@@ -46,20 +47,39 @@ private static Duration getTimeOut(ConfigProperties config) {
4647
return timeout != null ? timeout : config.getDuration("otel.exporter.dynatrace.timeout");
4748
}
4849

50+
private static AggregationTemporalitySelector getAggregationTemporalitySelector(ConfigProperties config) {
51+
String temporalityStr = config.getString("otel.exporter.dynatrace.metrics.temporality.preference");
52+
if (temporalityStr == null) {
53+
return AggregationTemporalitySelector.deltaPreferred();
54+
}
55+
AggregationTemporalitySelector temporalitySelector;
56+
switch (temporalityStr.toLowerCase(Locale.ROOT)) {
57+
case "cumulative":
58+
return AggregationTemporalitySelector.alwaysCumulative();
59+
case "delta":
60+
return AggregationTemporalitySelector.deltaPreferred();
61+
case "lowmemory":
62+
return AggregationTemporalitySelector.lowMemory();
63+
default:
64+
throw new ConfigurationException("Unrecognized aggregation temporality: " + temporalityStr);
65+
}
66+
}
67+
4968
private static DefaultAggregationSelector getDefaultAggregationSelector(ConfigProperties config) {
5069
String defaultHistogramAggregation =
5170
config.getString("otel.exporter.dynatrace.metrics.default.histogram.aggregation");
5271
if (defaultHistogramAggregation == null) {
53-
return DefaultAggregationSelector.getDefault().with(InstrumentType.HISTOGRAM, Aggregation.defaultAggregation());
72+
return DefaultAggregationSelector.getDefault()
73+
.with(InstrumentType.HISTOGRAM, Aggregation.defaultAggregation());
5474
}
5575
if (AggregationUtil.aggregationName(Aggregation.base2ExponentialBucketHistogram())
56-
.equalsIgnoreCase(defaultHistogramAggregation)) {
57-
return
58-
DefaultAggregationSelector.getDefault()
59-
.with(InstrumentType.HISTOGRAM, Aggregation.base2ExponentialBucketHistogram());
76+
.equalsIgnoreCase(defaultHistogramAggregation)) {
77+
return DefaultAggregationSelector.getDefault().with(InstrumentType.HISTOGRAM,
78+
Aggregation.base2ExponentialBucketHistogram());
6079
} else if (AggregationUtil.aggregationName(explicitBucketHistogram())
61-
.equalsIgnoreCase(defaultHistogramAggregation)) {
62-
return DefaultAggregationSelector.getDefault().with(InstrumentType.HISTOGRAM, Aggregation.explicitBucketHistogram());
80+
.equalsIgnoreCase(defaultHistogramAggregation)) {
81+
return DefaultAggregationSelector.getDefault()
82+
.with(InstrumentType.HISTOGRAM, Aggregation.explicitBucketHistogram());
6383
} else {
6484
throw new ConfigurationException(
6585
"Unrecognized default histogram aggregation: " + defaultHistogramAggregation);
@@ -83,16 +103,19 @@ public MetricExporter createExporter(ConfigProperties config) {
83103
return NoopMetricExporter.getInstance();
84104
}
85105

86-
LOG.info("Creating metrics exporter for service binding " + cfService.getName() + " (" + cfService.getLabel() + ")");
106+
LOG.info(
107+
"Creating metrics exporter for service binding " + cfService.getName() + " (" + cfService.getLabel() + ")");
87108

88109
String apiUrl = cfService.getCredentials().getString(CRED_DYNATRACE_APIURL);
89110
if (isBlank(apiUrl)) {
90-
LOG.warning("Credential \"" + CRED_DYNATRACE_APIURL + "\" not found. Skipping dynatrace exporter configuration");
111+
LOG.warning(
112+
"Credential \"" + CRED_DYNATRACE_APIURL + "\" not found. Skipping dynatrace exporter configuration");
91113
return NoopMetricExporter.getInstance();
92114
}
93115
String tokenName = config.getString("otel.javaagent.extension.sap.cf.binding.dynatrace.metrics.token-name");
94116
if (isBlank(tokenName)) {
95-
LOG.warning("Configuration \"otel.javaagent.extension.sap.cf.binding.dynatrace.metrics.token-name\" not found. Skipping dynatrace exporter configuration");
117+
LOG.warning(
118+
"Configuration \"otel.javaagent.extension.sap.cf.binding.dynatrace.metrics.token-name\" not found. Skipping dynatrace exporter configuration");
96119
return NoopMetricExporter.getInstance();
97120
}
98121
String apiToken = cfService.getCredentials().getString(tokenName);
@@ -102,19 +125,18 @@ public MetricExporter createExporter(ConfigProperties config) {
102125
}
103126

104127
OtlpHttpMetricExporterBuilder builder = OtlpHttpMetricExporter.builder();
105-
builder.setEndpoint(apiUrl + DT_APIURL_METRICS_SUFFIX)
106-
.setCompression(getCompression(config))
107-
.addHeader("Authorization", "Api-Token " + apiToken)
108-
.setRetryPolicy(RetryPolicy.getDefault())
109-
.setAggregationTemporalitySelector(AggregationTemporalitySelector.alwaysCumulative())
110-
.setDefaultAggregationSelector(getDefaultAggregationSelector(config));
128+
builder.setEndpoint(apiUrl + DT_APIURL_METRICS_SUFFIX).setCompression(getCompression(config))
129+
.addHeader("Authorization", "Api-Token " + apiToken).setRetryPolicy(RetryPolicy.getDefault())
130+
.setAggregationTemporalitySelector(getAggregationTemporalitySelector(config))
131+
.setDefaultAggregationSelector(getDefaultAggregationSelector(config));
111132

112133
Duration timeOut = getTimeOut(config);
113134
if (timeOut != null) {
114135
builder.setTimeout(timeOut);
115136
}
116137

117-
LOG.info("Created metrics exporter for service binding " + cfService.getName() + " (" + cfService.getLabel() + ")");
138+
LOG.info(
139+
"Created metrics exporter for service binding " + cfService.getName() + " (" + cfService.getLabel() + ")");
118140
return builder.build();
119141
}
120142

0 commit comments

Comments
 (0)