Add properties for Dynatrace metrics API v2 ingest with Micrometer

This commit is contained in:
Georg Pirklbauer 2021-04-19 10:33:10 +02:00 committed by Andy Wilkinson
parent 6f0b23502e
commit 3161164912
4 changed files with 230 additions and 7 deletions

View File

@ -16,6 +16,10 @@
package org.springframework.boot.actuate.autoconfigure.metrics.export.dynatrace;
import java.util.Map;
import io.micrometer.dynatrace.DynatraceApiVersion;
import org.springframework.boot.actuate.autoconfigure.metrics.export.properties.StepRegistryProperties;
import org.springframework.boot.context.properties.ConfigurationProperties;
@ -24,39 +28,79 @@ import org.springframework.boot.context.properties.ConfigurationProperties;
* metrics export.
*
* @author Andy Wilkinson
* @author Georg Pirklbauer
* @since 2.1.0
*/
@ConfigurationProperties(prefix = "management.metrics.export.dynatrace")
public class DynatraceProperties extends StepRegistryProperties {
/**
* The Dynatrace metrics API version that metrics should be sent to. Defaults to v1.
* Required to define which API is used for export.
*/
private DynatraceApiVersion apiVersion = DynatraceApiVersion.V1;
/**
* Dynatrace authentication token.
*
* API v1: required, API v2: optional
*/
private String apiToken;
/**
* ID of the custom device that is exporting metrics to Dynatrace.
*
* API v1: required, API v2: not applicable (ignored)
*/
private String deviceId;
/**
* Technology type for exported metrics. Used to group metrics under a logical
* technology name in the Dynatrace UI.
*
* API v1: required, API v2: not applicable (ignored)
*/
private String technologyType = "java";
/**
* URI to ship metrics to. Should be used for SaaS, self managed instances or to
* en-route through an internal proxy.
*
* API v1: required, API v2: optional
*/
private String uri;
/**
* Group for exported metrics. Used to specify custom device group name in the
* Dynatrace UI.
*
* API v1: required, API v2: not applicable (ignored)
*/
private String group;
/**
* An optional prefix string that is added to all metrics exported.
*
* API v1: not applicable (ignored), API v2: optional
*/
private String metricKeyPrefix;
/**
* An optional Boolean that allows enabling of the Dynatrace metadata export. On by
* default.
*
* API v1: not applicable (ignored), API v2: optional
*/
private Boolean enrichWithDynatraceMetadata = true;
/**
* Optional default dimensions that are added to all metrics in the form of key-value
* pairs. These are overwritten by Micrometer tags if they use the same key.
*
* API v1: not applicable (ignored), API v2: optional
*/
private Map<String, String> defaultDimensions;
public String getApiToken() {
return this.apiToken;
}
@ -97,4 +141,36 @@ public class DynatraceProperties extends StepRegistryProperties {
this.group = group;
}
public String getMetricKeyPrefix() {
return this.metricKeyPrefix;
}
public void setMetricKeyPrefix(String metricKeyPrefix) {
this.metricKeyPrefix = metricKeyPrefix;
}
public Boolean getEnrichWithDynatraceMetadata() {
return this.enrichWithDynatraceMetadata;
}
public void setEnrichWithDynatraceMetadata(Boolean enrichWithDynatraceMetadata) {
this.enrichWithDynatraceMetadata = enrichWithDynatraceMetadata;
}
public Map<String, String> getDefaultDimensions() {
return this.defaultDimensions;
}
public void setDefaultDimensions(Map<String, String> defaultDimensions) {
this.defaultDimensions = defaultDimensions;
}
public DynatraceApiVersion getApiVersion() {
return this.apiVersion;
}
public void setApiVersion(DynatraceApiVersion apiVersion) {
this.apiVersion = apiVersion;
}
}

View File

@ -16,6 +16,9 @@
package org.springframework.boot.actuate.autoconfigure.metrics.export.dynatrace;
import java.util.Map;
import io.micrometer.dynatrace.DynatraceApiVersion;
import io.micrometer.dynatrace.DynatraceConfig;
import org.springframework.boot.actuate.autoconfigure.metrics.export.properties.StepRegistryPropertiesConfigAdapter;
@ -24,6 +27,7 @@ import org.springframework.boot.actuate.autoconfigure.metrics.export.properties.
* Adapter to convert {@link DynatraceProperties} to a {@link DynatraceConfig}.
*
* @author Andy Wilkinson
* @author Georg Pirklbauer
*/
class DynatracePropertiesConfigAdapter extends StepRegistryPropertiesConfigAdapter<DynatraceProperties>
implements DynatraceConfig {
@ -62,4 +66,24 @@ class DynatracePropertiesConfigAdapter extends StepRegistryPropertiesConfigAdapt
return get(DynatraceProperties::getGroup, DynatraceConfig.super::group);
}
@Override
public DynatraceApiVersion apiVersion() {
return get(DynatraceProperties::getApiVersion, DynatraceConfig.super::apiVersion);
}
@Override
public String metricKeyPrefix() {
return get(DynatraceProperties::getMetricKeyPrefix, DynatraceConfig.super::metricKeyPrefix);
}
@Override
public Map<String, String> defaultDimensions() {
return get(DynatraceProperties::getDefaultDimensions, DynatraceConfig.super::defaultDimensions);
}
@Override
public boolean enrichWithDynatraceMetadata() {
return get(DynatraceProperties::getEnrichWithDynatraceMetadata,
DynatraceConfig.super::enrichWithDynatraceMetadata);
}
}

View File

@ -16,6 +16,9 @@
package org.springframework.boot.actuate.autoconfigure.metrics.export.dynatrace;
import java.util.HashMap;
import io.micrometer.dynatrace.DynatraceApiVersion;
import org.junit.jupiter.api.Test;
import static org.assertj.core.api.Assertions.assertThat;
@ -24,6 +27,7 @@ import static org.assertj.core.api.Assertions.assertThat;
* Tests for {@link DynatracePropertiesConfigAdapter}.
*
* @author Andy Wilkinson
* @author Georg Pirklbauer
*/
class DynatracePropertiesConfigAdapterTests {
@ -62,4 +66,54 @@ class DynatracePropertiesConfigAdapterTests {
assertThat(new DynatracePropertiesConfigAdapter(properties).group()).isEqualTo("group-1");
}
@Test
void whenPropertiesApiVersionIsSetAdapterGroupReturnsIt() {
DynatraceProperties properties = new DynatraceProperties();
properties.setApiVersion(DynatraceApiVersion.V1);
assertThat(new DynatracePropertiesConfigAdapter(properties).apiVersion()).isSameAs(DynatraceApiVersion.V1);
}
@Test
void whenPropertiesMetricKeyPrefixIsSetAdapterGroupReturnsIt() {
DynatraceProperties properties = new DynatraceProperties();
properties.setMetricKeyPrefix("my.prefix");
assertThat(new DynatracePropertiesConfigAdapter(properties).metricKeyPrefix()).isEqualTo("my.prefix");
}
@Test
void whenPropertiesEnrichWithOneAgentMetadataIsSetAdapterGroupReturnsIt() {
DynatraceProperties properties = new DynatraceProperties();
properties.setEnrichWithDynatraceMetadata(true);
assertThat(new DynatracePropertiesConfigAdapter(properties).enrichWithDynatraceMetadata()).isTrue();
}
@Test
void whenPropertiesDefaultDimensionsIsSetAdapterGroupReturnsIt() {
DynatraceProperties properties = new DynatraceProperties();
HashMap<String, String> defaultDimensions = new HashMap<String, String>() {
{
put("dim1", "value1");
put("dim2", "value2");
}
};
properties.setDefaultDimensions(defaultDimensions);
assertThat(new DynatracePropertiesConfigAdapter(properties).defaultDimensions())
.containsExactlyEntriesOf(defaultDimensions);
}
@Test
void defaultValues() {
DynatraceProperties properties = new DynatraceProperties();
assertThat(properties.getApiToken()).isNull();
assertThat(properties.getDeviceId()).isNull();
assertThat(properties.getTechnologyType()).isEqualTo("java");
assertThat(properties.getUri()).isNull();
assertThat(properties.getGroup()).isNull();
assertThat(properties.getApiVersion()).isSameAs(DynatraceApiVersion.V1);
assertThat(properties.getMetricKeyPrefix()).isNull();
assertThat(properties.getEnrichWithDynatraceMetadata()).isTrue();
assertThat(properties.getDefaultDimensions()).isNull();
}
}

View File

@ -147,8 +147,15 @@ You can also change the interval at which metrics are sent to Datadog:
[[actuator.metrics.export.dynatrace]]
==== Dynatrace
Dynatrace registry pushes metrics to the configured URI periodically.
To export metrics to {micrometer-registry-docs}/dynatrace[Dynatrace], your API token, device ID, and URI must be provided:
Dynatrace offers two metrics ingest APIs, both of which are implemented for {micrometer-registry-docs}/dynatrace[Micrometer]:
[[actuator.metrics.export.dynatrace.api-v2]]
===== API v2
The API v2 can be used in two ways:
If a local OneAgent is running on the host, it is enough to set the API version to v2 and metrics will be automatically exported to the https://www.dynatrace.com/support/help/how-to-use-dynatrace/metrics/metric-ingestion/ingestion-methods/local-api/[local OneAgent ingest endpoint], which forwards them to the Dynatrace backend:
[source,yaml,indent=0,subs="verbatim",configprops,configblocks]
----
@ -156,12 +163,74 @@ To export metrics to {micrometer-registry-docs}/dynatrace[Dynatrace], your API t
metrics:
export:
dynatrace:
api-token: "YOUR_TOKEN"
device-id: "YOUR_DEVICE_ID"
uri: "YOUR_URI"
api-version: "v2"
----
You can also change the interval at which metrics are sent to Dynatrace:
If no local OneAgent is running, the endpoint of the https://www.dynatrace.com/support/help/dynatrace-api/environment-api/metric-v2/post-ingest-metrics/[Metrics API v2] and an API token are required.
The https://www.dynatrace.com/support/help/dynatrace-api/basics/dynatrace-api-authentication/[API token] must have the "Ingest metrics" (`metrics.ingest`) permission set.
It is recommended to limit scope to only this one permission.
Please ensure that the endpoint URI contains the path (e.g. `/api/v2/metrics/ingest`).
[source,yaml,indent=0,subs="verbatim",configprops,configblocks]
----
management:
metrics:
export:
dynatrace:
api-version: "v2"
# uri: "https://{your-domain}/e/{your-environment-id}/api/v2/metrics/ingest" for managed deployments.
uri: "https://{your-environment-id}.live.dynatrace.com/api/v2/metrics/ingest"
api-token: "YOUR_TOKEN" # should be read from a secure source and not hard-coded.
----
When using the Dynatrace v2 API, the following optional features are available:
* Metric key prefix: Sets a prefix that will be prepended to all exported metric keys.
* Enrich with Dynatrace metadata: If a OneAgent or Dynatrace operator is running, enrich metrics with additional metadata (e.g. about the host, process or pod).
* Default dimensions: Specify key-value pairs that are added to all exported metrics.
If tags with the same key are specified using Micrometer, they overwrite the default dimensions.
[source,yaml,indent=0,subs="verbatim",configprops,configblocks]
----
management:
metrics:
export:
dynatrace:
# specify token and uri or leave blank for OneAgent export
api-version: "v2"
metric-key-prefix: "your.key.prefix"
enrich-with-dynatrace-metadata: true
default-dimensions:
key1: "value1"
key2: "value2"
----
[[actuator.metrics.export.dynatrace.api-v1]]
===== API v1 (Legacy)
The Dynatrace API v1 registry pushes metrics to the configured URI periodically using the https://www.dynatrace.com/support/help/dynatrace-api/environment-api/metric-v1/[Timeseries API v1].
For backwards-compatibility with existing setups, `api-version` defaults to `"v1"` but can also be specified explicitly as such.
To export metrics to {micrometer-registry-docs}/dynatrace[Dynatrace], your API token, device ID, and URI must be provided:
For the API v1, the base environment URI needs to be specified, without any path.
The API v1 endpoint path will be added automatically.
[source,yaml,indent=0,subs="verbatim",configprops,configblocks]
----
management:
metrics:
export:
dynatrace:
device-id: "YOUR_DEVICE_ID"
# uri: "https://{your-domain}/e/{your-environment-id}" on managed deployments.
uri: "https://{your-environment-id}.live.dynatrace.com"
api-token: "YOUR_TOKEN" # should be read from a secure property source
----
[[actuator.metrics.export.dynatrace.version-independent-settings]]
===== Version-independent settings
You can also change the interval at which metrics are sent to Dynatrace (works for both API versions).
The default export interval is `60s`.
[source,yaml,indent=0,subs="verbatim",configprops,configblocks]
----
@ -172,7 +241,7 @@ You can also change the interval at which metrics are sent to Dynatrace:
step: "30s"
----
More information on how to set up the Dynatrace exporter for Micrometer can be found in {micrometer-registry-docs}/dynatrace[the Micrometer documentation].
[[actuator.metrics.export.elastic]]
==== Elastic