Skip to content

Commit

Permalink
update docs
Browse files Browse the repository at this point in the history
  • Loading branch information
hoangtien2k3 committed Aug 22, 2024
1 parent 37cc1fa commit 018b2f8
Show file tree
Hide file tree
Showing 54 changed files with 4,406 additions and 153 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ This README provides quickstart instructions on running [`fw-commons`]() on bare
[![Maven Central](https://img.shields.io/badge/maven--central-1.1.0-orange.svg?style=plastic&logo=apachemaven)](https://central.sonatype.com/artifact/io.github.hoangtien2k3/fw-commons/1.1.0)
[![Gradle](https://img.shields.io/badge/gradle-1.1.0-orange.svg?style=plastic&logo=apachemaven)](https://central.sonatype.com/artifact/io.github.hoangtien2k3/fw-commons/1.1.0)

### ⬇️ [Download From Gradle and Maven Central](https://central.sonatype.com/artifact/cn.ponfee/commons-core/1.4)
#### ⬇️ [Download From Gradle and Maven Central](https://central.sonatype.com/artifact/io.github.hoangtien2k3/fw-commons/1.1.0)

#### Gradle

Expand Down
10 changes: 7 additions & 3 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@
<developer>
<name>Hoang Anh Tien</name>
<email>[email protected]</email>
<organization>io.hoangtien2k3</organization>
<organization>io.github.hoangtien2k3</organization>
<organizationUrl>https://github.com/hoangtien2k3</organizationUrl>
</developer>
</developers>
Expand Down Expand Up @@ -433,6 +433,7 @@
<version>${maven-javadoc-plugin.version}</version>
<configuration>
<javadocExecutable>${java.home}/bin/javadoc</javadocExecutable>
<failOnError>false</failOnError>
</configuration>
<executions>
<execution>
Expand Down Expand Up @@ -507,7 +508,8 @@
<removeUnusedImports/>
<palantirJavaFormat/>
<licenseHeader>
<content><![CDATA[
<content>
<![CDATA[
/*
* Copyright $YEAR author - Hoàng Anh Tiến
*
Expand All @@ -522,7 +524,9 @@
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
*/
]]></content>
]]>
</content>
</licenseHeader>
</java>
</configuration>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,16 +19,108 @@
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

/**
* The {@code LogPerformance} annotation is used to mark methods or classes for
* performance logging. It allows developers to specify what type of information
* should be logged when the annotated method or class is executed, including
* input arguments, output results, and other custom information.
*
* <p>
* This annotation is typically applied to methods in a service layer where
* performance monitoring is essential. The annotation can be configured to log
* specific types of data, such as input arguments, output results, and the
* duration of method execution. The logged information can then be used for
* performance analysis, debugging, and auditing purposes.
* </p>
*
* <h2>Example Usage:</h2>
*
* <pre>{@code
* @LogPerformance(logType = "API_CALL", actionType = "FETCH_DATA", logInput = true, logOutput = true, title = "Fetching Data")
* public Mono<DataResponse> fetchData(String id) {
* // Method implementation
* }
* }</pre>
*
* <p>
* In this example, the `fetchData` method is annotated with
* {@code @LogPerformance}, which will log the input arguments, output results,
* and execution duration when the method is called. The log will include the
* specified `logType`, `actionType`, and `title`.
* </p>
*
* <h2>Retention and Target:</h2>
* <p>
* The annotation is retained at runtime ({@link RetentionPolicy#RUNTIME}) and
* can be applied to both methods and types (classes or interfaces)
* ({@link ElementType#METHOD}, {@link ElementType#TYPE}).
* </p>
*/
@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface LogPerformance {

/**
* Specifies the type of log entry, such as "API_CALL", "DB_QUERY", etc.
* <p>
* This value helps categorize logs based on the type of operation being logged.
* For instance, you might use different log types for API calls versus database
* queries to differentiate them in your log analysis.
* </p>
*
* @return the type of log entry
*/
String logType() default "";

/**
* Specifies the type of action being performed, such as "CREATE", "UPDATE",
* "DELETE", etc.
* <p>
* This value can be used to identify what kind of action is being logged,
* providing more context for the log entry. For example, you might have actions
* like "FETCH_DATA", "SAVE_ENTITY", etc.
* </p>
*
* @return the type of action being logged
*/
String actionType() default "";

/**
* Indicates whether the output (result) of the method should be logged.
* <p>
* When set to {@code true}, the output of the method will be logged, provided
* it can be serialized. This is useful for tracing the results of method
* executions, especially when debugging or monitoring system behavior.
* </p>
*
* @return {@code true} if the output should be logged, {@code false} otherwise
*/
boolean logOutput() default true;

/**
* Indicates whether the input arguments of the method should be logged.
* <p>
* When set to {@code true}, the input arguments to the method will be logged.
* This is useful for capturing the state of the inputs when the method was
* called, which can be important for understanding the context of the log
* entry.
* </p>
*
* @return {@code true} if the input arguments should be logged, {@code false}
* otherwise
*/
boolean logInput() default true;

/**
* Specifies a custom title for the log entry.
* <p>
* This title can be used to provide a brief description of the logged
* operation, making it easier to identify and search for specific log entries
* in your logging system. For example, the title might be something like "User
* Login Attempt" or "Order Processing".
* </p>
*
* @return the custom title for the log entry
*/
String title() default "";
}
Original file line number Diff line number Diff line change
Expand Up @@ -22,16 +22,62 @@
import org.checkerframework.checker.nullness.qual.NonNull;
import org.checkerframework.checker.nullness.qual.Nullable;

/**
* This class implements the {@link RemovalListener} interface and provides
* custom handling for cache entry removals. It logs information when a cache
* entry is evicted and invokes a specified method.
*
* <p>
* The class uses Lombok annotations {@code @Slf4j} for logging and
* {@code @AllArgsConstructor} to generate a constructor with one parameter for
* each field in the class.
*
* <p>
* This listener is typically used in caching mechanisms where specific actions
* need to be taken when an entry is removed due to eviction.
*
* <p>
* The listener relies on a {@link Method} instance, which is passed through the
* constructor. This method is invoked whenever a cache entry associated with it
* is evicted.
*
* <p>
* Example usage:
*
* <pre>
* {@code
* Cache<String, Object> cache = Caffeine.newBuilder().removalListener(new CustomizeRemovalListener(someMethod))
* .build();
* }
* </pre>
*
* @author Your Name
*/
@Slf4j
@AllArgsConstructor
public class CustomizeRemovalListener implements RemovalListener {
private Method method;
private final Method method;

/**
* Handles the removal of a cache entry. If the removal cause is eviction, this
* method logs the event and invokes the method provided during the creation of
* this listener.
*
* @param key
* the key of the removed cache entry, can be null
* @param value
* the value of the removed cache entry, can be null
* @param removalCause
* the cause of the removal, never null
*/
@Override
public void onRemoval(@Nullable Object key, @Nullable Object value, @NonNull RemovalCause removalCause) {
if (removalCause.wasEvicted()) {
log.info("Cache " + method.getDeclaringClass().getSimpleName() + "." + method.getName()
+ " was evicted because " + removalCause);
log.info(
"Cache {}.{} was evicted because {}",
method.getDeclaringClass().getSimpleName(),
method.getName(),
removalCause);
CacheUtils.invokeMethod(method);
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,22 +21,84 @@
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.context.annotation.Configuration;

/**
* This aspect class is responsible for logging the performance of methods in
* the specified packages. It uses AOP (Aspect-Oriented Programming) to
* intercept method calls and log relevant information before and after the
* method execution.
*
* <p>
* The class uses Spring AOP and relies on two pointcuts to identify which
* methods should be logged:
* <ul>
* <li>{@code performancePointCut}: Matches methods in the specified packages
* (controller, service, repository, client) except for those in the Spring Boot
* Actuator package.</li>
* <li>{@code logPerfMethods}: Matches methods annotated with
* {@link io.hoangtien2k3.commons.annotations.LogPerformance}.</li>
* </ul>
*
* <p>
* The {@code @Around} advice is applied to the methods matched by these
* pointcuts, and it delegates the logging logic to {@link LoggerAspectUtils}.
*
* <p>
* Example of usage:
*
* <pre>
* {@code
* @LogPerformance
* public void someMethod() {
* // method implementation
* }
* }
* </pre>
*
* <p>
* The class is annotated with {@code @Aspect} to define it as an aspect, and
* {@code @Configuration} to ensure it is registered as a Spring bean. It also
* uses {@code @RequiredArgsConstructor} from Lombok to generate a constructor
* that injects the required dependencies.
*
* @author hoangtien2k3
*/
@Aspect
@Configuration
@RequiredArgsConstructor
public class LoggerAspect {

private final LoggerAspectUtils loggerAspectUtils;

/**
* Pointcut that matches the execution of any method within the specified
* packages (controller, service, repository, client) except for those under the
* Spring Boot Actuator package.
*/
@Pointcut("(execution(* io.hoangtien2k3.commons.*.controller..*(..)) || "
+ "execution(* io.hoangtien2k3.commons.*.service..*(..)) || "
+ "execution(* io.hoangtien2k3.commons.*.repository..*(..)) || "
+ "execution(* io.hoangtien2k3.commons.*.client..*(..))) &&"
+ "!execution(* org.springframework.boot.actuate..*(..))")
public void performancePointCut() {}

/**
* Pointcut that matches methods annotated with
* {@link io.hoangtien2k3.commons.annotations.LogPerformance}.
*/
@Pointcut("@annotation(io.hoangtien2k3.commons.annotations.LogPerformance)")
private void logPerfMethods() {}

/**
* Around advice that wraps the matched method executions, providing logging
* functionality around the method invocation. The actual logging logic is
* delegated to {@link LoggerAspectUtils#logAround}.
*
* @param joinPoint
* the join point representing the method execution
* @return the result of the method execution
* @throws Throwable
* if the method execution throws an exception
*/
@Around("performancePointCut() || logPerfMethods()")
public Object logAround(ProceedingJoinPoint joinPoint) throws Throwable {
return loggerAspectUtils.logAround(joinPoint);
Expand Down
Loading

0 comments on commit 018b2f8

Please sign in to comment.