Skip to content
Open
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
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,6 @@ target/
node_modules/
out/
*.class
.idea
*.iml

1 change: 1 addition & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
language: java
81 changes: 67 additions & 14 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,36 +1,89 @@
Under Siege
===============

Cassandra Statsd Reporting Tool
--------------------------------
===============================

Thanks to UnderSiege for getting this project off the ground.

REQUIREMENTS
----------------
* Maven
* Java
* Java 7

BUILD
----------------

Check which metrics library cassandra is using by looking in
cassandra/lib/metrics-core*, verify that pom.xml points to the
same exact version. For example, if you have metrics-core-2.2.0.jar,
make sure pom.xml has <version>2.2.0</version>.

`mvn package`

It may be necessary to build the jar against the same version of the metrics library being used in Cassandra.
Alternatively, grab the binary from bintray:

INSTAL
`curl -L http://dl.bintray.com/lookout/systems/com/github/lookout/metrics/agent/1.2/agent-1.2.jar -o agent-1.2.jar`

INSTALL
----------------

Toss the appropriate version of statsd library (hopefully in your .m2 folder by now) in your cassandra/lib/ directory.
Copy the statsd library from the .m2 folder to cassandra/lib.
Add the following to your cassandra startup script:

`JVM_OPTS="$JVM_OPTS -javaagent:/path/to/built.jar=localhost"`

Or whatever path you've decided to put your agent.

Note the '=localhost' at the end. You should change this to your statsd instance.

Copy the agent-1.2.jar to a new directory cassandra/plugins

Change cassandra startup to add this agent. This can be done in
a stock install by adding the following to /etc/default/cassandra:

`export JVM_OPTS="-javaagent:/usr/share/cassandra/plugins/agent-1.2.jar=localhost"`

Note the '=localhost' at the end. This supports the following syntaxes:
`hostname:port@interval`
For example:
`your.statsd.host.com:9999@60`
The default port is 8125 and the default interval is 10 (seconds); these
can be omitted. IPV6 is also supported with the following syntax:
`[2001:db8::1]:8888@300`
which means connect to 2001:db8::1 on port 8888 every 300 seconds.

REPORTING
----------------
A log message will be added to the system.log at startup to
confirm that everything is running, it looks like this:

`INFO [metrics-statsd-thread-1] 2014-12-19 19:05:37,120 StatsdReporter.java:65 - Statsd reporting to host localhost port 8125 every 10 seconds`

WHAT GETS REPORTED
------------------
Lots of stuff:

* Gossip statistics:
gossip.score.<IP>, which help decide who is closer/faster for queries
gossip.severity, which indicates how busy this node is self-reporting to others
* Per table statistics:
cfstats.<keyspace>.<columnfamily>.ReadCount
cfstats.<keyspace>.<columnfamily>.WriteCount
cfstats.<keyspace>.<columnfamily>.RecentReadLatencyMicros
cfstats.<keyspace>.<columnfamily>.RecentWriteLatencyMicros
cfstats.<keyspace>.<columnfamily>.TombstonesPerSlice
cfstats.<keyspace>.<columnfamily>.estimatedKeys
The last one is great for monitoring general trends, but of course don't
rely on that number to be very accurate.
* PHI reporter
Also supported is the currently-experimental PHI reporter, in PHI.<IP>,
coming to a Cassandra cluster near you soon.
* JVM GC metrics
* Anything else registered with yammer-metrics

DEBUGGING
----------------
Not working? There's a lot of tracing and debugging available. Change the
log4j-server.properties and add something like this to get extremely detailed
traces of what it's doing in the server.log.

`log4j.logger.com.github.lookout.metrics.agent.generators=TRACE`

TODO
----------------
Errors that happen during startup are not reported as well as they should
be, mostly because the logging system is not active during startup. The log
message is only generated when the actual metrics collector has run for the
first time.
130 changes: 74 additions & 56 deletions pom.xml
Original file line number Diff line number Diff line change
@@ -1,58 +1,76 @@
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>

<groupId>undersiege</groupId>
<artifactId>undersiege</artifactId>

<version>0.1</version>
<packaging>jar</packaging>

<name>cassandra-statsd-reporter-smm</name>
<url>http://maven.apache.org</url>

<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.target>1.6</maven.compiler.target>
<maven.compiler.source>1.6</maven.compiler.source>
</properties>

<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<configuration>
<archive>
<manifestFile>src/main/java/META-INF/MANIFEST.MF</manifestFile>
</archive>
</configuration>
</plugin>
</plugins>

</build>

<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>3.8.1</version>
<scope>test</scope>

</dependency>
<dependency>
<groupId>com.yammer.metrics</groupId>
<artifactId>metrics-core</artifactId>
<version>2.2.0</version>
</dependency>

<dependency>
<groupId>com.timgroup</groupId>
<artifactId>java-statsd-client</artifactId>
<version>2.0.0</version>
</dependency>



</dependencies>
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>

<groupId>com.github.lookout.metrics</groupId>
<artifactId>agent</artifactId>

<version>1.3</version>
<packaging>jar</packaging>

<name>cassandra-statsd-reporter</name>

<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.target>1.7</maven.compiler.target>
<maven.compiler.source>1.7</maven.compiler.source>
</properties>

<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>2.4</version>
<configuration>
<archive>
<manifestFile>src/main/java/META-INF/MANIFEST.MF</manifestFile>
</archive>
</configuration>
</plugin>
</plugins>

</build>

<dependencies>
<dependency>
<groupId>com.yammer.metrics</groupId>
<artifactId>metrics-core</artifactId>
<version>2.2.0</version>
<scope>provided</scope>
</dependency>

<dependency>
<groupId>com.timgroup</groupId>
<artifactId>java-statsd-client</artifactId>
<version>3.0.2</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.testng</groupId>
<artifactId>testng</artifactId>
<version>6.8.8</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
<version>1.10.17</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-simple</artifactId>
<version>1.7.9</version>
<scope>test</scope>
</dependency>

</dependencies>
<distributionManagement>
<repository>
<id>bintray-lookout-systems-cassandra-statsd-agent</id>
<name>lookout-systems-cassandra-statsd-agent</name>
<url>https://api.bintray.com/maven/lookout/systems/cassandra-statsd-agent</url>
</repository>
</distributionManagement>
</project>
4 changes: 2 additions & 2 deletions src/main/java/META-INF/MANIFEST.MF
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
Manifest-Version: 1.0
Premain-Class: com.shift.undersiege.ReportAgent
Manifest-Version: 1.0
Premain-Class: com.github.lookout.metrics.agent.ReportAgent
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
package com.github.lookout.metrics.agent;

/**
* Created by rkuris on 12/19/14.
*/
public class HostPortInterval {
public static final String DEFAULT_HOST = "localhost";
public static final int DEFAULT_PORT = 8125;
public static final int DEFAULT_INTERVAL = 10;

private final String host;
private final int port;
private final int interval;

public HostPortInterval(final String hostPortInterval) {
if (hostPortInterval == null || hostPortInterval.isEmpty()) {
this.host = DEFAULT_HOST;
this.port = DEFAULT_PORT;
this.interval = DEFAULT_INTERVAL;
return;
}
int intervalOffset = hostPortInterval.lastIndexOf('@');
final String hostPort;
if (intervalOffset == -1) {
this.interval = DEFAULT_INTERVAL;
hostPort = hostPortInterval;
} else {
this.interval = Integer.parseInt(hostPortInterval.substring(intervalOffset + 1));
hostPort = hostPortInterval.substring(0, intervalOffset);
}
int colonOffset = hostPort.lastIndexOf(':');
if (colonOffset == -1 || hostPort.endsWith("]")) {
this.host = stripBrackets(hostPort);
this.port = DEFAULT_PORT;
} else {
final String hostPart = hostPort.substring(0, colonOffset);
final String portPart = hostPort.substring(colonOffset + 1);
this.host = stripBrackets(hostPart);
this.port = Integer.parseInt(portPart);
}

}

private String stripBrackets(final String source) {
int sourceLength = source.length();
if (sourceLength > 2 && source.charAt(0) == '[' && source.charAt(sourceLength - 1) == ']') {
return source.substring(1, sourceLength - 1);
}
return source;
}

public String getHost() {
return host;
}

public int getPort() {
return port;
}

public int getInterval() {
return interval;
}

@Override
public String toString() {
return String.format("host %s port %d every %d seconds", host, port, interval);
}
}
26 changes: 26 additions & 0 deletions src/main/java/com/github/lookout/metrics/agent/ReportAgent.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package com.github.lookout.metrics.agent;

import com.timgroup.statsd.NonBlockingStatsDClient;
import com.timgroup.statsd.StatsDClient;

import java.io.IOException;
import java.lang.instrument.Instrumentation;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.concurrent.TimeUnit;

public class ReportAgent {

public static void premain(final String agentArgs, final Instrumentation inst) {
final String prefix = "cassandra";

final String[] reportingHostPorts = (agentArgs != null) ? agentArgs.split(",") : new String[]{null};
for (final String reportingHostPort : reportingHostPorts) {
final HostPortInterval hostPortInterval = new HostPortInterval(reportingHostPort);
final StatsDClient client = new NonBlockingStatsDClient(prefix, hostPortInterval.getHost(), hostPortInterval.getPort());
final StatsdReporter reporter = new StatsdReporter(hostPortInterval, client);
reporter.start(hostPortInterval.getInterval(), TimeUnit.SECONDS);
}
}
}

Loading