Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/woozoo73/adonistrack
Simple Java profiling tool
https://github.com/woozoo73/adonistrack
debug dynamic-analysis java logging performance profiler sequence-analysis
Last synced: 21 days ago
JSON representation
Simple Java profiling tool
- Host: GitHub
- URL: https://github.com/woozoo73/adonistrack
- Owner: woozoo73
- License: apache-2.0
- Created: 2019-04-16T01:32:14.000Z (over 5 years ago)
- Default Branch: master
- Last Pushed: 2024-01-28T03:41:35.000Z (11 months ago)
- Last Synced: 2024-08-05T17:27:05.081Z (4 months ago)
- Topics: debug, dynamic-analysis, java, logging, performance, profiler, sequence-analysis
- Language: Java
- Homepage:
- Size: 882 KB
- Stars: 4
- Watchers: 2
- Forks: 2
- Open Issues: 3
-
Metadata Files:
- Readme: README.adoc
- License: LICENSE.txt
Awesome Lists containing this project
- awesome-hacking-lists - woozoo73/adonistrack - Simple Java profiling tool (Java)
README
= AdonisTrack image:https://img.shields.io/badge/License-Apache%202.0-blue.svg["License", link="https://opensource.org/licenses/Apache-2.0"] image:https://maven-badges.herokuapp.com/maven-central/com.woozooha/adonistrack/badge.svg["Maven Central", link="https://maven-badges.herokuapp.com/maven-central/com.woozooha/adonistrack"]
Simple Java profiling tool. (The light version of 'hazin-tracer')
* You can trace the call stack immediately.
* There is no need to write code to track method calls.
* Provide method call information(parameters, return, error and execution time).
* Compatible with the Spring Framework.
* The information is not intermixed with concurrent calls.
* Provides extension points to customize.
* ...== Usage
=== 1. Add this library to your project
image:https://maven-badges.herokuapp.com/maven-central/com.woozooha/adonistrack/badge.svg["Maven Central", link="https://maven-badges.herokuapp.com/maven-central/com.woozooha/adonistrack"]
=== 2. Add AdonistrackFilter to your application
* If your application is not a web application, skip this section.
.Application.java
[source,java,indent=0]
----
package com.woozooha.adonistrack.test.spring;import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;import com.woozooha.adonistrack.filter.AdonistrackFilter;
@SpringBootApplication
public class Application {public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}@Bean
public FilterRegistrationBean profileFilter() {
FilterRegistrationBean registrationBean = new FilterRegistrationBean();registrationBean.setFilter(new AdonistrackFilter());
registrationBean.addUrlPatterns("/*");return registrationBean;
}}
----=== 3. Configure your aspect to profile
* Create a aspect by extending the `ProfileAspect`, such as `AdonisTrackAspect.java`
* Configure `profilePointcut` and `executionPointcut` of the aspect by using pointcut expression.
* You can set profile targets using pointcut expressions.
If you run into problems, you may need to change this @Pointcut expression.
The page below will help you.
https://howtodoinjava.com/spring-aop/aspectj-pointcut-expressions/.AdonisTrackAspect.java
[source,java,indent=0]
----
package com.woozooha.adonistrack.test.spring;import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;import com.woozooha.adonistrack.aspect.ProfileAspect;
@Aspect
@Component
public class AdonisTrackAspect extends ProfileAspect {/**
* Fix this @Pointcut expression according to your situation. For
* example, modify "com.woozooha.adonistrack.test.spring" to your application's
* top-level package name "com.yourcompany.killerapp".
*/
@Pointcut("execution(* *(..)) && (within(com.woozooha.adonistrack.test.spring..*) || within(com.woozooha.adonistrack.test.spring..*+))")
public void executionPointcut() {
}}
----=== 4. Run your application with above aspect `AdonistrackFilter` configuration and `AdonisTrackAspect.java`
.Runing application log
[indent=0]
----
. ____ _ __ _ _
/\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
\\/ ___)| |_)| | | | | || (_| | ) ) ) )
' |____| .__|_| |_|_| |_\__, | / / / /
=========|_|==============|___/=/_/_/_/
:: Spring Boot :: (v2.1.3.RELEASE)2019-04-17 13:45:18.014 INFO 254732 --- [ main] com.woozooha.hello.Application : Starting Application ...
2019-04-17 13:45:33.663 INFO 254732 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet : Completed initialization in 10 ms
----=== 5. Call your application and check the log
When your application is called via `GET /greeting?name=hello HTTP/1.1`
* This is the log when the execution was successful.
.Output log
[indent=0]
----
----> [REQUEST] GET http://localhost:8080/greeting/1 (230.83ms:100.00%)
----> com.woozooha.adonistrack.test.spring.GreetingController.greeting(1) (29.40ms:100.00%)
----> com.woozooha.adonistrack.test.spring.GreetingService.greeting(1) (25.33ms:100.00%)
----> com.sun.proxy.$Proxy87.findById(1) (19.92ms:100.00%)
<---- Optional[Greeting(id=1, content=Hello\nfoo)]
<---- Greeting(id=1, content=Hello\nfoo)
<---- Greeting(id=1, content=Hello\nfoo)
<---- [RESPONSE] 200
----* The above log means the following sequence diagram.
image:diagram-happy.png["Diagrams", link="https://github.com/francoislaberge/diagrams"]
* This is the log when the execution was failed.
.Output log
[indent=0]
----
----> [REQUEST] GET http://localhost:8080/greeting/2 (21.97ms:100.00%)
----> com.woozooha.adonistrack.test.spring.GreetingController.greeting(2) (5.60ms:100.00%)
----> com.woozooha.adonistrack.test.spring.GreetingService.greeting(2) (1.66ms:100.00%)
----> com.sun.proxy.$Proxy87.findById(2) (0.71ms:100.00%)
<---- Optional.empty
<<<<< java.util.NoSuchElementException: No value present
<<<<< java.util.NoSuchElementException: No value present
<---- [RESPONSE] 200
----* The above log means the following sequence diagram.
image:diagram-unhappy.png["Diagrams", link="https://github.com/francoislaberge/diagrams"]
=== 6. More options
To replace default "ToStringFormat" with custom format, you need to set property "adonistrack.to-string.class".
.Application.java
[source,java,indent=0]
----
@SpringBootApplication
public class Application {public static void main(String[] args) {
System.setProperty("adonistrack.to-string.class", YourCustomToStringFormat.class.getName());
SpringApplication.run(Application.class, args);
}...
}
----Adonistrack supports load-time-weaving for even more powerful profiling.
If you want to profile JDBC queries, do the following.* Add aop.xml file to your application project.
./META-INF/aop.xml
[source,xml,indent=0]
----
----
* Add VM arguments when run your application.
.VM arguments
----
-javaagent:/{your-home-path}/.m2/repository/org/aspectj/aspectjweaver/1.9.2/aspectjweaver-1.9.2.jar
----You can now see that the JDBC query is profiled as shown below.
.Output log
[indent=0]
----
----> [REQUEST] GET http://localhost:8080/greeting/1 (227.91ms:100.00%)
----> com.woozooha.adonistrack.test.spring.GreetingController.greeting(1) (36.04ms:100.00%)
----> com.woozooha.adonistrack.test.spring.GreetingService.greeting(1) (31.40ms:100.00%)
----> com.sun.proxy.$Proxy88.findById(1) (26.41ms:100.00%)
| [JDBC] [sql=select greeting0_.id as id1_0_0_, greeting0_.content as content2_0_0_ from greeting greeting0_ where greeting0_.id=?, parameterMap={1=1}]
<---- Optional[Greeting(id=1, content=Hello\nfoo)]
<---- Greeting(id=1, content=Hello\nfoo)
<---- Greeting(id=1, content=Hello\nfoo)
<---- [RESPONSE] 200
----== 7. Known issues
=== 1. HTTP status code mismatch errors can occur when using `AdonisTrackFilter`
* To fix this error:
* 1. Remove `AdonisTrackFilter`..Application.java
[source,java,indent=0]
----
package com.woozooha.adonistrack.test.spring;import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;import com.woozooha.adonistrack.filter.AdonistrackFilter;
@SpringBootApplication
public class Application {public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}}
----* 2. Depending on the situation, you can correct the HTTP status code by create a little bit of code as shown below.
.AdonistrackInterceptor.java
[source,java,indent=0]
----
package com.woozooha.adonistrack.test.spring;import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;import org.springframework.lang.Nullable;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;import com.woozooha.adonistrack.aspect.ProfileAspect;
import com.woozooha.adonistrack.domain.Event;
import com.woozooha.adonistrack.domain.Invocation;
import com.woozooha.adonistrack.domain.RequestInfo;
import com.woozooha.adonistrack.domain.RequestInfoEvent;
import com.woozooha.adonistrack.domain.ResponseInfo;
import com.woozooha.adonistrack.domain.ResponseInfoEvent;public class AdonistrackInterceptor implements HandlerInterceptor {
private static ThreadLocal CONTEXT = new ThreadLocal();
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
throws Exception {
if (request.getRequestURI().startsWith("/adonistrack")) {
return true;
}Invocation invocation = CONTEXT.get();
if (invocation == null) {
invocation = before(request);
CONTEXT.set(invocation);
}return true;
}@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
@Nullable ModelAndView modelAndView) throws Exception {
if (request.getRequestURI().startsWith("/adonistrack")) {
return;
}Invocation invocation = CONTEXT.get();
if (invocation != null) {
after(invocation, request, response);
CONTEXT.set(null);
}
}private Invocation before(HttpServletRequest request) {
Event event = new RequestInfoEvent(new RequestInfo(request));return ProfileAspect.before(event);
}private void after(Invocation invocation, HttpServletRequest request, HttpServletResponse response) {
Event event = new ResponseInfoEvent(new ResponseInfo(response));ProfileAspect.after(invocation, event);
}}
----* 3. Add your `AdonisTrackInterceptor`.
.WebConfig.java
[source,java,indent=0]
----
package com.woozooha.adonistrack.test.spring;import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;@Configuration
public class WebConfig implements WebMvcConfigurer {@Override
public void addInterceptors(InterceptorRegistry registry) {
AdonistrackInterceptor adonistrackInterceptor = new AdonistrackInterceptor();
registry.addInterceptor(adonistrackInterceptor).addPathPatterns("/**/*");
}}
----* 4. Now, RESPONSE status code is `500`.
.Output log
[indent=0]
----
----> [REQUEST] GET http://localhost:8080/greeting/2 (134.97ms:100.00%)
----> com.woozooha.adonistrack.test.spring.GreetingController.greeting(2) (29.34ms:100.00%)
----> com.woozooha.adonistrack.test.spring.GreetingService.greeting(2) (9.78ms:100.00%)
----> com.sun.proxy.$Proxy96.findById(2) (6.15ms:100.00%)
| [JDBC] [sql=select greeting0_.id as id1_0_0_, greeting0_.content as content2_0_0_ from greeting greeting0_ where greeting0_.id=?, parameterMap={1=2}]
<---- Optional.empty
<<<<< java.util.NoSuchElementException: No value present
<<<<< java.util.NoSuchElementException: No value present
<---- [RESPONSE] 500
----== License
AdonisTrack is Open Source software released under the Apache 2.0 license.
== AdonisTrack?
The flower language of Adonis is "sad memories" in the West but "eternal happiness" in the East.
image:adonis-flower-01.jpg["Adonis amurensis", link="https://en.wikipedia.org/wiki/Adonis_amurensis", width=42%]
image:adonis-flower-02.jpg["Adonis amurensis", link="https://en.wikipedia.org/wiki/Adonis_amurensis", width=42%]
image:adonis-flower-03.jpg["Adonis amurensis", link="https://en.wikipedia.org/wiki/Adonis_amurensis", width=42%]
image:adonis-flower-04.jpg["Adonis amurensis", link="https://en.wikipedia.org/wiki/Adonis_amurensis", width=42%]