로깅의 뜻과 존재 이유
로깅 : 애클리케이션이 동작하는 동안 시스템의 상태나 동작 정보를 시간순으로 기록하는 것
사용자나 고객에게 꼭 필요한 기능은 아니지만, 디버깅이나 개발 이후 발생한 문제를 해결할 때 원인을 분석하는데 꼭 필요한 요소이다.
자바에서 가장 많이 사용되는 로깅 프레임워크는 Logback로 log4j이후 출시되었으며, slf4j를 기반으로 구현되었다.
LOGBACK의 특징
- 크게 5개의 로그레벨로 설정할 수 있다. (ERROR, WARN, INFO, DEBUG, TRACE)
- 실제 운영 환경과 개발 환경에서 각각 다른 출력 레벨을 설정해서 로그를 확인할 수 있다.
- LOGBACK 설정 파일을 일정 시가남다 스캔해서 애플리케이션을 재가동하지 않아도 설정을 변경할 수 있다.
- 별도의 프로그램 지원 업싱도 자체적으로 로그 파일을 압축할 수 있다.
- 저장된 로그 파일에 대한 보관 기간 등을 설정해서 관리할 수 있다.
사용법
1. pom.xml에 log 의존성 주입
<!-- Logging -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>${org.slf4j-version}</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>jcl-over-slf4j</artifactId>
<version>${org.slf4j-version}</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>${org.slf4j-version}</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.15</version>
<exclusions>
<exclusion>
<groupId>javax.mail</groupId>
<artifactId>mail</artifactId>
</exclusion>
<exclusion>
<groupId>javax.jms</groupId>
<artifactId>jms</artifactId>
</exclusion>
<exclusion>
<groupId>com.sun.jdmk</groupId>
<artifactId>jmxtools</artifactId>
</exclusion>
<exclusion>
<groupId>com.sun.jmx</groupId>
<artifactId>jmxri</artifactId>
</exclusion>
</exclusions>
<scope>runtime</scope>
</dependency>
2. java/resources 에 logback-spring.xml 파일 추가
<?xml version="1.0" encoding="UTF-8"?>
<!-- 60초마다 설정 파일의 변경을 확인 하여 변경시 갱신 -->
<configuration scan="true" scanPeriod="60 seconds">
<!--로그 파일 저장 위치 -->
<springProfile name="dev">
<property name="LOGS_PATH" value="./logs" />
</springProfile>
<!-- 이 속성 안 쓸거임 -->
<property name="CONSOLE_LOG_PATTERN" value="${CONSOLE_LOG_PATTERN:-%clr(%d{${LOG_DATEFORMAT_PATTERN:-yyyy-MM-dd HH:mm:ss.SSS}}){green} %clr(${LOG_LEVEL_PATTERN:-%5p}) %clr(${PID:- }){magenta} %clr(---){faint} %clr([%15.15t]){faint} %clr(%-40.40logger{39}){cyan} %clr(:){faint} %m%n${LOG_EXCEPTION_CONVERSION_WORD:-%wEx}}" />
<property name="CONSOLE_LOG_CHARSET" value="${CONSOLE_LOG_CHARSET:-default}" />
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<withJansi>true</withJansi>
<encoder>
<pattern>[%d{yyyy-MM-dd HH:mm:ss}:%-3relative][%thread] %green(%-5level) %logger{35} %cyan(%logger{15}) - %msg %n</pattern>
</encoder>
</appender>
<appender name="DAILY_ROLLING_FILE_APPENDER" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>${LOGS_PATH}/logback.log</file>
<encoder>
<pattern>[%d{yyyy-MM-dd HH:mm:ss}:%-3relative][%thread] %-5level%logger{35} - %msg%n</pattern>
</encoder>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>${LOGS_PATH}/logback.%d{yyyy-MM-dd}.%i.log.gz
</fileNamePattern>
<timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
<!-- or whenever the file size reaches 100MB -->
<maxFileSize>5MB</maxFileSize>
<!-- kb, mb, gb -->
</timeBasedFileNamingAndTriggeringPolicy>
<maxHistory>30</maxHistory>
</rollingPolicy>
</appender>
<logger name="net.lunalabs.central" level="INFO">
<appender-ref ref="DAILY_ROLLING_FILE_APPENDER" />
</logger>
<!-- log4jdbc 옵션 설정 -->
<logger name="jdbc" level="OFF" /> <!-- 커넥션 open close 이벤트를 로그로 남긴다. -->
<logger name="jdbc.connection" level="OFF" /> <!-- SQL문만을 로그로 남기며, PreparedStatement일 경우 관련된 argument 값으로 대체된 SQL문이 보여진다. -->
<logger name="jdbc.sqlonly" level="OFF" /> <!-- SQL문과 해당 SQL을 실행시키는데 수행된 시간 정보(milliseconds)를 포함한다. -->
<logger name="jdbc.sqltiming" level="DEBUG" /> <!-- ResultSet을 제외한 모든 JDBC 호출 정보를 로그로 남긴다. 많은 양의 로그가 생성되므로 특별히 JDBC 문제를 추적해야 할 필요가 있는 경우를 제외하고는 사용을 권장하지 않는다. -->
<logger name="jdbc.audit" level="OFF" /> <!-- ResultSet을 포함한 모든 JDBC 호출 정보를 로그로 남기므로 매우 방대한 양의 로그가 생성된다. -->
<logger name="jdbc.resultset" level="OFF" /> <!-- SQL 결과 조회된 데이터의 table을 로그로 남긴다. -->
<logger name="jdbc.resultsettable" level="OFF" />
<root level="INFO">
<appender-ref ref="STDOUT" />
</root>
</configuration>
3. 컨트롤러에 Logger 객체 정의
private final Logger logger = LoggerFactory.getLogger(GetController.class);
4. 로그 출력 코드 작성
package controller;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class LogController {
private final Logger logger = LoggerFactory.getLogger("LOgerController의 로그");
@RequestMapping(value="/hello", method=RequestMethod.GET)
public String getHello() {
logger.info("getHello()메서드를 호출하였습니다.");
return "Hello World";
}
}
반응형