diff options
Diffstat (limited to 'metrics-proxy/src')
3 files changed, 133 insertions, 0 deletions
diff --git a/metrics-proxy/src/main/java/ai/vespa/metricsproxy/telegraf/Telegraf.java b/metrics-proxy/src/main/java/ai/vespa/metricsproxy/telegraf/Telegraf.java new file mode 100644 index 00000000000..09b888650e5 --- /dev/null +++ b/metrics-proxy/src/main/java/ai/vespa/metricsproxy/telegraf/Telegraf.java @@ -0,0 +1,77 @@ +// Copyright 2020 Oath Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. +package ai.vespa.metricsproxy.telegraf; + +import com.google.inject.Inject; +import com.yahoo.component.AbstractComponent; +import com.yahoo.system.execution.ProcessExecutor; +import org.apache.velocity.Template; +import org.apache.velocity.VelocityContext; +import org.apache.velocity.app.VelocityEngine; + +import java.io.FileWriter; + +import static com.yahoo.yolean.Exceptions.uncheck; + +/** + * @author olaa + */ +public class Telegraf extends AbstractComponent { + + private static final String TELEGRAF_CONFIG_PATH = "/etc/telegraf/telegraf.conf"; + private static final String TELEGRAF_CONFIG_TEMPLATE_PATH = "src/main/resources/templates/cloudwatch_plugin.vm"; + private final TelegrafRegistry telegrafRegistry; + + @Inject + public Telegraf(TelegrafRegistry telegrafRegistry, TelegrafConfig telegrafConfig) { + this.telegrafRegistry = telegrafRegistry; + telegrafRegistry.addInstance(this); + writeConfig(telegrafConfig); + restartTelegraf(); + } + + private void writeConfig(TelegrafConfig telegrafConfig) { + VelocityEngine velocityEngine = new VelocityEngine(); + velocityEngine.init(); + Template template = velocityEngine.getTemplate(TELEGRAF_CONFIG_TEMPLATE_PATH); + + VelocityContext context = new VelocityContext(); + context.put("intervalSeconds", telegrafConfig.intervalSeconds()); + context.put("cloudwatchRegion", telegrafConfig.cloudWatch().region()); + context.put("cloudwatchNamespace", telegrafConfig.cloudWatch().namespace()); + context.put("cloudwatchSecretKey", telegrafConfig.cloudWatch().secretKeyName()); + context.put("cloudwatchAccessKey", telegrafConfig.cloudWatch().accessKeyName()); + context.put("cloudwatchProfile", telegrafConfig.cloudWatch().profile()); + context.put("isHosted", !telegrafConfig.cloudWatch().secretKeyName().isBlank()); + context.put("vespaConsumer", telegrafConfig.vespa().consumer()); + // TODO: Add node cert if hosted + + FileWriter writer = uncheck(() -> new FileWriter(TELEGRAF_CONFIG_PATH)); + template.merge(context, writer); + uncheck(writer::close); + } + + private void restartTelegraf() { + executeCommand("service telegraf restart"); + } + + private void stopTelegraf() { + executeCommand("service telegraf stop"); + } + + private void executeCommand(String command) { + ProcessExecutor processExecutor = new ProcessExecutor + .Builder(10) + .successExitCodes(0) + .build(); + uncheck(() -> processExecutor.execute(command)) + .orElseThrow(() -> new RuntimeException("Running " + command + " timed out")); + } + + @Override + public void deconstruct() { + telegrafRegistry.removeInstance(this); + if (telegrafRegistry.isEmpty()) { + stopTelegraf(); + } + } +} diff --git a/metrics-proxy/src/main/java/ai/vespa/metricsproxy/telegraf/TelegrafRegistry.java b/metrics-proxy/src/main/java/ai/vespa/metricsproxy/telegraf/TelegrafRegistry.java new file mode 100644 index 00000000000..429da5bb933 --- /dev/null +++ b/metrics-proxy/src/main/java/ai/vespa/metricsproxy/telegraf/TelegrafRegistry.java @@ -0,0 +1,26 @@ +// Copyright 2020 Oath Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. +package ai.vespa.metricsproxy.telegraf; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +/** + * @author olaa + */ +public class TelegrafRegistry { + + private static final List<Telegraf> telegrafInstances = Collections.synchronizedList(new ArrayList<>()); + + public void addInstance(Telegraf telegraf) { + telegrafInstances.add(telegraf); + } + + public void removeInstance(Telegraf telegraf) { + telegrafInstances.remove(telegraf); + } + + public boolean isEmpty() { + return telegrafInstances.isEmpty(); + } +} diff --git a/metrics-proxy/src/main/resources/templates/cloudwatch_plugin.vm b/metrics-proxy/src/main/resources/templates/cloudwatch_plugin.vm new file mode 100644 index 00000000000..22349e34d67 --- /dev/null +++ b/metrics-proxy/src/main/resources/templates/cloudwatch_plugin.vm @@ -0,0 +1,30 @@ +# Configuration for telegraf agent +[agent] + interval = "${intervalSeconds}s" + round_interval = true + metric_batch_size = 1000 + metric_buffer_limit = 10000 + collection_jitter = "0s" + flush_interval = "${intervalSeconds}s" + flush_jitter = "0s" + precision = "" + +# Configuration for AWS CloudWatch output. +[[outputs.cloudwatch]] + region = "$cloudwatchRegion" + namespace = "$cloudwatchNamespace" +#if( $isHosted ) + access_key = "$cloudwatchSecretKey" + secret_key = "$cloudwatchAccessKey" +#else + profile = "$cloudwatchProfile" +#end + +# Configuration for Vespa input plugin +[[inputs.vespa]] + url = "http://localhost:19092/metrics/v2/values?consumer=$vespaConsumer" +#if( $isHosted ) + tls_cert = "${VESPA_CERTIFICATE_PATH}" + tls_key = "${VESPA_KEY_PATH}" + insecure_skip_verify = true +#end
\ No newline at end of file |