Marvel: Update settings

Original commit: elastic/x-pack-elasticsearch@2cc525e95a
This commit is contained in:
Tanguy Leroux 2015-08-18 12:32:49 +02:00
parent 29f8362bce
commit 4756f07f2b
22 changed files with 487 additions and 321 deletions

View File

@ -16,7 +16,8 @@ import org.elasticsearch.common.logging.Loggers;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.marvel.agent.AgentService;
import org.elasticsearch.marvel.agent.exporter.HttpESExporter;
import org.elasticsearch.marvel.agent.settings.MarvelSettingsService;
import org.elasticsearch.marvel.agent.settings.MarvelSetting;
import org.elasticsearch.marvel.agent.settings.MarvelSettings;
import org.elasticsearch.marvel.license.LicenseService;
import org.elasticsearch.plugins.AbstractPlugin;
import org.elasticsearch.tribe.TribeService;
@ -81,21 +82,16 @@ public class MarvelPlugin extends AbstractPlugin {
}
public void onModule(ClusterModule module) {
// AgentService
module.registerClusterDynamicSetting(AgentService.SETTINGS_INTERVAL, Validator.EMPTY);
module.registerClusterDynamicSetting(AgentService.SETTINGS_STATS_TIMEOUT, Validator.EMPTY);
// HttpESExporter
module.registerClusterDynamicSetting(HttpESExporter.SETTINGS_HOSTS, Validator.EMPTY);
module.registerClusterDynamicSetting(HttpESExporter.SETTINGS_HOSTS + ".*", Validator.EMPTY);
module.registerClusterDynamicSetting(HttpESExporter.SETTINGS_TIMEOUT, Validator.EMPTY);
module.registerClusterDynamicSetting(HttpESExporter.SETTINGS_READ_TIMEOUT, Validator.EMPTY);
module.registerClusterDynamicSetting(HttpESExporter.SETTINGS_SSL_HOSTNAME_VERIFICATION, Validator.EMPTY);
// MarvelSettingsService
module.registerClusterDynamicSetting(MarvelSettingsService.CLUSTER_STATE_TIMEOUT, Validator.EMPTY);
module.registerClusterDynamicSetting(MarvelSettingsService.CLUSTER_STATS_TIMEOUT, Validator.EMPTY);
module.registerClusterDynamicSetting(MarvelSettingsService.INDEX_RECOVERY_ACTIVE_ONLY, Validator.EMPTY);
module.registerClusterDynamicSetting(MarvelSettingsService.INDEX_RECOVERY_TIMEOUT, Validator.EMPTY);
module.registerClusterDynamicSetting(MarvelSettingsService.INDICES, Validator.EMPTY);
module.registerClusterDynamicSetting(MarvelSettingsService.INDEX_STATS_TIMEOUT, Validator.EMPTY);
for (MarvelSetting setting : MarvelSettings.dynamicSettings()) {
module.registerClusterDynamicSetting(setting.dynamicSettingName(), setting.dynamicValidator());
}
}
}

View File

@ -5,62 +5,68 @@
*/
package org.elasticsearch.marvel.agent;
import com.google.common.collect.ImmutableSet;
import org.elasticsearch.common.component.AbstractLifecycleComponent;
import org.elasticsearch.common.inject.Inject;
import org.elasticsearch.common.regex.Regex;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.unit.TimeValue;
import org.elasticsearch.common.util.CollectionUtils;
import org.elasticsearch.common.util.concurrent.EsExecutors;
import org.elasticsearch.marvel.agent.collector.Collector;
import org.elasticsearch.marvel.agent.exporter.Exporter;
import org.elasticsearch.marvel.agent.exporter.MarvelDoc;
import org.elasticsearch.marvel.agent.settings.MarvelSettings;
import org.elasticsearch.marvel.license.LicenseService;
import org.elasticsearch.node.settings.NodeSettingsService;
import java.util.Collection;
import java.util.Set;
import java.util.*;
public class AgentService extends AbstractLifecycleComponent<AgentService> implements NodeSettingsService.Listener {
private static final String SETTINGS_BASE = "marvel.agent.";
public static final String SETTINGS_INTERVAL = SETTINGS_BASE + "interval";
public static final String SETTINGS_ENABLED = SETTINGS_BASE + "enabled";
public static final String SETTINGS_STATS_TIMEOUT = SETTINGS_BASE + "stats.timeout";
private volatile ExportingWorker exportingWorker;
private volatile Thread workerThread;
private volatile long samplingInterval;
private volatile TimeValue clusterStatsTimeout;
private final MarvelSettings marvelSettings;
private final Collection<Collector> collectors;
private final Collection<Exporter> exporters;
@Inject
public AgentService(Settings settings, NodeSettingsService nodeSettingsService,
LicenseService licenseService,
LicenseService licenseService, MarvelSettings marvelSettings,
Set<Collector> collectors, Set<Exporter> exporters) {
super(settings);
this.samplingInterval = settings.getAsTime(SETTINGS_INTERVAL, TimeValue.timeValueSeconds(10)).millis();
this.marvelSettings = marvelSettings;
this.samplingInterval = marvelSettings.interval().millis();
TimeValue statsTimeout = settings.getAsTime(SETTINGS_STATS_TIMEOUT, TimeValue.timeValueMinutes(10));
if (settings.getAsBoolean(SETTINGS_ENABLED, true)) {
this.collectors = ImmutableSet.copyOf(collectors);
this.exporters = ImmutableSet.copyOf(exporters);
} else {
this.collectors = ImmutableSet.of();
this.exporters = ImmutableSet.of();
logger.info("collecting disabled by settings");
}
this.collectors = Collections.unmodifiableSet(filterCollectors(collectors, marvelSettings.collectors()));
this.exporters = Collections.unmodifiableSet(exporters);
nodeSettingsService.addListener(this);
logger.trace("marvel is running in [{}] mode", licenseService.mode());
}
protected Set<Collector> filterCollectors(Set<Collector> collectors, String[] filters) {
if (CollectionUtils.isEmpty(filters)) {
return collectors;
}
Set<Collector> list = new HashSet<>();
for (Collector collector : collectors) {
if (Regex.simpleMatch(filters, collector.name().toLowerCase(Locale.ROOT))) {
list.add(collector);
/* TODO Always add license collector
} else if (collector instanceof LicensesCollector) {
list.add(collector);
*/
}
}
return list;
}
protected void applyIntervalSettings() {
if (samplingInterval <= 0) {
logger.info("data sampling is disabled due to interval settings [{}]", samplingInterval);
@ -142,7 +148,7 @@ public class AgentService extends AbstractLifecycleComponent<AgentService> imple
@Override
public void onRefreshSettings(Settings settings) {
TimeValue newSamplingInterval = settings.getAsTime(SETTINGS_INTERVAL, null);
TimeValue newSamplingInterval = settings.getAsTime(MarvelSettings.INTERVAL, null);
if (newSamplingInterval != null && newSamplingInterval.millis() != samplingInterval) {
logger.info("sampling interval updated to [{}]", newSamplingInterval);
samplingInterval = newSamplingInterval.millis();
@ -156,10 +162,14 @@ public class AgentService extends AbstractLifecycleComponent<AgentService> imple
@Override
public void run() {
boolean firstRun = true;
while (!closed) {
// sleep first to allow node to complete initialization before collecting the first start
try {
Thread.sleep(samplingInterval);
long interval = (firstRun && (marvelSettings.startUpDelay() != null)) ? marvelSettings.startUpDelay().millis() : samplingInterval;
Thread.sleep(interval);
if (closed) {
continue;
}
@ -173,11 +183,18 @@ public class AgentService extends AbstractLifecycleComponent<AgentService> imple
exporter.export(results);
}
}
if (closed) {
// Stop collecting if the worker is marked as closed
break;
}
}
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
} catch (Throwable t) {
logger.error("Background thread had an uncaught exception:", t);
} finally {
firstRun = false;
}
}
logger.debug("worker shutdown");

View File

@ -13,7 +13,7 @@ import org.elasticsearch.common.component.AbstractLifecycleComponent;
import org.elasticsearch.common.inject.Inject;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.marvel.agent.exporter.MarvelDoc;
import org.elasticsearch.marvel.agent.settings.MarvelSettingsService;
import org.elasticsearch.marvel.agent.settings.MarvelSettings;
import java.util.Collection;
@ -23,11 +23,11 @@ public abstract class AbstractCollector<T> extends AbstractLifecycleComponent<T>
protected final ClusterService clusterService;
protected final ClusterName clusterName;
protected final MarvelSettingsService marvelSettings;
protected final MarvelSettings marvelSettings;
@Inject
public AbstractCollector(Settings settings, String name, ClusterService clusterService,
ClusterName clusterName, MarvelSettingsService marvelSettings) {
ClusterName clusterName, MarvelSettings marvelSettings) {
super(settings);
this.name = name;
this.clusterService = clusterService;

View File

@ -16,7 +16,7 @@ import org.elasticsearch.common.inject.Inject;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.marvel.agent.collector.AbstractCollector;
import org.elasticsearch.marvel.agent.exporter.MarvelDoc;
import org.elasticsearch.marvel.agent.settings.MarvelSettingsService;
import org.elasticsearch.marvel.agent.settings.MarvelSettings;
import java.util.Collection;
@ -35,7 +35,7 @@ public class ClusterStateCollector extends AbstractCollector<ClusterStateCollect
@Inject
public ClusterStateCollector(Settings settings, ClusterService clusterService,
ClusterName clusterName, MarvelSettingsService marvelSettings, Client client) {
ClusterName clusterName, MarvelSettings marvelSettings, Client client) {
super(settings, NAME, clusterService, clusterName, marvelSettings);
this.client = client;
}

View File

@ -14,7 +14,7 @@ import org.elasticsearch.common.inject.Inject;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.marvel.agent.collector.AbstractCollector;
import org.elasticsearch.marvel.agent.exporter.MarvelDoc;
import org.elasticsearch.marvel.agent.settings.MarvelSettingsService;
import org.elasticsearch.marvel.agent.settings.MarvelSettings;
import java.util.Collection;
@ -33,7 +33,7 @@ public class ClusterStatsCollector extends AbstractCollector<ClusterStatsCollect
@Inject
public ClusterStatsCollector(Settings settings, ClusterService clusterService,
ClusterName clusterName, MarvelSettingsService marvelSettings, Client client) {
ClusterName clusterName, MarvelSettings marvelSettings, Client client) {
super(settings, NAME, clusterService, clusterName, marvelSettings);
this.client = client;
}

View File

@ -15,7 +15,7 @@ import org.elasticsearch.common.inject.Inject;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.marvel.agent.collector.AbstractCollector;
import org.elasticsearch.marvel.agent.exporter.MarvelDoc;
import org.elasticsearch.marvel.agent.settings.MarvelSettingsService;
import org.elasticsearch.marvel.agent.settings.MarvelSettings;
import java.util.Collection;
@ -34,7 +34,7 @@ public class IndexRecoveryCollector extends AbstractCollector<IndexRecoveryColle
@Inject
public IndexRecoveryCollector(Settings settings, ClusterService clusterService,
ClusterName clusterName, MarvelSettingsService marvelSettings, Client client) {
ClusterName clusterName, MarvelSettings marvelSettings, Client client) {
super(settings, NAME, clusterService, clusterName, marvelSettings);
this.client = client;
}

View File

@ -16,7 +16,7 @@ import org.elasticsearch.common.inject.Inject;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.marvel.agent.collector.AbstractCollector;
import org.elasticsearch.marvel.agent.exporter.MarvelDoc;
import org.elasticsearch.marvel.agent.settings.MarvelSettingsService;
import org.elasticsearch.marvel.agent.settings.MarvelSettings;
import java.util.Collection;
@ -35,7 +35,7 @@ public class IndexStatsCollector extends AbstractCollector<IndexStatsCollector>
@Inject
public IndexStatsCollector(Settings settings, ClusterService clusterService,
ClusterName clusterName, MarvelSettingsService marvelSettings, Client client) {
ClusterName clusterName, MarvelSettings marvelSettings, Client client) {
super(settings, NAME, clusterService, clusterName, marvelSettings);
this.client = client;
}
@ -50,6 +50,7 @@ public class IndexStatsCollector extends AbstractCollector<IndexStatsCollector>
ImmutableList.Builder<MarvelDoc> results = ImmutableList.builder();
IndicesStatsResponse indicesStats = client.admin().indices().prepareStats()
.setRefresh(true)
.setIndices(marvelSettings.indices())
.setIndicesOptions(IndicesOptions.lenientExpandOpen())
.get(marvelSettings.indexStatsTimeout());

View File

@ -20,7 +20,7 @@ import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.discovery.DiscoveryService;
import org.elasticsearch.marvel.agent.collector.AbstractCollector;
import org.elasticsearch.marvel.agent.exporter.MarvelDoc;
import org.elasticsearch.marvel.agent.settings.MarvelSettingsService;
import org.elasticsearch.marvel.agent.settings.MarvelSettings;
import org.elasticsearch.node.service.NodeService;
import java.util.Collection;
@ -45,7 +45,7 @@ public class NodeStatsCollector extends AbstractCollector<NodeStatsCollector> {
@Inject
public NodeStatsCollector(Settings settings, ClusterService clusterService, ClusterName clusterName,
MarvelSettingsService marvelSettings,
MarvelSettings marvelSettings,
NodeService nodeService, DiscoveryService discoveryService,
Provider<DiskThresholdDecider> diskThresholdDeciderProvider) {
super(settings, NAME, clusterService, clusterName, marvelSettings);

View File

@ -6,26 +6,28 @@
package org.elasticsearch.marvel.agent.settings;
import org.elasticsearch.ElasticsearchParseException;
import org.elasticsearch.cluster.settings.Validator;
import org.elasticsearch.common.Strings;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.unit.TimeValue;
import java.util.Arrays;
public abstract class MarvelSetting<V> {
private final String name;
private final String description;
private final V defaultValue;
private final boolean dynamic;
private volatile V value;
MarvelSetting(String name, String description, V defaultValue) {
MarvelSetting(String name, String description, V defaultValue, boolean dynamic) {
this.name = name;
this.description = description;
this.defaultValue = defaultValue;
this.value = defaultValue;
this.dynamic = dynamic;
}
abstract boolean onInit(Settings settings);
abstract boolean onRefresh(Settings settings);
public String getName() {
@ -36,15 +38,11 @@ public abstract class MarvelSetting<V> {
return description;
}
public V getDefaultValue() {
return defaultValue;
}
public V getValue() {
return value;
}
public void setValue(V value) {
public synchronized void setValue(V value) {
this.value = value;
}
@ -53,39 +51,46 @@ public abstract class MarvelSetting<V> {
}
public boolean isDynamic() {
return true;
return dynamic;
}
public String dynamicSettingName() {
return getName();
}
public static BooleanSetting booleanSetting(String name, Boolean defaultValue, String description) {
return new BooleanSetting(name, description, defaultValue);
public Validator dynamicValidator() {
return Validator.EMPTY;
}
public static StringSetting stringSetting(String name, String defaultValue, String description) {
return new StringSetting(name, description, defaultValue);
@Override
public String toString() {
return "marvel setting [" + getName() + " : " + getValueAsString() + "]";
}
public static StringArraySetting arraySetting(String name, String[] defaultValue, String description) {
return new StringArraySetting(name, description, defaultValue);
public static BooleanSetting booleanSetting(String name, Boolean defaultValue, String description, boolean dynamic) {
return new BooleanSetting(name, description, defaultValue, dynamic);
}
public static TimeValueSetting timeSetting(String name, TimeValue defaultValue, String description) {
return new TimeValueSetting(name, description, defaultValue);
public static StringSetting stringSetting(String name, String defaultValue, String description, boolean dynamic) {
return new StringSetting(name, description, defaultValue, dynamic);
}
public static StringArraySetting arraySetting(String name, String[] defaultValue, String description, boolean dynamic) {
return new StringArraySetting(name, description, defaultValue, dynamic);
}
public static TimeValueSetting timeSetting(String name, TimeValue defaultValue, String description, boolean dynamic) {
return new TimeValueSetting(name, description, defaultValue, dynamic);
}
public static TimeoutValueSetting timeoutSetting(String name, TimeValue defaultTimeoutValue, String description, boolean dynamic) {
return new TimeoutValueSetting(name, description, defaultTimeoutValue, dynamic);
}
static class BooleanSetting extends MarvelSetting<Boolean> {
BooleanSetting(String name, String description, Boolean defaultValue) {
super(name, description, defaultValue);
}
@Override
boolean onInit(Settings settings) {
setValue(settings.getAsBoolean(getName(), getDefaultValue()));
return true;
BooleanSetting(String name, String description, Boolean defaultValue, boolean dynamic) {
super(name, description, defaultValue, dynamic);
}
@Override
@ -97,18 +102,17 @@ public abstract class MarvelSetting<V> {
}
return false;
}
@Override
public Validator dynamicValidator() {
return Validator.BOOLEAN;
}
}
static class StringSetting extends MarvelSetting<String> {
StringSetting(String name, String description, String defaultValue) {
super(name, description, defaultValue);
}
@Override
boolean onInit(Settings settings) {
setValue(settings.get(getName(), getDefaultValue()));
return true;
StringSetting(String name, String description, String defaultValue, boolean dynamic) {
super(name, description, defaultValue, dynamic);
}
@Override
@ -124,29 +128,14 @@ public abstract class MarvelSetting<V> {
static class StringArraySetting extends MarvelSetting<String[]> {
StringArraySetting(String name, String description, String[] defaultValue) {
super(name, description, defaultValue);
}
@Override
boolean onInit(Settings settings) {
String[] a;
if (getDefaultValue() != null) {
a = settings.getAsArray(getName(), getDefaultValue(), true);
} else {
a = settings.getAsArray(getName());
}
if (a != null) {
setValue(a);
return true;
}
return false;
StringArraySetting(String name, String description, String[] defaultValue, boolean dynamic) {
super(name, description, defaultValue, dynamic);
}
@Override
boolean onRefresh(Settings settings) {
String[] updated = settings.getAsArray(getName(), null);
if (updated != null) {
if ((updated != null) && (!Arrays.equals(updated, getValue()))) {
setValue(updated);
return true;
}
@ -167,18 +156,8 @@ public abstract class MarvelSetting<V> {
static class TimeValueSetting extends MarvelSetting<TimeValue> {
TimeValueSetting(String name, String description, TimeValue defaultValue) {
super(name, description, defaultValue);
}
@Override
boolean onInit(Settings settings) {
TimeValue t = get(settings, getDefaultValue());
if (t != null) {
setValue(t);
return true;
}
return false;
TimeValueSetting(String name, String description, TimeValue defaultValue, boolean dynamic) {
super(name, description, defaultValue, dynamic);
}
@Override
@ -205,5 +184,22 @@ public abstract class MarvelSetting<V> {
}
return null;
}
@Override
public Validator dynamicValidator() {
return Validator.TIME;
}
}
static class TimeoutValueSetting extends TimeValueSetting {
TimeoutValueSetting(String name, String description, TimeValue defaultValue, boolean dynamic) {
super(name, description, defaultValue, dynamic);
}
@Override
public Validator dynamicValidator() {
return Validator.TIMEOUT;
}
}
}

View File

@ -0,0 +1,165 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/
package org.elasticsearch.marvel.agent.settings;
import org.elasticsearch.common.Strings;
import org.elasticsearch.common.component.AbstractComponent;
import org.elasticsearch.common.inject.Inject;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.unit.TimeValue;
import org.elasticsearch.marvel.MarvelPlugin;
import org.elasticsearch.node.settings.NodeSettingsService;
import java.util.*;
import static org.elasticsearch.marvel.agent.settings.MarvelSetting.*;
public class MarvelSettings extends AbstractComponent implements NodeSettingsService.Listener {
private static final String PREFIX = MarvelPlugin.NAME + ".agent.";
public static final String INTERVAL = PREFIX + "interval";
public static final String STARTUP_DELAY = PREFIX + "startup.delay";
public static final String INDEX_STATS_TIMEOUT = PREFIX + "index.stats.timeout";
public static final String INDICES = PREFIX + "indices";
public static final String CLUSTER_STATE_TIMEOUT = PREFIX + "cluster.state.timeout";
public static final String CLUSTER_STATS_TIMEOUT = PREFIX + "cluster.stats.timeout";
public static final String INDEX_RECOVERY_TIMEOUT = PREFIX + "index.recovery.timeout";
public static final String INDEX_RECOVERY_ACTIVE_ONLY = PREFIX + "index.recovery.active_only";
public static final String COLLECTORS = PREFIX + "collectors";
private static Map<String, ? extends MarvelSetting> MARVEL_SETTINGS = Collections.EMPTY_MAP;
static {
Map<String, MarvelSetting> map = new HashMap<>();
map.put(INTERVAL, timeSetting(INTERVAL, TimeValue.timeValueSeconds(10),
"Sampling interval between two collections (default to 10s)", true));
map.put(STARTUP_DELAY, timeSetting(STARTUP_DELAY, null,
"Waiting time before the agent start to collect data (default to sampling interval)", false));
map.put(INDEX_STATS_TIMEOUT, timeoutSetting(INDEX_STATS_TIMEOUT, TimeValue.timeValueMinutes(10),
"Timeout value when collecting indices statistics (default to 10m)", true));
map.put(INDICES, arraySetting(INDICES, Strings.EMPTY_ARRAY,
"List of indices names whose stats will be exported (default to all indices)", true));
map.put(CLUSTER_STATE_TIMEOUT, timeoutSetting(CLUSTER_STATE_TIMEOUT, TimeValue.timeValueMinutes(10),
"Timeout value when collecting the cluster state (default to 10m)", true));
map.put(CLUSTER_STATS_TIMEOUT, timeoutSetting(CLUSTER_STATS_TIMEOUT, TimeValue.timeValueMinutes(10),
"Timeout value when collecting the cluster statistics (default to 10m)", true));
map.put(INDEX_RECOVERY_TIMEOUT, timeoutSetting(INDEX_RECOVERY_TIMEOUT, TimeValue.timeValueMinutes(10),
"Timeout value when collecting the recovery information (default to 10m)", true));
map.put(INDEX_RECOVERY_ACTIVE_ONLY, booleanSetting(INDEX_RECOVERY_ACTIVE_ONLY, Boolean.FALSE,
"INDEX_RECOVERY_ACTIVE_ONLY to indicate if only active recoveries should be collected (default to false: all recoveries are collected)", true));
map.put(COLLECTORS, arraySetting(COLLECTORS, Strings.EMPTY_ARRAY,
"List of collectors allowed to collect data (default to all)", false));
MARVEL_SETTINGS = Collections.unmodifiableMap(map);
}
@Inject
public MarvelSettings(Settings clusterSettings, NodeSettingsService nodeSettingsService) {
super(clusterSettings);
logger.trace("initializing marvel settings:");
updateSettings(clusterSettings, false);
logger.trace("registering the service as a node settings listener");
nodeSettingsService.addListener(this);
}
@Override
public void onRefreshSettings(Settings clusterSettings) {
if (clusterSettings.names() == null || clusterSettings.names().isEmpty()) {
return;
}
updateSettings(clusterSettings, true);
}
private synchronized void updateSettings(Settings clusterSettings, boolean dynamicOnly) {
for (MarvelSetting setting : settings()) {
if (!dynamicOnly || setting.isDynamic()) {
if (setting.onRefresh(clusterSettings)) {
logger.info("{} updated", setting);
}
}
}
}
/**
* Returns the setting corresponding to the given name
*
* @param name The given name
* @return The associated setting, null if not found
*/
synchronized MarvelSetting getSetting(String name) {
MarvelSetting setting = MARVEL_SETTINGS.get(name);
if (setting == null) {
throw new IllegalArgumentException("no marvel setting initialized for [" + name + "]");
}
return setting;
}
/**
* Returns the settings corresponding to the given name
*
* @param name The given name
* @return The associated setting
*/
<T> T getSettingValue(String name) {
MarvelSetting setting = getSetting(name);
if (setting == null) {
throw new IllegalArgumentException("no marvel setting initialized for [" + name + "]");
}
return (T) setting.getValue();
}
public static Collection<? extends MarvelSetting> settings() {
return MARVEL_SETTINGS.values();
}
public static synchronized Collection<MarvelSetting> dynamicSettings() {
List<MarvelSetting> list = new ArrayList<>();
for (MarvelSetting setting : settings()) {
if (setting.isDynamic()) {
list.add(setting);
}
}
return list;
}
public TimeValue interval() {
return getSettingValue(INTERVAL);
}
public TimeValue startUpDelay() {
return getSettingValue(STARTUP_DELAY);
}
public TimeValue indexStatsTimeout() {
return getSettingValue(INDEX_STATS_TIMEOUT);
}
public String[] indices() {
return getSettingValue(INDICES);
}
public TimeValue clusterStateTimeout() {
return getSettingValue(CLUSTER_STATE_TIMEOUT);
}
public TimeValue clusterStatsTimeout() {
return getSettingValue(CLUSTER_STATS_TIMEOUT);
}
public TimeValue recoveryTimeout() {
return getSettingValue(INDEX_RECOVERY_TIMEOUT);
}
public boolean recoveryActiveOnly() {
return getSettingValue(INDEX_RECOVERY_ACTIVE_ONLY);
}
public String[] collectors() {
return getSettingValue(COLLECTORS);
}
}

View File

@ -11,6 +11,6 @@ public class MarvelSettingsModule extends AbstractModule {
@Override
protected void configure() {
bind(MarvelSettingsService.class).asEagerSingleton();
bind(MarvelSettings.class).asEagerSingleton();
}
}

View File

@ -1,115 +0,0 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/
package org.elasticsearch.marvel.agent.settings;
import com.google.common.collect.ImmutableList;
import org.elasticsearch.common.Strings;
import org.elasticsearch.common.component.AbstractComponent;
import org.elasticsearch.common.inject.Inject;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.unit.TimeValue;
import org.elasticsearch.marvel.MarvelPlugin;
import org.elasticsearch.marvel.agent.settings.MarvelSetting.StringArraySetting;
import org.elasticsearch.marvel.agent.settings.MarvelSetting.TimeValueSetting;
import org.elasticsearch.node.settings.NodeSettingsService;
import java.util.List;
public class MarvelSettingsService extends AbstractComponent implements NodeSettingsService.Listener {
private static final String PREFIX = MarvelPlugin.NAME + ".agent.";
private final List<MarvelSetting> settings;
public static final String INDEX_STATS_TIMEOUT = PREFIX + "index.stats.timeout";
final TimeValueSetting indexStatsTimeout = MarvelSetting.timeSetting(INDEX_STATS_TIMEOUT, TimeValue.timeValueMinutes(10),
"Timeout value when collecting indices statistics (default to 10m)");
public static final String INDICES = PREFIX + "indices";
final StringArraySetting indices = MarvelSetting.arraySetting(INDICES, Strings.EMPTY_ARRAY,
"List of indices names whose stats will be exported (default to all indices)");
public static final String CLUSTER_STATE_TIMEOUT = PREFIX + "cluster.state.timeout";
final TimeValueSetting clusterStateTimeout = MarvelSetting.timeSetting(CLUSTER_STATE_TIMEOUT, TimeValue.timeValueMinutes(10),
"Timeout value when collecting the cluster state (default to 10m)");
public static final String CLUSTER_STATS_TIMEOUT = PREFIX + "cluster.stats.timeout";
final TimeValueSetting clusterStatsTimeout = MarvelSetting.timeSetting(CLUSTER_STATS_TIMEOUT, TimeValue.timeValueMinutes(10),
"Timeout value when collecting the cluster statistics (default to 10m)");
public static final String INDEX_RECOVERY_TIMEOUT = PREFIX + "index.recovery.timeout";
final TimeValueSetting recoveryTimeout = MarvelSetting.timeSetting(INDEX_RECOVERY_TIMEOUT, TimeValue.timeValueMinutes(10),
"Timeout value when collecting the recovery information (default to 10m)");
public static final String INDEX_RECOVERY_ACTIVE_ONLY = PREFIX + "index.recovery.active_only";
final MarvelSetting.BooleanSetting recoveryActiveOnly = MarvelSetting.booleanSetting(INDEX_RECOVERY_ACTIVE_ONLY, Boolean.FALSE,
"Flag to indicate if only active recoveries should be collected (default to false: all recoveries are collected)");
MarvelSettingsService(Settings clusterSettings) {
super(clusterSettings);
// List of marvel settings
ImmutableList.Builder<MarvelSetting> builder = ImmutableList.builder();
builder.add(indexStatsTimeout);
builder.add(indices);
builder.add(clusterStateTimeout);
builder.add(clusterStatsTimeout);
builder.add(recoveryTimeout);
builder.add(recoveryActiveOnly);
this.settings = builder.build();
logger.trace("initializing marvel settings:");
for (MarvelSetting setting : settings) {
// Initialize all settings and register them as a dynamic settings
if (setting.onInit(clusterSettings)) {
logger.trace("\t{} ({}) initialized to [{}]", setting.getName(), setting.getDescription(), setting.getValueAsString());
} else {
logger.trace("\t{} ({}) initialized", setting.getName(), setting.getDescription());
}
}
}
@Inject
public MarvelSettingsService(Settings clusterSettings, NodeSettingsService nodeSettingsService) {
this(clusterSettings);
logger.trace("registering the service as a node settings listener");
nodeSettingsService.addListener(this);
}
@Override
public void onRefreshSettings(Settings clusterSettings) {
for (MarvelSetting setting : settings) {
if (setting.onRefresh(clusterSettings)) {
logger.trace("setting [{}] updated to [{}]", setting.getName(), setting.getValueAsString());
}
}
}
public TimeValue indexStatsTimeout() {
return indexStatsTimeout.getValue();
}
public String[] indices() {
return indices.getValue();
}
public TimeValue clusterStateTimeout() {
return clusterStateTimeout.getValue();
}
public TimeValue clusterStatsTimeout() {
return clusterStatsTimeout.getValue();
}
public TimeValue recoveryTimeout() {
return recoveryTimeout.getValue();
}
public boolean recoveryActiveOnly() {
return recoveryActiveOnly.getValue();
}
}

View File

@ -11,7 +11,7 @@ import org.elasticsearch.cluster.ClusterState;
import org.elasticsearch.cluster.metadata.IndexMetaData;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.marvel.agent.exporter.MarvelDoc;
import org.elasticsearch.marvel.agent.settings.MarvelSettingsService;
import org.elasticsearch.marvel.agent.settings.MarvelSettings;
import org.elasticsearch.test.ESSingleNodeTestCase;
import org.junit.Test;
@ -121,7 +121,7 @@ public class ClusterStateCollectorTests extends ESSingleNodeTestCase {
return new ClusterStateCollector(getInstanceFromNode(Settings.class),
getInstanceFromNode(ClusterService.class),
getInstanceFromNode(ClusterName.class),
getInstanceFromNode(MarvelSettingsService.class),
getInstanceFromNode(MarvelSettings.class),
client());
}
}

View File

@ -9,7 +9,7 @@ import org.elasticsearch.cluster.ClusterName;
import org.elasticsearch.cluster.ClusterService;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.marvel.agent.exporter.MarvelDoc;
import org.elasticsearch.marvel.agent.settings.MarvelSettingsService;
import org.elasticsearch.marvel.agent.settings.MarvelSettings;
import org.elasticsearch.test.ESIntegTestCase;
import org.junit.Test;
@ -43,7 +43,7 @@ public class ClusterStatsCollectorTests extends ESIntegTestCase {
return new ClusterStatsCollector(internalCluster().getInstance(Settings.class),
internalCluster().getInstance(ClusterService.class),
internalCluster().getInstance(ClusterName.class),
internalCluster().getInstance(MarvelSettingsService.class),
internalCluster().getInstance(MarvelSettings.class),
client());
}
}

View File

@ -13,7 +13,7 @@ import org.elasticsearch.cluster.block.ClusterBlocks;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.indices.recovery.RecoveryState;
import org.elasticsearch.marvel.agent.exporter.MarvelDoc;
import org.elasticsearch.marvel.agent.settings.MarvelSettingsService;
import org.elasticsearch.marvel.agent.settings.MarvelSettings;
import org.elasticsearch.test.ESIntegTestCase;
import org.junit.Test;
@ -40,8 +40,8 @@ public class IndexRecoveryCollectorTests extends ESIntegTestCase {
protected Settings nodeSettings(int nodeOrdinal) {
return settingsBuilder()
.put(super.nodeSettings(nodeOrdinal))
.put(MarvelSettingsService.INDEX_RECOVERY_ACTIVE_ONLY, activeOnly)
.put(MarvelSettingsService.INDICES, indexName)
.put(MarvelSettings.INDEX_RECOVERY_ACTIVE_ONLY, activeOnly)
.put(MarvelSettings.INDICES, indexName)
.build();
}
@ -80,8 +80,8 @@ public class IndexRecoveryCollectorTests extends ESIntegTestCase {
waitForNoBlocksOnNode(node2);
waitForRelocation();
for (MarvelSettingsService marvelSettingsService : internalCluster().getInstances(MarvelSettingsService.class)) {
assertThat(marvelSettingsService.recoveryActiveOnly(), equalTo(activeOnly));
for (MarvelSettings marvelSettings : internalCluster().getInstances(MarvelSettings.class)) {
assertThat(marvelSettings.recoveryActiveOnly(), equalTo(activeOnly));
}
logger.info("--> collect index recovery data");
@ -125,7 +125,7 @@ public class IndexRecoveryCollectorTests extends ESIntegTestCase {
return new IndexRecoveryCollector(internalCluster().getInstance(Settings.class),
internalCluster().getInstance(ClusterService.class),
internalCluster().getInstance(ClusterName.class),
internalCluster().getInstance(MarvelSettingsService.class),
internalCluster().getInstance(MarvelSettings.class),
client());
}

View File

@ -12,7 +12,7 @@ import org.elasticsearch.cluster.block.ClusterBlock;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.unit.TimeValue;
import org.elasticsearch.marvel.agent.exporter.MarvelDoc;
import org.elasticsearch.marvel.agent.settings.MarvelSettingsService;
import org.elasticsearch.marvel.agent.settings.MarvelSettings;
import org.elasticsearch.test.ESSingleNodeTestCase;
import org.junit.Test;
@ -128,7 +128,7 @@ public class IndexStatsCollectorTests extends ESSingleNodeTestCase {
return new IndexStatsCollector(getInstanceFromNode(Settings.class),
getInstanceFromNode(ClusterService.class),
getInstanceFromNode(ClusterName.class),
getInstanceFromNode(MarvelSettingsService.class),
getInstanceFromNode(MarvelSettings.class),
client());
}

View File

@ -13,7 +13,7 @@ import org.elasticsearch.common.inject.Provider;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.discovery.DiscoveryService;
import org.elasticsearch.marvel.agent.exporter.MarvelDoc;
import org.elasticsearch.marvel.agent.settings.MarvelSettingsService;
import org.elasticsearch.marvel.agent.settings.MarvelSettings;
import org.elasticsearch.node.service.NodeService;
import org.elasticsearch.test.ESIntegTestCase;
import org.junit.Test;
@ -57,7 +57,7 @@ public class NodeStatsCollectorTests extends ESIntegTestCase {
return new NodeStatsCollector(internalCluster().getInstance(Settings.class, nodeId),
internalCluster().getInstance(ClusterService.class, nodeId),
internalCluster().getInstance(ClusterName.class, nodeId),
internalCluster().getInstance(MarvelSettingsService.class, nodeId),
internalCluster().getInstance(MarvelSettings.class, nodeId),
internalCluster().getInstance(NodeService.class, nodeId),
internalCluster().getInstance(DiscoveryService.class, nodeId),
new Provider<DiskThresholdDecider>() {

View File

@ -16,6 +16,7 @@ import org.elasticsearch.license.plugin.LicensePlugin;
import org.elasticsearch.marvel.MarvelPlugin;
import org.elasticsearch.marvel.agent.AgentService;
import org.elasticsearch.marvel.agent.collector.indices.IndexStatsMarvelDoc;
import org.elasticsearch.marvel.agent.settings.MarvelSettings;
import org.elasticsearch.node.Node;
import org.elasticsearch.test.ESIntegTestCase;
import org.elasticsearch.test.ESIntegTestCase.ClusterScope;
@ -47,7 +48,7 @@ public class HttpESExporterTests extends ESIntegTestCase {
@Test
public void testHttpServerOff() {
Settings.Builder builder = Settings.builder()
.put(AgentService.SETTINGS_INTERVAL, "200m")
.put(MarvelSettings.STARTUP_DELAY, "200m")
.put(Node.HTTP_ENABLED, false);
internalCluster().startNode(builder);
HttpESExporter httpEsExporter = getEsExporter();
@ -85,7 +86,7 @@ public class HttpESExporterTests extends ESIntegTestCase {
@Test
public void testTemplateAdditionDespiteOfLateClusterForming() {
Settings.Builder builder = Settings.builder()
.put(AgentService.SETTINGS_INTERVAL, "200m")
.put(MarvelSettings.STARTUP_DELAY, "200m")
.put(Node.HTTP_ENABLED, true)
.put("discovery.type", "zen")
.put("discovery.zen.ping_timeout", "1s")
@ -113,7 +114,7 @@ public class HttpESExporterTests extends ESIntegTestCase {
public void testDynamicHostChange() {
// disable exporting to be able to use non valid hosts
Settings.Builder builder = Settings.builder()
.put(AgentService.SETTINGS_INTERVAL, "-1");
.put(MarvelSettings.INTERVAL, "-1");
internalCluster().startNode(builder);
HttpESExporter httpEsExporter = getEsExporter();
@ -133,7 +134,7 @@ public class HttpESExporterTests extends ESIntegTestCase {
@Test
public void testHostChangeReChecksTemplate() {
Settings.Builder builder = Settings.builder()
.put(AgentService.SETTINGS_INTERVAL, "200m")
.put(MarvelSettings.STARTUP_DELAY, "200m")
.put(Node.HTTP_ENABLED, true);
internalCluster().startNode(builder);
@ -159,7 +160,7 @@ public class HttpESExporterTests extends ESIntegTestCase {
@Test
public void testHostFailureChecksTemplate() throws InterruptedException, IOException {
Settings.Builder builder = Settings.builder()
.put(AgentService.SETTINGS_INTERVAL, "200m")
.put(MarvelSettings.STARTUP_DELAY, "200m")
.put(Node.HTTP_ENABLED, true);
final String node0 = internalCluster().startNode(builder);
String node1 = internalCluster().startNode(builder);

View File

@ -12,8 +12,8 @@ import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.license.plugin.LicensePlugin;
import org.elasticsearch.marvel.MarvelPlugin;
import org.elasticsearch.marvel.agent.AgentService;
import org.elasticsearch.marvel.agent.collector.indices.IndexStatsCollector;
import org.elasticsearch.marvel.agent.settings.MarvelSettings;
import org.elasticsearch.node.Node;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.test.ESIntegTestCase;
@ -33,7 +33,9 @@ public class IndexStatsRendererIT extends ESIntegTestCase {
.put(super.nodeSettings(nodeOrdinal))
.put("plugin.types", MarvelPlugin.class.getName() + "," + LicensePlugin.class.getName())
.put(Node.HTTP_ENABLED, true)
.put(AgentService.SETTINGS_INTERVAL, "200ms")
.put(MarvelSettings.STARTUP_DELAY, "1s")
.put(MarvelSettings.INTERVAL, "30s")
.put(MarvelSettings.COLLECTORS, IndexStatsCollector.NAME)
.build();
}

View File

@ -23,16 +23,14 @@ public class MarvelSettingTests extends ESTestCase {
if (randomBoolean()) {
defaultValue = randomBoolean();
}
boolean dynamic = randomBoolean();
MarvelSetting.BooleanSetting setting = MarvelSetting.booleanSetting(name, defaultValue, description);
MarvelSetting.BooleanSetting setting = MarvelSetting.booleanSetting(name, defaultValue, description, dynamic);
assertThat(setting.getName(), equalTo(name));
assertThat(setting.getDescription(), equalTo(description));
assertThat(setting.getDefaultValue(), equalTo(defaultValue));
setting.onInit(settingsBuilder().build());
assertThat(setting.getValue(), equalTo(defaultValue));
setting.onInit(settingsBuilder().put(name, Boolean.FALSE).build());
setting.onRefresh(settingsBuilder().put(name, Boolean.FALSE).build());
assertFalse(setting.getValue());
setting.onRefresh(settingsBuilder().put(name, Boolean.TRUE).build());
@ -47,28 +45,22 @@ public class MarvelSettingTests extends ESTestCase {
if (randomBoolean()) {
defaultValue = randomTimeValue();
}
boolean dynamic = randomBoolean();
MarvelSetting.TimeValueSetting setting = MarvelSetting.timeSetting(name, defaultValue, description);
MarvelSetting.TimeValueSetting setting = MarvelSetting.timeSetting(name, defaultValue, description, dynamic);
assertThat(setting.getName(), equalTo(name));
assertThat(setting.getDescription(), equalTo(description));
if (defaultValue == null) {
assertNull(setting.getDefaultValue());
} else {
assertThat(setting.getDefaultValue().millis(), equalTo(defaultValue.millis()));
}
setting.onInit(settingsBuilder().build());
if (defaultValue == null) {
assertNull(setting.getValue());
} else {
assertThat(setting.getValue().millis(), equalTo(defaultValue.millis()));
}
setting.onInit(settingsBuilder().put(name, 15000L).build());
setting.onRefresh(settingsBuilder().put(name, 15000L).build());
assertThat(setting.getValue().millis(), equalTo(15000L));
TimeValue updated = randomTimeValue();
setting.onInit(settingsBuilder().put(name, updated.toString()).build());
setting.onRefresh(settingsBuilder().put(name, updated.toString()).build());
assertThat(setting.getValue().millis(), equalTo(updated.millis()));
updated = randomTimeValue();
@ -84,17 +76,22 @@ public class MarvelSettingTests extends ESTestCase {
if (randomBoolean()) {
defaultValue = randomAsciiOfLength(15);
}
boolean dynamic = randomBoolean();
MarvelSetting.StringSetting setting = MarvelSetting.stringSetting(name, defaultValue, description);
MarvelSetting.StringSetting setting = MarvelSetting.stringSetting(name, defaultValue, description, dynamic);
assertThat(setting.getName(), equalTo(name));
assertThat(setting.getDescription(), equalTo(description));
assertThat(setting.getDefaultValue(), equalTo(defaultValue));
if (defaultValue == null) {
assertNull(setting.getValue());
} else {
assertThat(setting.getValue(), equalTo(defaultValue));
}
setting.onInit(settingsBuilder().build());
setting.onRefresh(settingsBuilder().build());
assertThat(setting.getValue(), equalTo(defaultValue));
String updated = randomAsciiOfLength(15);
setting.onInit(settingsBuilder().put(name, updated).build());
setting.onRefresh(settingsBuilder().put(name, updated).build());
assertThat(setting.getValue(), equalTo(updated));
updated = randomAsciiOfLength(15);
@ -110,25 +107,22 @@ public class MarvelSettingTests extends ESTestCase {
if (randomBoolean()) {
defaultValue = randomStringArray();
}
boolean dynamic = randomBoolean();
MarvelSetting.StringArraySetting setting = MarvelSetting.arraySetting(name, defaultValue, description);
MarvelSetting.StringArraySetting setting = MarvelSetting.arraySetting(name, defaultValue, description, dynamic);
assertThat(setting.getName(), equalTo(name));
assertThat(setting.getDescription(), equalTo(description));
if (defaultValue == null) {
assertNull(setting.getDefaultValue());
} else {
assertArrayEquals(setting.getDefaultValue(), defaultValue);
}
setting.onInit(settingsBuilder().build());
if (defaultValue == null) {
assertArrayEquals(setting.getValue(), Strings.EMPTY_ARRAY);
assertNull(setting.getValue());
} else {
assertArrayEquals(setting.getValue(), defaultValue);
}
setting.onRefresh(settingsBuilder().build());
assertArrayEquals(setting.getValue(), defaultValue);
String[] updated = randomStringArray();
setting.onInit(settingsBuilder().put(name, Strings.arrayToCommaDelimitedString(updated)).build());
setting.onRefresh(settingsBuilder().put(name, Strings.arrayToCommaDelimitedString(updated)).build());
assertArrayEquals(setting.getValue(), updated);
updated = randomStringArray();

View File

@ -1,42 +0,0 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/
package org.elasticsearch.marvel.agent.settings;
import org.elasticsearch.common.Strings;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.unit.TimeValue;
import org.elasticsearch.test.ESTestCase;
import org.junit.Test;
import static org.elasticsearch.common.settings.Settings.settingsBuilder;
import static org.hamcrest.Matchers.equalTo;
public class MarvelSettingsServiceTests extends ESTestCase {
@Test
public void testMarvelSettingService() {
MarvelSettingsService service = new MarvelSettingsService(Settings.EMPTY);
TimeValue indexStatsTimeout = service.indexStatsTimeout();
assertNotNull(indexStatsTimeout);
String[] indices = service.indices();
assertNotNull(indices);
TimeValue updatedIndexStatsTimeout = TimeValue.timeValueSeconds(60L);
String[] updatedIndices = new String[]{"index-0", "index-1"};
Settings settings = settingsBuilder()
.put(service.indexStatsTimeout.getName(), updatedIndexStatsTimeout)
.put(service.indices.getName(), Strings.arrayToCommaDelimitedString(updatedIndices))
.build();
service.onRefreshSettings(settings);
assertThat(service.indexStatsTimeout(), equalTo(updatedIndexStatsTimeout));
assertArrayEquals(service.indices(), updatedIndices);
}
}

View File

@ -0,0 +1,151 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/
package org.elasticsearch.marvel.agent.settings;
import org.elasticsearch.action.admin.cluster.settings.ClusterUpdateSettingsRequestBuilder;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.unit.TimeValue;
import org.elasticsearch.license.plugin.LicensePlugin;
import org.elasticsearch.marvel.MarvelPlugin;
import org.elasticsearch.node.Node;
import org.elasticsearch.test.ESIntegTestCase;
import org.junit.Test;
import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertAcked;
import static org.hamcrest.Matchers.equalTo;
@ESIntegTestCase.ClusterScope(scope = ESIntegTestCase.Scope.TEST, numDataNodes = 1)
public class MarvelSettingsTests extends ESIntegTestCase {
private final TimeValue startUp = randomTimeValue();
private final TimeValue interval = randomTimeValue();
private final TimeValue indexStatsTimeout = randomTimeValue();
private final String[] indices = randomStringArray();
private final TimeValue clusterStateTimeout = randomTimeValue();
private final TimeValue clusterStatsTimeout = randomTimeValue();
private final TimeValue recoveryTimeout = randomTimeValue();
private final Boolean recoveryActiveOnly = randomBoolean();
private final String[] collectors = randomStringArray();
@Override
protected Settings nodeSettings(int nodeOrdinal) {
return Settings.builder()
.put(super.nodeSettings(nodeOrdinal))
.put("plugin.types", MarvelPlugin.class.getName() + "," + LicensePlugin.class.getName())
.put(Node.HTTP_ENABLED, true)
.put(marvelSettings())
.build();
}
private Settings marvelSettings() {
return Settings.builder()
.put(MarvelSettings.STARTUP_DELAY, startUp)
.put(MarvelSettings.INTERVAL, interval)
.put(MarvelSettings.INDEX_STATS_TIMEOUT, indexStatsTimeout)
.putArray(MarvelSettings.INDICES, indices)
.put(MarvelSettings.CLUSTER_STATE_TIMEOUT, clusterStateTimeout)
.put(MarvelSettings.CLUSTER_STATS_TIMEOUT, clusterStatsTimeout)
.put(MarvelSettings.INDEX_RECOVERY_TIMEOUT, recoveryTimeout)
.put(MarvelSettings.INDEX_RECOVERY_ACTIVE_ONLY, recoveryActiveOnly)
.putArray(MarvelSettings.COLLECTORS, collectors)
.build();
}
@Test
public void testMarvelSettingService() throws Exception {
logger.info("--> testing marvel settings service initialization");
for (final MarvelSettings marvelSettings : internalCluster().getInstances(MarvelSettings.class)) {
assertThat(marvelSettings.startUpDelay().millis(), equalTo(startUp.millis()));
assertThat(marvelSettings.interval().millis(), equalTo(interval.millis()));
assertThat(marvelSettings.indexStatsTimeout().millis(), equalTo(indexStatsTimeout.millis()));
assertArrayEquals(marvelSettings.indices(), indices);
assertThat(marvelSettings.clusterStateTimeout().millis(), equalTo(clusterStateTimeout.millis()));
assertThat(marvelSettings.clusterStatsTimeout().millis(), equalTo(clusterStatsTimeout.millis()));
assertThat(marvelSettings.recoveryTimeout().millis(), equalTo(recoveryTimeout.millis()));
assertThat(marvelSettings.recoveryActiveOnly(), equalTo(recoveryActiveOnly));
assertArrayEquals(marvelSettings.collectors(), collectors);
for (final MarvelSetting setting : MarvelSettings.dynamicSettings()) {
assertThat(marvelSettings.getSettingValue(setting.getName()), equalTo(setting.getValue()));
}
}
logger.info("--> testing marvel dynamic settings update");
for (final MarvelSetting setting : MarvelSettings.dynamicSettings()) {
Object updated = null;
Settings.Builder transientSettings = Settings.builder();
if (setting instanceof MarvelSetting.TimeValueSetting) {
updated = randomTimeValue();
transientSettings.put(setting.getName(), updated);
} else if (setting instanceof MarvelSetting.BooleanSetting) {
updated = randomBoolean();
transientSettings.put(setting.getName(), updated);
} else if (setting instanceof MarvelSetting.StringSetting) {
updated = randomAsciiOfLength(10);
transientSettings.put(setting.getName(), updated);
} else if (setting instanceof MarvelSetting.StringArraySetting) {
updated = randomStringArray();
transientSettings.putArray(setting.getName(), (String[]) updated);
}
logger.info("--> updating {} to value [{}]", setting, updated);
assertAcked(prepareRandomUpdateSettings(transientSettings.build()).get());
// checking that the value has been correctly updated on all marvel settings services
final Object expected = updated;
assertBusy(new Runnable() {
@Override
public void run() {
for (final MarvelSettings marvelSettings : internalCluster().getInstances(MarvelSettings.class)) {
MarvelSetting current = marvelSettings.getSetting(setting.getName());
Object value = current.getValue();
logger.info("--> {} in {}", current, marvelSettings);
if (setting instanceof MarvelSetting.TimeValueSetting) {
assertThat(((TimeValue) value).millis(), equalTo(((TimeValue) expected).millis()));
} else if (setting instanceof MarvelSetting.BooleanSetting) {
assertThat((Boolean) value, equalTo((Boolean) expected));
} else if (setting instanceof MarvelSetting.StringSetting) {
assertThat((String) value, equalTo((String) expected));
} else if (setting instanceof MarvelSetting.StringArraySetting) {
assertArrayEquals((String[]) value, (String[]) expected);
}
}
}
});
}
}
private ClusterUpdateSettingsRequestBuilder prepareRandomUpdateSettings(Settings updateSettings) {
ClusterUpdateSettingsRequestBuilder requestBuilder = client().admin().cluster().prepareUpdateSettings();
if (randomBoolean()) {
requestBuilder.setTransientSettings(updateSettings);
} else {
requestBuilder.setPersistentSettings(updateSettings);
}
return requestBuilder;
}
private TimeValue randomTimeValue() {
return TimeValue.parseTimeValue(randomFrom("1s", "10s", "30s", "1m", "30m", "1h"), null, getClass().getSimpleName());
}
private String[] randomStringArray() {
final int size = scaledRandomIntBetween(1, 10);
String[] items = new String[size];
for (int i = 0; i < size; i++) {
items[i] = randomAsciiOfLength(5);
}
return items;
}
}