aboutsummaryrefslogtreecommitdiffstats
path: root/config-model/src/main/java/com/yahoo/vespa/model/admin/otel/OpenTelemetryConfigGenerator.java
diff options
context:
space:
mode:
Diffstat (limited to 'config-model/src/main/java/com/yahoo/vespa/model/admin/otel/OpenTelemetryConfigGenerator.java')
-rw-r--r--config-model/src/main/java/com/yahoo/vespa/model/admin/otel/OpenTelemetryConfigGenerator.java121
1 files changed, 119 insertions, 2 deletions
diff --git a/config-model/src/main/java/com/yahoo/vespa/model/admin/otel/OpenTelemetryConfigGenerator.java b/config-model/src/main/java/com/yahoo/vespa/model/admin/otel/OpenTelemetryConfigGenerator.java
index 36eab6a04b3..3f7ca7b46a7 100644
--- a/config-model/src/main/java/com/yahoo/vespa/model/admin/otel/OpenTelemetryConfigGenerator.java
+++ b/config-model/src/main/java/com/yahoo/vespa/model/admin/otel/OpenTelemetryConfigGenerator.java
@@ -1,16 +1,23 @@
// Copyright Vespa.ai. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
package com.yahoo.vespa.model.admin.otel;
+import ai.vespa.metricsproxy.metric.dimensions.PublicDimensions;
import com.fasterxml.jackson.core.JsonEncoding;
import com.fasterxml.jackson.core.JsonFactory;
import com.fasterxml.jackson.core.JsonGenerator;
import com.yahoo.config.model.ApplicationConfigProducerRoot.StatePortInfo;
+import com.yahoo.config.provision.ApplicationId;
+import com.yahoo.config.provision.ClusterMembership;
+import com.yahoo.config.provision.ClusterSpec;
import com.yahoo.config.provision.Zone;
+import com.yahoo.vespa.model.Service;
import java.io.ByteArrayOutputStream;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
+import java.util.LinkedHashMap;
import java.util.List;
+import java.util.Map;
import static com.yahoo.vespa.defaults.Defaults.getDefaults;
@@ -24,8 +31,12 @@ public class OpenTelemetryConfigGenerator {
private final String cert_file;
private final String key_file;
private List<StatePortInfo> statePorts = new ArrayList<>();
+ private final Zone zone;
+ private final ApplicationId applicationId;
- OpenTelemetryConfigGenerator(Zone zone) {
+ OpenTelemetryConfigGenerator(Zone zone, ApplicationId applicationId) {
+ this.zone = zone;
+ this.applicationId = applicationId;
boolean isCd = true;
boolean isPublic = true;
if (zone != null) {
@@ -81,8 +92,15 @@ public class OpenTelemetryConfigGenerator {
if (useTls) addTls(g);
{
g.writeFieldName("labels");
+ var dimVals = serviceAttributes(statePort.service());
+ // these will be tagged as dimension-name/label-value
+ // attributes on all metrics from this /state/v1 port
g.writeStartObject();
- g.writeStringField("service_type", statePort.serviceType());
+ for (var entry : dimVals.entrySet()) {
+ if (entry.getValue() != null) {
+ g.writeStringField(entry.getKey(), entry.getValue());
+ }
+ }
g.writeEndObject();
}
g.writeEndObject();
@@ -123,6 +141,37 @@ public class OpenTelemetryConfigGenerator {
}
g.writeEndObject(); // file
}
+ private void addProcessors(JsonGenerator g) throws java.io.IOException {
+ g.writeFieldName("processors");
+ g.writeStartObject();
+ addResourceProcessor(g);
+ g.writeEndObject();
+ }
+ private void addResourceProcessor(JsonGenerator g) throws java.io.IOException {
+ g.writeFieldName("resource");
+ g.writeStartObject();
+ g.writeFieldName("attributes");
+ g.writeStartArray();
+ // common attributes for all metrics from all services;
+ // which application and which cloud/system/zone/environment
+ addAttributeInsert(g, PublicDimensions.ZONE, zoneAttr());
+ addAttributeInsert(g, PublicDimensions.APPLICATION_ID, appIdAttr());
+ addAttributeInsert(g, "system", systemAttr());
+ addAttributeInsert(g, "tenantName", tenantAttr());
+ addAttributeInsert(g, "applicationName", appNameAttr());
+ addAttributeInsert(g, "instanceName", appInstanceAttr());
+ addAttributeInsert(g, "cloud", cloudAttr());
+ g.writeEndArray();
+ g.writeEndObject();
+ }
+ private void addAttributeInsert(JsonGenerator g, String key, String value) throws java.io.IOException {
+ if (value == null) return;
+ g.writeStartObject();
+ g.writeStringField("key", key);
+ g.writeStringField("value", value);
+ g.writeStringField("action", "insert");
+ g.writeEndObject();
+ }
private void addServiceBlock(JsonGenerator g) throws java.io.IOException {
g.writeFieldName("service");
g.writeStartObject();
@@ -159,6 +208,7 @@ public class OpenTelemetryConfigGenerator {
}
g.writeFieldName("processors");
g.writeStartArray();
+ g.writeString("resource");
g.writeEndArray();
{
g.writeFieldName("exporters");
@@ -186,6 +236,7 @@ public class OpenTelemetryConfigGenerator {
g.writeStartObject();
addReceivers(g);
addExporters(g);
+ addProcessors(g);
addServiceBlock(g);
g.writeEndObject(); // root
g.close();
@@ -203,4 +254,70 @@ public class OpenTelemetryConfigGenerator {
List<String> referencedPaths() {
return List.of(ca_file, cert_file, key_file);
}
+
+ private String zoneAttr() {
+ if (zone == null) return null;
+ return zone.environment().value() + "." + zone.region().value();
+ }
+ private String appIdAttr() {
+ if (applicationId == null) return null;
+ return applicationId.toFullString();
+ }
+ private String systemAttr() {
+ if (zone == null) return null;
+ return zone.system().value();
+ }
+ private String tenantAttr() {
+ if (applicationId == null) return null;
+ return applicationId.tenant().value();
+ }
+ private String appNameAttr() {
+ if (applicationId == null) return null;
+ return applicationId.application().value();
+ }
+ private String appInstanceAttr() {
+ if (applicationId == null) return null;
+ return applicationId.instance().value();
+ }
+ private String cloudAttr() {
+ if (zone == null) return null;
+ return zone.cloud().name().value();
+ }
+
+ private String getDeploymentCluster(ClusterSpec cluster) {
+ if (applicationId == null) return null;
+ if (zone == null) return null;
+ String appString = applicationId.toFullString();
+ return String.join(".", appString,
+ zone.environment().value(),
+ zone.region().value(),
+ cluster.id().value());
+ }
+
+ private Map<String, String> serviceAttributes(Service svc) {
+ Map<String, String> dimvals = new LinkedHashMap<>();
+ dimvals.put("instance", svc.getServiceName()); // should maybe be "local_service_name" ?
+ dimvals.put("instanceType", svc.getServiceType()); // maybe "local_service_type", or remove
+ String cName = svc.getServicePropertyString("clustername", null);
+ if (cName != null) {
+ // what about "clusterid" below, is it always the same?
+ dimvals.put("clustername", cName);
+ }
+ String cType = svc.getServicePropertyString("clustertype", null);
+ if (cType != null) {
+ dimvals.put("clustertype", cType);
+ }
+ var hostResource = svc.getHost();
+ if (hostResource != null) {
+ hostResource.spec().membership().map(ClusterMembership::cluster).ifPresent(cluster -> {
+ dimvals.put(PublicDimensions.DEPLOYMENT_CLUSTER, getDeploymentCluster(cluster));
+ // overrides value above
+ dimvals.put(PublicDimensions.INTERNAL_CLUSTER_TYPE, cluster.type().name());
+ // alternative to above
+ dimvals.put(PublicDimensions.INTERNAL_CLUSTER_ID, cluster.id().value());
+ cluster.group().ifPresent(group -> dimvals.put(PublicDimensions.GROUP_ID, group.toString()));
+ });
+ }
+ return dimvals;
+ }
}