Logging, Profiles

calis_ws·2023년 7월 2일
0

Logging

실무에서는 Systemm.out.println()과 같은 시스템 콘솔 보다는 필요한 정보를 출력하거나 디버깅 없이 별도의 logging 라이브러리를 사용한다. 이를 통해 디버깅이나 타임프탬프 등 정해진 양식에 맞춰 화면에 띄우거나 파일 로그를 남길 수 있다.

  • 실제 서비스 중인 애플리케이션의 콘솔을 보는 데 어려움

  • 어플리케이션이 실행 중일 때 일어난 일의 기록

  • Logging : 로그를 남기는 행위

  • Logger : 로그를 작성하기 위해 사용하는 객체

  • 문제가 발생했을 때 로그 파일을 통해 문제의 원인과 발생 지점을 추적 가능

  • Log는 Spring Boot 에 내장되어 있음

TestController

//@Slf4j
@RestController
public class TestController {
    private static final Logger log = LoggerFactory.getLogger(TestController.class);

    @GetMapping("/log")
    public void logTest() {
        log.trace("A TRACE message");
        log.debug("A DEBUG message");
        log.info("A INFO message");
        log.warn("A WARN message");
        log.error("A ERROR message");
    }

url 접속

로그가 남는다.

Log Level

로그에 남길 정보의 중요도에 따라 나눈 단계이다. 아래로 갈수록 높은 단계이다.

  • trace : 아주 사소한 변화까지 로그로 남긴다. 가장 낮은 단계이다.

  • debug : 디버깅에 도움이 될 변화들을 로그로 남긴다.

  • info : 프로그램을 실행하는 동안의 변화들을 정보 제공을 위해 로그로 남긴다.

  • warn : 프로그램이 실행 중일 때 현재 시점에서는 문제가 발생하지 않았지만, 차후에 문제가 생길 수도 있다는 경고 목적으로 로그를 남긴다.

  • error : 서비스가 정상적으로 요청을 처리하지 못했음을 알리기 위해 로그를 남긴다.

warn

멈춘것처럼 보이지만 보여줄 로그가 없는 것이다.

debug

무수한 로그들이 뜨게 된다.

trace

info

Logback

특정 파일에 로그를 남기거나, 특정 날짜까지만 기록하는 등 로그의 형식을 제어하기 위해 Logback을 사용한다.

resources 패키지에 logback-spring.xml 추가

<?xml version="1.0" encoding="UTF-8"?>
<configuration>

    <property name="LOGS" value="./logs" />

    <appender name="Console"
              class="ch.qos.logback.core.ConsoleAppender">
        <layout class="ch.qos.logback.classic.PatternLayout">
            <Pattern>
                %cyan(%d{ISO8601}) %highlight(%-5level) [%blue(%t)] %yellow(%C{1}): %msg%n%throwable
            </Pattern>
        </layout>
    </appender>
    <appender name="File" class="ch.qos.logback.core.FileAppender">
        <file>${LOGS}/file-log.log</file>
        <encoder
                class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
            <Pattern>%d %p %C{1} [%t] %m%n</Pattern>
        </encoder>

    </appender>

    <appender name="RollingFile"
              class="ch.qos.logback.core.rolling.RollingFileAppender">
        <file>${LOGS}/rolling-file-log.log</file>
        <encoder
                class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
            <Pattern>%d %p %C{1} [%t] %m%n</Pattern>
        </encoder>

        <rollingPolicy
                class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
            <fileNamePattern>${LOGS}/archived/rolling-file-log-%d{yyyy-MM-dd_HH-mm-ss}.%i.log
            </fileNamePattern>
            <maxFileSize>100MB</maxFileSize>
            <maxHistory>10</maxHistory>
            <totalSizeCap>1GB</totalSizeCap>
        </rollingPolicy>
    </appender>

    <!-- LOG everything at INFO level -->
    <root level="info">
        <appender-ref ref="RollingFile" />
        <appender-ref ref="Console" />
    </root>

    <!-- LOG "org*" at WARN level -->
    <logger name="org" level="warn" additivity="false">
        <appender-ref ref="Console" />
        <appender-ref ref="File" />
    </logger>

    <!-- LOG "com.example.contents*" at TRACE level -->
    <logger name="com.example.contents" level="trace" additivity="false">
        <appender-ref ref="RollingFile" />
        <appender-ref ref="Console" />
        <appender-ref ref="File" />
    </logger>

</configuration>

ContentsApplication 재 실행

로그의 형식이 바뀐다.

logs 패키지와 log 파일이 생성된다.

"로그 남기기" 추가하기

xml 파일의 아래 부분을 주석처리

<Pattern> 코드에 “로그남기기” 를 추가하면

다시 실행했을 때 “로그남기기”가 추가된걸 볼 수 있다.

Logback 세부 설명

appender : 로그를 받아 작성해주는 역할을 하는 클래스이다.

  • ConsoleAppender는 콘솔에 로그를 남긴다.

  • FileAppender는 파일에 로그를 남긴다.

  • RollingFileAppender는 특정 조건에 따라서 파일 갯수, 크기, 총 용량을 제한하며 로그를 남긴다.

Pattern, Layout, Encoder : 패턴 내용을 해석한 후, <layout>은 문자열로 변환하고, <encoder>는 파일로 작성 가능한 Byte Array로 변환합니다.

  • %d : 로그가 작성된 날짜
  • %p : 로그 레벨
  • %c : 로그 남긴 스레드
  • %m : 로그 메시지
  • %n : 개행 문자

FileNamePattern

%d{yyyy-MM-dd_HH-mm-ss} 처럼 파일 이름의 패턴을 지정할 수가 있는데, 이처럼 파일 이름에 남기는 시간 구분이 초 단위라면 파일도 초단위로 새로 생성되게 된다.

매 초마다 로그 생성하기

ContentsApplication

@Slf4j
@SpringBootApplication
public class ContentsApplication {
	public static void main(String[] args) {
		SpringApplication.run(ContentsApplication.class, args);

		Runnable logRunnable = () -> log.info("log test {}", LocalDateTime.now());
		ScheduledExecutorService executor = Executors.newScheduledThreadPool(1);
		executor.scheduleAtFixedRate(logRunnable, 0, 500, TimeUnit.MILLISECONDS);
	}
}

매 초마다 로그 생성이 된다.

resourses에 없는 logback-spring.xml 적용하기

Profiles

개발, 테스트, 운영 등 환경에 따라 서버나 설정 값, 동작이 다를 수 있다. 그럴 때 사용할 수 있는 기능으로 어플리케이션 실행 시 기능 마다 다른 설정을 할 수 있는 기능이다.

사용 방법

application-{profile}.yaml ← 이와 같은 형식으로 yaml 파일을 생성한다.

application.yaml 파일 생성 목록

application.yaml

spring:
  profiles:
    default: dev # application-dev.yaml을 기본으로 사용
  servlet:
    multipart:
      max-file-size: 10MB
      max-request-size: 10MB
  mvc:
    # /static/ 으로 시작하는 요청에 대해 정적 파일 서빙
    static-path-pattern: /static/**
  web:
    resources:
      # 정적 파일 탐색 장소
      static-locations: file:media/,classpath:/static

logging:
  level:
    root: info
  config: file:logback-spring.xml

application-dev

spring:
  datasource:
    url: jdbc:sqlite:db.sqlite
    driver-class-name: org.sqlite.JDBC
  jpa:
    hibernate:
      ddl-auto: update
    show-sql: true
    database-platform: org.hibernate.community.dialect.SQLiteDialect
    defer-datasource-initialization: true
  sql:
    init:
      mode: always

어노테이션

  • @Profiles : 프로필을 구분하여 Bean을 로드할 수 있는 어노테이션이다.
  • @ActiveProfiles : 테스트 수행 시 어떤 profile을 사용할 것인지 정해주는 어노테이션이다.

테스트 코드를 실행할 때 test.yaml의 설정을 사용

application-test.yaml

spring:
  datasource:
    url: jdbc:h2:mem:testdb
    driver-class-name: org.h2.Driver
    username: sa
    password: password
  jpa:
    database: h2
    database-platform: org.hibernate.dialect.H2Dialect

logging:
  level:
    root: debug

UserControllerTests

@ActiveProfiles("test")
@ExtendWith(MockitoExtension.class)
public class UserControllerTests {
    @Mock
    private UserService userService;

출처 멋사 5기 백엔드 위키 6팀 식스센스

인사이트 타임

백엔드 위키 작성

review

멘토님께서 오전수업 내용만 위키작성을 부탁하셔서 이게 웬떡이냐 하고 신이났다. 오후 수업부턴 서프라이즈라는 떡밥을 남긴 채 사라지셨다. 무슨 서프라이즈일까 큰 기대는 하지 않았지만 어쨌든 팀원들과 ㄱㅇㄷ을 외치며 한 주의 마무리가 훈훈하게 끝나나 싶었는데 갑자기 뜬 공지 내용은 이러했다.

"오늘부터 3일간 개인 미션 프로젝트 수행"
이게 무슨 소린가. 갑자기 프로젝트라고? 내용은 중고 거래 플랫폼(당근마켓 같은거) API를 만들어보라는 개인 미션이었다. 아니 나 지금 할 줄 아는거 숨쉬기가 전부인데 이게 뭔일이람. 할튼 일단 만들라고 하니까 무슨 수를 써서라도 만들어야겠지. 요구사항이 지금까지 배운걸 만드는 것과 비슷하긴 했지만 꽤 오랜 시간을 써야 할 것 같다. 나 어떡하냐

profile
반갑습니다람지

0개의 댓글