aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorOla Aunronning <olaa@yahooinc.com>2024-04-08 13:52:44 +0200
committerOla Aunronning <olaa@yahooinc.com>2024-04-08 13:53:52 +0200
commite8b20619da13eb97b976f528df00881e2d0f7248 (patch)
treead1675a643c54f8f3c6cb4eec63eaf22274212e9
parent88b23778c4a4bc6b3210e82f0aab015deb6a7495 (diff)
Otel on logserver WIPolaa/otel-config-model
-rw-r--r--config-model-api/abi-spec.json3
-rw-r--r--config-model-api/src/main/java/com/yahoo/config/model/api/ModelContext.java1
-rw-r--r--config-model/src/main/java/com/yahoo/config/model/deploy/TestProperties.java7
-rw-r--r--config-model/src/main/java/com/yahoo/vespa/model/admin/LogserverContainerCluster.java3
-rw-r--r--config-model/src/main/java/com/yahoo/vespa/model/admin/otel/OpenTelemetryCollector.java43
-rw-r--r--config-model/src/main/java/com/yahoo/vespa/model/admin/otel/OpenTelemetryConfigGenerator.java46
-rw-r--r--config-model/src/main/java/com/yahoo/vespa/model/builder/xml/dom/DomAdminV4Builder.java12
-rw-r--r--config-model/src/test/java/com/yahoo/vespa/model/admin/DedicatedAdminV4Test.java21
-rw-r--r--configdefinitions/src/vespa/open-telemetry.def5
-rw-r--r--configserver/src/main/java/com/yahoo/vespa/config/server/deploy/ModelContextImpl.java3
-rw-r--r--flags/src/main/java/com/yahoo/vespa/flags/Flags.java6
11 files changed, 149 insertions, 1 deletions
diff --git a/config-model-api/abi-spec.json b/config-model-api/abi-spec.json
index 9a975f1b727..2b2a51e1cc5 100644
--- a/config-model-api/abi-spec.json
+++ b/config-model-api/abi-spec.json
@@ -1324,7 +1324,8 @@
"public java.lang.String unknownConfigDefinition()",
"public int searchHandlerThreadpool()",
"public boolean alwaysMarkPhraseExpensive()",
- "public boolean sortBlueprintsByCost()"
+ "public boolean sortBlueprintsByCost()",
+ "public boolean logserverOtelCol()"
],
"fields" : [ ]
},
diff --git a/config-model-api/src/main/java/com/yahoo/config/model/api/ModelContext.java b/config-model-api/src/main/java/com/yahoo/config/model/api/ModelContext.java
index 4a4d4648deb..7af9d9644e4 100644
--- a/config-model-api/src/main/java/com/yahoo/config/model/api/ModelContext.java
+++ b/config-model-api/src/main/java/com/yahoo/config/model/api/ModelContext.java
@@ -112,6 +112,7 @@ public interface ModelContext {
@ModelFeatureFlag(owners = {"hmusum"}) default int searchHandlerThreadpool() { return 2; }
@ModelFeatureFlag(owners = {"baldersheim"}) default boolean alwaysMarkPhraseExpensive() { return false; }
@ModelFeatureFlag(owners = {"baldersheim"}) default boolean sortBlueprintsByCost() { return false; }
+ @ModelFeatureFlag(owners = {"olaa"}) default boolean logserverOtelCol() { return false; }
}
/** Warning: As elsewhere in this package, do not make backwards incompatible changes that will break old config models! */
diff --git a/config-model/src/main/java/com/yahoo/config/model/deploy/TestProperties.java b/config-model/src/main/java/com/yahoo/config/model/deploy/TestProperties.java
index 11d3a48ee51..72eabafadf6 100644
--- a/config-model/src/main/java/com/yahoo/config/model/deploy/TestProperties.java
+++ b/config-model/src/main/java/com/yahoo/config/model/deploy/TestProperties.java
@@ -83,6 +83,7 @@ public class TestProperties implements ModelContext.Properties, ModelContext.Fea
private boolean allowUserFilters = true;
private List<DataplaneToken> dataplaneTokens;
private int contentLayerMetadataFeatureLevel = 0;
+ private boolean logserverOtelCol = false;
@Override public ModelContext.FeatureFlags featureFlags() { return this; }
@Override public boolean multitenant() { return multitenant; }
@@ -139,6 +140,7 @@ public class TestProperties implements ModelContext.Properties, ModelContext.Fea
@Override public boolean allowUserFilters() { return allowUserFilters; }
@Override public List<DataplaneToken> dataplaneTokens() { return dataplaneTokens; }
@Override public int contentLayerMetadataFeatureLevel() { return contentLayerMetadataFeatureLevel; }
+ @Override public boolean logserverOtelCol() { return logserverOtelCol; }
public TestProperties sharedStringRepoNoReclaim(boolean sharedStringRepoNoReclaim) {
this.sharedStringRepoNoReclaim = sharedStringRepoNoReclaim;
@@ -369,6 +371,11 @@ public class TestProperties implements ModelContext.Properties, ModelContext.Fea
return this;
}
+ public TestProperties setLogserverOtelCol(boolean logserverOtelCol) {
+ this.logserverOtelCol = logserverOtelCol;
+ return this;
+ }
+
public static class Spec implements ConfigServerSpec {
private final String hostName;
diff --git a/config-model/src/main/java/com/yahoo/vespa/model/admin/LogserverContainerCluster.java b/config-model/src/main/java/com/yahoo/vespa/model/admin/LogserverContainerCluster.java
index 654c81f0519..629ce54d9dd 100644
--- a/config-model/src/main/java/com/yahoo/vespa/model/admin/LogserverContainerCluster.java
+++ b/config-model/src/main/java/com/yahoo/vespa/model/admin/LogserverContainerCluster.java
@@ -5,6 +5,8 @@ import com.yahoo.config.model.deploy.DeployState;
import com.yahoo.config.model.producer.TreeConfigProducer;
import com.yahoo.config.provision.ClusterSpec;
import com.yahoo.search.config.QrStartConfig;
+import com.yahoo.vespa.model.admin.otel.OpenTelemetryCollector;
+import com.yahoo.vespa.model.admin.otel.OpenTelemetryConfigGenerator;
import com.yahoo.vespa.model.container.ContainerCluster;
import com.yahoo.vespa.model.container.PlatformBundles;
import com.yahoo.vespa.model.container.component.Handler;
@@ -29,6 +31,7 @@ public class LogserverContainerCluster extends ContainerCluster<LogserverContain
setJvmGCOptions(deployState.getProperties().jvmGCOptions(Optional.of(ClusterSpec.Type.admin)));
if (isHostedVespa())
addAccessLog(getName());
+
}
@Override
diff --git a/config-model/src/main/java/com/yahoo/vespa/model/admin/otel/OpenTelemetryCollector.java b/config-model/src/main/java/com/yahoo/vespa/model/admin/otel/OpenTelemetryCollector.java
new file mode 100644
index 00000000000..71e2a670034
--- /dev/null
+++ b/config-model/src/main/java/com/yahoo/vespa/model/admin/otel/OpenTelemetryCollector.java
@@ -0,0 +1,43 @@
+// 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 com.yahoo.cloud.config.OpenTelemetryConfig;
+import com.yahoo.config.model.producer.TreeConfigProducer;
+import com.yahoo.vespa.model.AbstractService;
+import com.yahoo.vespa.model.PortAllocBridge;
+
+import java.util.Optional;
+
+public class OpenTelemetryCollector extends AbstractService implements OpenTelemetryConfig.Producer {
+
+ private final String config;
+
+ public OpenTelemetryCollector(TreeConfigProducer<?> parent, String config) {
+ super(parent, "otelcol");
+ setProp("clustertype", "admin");
+ setProp("clustername", "admin");
+ this.config = config;
+ }
+
+ /**
+ * @return the startup command for the otelcol wrapper
+ */
+ @Override
+ public Optional<String> getStartupCommand() {
+ return Optional.of("exec $ROOT/bin/vespa-otelcol-start");
+ }
+
+
+ @Override
+ public void allocatePorts(int start, PortAllocBridge from) {}
+
+ @Override
+ public int getPortCount() {
+ return 0;
+ }
+
+ @Override
+ public void getConfig(OpenTelemetryConfig.Builder builder) {
+ builder.config(config);
+ }
+}
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
new file mode 100644
index 00000000000..7d18cf36f58
--- /dev/null
+++ b/config-model/src/main/java/com/yahoo/vespa/model/admin/otel/OpenTelemetryConfigGenerator.java
@@ -0,0 +1,46 @@
+// 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;
+
+/**
+ * @author olaa
+ */
+public class OpenTelemetryConfigGenerator {
+
+ // For now - just create dummy config
+ /*
+ TODO: Create config
+ 1. polling /state/v1 handler of every service
+ 2. Processing with mapping/filtering from metric sets
+ 3. Exporter to correct endpoint (alternatively amended)
+ */
+ public static String generate() {
+
+ return """
+ receivers:
+ prometheus_simple:
+ collection_interval: 60s
+ endpoint: 'localhost:4080'
+ metrics_path: '/state/v1/metrics
+ params:
+ format: 'prometheus'
+ tls:
+ ca_file: '/opt/vespa/var/vespa//trust-store.pem'
+ cert_file: '/var/lib/sia/certs/vespa.external.cd.tenant.cert.pem'
+ insecure_skip_verify: true
+ key_file: '/var/lib/sia/keys/vespa.external.cd.tenant.key.pem'
+ exporters:
+ file:
+ path: /opt/vespa/logs/vespa/otel-test.json
+ rotation:
+ max_megabytes: 10
+ max_days: 3
+ max_backups: 1
+ service:
+ pipelines:
+ metrics:
+ receivers: [ prometheus_simple ]
+ processors: [ ]
+ exporters: [ file ]
+ """;
+ }
+}
diff --git a/config-model/src/main/java/com/yahoo/vespa/model/builder/xml/dom/DomAdminV4Builder.java b/config-model/src/main/java/com/yahoo/vespa/model/builder/xml/dom/DomAdminV4Builder.java
index f722cf375f3..79866980170 100644
--- a/config-model/src/main/java/com/yahoo/vespa/model/builder/xml/dom/DomAdminV4Builder.java
+++ b/config-model/src/main/java/com/yahoo/vespa/model/builder/xml/dom/DomAdminV4Builder.java
@@ -4,6 +4,7 @@ package com.yahoo.vespa.model.builder.xml.dom;
import com.yahoo.config.model.ConfigModelContext;
import com.yahoo.config.model.api.ConfigServerSpec;
import com.yahoo.config.model.deploy.DeployState;
+import com.yahoo.config.model.producer.TreeConfigProducer;
import com.yahoo.config.provision.ClusterSpec;
import com.yahoo.vespa.model.HostResource;
import com.yahoo.vespa.model.HostSystem;
@@ -12,6 +13,8 @@ import com.yahoo.vespa.model.admin.Logserver;
import com.yahoo.vespa.model.admin.LogserverContainer;
import com.yahoo.vespa.model.admin.LogserverContainerCluster;
import com.yahoo.vespa.model.admin.Slobrok;
+import com.yahoo.vespa.model.admin.otel.OpenTelemetryCollector;
+import com.yahoo.vespa.model.admin.otel.OpenTelemetryConfigGenerator;
import com.yahoo.vespa.model.container.Container;
import com.yahoo.vespa.model.container.ContainerModel;
import org.w3c.dom.Element;
@@ -113,9 +116,18 @@ public class DomAdminV4Builder extends DomAdminBuilderBase {
logServerCluster.addContainer(container);
admin.addAndInitializeService(deployState, hostResource, container);
admin.setLogserverContainerCluster(logServerCluster);
+ if (deployState.featureFlags().logserverOtelCol())
+ addOtelcol(admin, deployState, hostResource);
context.getConfigModelRepoAdder().add(logserverClusterModel);
}
+
+ private void addOtelcol(TreeConfigProducer<?> parent, DeployState deployState, HostResource hostResource) {
+ var otelcol = new OpenTelemetryCollector(parent, OpenTelemetryConfigGenerator.generate());
+ otelcol.setHostResource(hostResource);
+ otelcol.initService(deployState);
+ }
+
private Collection<HostResource> allocateHosts(HostSystem hostSystem, String clusterId, NodesSpecification nodesSpecification) {
return nodesSpecification.provision(hostSystem,
ClusterSpec.Type.admin,
diff --git a/config-model/src/test/java/com/yahoo/vespa/model/admin/DedicatedAdminV4Test.java b/config-model/src/test/java/com/yahoo/vespa/model/admin/DedicatedAdminV4Test.java
index 326fb633877..8265dac9751 100644
--- a/config-model/src/test/java/com/yahoo/vespa/model/admin/DedicatedAdminV4Test.java
+++ b/config-model/src/test/java/com/yahoo/vespa/model/admin/DedicatedAdminV4Test.java
@@ -212,6 +212,27 @@ public class DedicatedAdminV4Test {
METRICS_PROXY_CONTAINER.serviceName, LOGSERVER_CONTAINER.serviceName);
}
+ @Test
+ void testOtelServiceWhenFeatureFlagEnabled() throws Exception {
+ String services = "<services>" +
+ " <admin version='4.0'>" +
+ " <logservers>" +
+ " <nodes count='1' dedicated='true'/>" +
+ " </logservers>" +
+ " </admin>" +
+ "</services>";
+
+ VespaModel model = createModel(hosts, services, new DeployState.Builder()
+ .zone(new Zone(SystemName.Public, Environment.dev, RegionName.defaultName()))
+ .properties(new TestProperties()
+ .setLogserverOtelCol(true)
+ .setHostedVespa(true)));
+ assertEquals(1, model.getHosts().size());
+ // Should create a logserver container on the same node as logserver
+ assertHostContainsServices(model, "hosts/myhost0", "slobrok", "logd", "logserver", "opentelemetrycollector",
+ METRICS_PROXY_CONTAINER.serviceName, LOGSERVER_CONTAINER.serviceName);
+ }
+
private Set<String> serviceNames(VespaModel model, String hostname) {
SentinelConfig config = model.getConfig(SentinelConfig.class, hostname);
return config.service().stream().map(SentinelConfig.Service::name).collect(Collectors.toSet());
diff --git a/configdefinitions/src/vespa/open-telemetry.def b/configdefinitions/src/vespa/open-telemetry.def
new file mode 100644
index 00000000000..15a0e92b32c
--- /dev/null
+++ b/configdefinitions/src/vespa/open-telemetry.def
@@ -0,0 +1,5 @@
+# Copyright Vespa.ai. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+namespace=cloud.config
+
+# For now - store entire config in one string
+config string
diff --git a/configserver/src/main/java/com/yahoo/vespa/config/server/deploy/ModelContextImpl.java b/configserver/src/main/java/com/yahoo/vespa/config/server/deploy/ModelContextImpl.java
index 26732d2e20f..d3c7a8f1c3e 100644
--- a/configserver/src/main/java/com/yahoo/vespa/config/server/deploy/ModelContextImpl.java
+++ b/configserver/src/main/java/com/yahoo/vespa/config/server/deploy/ModelContextImpl.java
@@ -206,6 +206,7 @@ public class ModelContextImpl implements ModelContext {
private final int contentLayerMetadataFeatureLevel;
private final String unknownConfigDefinition;
private final int searchHandlerThreadpool;
+ private final boolean logserverOtelCol;
public FeatureFlags(FlagSource source, ApplicationId appId, Version version) {
this.defaultTermwiseLimit = flagValue(source, appId, version, Flags.DEFAULT_TERM_WISE_LIMIT);
@@ -248,6 +249,7 @@ public class ModelContextImpl implements ModelContext {
this.searchHandlerThreadpool = flagValue(source, appId, version, Flags.SEARCH_HANDLER_THREADPOOL);
this.alwaysMarkPhraseExpensive = flagValue(source, appId, version, Flags.ALWAYS_MARK_PHRASE_EXPENSIVE);
this.sortBlueprintsByCost = flagValue(source, appId, version, Flags.SORT_BLUEPRINTS_BY_COST);
+ this.logserverOtelCol = flagValue(source, appId, version, Flags.LOGSERVER_OTELCOL_AGENT);
}
@Override public int heapSizePercentage() { return heapPercentage; }
@@ -298,6 +300,7 @@ public class ModelContextImpl implements ModelContext {
@Override public String unknownConfigDefinition() { return unknownConfigDefinition; }
@Override public int searchHandlerThreadpool() { return searchHandlerThreadpool; }
@Override public boolean sortBlueprintsByCost() { return sortBlueprintsByCost; }
+ @Override public boolean logserverOtelCol() { return logserverOtelCol; }
private static <V> V flagValue(FlagSource source, ApplicationId appId, Version vespaVersion, UnboundFlag<? extends V, ?, ?> flag) {
return flag.bindTo(source)
diff --git a/flags/src/main/java/com/yahoo/vespa/flags/Flags.java b/flags/src/main/java/com/yahoo/vespa/flags/Flags.java
index 03a713f37f5..2c780990723 100644
--- a/flags/src/main/java/com/yahoo/vespa/flags/Flags.java
+++ b/flags/src/main/java/com/yahoo/vespa/flags/Flags.java
@@ -422,6 +422,12 @@ public class Flags {
"Role definitions for the system",
"Takes effect immediately");
+ public static UnboundBooleanFlag LOGSERVER_OTELCOL_AGENT = defineFeatureFlag(
+ "logserver-otelcol-agent", false,
+ List.of("olaa"), "2024-04-03", "2024-12-31",
+ "Whether logserver container should run otel agent",
+ "Takes effect at redeployment", INSTANCE_ID);
+
/** WARNING: public for testing: All flags should be defined in {@link Flags}. */
public static UnboundBooleanFlag defineFeatureFlag(String flagId, boolean defaultValue, List<String> owners,
String createdAt, String expiresAt, String description,