Skip to content

Commit 0737bac

Browse files
authored
PR for logbook springboot article (#16783)
* - code for logbook article * -- correcting path in junit test * changing log file path * Create sample.xml * Create logback-extension.log * -- changed log path here * added cleanup function * -- Added code for sink examples -- composite sink and logstash sink example * -- adding chunksink sample, unit tests for the same are pending * - added configuration example for all the sinks * - added configuration example for all the sinks * - added configuration example for all the sinks * -- correcting contenttype configuration -- added version properties in pom.cml * -- removing delete log file method * deleted log file and sample.xml
1 parent dc663c8 commit 0737bac

File tree

7 files changed

+249
-3
lines changed

7 files changed

+249
-3
lines changed

spring-boot-modules/spring-boot-logging-logback/pom.xml

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@
77
<name>spring-boot-logging-logback</name>
88
<packaging>jar</packaging>
99
<description>Demo project for Spring Boot Logging with Logback</description>
10-
1110
<parent>
1211
<groupId>com.baeldung.spring-boot-modules</groupId>
1312
<artifactId>spring-boot-modules</artifactId>
@@ -23,6 +22,21 @@
2322
<groupId>org.springframework.boot</groupId>
2423
<artifactId>spring-boot-starter-test</artifactId>
2524
</dependency>
25+
<dependency>
26+
<groupId>org.zalando</groupId>
27+
<artifactId>logbook-spring-boot-starter</artifactId>
28+
<version>${logbook-spring-boot-starter.version}</version>
29+
</dependency>
30+
<dependency>
31+
<groupId>net.logstash.logback</groupId>
32+
<artifactId>logstash-logback-encoder</artifactId>
33+
<version>${logstash-logback-encoder.version}</version>
34+
</dependency>
35+
<dependency>
36+
<groupId>org.zalando</groupId>
37+
<artifactId>logbook-logstash</artifactId>
38+
<version>${logbook-logstash.version}</version>
39+
</dependency>
2640
</dependencies>
2741

2842
<build>
@@ -34,4 +48,9 @@
3448
</plugins>
3549
</build>
3650

51+
<properties>
52+
<logbook-spring-boot-starter.version>3.9.0</logbook-spring-boot-starter.version>
53+
<logstash-logback-encoder.version>7.4</logstash-logback-encoder.version>
54+
<logbook-logstash.version>3.9.0</logbook-logstash.version>
55+
</properties>
3756
</project>
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
package com.baeldung.controller;
2+
3+
import org.springframework.web.bind.annotation.GetMapping;
4+
import org.springframework.web.bind.annotation.RequestMapping;
5+
import org.springframework.web.bind.annotation.RequestParam;
6+
import org.springframework.web.bind.annotation.RestController;
7+
8+
@RestController
9+
@RequestMapping("/api/")
10+
public class SampleController {
11+
12+
@RequestMapping("hello")
13+
public String sayHello(@RequestParam(value = "name", defaultValue = "World") String name) {
14+
return String.format("Hello, %s!", name);
15+
}
16+
17+
@GetMapping("welcome")
18+
public String getStudent(@RequestParam(value = "name", defaultValue = "World") String name) {
19+
return String.format("Welcome, %s!", name);
20+
}
21+
}

spring-boot-modules/spring-boot-logging-logback/src/main/java/com/baeldung/extensions/SpringBootLogbackExtensionsApplication.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,10 @@
44
import org.slf4j.LoggerFactory;
55
import org.springframework.boot.SpringApplication;
66
import org.springframework.boot.autoconfigure.SpringBootApplication;
7+
import org.springframework.context.annotation.ComponentScan;
78

89
@SpringBootApplication
10+
@ComponentScan(basePackages = { "com.baeldung.controller", "com.baeldung.logging", "com.baeldung.logbookconfig" })
911
public class SpringBootLogbackExtensionsApplication {
1012

1113
private static final Logger logger = LoggerFactory.getLogger(SpringBootLogbackExtensionsApplication.class);
Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
package com.baeldung.logbookconfig;
2+
3+
import java.util.Arrays;
4+
5+
import org.slf4j.event.Level;
6+
import org.springframework.context.annotation.Bean;
7+
import org.springframework.context.annotation.Configuration;
8+
import org.zalando.logbook.HttpLogFormatter;
9+
import org.zalando.logbook.Logbook;
10+
import org.zalando.logbook.core.ChunkingSink;
11+
import org.zalando.logbook.core.CommonsLogFormatSink;
12+
import org.zalando.logbook.core.CompositeSink;
13+
import org.zalando.logbook.core.Conditions;
14+
import org.zalando.logbook.core.DefaultHttpLogFormatter;
15+
import org.zalando.logbook.core.DefaultHttpLogWriter;
16+
import org.zalando.logbook.core.DefaultSink;
17+
import org.zalando.logbook.core.ExtendedLogFormatSink;
18+
import org.zalando.logbook.json.JsonHttpLogFormatter;
19+
import org.zalando.logbook.logstash.LogstashLogbackSink;
20+
21+
@Configuration
22+
public class LogBookConfig {
23+
24+
@Bean
25+
public Logbook logbook() {
26+
Logbook logbook = Logbook.builder()
27+
.condition(Conditions.exclude(Conditions.requestTo("/api/welcome"), Conditions.contentType(
28+
"application/octet-stream"), Conditions.header("X-Secret", "true")))
29+
.sink(new DefaultSink(new DefaultHttpLogFormatter(), new DefaultHttpLogWriter()))
30+
.build();
31+
return logbook;
32+
}
33+
34+
//@Bean
35+
public Logbook chunkSink() {
36+
Logbook logbook = Logbook.builder()
37+
.sink(new ChunkingSink(new CommonsLogFormatSink(new DefaultHttpLogWriter()), 1000))
38+
.build();
39+
return logbook;
40+
}
41+
42+
//@Bean
43+
public Logbook compositesink() {
44+
CompositeSink comsink = new CompositeSink(Arrays.asList(new CommonsLogFormatSink(new DefaultHttpLogWriter()), new ExtendedLogFormatSink(
45+
new DefaultHttpLogWriter())));
46+
Logbook logbook = Logbook.builder()
47+
.sink(comsink)
48+
.build();
49+
return logbook;
50+
}
51+
52+
// to run logstash example set spring.profiles.active=logbooklogstash in application.properties and enable following bean disabling all others
53+
//@Bean
54+
public Logbook logstashsink() {
55+
HttpLogFormatter formatter = new JsonHttpLogFormatter();
56+
LogstashLogbackSink logstashsink = new LogstashLogbackSink(formatter, Level.INFO);
57+
58+
Logbook logbook = Logbook.builder()
59+
.sink(logstashsink)
60+
.build();
61+
return logbook;
62+
}
63+
64+
//@Bean
65+
public Logbook commonLogFormat() {
66+
Logbook logbook = Logbook.builder()
67+
.sink(new CommonsLogFormatSink(new DefaultHttpLogWriter()))
68+
.build();
69+
return logbook;
70+
}
71+
72+
//@Bean
73+
public Logbook extendedLogFormat() {
74+
Logbook logbook = Logbook.builder()
75+
.sink(new ExtendedLogFormatSink(new DefaultHttpLogWriter()))
76+
.build();
77+
return logbook;
78+
}
79+
}
Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1,15 @@
1-
spring.application.name=logback-extension
1+
spring.application.name=logback-extension
2+
logging.config=./src/main/resources/logback-spring.xml
3+
4+
spring.profiles.active=logbook
5+
server.port=8083
6+
7+
# Enable Logbook
8+
logbook.filter.enabled=true
9+
# Log incoming requests and responses
10+
logbook.format.style=http
11+
# Include request and response bodies
12+
logbook.include.body=true
13+
# this is needed to display http requests
14+
logging.level.org.zalando.logbook.Logbook=TRACE
15+

spring-boot-modules/spring-boot-logging-logback/src/main/resources/logback-spring.xml

Lines changed: 45 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
<?xml version="1.0" encoding="UTF-8"?>
22
<configuration>
33

4+
<property name="LOG_PATH" value="${LOG_PATH:-./src/main/resources/logs}"/>
45
<property name="LOGS" value="./logs" />
56
<springProperty scope="context" name="application.name" source="spring.application.name" />
67

@@ -24,10 +25,53 @@
2425
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
2526
<fileNamePattern>${LOGS}/archived/${application.name}-%d{yyyy-MM-dd}.log</fileNamePattern>
2627
</rollingPolicy>
27-
</appender>
28+
</appender>
29+
2830
<root level="info">
2931
<appender-ref ref="RollingFile" />
3032
</root>
3133
</springProfile>
34+
35+
<springProfile name="logbook">
36+
37+
<appender name="RollingFile" class="ch.qos.logback.core.rolling.RollingFileAppender">
38+
<file>${LOG_PATH}/${application.name}.log</file>
39+
<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
40+
<Pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</Pattern>
41+
</encoder>
42+
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
43+
<fileNamePattern>${LOG_PATH}/archived/${application.name}-%d{yyyy-MM-dd}.log</fileNamePattern>
44+
</rollingPolicy>
45+
</appender>
46+
47+
<logger name="org.zalando.logbook" level="INFO" additivity="false">
48+
<appender-ref ref="RollingFile"/>
49+
</logger>
50+
51+
<root level="INFO">
52+
<appender-ref ref="RollingFile"/>
53+
</root>
54+
55+
</springProfile>
56+
57+
<springProfile name="logbooklogstash">
58+
59+
<appender name="RollingFile" class="ch.qos.logback.core.rolling.RollingFileAppender">
60+
<file>${LOG_PATH}/${application.name}.log</file>
61+
<encoder class="net.logstash.logback.encoder.LogstashEncoder"/>
62+
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
63+
<fileNamePattern>${LOG_PATH}/archived/${application.name}-%d{yyyy-MM-dd}.log</fileNamePattern>
64+
</rollingPolicy>
65+
</appender>
66+
67+
<logger name="org.zalando.logbook" level="INFO" additivity="false">
68+
<appender-ref ref="RollingFile"/>
69+
</logger>
70+
71+
<root level="INFO">
72+
<appender-ref ref="RollingFile"/>
73+
</root>
74+
75+
</springProfile>
3276

3377
</configuration>
Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
package com.baeldung.logbook;
2+
3+
import static org.junit.jupiter.api.Assertions.assertFalse;
4+
import static org.junit.jupiter.api.Assertions.assertTrue;
5+
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
6+
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content;
7+
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
8+
9+
import java.io.IOException;
10+
import java.nio.file.Files;
11+
import java.nio.file.Path;
12+
import java.nio.file.Paths;
13+
import java.util.List;
14+
15+
import org.junit.BeforeClass;
16+
import org.junit.Test;
17+
import org.junit.runner.RunWith;
18+
import org.springframework.beans.factory.annotation.Autowired;
19+
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
20+
import org.springframework.boot.test.context.SpringBootTest;
21+
import org.springframework.test.context.junit4.SpringRunner;
22+
import org.springframework.test.web.servlet.MockMvc;
23+
24+
import com.baeldung.extensions.SpringBootLogbackExtensionsApplication;
25+
26+
@RunWith(SpringRunner.class)
27+
@SpringBootTest(classes = SpringBootLogbackExtensionsApplication.class)
28+
@AutoConfigureMockMvc
29+
public class LogBookUnitTest {
30+
31+
private static String logFilePath;
32+
33+
@Autowired
34+
private MockMvc mockMvc;
35+
36+
@Test
37+
public void whenHttpRequestCalled_thenRequestDetailsLogged() throws Exception {
38+
mockMvc.perform(get("/api/hello"))
39+
.andExpect(status().isOk())
40+
.andExpect(content().string("Hello, World!"));
41+
42+
List<String> logLines = Files.readAllLines(Paths.get(logFilePath));
43+
boolean isLogged = logLines.stream()
44+
.anyMatch(line -> line.contains("http://localhost/api/hello"));
45+
assertTrue(isLogged, "Log file should contain log message containing api request details");
46+
}
47+
48+
@Test
49+
public void whenExcludedHttpRequestCalled_thenRequestDetailsNotLogged() throws Exception {
50+
mockMvc.perform(get("/api/welcome"))
51+
.andExpect(status().isOk())
52+
.andExpect(content().string("Welcome, World!"));
53+
54+
List<String> logLines = Files.readAllLines(Paths.get(logFilePath));
55+
boolean isLogged = logLines.stream()
56+
.anyMatch(line -> line.contains("http://localhost/api/welcome"));
57+
assertFalse(isLogged, "Log file should not contain log message containing api request details");
58+
}
59+
60+
@BeforeClass
61+
public static void init() throws IOException {
62+
Path resourcesPath = Paths.get("src", "main", "resources");
63+
logFilePath = resourcesPath.resolve("logs/logback-extension.log")
64+
.toAbsolutePath()
65+
.toString();
66+
}
67+
}

0 commit comments

Comments
 (0)