Recently I’ve incorporated Perf4j for runtime performance statistics on a number of projects, combined with our in-house counters and other standard libs (actually I quite like the annotation-style logging of perf-stats, and the tag-name rollup conventions, and will probably retrofit both into our existing collection tools). I had a bit of difficulay initially getting AspectJ to do CTW for the collection (and in retrospect, very much want to investivate the agent-based LTW approach, since it’d give us the ability to flip on/off recording, while it should be basically just as fast except on object creation – which for Spring/Singleton instantiated services (most of our performance code) is not significant.
Anyhow, the meat, plugin config 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 | <plugin> <groupId>org.codehaus.mojo</groupId> <artifactId>aspectj-maven-plugin</artifactId> <version>1.3</version> <configuration> <showWeaveInfo>true</showWeaveInfo> <source>1.6</source> <weaveDependencies> <dependency> <groupId>org.perf4j</groupId> <artifactId>perf4j</artifactId> </dependency> </weaveDependencies> </configuration> <executions> <execution> <goals> <goal>compile</goal> <!-- use this goal to weave all your main classes --> <goal>test-compile</goal> <!-- use this goal to weave all your test classes --> </goals> </execution> </executions> </plugin> |
Also dependencies (we use Log4j, though we’re looking at Logback as well):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | <dependency> <groupId>org.aspectj</groupId> <artifactId>aspectjrt</artifactId> <version>1.6.7</version> </dependency> <dependency> <groupId>org.perf4j</groupId> <artifactId>perf4j</artifactId> <version>0.9.13</version> <classifier>log4jonly</classifier> </dependency> <dependency> <groupId>commons-jexl</groupId> <artifactId>commons-jexl</artifactId> <version>1.1</version> </dependency> |
Performance note: We did some unit testing of methods which were instrumented/non-instrumented (our unit test basically spewed out a couple thousand garbage string+ints in a loop, which was instrumented or not)
We saw something like 3x the number of minor GCs (though GC was still fast) – no additional major GCs after adding Perf4j. Overall execution time was higher as well, though not by the same degree.
Just a question: how did you get past the NoSuchMethodException on the TimingAspect? I’m trying exactly the same thing, but when I run my @Profiled classes, they always end up with a NSME.
I don’t remember getting a NSME when I was working through – did you make sure to only grab the log4j (or whatever framework you’re using) version of the jar? I know strange things happen trying to weave in all framework versions, since they clobber each other.