ํ์ฌ Spring Batch๋ฅผ ํตํ ๊ฐ๋จํ ๋ฐฐ์น ํ๋ก๊ทธ๋จ์ ๋ง๋ค๊ณ ์์ต๋๋ค.
API๋ฅผ ํตํด ๋ฐ์ดํฐ๋ฅผ DB์ ์
๋ฐ์ดํธ๋ฅผ ํ๋ ์์
์ ์งํํ๋๋ฐ, ํ์ฌ ํ
์คํธ ๊ธฐ๊ฐ์ด๋ผ ํด๋น ํ๋ก๊ทธ๋จ์ด ์ ๋์ํ๋์ง์ ๋ํ ํ์ธ์ด ํ์ํ์ต๋๋ค. ํ์ฌ ํ์ฌ์์ ์ฌ์ฉํ๋ slf4j
๋ฅผ ์ฌ์ฉํ ๊น ๊ณ ๋ฏผํ์์ง๋ง, ์ ๋ง์ ์ฌ์ด๋ ํ๋ก์ ํธ๊ธฐ๋ ํ๊ณ , logback
์ ๋ํ ์ฑ๋ฅ์ด slf4j
๋ณด๋ค ์์๋ค๋ ๊ธ์ ๋ณด์์ต๋๋ค. ๊ณต๋ถํ ๊ฒธ logback
๋ฅผ ์ด์ฉํ์ฌ ๋ก๊ทธ๋ฅผ ์๊ธฐ๋ก ํ์ต๋๋ค.
๊ทธ๋์ Spring Boot์์ Logback์ ์ค์ ํ๋ ๋ฐฉ๋ฒ, ์ค์ ๋ก ์ ์ฉํ๋ฉด์ ๋ฐ์ํ์๋ ์ด์์ ๋ํด ๊ฐ๋ตํ๊ฒ ์์ ํ๋ ค ํฉ๋๋ค.
์ ์ ์ด ํ์ํ ๋ถ๋ถ์ ๋ํด์๋ ์๋ ์๋ ๋๊ธ ๋ถํ๋๋ฆฝ๋๋ค.
(Spring Boot์ ๋ํ ํฌ์คํ
์.. ์ธ์ ๊ฐ..)
์ฌ์ฉํ๋ ๊ธฐ์ ๋ฒ์
- Spring Batch 4.2 (Spring Boot 2.2)
- Logback 1.2.3
1. Logback ์ค์ ํ๊ธฐ
(์ ๊ฐ ์๊ธฐ๋ก๋) spring-boot-starter-batch
์ ์์กด์ฑ์ ๋ค์๊ณผ ๊ฐ์ต๋๋ค.
spring-boot-starter
ใด spring-boot-starter-batch
spring-boot-starter
๋ด์๋ ๊ธฐ๋ณธ์ ์ผ๋ก ์ฌ์ฉํ ์ ์๋๋ก ๋ก๊ทธ ์์คํ
(logback
, slf4j
๋ฑ)์ ์ ๊ณตํ๊ณ ์์ต๋๋ค.
(๊ทธ๋์ ํ์ฌ ํ์์ ํ๋ก์ ํธ์๋ logback-core-1.2.3.jar, logback-classic-1.2.3.jar๊ฐ depend๋์ด ์์ต๋๋ค.)
๋ง์ฝ logback์ ๋ค๋ฅธ ๋ฒ์ ์ ์ฌ์ฉํ๋ ค๊ฑฐ๋, ํน์ spring-boot-starter-batch
๋ด์ ํฌํจ์ด ๋์ด์์ง ์๋ค๋ฉด,pom.xml
์ ๋ค์ dependency๋ฅผ ์ ์ฉํ๋ฉด ๋ฉ๋๋ค.
(๋ฌผ๋ก <repository />
๋ก ์ค์ ํด๋ ๋ ํ์งํ ๋ฆฌ ์ฃผ์ ๋ด์ logback
์ด ์์ด์ผ ํฉ๋๋ค.)
...(์ค๋ต)
<dependencies>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
</dependency>
</dependencies>
...(ํ๋ต)
2. logback-spring.xml ์์ฑํ๊ธฐ
logback
๋ฅผ ์ฌ์ฉํ๊ธฐ ์ํด์๋, ๊ทธ์ ํด๋นํ๋ ์ค์ ํ์ผ์ ์์ฑํด์ผ ํฉ๋๋ค.${ํ๋ก์ ํธ๊ฒฝ๋ก}/src/main/resources
๊ฒฝ๋ก์ logback-spring.xml
ํ์ผ์ ๋ง๋ค์ด์ฃผ๋ฉด, ์ ํ๋ฆฌ์ผ์ด์
์ด ๊ตฌ๋ ๋ ๋ logback์์ ํด๋น ํ์ผ์ ์ฝ์ด์ต๋๋ค.
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<!-- ๋ก๊ทธ๊ฐ ์ ์ฅ๋ ๊ฒฝ๋ก -->
<property name="LOG_PATH" value="/log" />
<!-- ํ์ผ๋ก ๋ก๊ทธ๋ฅผ ์์ฑํ ๋ -->
<appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>log/ldata.log</file>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>log/ldata.%d{yyyy-MM-dd}.log</fileNamePattern>
<maxHistory>30</maxHistory>
</rollingPolicy>
<encoder>
<pattern>%date %level [%thread] %msg%n</pattern>
</encoder>
</appender>
<!-- ์ฝ์์์ ๋ก๊ทธ๋ฅผ ์์ฑํ ๋ -->
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<!-- <pattern>%msg%n</pattern> -->
<pattern>%date %level [%thread] %logger{10} [%file:%line] %msg%n</pattern>
</encoder>
</appender>
<!-- ํ๋ก๊ทธ๋จ์์ ์ ์ฉ๋ ๋ก๊ทธ ๋ ๋ฒจ -->
<root level="INFO">
<appender-ref ref="FILE" />
<appender-ref ref="STDOUT" />
</root>
</configuration>
<configuration/>
, <appender/>
์ ๊ด๋ จ๋ ์ค๋ช
์ ๊ณต์ ํํ์ด์ง์ ์ ๋์์๋ต๋๋ค. (์์ด๋ผ์ ๋ฌธ์ ..)
์์ ์์ฑ๋ logback-spring.xml
์ ๋ํ ํด์์ ๋ค์๊ณผ ๊ฐ์ต๋๋ค.
- ํ์ผ๋ก ๋ก๊ทธ๋ฅผ ์์ฑํ ๋
- file์ ์ด๋ฆ์
ldata.log
๋ก ์์ฑํ๋ค. - ์ค๋ ์ดํ, ํ๋ฃจ๊ฐ ์ง๋๊ฐ ๋๋ง๋ค ์ด๋ฆ์ ๋ค๋ฅด๊ฒ ์์ฑํ๋ค.
- ํ์ผ๋ช ์ ํจํด์ ๋ค์๊ณผ ๊ฐ์ด ์ง์ ํ๋ค : ldata.2019-11-15.log
- ์ด ํ์ผ๋ค์ ์ต๋ 30์ผ๊น์ง๋ง ๋ณด์ ํ๋ฉฐ, ์ดํ ์๋์ผ๋ก ์ญ์ ํ๋ค.
- file ๋ด์ ์ ํ์ง ๋ก๊ทธ๋ค์ ๋ค์๊ณผ ๊ฐ์ด ์์ฑํ๋ค : 2019-11-14 [INFO] step : [updateStep] executed in 529ms
- file์ ์ด๋ฆ์
- ์ฝ์์์ ๋ก๊ทธ๋ฅผ ๋ณด์ฌ์ค ๋
- console ๋ด์์ ๋ณด์ฌ์ค ๋ก๊ทธ๋ค์ ๋ค์๊ณผ ๊ฐ์ด ์์ฑํ๋ค : 2019-11-14 [INFO] [main] o.s.b.c.l.s.JobLauncher [JobLauncher.java:149] Job: [SimpleJob: [name=updateJob]] status: [COMPLETED] in 698ms
- ํ์ฌ ์ด ํ๋ก์ ํธ์ ๋ก๊ทธ ๋ ๋ฒจ์ INFO
3. logback ์ฌ์ฉํ๊ธฐ
์ด์ logback์ ๋ํ ์ค์ ๊น์ง ๋ง์ณค๋ค๋ฉด, ์ค์ ์ ํ๋ฆฌ์ผ์ด์
๋จ๊ณ์์ ๋ก๊ทธ๋ฅผ ์ฐธ์กฐํด์ผ ํฉ๋๋ค.
(ํด๋น ๋ถ๋ถ์ ๋ํ ์ค๋ช
์ด ํ๋ฆด ์ ์์ผ๋ฏ๋ก, ์ด ๊ธ์ ํ์ธํ์๋ ๋ถ์ด์๋ผ๋ฉด ์๋ ์๋ ํผ๋๋ฐฑ์ ๋ถํ๋๋ฆฝ๋๋ค...)
์ค์ ๋ก ์์ฑํ๊ณ ์๋ Application๋จ์์ ๋ค์๊ณผ ๊ฐ์ด ์ฝ๋๋ฅผ ์์ฑํฉ๋๋ค.
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@EnableBatchProcessing
@SpringBootApplication
public class Application {
private static final Logger logger = LoggerFactory.getLogger(Application.class);
public static void main (String[] args) {
logger.info("INFO...");
logger.error("ERROR...");
}
}
์ ์ฝ๋์ ๋ํ ์คํ ๊ฒฐ๊ณผ๋ฅผ ๊ฐ๋ตํ๊ฒ ์ ์๋ฉด ๋ค์๊ณผ ๊ฐ์ต๋๋ค.
2019-11-15 [INFO] INFO...
2019-11-15 [ERROR] ERROR...
4. ์ด์..๋ผ๊ธฐ ๋ณด๋ค๋ ๋ฐ์ํ๋ ๋ฌธ์ ์
1.XML์ ์์ฑํ๋๋ ์ ํ๋ฆฌ์ผ์ด์ ๊ตฌ๋์ ์๋ฌ๊ฐ ๋ฐ์ํจ
1.1 ๋ด๊ฐ ์์ฑํ๋ ์ฝ๋
<appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>ldata.log</file>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<!-- daily rollover -->
<fileNamePattern>ldata-%d{yyyy-MM-dd}.log</fileNamePattern>
<!-- each file should be at most 100MB, keep 60 days worth of history, but at most 20GB -->
<maxFileSize>100MB</maxFileSize>
<!-- keep 30 days' worth of history capped at 3GB total size -->
<maxHistory>30</maxHistory>
<totalSizeCap>2GB</totalSizeCap>
</rollingPolicy>
<encoder>
<pattern>%date %level [%thread] %logger{10} [%file:%line] %msg%n</pattern>
</encoder>
</appender>
1.2 ๋ํ๋ฌ๋ ์ค๋ฅ
2019-11-14 16:12:45,568 ERROR [main] o.s.b.SpringApplication [SpringApplication.java:826] Application run failed
java.lang.IllegalStateException: Logback configuration error detected:
ERROR in ch.qos.logback.core.joran.spi.Interpreter@11:20 - no applicable action for [maxFileSize], current ElementPath is [[configuration][appender][rollingPolicy][maxFileSize]]
at org.springframework.boot.logging.logback.LogbackLoggingSystem.loadConfiguration(LogbackLoggingSystem.java:169)
at org.springframework.boot.logging.AbstractLoggingSystem.initializeWithConventions(AbstractLoggingSystem.java:80)
at org.springframework.boot.logging.AbstractLoggingSystem.initialize(AbstractLoggingSystem.java:60)
at org.springframework.boot.logging.logback.LogbackLoggingSystem.initialize(LogbackLoggingSystem.java:118)
at org.springframework.boot.context.logging.LoggingApplicationListener.initializeSystem(LoggingApplicationListener.java:312)
at org.springframework.boot.context.logging.LoggingApplicationListener.initialize(LoggingApplicationListener.java:287)
at org.springframework.boot.context.logging.LoggingApplicationListener.onApplicationEnvironmentPreparedEvent(LoggingApplicationListener.java:245)
at org.springframework.boot.context.logging.LoggingApplicationListener.onApplicationEvent(LoggingApplicationListener.java:222)
at org.springframework.context.event.SimpleApplicationEventMulticaster.doInvokeListener(SimpleApplicationEventMulticaster.java:172)
at org.springframework.context.event.SimpleApplicationEventMulticaster.invokeListener(SimpleApplicationEventMulticaster.java:165)
at org.springframework.context.event.SimpleApplicationEventMulticaster.multicastEvent(SimpleApplicationEventMulticaster.java:139)
at org.springframework.context.event.SimpleApplicationEventMulticaster.multicastEvent(SimpleApplicationEventMulticaster.java:127)
at org.springframework.boot.context.event.EventPublishingRunListener.environmentPrepared(EventPublishingRunListener.java:76)
at org.springframework.boot.SpringApplicationRunListeners.environmentPrepared(SpringApplicationRunListeners.java:53)
at org.springframework.boot.SpringApplication.prepareEnvironment(SpringApplication.java:345)
- no applicable action for [maxFileSize] ๊ฐ ํต์ฌ ๋ฌธ๊ตฌ
1.3 ์ค๋ฅ์ ์์ธ ๋ฐ ํด๊ฒฐ๋ฐฉ์
- ๊ณต์ ๋ฌธ์๋ฅผ ๋ณด๋ฉฐ ์์ ๋ฅผ ๋ถ์ด๋ ๊ณผ์ ์์, `TimeBasedRollingPolicy` ํด๋์ค๊ฐ ํ๋ฆฐ ๊ฒ์ ํ์ธํ๊ฒ ๋จ. (^^)
- ํ์ฌ rollingPolicy์ class๋ `TimeBasedRollingPolicy`์ด๋ ๋ด๊ฐ ์์ฑํ ์์ฑ๋ค(`maxFileSize`, `totalSizeCap`)`์ ์ฌ์ฉํ๋ ค๋ฉด class๋ฅผ `SizeAndTimeBasedRollingPolicy`๋ก ์ง์ ํด์ฃผ์ด์ผ ์ค๋ฅ๊ฐ ๋์ง ์์ต๋๋ค!
- ๊ทธ๋ฌ๋ฏ๋ก ์ ์ ๋น์ทํ ์ค๋ฅ๊ฐ ๋ฐ์ํ์๋ค๋ฉด
1. XML์ ์ฌ๋ฐ๋ฅด๊ฒ ์์ฑํ์๋์ง (์ด์ด๋๊ณ ๋ซ์ ํ๊ทธ๋ ์๋์ง, / ๊ฐ ๋น ์ก๋ค๋์ง ๋ฑ๋ฑ..)
2. ๊ฐ Class์ ํด๋นํ๋ ์์ฑ์ ์ฌ๋ฐ๋ฅด๊ฒ ์์ฑํ์๋์ง
๊ผญ ํ์ธ์ ํด์ฃผ์ธ์.
'๐ป Back-End' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
DuckDuckGoSearchAPIWrapper.run HTTPError (0) | 2025.01.26 |
---|---|
[Excel] Spring์์ ์์ ์ ์ถ๋ ฅํ๋ ๋ฐฉ๋ฒ (0) | 2020.11.24 |
Telegram Bot API (0) | 2019.10.01 |
[JEUS] Session Timeout ์ค์ (1) | 2019.02.13 |
[Web] #Servlet #GET #POST (0) | 2018.07.24 |