
com.wavefront.agent.logsharvesting.LogsIngestionConfigManager Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of proxy Show documentation
Show all versions of proxy Show documentation
Service for batching and relaying metric traffic to Wavefront
package com.wavefront.agent.logsharvesting;
import com.github.benmanes.caffeine.cache.Caffeine;
import com.github.benmanes.caffeine.cache.LoadingCache;
import com.google.common.annotations.VisibleForTesting;
import com.wavefront.agent.config.ConfigurationException;
import com.wavefront.agent.config.LogsIngestionConfig;
import com.wavefront.agent.config.MetricMatcher;
import com.yammer.metrics.Metrics;
import com.yammer.metrics.core.Counter;
import com.yammer.metrics.core.MetricName;
import java.util.Timer;
import java.util.TimerTask;
import java.util.concurrent.TimeUnit;
import java.util.function.Consumer;
import java.util.function.Supplier;
import java.util.logging.Level;
import java.util.logging.Logger;
/**
* Wrapper for a {@link LogsIngestionConfig} that supports hot-loading and removal notifications.
*
* @author Mori Bellamy ([email protected])
*/
public class LogsIngestionConfigManager {
protected static final Logger logger =
Logger.getLogger(LogsIngestionConfigManager.class.getCanonicalName());
private static final Counter configReloads =
Metrics.newCounter(new MetricName("logsharvesting", "", "config-reloads.successful"));
private static final Counter failedConfigReloads =
Metrics.newCounter(new MetricName("logsharvesting", "", "config-reloads.failed"));
private LogsIngestionConfig lastParsedConfig;
// The only key in this cache is "true". Basically we want the cache expiry and reloading logic.
private final LoadingCache logsIngestionConfigLoadingCache;
private final Consumer removalListener;
public LogsIngestionConfigManager(
Supplier logsIngestionConfigSupplier,
Consumer removalListener)
throws ConfigurationException {
this.removalListener = removalListener;
lastParsedConfig = logsIngestionConfigSupplier.get();
if (lastParsedConfig == null)
throw new ConfigurationException("Could not load initial config.");
lastParsedConfig.verifyAndInit();
this.logsIngestionConfigLoadingCache =
Caffeine.newBuilder()
.expireAfterWrite(lastParsedConfig.configReloadIntervalSeconds, TimeUnit.SECONDS)
.build(
(ignored) -> {
LogsIngestionConfig nextConfig = logsIngestionConfigSupplier.get();
if (nextConfig == null) {
logger.warning("Unable to reload logs ingestion config file!");
failedConfigReloads.inc();
} else if (!lastParsedConfig.equals(nextConfig)) {
nextConfig.verifyAndInit(); // If it throws, we keep the last
// (good) config.
processConfigChange(nextConfig);
logger.info("Loaded new config: " + lastParsedConfig.toString());
configReloads.inc();
}
return lastParsedConfig;
});
// Force reload every N seconds.
new Timer("Timer-logsingestion-configmanager")
.schedule(
new TimerTask() {
@Override
public void run() {
try {
logsIngestionConfigLoadingCache.get(true);
} catch (Exception e) {
logger.log(Level.SEVERE, "Cannot load a new logs ingestion config.", e);
}
}
},
lastParsedConfig.aggregationIntervalSeconds,
lastParsedConfig.aggregationIntervalSeconds);
}
public LogsIngestionConfig getConfig() {
return logsIngestionConfigLoadingCache.get(true);
}
/** Forces the next call to {@link #getConfig()} to call the config supplier. */
@VisibleForTesting
public void forceConfigReload() {
logsIngestionConfigLoadingCache.invalidate(true);
}
private void processConfigChange(LogsIngestionConfig nextConfig) {
if (nextConfig.useWavefrontHistograms != lastParsedConfig.useWavefrontHistograms) {
logger.warning(
"useWavefrontHistograms property cannot be changed at runtime, "
+ "proxy restart required!");
}
if (nextConfig.useDeltaCounters != lastParsedConfig.useDeltaCounters) {
logger.warning(
"useDeltaCounters property cannot be changed at runtime, " + "proxy restart required!");
}
if (nextConfig.reportEmptyHistogramStats != lastParsedConfig.reportEmptyHistogramStats) {
logger.warning(
"reportEmptyHistogramStats property cannot be changed at runtime, "
+ "proxy restart required!");
}
if (!nextConfig.aggregationIntervalSeconds.equals(
lastParsedConfig.aggregationIntervalSeconds)) {
logger.warning(
"aggregationIntervalSeconds property cannot be changed at runtime, "
+ "proxy restart required!");
}
if (nextConfig.configReloadIntervalSeconds != lastParsedConfig.configReloadIntervalSeconds) {
logger.warning(
"configReloadIntervalSeconds property cannot be changed at runtime, "
+ "proxy restart required!");
}
if (nextConfig.expiryMillis != lastParsedConfig.expiryMillis) {
logger.warning(
"expiryMillis property cannot be changed at runtime, " + "proxy restart required!");
}
for (MetricMatcher oldMatcher : lastParsedConfig.counters) {
if (!nextConfig.counters.contains(oldMatcher)) removalListener.accept(oldMatcher);
}
for (MetricMatcher oldMatcher : lastParsedConfig.gauges) {
if (!nextConfig.gauges.contains(oldMatcher)) removalListener.accept(oldMatcher);
}
for (MetricMatcher oldMatcher : lastParsedConfig.histograms) {
if (!nextConfig.histograms.contains(oldMatcher)) removalListener.accept(oldMatcher);
}
lastParsedConfig = nextConfig;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy