Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add service checks to jmxfetch #38

Closed
wants to merge 9 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
Changes
=======

# 0.4.2 / 03-12-2014
* [FEATURE] Send service checks for JMX integrations

# 0.4.1 / 02-11-2014
* [FEATURE/BUGFIX] Fetch more JVM (Non)Heap variables by default. See[bd8915c2f1eec794f406414b678ce6110407dce1](https://github.com/DataDog/jmxfetch/commit/bd8915c2f1eec794f406414b678ce6110407dce1)
* [BUGFIX] Memory leak fix when fetching attributes value is failing. See [#30][]
Expand All @@ -21,4 +24,4 @@ Changes
[#26]: https://github.com/DataDog/jmxfetch/issues/26
[#28]: https://github.com/DataDog/jmxfetch/issues/28
[#30]: https://github.com/DataDog/jmxfetch/issues/30
[@coupacooke]: https://github.com/coupacooke
[@coupacooke]: https://github.com/coupacooke
6 changes: 3 additions & 3 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

<groupId>datadog</groupId>
<artifactId>jmxfetch</artifactId>
<version>0.4.1</version>
<version>0.4.2</version>
<packaging>jar</packaging>

<name>jmxfetch</name>
Expand All @@ -12,7 +12,7 @@
<properties>
<commons-io.version>2.4</commons-io.version>
<guava.version>17.0</guava.version>
<java-dogstatsd-client.version>2.0.8</java-dogstatsd-client.version>
<java-dogstatsd-client.version>2.1.0</java-dogstatsd-client.version>
<jcommander.version>1.35</jcommander.version>
<junit.version>4.11</junit.version>
<log4j.version>1.2.17</log4j.version>
Expand Down Expand Up @@ -53,7 +53,7 @@
<version>${commons-io.version}</version>
</dependency>
<dependency>
<groupId>com.indeed</groupId>
<groupId>com.datadoghq</groupId>
<artifactId>java-dogstatsd-client</artifactId>
<version>${java-dogstatsd-client.version}</version>
</dependency>
Expand Down
35 changes: 23 additions & 12 deletions src/main/java/org/datadog/jmxfetch/App.java
Original file line number Diff line number Diff line change
Expand Up @@ -166,22 +166,22 @@ public void doIteration() {
while (it.hasNext()) {
Instance instance = it.next();
LinkedList<HashMap<String, Object>> metrics;
String instanceStatus = Status.STATUS_OK;
int instanceStatus = Status.STATUS_OK;
String instanceMessage = null;
try {
metrics = instance.getMetrics();
} catch (IOException e) {
String warning = "Unable to refresh bean list for instance " + instance;
LOGGER.warn(warning, e);
appConfig.getStatus().addInstanceStats(instance.getCheckName(), instance.getName(), 0, warning, Status.STATUS_ERROR);
reportStatus(appConfig, reporter, instance, 0, warning, Status.STATUS_ERROR);
brokenInstances.add(instance);
continue;
}

if (metrics.size() == 0) {
String warning = "Instance " + instance + " didn't return any metrics";
LOGGER.warn(warning);
appConfig.getStatus().addInstanceStats(instance.getCheckName(), instance.getName(), 0, warning, Status.STATUS_ERROR);
reportStatus(appConfig, reporter, instance, 0, warning, Status.STATUS_ERROR);
brokenInstances.add(instance);
continue;
} else if (instance.isLimitReached()) {
Expand All @@ -195,8 +195,8 @@ public void doIteration() {
CustomLogger.laconic(LOGGER, Level.WARN, instanceMessage, 0);
}
reporter.sendMetrics(metrics, instance.getName());
appConfig.getStatus().addInstanceStats(instance.getCheckName(), instance.getName(),
metrics.size(), instanceMessage, instanceStatus);

reportStatus(appConfig, reporter, instance, metrics.size(), instanceMessage, instanceStatus);
}


Expand Down Expand Up @@ -227,19 +227,19 @@ public void doIteration() {
} catch (IOException e) {
String warning = "Cannot connect to instance " + instance + ". Is a JMX Server running at this address?";
LOGGER.warn(warning);
appConfig.getStatus().addInstanceStats(instance.getCheckName(), instance.getName(), 0, warning, Status.STATUS_ERROR);
reportStatus(appConfig, reporter, instance, 0, warning, Status.STATUS_ERROR);
} catch (SecurityException e) {
String warning = "Cannot connect to instance " + instance + " because of bad credentials. Please check your credentials";
LOGGER.warn(warning);
appConfig.getStatus().addInstanceStats(instance.getCheckName(), instance.getName(), 0, warning, Status.STATUS_ERROR);
reportStatus(appConfig, reporter, instance, 0, warning, Status.STATUS_ERROR);
} catch (FailedLoginException e) {
String warning = "Cannot connect to instance " + instance + " because of bad credentials. Please check your credentials";
LOGGER.warn(warning);
appConfig.getStatus().addInstanceStats(instance.getCheckName(), instance.getName(), 0, warning, Status.STATUS_ERROR);
reportStatus(appConfig, reporter, instance, 0, warning, Status.STATUS_ERROR);
} catch (Exception e) {
String warning = "Cannot connect to instance " + instance + " for an unknown reason." + e.getMessage();
LOGGER.fatal(warning, e);
appConfig.getStatus().addInstanceStats(instance.getCheckName(), instance.getName(), 0, warning, Status.STATUS_ERROR);
reportStatus(appConfig, reporter, instance, 0, warning, Status.STATUS_ERROR);
}
}

Expand All @@ -248,7 +248,6 @@ public void doIteration() {
} catch (Exception e) {
LOGGER.error("Unable to flush stats.", e);
}

}

private HashMap<String, YamlParser> getConfigs(AppConfig config) {
Expand Down Expand Up @@ -282,10 +281,22 @@ private HashMap<String, YamlParser> getConfigs(AppConfig config) {
return configs;
}

private void reportStatus(AppConfig appConfig, Reporter reporter, Instance instance,
int metricCount, String message, int status) {
String checkName = instance.getCheckName();
appConfig.getStatus().addInstanceStats(checkName, instance.getName(),
metricCount, message, status);

reporter.sendServiceCheck(checkName, status, message, instance.getHostname(),
instance.getServiceCheckTags());
}

public void init(boolean forceNewConnection) {
clearInstances(instances);
clearInstances(brokenInstances);

Reporter reporter = appConfig.getReporter();

Iterator<Entry<String, YamlParser>> it = configs.entrySet().iterator();
while (it.hasNext()) {
Map.Entry<String, YamlParser> entry = it.next();
Expand Down Expand Up @@ -322,13 +333,13 @@ public void init(boolean forceNewConnection) {
instance.cleanUp();
brokenInstances.add(instance);
String warning = "Cannot connect to instance " + instance + " " + e.getMessage();
appConfig.getStatus().addInstanceStats(name, instance.getName(), 0, warning, Status.STATUS_ERROR);
reportStatus(appConfig, reporter, instance, 0, warning, Status.STATUS_ERROR);
LOGGER.error(warning);
} catch (Exception e) {
instance.cleanUp();
brokenInstances.add(instance);
String warning = "Unexpected exception while initiating instance " + instance + " : " + e.getMessage();
appConfig.getStatus().addInstanceStats(name, instance.getName(), 0, warning, Status.STATUS_ERROR);
reportStatus(appConfig, reporter, instance, 0, warning, Status.STATUS_ERROR);
LOGGER.error(warning, e);
}
}
Expand Down
31 changes: 31 additions & 0 deletions src/main/java/org/datadog/jmxfetch/Instance.java
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
import java.util.LinkedHashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;

import javax.management.MBeanAttributeInfo;
Expand Down Expand Up @@ -268,10 +269,40 @@ private void refreshBeansList() throws IOException {
this.lastRefreshTime = System.currentTimeMillis();
}

public String[] getServiceCheckTags() {
LinkedHashMap<String, Object> yaml = this.getYaml();
List<String> tags = new ArrayList<String>();
LinkedHashMap<String, String> instanceTags;
instanceTags = (LinkedHashMap<String, String>) yaml.get("tags");
if (instanceTags != null) {
for (Map.Entry<String, String> tag : instanceTags.entrySet()) {
tags.add(tag.getKey() + ":" + tag.getValue());
}
}

if (yaml.get("process_name_regex") != null) {
tags.add("process:" + yaml.get("process_name_regex"));
}
if (yaml.get("port") != null) {
tags.add("port:" + yaml.get("port"));
}

return tags.toArray(new String[tags.size()]);
}

public String getName() {
return this.instanceName;
}

public String getHostname(){
Object host = this.yaml.get("host");
if (host != null) {
return host.toString();
} else {
return null;
}
}

LinkedHashMap<String, Object> getYaml() {
return this.yaml;
}
Expand Down
12 changes: 6 additions & 6 deletions src/main/java/org/datadog/jmxfetch/Status.java
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,9 @@

public class Status {

public final static String STATUS_WARNING = "WARNING";
public final static String STATUS_OK = "OK";
public final static String STATUS_ERROR = "ERROR";
public final static int STATUS_WARNING = 1;
public final static int STATUS_OK = 0;
public final static int STATUS_ERROR = 2;
private final static Logger LOGGER = Logger.getLogger(Status.class.getName());
private final static String INITIALIZED_CHECKS = "initialized_checks";
private final static String FAILED_CHECKS = "failed_checks";
Expand Down Expand Up @@ -40,12 +40,12 @@ private void clearStats() {
instanceStats.put(FAILED_CHECKS, new HashMap<String, Object>());
}

public void addInstanceStats(String checkName, String instance, int metricCount, String message, String status) {
public void addInstanceStats(String checkName, String instance, int metricCount, String message, int status) {
addStats(checkName, instance, metricCount, message, status, INITIALIZED_CHECKS);
}

@SuppressWarnings("unchecked")
private void addStats(String checkName, String instance, int metricCount, String message, String status, String key) {
private void addStats(String checkName, String instance, int metricCount, String message, int status, String key) {
LinkedList<HashMap<String, Object>> checkStats;
HashMap<String, Object> initializedChecks;
initializedChecks = (HashMap<String, Object>) this.instanceStats.get(key);
Expand All @@ -70,7 +70,7 @@ private void addStats(String checkName, String instance, int metricCount, String
this.instanceStats.put(key, initializedChecks);
}

public void addInitFailedCheck(String checkName, String message, String status) {
public void addInitFailedCheck(String checkName, String message, int status) {
addStats(checkName, null, -1, message, status, FAILED_CHECKS);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
public class ConsoleReporter extends Reporter {

private LinkedList<HashMap<String, Object>> metrics = new LinkedList<HashMap<String, Object>>();
private LinkedList<HashMap<String, Object>> serviceChecks = new LinkedList<HashMap<String, Object>>();

@Override
protected void sendMetricPoint(String metricName, double value, String[] tags) {
Expand All @@ -33,6 +34,31 @@ public LinkedList<HashMap<String, Object>> getMetrics() {
return returnedMetrics;
}

public void sendServiceCheck(String checkName, int status, String message, String hostname, String[] tags) {
String tagString = "";
if (tags != null && tags.length > 0) {
tagString = "[" + Joiner.on(",").join(tags) + "]";
}
System.out.println(checkName + tagString + " - " + System.currentTimeMillis() / 1000 + " = " + status);

HashMap<String, Object> sc = new HashMap<String, Object>();
sc.put("name", checkName);
sc.put("status", Integer.toString(status));
sc.put("message", message);
sc.put("hostname", hostname);
sc.put("tags", tags);
serviceChecks.add(sc);
}

public LinkedList<HashMap<String, Object>> getServiceChecks() {
LinkedList<HashMap<String, Object>> returnedServiceChecks = new LinkedList<HashMap<String, Object>>();
for (HashMap<String, Object> map : serviceChecks) {
returnedServiceChecks.add(new HashMap<String, Object>(map));
}
serviceChecks.clear();
return returnedServiceChecks;
}

@Override
public void displayMetricReached() {
System.out.println("\n\n\n ------- METRIC LIMIT REACHED: ATTRIBUTES BELOW WON'T BE COLLECTED -------\n\n\n");
Expand Down
2 changes: 2 additions & 0 deletions src/main/java/org/datadog/jmxfetch/reporter/Reporter.java
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,8 @@ private void postProcessCassandra(HashMap<String, Object> metric) {

protected abstract void sendMetricPoint(String metricName, double value, String[] tags);

public abstract void sendServiceCheck(String checkName, int status, String message, String hostname, String[] tags);

public abstract void displayMetricReached();

public abstract void displayNonMatchingAttributeName(JMXAttribute jmxAttribute);
Expand Down
14 changes: 14 additions & 0 deletions src/main/java/org/datadog/jmxfetch/reporter/StatsdReporter.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,10 @@

import com.timgroup.statsd.NonBlockingStatsDClient;
import com.timgroup.statsd.StatsDClient;
import com.timgroup.statsd.ServiceCheck;
import org.datadog.jmxfetch.Instance;
import org.datadog.jmxfetch.JMXAttribute;
import org.datadog.jmxfetch.Status;

public class StatsdReporter extends Reporter {

Expand All @@ -29,6 +31,18 @@ protected void sendMetricPoint(String metricName, double value, String[] tags) {
statsDClient.gauge(metricName, value, tags);
}

public void sendServiceCheck(String checkName, int status, String message,
String hostname, String[] tags) {
if (System.currentTimeMillis() - this.initializationTime > 300 * 1000) {
this.statsDClient.stop();
init();
}

ServiceCheck sc = new ServiceCheck(String.format("%s.can_connect", checkName),
status, message, hostname, tags);
statsDClient.serviceCheck(sc);
}

public void displayMetricReached() {
throw new UnsupportedOperationException();
}
Expand Down
6 changes: 6 additions & 0 deletions src/test/java/org/datadog/jmxfetch/SimpleTestJavaApp.java
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,12 @@ public void incrementHashMapCounter(int inc) {
hashmap.put("thisiscounter", hashmap.get("thisiscounter") + inc);
}

public void populateHashMap(int count) {
for (Integer i =1;i <= count ; i++ ) {
hashmap.put(i.toString(), i);
}
}

public HashMap<String, Integer> getHashmap() {
return hashmap;
}
Expand Down
Loading