package com.sf.monitor; import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.core.type.TypeReference; import com.google.common.collect.ImmutableList; import com.sf.log.Logger; import com.sf.monitor.druid.DruidInfoFetcher; import com.sf.monitor.druid.DruidInfos; import com.sf.monitor.kafka.KafkaInfoFetcher; import com.sf.monitor.zk.ZookeeperInfoFetcher; import java.io.File; import java.io.IOException; import java.util.List; import java.util.Map; import java.util.regex.Matcher; import java.util.regex.Pattern; public class Config { private static final Logger log = new Logger(Config.class); @JsonProperty public Prometheus prometheus; @JsonProperty public CuratorConfig zookeeper; @JsonProperty("druid") public DruidInfos druidInfos; @JsonProperty public KafkaConfig kafka; @JsonProperty public NotifyConfig notify; @JsonProperty public Fetchers fetchers; public List<InfoFetcher> fetcherList() { return ImmutableList.<InfoFetcher>of(fetchers.druidFetcher, fetchers.kafkaFetcher, fetchers.zookeeperFetcher); } public static class Prometheus { @JsonProperty public String namespace; @JsonProperty public String serverUrl; } public static class CuratorConfig { @JsonProperty public String addrs; @JsonProperty public int connectionTimeout; @JsonProperty public int baseSleepTimeMs = 1000; @JsonProperty public int maxRetries = 20; @JsonProperty public int maxSleepMs = 30000; } public static class NotifyConfig { @JsonProperty public boolean doSend; @JsonProperty public String appName; @JsonProperty public String url; @JsonProperty public List<String> emails; @JsonProperty public List<String> phones; } public static class KafkaConfig { @JsonProperty public boolean warning; @JsonProperty public long warnDefaultLag = 100000; @JsonProperty public Map<String, Long> warnLagSpec; @JsonProperty public Pattern ignoreConsumerRegex; @JsonProperty public String stormKafkaRoot; @JsonCreator public KafkaConfig( @JsonProperty("warning") boolean warning, @JsonProperty("warnDefaultLag") long warnDefaultLag, @JsonProperty("warnLagSpec") Map<String, Long> warnLagSpec, @JsonProperty("ignoreConsumerRegex") String ignoreConsumerRegex, @JsonProperty("stormKafka") String stormKafkaRoot ) { this.warning = warning; this.warnDefaultLag = warnDefaultLag; this.warnLagSpec = warnLagSpec; if (ignoreConsumerRegex != null) { this.ignoreConsumerRegex = Pattern.compile(ignoreConsumerRegex); } this.stormKafkaRoot = stormKafkaRoot; } public long getWarnLag(String topic, String consumer) { if (warnLagSpec == null) { return warnDefaultLag; } Long lag = warnLagSpec.get(topic + "|" + consumer); return lag != null ? lag : warnDefaultLag; } public boolean shouldAlarm(String topic, String consumer, long lag) { if (!warning) { return false; } if (ignoreConsumerRegex != null) { Matcher matcher = ignoreConsumerRegex.matcher(consumer); if (matcher.matches()) { return false; } } return lag > getWarnLag(topic, consumer) || lag < 0; } } public static class Fetchers { @JsonProperty public DruidInfoFetcher druidFetcher; @JsonProperty public KafkaInfoFetcher kafkaFetcher; @JsonProperty public ZookeeperInfoFetcher zookeeperFetcher; } public static Config config; public static void init(String configDir) { try { config = mapConfig(configDir + "/config.json", Config.class); } catch (IOException e) { log.error(e, "Initial configuration failed!"); System.exit(-1); } } private static <T> T mapConfig(String path, Class<T> clazz) throws IOException { File configFile = new File(path); if (!configFile.isFile() && !configFile.canRead()) { log.error("config file[%s] invalid!", path); throw new RuntimeException(String.format("config file[%s] invalid!", path)); } return Resources.jsonMapper.readValue(configFile, clazz); } private static <T> T mapConfig(String path, TypeReference ref) throws IOException { File configFile = new File(path); if (!configFile.isFile() && !configFile.canRead()) { log.error("config file[%s] invalid!", path); throw new RuntimeException(String.format("config file[%s] invalid!", path)); } return Resources.jsonMapper.readValue(configFile, ref); } }