Skip to content

Commit c0b19e6

Browse files
committed
INT-3977: Improve LoggingHandler for JavaConfig
JIRA: https://jira.spring.io/browse/INT-3977 * Add `Level` ctor * Add `setLogExpression(Expression)` and `setLogExpressionString(String)` * Deprecate existing `setExpression(String)` in favor of those new * Some refactor for redundant code around `evaluationContext` * Fix tests according a new `LoggingHandler` logic * Add JavaConfig sample to the Reference Manual
1 parent dee5c91 commit c0b19e6

File tree

4 files changed

+108
-17
lines changed

4 files changed

+108
-17
lines changed

spring-integration-core/src/main/java/org/springframework/integration/config/xml/LoggingChannelAdapterParser.java

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2014 the original author or authors.
2+
* Copyright 2002-2016 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -28,6 +28,8 @@
2828
* Parser for the 'logging-channel-adapter' element.
2929
*
3030
* @author Mark Fisher
31+
* @author Artem Bilan
32+
*
3133
* @since 1.0.1
3234
*/
3335
public class LoggingChannelAdapterParser extends AbstractOutboundChannelAdapterParser {
@@ -47,7 +49,7 @@ protected AbstractBeanDefinition parseConsumer(Element element, ParserContext pa
4749
builder.addPropertyValue("shouldLogFullMessage", logFullMessage);
4850
}
4951
IntegrationNamespaceUtils.setValueIfAttributeDefined(builder, element, "logger-name");
50-
IntegrationNamespaceUtils.setValueIfAttributeDefined(builder, element, "expression");
52+
IntegrationNamespaceUtils.setValueIfAttributeDefined(builder, element, "expression", "logExpressionString");
5153
return builder.getBeanDefinition();
5254
}
5355

spring-integration-core/src/main/java/org/springframework/integration/handler/LoggingHandler.java

Lines changed: 51 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@
3838
*
3939
* @author Mark Fisher
4040
* @author Gary Russell
41+
* @author Artem Bilan
4142
* @since 1.0.1
4243
*/
4344
public class LoggingHandler extends AbstractMessageHandler {
@@ -68,9 +69,10 @@ public enum Level {
6869
* The valid levels are: FATAL, ERROR, WARN, INFO, DEBUG, or TRACE
6970
* </p>
7071
* @param level The level.
72+
* @see LoggingHandler(Level)
7173
*/
7274
public LoggingHandler(String level) {
73-
Assert.notNull(level, "'level' cannot be null");
75+
Assert.hasText(level, "'level' cannot be empty");
7476
try {
7577
this.level = Level.valueOf(level.toUpperCase());
7678
}
@@ -79,14 +81,50 @@ public LoggingHandler(String level) {
7981
+ "'. The (case-insensitive) supported values are: "
8082
+ StringUtils.arrayToCommaDelimitedString(Level.values()));
8183
}
82-
this.evaluationContext = ExpressionUtils.createStandardEvaluationContext();
83-
this.expression = EXPRESSION_PARSER.parseExpression("payload");
8484
}
8585

86+
/**
87+
* Create a {@link LoggingHandler} with the given log {@link Level}.
88+
* @param level the {@link Level} to use.
89+
* @since 4.3
90+
*/
91+
public LoggingHandler(Level level) {
92+
Assert.notNull(level, "'level' cannot be null");
93+
this.level = level;
94+
}
95+
96+
/**
97+
* Set a SpEL expression string to use.
98+
* @param expressionString the SpEL expression string to use.
99+
* @deprecated in favor of {@link #setLogExpressionString(String)}
100+
*/
101+
@Deprecated
86102
public void setExpression(String expressionString) {
87-
Assert.isTrue(!(this.shouldLogFullMessageSet), "Cannot set both 'expression' AND 'shouldLogFullMessage' properties");
103+
setLogExpressionString(expressionString);
104+
}
105+
106+
/**
107+
* Set a SpEL expression string to use.
108+
* @param expressionString the SpEL expression string to use.
109+
* @since 4.3
110+
* @see #setLogExpression(Expression)
111+
*/
112+
public void setLogExpressionString(String expressionString) {
113+
Assert.hasText(expressionString, "'expressionString' must not be empty");
114+
setLogExpression(EXPRESSION_PARSER.parseExpression(expressionString));
115+
}
116+
117+
/**
118+
* Set an {@link Expression} to evaluate a log entry at runtime against the request {@link Message}.
119+
* @param expression the {@link Expression} to use.
120+
* @since 4.3
121+
* @see #setLogExpressionString(String)
122+
*/
123+
public void setLogExpression(Expression expression) {
124+
Assert.isTrue(!(this.shouldLogFullMessageSet),
125+
"Cannot set both 'expression' AND 'shouldLogFullMessage' properties");
88126
this.expressionSet = true;
89-
this.expression = EXPRESSION_PARSER.parseExpression(expressionString);
127+
this.expression = expression;
90128
}
91129

92130
/**
@@ -97,8 +135,7 @@ public Level getLevel() {
97135
}
98136

99137
/**
100-
* Set the logging {@link Level}.
101-
*
138+
* Set the logging {@link Level} to change the behavior at runtime.
102139
* @param level the level.
103140
*/
104141
public void setLevel(Level level) {
@@ -114,14 +151,14 @@ public void setLoggerName(String loggerName) {
114151
/**
115152
* Specify whether to log the full Message. Otherwise, only the payload will be logged. This value is
116153
* <code>false</code> by default.
117-
*
118154
* @param shouldLogFullMessage true if the complete message should be logged.
119155
*/
120156
public void setShouldLogFullMessage(boolean shouldLogFullMessage) {
121157
Assert.isTrue(!(this.expressionSet), "Cannot set both 'expression' AND 'shouldLogFullMessage' properties");
122158
this.shouldLogFullMessageSet = true;
123-
this.expression = (shouldLogFullMessage) ? EXPRESSION_PARSER.parseExpression("#root") : EXPRESSION_PARSER
124-
.parseExpression("payload");
159+
this.expression = (shouldLogFullMessage)
160+
? EXPRESSION_PARSER.parseExpression("#root")
161+
: EXPRESSION_PARSER.parseExpression("payload");
125162
}
126163

127164
@Override
@@ -132,7 +169,10 @@ public String getComponentType() {
132169
@Override
133170
protected void onInit() throws Exception {
134171
super.onInit();
135-
this.evaluationContext = ExpressionUtils.createStandardEvaluationContext(this.getBeanFactory());
172+
this.evaluationContext = ExpressionUtils.createStandardEvaluationContext(getBeanFactory());
173+
if (this.expression == null) {
174+
this.expression = EXPRESSION_PARSER.parseExpression("payload");
175+
}
136176
}
137177

138178
@Override

spring-integration-core/src/test/java/org/springframework/integration/handler/LoggingHandlerTests.java

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2014 the original author or authors.
2+
* Copyright 2002-2016 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -18,6 +18,7 @@
1818

1919
import static org.junit.Assert.assertEquals;
2020
import static org.junit.Assert.fail;
21+
import static org.mockito.Mockito.mock;
2122
import static org.mockito.Mockito.never;
2223
import static org.mockito.Mockito.spy;
2324
import static org.mockito.Mockito.times;
@@ -29,6 +30,7 @@
2930
import org.junit.runner.RunWith;
3031
import org.mockito.Mockito;
3132
import org.springframework.beans.DirectFieldAccessor;
33+
import org.springframework.beans.factory.BeanFactory;
3234
import org.springframework.beans.factory.annotation.Autowired;
3335
import org.springframework.expression.EvaluationContext;
3436
import org.springframework.expression.Expression;
@@ -61,7 +63,7 @@ public void logWithExpression() {
6163
@Test
6264
public void assertMutuallyExclusive() {
6365
LoggingHandler loggingHandler = new LoggingHandler("INFO");
64-
loggingHandler.setExpression("'foo'");
66+
loggingHandler.setLogExpressionString("'foo'");
6567
try {
6668
loggingHandler.setShouldLogFullMessage(true);
6769
fail("Expected IllegalArgumentException");
@@ -73,7 +75,7 @@ public void assertMutuallyExclusive() {
7375
loggingHandler = new LoggingHandler("INFO");
7476
loggingHandler.setShouldLogFullMessage(true);
7577
try {
76-
loggingHandler.setExpression("'foo'");
78+
loggingHandler.setLogExpressionString("'foo'");
7779
fail("Expected IllegalArgumentException");
7880
}
7981
catch (IllegalArgumentException e) {
@@ -84,6 +86,9 @@ public void assertMutuallyExclusive() {
8486
@Test
8587
public void testDontEvaluateIfNotEnabled() {
8688
LoggingHandler loggingHandler = new LoggingHandler("INFO");
89+
loggingHandler.setBeanFactory(mock(BeanFactory.class));
90+
loggingHandler.afterPropertiesSet();
91+
8792
DirectFieldAccessor accessor = new DirectFieldAccessor(loggingHandler);
8893
Log log = (Log) accessor.getPropertyValue("messageLogger");
8994
log = spy(log);
@@ -102,7 +107,10 @@ public void testDontEvaluateIfNotEnabled() {
102107

103108
@Test
104109
public void testChangeLevel() {
105-
LoggingHandler loggingHandler = new LoggingHandler("INFO");
110+
LoggingHandler loggingHandler = new LoggingHandler(Level.INFO);
111+
loggingHandler.setBeanFactory(mock(BeanFactory.class));
112+
loggingHandler.afterPropertiesSet();
113+
106114
DirectFieldAccessor accessor = new DirectFieldAccessor(loggingHandler);
107115
Log log = (Log) accessor.getPropertyValue("messageLogger");
108116
log = spy(log);

src/reference/asciidoc/logging-adapter.adoc

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,3 +40,44 @@ This attribute cannot be specified if `expression` is specified.
4040
<5> Specifies the _name_ of the logger (known as `category` in `log4j`) used for log messages created by this adapter.
4141
This enables setting the log name (in the logging subsystem) for individual adapters.
4242
By default, all adapters will log under the name `org.springframework.integration.handler.LoggingHandler`.
43+
44+
==== Configuring with Java Configuration
45+
46+
The following Spring Boot application provides an example of configuring the `LoggingHandler` using Java configuration:
47+
[source, java]
48+
----
49+
@SpringBootApplication
50+
public class LoggingJavaApplication {
51+
52+
public static void main(String[] args) {
53+
ConfigurableApplicationContext context =
54+
new SpringApplicationBuilder(LoggingJavaApplication.class)
55+
.web(false)
56+
.run(args);
57+
MyGateway gateway = context.getBean(MyGateway.class);
58+
gateway.sendToLogger("foo");
59+
}
60+
61+
@Bean
62+
public MessageChannel logInputChannel() {
63+
return new DirectChannel();
64+
}
65+
66+
@Bean
67+
@ServiceActivator(inputChannel = "logChannel")
68+
public LoggingHandler logging() {
69+
LoggingHandler adapter = new LoggingHandler(LoggingHandler.Level.DEBUG);
70+
adapter.setLoggerName("TEST_LOGGER");
71+
adapter.setLogExpressionString("headers.id + ': ' + payload");
72+
return adapter;
73+
}
74+
75+
@MessagingGateway(defaultRequestChannel = "logChannel")
76+
public interface MyGateway {
77+
78+
void sendToLogger(String data);
79+
80+
}
81+
82+
}
83+
----

0 commit comments

Comments
 (0)