From dee4a9914b6928c1712058a162d7d4a133cd57c0 Mon Sep 17 00:00:00 2001 From: Harald Musum Date: Sun, 24 Sep 2017 21:37:13 +0200 Subject: Add support for logforwarder --- config-model/pom.xml | 7 +- .../com/yahoo/vespa/model/admin/LogForwarder.java | 59 ++++++++++++++++ .../model/builder/xml/dom/DomAdminBuilderBase.java | 24 +++++++ .../model/builder/xml/dom/DomAdminV2Builder.java | 3 + .../model/builder/xml/dom/DomAdminV4Builder.java | 4 ++ .../vespa/model/builder/xml/dom/ModelElement.java | 14 +++- config-model/src/main/resources/schema/admin.rnc | 20 +++++- .../com/yahoo/vespa/model/admin/AdminTestCase.java | 46 +++++++++++- .../vespa/model/admin/DedicatedAdminV4Test.java | 81 +++++++++++++++++++++- logforwarder/pom.xml | 40 +++++++++++ .../resources/configdefinitions/logforwarder.def | 7 ++ .../src/main/sh/vespa-logforwarder-start.sh | 72 +++++++++++++++++++ pom.xml | 1 + 13 files changed, 370 insertions(+), 8 deletions(-) create mode 100644 config-model/src/main/java/com/yahoo/vespa/model/admin/LogForwarder.java create mode 100644 logforwarder/pom.xml create mode 100644 logforwarder/src/main/resources/configdefinitions/logforwarder.def create mode 100755 logforwarder/src/main/sh/vespa-logforwarder-start.sh diff --git a/config-model/pom.xml b/config-model/pom.xml index c1c08e6e702..8d8ea3203b5 100644 --- a/config-model/pom.xml +++ b/config-model/pom.xml @@ -279,11 +279,16 @@ filedistribution ${project.version} - + com.yahoo.vespa searchsummary ${project.version} + + com.yahoo.vespa + logforwarder + ${project.version} + org.scalatest scalatest_${scala.major-version} diff --git a/config-model/src/main/java/com/yahoo/vespa/model/admin/LogForwarder.java b/config-model/src/main/java/com/yahoo/vespa/model/admin/LogForwarder.java new file mode 100644 index 00000000000..90fb66fc400 --- /dev/null +++ b/config-model/src/main/java/com/yahoo/vespa/model/admin/LogForwarder.java @@ -0,0 +1,59 @@ +// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. +package com.yahoo.vespa.model.admin; + +import com.yahoo.cloud.config.LogforwarderConfig; +import com.yahoo.config.model.producer.AbstractConfigProducer; +import com.yahoo.vespa.model.AbstractService; + +import java.util.ArrayList; +import java.util.List; + +public class LogForwarder extends AbstractService implements LogforwarderConfig.Producer { + + private final String type; + private final List sources; + private final String endpoints; + private final String indexName; + + /** + * Creates a new LogForwarder instance. + */ + // TODO: Use proper types? + public LogForwarder(AbstractConfigProducer parent, int index, String type, List sources, String endpoints, String indexName) { + super(parent, "logforwarder." + index); + this.type = type; + this.sources = sources; + this.endpoints = endpoints; + this.indexName = indexName; + setProp("clustertype", "hosts"); + setProp("clustername", "admin"); + } + + /** + * LogForwarder does not need any ports. + * + * @return The number of ports reserved by the LogForwarder + */ + public int getPortCount() { return 0; } + + /** + * @return The command used to start LogForwarder + */ + public String getStartupCommand() { return "exec $ROOT/libexec/vespa/vespa-logforwarder-start " + getConfigId(); } + + @Override + public void getConfig(LogforwarderConfig.Builder builder) { + List sourceList = new ArrayList<>(); + for (String s : this.sources) { + LogforwarderConfig.Sources.Builder source = new LogforwarderConfig.Sources.Builder(); + source.log(s); + sourceList.add(source); + } + + builder.type(type); + builder.endpoint(endpoints); + builder.index(indexName); + builder.sources(sourceList); + } + +} diff --git a/config-model/src/main/java/com/yahoo/vespa/model/builder/xml/dom/DomAdminBuilderBase.java b/config-model/src/main/java/com/yahoo/vespa/model/builder/xml/dom/DomAdminBuilderBase.java index 908481aad63..79340e9e7ff 100644 --- a/config-model/src/main/java/com/yahoo/vespa/model/builder/xml/dom/DomAdminBuilderBase.java +++ b/config-model/src/main/java/com/yahoo/vespa/model/builder/xml/dom/DomAdminBuilderBase.java @@ -19,6 +19,7 @@ import com.yahoo.config.application.api.FileRegistry; import org.w3c.dom.Element; import java.util.*; +import java.util.stream.Collectors; import static com.yahoo.vespa.model.admin.monitoring.builder.PredefinedMetricSets.predefinedMetricSets; @@ -111,4 +112,27 @@ public abstract class DomAdminBuilderBase extends VespaDomBuilder.DomConfigProdu return minutes; } + void addLogForwarders(ModelElement logForwardingElement, Admin admin) { + if (logForwardingElement == null) return; + + int i = 0; + for (ModelElement e : logForwardingElement.getChildren("forward")) { + String type = e.getStringAttribute("type"); + List sources = e.getChild("source").getChildren("log") + .stream() + .map(ModelElement::asString) + .collect(Collectors.toList()); + String index = e.getChild("destination").getChild("index").asString(); + String endpoint = e.getChild("destination").getChild("endpoint").asString(); + + for (HostResource host : admin.getHostSystem().getHosts()) { + System.out.println("Adding " + e + " on host " + host.getHostName()); + LogForwarder logForwarder = new LogForwarder(admin, i, type, sources, endpoint, index); + logForwarder.setHostResource(host); + logForwarder.initService(); + i++; + } + } + } + } diff --git a/config-model/src/main/java/com/yahoo/vespa/model/builder/xml/dom/DomAdminV2Builder.java b/config-model/src/main/java/com/yahoo/vespa/model/builder/xml/dom/DomAdminV2Builder.java index 180cf4eadec..dd1d4e36255 100644 --- a/config-model/src/main/java/com/yahoo/vespa/model/builder/xml/dom/DomAdminV2Builder.java +++ b/config-model/src/main/java/com/yahoo/vespa/model/builder/xml/dom/DomAdminV2Builder.java @@ -49,6 +49,9 @@ public class DomAdminV2Builder extends DomAdminBuilderBase { admin.addSlobroks(getSlobroks(admin, XML.getChild(adminE, "slobroks"))); if ( ! admin.multitenant()) admin.setClusterControllers(addConfiguredClusterControllers(admin, adminE)); + + ModelElement adminElement = new ModelElement(adminE); + addLogForwarders(adminElement.getChild("logforwarding"), admin); } private List parseConfigservers(Admin admin, Element adminE) { 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 5e22ba3961f..5642c788c0d 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 @@ -19,6 +19,8 @@ import java.util.Collection; import java.util.Collections; import java.util.List; import java.util.Optional; +import java.util.Set; +import java.util.stream.Collectors; /** * Builds the admin model from a version 4 XML tag, or as a default when an admin 3 tag or no admin tag is used. @@ -51,6 +53,8 @@ public class DomAdminV4Builder extends DomAdminBuilderBase { assignSlobroks(requestedSlobroks.orElse(NodesSpecification.nonDedicated(3, version)), admin); assignLogserver(requestedLogservers.orElse(NodesSpecification.nonDedicated(1, version)), admin); + + addLogForwarders(adminElement.getChild("logforwarding"), admin); } private void assignSlobroks(NodesSpecification nodesSpecification, Admin admin) { diff --git a/config-model/src/main/java/com/yahoo/vespa/model/builder/xml/dom/ModelElement.java b/config-model/src/main/java/com/yahoo/vespa/model/builder/xml/dom/ModelElement.java index c5bc275a9e1..1fc70e343f3 100644 --- a/config-model/src/main/java/com/yahoo/vespa/model/builder/xml/dom/ModelElement.java +++ b/config-model/src/main/java/com/yahoo/vespa/model/builder/xml/dom/ModelElement.java @@ -11,7 +11,7 @@ import java.util.List; import java.util.StringTokenizer; /** - * A w3c Element wrapper whith a better API. + * A w3c Element wrapper with a better API. * * Author unknown. */ @@ -46,6 +46,18 @@ public class ModelElement { return null; } + /** + * If not found, return empty list + */ + public List getChildren(String name) { + List e = XML.getChildren(xml, name); + + List list = new ArrayList<>(); + e.forEach(element -> list.add(new ModelElement(element))); + + return list; + } + public ModelElement getChildByPath(String path) { StringTokenizer tokenizer = new StringTokenizer(path, "."); ModelElement curElem = this; diff --git a/config-model/src/main/resources/schema/admin.rnc b/config-model/src/main/resources/schema/admin.rnc index 26705784a34..93807e985f0 100644 --- a/config-model/src/main/resources/schema/admin.rnc +++ b/config-model/src/main/resources/schema/admin.rnc @@ -13,7 +13,8 @@ AdminV2 = AdminSlobroks? & (LegacyAdminMonitoring | AdminMonitoring)? & (LegacyMetricConsumers | Metrics)? & - ClusterControllers? + ClusterControllers? & + LogForwarding? } AdminV3 = @@ -32,7 +33,8 @@ AdminV4 = AdminV4LogServers? & GenericConfig* & (LegacyAdminMonitoring | AdminMonitoring)? & - (LegacyMetricConsumers | Metrics)? + (LegacyMetricConsumers | Metrics)? & + LogForwarding? } AdminV4Slobroks = @@ -112,3 +114,17 @@ ClusterControllers = element cluster-controllers { service.attlist }+ } + +LogForwarding = element logforwarding { + element forward { + attribute type {xsd:string } & + element source { + element log { "access"| "vespa" }+ + } & + element destination { + element endpoint { xsd:string } & + element index { xsd:string } # TODO: Mandatory or with a default value? + } + }+ + +} \ No newline at end of file diff --git a/config-model/src/test/java/com/yahoo/vespa/model/admin/AdminTestCase.java b/config-model/src/test/java/com/yahoo/vespa/model/admin/AdminTestCase.java index 2dfef135425..5ee0528ca7e 100644 --- a/config-model/src/test/java/com/yahoo/vespa/model/admin/AdminTestCase.java +++ b/config-model/src/test/java/com/yahoo/vespa/model/admin/AdminTestCase.java @@ -8,6 +8,7 @@ import com.yahoo.cloud.config.SentinelConfig; import com.yahoo.config.model.ApplicationConfigProducerRoot; import com.yahoo.config.model.deploy.DeployProperties; import com.yahoo.config.model.deploy.DeployState; +import com.yahoo.config.model.test.MockApplicationPackage; import com.yahoo.config.model.test.TestDriver; import com.yahoo.config.model.test.TestRoot; import com.yahoo.config.provision.ApplicationId; @@ -22,9 +23,12 @@ import com.yahoo.vespa.model.container.ContainerCluster; import com.yahoo.vespa.model.container.component.Component; import com.yahoo.vespa.model.container.component.StatisticsComponent; import com.yahoo.vespa.model.test.utils.VespaModelCreatorWithFilePkg; +import com.yahoo.vespa.model.test.utils.VespaModelCreatorWithMockPkg; +import org.junit.Ignore; import org.junit.Test; import java.util.Set; +import java.util.stream.IntStream; import static org.hamcrest.CoreMatchers.is; import static org.junit.Assert.assertEquals; @@ -246,7 +250,47 @@ public class AdminTestCase { assertEquals(sc.values(0).operations(0).name(), StatisticsConfig.Values.Operations.Name.REGULAR); assertEquals(sc.values(0).operations(0).arguments(0).key(), "limits"); assertEquals(sc.values(0).operations(0).arguments(0).value(), "25,50,100,500"); - } + @Test + public void testLogForwarding() throws Exception { + String hosts = "" + + " " + + " node0" + + " " + + ""; + + String services = "" + + " " + + " " + + " " + + " " + + " " + + " access" + + " vespa" + + " " + + " " + + " host1:port,host2:port" + + " all" + + " " + + " " + + " " + + " " + + " access" + + " " + + " " + + " host3:port" + + " access" + + " " + + " " + + " " + + " " + + ""; + + VespaModel vespaModel = new VespaModelCreatorWithMockPkg(hosts, services).create(); + + Set configIds = vespaModel.getConfigIds(); + // 2 logforwarders on each host + IntStream.of(0, 1).forEach(i -> assertTrue(configIds.toString(), configIds.contains("admin/logforwarder." + i))); + } } 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 5b5094a9c43..8b451381dbe 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 @@ -1,6 +1,7 @@ // Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. package com.yahoo.vespa.model.admin; +import com.yahoo.cloud.config.LogforwarderConfig; import com.yahoo.cloud.config.SentinelConfig; import com.yahoo.config.model.NullConfigModelRegistry; import com.yahoo.config.application.api.ApplicationPackage; @@ -16,13 +17,13 @@ import org.junit.Test; import org.xml.sax.SAXException; import java.io.IOException; +import java.util.List; import java.util.Set; import java.util.stream.Collectors; +import java.util.stream.IntStream; import static com.yahoo.vespa.model.admin.monitoring.DefaultMetricsConsumer.VESPA_CONSUMER_ID; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertTrue; -import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.*; /** * @author lulf @@ -141,6 +142,80 @@ public class DedicatedAdminV4Test { "slobrok", "logd", "filedistributorservice", "qrserver"); } + @Test + public void testLogForwarding() throws IOException, SAXException { + String services = "" + + " " + + " " + + " " + + " " + + " " + + " " + + " access" + + " vespa" + + " " + + " " + + " host1:port,host2:port" + + " all" + + " " + + " " + + " " + + " " + + " access" + + " " + + " " + + " host3:port" + + " access" + + " " + + " " + + " " + + " " + + ""; + + VespaModel model = createModel(hosts, services); + assertEquals(3, model.getHosts().size()); + + assertHostContainsServices(model, "hosts/myhost0", + "filedistributorservice", "logd", "logforwarder", "logforwarder2", "slobrok"); + assertHostContainsServices(model, "hosts/myhost1", + "filedistributorservice", "logd", "logforwarder", "logforwarder2", "slobrok"); + assertHostContainsServices(model, "hosts/myhost2", + "filedistributorservice", "logd", "logforwarder", "logforwarder2", "logserver"); + + Set configIds = model.getConfigIds(); + // 2 logforwarders on each host + IntStream.of(0, 1, 2, 3, 4, 5).forEach(i -> assertTrue(configIds.toString(), configIds.contains("admin/logforwarder." + i))); + + // First forwarder + { + LogforwarderConfig.Builder builder = new LogforwarderConfig.Builder(); + model.getConfig(builder, "admin/logforwarder.0"); + LogforwarderConfig config = new LogforwarderConfig(builder); + + assertEquals("splunk", config.type()); + assertEquals("host1:port,host2:port", config.endpoint()); + assertEquals("all", config.index()); + List sources = config.sources(); + assertEquals(2, sources.size()); + assertEquals("access", sources.get(0).log()); + assertEquals("vespa", sources.get(1).log()); + } + + // Two forwarders on each host, so forwarder with id admin/logforwarder.3 should be different + { + LogforwarderConfig.Builder builder = new LogforwarderConfig.Builder(); + model.getConfig(builder, "admin/logforwarder.3"); + LogforwarderConfig config = new LogforwarderConfig(builder); + + assertEquals("splunk", config.type()); + assertEquals("host3:port", config.endpoint()); + assertEquals("access", config.index()); + List sources = config.sources(); + assertEquals(1, sources.size()); + assertEquals("access", sources.get(0).log()); + } + } + private Set 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/logforwarder/pom.xml b/logforwarder/pom.xml new file mode 100644 index 00000000000..505ca9f108b --- /dev/null +++ b/logforwarder/pom.xml @@ -0,0 +1,40 @@ + + + 4.0.0 + + com.yahoo.vespa + parent + 6-SNAPSHOT + + logforwarder + 6-SNAPSHOT + jar + ${project.artifactId} + + + com.yahoo.vespa + config-lib + ${project.version} + + + + + + com.yahoo.vespa + config-class-plugin + ${project.version} + + + config-gen + + config-gen + + + + + + + diff --git a/logforwarder/src/main/resources/configdefinitions/logforwarder.def b/logforwarder/src/main/resources/configdefinitions/logforwarder.def new file mode 100644 index 00000000000..66750a81af8 --- /dev/null +++ b/logforwarder/src/main/resources/configdefinitions/logforwarder.def @@ -0,0 +1,7 @@ +namespace=cloud.config + +# Forwarder that forwards onle or more types of log to an endpoint +type string +sources[].log string +endpoint string +index string diff --git a/logforwarder/src/main/sh/vespa-logforwarder-start.sh b/logforwarder/src/main/sh/vespa-logforwarder-start.sh new file mode 100755 index 00000000000..20864d7b4e6 --- /dev/null +++ b/logforwarder/src/main/sh/vespa-logforwarder-start.sh @@ -0,0 +1,72 @@ +#!/bin/sh +# Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. + +# BEGIN environment bootstrap section +# Do not edit between here and END as this section should stay identical in all scripts + +findpath () { + myname=${0} + mypath=${myname%/*} + myname=${myname##*/} + if [ "$mypath" ] && [ -d "$mypath" ]; then + return + fi + mypath=$(pwd) + if [ -f "${mypath}/${myname}" ]; then + return + fi + echo "FATAL: Could not figure out the path where $myname lives from $0" + exit 1 +} + +COMMON_ENV=libexec/vespa/common-env.sh + +source_common_env () { + if [ "$VESPA_HOME" ] && [ -d "$VESPA_HOME" ]; then + export VESPA_HOME + common_env=$VESPA_HOME/$COMMON_ENV + if [ -f "$common_env" ]; then + . $common_env + return + fi + fi + return 1 +} + +findroot () { + source_common_env && return + if [ "$VESPA_HOME" ]; then + echo "FATAL: bad VESPA_HOME value '$VESPA_HOME'" + exit 1 + fi + if [ "$ROOT" ] && [ -d "$ROOT" ]; then + VESPA_HOME="$ROOT" + source_common_env && return + fi + findpath + while [ "$mypath" ]; do + VESPA_HOME=${mypath} + source_common_env && return + mypath=${mypath%/*} + done + echo "FATAL: missing VESPA_HOME environment variable" + echo "Could not locate $COMMON_ENV anywhere" + exit 1 +} + +findroot + +# END environment bootstrap section + +ROOT=${VESPA_HOME%/} +export ROOT +cd $ROOT || { echo "Cannot cd to $ROOT" 1>&2; exit 1; } + +# TODO: Get config and start logforwarder properly + +configid=$1 + +config=`$VESPA_HOME/bin/vespa-get-config -j -n cloud.config.logforwarder -i $configid` +echo $config + +sleep 10000000 diff --git a/pom.xml b/pom.xml index 0c41a993fdf..364c79f2cfb 100644 --- a/pom.xml +++ b/pom.xml @@ -977,6 +977,7 @@ libmlr linguistics logd + logforwarder logserver messagebus-disc messagebus -- cgit v1.2.3 From 14b32518dc6b04c791b6aca7adf873d31873de1c Mon Sep 17 00:00:00 2001 From: Arne Juul Date: Mon, 2 Oct 2017 12:26:28 +0000 Subject: add C++ application logforwarder-start --- CMakeLists.txt | 1 + logforwarder/CMakeLists.txt | 10 ++++ .../src/apps/vespa-logforwarder-start/.gitignore | 3 ++ .../apps/vespa-logforwarder-start/CMakeLists.txt | 13 +++++ .../apps/vespa-logforwarder-start/cf-handler.cpp | 63 ++++++++++++++++++++++ .../src/apps/vespa-logforwarder-start/cf-handler.h | 20 +++++++ .../apps/vespa-logforwarder-start/logforwarder.def | 7 +++ .../src/apps/vespa-logforwarder-start/main.cpp | 38 +++++++++++++ .../apps/vespa-logforwarder-start/sig-catch.cpp | 40 ++++++++++++++ .../src/apps/vespa-logforwarder-start/sig-catch.h | 8 +++ 10 files changed, 203 insertions(+) create mode 100644 logforwarder/CMakeLists.txt create mode 100644 logforwarder/src/apps/vespa-logforwarder-start/.gitignore create mode 100644 logforwarder/src/apps/vespa-logforwarder-start/CMakeLists.txt create mode 100644 logforwarder/src/apps/vespa-logforwarder-start/cf-handler.cpp create mode 100644 logforwarder/src/apps/vespa-logforwarder-start/cf-handler.h create mode 100644 logforwarder/src/apps/vespa-logforwarder-start/logforwarder.def create mode 100644 logforwarder/src/apps/vespa-logforwarder-start/main.cpp create mode 100644 logforwarder/src/apps/vespa-logforwarder-start/sig-catch.cpp create mode 100644 logforwarder/src/apps/vespa-logforwarder-start/sig-catch.h diff --git a/CMakeLists.txt b/CMakeLists.txt index f7752d5915e..db6bbde423a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -71,6 +71,7 @@ add_subdirectory(jrt_test) add_subdirectory(juniper) add_subdirectory(logd) add_subdirectory(logserver) +add_subdirectory(logforwarder) add_subdirectory(lowercasing_test) add_subdirectory(memfilepersistence) add_subdirectory(messagebus) diff --git a/logforwarder/CMakeLists.txt b/logforwarder/CMakeLists.txt new file mode 100644 index 00000000000..bd1e480a074 --- /dev/null +++ b/logforwarder/CMakeLists.txt @@ -0,0 +1,10 @@ +# Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. +vespa_define_module( + DEPENDS + vespalog + vespalib + config_cloudconfig + + APPS + src/apps/vespa-logforwarder-start +) diff --git a/logforwarder/src/apps/vespa-logforwarder-start/.gitignore b/logforwarder/src/apps/vespa-logforwarder-start/.gitignore new file mode 100644 index 00000000000..d98b2a9ccc7 --- /dev/null +++ b/logforwarder/src/apps/vespa-logforwarder-start/.gitignore @@ -0,0 +1,3 @@ +vespa-logforwarder-start_app +config-logforwarder.cpp +config-logforwarder.h diff --git a/logforwarder/src/apps/vespa-logforwarder-start/CMakeLists.txt b/logforwarder/src/apps/vespa-logforwarder-start/CMakeLists.txt new file mode 100644 index 00000000000..ac9667d5f9e --- /dev/null +++ b/logforwarder/src/apps/vespa-logforwarder-start/CMakeLists.txt @@ -0,0 +1,13 @@ +# Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. +vespa_add_executable(vespa-logforwarder-start_app + SOURCES + main.cpp + cf-handler.cpp + sig-catch.cpp + OUTPUT_NAME vespa-logforwarder-start_app + INSTALL bin + DEPENDS + config_cloudconfig +) +vespa_generate_config(vespa-logforwarder-start_app logforwarder.def) +install(FILES logforwarder.def RENAME cloud.config.logforwarder.def DESTINATION var/db/vespa/config_server/serverdb/classes) diff --git a/logforwarder/src/apps/vespa-logforwarder-start/cf-handler.cpp b/logforwarder/src/apps/vespa-logforwarder-start/cf-handler.cpp new file mode 100644 index 00000000000..479bf33ab59 --- /dev/null +++ b/logforwarder/src/apps/vespa-logforwarder-start/cf-handler.cpp @@ -0,0 +1,63 @@ +// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. + +#include "cf-handler.h" +#include +#include + +#include +LOG_SETUP(".cf-handler"); + +CfHandler::CfHandler() : _subscriber() {} + +CfHandler::~CfHandler() +{ +} + +void +CfHandler::subscribe(const std::string & configId, uint64_t timeoutMS) +{ + _handle = _subscriber.subscribe(configId, timeoutMS); +} + +void +CfHandler::doConfigure() +{ + std::unique_ptr cfg(_handle->getConfig()); + const LogforwarderConfig& config(*cfg); + + printf("logforwarder type: %s\n", config.type.c_str()); + for (unsigned int i = 0; i < config.sources.size(); ++i) { + printf("source %d is: %s\n", i, config.sources[i].log.c_str()); + } + printf("endpoint: %s\n", config.endpoint.c_str()); + printf("index: %s\n", config.index.c_str()); +} + +void +CfHandler::check() +{ + if (_subscriber.nextConfig(0)) { + doConfigure(); + } +} + +constexpr uint64_t CONFIG_TIMEOUT_MS = 30 * 1000; + +void +CfHandler::start(const char *configId) +{ + LOG(debug, "Reading configuration configid '%s'", configId); + try { + subscribe(configId, CONFIG_TIMEOUT_MS); + } catch (config::ConfigTimeoutException & ex) { + LOG(warning, "Timout getting config, please check your setup. Will exit and restart: %s", ex.getMessage().c_str()); + exit(EXIT_FAILURE); + } catch (config::InvalidConfigException& ex) { + LOG(error, "Fatal: Invalid configuration, please check your setup: %s", ex.getMessage().c_str()); + exit(EXIT_FAILURE); + } catch (config::ConfigRuntimeException& ex) { + LOG(error, "Fatal: Could not get config, please check your setup: %s", ex.getMessage().c_str()); + exit(EXIT_FAILURE); + } + doConfigure(); +} diff --git a/logforwarder/src/apps/vespa-logforwarder-start/cf-handler.h b/logforwarder/src/apps/vespa-logforwarder-start/cf-handler.h new file mode 100644 index 00000000000..6ad27d81b0d --- /dev/null +++ b/logforwarder/src/apps/vespa-logforwarder-start/cf-handler.h @@ -0,0 +1,20 @@ +// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. +#pragma once + +#include +#include "config-logforwarder.h" + +using cloud::config::LogforwarderConfig; + +class CfHandler { +private: + config::ConfigSubscriber _subscriber; + config::ConfigHandle::UP _handle; + void subscribe(const std::string & configId, uint64_t timeoutMS); + void doConfigure(); +public: + CfHandler(); + virtual ~CfHandler(); + void start(const char *configId); + void check(); +}; diff --git a/logforwarder/src/apps/vespa-logforwarder-start/logforwarder.def b/logforwarder/src/apps/vespa-logforwarder-start/logforwarder.def new file mode 100644 index 00000000000..66750a81af8 --- /dev/null +++ b/logforwarder/src/apps/vespa-logforwarder-start/logforwarder.def @@ -0,0 +1,7 @@ +namespace=cloud.config + +# Forwarder that forwards onle or more types of log to an endpoint +type string +sources[].log string +endpoint string +index string diff --git a/logforwarder/src/apps/vespa-logforwarder-start/main.cpp b/logforwarder/src/apps/vespa-logforwarder-start/main.cpp new file mode 100644 index 00000000000..e06d3dd6d8d --- /dev/null +++ b/logforwarder/src/apps/vespa-logforwarder-start/main.cpp @@ -0,0 +1,38 @@ +// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. + +#include +#include + +#include +LOG_SETUP("vespa-logforwarder-start"); + +#include "cf-handler.h" +#include "sig-catch.h" + +class Wrapper { + const char *_configId; +public: + Wrapper(const char *cfid) : _configId(cfid) {} + void run() { + SigCatch catcher; + CfHandler handler; + handler.start(_configId); + while (! catcher.receivedStopSignal()) { + handler.check(); + usleep(12500); // Avoid busy looping; + } + } +}; + +int +main(int argc, char** argv) +{ + int c = getopt(argc, argv, "c:"); + if (c != 'c') { + LOG(error, "Usage: %s -c ", argv[0]); + exit(EXIT_FAILURE); + } + Wrapper wrapper(optarg); + wrapper.run(); + return 0; +} diff --git a/logforwarder/src/apps/vespa-logforwarder-start/sig-catch.cpp b/logforwarder/src/apps/vespa-logforwarder-start/sig-catch.cpp new file mode 100644 index 00000000000..acd82ffd29e --- /dev/null +++ b/logforwarder/src/apps/vespa-logforwarder-start/sig-catch.cpp @@ -0,0 +1,40 @@ +// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. + +#include "sig-catch.h" +#include +#include +#include + +static int sigPermanent(int sig, void(*handler)(int)); +static void setStopFlag(int sig); +sig_atomic_t stop = 0; + +SigCatch::SigCatch() +{ + sigPermanent(SIGTERM, setStopFlag); + sigPermanent(SIGINT, setStopFlag); +} + +bool +SigCatch::receivedStopSignal() { + return stop != 0; +} + +static void +setStopFlag(int sig) +{ + (void)sig; + stop = 1; +} + +static int +sigPermanent(int sig, void(*handler)(int)) +{ + struct sigaction sa; + + memset(&sa, 0, sizeof(sa)); + sigemptyset(&sa.sa_mask); + sa.sa_flags = 0; // no SA_RESTART! + sa.sa_handler = handler; + return sigaction(sig, &sa, nullptr); +} diff --git a/logforwarder/src/apps/vespa-logforwarder-start/sig-catch.h b/logforwarder/src/apps/vespa-logforwarder-start/sig-catch.h new file mode 100644 index 00000000000..905f37103ec --- /dev/null +++ b/logforwarder/src/apps/vespa-logforwarder-start/sig-catch.h @@ -0,0 +1,8 @@ +// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. + +class SigCatch +{ +public: + SigCatch(); + bool receivedStopSignal(); +}; -- cgit v1.2.3 From e69f8c07bf16acc8e59f2a5f836bfe7d03601553 Mon Sep 17 00:00:00 2001 From: Arne Juul Date: Mon, 2 Oct 2017 12:30:15 +0000 Subject: revert admin.rnc changes --- config-model/src/main/resources/schema/admin.rnc | 20 ++------------------ 1 file changed, 2 insertions(+), 18 deletions(-) diff --git a/config-model/src/main/resources/schema/admin.rnc b/config-model/src/main/resources/schema/admin.rnc index 93807e985f0..26705784a34 100644 --- a/config-model/src/main/resources/schema/admin.rnc +++ b/config-model/src/main/resources/schema/admin.rnc @@ -13,8 +13,7 @@ AdminV2 = AdminSlobroks? & (LegacyAdminMonitoring | AdminMonitoring)? & (LegacyMetricConsumers | Metrics)? & - ClusterControllers? & - LogForwarding? + ClusterControllers? } AdminV3 = @@ -33,8 +32,7 @@ AdminV4 = AdminV4LogServers? & GenericConfig* & (LegacyAdminMonitoring | AdminMonitoring)? & - (LegacyMetricConsumers | Metrics)? & - LogForwarding? + (LegacyMetricConsumers | Metrics)? } AdminV4Slobroks = @@ -114,17 +112,3 @@ ClusterControllers = element cluster-controllers { service.attlist }+ } - -LogForwarding = element logforwarding { - element forward { - attribute type {xsd:string } & - element source { - element log { "access"| "vespa" }+ - } & - element destination { - element endpoint { xsd:string } & - element index { xsd:string } # TODO: Mandatory or with a default value? - } - }+ - -} \ No newline at end of file -- cgit v1.2.3 From f63292744237def528761fc0bcd38398e95ddb6d Mon Sep 17 00:00:00 2001 From: Harald Musum Date: Mon, 28 Aug 2017 17:21:58 +0200 Subject: Add schema for logforwarding * Add support for version 2 and 4 (version 3 is not used) --- config-model/src/main/resources/schema/admin.rnc | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/config-model/src/main/resources/schema/admin.rnc b/config-model/src/main/resources/schema/admin.rnc index 26705784a34..93807e985f0 100644 --- a/config-model/src/main/resources/schema/admin.rnc +++ b/config-model/src/main/resources/schema/admin.rnc @@ -13,7 +13,8 @@ AdminV2 = AdminSlobroks? & (LegacyAdminMonitoring | AdminMonitoring)? & (LegacyMetricConsumers | Metrics)? & - ClusterControllers? + ClusterControllers? & + LogForwarding? } AdminV3 = @@ -32,7 +33,8 @@ AdminV4 = AdminV4LogServers? & GenericConfig* & (LegacyAdminMonitoring | AdminMonitoring)? & - (LegacyMetricConsumers | Metrics)? + (LegacyMetricConsumers | Metrics)? & + LogForwarding? } AdminV4Slobroks = @@ -112,3 +114,17 @@ ClusterControllers = element cluster-controllers { service.attlist }+ } + +LogForwarding = element logforwarding { + element forward { + attribute type {xsd:string } & + element source { + element log { "access"| "vespa" }+ + } & + element destination { + element endpoint { xsd:string } & + element index { xsd:string } # TODO: Mandatory or with a default value? + } + }+ + +} \ No newline at end of file -- cgit v1.2.3 From 513cd53ae212050af0deb8f91d3b0ed5c40777e2 Mon Sep 17 00:00:00 2001 From: Harald Musum Date: Mon, 28 Aug 2017 17:23:45 +0200 Subject: index is mandatory --- config-model/src/main/resources/schema/admin.rnc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config-model/src/main/resources/schema/admin.rnc b/config-model/src/main/resources/schema/admin.rnc index 93807e985f0..eea3d156771 100644 --- a/config-model/src/main/resources/schema/admin.rnc +++ b/config-model/src/main/resources/schema/admin.rnc @@ -123,7 +123,7 @@ LogForwarding = element logforwarding { } & element destination { element endpoint { xsd:string } & - element index { xsd:string } # TODO: Mandatory or with a default value? + element index { xsd:string } } }+ -- cgit v1.2.3 From 0f7f98734e4bb6644644d746f12f1ba15f1b26b2 Mon Sep 17 00:00:00 2001 From: Harald Musum Date: Mon, 28 Aug 2017 17:24:15 +0200 Subject: Add newline --- config-model/src/main/resources/schema/admin.rnc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config-model/src/main/resources/schema/admin.rnc b/config-model/src/main/resources/schema/admin.rnc index eea3d156771..860f9637a28 100644 --- a/config-model/src/main/resources/schema/admin.rnc +++ b/config-model/src/main/resources/schema/admin.rnc @@ -127,4 +127,4 @@ LogForwarding = element logforwarding { } }+ -} \ No newline at end of file +} -- cgit v1.2.3 From fb626da54b7b70fbe06982a99b2d3cc0091f1d3d Mon Sep 17 00:00:00 2001 From: Bjorn Meland Date: Tue, 12 Sep 2017 15:00:26 +0200 Subject: Using Splunk deployment server to configure forwarding --- config-model/src/main/resources/schema/admin.rnc | 16 +++++----------- 1 file changed, 5 insertions(+), 11 deletions(-) diff --git a/config-model/src/main/resources/schema/admin.rnc b/config-model/src/main/resources/schema/admin.rnc index 860f9637a28..cfade886b06 100644 --- a/config-model/src/main/resources/schema/admin.rnc +++ b/config-model/src/main/resources/schema/admin.rnc @@ -116,15 +116,9 @@ ClusterControllers = element cluster-controllers { } LogForwarding = element logforwarding { - element forward { - attribute type {xsd:string } & - element source { - element log { "access"| "vespa" }+ - } & - element destination { - element endpoint { xsd:string } & - element index { xsd:string } - } - }+ - + element splunk { + attribute deployment-server {xsd:string } & + attribute management-port {xsd:positiveInteger } & + attribute client-name {xsd:string } + } } -- cgit v1.2.3 From 84dd400c04bcf812ca773d148b61b401cc7e75e1 Mon Sep 17 00:00:00 2001 From: Bjorn Meland Date: Tue, 12 Sep 2017 15:02:46 +0200 Subject: some more space... --- config-model/src/main/resources/schema/admin.rnc | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/config-model/src/main/resources/schema/admin.rnc b/config-model/src/main/resources/schema/admin.rnc index cfade886b06..55ca958e2bb 100644 --- a/config-model/src/main/resources/schema/admin.rnc +++ b/config-model/src/main/resources/schema/admin.rnc @@ -117,8 +117,8 @@ ClusterControllers = element cluster-controllers { LogForwarding = element logforwarding { element splunk { - attribute deployment-server {xsd:string } & - attribute management-port {xsd:positiveInteger } & - attribute client-name {xsd:string } + attribute deployment-server { xsd:string } & + attribute management-port { xsd:positiveInteger } & + attribute client-name { xsd:string } } } -- cgit v1.2.3 From 3b2f3992cfe417e29ccd6e0dc52017664e3530b2 Mon Sep 17 00:00:00 2001 From: Bjørn Meland Date: Mon, 2 Oct 2017 15:07:04 +0200 Subject: Removed port for deployment server, will require host:port as server This is as Manhattan is doing it too --- config-model/src/main/resources/schema/admin.rnc | 1 - 1 file changed, 1 deletion(-) diff --git a/config-model/src/main/resources/schema/admin.rnc b/config-model/src/main/resources/schema/admin.rnc index 55ca958e2bb..3ab02af3efd 100644 --- a/config-model/src/main/resources/schema/admin.rnc +++ b/config-model/src/main/resources/schema/admin.rnc @@ -118,7 +118,6 @@ ClusterControllers = element cluster-controllers { LogForwarding = element logforwarding { element splunk { attribute deployment-server { xsd:string } & - attribute management-port { xsd:positiveInteger } & attribute client-name { xsd:string } } } -- cgit v1.2.3 From deb22c99216e4545610e08928490eba617b7b8b7 Mon Sep 17 00:00:00 2001 From: Arne Juul Date: Mon, 2 Oct 2017 13:39:19 +0000 Subject: update with new schema --- .../com/yahoo/vespa/model/admin/LogForwarder.java | 47 +++++++++++--------- .../model/builder/xml/dom/DomAdminBuilderBase.java | 16 +++---- .../com/yahoo/vespa/model/admin/AdminTestCase.java | 27 +++--------- .../vespa/model/admin/DedicatedAdminV4Test.java | 51 +++++----------------- .../src/test/schema-test-files/services.xml | 3 ++ .../apps/vespa-logforwarder-start/cf-handler.cpp | 9 ++-- .../apps/vespa-logforwarder-start/logforwarder.def | 9 ++-- .../resources/configdefinitions/logforwarder.def | 9 ++-- 8 files changed, 63 insertions(+), 108 deletions(-) diff --git a/config-model/src/main/java/com/yahoo/vespa/model/admin/LogForwarder.java b/config-model/src/main/java/com/yahoo/vespa/model/admin/LogForwarder.java index 90fb66fc400..0df6566829c 100644 --- a/config-model/src/main/java/com/yahoo/vespa/model/admin/LogForwarder.java +++ b/config-model/src/main/java/com/yahoo/vespa/model/admin/LogForwarder.java @@ -10,25 +10,39 @@ import java.util.List; public class LogForwarder extends AbstractService implements LogforwarderConfig.Producer { - private final String type; - private final List sources; - private final String endpoints; - private final String indexName; + public static class Config { + public final String deploymentServer; + public final String clientName; + + private Config(String ds, String cn) { + this.deploymentServer = ds; + this.clientName = cn; + } + public Config withDeploymentServer(String ds) { + return new Config(ds, clientName); + } + public Config withClientName(String cn) { + return new Config(deploymentServer, cn); + } + } + + private final Config config; /** * Creates a new LogForwarder instance. */ // TODO: Use proper types? - public LogForwarder(AbstractConfigProducer parent, int index, String type, List sources, String endpoints, String indexName) { + public LogForwarder(AbstractConfigProducer parent, int index, Config config) { super(parent, "logforwarder." + index); - this.type = type; - this.sources = sources; - this.endpoints = endpoints; - this.indexName = indexName; + this.config = config; setProp("clustertype", "hosts"); setProp("clustername", "admin"); } + public static Config cfg() { + return new Config(null, null); + } + /** * LogForwarder does not need any ports. * @@ -39,21 +53,12 @@ public class LogForwarder extends AbstractService implements LogforwarderConfig. /** * @return The command used to start LogForwarder */ - public String getStartupCommand() { return "exec $ROOT/libexec/vespa/vespa-logforwarder-start " + getConfigId(); } + public String getStartupCommand() { return "exec $ROOT/libexec/vespa/vespa-logforwarder-start -c " + getConfigId(); } @Override public void getConfig(LogforwarderConfig.Builder builder) { - List sourceList = new ArrayList<>(); - for (String s : this.sources) { - LogforwarderConfig.Sources.Builder source = new LogforwarderConfig.Sources.Builder(); - source.log(s); - sourceList.add(source); - } - - builder.type(type); - builder.endpoint(endpoints); - builder.index(indexName); - builder.sources(sourceList); + builder.deploymentServer(config.deploymentServer); + builder.clientName(config.clientName); } } diff --git a/config-model/src/main/java/com/yahoo/vespa/model/builder/xml/dom/DomAdminBuilderBase.java b/config-model/src/main/java/com/yahoo/vespa/model/builder/xml/dom/DomAdminBuilderBase.java index 79340e9e7ff..0a93bee962d 100644 --- a/config-model/src/main/java/com/yahoo/vespa/model/builder/xml/dom/DomAdminBuilderBase.java +++ b/config-model/src/main/java/com/yahoo/vespa/model/builder/xml/dom/DomAdminBuilderBase.java @@ -116,18 +116,12 @@ public abstract class DomAdminBuilderBase extends VespaDomBuilder.DomConfigProdu if (logForwardingElement == null) return; int i = 0; - for (ModelElement e : logForwardingElement.getChildren("forward")) { - String type = e.getStringAttribute("type"); - List sources = e.getChild("source").getChildren("log") - .stream() - .map(ModelElement::asString) - .collect(Collectors.toList()); - String index = e.getChild("destination").getChild("index").asString(); - String endpoint = e.getChild("destination").getChild("endpoint").asString(); - + for (ModelElement e : logForwardingElement.getChildren("splunk")) { + LogForwarder.Config cfg = LogForwarder.cfg() + .withDeploymentServer(e.getStringAttribute("deployment-server")) + .withClientName(e.getStringAttribute("client-name")); for (HostResource host : admin.getHostSystem().getHosts()) { - System.out.println("Adding " + e + " on host " + host.getHostName()); - LogForwarder logForwarder = new LogForwarder(admin, i, type, sources, endpoint, index); + LogForwarder logForwarder = new LogForwarder(admin, i, cfg); logForwarder.setHostResource(host); logForwarder.initService(); i++; diff --git a/config-model/src/test/java/com/yahoo/vespa/model/admin/AdminTestCase.java b/config-model/src/test/java/com/yahoo/vespa/model/admin/AdminTestCase.java index 5ee0528ca7e..0a2690edec9 100644 --- a/config-model/src/test/java/com/yahoo/vespa/model/admin/AdminTestCase.java +++ b/config-model/src/test/java/com/yahoo/vespa/model/admin/AdminTestCase.java @@ -264,25 +264,7 @@ public class AdminTestCase { " " + " " + " " + - " " + - " " + - " access" + - " vespa" + - " " + - " " + - " host1:port,host2:port" + - " all" + - " " + - " " + - " " + - " " + - " access" + - " " + - " " + - " host3:port" + - " access" + - " " + - " " + + " " + " " + " " + ""; @@ -290,7 +272,10 @@ public class AdminTestCase { VespaModel vespaModel = new VespaModelCreatorWithMockPkg(hosts, services).create(); Set configIds = vespaModel.getConfigIds(); - // 2 logforwarders on each host - IntStream.of(0, 1).forEach(i -> assertTrue(configIds.toString(), configIds.contains("admin/logforwarder." + i))); + // 1 logforwarder on each host + assertTrue(configIds.toString(), configIds.contains("admin/logforwarder.0")); } } + + + 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 8b451381dbe..e3f773a64c2 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 @@ -149,25 +149,7 @@ public class DedicatedAdminV4Test { " " + " " + " " + - " " + - " " + - " access" + - " vespa" + - " " + - " " + - " host1:port,host2:port" + - " all" + - " " + - " " + - " " + - " " + - " access" + - " " + - " " + - " host3:port" + - " access" + - " " + - " " + + " " + " " + " " + ""; @@ -176,15 +158,15 @@ public class DedicatedAdminV4Test { assertEquals(3, model.getHosts().size()); assertHostContainsServices(model, "hosts/myhost0", - "filedistributorservice", "logd", "logforwarder", "logforwarder2", "slobrok"); + "filedistributorservice", "logd", "logforwarder", "slobrok"); assertHostContainsServices(model, "hosts/myhost1", - "filedistributorservice", "logd", "logforwarder", "logforwarder2", "slobrok"); + "filedistributorservice", "logd", "logforwarder", "slobrok"); assertHostContainsServices(model, "hosts/myhost2", - "filedistributorservice", "logd", "logforwarder", "logforwarder2", "logserver"); + "filedistributorservice", "logd", "logforwarder", "logserver"); Set configIds = model.getConfigIds(); - // 2 logforwarders on each host - IntStream.of(0, 1, 2, 3, 4, 5).forEach(i -> assertTrue(configIds.toString(), configIds.contains("admin/logforwarder." + i))); + // 1 logforwarder on each host + IntStream.of(0, 1, 2).forEach(i -> assertTrue(configIds.toString(), configIds.contains("admin/logforwarder." + i))); // First forwarder { @@ -192,27 +174,18 @@ public class DedicatedAdminV4Test { model.getConfig(builder, "admin/logforwarder.0"); LogforwarderConfig config = new LogforwarderConfig(builder); - assertEquals("splunk", config.type()); - assertEquals("host1:port,host2:port", config.endpoint()); - assertEquals("all", config.index()); - List sources = config.sources(); - assertEquals(2, sources.size()); - assertEquals("access", sources.get(0).log()); - assertEquals("vespa", sources.get(1).log()); + assertEquals("foo:123", config.deploymentServer()); + assertEquals("foocli", config.clientName()); } - // Two forwarders on each host, so forwarder with id admin/logforwarder.3 should be different + // Other host's forwarder { LogforwarderConfig.Builder builder = new LogforwarderConfig.Builder(); - model.getConfig(builder, "admin/logforwarder.3"); + model.getConfig(builder, "admin/logforwarder.2"); LogforwarderConfig config = new LogforwarderConfig(builder); - assertEquals("splunk", config.type()); - assertEquals("host3:port", config.endpoint()); - assertEquals("access", config.index()); - List sources = config.sources(); - assertEquals(1, sources.size()); - assertEquals("access", sources.get(0).log()); + assertEquals("foo:123", config.deploymentServer()); + assertEquals("foocli", config.clientName()); } } diff --git a/config-model/src/test/schema-test-files/services.xml b/config-model/src/test/schema-test-files/services.xml index 322f4ed8356..4b6eb12208c 100644 --- a/config-model/src/test/schema-test-files/services.xml +++ b/config-model/src/test/schema-test-files/services.xml @@ -26,6 +26,9 @@ + + + diff --git a/logforwarder/src/apps/vespa-logforwarder-start/cf-handler.cpp b/logforwarder/src/apps/vespa-logforwarder-start/cf-handler.cpp index 479bf33ab59..573a23a373e 100644 --- a/logforwarder/src/apps/vespa-logforwarder-start/cf-handler.cpp +++ b/logforwarder/src/apps/vespa-logforwarder-start/cf-handler.cpp @@ -25,12 +25,9 @@ CfHandler::doConfigure() std::unique_ptr cfg(_handle->getConfig()); const LogforwarderConfig& config(*cfg); - printf("logforwarder type: %s\n", config.type.c_str()); - for (unsigned int i = 0; i < config.sources.size(); ++i) { - printf("source %d is: %s\n", i, config.sources[i].log.c_str()); - } - printf("endpoint: %s\n", config.endpoint.c_str()); - printf("index: %s\n", config.index.c_str()); + printf("logforwarder:\n"); + printf(" deployment server: %s\n", config.deploymentServer.c_str()); + printf(" client name: %s\n", config.clientName.c_str()); } void diff --git a/logforwarder/src/apps/vespa-logforwarder-start/logforwarder.def b/logforwarder/src/apps/vespa-logforwarder-start/logforwarder.def index 66750a81af8..205e8ad3b8c 100644 --- a/logforwarder/src/apps/vespa-logforwarder-start/logforwarder.def +++ b/logforwarder/src/apps/vespa-logforwarder-start/logforwarder.def @@ -1,7 +1,6 @@ namespace=cloud.config -# Forwarder that forwards onle or more types of log to an endpoint -type string -sources[].log string -endpoint string -index string +# only splunk type config for now + +deploymentServer string default="" +clientName string default="" diff --git a/logforwarder/src/main/resources/configdefinitions/logforwarder.def b/logforwarder/src/main/resources/configdefinitions/logforwarder.def index 66750a81af8..205e8ad3b8c 100644 --- a/logforwarder/src/main/resources/configdefinitions/logforwarder.def +++ b/logforwarder/src/main/resources/configdefinitions/logforwarder.def @@ -1,7 +1,6 @@ namespace=cloud.config -# Forwarder that forwards onle or more types of log to an endpoint -type string -sources[].log string -endpoint string -index string +# only splunk type config for now + +deploymentServer string default="" +clientName string default="" -- cgit v1.2.3 From 4dcb4d900d6ac8143e95cf7189b40fbc464182e6 Mon Sep 17 00:00:00 2001 From: Arne Juul Date: Tue, 3 Oct 2017 09:32:30 +0000 Subject: write config file --- .../apps/vespa-logforwarder-start/cf-handler.cpp | 37 +++++++++++++++++++--- 1 file changed, 32 insertions(+), 5 deletions(-) diff --git a/logforwarder/src/apps/vespa-logforwarder-start/cf-handler.cpp b/logforwarder/src/apps/vespa-logforwarder-start/cf-handler.cpp index 573a23a373e..13370c08b59 100644 --- a/logforwarder/src/apps/vespa-logforwarder-start/cf-handler.cpp +++ b/logforwarder/src/apps/vespa-logforwarder-start/cf-handler.cpp @@ -1,6 +1,7 @@ // Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. #include "cf-handler.h" +#include #include #include @@ -19,15 +20,41 @@ CfHandler::subscribe(const std::string & configId, uint64_t timeoutMS) _handle = _subscriber.subscribe(configId, timeoutMS); } +namespace { +std::string +cfFilePath() { + std::string path = vespa::Defaults::underVespaHome("var/db/vespa/splunk"); + DIR *dp = opendir(path.c_str()); + if (dp == NULL) { + if (errno != ENOTDIR || mkdir(path.c_str() != 0)) { + perror(path.c_str()); + } + } + if (dp != NULL) closedir(dp); + path += "/deploymentclient.conf; + return path; +} +} + void CfHandler::doConfigure() { std::unique_ptr cfg(_handle->getConfig()); const LogforwarderConfig& config(*cfg); - printf("logforwarder:\n"); - printf(" deployment server: %s\n", config.deploymentServer.c_str()); - printf(" client name: %s\n", config.clientName.c_str()); + std::string path = cfFilePath(); + std::string tmpPath = path + ".new"; + FILE *fp = fopen(tmpPath.c_str(), "w"); + if (fp == NULL) return; + + fprintf(fp, "[deployment-client]\n"); + fprintf(fp, "clientName = %s\n", config.clientName.c_str()); + fprintf(fp, "\n"); + fprintf(fp, "[target-broker:deploymentServer]\n"); + fprintf(fp, "targetUri = %s\n", config.deploymentServer.c_str()); + + fclose(fp); + rename(tmpPath.c_str(), path.c_str()); } void @@ -43,9 +70,10 @@ constexpr uint64_t CONFIG_TIMEOUT_MS = 30 * 1000; void CfHandler::start(const char *configId) { - LOG(debug, "Reading configuration configid '%s'", configId); + LOG(debug, "Reading configuration with id '%s'", configId); try { subscribe(configId, CONFIG_TIMEOUT_MS); + doConfigure(); } catch (config::ConfigTimeoutException & ex) { LOG(warning, "Timout getting config, please check your setup. Will exit and restart: %s", ex.getMessage().c_str()); exit(EXIT_FAILURE); @@ -56,5 +84,4 @@ CfHandler::start(const char *configId) LOG(error, "Fatal: Could not get config, please check your setup: %s", ex.getMessage().c_str()); exit(EXIT_FAILURE); } - doConfigure(); } -- cgit v1.2.3 From 6e3ba633e61824224fc4160928f1b8bd4e81b50e Mon Sep 17 00:00:00 2001 From: Arne Juul Date: Tue, 3 Oct 2017 13:43:24 +0000 Subject: move logforwarder.def to configdefinitions module --- config-model/pom.xml | 5 -- configdefinitions/src/vespa/CMakeLists.txt | 2 + configdefinitions/src/vespa/logforwarder.def | 6 ++ logforwarder/pom.xml | 40 ------------ .../apps/vespa-logforwarder-start/CMakeLists.txt | 3 +- .../apps/vespa-logforwarder-start/cf-handler.cpp | 8 ++- .../src/apps/vespa-logforwarder-start/cf-handler.h | 2 +- .../apps/vespa-logforwarder-start/logforwarder.def | 6 -- .../resources/configdefinitions/logforwarder.def | 6 -- .../src/main/sh/vespa-logforwarder-start.sh | 72 ---------------------- pom.xml | 1 - 11 files changed, 16 insertions(+), 135 deletions(-) create mode 100644 configdefinitions/src/vespa/logforwarder.def delete mode 100644 logforwarder/pom.xml delete mode 100644 logforwarder/src/apps/vespa-logforwarder-start/logforwarder.def delete mode 100644 logforwarder/src/main/resources/configdefinitions/logforwarder.def delete mode 100755 logforwarder/src/main/sh/vespa-logforwarder-start.sh diff --git a/config-model/pom.xml b/config-model/pom.xml index 8d8ea3203b5..4e79da3279d 100644 --- a/config-model/pom.xml +++ b/config-model/pom.xml @@ -284,11 +284,6 @@ searchsummary ${project.version} - - com.yahoo.vespa - logforwarder - ${project.version} - org.scalatest scalatest_${scala.major-version} diff --git a/configdefinitions/src/vespa/CMakeLists.txt b/configdefinitions/src/vespa/CMakeLists.txt index 4ed4dc06d41..9297383c53f 100644 --- a/configdefinitions/src/vespa/CMakeLists.txt +++ b/configdefinitions/src/vespa/CMakeLists.txt @@ -28,6 +28,8 @@ vespa_generate_config(configdefinitions lb-services.def) install_config_definition(lb-services.def cloud.config.lb-services.def) vespa_generate_config(configdefinitions load-type.def) install_config_definition(load-type.def vespa.config.content.load-type.def) +vespa_generate_config(configdefinitions logforwarder.def) +install_config_definition(logforwarder.def cloud.config.logforwarder.def) vespa_generate_config(configdefinitions messagetyperouteselectorpolicy.def) install_config_definition(messagetyperouteselectorpolicy.def vespa.config.content.messagetyperouteselectorpolicy.def) vespa_generate_config(configdefinitions model.def) diff --git a/configdefinitions/src/vespa/logforwarder.def b/configdefinitions/src/vespa/logforwarder.def new file mode 100644 index 00000000000..205e8ad3b8c --- /dev/null +++ b/configdefinitions/src/vespa/logforwarder.def @@ -0,0 +1,6 @@ +namespace=cloud.config + +# only splunk type config for now + +deploymentServer string default="" +clientName string default="" diff --git a/logforwarder/pom.xml b/logforwarder/pom.xml deleted file mode 100644 index 505ca9f108b..00000000000 --- a/logforwarder/pom.xml +++ /dev/null @@ -1,40 +0,0 @@ - - - 4.0.0 - - com.yahoo.vespa - parent - 6-SNAPSHOT - - logforwarder - 6-SNAPSHOT - jar - ${project.artifactId} - - - com.yahoo.vespa - config-lib - ${project.version} - - - - - - com.yahoo.vespa - config-class-plugin - ${project.version} - - - config-gen - - config-gen - - - - - - - diff --git a/logforwarder/src/apps/vespa-logforwarder-start/CMakeLists.txt b/logforwarder/src/apps/vespa-logforwarder-start/CMakeLists.txt index ac9667d5f9e..be124fd641c 100644 --- a/logforwarder/src/apps/vespa-logforwarder-start/CMakeLists.txt +++ b/logforwarder/src/apps/vespa-logforwarder-start/CMakeLists.txt @@ -8,6 +8,5 @@ vespa_add_executable(vespa-logforwarder-start_app INSTALL bin DEPENDS config_cloudconfig + configdefinitions ) -vespa_generate_config(vespa-logforwarder-start_app logforwarder.def) -install(FILES logforwarder.def RENAME cloud.config.logforwarder.def DESTINATION var/db/vespa/config_server/serverdb/classes) diff --git a/logforwarder/src/apps/vespa-logforwarder-start/cf-handler.cpp b/logforwarder/src/apps/vespa-logforwarder-start/cf-handler.cpp index 13370c08b59..b4b4bdbc7f2 100644 --- a/logforwarder/src/apps/vespa-logforwarder-start/cf-handler.cpp +++ b/logforwarder/src/apps/vespa-logforwarder-start/cf-handler.cpp @@ -1,6 +1,10 @@ // Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. #include "cf-handler.h" +#include +#include +#include +#include #include #include #include @@ -26,12 +30,12 @@ cfFilePath() { std::string path = vespa::Defaults::underVespaHome("var/db/vespa/splunk"); DIR *dp = opendir(path.c_str()); if (dp == NULL) { - if (errno != ENOTDIR || mkdir(path.c_str() != 0)) { + if (errno != ENOTDIR || mkdir(path.c_str(), 0755) != 0) { perror(path.c_str()); } } if (dp != NULL) closedir(dp); - path += "/deploymentclient.conf; + path += "/deploymentclient.conf"; return path; } } diff --git a/logforwarder/src/apps/vespa-logforwarder-start/cf-handler.h b/logforwarder/src/apps/vespa-logforwarder-start/cf-handler.h index 6ad27d81b0d..99f0a6cd6d5 100644 --- a/logforwarder/src/apps/vespa-logforwarder-start/cf-handler.h +++ b/logforwarder/src/apps/vespa-logforwarder-start/cf-handler.h @@ -2,7 +2,7 @@ #pragma once #include -#include "config-logforwarder.h" +#include using cloud::config::LogforwarderConfig; diff --git a/logforwarder/src/apps/vespa-logforwarder-start/logforwarder.def b/logforwarder/src/apps/vespa-logforwarder-start/logforwarder.def deleted file mode 100644 index 205e8ad3b8c..00000000000 --- a/logforwarder/src/apps/vespa-logforwarder-start/logforwarder.def +++ /dev/null @@ -1,6 +0,0 @@ -namespace=cloud.config - -# only splunk type config for now - -deploymentServer string default="" -clientName string default="" diff --git a/logforwarder/src/main/resources/configdefinitions/logforwarder.def b/logforwarder/src/main/resources/configdefinitions/logforwarder.def deleted file mode 100644 index 205e8ad3b8c..00000000000 --- a/logforwarder/src/main/resources/configdefinitions/logforwarder.def +++ /dev/null @@ -1,6 +0,0 @@ -namespace=cloud.config - -# only splunk type config for now - -deploymentServer string default="" -clientName string default="" diff --git a/logforwarder/src/main/sh/vespa-logforwarder-start.sh b/logforwarder/src/main/sh/vespa-logforwarder-start.sh deleted file mode 100755 index 20864d7b4e6..00000000000 --- a/logforwarder/src/main/sh/vespa-logforwarder-start.sh +++ /dev/null @@ -1,72 +0,0 @@ -#!/bin/sh -# Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. - -# BEGIN environment bootstrap section -# Do not edit between here and END as this section should stay identical in all scripts - -findpath () { - myname=${0} - mypath=${myname%/*} - myname=${myname##*/} - if [ "$mypath" ] && [ -d "$mypath" ]; then - return - fi - mypath=$(pwd) - if [ -f "${mypath}/${myname}" ]; then - return - fi - echo "FATAL: Could not figure out the path where $myname lives from $0" - exit 1 -} - -COMMON_ENV=libexec/vespa/common-env.sh - -source_common_env () { - if [ "$VESPA_HOME" ] && [ -d "$VESPA_HOME" ]; then - export VESPA_HOME - common_env=$VESPA_HOME/$COMMON_ENV - if [ -f "$common_env" ]; then - . $common_env - return - fi - fi - return 1 -} - -findroot () { - source_common_env && return - if [ "$VESPA_HOME" ]; then - echo "FATAL: bad VESPA_HOME value '$VESPA_HOME'" - exit 1 - fi - if [ "$ROOT" ] && [ -d "$ROOT" ]; then - VESPA_HOME="$ROOT" - source_common_env && return - fi - findpath - while [ "$mypath" ]; do - VESPA_HOME=${mypath} - source_common_env && return - mypath=${mypath%/*} - done - echo "FATAL: missing VESPA_HOME environment variable" - echo "Could not locate $COMMON_ENV anywhere" - exit 1 -} - -findroot - -# END environment bootstrap section - -ROOT=${VESPA_HOME%/} -export ROOT -cd $ROOT || { echo "Cannot cd to $ROOT" 1>&2; exit 1; } - -# TODO: Get config and start logforwarder properly - -configid=$1 - -config=`$VESPA_HOME/bin/vespa-get-config -j -n cloud.config.logforwarder -i $configid` -echo $config - -sleep 10000000 diff --git a/pom.xml b/pom.xml index 364c79f2cfb..0c41a993fdf 100644 --- a/pom.xml +++ b/pom.xml @@ -977,7 +977,6 @@ libmlr linguistics logd - logforwarder logserver messagebus-disc messagebus -- cgit v1.2.3 From 592784da1d4879c7f653c77f83c3873e461b5172 Mon Sep 17 00:00:00 2001 From: Arne Juul Date: Wed, 4 Oct 2017 08:42:03 +0000 Subject: add administrative files --- logforwarder/OWNERS | 1 + logforwarder/README | 5 +++++ 2 files changed, 6 insertions(+) create mode 100644 logforwarder/OWNERS create mode 100644 logforwarder/README diff --git a/logforwarder/OWNERS b/logforwarder/OWNERS new file mode 100644 index 00000000000..67cd2820bb8 --- /dev/null +++ b/logforwarder/OWNERS @@ -0,0 +1 @@ +arnej27959 diff --git a/logforwarder/README b/logforwarder/README new file mode 100644 index 00000000000..30f5992157b --- /dev/null +++ b/logforwarder/README @@ -0,0 +1,5 @@ +Utility for log forwarding management + +currently this only supports "splunk", and +just saves splunk config in a file using the +appropriate format. -- cgit v1.2.3 From 51342b8ef547b97d2087faca64f4300a26037cd8 Mon Sep 17 00:00:00 2001 From: Arne Juul Date: Wed, 4 Oct 2017 08:42:12 +0000 Subject: fix binary name --- logforwarder/src/apps/vespa-logforwarder-start/.gitignore | 2 +- logforwarder/src/apps/vespa-logforwarder-start/CMakeLists.txt | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/logforwarder/src/apps/vespa-logforwarder-start/.gitignore b/logforwarder/src/apps/vespa-logforwarder-start/.gitignore index d98b2a9ccc7..64d78991a4c 100644 --- a/logforwarder/src/apps/vespa-logforwarder-start/.gitignore +++ b/logforwarder/src/apps/vespa-logforwarder-start/.gitignore @@ -1,3 +1,3 @@ -vespa-logforwarder-start_app +vespa-logforwarder-start config-logforwarder.cpp config-logforwarder.h diff --git a/logforwarder/src/apps/vespa-logforwarder-start/CMakeLists.txt b/logforwarder/src/apps/vespa-logforwarder-start/CMakeLists.txt index be124fd641c..f26edd8eee8 100644 --- a/logforwarder/src/apps/vespa-logforwarder-start/CMakeLists.txt +++ b/logforwarder/src/apps/vespa-logforwarder-start/CMakeLists.txt @@ -1,10 +1,10 @@ # Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. -vespa_add_executable(vespa-logforwarder-start_app +vespa_add_executable(logforwarder-start_app SOURCES main.cpp cf-handler.cpp sig-catch.cpp - OUTPUT_NAME vespa-logforwarder-start_app + OUTPUT_NAME vespa-logforwarder-start INSTALL bin DEPENDS config_cloudconfig -- cgit v1.2.3 From 4bd3cbb248cd5eaeda18d7e7d8d61fd2874854f0 Mon Sep 17 00:00:00 2001 From: Arne Juul Date: Thu, 5 Oct 2017 06:29:31 +0000 Subject: binary moved --- .../src/main/java/com/yahoo/vespa/model/admin/LogForwarder.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config-model/src/main/java/com/yahoo/vespa/model/admin/LogForwarder.java b/config-model/src/main/java/com/yahoo/vespa/model/admin/LogForwarder.java index 0df6566829c..46f5807b350 100644 --- a/config-model/src/main/java/com/yahoo/vespa/model/admin/LogForwarder.java +++ b/config-model/src/main/java/com/yahoo/vespa/model/admin/LogForwarder.java @@ -53,7 +53,7 @@ public class LogForwarder extends AbstractService implements LogforwarderConfig. /** * @return The command used to start LogForwarder */ - public String getStartupCommand() { return "exec $ROOT/libexec/vespa/vespa-logforwarder-start -c " + getConfigId(); } + public String getStartupCommand() { return "exec $ROOT/bin/vespa-logforwarder-start -c " + getConfigId(); } @Override public void getConfig(LogforwarderConfig.Builder builder) { -- cgit v1.2.3 From 38c71c457fd6d3177d541b9dcf2ec32038d8c771 Mon Sep 17 00:00:00 2001 From: Arne Juul Date: Thu, 5 Oct 2017 07:25:40 +0000 Subject: handle SIGPIPE --- logforwarder/src/apps/vespa-logforwarder-start/sig-catch.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/logforwarder/src/apps/vespa-logforwarder-start/sig-catch.cpp b/logforwarder/src/apps/vespa-logforwarder-start/sig-catch.cpp index acd82ffd29e..b10275d515e 100644 --- a/logforwarder/src/apps/vespa-logforwarder-start/sig-catch.cpp +++ b/logforwarder/src/apps/vespa-logforwarder-start/sig-catch.cpp @@ -11,6 +11,7 @@ sig_atomic_t stop = 0; SigCatch::SigCatch() { + sigPermanent(SIGPIPE, SIG_IGN); sigPermanent(SIGTERM, setStopFlag); sigPermanent(SIGINT, setStopFlag); } -- cgit v1.2.3 From 187486aee56dfacf6478d412c9385cb6b17a6193 Mon Sep 17 00:00:00 2001 From: Arne Juul Date: Thu, 5 Oct 2017 07:25:53 +0000 Subject: fix logic * missing directory gives ENOENT * cannot get config just after subscribe, must do nextConfig() first --- logforwarder/src/apps/vespa-logforwarder-start/cf-handler.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/logforwarder/src/apps/vespa-logforwarder-start/cf-handler.cpp b/logforwarder/src/apps/vespa-logforwarder-start/cf-handler.cpp index b4b4bdbc7f2..e34a83030e8 100644 --- a/logforwarder/src/apps/vespa-logforwarder-start/cf-handler.cpp +++ b/logforwarder/src/apps/vespa-logforwarder-start/cf-handler.cpp @@ -30,11 +30,12 @@ cfFilePath() { std::string path = vespa::Defaults::underVespaHome("var/db/vespa/splunk"); DIR *dp = opendir(path.c_str()); if (dp == NULL) { - if (errno != ENOTDIR || mkdir(path.c_str(), 0755) != 0) { + if (errno != ENOENT || mkdir(path.c_str(), 0755) != 0) { perror(path.c_str()); } + } else { + closedir(dp); } - if (dp != NULL) closedir(dp); path += "/deploymentclient.conf"; return path; } @@ -77,7 +78,6 @@ CfHandler::start(const char *configId) LOG(debug, "Reading configuration with id '%s'", configId); try { subscribe(configId, CONFIG_TIMEOUT_MS); - doConfigure(); } catch (config::ConfigTimeoutException & ex) { LOG(warning, "Timout getting config, please check your setup. Will exit and restart: %s", ex.getMessage().c_str()); exit(EXIT_FAILURE); -- cgit v1.2.3 From c206adf7dfde86c32653937a43e0ef08de67ed29 Mon Sep 17 00:00:00 2001 From: Arne Juul Date: Thu, 5 Oct 2017 07:27:08 +0000 Subject: cosmetics --- .../com/yahoo/vespa/model/builder/xml/dom/DomAdminBuilderBase.java | 1 - .../java/com/yahoo/vespa/model/builder/xml/dom/DomAdminV4Builder.java | 2 -- .../src/test/java/com/yahoo/vespa/model/admin/AdminTestCase.java | 3 --- 3 files changed, 6 deletions(-) diff --git a/config-model/src/main/java/com/yahoo/vespa/model/builder/xml/dom/DomAdminBuilderBase.java b/config-model/src/main/java/com/yahoo/vespa/model/builder/xml/dom/DomAdminBuilderBase.java index 0a93bee962d..3049112ac0a 100644 --- a/config-model/src/main/java/com/yahoo/vespa/model/builder/xml/dom/DomAdminBuilderBase.java +++ b/config-model/src/main/java/com/yahoo/vespa/model/builder/xml/dom/DomAdminBuilderBase.java @@ -19,7 +19,6 @@ import com.yahoo.config.application.api.FileRegistry; import org.w3c.dom.Element; import java.util.*; -import java.util.stream.Collectors; import static com.yahoo.vespa.model.admin.monitoring.builder.PredefinedMetricSets.predefinedMetricSets; 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 5642c788c0d..cb8ec205395 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 @@ -19,8 +19,6 @@ import java.util.Collection; import java.util.Collections; import java.util.List; import java.util.Optional; -import java.util.Set; -import java.util.stream.Collectors; /** * Builds the admin model from a version 4 XML tag, or as a default when an admin 3 tag or no admin tag is used. diff --git a/config-model/src/test/java/com/yahoo/vespa/model/admin/AdminTestCase.java b/config-model/src/test/java/com/yahoo/vespa/model/admin/AdminTestCase.java index 0a2690edec9..b5375ccbce4 100644 --- a/config-model/src/test/java/com/yahoo/vespa/model/admin/AdminTestCase.java +++ b/config-model/src/test/java/com/yahoo/vespa/model/admin/AdminTestCase.java @@ -276,6 +276,3 @@ public class AdminTestCase { assertTrue(configIds.toString(), configIds.contains("admin/logforwarder.0")); } } - - - -- cgit v1.2.3