In the usual use to some software, such as a treasure or a book, by recording the user's behavior to build and analyze the user's behavioral data, but also to better optimize the product design and improve the user experience. For example, in an order system, it is necessary to determine the tracking of user behavior, for example:
- Login/Logout
- Browse Products
- add-ons
- Search for product keywords
- an order (of goods)
The above behavior will need to use the logging system to store or record data, Java has several logging programs, a brief introduction to several implementation options, as well as the need to pay attention to the point.
Issues to be aware of when adding logs
Depending on the business, you need to use match to the right logging scheme. Several issues also need to be noted:
- It must not affect the original business logic.
- No errors can be reported, and even if they are, they cannot affect the original business code.
- For time-consuming logging code, use asynchronous methods
- Low intrusiveness, minimal changes to original code
Spring AOP
Spring AOP through facet programming to achieve the ability to dynamically add functionality without modifying the original code. This approach has the following benefits:
- low invasive
- Highly reusable
This article uses annotation-based AOP, first define a cutout annotation AopTest.
/**
* Cutting annotations
*/
@Target({, })
@Retention()
public @interface AopTest {
}
Create the notification @Around again:
@Around("@annotation()")
public Object annotationTest(ProceedingJoinPoint joinPoint) throws Throwable {
("pre-implementation");
Object result = (); // Implementation of the target methodology
Object[] args = ();
("post-implementation");
return result;
}
It's usually in thepost-implementation
Add logging can be, want to add logging in that method or interface, just need to add annotations on the method, such as adding annotations in the interface:
@GetMapping
@AopTest
public String first(String param) {
("fulfillmentfirstmethodologies");
return "result " + param;
}
After requesting the interface, the following output is available:
Before execution
Execute the first method
After
But there is a problem with the cutter, the execution of the cutter error, the method can not be executed, you need to catch exceptions to ensure the normal execution of the business code, to transform the notification of the above:
@Around("@annotation()")
public Object annotationTest(ProceedingJoinPoint joinPoint) throws Throwable {("pre-implementation");
("pre-implementation");
Object result = (); // Implementation of the target methodology
try {
Object[] args = ();
// Add Log
("post-implementation");
int a = 1/0;
} catch (Exception e) {
(());
}
return result;
}
After the modification, even if the cutout reports an error, it won't affect the execution of the business code anymore.
AOP is synchronous execution, if the log to add is a more time-consuming operation, it will also affect the response speed of the interface, at this time you can use asynchronous way, such as message queues.
To summarize, Spring AOP has several advantages and disadvantages.
-
Pros:
- low invasive
- Highly reusable
Disadvantages and Solutions:
1、Cutting errors may affect the business code
- Problem: Exceptions in cutovers that are not handled correctly may affect the normal execution of business code.
- Solution:
- Catch exceptions and ensure proper execution of business code
- Generally use try catch to catch exceptions and prevent upward propagation
2. Synchronized execution affects interface response speed
- Problem: If there are time-consuming operations in the cutout, the synchronization operation can cause the interface to become less responsive.
- Solution:
- Asynchronous execution of time-consuming operations via message queues
- Use @Async to execute the method asynchronously, detaching the task from the main thread and handing it off to another thread pool for execution
Event Listening + Asynchronous
The Spring event-listening mechanism is aPublish-Subscribe
pattern, which decouples event publishing from listening. Through this mechanism, the event publisher does not need to be concerned with the logic of listening, and the listener does not need to directly rely on the publisher.
Spring event listening has three components:
- event
Customize an event, inheriting ApplicationEvent:
@Getter
@Setter
public class DemoEvent extends ApplicationEvent {
private String name;
public DemoEvent(Object source) {
super(source);
}
}
- event listener
Listens for events based on the @EventListener annotation:
@Component
@Slf4j
public class DemoEventListener {
@EventListener
public void handleEvent(DemoEvent event){
(());
("event listener");
}
}
- Event Releases
To post an event using the method
@Autowired
private ApplicationEventPublisher applicationEventPublisher;
@Override
public void publish() {
// Execute the business code
("Execute login, current time {}",());
DemoEvent event = new DemoEvent(this);
("hello");
(event);
("Login completed, current time {}",()); ("Executing service.
("Executing service"); (event); ("Login completed, current time {}",()); ("Executing service"); ("Executing service")
}
After configuring event publishing and listening, add event publishing to the business code and logging to the listening method.
Although Spring event listener decouples publishing and listening, it only decouples the logic code.synchronous execution
and are all executed in the same thread, so event listening doesn't solve the problem of adding logging errors, and time consuming issues.
- Verify that the listener methods are synchronized
Add a delay to the event listener:
@EventListener
public void handleEvent(DemoEvent event){
try {
(2000);
} catch (InterruptedException e) {
();
}
(());
("event listener");
}
Console Output:
Execute login, current time 16:52:30.799
hello
Listening for events
Login completed, current time 16:52:33.799
Execute service
interface takes more than 3 seconds to execute, and the publish method waits until the listener method finishes executing.
Event listening is synchronized
。
- Verify that listening method error reporting affects the main process
Add an error code to the listener method:
@EventListener
public void handleEvent(DemoEvent event){
int a = 1/0;
(());
("事件监听");
}
Console Output:
Execute login, current time 17:10:08.396
: / by zero
The listener method reports an error, the interface also reports an error, and the business code cannot be executed, indicating that the
Listening to methods that report errors affects event posting methods
。
To solve the problem of error reporting, it is sufficient to use exception catching. And for delays, you need to use thesynchronous
The operation of theAsynchronous means that another thread is started to execute the listener method.
In addition to solving the problem of latency, asynchrony also incidentally solves the problem of error reporting.
Implementing asynchrony adds @Async asynchronous annotation to the listener method, and the listener method adds delay and error codes:
Execute login, current time 17:21:50.971
Completed login, current time 17:21:50.974
Execute service
The publish method is neither delayed nor affected by listening for errors, so asynchrony is the perfect solution to time-consuming and error-reporting problems.
message queue
Mass logging scenarios, message queues are a good choice, it is also decoupled publisher and subscriber, if the subscriber turned on the manual confirmation, the consumer also need to use try catch catch exception information to ensure that the message can be consumed normally.
summarize
This article describes several logging implementation options:
-
Spring AOP
:- Pros: Low invasiveness, code reproducibility
- Problems and solutions:
- The section may report an error, the error will affect the normal execution of the business code, the solution is to use try catch catch exceptions.
- Logging will affect the efficiency of business code execution, you can use the message queue asynchronous execution of logging operations
-
Event Listening + Asynchronous
:- Benefits: Decouple business logic and logging to improve code cohesion.
- Disadvantages as well as solutions:
- The same problems that exist with AOP also exist with event listening, where both error reporting and latency affect the business code. Error reporting can be used to catch exceptions, the delay problem can be solved using asynchronous way, and asynchronous another thread also by the way to solve the problem of error reporting affects the business code.
-
message queue
:- Benefits: Used in high concurrency journaling scenarios
- Problems: Increase the complexity and stability of the system, and also need to consider the loss and repeated consumption of messages.