h1. echocat JeMoni 
"!https://secure.travis-ci.org/echocat/jemoni.png!":https://travis-ci.org/echocat/jemoni

...is a toolset for monitoring JVMs. Generally it aims features around JMX.

h1. JMX

h2. Make a bean to a MBean

You can simply use annotations to publish the information and operations of your beans.

bc.. @Bean(description = "Very cool things here")
public class Foo {
    
    private String _message;

    @Attribute(description = "A nice message")
    public String getMessage() {
        return _message;
    }

    public void setMessage(String message) {
        _message = message;
    }

    @Attribute(name= "numberOfDevil")
    public int getNumber() {
        return 666;
    }

    @Operation(description = "Say something")
    public String say(@Argument(description = "magicNumber") int forInteger) {
        return "What a cool number: " + forInteger;
    }

    public long getNumberThatIsHiddenInJmx() {
        return 1234;
    }
}

h2. Publish your bean

bc.. final JmxRegistry registry = new JmxRegistry();
final Registration registration = registry.register(new Foo());

// Do something here ... you bean is now known in you local MBeanServer

registration.close(); // Never forget to release it from the JMX context

h2. JvmHealth

The @org.echocat.jemoni.jmx.support.JvmHealth@ bean is a container with the most important values of the JVM. Normally this values are widespread in the whole JMX context. Here you can find all values at one place.

bc. final JvmHealth jvmHealth = new JvmHealth(jmxRegistry);
// Run your application...
jvmHealth.close(); // Close it at shutdown of your application

The resulting MBean will be located under @org.echocat.jemoni.jmx.support:name=JvmHealth@ and provides the attributes:
* @long gcCollectionCount@
* @long gcCollectionTime@
* @long heapCommitted@
* @long heapInit@
* @long heapMax@
* @long heapUsed@
* @long nonHeapCommitted@
* @long nonHeapInit@
* @long nonHeapMax@
* @long nonHeapUsed@
* @long loadedClassCount@
* @long unloadedClassCount@
* @long totalLoadedClassCount@
* @long busyThreadCount@
* @long totalThreadCount@
* @long uptime@ _Yes there are possible usage scenarios ;-)_

... and operations:
* @void exit(int exitCode)@
* @void gc()@
* @java.util.Map<String, String> getSystemProperties()@
* @String getSystemProperty(String name)@
* @void setSystemProperty(String name, String value)@

h2. ServletHealth

The @org.echocat.jemoni.jmx.support.ServletHealth@ is a @ServletFilter@ which could be used to determinate the performance of running requests. It will measure all incoming request and will create a statistic of _requests per second_ and _average request duration_.

The values could be separated in scopes that could configured in the web.xml.

h3. Default usage in web.xml

bc. <filter>
    <filter-name>serlvetHealth</filter-name>
    <filter-class>org.echocat.jemoni.jmx.support.ServletHealth</filter-class>
    <init-param>
        <param-name>mapping</param-name>
        <param-value>
            /foo.*>foo
            /bar.*>bar
            .*\.html>html
            .*\.action>action
        </param-value>
    </init-param>
</filter>
<filter-mapping>
    <filter-name>serlvetHealth</filter-name>
    <url-pattern>*</url-pattern>
</filter-mapping>

The resulting MBean will be located under @org.echocat.jemoni.jmx.support:name=ServletHealth@ and provides the attributes:
* @double foo.requestsPerSecond@
* @double foo.averageRequestDuration@
* @double bar.requestsPerSecond@
* @double bar.averageRequestDuration@
* @double html.requestsPerSecond@
* @double html.averageRequestDuration@
* @double action.requestsPerSecond@
* @double action.averageRequestDuration@
* @double requestsPerSecond@ - includes also the values of all other @*.requestsPerSecond@
* @double averageRequestDuration@ - includes also the values of all other @*.averageRequestDuration@

h3. Use an interceptor

It is possible to use an interceptor to ignore requests or modify the target scope name. You have to implement @org.echocat.jemoni.jmx.support.ServletHealth.Interceptor@ and define it in the web.xml.

bc. <init-param>
    <param-name>interceptor</param-name>
    <param-value>my.InterceptorImpl</param-value>
</init-param>

h3. Use it with spring

You have to ways. You could initialize this filter directly with spring and inject the dependencies directly. Our define it in the filter config and the filter will resolve the values over the @WebApplicationContext@.

bc. <init-param>
    <param-name>interceptor-ref</param-name>
    <param-value>myInterceptorBeanId</param-value>
</init-param>
<init-param>
    <param-name>registry-ref</param-name>
    <param-value>myJmxRegistryBeanId</param-value>
</init-param>

h1. Carbon

...or _Graphite_ is a tool to visualize measure points. It could be used to visualize performance data of websites, memory usage, ... 

"Visit the Graphite website to get in touch with it.":http://graphite.wikidot.com/
"!http://graphite.wdfiles.com/local--files/screen-shots/graphite_fullscreen_800.png!":http://graphite.wikidot.com/

h2. Writer

The first important tool is the @CarbonWriter@ to write measure points to a carbon server.

h3. Initialize with Spring

bc.. <beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:carbon="https://jemoni.echocat.org/schemas/carbon.xsd"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
                           https://jemoni.echocat.org/schemas/carbon.xsd https://jemoni.echocat.org/schemas/carbon-1.0.xsd">

    <carbon:writer address="my.carbon.server:666" />

</beans>

h3. Initialize direct

bc.. final CarbonWriter writer = new CarbonWriter();
writer.setAddress(new InetSocketAddress("my.carbon.server", 666));
writer.init();
// your application is running
writer.close(); // Do not forget to close it on JVM shutdown

h3. Use it

bc.. writer.write("my.path", 12.3);

h2. Jmx2CarbonBridge

If you want to push data of MBeans to a carbon you simply have to configure the Jmx2CarbonBridge. It automatically detects all MBeans that machtes the given rules and export it in a defined interval to the carbon server.

h3. Initialize with Spring

bc.. <beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:carbon="https://jemoni.echocat.org/schemas/carbon.xsd"
       xmlns:j2cr="https://jemoni.echocat.org/schemas/jmx2carbonRules.xsd"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
                           https://jemoni.echocat.org/schemas/carbon.xsd https://jemoni.echocat.org/schemas/carbon-1.0.xsd
                           https://jemoni.echocat.org/schemas/jmx2carbonRules.xsd https://jemoni.echocat.org/schemas/jmx2carbonRules-1.0.xsd">

    <carbon:writer address="my.carbon.server:666" />
    <carbon:jmx2carbonBridge writer-ref="org.echocat.jemoni.carbon.CarbonWriter">
        <j2cr:configuration>
            <j2cr:rule updateEvery="1s">
                <j2cr:include pattern="/.*org\.echocat\.jemoni\.demo1.*/" />
                <j2cr:exclude>
                    <j2cr:attribute pattern="/.*ignored/"/>
                </j2cr:exclude>
            </j2cr:rule>
            <j2cr:rule updateEvery="10s">
                <j2cr:include pattern="/.*org\.echocat\.jemoni\.demo2.*/" />
            </j2cr:rule>
        </j2cr:configuration>
    </carbon:jmx2carbonBridge>
</beans>

h3. Initialize direct

bc.. final Jmx2CarbonBridge bridge = new Jmx2CarbonBridge(writer);
bridge.setConfiguration(configuration().rules(
    rule().updateEvery("1s").includes(
        object().pattern("/.*org\\.echocat\\.jemoni\\.demo1.*/")
    ).excludes(
        object().attributes(
            attribute("/.*ignored/")
        )
    ), rule().updateEvery("10s").includes(
        object().pattern("/.*org\\.echocat\\.jemoni\\.demo2.*/")
    )
));
bridge.init();
// your application is running
bridge.close(); // Do not forget to close it on JVM shutdown

h3. Use it

You have nothing to do. Until the bridge is running it will write all the time to the carbon server. If it is not reachable some measure points will be lost. The carbon writer only buffers a limited amount of measure points.

h1. Links

* "Maven Repository":http://repo.echocat.org/echocat
* "Download latest bundle":https://repo.echocat.org/jemoni-releases/org/echocat/jemoni/bundle/[RELEASE]/bundle-[RELEASE]-distribution.zip (If you don't want to use maven)
* "Issues":https://github.com/echocat/jemoni/issues

h1. Use with Maven

bc. <repositories>
    <repository>
        <id>echocat</id>
        <url>http://repo.echocat.org/echocat</url>
    </repository>
</repositories>
<dependencies>
    <dependency>
        <groupId>org.echocat.jemoni</groupId>
        <artifactId>jmx</artifactId>
        <version>-- version --</version>
    </dependency>
    <dependency>
        <groupId>org.echocat.jemoni</groupId>
        <artifactId>carbon</artifactId>
        <version>-- version --</version>
    </dependency>
</dependencies>

"Find out what are the possible versions or what is the latest version.":http://repo.echocat.org/echocat/org/echocat/jemoni/

h1. License

echocat Velma is licensed under "MPL 2.0":http://mozilla.org/MPL/2.0/.

h1. Want to help?

You are welcome. Fork or "contact us":mailto:contact@echocat.org.
