Note: Yammer metrics has now moved to metrics-core.
from com.yammer.metrics:metrics-core:2.2.0 (NOT supported anymore) to com.codahale.metrics:metrics-core:3.0.*
from com.codahale.metrics:metrics-core:3.0.* to io.dropwizard.metrics:metrics-core:3.1.* since 2014.
When you are running long term applications like web applications, batch jobs, or stand-alone status update jobs, it is good to know some statistics about them, like number of requests served or request duration. You can also gather more generic information like the state of your internal collections, how many times some portion of code is being executed, or health checks like database availability, or any kind of connection to an external system.
All this kind of instrumentation can be achieved by using native JMX or using a modular project like yammer Metrics. Metrics provides a powerful way to measure the behaviour of your critical components and reporting them to a variety of systems like, JConsole, System Console, Ganglia, Graphite, CSV, or making them available through a web services as JSON data.
Step 1: Create a new Maven based Java project.
1 |
mvn archetype:generate -DgroupId=com.mytutorial -DartifactId=simpleYammerMetrics -DinteractiveMode=false |
Step 2: Import it into eclipse via File –> Import –> Maven –> “Existing Maven Projects”
Step 3: It should look like as shown below after completing the steps below.
Step 4: Update the pom.xml file as shown below
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 |
<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/maven-v4_0_0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.mytutorial</groupId> <artifactId>simpleYammerMetrics</artifactId> <packaging>jar</packaging> <version>1.0-SNAPSHOT</version> <name>simpleYammerMetrics</name> <url>http://maven.apache.org</url> <dependencies> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>3.8.1</version> <scope>test</scope> </dependency> <!-- Yammer metrics dependencies--> <dependency> <groupId>com.yammer.metrics</groupId> <artifactId>metrics-core</artifactId> <version>2.1.2</version> </dependency> <dependency> <groupId>com.yammer.metrics</groupId> <artifactId>metrics-annotation</artifactId> <version>2.1.2</version> </dependency> <dependency> <groupId>com.yammer.metrics</groupId> <artifactId>metrics-spring</artifactId> <version>2.1.2</version> </dependency> </dependencies> </project> |
Step 5: The dummy Request class.
1 2 3 4 5 |
package com.mytutorial; public class Request { } |
Step 6: The dummy trading engine interface.
1 2 3 4 5 6 |
package com.mytutorial; public interface TradeEngine { abstract void execute(Request... requests); } |
Step 7: The dummy trading engine implementation with yammer annotations to gather metrics.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 |
package com.mytutorial; import java.util.concurrent.atomic.AtomicInteger; import com.yammer.metrics.annotation.ExceptionMetered; import com.yammer.metrics.annotation.Gauge; import com.yammer.metrics.annotation.Timed; public class TradeEngineImpl implements TradeEngine { @Gauge private final AtomicInteger currentRequests = new AtomicInteger(); @Timed @ExceptionMetered public void execute(Request... requests) { executingRequests(requests.length); try { Thread.sleep(2000); //just to emulate some processing } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } private void executingRequests(int count) { this.currentRequests.addAndGet(count); } } |
Step 8: The spring context file to wire up Yammer and Java class defined above.
src/amin/resources/applicationContext.xml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:metrics="http://www.yammer.com/schema/metrics" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd http://www.yammer.com/schema/metrics http://www.yammer.com/schema/metrics/metrics.xsd"> <metrics:metrics-registry id="trade-metrics"/> <metrics:health-check-registry id="trade-health"/> <metrics:annotation-driven metrics-registry="trade-metrics" /> <metrics:jmx-reporter metrics-registry="trade-metrics"/> <bean id="tradeEngine" class="com.mytutorial.TradeEngineImpl"/> </beans> |
Step 8: The main class that starts the trading engine and fires requests every 5 seconds in a continuos loop.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 |
package com.mytutorial; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; public class TradeEngineMain { public static void main(String[] args) { ApplicationContext context = new ClassPathXmlApplicationContext( new String[] { "applicationContext.xml" }); TradeEngine tradeEngine = (TradeEngine) context.getBean("tradeEngine"); try { while (true) { Request[] requests = new Request[2]; requests[0] = new Request(); requests[1] = new Request(); tradeEngine.execute(requests); Thread.sleep(5000); } } catch (InterruptedException e) { e.printStackTrace(); } } } |
Step 9: Run the “TradeEngineMain“, which starts the trading engine in a continous loop.
Step 10: Whilst the engine is running, from a DOS prompt invoke the JMX window by typing “jconsole”. You can type “jps” to find the process id of the trading engine that is running.
Step 11: You can see the metrics in the jconsole JMX window as shown below. Yammer supports more outputs including RESTful web service to report stats.