Skip to content

Commit f331ed5

Browse files
authored
Merge pull request #31 from spt-development/feature/spring-boot-3.3.1-upgrade
Feature/spring boot 3.3.1 upgrade
2 parents 4ba387a + 62c7c23 commit f331ed5

24 files changed

+962
-210
lines changed

README.md

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,35 @@ public DaoSupportLogger daoSupportLogger() {
5757
`Unable to proxy interface-implementing method [public final void org.springframework.dao.support.DaoSupport.afterPropertiesSet() throws java.lang.IllegalArgumentException,org.springframework.beans.factory.BeanInitializationException]
5858
because it is marked as final, consider using interface-based JDK proxies instead.`
5959

60+
The aspects above rely on classes either extending specific base classes or being annotated with particular annotations. `BeanLogger` has
61+
been introduced to add logging to arbitrary beans whether they are annotated with annotations such as `@Component` or whether they are
62+
instantiated with a factory method. Logging for arbitrary beans is enabled with the `EnableBeanLogging` annotation:
63+
64+
```java
65+
@Configuration
66+
@EnableBeanLogging(
67+
excludedClasses = MyExcludedBean.class,
68+
includeBasePackageClasses = {
69+
MyLoggedBean.class
70+
}
71+
)
72+
static class MyConfiguration {
73+
@Bean
74+
MyLoggedClass myLoggedBean() {
75+
return new MyLoggedClass();
76+
}
77+
78+
@Bean
79+
MyExcludedBean myExcludedBean() {
80+
return new MyExcludedBean();
81+
}
82+
}
83+
```
84+
85+
*NOTE* `excludedClasses` only excludes the class from logging being added with `BeanLogger` and as such, logging could still be added
86+
with one of the other aspects from this librar, such as `DaoSupportLogger` if it extends the right base class or is annotated with the
87+
right annotation.
88+
6089
Building locally
6190
================
6291

config/checkstyle/spt_checks_suppressions.xml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,9 @@
44
"https://checkstyle.org/dtds/suppressions_1_2.dtd">
55
<suppressions>
66
<!-- Allow Logger aspect methods to throw Throwable -->
7+
<suppress checks="IllegalThrows" files="src[\\/]main[\\/]java[\\/]com[\\/]spt[\\/]development[\\/]logging[\\/]spring[\\/]invocation[\\/]LoggedInvocation.java" />
8+
<suppress checks="IllegalThrows" files="src[\\/]main[\\/]java[\\/]com[\\/]spt[\\/]development[\\/]logging[\\/]spring[\\/]invocation[\\/]ProceedingJoinPointAdapter.java" />
9+
<suppress checks="IllegalThrows" files="src[\\/]main[\\/]java[\\/]com[\\/]spt[\\/]development[\\/]logging[\\/]spring[\\/]InvocationLogger.java" />
710
<suppress checks="IllegalThrows" files="src[\\/]main[\\/]java[\\/]com[\\/]spt[\\/]development[\\/]logging[\\/]spring[\\/]LoggerAspect.java" />
811
<suppress checks="IllegalThrows" files="src[\\/]main[\\/]java[\\/]com[\\/]spt[\\/]development[\\/]logging[\\/]spring[\\/](JmsListener|RestController|Repository|Service)Logger.java" />
912
</suppressions>

config/findbugs/findbugs-exclude.xml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,4 +21,10 @@
2121
<Class name="com.spt.development.logging.spring.ServiceLogger" />
2222
<Bug pattern="SLF4J_SIGN_ONLY_FORMAT" />
2323
</Match>
24+
25+
<!-- No obvious workaround - not possible to take a copy of proceedingJoinPoint -->
26+
<Match>
27+
<Class name="com.spt.development.logging.spring.invocation.ProceedingJoinPointAdapter" />
28+
<Bug pattern="EI_EXPOSE_REP2" />
29+
</Match>
2430
</FindBugsFilter>

config/versions/version-rules.xml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,5 +45,10 @@
4545
<ignoreVersion type="regex">.*</ignoreVersion>
4646
</ignoreVersions>
4747
</rule>
48+
<rule groupId="org.springframework" artifactId="spring-framework-bom" comparisonMethod="maven">
49+
<ignoreVersions>
50+
<ignoreVersion type="regex">.*</ignoreVersion>
51+
</ignoreVersions>
52+
</rule>
4853
</rules>
4954
</ruleset>
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
## New Features
2+
3+
* Added logging for public methods of any bean of types from configured packages.
4+
5+
## Dependencies
6+
7+
* Aligned dependencies with [Spring Boot 3.3.1](https://github.com/spring-projects/spring-boot/releases/tag/v3.3.1)

pom.xml

Lines changed: 34 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33

44
<groupId>com.spt-development</groupId>
55
<artifactId>spt-development-logging-spring</artifactId>
6-
<version>3.1.2-SNAPSHOT</version>
6+
<version>3.2.0-SNAPSHOT</version>
77

88
<name>logging-spring</name>
99
<description>A very simple library for getting/setting the current correlation ID, utilising ThreadLocal.</description>
@@ -41,10 +41,10 @@
4141
<aspectj.version>1.9.22</aspectj.version>
4242
<httpcore5.version>5.2.4</httpcore5.version>
4343
<slf4j.version>2.0.13</slf4j.version>
44-
<spring.version>6.1.8</spring.version>
44+
<spring.version>6.1.10</spring.version>
4545

4646
<!-- Test dependency versions -->
47-
<spt-development-test.version>3.1.7</spt-development-test.version>
47+
<spt-development-test.version>3.1.8</spt-development-test.version>
4848

4949
<!-- Test dependency versions, matched to Spring Boot -->
5050
<hamcrest.version>2.2</hamcrest.version>
@@ -55,31 +55,31 @@
5555
<!-- Plugin versions -->
5656
<build-helper-maven-plugin.version>3.6.0</build-helper-maven-plugin.version>
5757
<checkstyle-maven-plugin.version>3.4.0</checkstyle-maven-plugin.version>
58-
<dependency-check-maven.version>9.2.0</dependency-check-maven.version>
58+
<dependency-check-maven.version>10.0.2</dependency-check-maven.version>
5959
<jacoco-maven-plugin.version>0.8.12</jacoco-maven-plugin.version>
6060
<license-maven-plugin.version>2.4.0</license-maven-plugin.version>
6161
<maven-compiler-plugin.version>3.13.0</maven-compiler-plugin.version>
62-
<maven-dependency-plugin.version>3.6.1</maven-dependency-plugin.version>
62+
<maven-dependency-plugin.version>3.7.1</maven-dependency-plugin.version>
6363
<maven-enforcer-plugin.version>3.5.0</maven-enforcer-plugin.version>
6464
<maven-gpg-plugin.version>3.2.4</maven-gpg-plugin.version>
6565
<maven-javadoc-plugin.version>3.7.0</maven-javadoc-plugin.version>
6666
<maven-jxr-plugin.version>3.4.0</maven-jxr-plugin.version>
67-
<maven-pmd-plugin.version>3.22.0</maven-pmd-plugin.version>
68-
<maven-release-plugin.version>3.0.1</maven-release-plugin.version>
67+
<maven-pmd-plugin.version>3.24.0</maven-pmd-plugin.version>
68+
<maven-release-plugin.version>3.1.0</maven-release-plugin.version>
6969
<maven-scm-plugin.version>2.1.0</maven-scm-plugin.version>
7070
<maven-source-plugin.version>3.3.1</maven-source-plugin.version>
71-
<maven-surefire-plugin.version>3.2.5</maven-surefire-plugin.version>
71+
<maven-surefire-plugin.version>3.3.1</maven-surefire-plugin.version>
7272
<nexus-staging-plugin.version>1.7.0</nexus-staging-plugin.version>
7373
<pitest-maven.version>1.16.1</pitest-maven.version>
74-
<spotbugs.version>4.8.5.0</spotbugs.version>
75-
<versions-maven-plugin.version>2.16.2</versions-maven-plugin.version>
74+
<spotbugs.version>4.8.6.2</spotbugs.version>
75+
<versions-maven-plugin.version>2.17.0</versions-maven-plugin.version>
7676

7777
<!-- Plugin dependencies -->
7878
<checkstyle.version>10.17.0</checkstyle.version>
7979
<findbugs-slf4j-bug-pattern.version>1.5.0</findbugs-slf4j-bug-pattern.version>
8080
<findbugs-sec-bug-pattern.version>1.12.0</findbugs-sec-bug-pattern.version>
8181
<pitest-junit5-plugin.version>1.2.1</pitest-junit5-plugin.version>
82-
<pmd.version>7.2.0</pmd.version>
82+
<pmd.version>7.3.0</pmd.version>
8383
</properties>
8484

8585
<dependencyManagement>
@@ -118,6 +118,21 @@
118118

119119
<dependencies>
120120
<!-- Spring dependencies -->
121+
<dependency>
122+
<groupId>org.springframework</groupId>
123+
<artifactId>spring-aop</artifactId>
124+
<!-- Version defined in spring framework bom, imported in dependencyManagement section -->
125+
</dependency>
126+
<dependency>
127+
<groupId>org.springframework</groupId>
128+
<artifactId>spring-beans</artifactId>
129+
<!-- Version defined in spring framework bom, imported in dependencyManagement section -->
130+
</dependency>
131+
<dependency>
132+
<groupId>org.springframework</groupId>
133+
<artifactId>spring-context</artifactId>
134+
<!-- Version defined in spring framework bom, imported in dependencyManagement section -->
135+
</dependency>
121136
<dependency>
122137
<groupId>org.springframework</groupId>
123138
<artifactId>spring-core</artifactId>
@@ -192,6 +207,12 @@
192207
<version>${mockito.version}</version>
193208
<scope>test</scope>
194209
</dependency>
210+
<dependency>
211+
<groupId>org.springframework</groupId>
212+
<artifactId>spring-test</artifactId>
213+
<scope>test</scope>
214+
<!-- Version defined in spring framework bom, imported in dependencyManagement section -->
215+
</dependency>
195216

196217
<!-- Test dependencies not directly related to testing -->
197218
<dependency>
@@ -471,7 +492,7 @@
471492
<limit>
472493
<counter>LINE</counter>
473494
<value>COVEREDRATIO</value>
474-
<minimum>0.97</minimum>
495+
<minimum>0.83</minimum>
475496
</limit>
476497
</limits>
477498
<includes>
@@ -542,7 +563,7 @@
542563
<configuration>
543564
<mutationThreshold>100</mutationThreshold>
544565
<excludedClasses>
545-
<param>com.spt.development.audit.spring.security.AuthenticationAdapterFactory</param>
566+
<param>com.spt.development.logging.spring.annotation.BeanLoggerConfiguration</param>
546567
</excludedClasses>
547568
</configuration>
548569
<executions>
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
package com.spt.development.logging.spring;
2+
3+
import com.spt.development.logging.spring.invocation.MethodInvocationAdapter;
4+
import org.aopalliance.intercept.MethodInterceptor;
5+
import org.aopalliance.intercept.MethodInvocation;
6+
7+
/**
8+
* Logs calls to methods. Intended to be combined with {@link org.springframework.aop.aspectj.AspectJExpressionPointcutAdvisor}
9+
* to add logging to the public methods of arbitrary Spring beans.
10+
*/
11+
public class BeanLogger extends InvocationLogger implements MethodInterceptor {
12+
13+
/**
14+
* Creates a new instance of the logger method interceptor. The log statements added by the interceptor will include the
15+
* current correlation ID; see {@link BeanLogger#BeanLogger(boolean)} to disable this behaviour.
16+
*/
17+
public BeanLogger() {
18+
this(true);
19+
}
20+
21+
/**
22+
* Creates a new instance of the logger method interceptor.
23+
*
24+
* @param includeCorrelationIdInLogs a flag to determine whether the correlation ID should be explicitly included
25+
* in the log statements added by the interceptor.
26+
*/
27+
public BeanLogger(final boolean includeCorrelationIdInLogs) {
28+
super(includeCorrelationIdInLogs);
29+
}
30+
31+
/**
32+
* Outputs DEBUG level logging when a public method intercepted by this interceptor is called and when it
33+
* returns (without exception). If TRACE level logging is enabled and the method has a non-<code>void</code>
34+
* return type, the return value will be included in the logging. For example:
35+
*
36+
* <pre>
37+
* [40872057-a1b6-4fdd-bce1-7882929bbce6] MyBean.read(4)
38+
* ...
39+
* [40872057-a1b6-4fdd-bce1-7882929bbce6] MyBean.read Returned: MyEntity(id=4, name=test)
40+
* </pre>
41+
*
42+
* @param invocation the method invocation required for implementing a {@link MethodInterceptor}.
43+
*
44+
* @return the value returned from the method logged.
45+
*
46+
* @throws Throwable thrown if the method logged throws a {@link Throwable}.
47+
*/
48+
@Override
49+
public Object invoke(MethodInvocation invocation) throws Throwable {
50+
return super.log(new MethodInvocationAdapter(invocation));
51+
}
52+
}
Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
package com.spt.development.logging.spring;
2+
3+
import com.spt.development.cid.CorrelationId;
4+
import com.spt.development.logging.spring.invocation.LoggedInvocation;
5+
import org.slf4j.LoggerFactory;
6+
import org.slf4j.event.Level;
7+
8+
import java.lang.reflect.Method;
9+
import java.util.function.BiConsumer;
10+
11+
import static com.spt.development.logging.spring.LoggerUtil.formatArgs;
12+
13+
abstract class InvocationLogger {
14+
15+
private final boolean includeCorrelationIdInLogs;
16+
private final boolean isStartAndCompleteMethodLoggedAtInfo;
17+
18+
InvocationLogger(final boolean includeCorrelationIdInLogs) {
19+
this(includeCorrelationIdInLogs, false);
20+
}
21+
22+
InvocationLogger(final boolean includeCorrelationIdInLogs, final boolean isStartAndCompleteMethodLoggedAtInfo) {
23+
this.includeCorrelationIdInLogs = includeCorrelationIdInLogs;
24+
this.isStartAndCompleteMethodLoggedAtInfo = isStartAndCompleteMethodLoggedAtInfo;
25+
}
26+
27+
Object log(final LoggedInvocation invocation) throws Throwable {
28+
final Method method = invocation.getMethod();
29+
final org.slf4j.Logger log = LoggerFactory.getLogger(invocation.getDeclaringClass());
30+
31+
if (log.isEnabledForLevel(isStartAndCompleteMethodLoggedAtInfo ? Level.INFO : Level.DEBUG)) {
32+
startAndCompleteMethodLogger().accept(
33+
log, "{}.{}({})", invocation.getDeclaringClass().getSimpleName(), method.getName(),
34+
formatArgs(method.getParameterAnnotations(), invocation.getArgs()));
35+
}
36+
return proceed(invocation, log);
37+
}
38+
39+
Object proceed(LoggedInvocation invocation, org.slf4j.Logger log) throws Throwable {
40+
final Object result = invocation.proceed();
41+
42+
if (log.isTraceEnabled()) {
43+
final Method method = invocation.getMethod();
44+
45+
if (!method.getReturnType().equals(void.class)) {
46+
trace(log, "{}.{} Returned: {}", invocation.getDeclaringClass().getSimpleName(), method.getName(), result);
47+
48+
return result;
49+
}
50+
}
51+
52+
startAndCompleteMethodLogger().accept(
53+
log, "{}.{} - complete",
54+
invocation.getDeclaringClass().getSimpleName(),
55+
invocation.getMethod().getName()
56+
);
57+
return result;
58+
}
59+
60+
private LoggerConsumer startAndCompleteMethodLogger() {
61+
return isStartAndCompleteMethodLoggedAtInfo ? this::info : this::debug;
62+
}
63+
64+
void trace(org.slf4j.Logger logger, String format, Object... arguments) {
65+
log(logger::trace, format, arguments);
66+
}
67+
68+
void debug(org.slf4j.Logger logger, String format, Object... arguments) {
69+
log(logger::debug, format, arguments);
70+
}
71+
72+
void info(org.slf4j.Logger logger, String format, Object... arguments) {
73+
log(logger::info, format, arguments);
74+
}
75+
76+
void error(org.slf4j.Logger logger, String format, Object... arguments) {
77+
log(logger::error, format, arguments);
78+
}
79+
80+
private void log(BiConsumer<String, Object[]> log, String format, Object[] arguments) {
81+
if (includeCorrelationIdInLogs) {
82+
log.accept("[{}] " + format, addCorrelationIdToArguments(arguments));
83+
return;
84+
}
85+
log.accept(format, arguments);
86+
}
87+
88+
private Object[] addCorrelationIdToArguments(Object[] arguments) {
89+
final Object[] newArguments = new Object[arguments.length + 1];
90+
newArguments[0] = CorrelationId.get();
91+
92+
System.arraycopy(arguments, 0, newArguments, 1, arguments.length);
93+
94+
return newArguments;
95+
}
96+
97+
@FunctionalInterface
98+
public interface LoggerConsumer {
99+
void accept(org.slf4j.Logger log, String format, Object... arguments);
100+
}
101+
}

src/main/java/com/spt/development/logging/spring/JmsListenerLogger.java

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package com.spt.development.logging.spring;
22

3+
import com.spt.development.logging.spring.invocation.LoggedInvocation;
34
import org.aspectj.lang.ProceedingJoinPoint;
45
import org.aspectj.lang.annotation.Around;
56
import org.aspectj.lang.annotation.Aspect;
@@ -55,10 +56,10 @@ public Object log(final ProceedingJoinPoint point) throws Throwable {
5556
}
5657

5758
@Override
58-
Object proceed(ProceedingJoinPoint point, Logger log) throws Throwable {
59-
final Object result = point.proceed();
59+
Object proceed(LoggedInvocation invocation, Logger log) throws Throwable {
60+
final Object result = invocation.proceed();
6061

61-
info(log, "{}.{} - complete", point.getTarget().getClass().getSimpleName(), point.getSignature().getName());
62+
info(log, "{}.{} - complete", invocation.getDeclaringClass().getSimpleName(), invocation.getMethod().getName());
6263

6364
return result;
6465
}

0 commit comments

Comments
 (0)