How to Mask Sensitive Data in Spring Boot Logs with Logback
Learn how to protect personal data in Spring Boot 3.2.5 applications by customizing Logback's PatternLayout and appender to mask fields such as name, phone, password, and email, with step‑by‑step code examples, configuration snippets, and handling of object logging.
1. Introduction
In the era of data protection, handling and recording personal sensitive data requires careful masking to safeguard privacy. This article demonstrates how to use Logback to hide sensitive data in logs. Although logging is the last line of defense, it is not a complete solution.
Logback is a widely used Java logging framework that replaces Log4j, offering faster performance, richer configuration options, and flexible log file archiving.
We will mask user‑related sensitive data when logging application activity.
2. Practical Example
2.1 Environment Preparation
Define an entity class:
<code>public class User {
private Long id;
private String name;
private String address;
private String phone;
private String password;
private String email;
// getters, setters
}</code>We will mask the name , phone , password , and email fields.
Interface Definition
<code>@GetMapping("/login")
public User login() throws Exception {
// TODO
User user = new User(1L, "张三", "新疆", "1399999999", "123456789", "[email protected]");
logger.info("用户信息: {}", new ObjectMapper().writeValueAsString(user));
return user;
}</code>Normal log output:
2.2 Custom PatternLayout
Implement a custom MaskingPatternLayout that extends Logback's PatternLayout and masks configured patterns:
<code>public class MaskingPatternLayout extends PatternLayout {
private Pattern multilinePattern;
private List<String> maskPatterns = new ArrayList<>();
public void addMaskPattern(String maskPattern) {
maskPatterns.add(maskPattern);
multilinePattern = Pattern.compile(maskPatterns.stream().collect(Collectors.joining("|")), Pattern.MULTILINE);
}
@Override
public String doLayout(ILoggingEvent event) {
return maskMessage(super.doLayout(event));
}
private String maskMessage(String content) {
if (multilinePattern == null) {
return content;
}
StringBuilder sb = new StringBuilder(content);
Matcher matcher = multilinePattern.matcher(sb);
while (matcher.find()) {
IntStream.rangeClosed(1, matcher.groupCount()).forEach(group -> {
if (matcher.group(group) != null) {
IntStream.range(matcher.start(group), matcher.end(group)).forEach(i -> sb.setCharAt(i, '*'));
}
});
}
return sb.toString();
}
}</code>The PatternLayout.doLayout() method formats each log event; our override masks any content matching the configured patterns.
2.3 Logback Configuration
Add the custom layout and mask patterns in logback-spring.xml (or logback.xml ):
<code><appender name="mask" class="ch.qos.logback.core.ConsoleAppender">
<encoder class="ch.qos.logback.core.encoder.LayoutWrappingEncoder">
<layout class="com.pack.sensitive.log.MaskingPatternLayout">
<maskPattern>"name"\s*:\s*"(.*?)"</maskPattern>
<maskPattern>"phone"\s*:\s*"(.*?)"</maskPattern>
<maskPattern>"password"\s*:\s*"(.*?)"</maskPattern>
<maskPattern>([\w.-]+@[\w.-]+\.\w+)</maskPattern>
<pattern>%d{22:mm:ss} %-5level %logger Line:%-3L - %msg%n</pattern>
<charset>UTF-8</charset>
</layout>
</encoder>
</appender></code>After applying the configuration, the log output masks the sensitive fields:
Handling Direct Object Logging
When logging the object directly, additional patterns are required:
<code><maskPattern>name\s*=\s*(.*?),</maskPattern>
<maskPattern>password\s*=\s*(.*?),</maskPattern></code>After adding these patterns, the logs are correctly masked:
This demonstrates how to effectively mask sensitive information in Spring Boot logs using a custom Logback layout and appropriate configuration.
Spring Full-Stack Practical Cases
Full-stack Java development with Vue 2/3 front-end suite; hands-on examples and source code analysis for Spring, Spring Boot 2/3, and Spring Cloud.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.