Java 8 went out few weeks ago and the question of monitoring is already here. Apache Sirona has several monitoring/interception flavors like CDI, Spring, JavaAgent…but the most interesting is the javaagent which doesn’t mandate to be integrated with a particular technology.
Since it instruments bytecode the question of Java 8 compatibility is important.
Since last week Sirona javaagent now uses asm 5 which supports Java 8. Another important thing is the javaagent was rewritten to really instrument in place methods and not create a kind of proxy. What does it change?
Well first asm upgrade allows you to use Java 8 with Sirona which is already important.
Then if you write a little Java 8 application, let say this one:
package org.foo; // some imports public class SironaTest { @Test public void run() { assertEquals("foo", new Simple().name()); assertEquals("default name", new DefaultImpl().defaultName()); assertEquals("default name", new DefaultImpl2().defaultName()); dump(); } private void dump() { // dump sirona information playing with java 8 final List<Counter> c = new ArrayList<>(Repository.INSTANCE.counters()); System.out.println("#Counters = " + c.size()); c.stream() .filter(c1 -> !c1.getKey().getName().startsWith("com.intellij") && !c1.getKey().getName().startsWith("org.junit") && !c1.getKey().getName().startsWith("jdk.") && !c1.getKey().getName().startsWith("junit")) .sorted((c1, c2) -> c1.getKey().getName().compareTo(c2.getKey().getName())) .forEach(System.out::println); } public static class Simple { String name() { // to check we support lambda in enhanced classes return asList("foo", "bar").stream() .filter(c1 -> !c1.startsWith("b")) .reduce((a, b) -> a + b) .get(); } } public static class DefaultImpl implements DefaultItf { } public static interface DefaultItf { default String defaultName() { return "default name"; } } }
And if you add sirona javaagent on the test JVM you’ll get a lot of information and the interesting ones are:
DefaultCounter{concurrency=0, key=name=org.foo.SironaTest$DefaultImpl2.defaultName, dataStore=org.apache.sirona.store.counter.InMemoryCounterDataStore@763d9750, maxConcurrency=1, statistics=OptimizedStatistics{n=1, sum=19377.0, min=19377.0, max=19377.0, m1=19377.0, m2=0.0}} DefaultCounter{concurrency=0, key=name=org.foo.SironaTest$DefaultItf.defaultName, dataStore=org.apache.sirona.store.counter.InMemoryCounterDataStore@763d9750, maxConcurrency=1, statistics=OptimizedStatistics{n=2, sum=10669.0, min=2070.0, max=8599.0, m1=5334.5, m2=2.13139205E7}} DefaultCounter{concurrency=0, key=name=org.foo.SironaTest$Simple.lambda$name$3, dataStore=org.apache.sirona.store.counter.InMemoryCounterDataStore@763d9750, maxConcurrency=1, statistics=OptimizedStatistics{n=2, sum=42366.0, min=2109.0, max=40257.0, m1=21183.0, m2=7.27634952E8}} DefaultCounter{concurrency=0, key=name=org.foo.SironaTest$Simple.name, dataStore=org.apache.sirona.store.counter.InMemoryCounterDataStore@763d9750, maxConcurrency=1, statistics=OptimizedStatistics{n=1, sum=2.11358741E8, min=2.11358741E8, max=2.11358741E8, m1=2.11358741E8, m2=0.0}} DefaultCounter{concurrency=1, key=name=org.foo.SironaTest.dump, dataStore=org.apache.sirona.store.counter.InMemoryCounterDataStore@763d9750, maxConcurrency=1, statistics=OptimizedStatistics{n=0, sum=0.0, min=NaN, max=NaN, m1=NaN, m2=NaN}} DefaultCounter{concurrency=1, key=name=org.foo.SironaTest.run, dataStore=org.apache.sirona.store.counter.InMemoryCounterDataStore@763d9750, maxConcurrency=1, statistics=OptimizedStatistics{n=0, sum=0.0, min=NaN, max=NaN, m1=NaN, m2=NaN}}
If we clean up it a bit we get:
key=name=org.foo.SironaTest$DefaultImpl2.defaultName key=name=org.foo.SironaTest$DefaultItf.defaultName key=name=org.foo.SironaTest$Simple.lambda$name$3 key=name=org.foo.SironaTest$Simple.name
What we can see is:
- Sirona intercepts well java 8 methods
- Sirona intercepts well java 8 default interface methods 🙂 (here DefaultItf.defaultName())
- Sirona intercepts well java 8 lambdas 🙂 (here Simple.name() lambda seen as Simple.lambda$name$3)
So sirona is ready Java 8 so really no reason to not monitor your apps 😉