지석이의 일기
로그백 Logback과 log4jdbc 로그파일로 적재해보자. 본문
로그백은 왜 하는걸까?
로깅을 통해 개발자는 개발 과정 혹은 개발 후에 발생할 수 있는 예상치 못한 애플리케이션의 문제를 진단할 수 있고, 다양한 정보를 수집할 수 있다. 사용자들의 이동 분석도 할 수있다.
또한 각 단계별로 위험도 등급을 나누어 파일로 적재할수도있다.
하지만 무분별하게 로깅을 난발하면 과유불급이다.
일단 로깅을 설치하고 어디 어디에 로깅 파일을 넣어야하는지 확인해보자.
이번 시간에는 SLF4J 의 구현체 Logback 을 사용해서 로깅을 구현해보겠다.
로그백 초간단 사용
스프링부트에서는 기본적으로 내장이 되어있고, 구현체이다 보니 그냥 별도의 초기화 없이 바로 사용이 가능하다.
이런식으로 클래스 전역 변수로 전언하고,
@Controller public class HomeController { private final Logger logger = LoggerFactory.getLogger("HomeController"); @RequestMapping("/") public String home(Model model) { logger.info("메인홈페이지 접속"); return "/Index"; } } } |
이런식으로, getLogger에 String값을 넣으면 어디서 이 로그를 호출한건지 얼추 알수있다.
구동을 하면 다음과 같다.

정말 간단하게 Logback을 사용했는데 "겨우 이정도?" 면 "굳이?","그냥 System.out.println()을 사용하겠다!" 라고 할 수 있겠지만, logback은 이게 끝이 아니다.
필자가 생각하기에 최소한 2가지 이유가 있는데 우선 첫번재 이유를 보겠다.
일단 로그에는 개발자들이 개발을 하거나, 추후 운영을 할때 신경을 더 써야 한다는 의미로 레벨이 5개 존재하는데
심각도 수준으로 Error > Warn > Info > Debug > Trace 가 있다.
수준이 올라갈수록 개발자는 무조건 해당 알림에대해 인지를 하고 있어야한다! 라는 의미로 해석하면된다.
또한 기본적으로 설정된 디버그 레벨보다 수준이 낮은 레벨의 디버그는 노출되지 않는다.
(따로 레벨을 설정하지 않았으면 기본은 info이다)
개발단계에서는 낮은 레벨의 탐지를 사용해서 콘솔을 많이 찍어도 되지만, 운영에 올릴때는 INFO이상으로해야 파일 용량에 부담이 없다!
두번째는 언제나 개발자나 운영자가 서버에 붙어 실행 현황이나 에러 현환을 확인 할수가없다.
무슨 사건이 일어나면 그건 언제나 과거이므로, 과거 행적을 확인 해야하는데, 그걸 로그백- 로그파일로 확인할수있다.
우리가 로그백을 사용해야하는 가장 큰 이유인 파일 적재에 대해 공부해보자.
로그파일 생성 환경
스프링 부트에서는 기본적으로 가장 많이 쓰이는 application.properties가 있는데, 물론 여기서 기본적인 셋팅을 할 수 있겠지만 세세한 설정은 하지 못하므로, logback-spring.xml을 만들어 연동하도록 하겠다.
/src/main/resources 경로에 logback-spring.xml파일을 만들자. 파일을 만들고 configuration 태그를 사용하면 프로젝트 시작시 알아서 설정을 읽는다. 풀경로는 /src/main/resources/logback-spring.xml 이다.
<configuration scan="true" scanPeriod="100 seconds"> <appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender"> <layout class="ch.qos.logback.classic.PatternLayout"> <Pattern>[%d{yyyy-MM-dd HH:mm:ss}:%-1relative][%thread] %-5level %logger{36} - %msg%n</Pattern> </layout> </appender> <appender name="INFO_LOG" class="ch.qos.logback.core.rolling.RollingFileAppender"> <file>./logs/info.log</file> <!--파일을 저장할 경로를 정한다--> <filter class="ch.qos.logback.classic.filter.LevelFilter"> <level>INFO</level> <onMatch>ACCEPT</onMatch> <!--해당 레벨만 기록한다.--> <onMismatch>DENY</onMismatch> <!--다른 수준의 레벨은 기록하지 않는다.(상위 레벨도 기록 안함), 상위 수준의 레벨에 대한 기록을 원하면 ACCEPT 로 하면 기록된다.--> </filter> <!--레벨별 필터링이 필요없을 경우 filter class 관련된 부분을 삭제하면 됨--> <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>./was-logs/info.%d{yyyy-MM-dd}.%i.log.gz</fileNamePattern> <!--해당 패턴 네이밍으로 이전 파일이 기록됨--> <timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP"> <maxFileSize>100MB</maxFileSize> <!--한 파일의 최대 용량--> </timeBasedFileNamingAndTriggeringPolicy> <maxHistory>180</maxHistory><!-- 한 파일의 최대 저장 기한--> </rollingPolicy> </appender> <springProfile name="local"> <root level="DEBUG"> <appender-ref ref="CONSOLE"/> </root> </springProfile> <springProfile name="real"> <root level="INFO"> <appender-ref ref="CONSOLE"/> <appender-ref ref="INFO_LOG"/> </root> </springProfile> <!-- 특정패키지 로깅레벨 설정--> <logger name="org.apache.ibatis" level="INFO" additivity="false"> <appender-ref ref="CONSOLE"/> <appender-ref ref="INFO_LOG"/> </logger> <!-- [S]프로필 상관없이 전체 다 적용 --> <!-- log4jdbc 옵션 설정 --> <logger name="jdbc" level="OFF"/> <!-- sql문만 로깅할지 여부 --> <logger name="jdbc.sqlonly" level="OFF"/> <!--쿼리문 수행시간 로깅 여부--> <logger name="jdbc.sqltiming" level="DEBUG"/> <!--ResultSet외 모든 JDBC 호출 정보 로깅할지 여부--> <logger name="jdbc.audit" level="OFF"/> <!--ResultSet 포함 모든 JDBC 호출 정보를 로깅--> <logger name="jdbc.resultset" level="OFF"/> <logger name="jdbc.resultsettable" level="DEBUG"/> <!--connection open close 로깅 여부--> <logger name="jdbc.connection" level="OFF"/> <!-- [E]프로필 상관없이 전체 다 적용 --> </configuration> |
root level <= 전체 로깅 레벨 지정 (기본이 info이지만 하단의 appender-ref 를 사용하기 위함)
appender class=ch.qos.logback.core.ConsoleAppender <= 기본 콘솔 환경
이런식으로 원하는 방식으로 콘솔에 찍힐 로그를 수정할수있다.
appender class=ch.qos.logback.core.rolling.RollingFileAppender <= 파일로 적재시킬 태그
여기까지 단순히 로그 노출 방식 설정 및 파일로 적재하는 방식에 대해서 봤는데, 사용하다보니, 왜 DB 쿼리는 노출이 안되지? 라는 생각이 들었고... 그건 LOG4JDBC 를 사용해야한다.
LOG4JDBC를 사용하려면 maven을 수정해서 추가적으로 jar를 받아야한다.
<dependency>
<groupId>org.bgee.log4jdbc-log4j2</groupId> <artifactId>log4jdbc-log4j2-jdbc4.1</artifactId> <version>1.16</version> </dependency> <dependency> |
jdbc4를 받아주고, application.properties의 dbDatasource를 수정해주자.
spring.datasource.jdbc-url=jdbc:log4jdbc:mysql:{ip...}
spring.datasource.driver-class-name=net.sf.log4jdbc.sql.jdbcapi.DriverSpy
또한 ,/src/main/resources/logback-spring.xml과 같은 경로에 log4jdbc.log4j2.properties를 만들고
log4jdbc.spylogdelegator.name=net.sf.log4jdbc.log.slf4j.Slf4jSpyLogDelegator
log4jdbc.dump.sql.maxlinelength=0 |
을 넣어주자.
이후 logback-spring.xml 에 새로운 태그들을 넣어주면 되는데
<!-- 특정패키지 로깅레벨 설정 -->
<logger name="org.apache.ibatis" level="INFO" additivity="false"> <appender-ref ref="STDOUT"/> <appender-ref ref="INFO_LOG"/> </logger> <!-- log4jdbc 옵션 설정 --> <logger name="jdbc" level="OFF"/> <!-- sql문만 로깅할지 여부 --> <logger name="jdbc.sqlonly" level="OFF"/> <!-- 쿼리문 수행시간 로깅 여부 --> <logger name="jdbc.sqltiming" level="DEBUG"/> <!-- ResultSet외 모든 JDBC 호출 정보 로깅할지 여부 --> <logger name="jdbc.audit" level="OFF"/> <!-- ResultSet 포함 모든 JDBC 호출 정보를 로깅 --> <logger name="jdbc.resultset" level="OFF"/> <logger name="jdbc.resultsettable" level="DEBUG"/> <!-- connection open close 로깅 여부 --> <logger name="jdbc.connection" level="OFF"/> |
이런 식으로 콘솔창에 내가 입력한 파라미터에 대한 쿼리와 데이터 결과값을 확인 할수 있다.!
'Java' 카테고리의 다른 글
인텔리 제이(Intelli J)를 써보자. + Spring boot web 구동 (0) | 2023.10.15 |
---|---|
Spring boot JPA 를 사용해보자. (0) | 2023.09.09 |
Spring Boot 의 DB에서 조회뒤 view로 넘겨보자 (0) | 2023.01.15 |
Spring Boot 프로젝트에 Mysql연결하기 (0) | 2022.03.17 |
5. AWS서버에 DB를 설치해서 DB서버로 만들어보자 (0) | 2022.03.17 |