Skip to content

Commit e13a899

Browse files
authored
Merge pull request #611 from JNU-econovation/feat/#605
[BE/FEAT] 운영 로그 masking 처리하기
2 parents b28b5b7 + 6bfd309 commit e13a899

File tree

5 files changed

+110
-51
lines changed

5 files changed

+110
-51
lines changed
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
package com.gaebaljip.exceed.common.log;
2+
3+
import java.util.ArrayList;
4+
import java.util.List;
5+
import java.util.regex.Matcher;
6+
import java.util.regex.Pattern;
7+
import java.util.stream.Collectors;
8+
import java.util.stream.IntStream;
9+
10+
import ch.qos.logback.classic.PatternLayout;
11+
import ch.qos.logback.classic.spi.ILoggingEvent;
12+
13+
public class MaskingPatternLayout extends PatternLayout {
14+
15+
private Pattern multilinePattern;
16+
private List<String> maskPatterns = new ArrayList<>();
17+
18+
public void addMaskPattern(String maskPattern) {
19+
maskPatterns.add(maskPattern);
20+
multilinePattern =
21+
Pattern.compile(
22+
maskPatterns.stream().collect(Collectors.joining("|")), Pattern.MULTILINE);
23+
}
24+
25+
@Override
26+
public String doLayout(ILoggingEvent event) {
27+
return maskMessage(super.doLayout(event));
28+
}
29+
30+
private String maskMessage(String message) {
31+
if (multilinePattern == null) {
32+
return message;
33+
}
34+
StringBuilder sb = new StringBuilder(message);
35+
Matcher matcher = multilinePattern.matcher(sb);
36+
while (matcher.find()) {
37+
IntStream.rangeClosed(1, matcher.groupCount())
38+
.forEach(
39+
group -> {
40+
if (matcher.group(group) != null) {
41+
IntStream.range(matcher.start(group), matcher.end(group))
42+
.forEach(i -> sb.setCharAt(i, '*'));
43+
}
44+
});
45+
}
46+
return sb.toString();
47+
}
48+
}

src/main/resources/application-local.yml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@ spring:
1818
hibernate:
1919
show_sql : true
2020
format_sql: true
21-
use_sql_comments: true
2221

2322

2423
cloud:

src/main/resources/application-prod.yml

Lines changed: 1 addition & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -14,11 +14,7 @@ spring:
1414
physical-strategy: org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl
1515
dialect: org.hibernate.dialect.MariaDBDialect
1616
ddl-auto: validate
17-
properties:
18-
hibernate:
19-
show_sql: true
20-
format_sql: true
21-
use_sql_comments: true
17+
2218
cloud:
2319
aws:
2420
credentials:
@@ -84,14 +80,6 @@ server:
8480
mbeanregistry:
8581
enabled: true
8682

87-
logging:
88-
level:
89-
org:
90-
hibernate:
91-
type:
92-
descriptor:
93-
sql: info
94-
9583
org:
9684
quartz:
9785
scheduler:

src/main/resources/logback-spring.xml

Lines changed: 31 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2,25 +2,48 @@
22
<configuration>
33
<conversionRule conversionWord="clr" converterClass="org.springframework.boot.logging.logback.ColorConverter" />
44

5-
<property name="CONSOLE_LOG_PATTERN" value="%d{yyyy-MM-dd HH:mm:ss.SSS} [%X{REQUEST_ID}] [%thread] %clr(%5level) %cyan(%logger) - %msg%n" />
6-
<property name="FILE_LOG_PATTERN" value="%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %5level %logger - %msg%n" />
5+
<property name="CONSOLE_LOG_PATTERN" value="%d{yyyy-MM-dd HH:mm:ss.SSS} %clr([%X{REQUEST_ID}]){magenta} [%thread] %clr(%5level) %clr(%20logger){cyan} - %msg%n" />
6+
<property name="FILE_LOG_PATTERN" value="%d{yyyy-MM-dd HH:mm:ss.SSS} [%X{REQUEST_ID}] [%thread] %5level %20logger - %msg%n" />
77

88
<appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
9-
<encoder>
10-
<pattern>${CONSOLE_LOG_PATTERN}</pattern>
9+
<encoder class="ch.qos.logback.core.encoder.LayoutWrappingEncoder">
10+
<layout class="com.gaebaljip.exceed.common.log.MaskingPatternLayout">
11+
<maskPattern>\"(?i).*email.*"\s*:\s*\"(.*?)\"</maskPattern>
12+
<maskPattern>\"(?i).*password.*"\s*:\s*\"(.*?)\"</maskPattern>
13+
<maskPattern>\"(?i).*height.*"\s*:\s*(\d+)</maskPattern>
14+
<maskPattern>\"(?i).*weight.*"\s*:\s*(\d+)</maskPattern>
15+
<maskPattern>\"(?i).*targetWeight.*"\s*:\s*(\d+)</maskPattern>
16+
<maskPattern>\"(?i).*age.*"\s*:\s*(\d+)</maskPattern>
17+
<maskPattern>\"(?i).*etc.*"\s*:\s*\"(.*?)\"</maskPattern>
18+
<maskPattern>\"(?i).*activity.*"\s*:\s*\"(.*?)\"</maskPattern>
19+
<pattern>${CONSOLE_LOG_PATTERN}</pattern>
20+
</layout>
1121
</encoder>
1222
</appender>
23+
1324
<appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
14-
<encoder>
15-
<pattern>${FILE_LOG_PATTERN}</pattern>
25+
<encoder class="ch.qos.logback.core.encoder.LayoutWrappingEncoder">
26+
<layout class="com.gaebaljip.exceed.common.log.MaskingPatternLayout">
27+
<maskPattern>\"(?i).*email.*"\s*:\s*\"(.*?)\"</maskPattern>
28+
<maskPattern>\"(?i).*password.*"\s*:\s*\"(.*?)\"</maskPattern>
29+
<maskPattern>\"(?i).*height.*"\s*:\s*(\d+)</maskPattern>
30+
<maskPattern>\"(?i).*weight.*"\s*:\s*(\d+)</maskPattern>
31+
<maskPattern>\"(?i).*targetWeight.*"\s*:\s*(\d+)</maskPattern>
32+
<maskPattern>\"(?i).*age.*"\s*:\s*(\d+)</maskPattern>
33+
<maskPattern>\"(?i).*etc.*"\s*:\s*\"(.*?)\"</maskPattern>
34+
<maskPattern>\"(?i).*activity.*"\s*:\s*\"(.*?)\"</maskPattern>
35+
<pattern>${FILE_LOG_PATTERN}</pattern>
36+
</layout>
1637
</encoder>
1738
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
1839
<fileNamePattern>./log/%d{yyyy-MM-dd}.%i.log</fileNamePattern>
19-
<maxFileSize>100MB</maxFileSize>
40+
<maxFileSize>10MB</maxFileSize>
2041
<maxHistory>30</maxHistory>
42+
<totalSizeCap>100MB</totalSizeCap>
2143
</rollingPolicy>
2244
</appender>
2345

46+
2447
<springProfile name="local">
2548
<logger name="com.gaebaljip.exceed" level="DEBUG" />
2649
<root level="INFO">
@@ -39,4 +62,4 @@
3962
<appender-ref ref="FILE" />
4063
</root>
4164
</springProfile>
42-
</configuration>
65+
</configuration>

src/test/java/com/gaebaljip/exceed/common/SchemaValidationTest.java

Lines changed: 30 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,36 +1,37 @@
1-
//package com.gaebaljip.exceed.common;
2-
//
3-
//import java.io.IOException;
4-
//import java.nio.file.Files;
5-
//import java.nio.file.Paths;
6-
//import java.sql.Connection;
7-
//import java.sql.SQLException;
8-
//import java.sql.Statement;
9-
//
10-
//import org.junit.jupiter.api.AfterAll;
11-
//import org.junit.jupiter.api.BeforeAll;
12-
//import org.junit.jupiter.api.Test;
13-
//import org.springframework.boot.test.autoconfigure.jdbc.AutoConfigureTestDatabase;
14-
//import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest;
15-
//import org.springframework.context.annotation.Import;
16-
//import org.springframework.test.context.DynamicPropertyRegistry;
17-
//import org.springframework.test.context.DynamicPropertySource;
18-
//import org.testcontainers.containers.GenericContainer;
19-
//import org.testcontainers.containers.MariaDBContainer;
20-
//import org.testcontainers.utility.DockerImageName;
21-
//
22-
//import com.gaebaljip.exceed.config.QueryDslConfig;
23-
//
24-
//@DataJpaTest(properties = "spring.jpa.hibernate.ddl-auto=validate")
25-
//@AutoConfigureTestDatabase(replace = AutoConfigureTestDatabase.Replace.NONE)
26-
//@Import(QueryDslConfig.class)
27-
//public class SchemaValidationTest {
1+
// package com.gaebaljip.exceed.common;
2+
//
3+
// import java.io.IOException;
4+
// import java.nio.file.Files;
5+
// import java.nio.file.Paths;
6+
// import java.sql.Connection;
7+
// import java.sql.SQLException;
8+
// import java.sql.Statement;
9+
//
10+
// import org.junit.jupiter.api.AfterAll;
11+
// import org.junit.jupiter.api.BeforeAll;
12+
// import org.junit.jupiter.api.Test;
13+
// import org.springframework.boot.test.autoconfigure.jdbc.AutoConfigureTestDatabase;
14+
// import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest;
15+
// import org.springframework.context.annotation.Import;
16+
// import org.springframework.test.context.DynamicPropertyRegistry;
17+
// import org.springframework.test.context.DynamicPropertySource;
18+
// import org.testcontainers.containers.GenericContainer;
19+
// import org.testcontainers.containers.MariaDBContainer;
20+
// import org.testcontainers.utility.DockerImageName;
21+
//
22+
// import com.gaebaljip.exceed.config.QueryDslConfig;
23+
//
24+
// @DataJpaTest(properties = "spring.jpa.hibernate.ddl-auto=validate")
25+
// @AutoConfigureTestDatabase(replace = AutoConfigureTestDatabase.Replace.NONE)
26+
// @Import(QueryDslConfig.class)
27+
// public class SchemaValidationTest {
2828
//
2929
// private static MariaDBContainer<?> schemaValidationMariaDB;
3030
// private static GenericContainer<?> redisContainer;
3131
//
3232
// private static String getAbsolutePath() {
33-
// String relativePath = "resources/gaebaljip-develop-environment/mariadb-init/01_schema.sql";
33+
// String relativePath =
34+
// "resources/gaebaljip-develop-environment/mariadb-init/01_schema.sql";
3435
// String currentDir = System.getProperty("user.dir");
3536
// return Paths.get(currentDir, relativePath).normalize().toAbsolutePath().toString();
3637
// }
@@ -92,4 +93,4 @@
9293
//
9394
// @Test
9495
// public void testSchemaValidity() {}
95-
//}
96+
// }

0 commit comments

Comments
 (0)