ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 스프링부트 API/AOP 03 - Sentry 및 Log 적용
    스프링/API-AOP 2021. 9. 19. 10:48

    유투버 '데어프로그래밍'님의 강의 참조

     

     

    마지막 강의

    • 전처리시에 REQUEST 값 처리 방법
    • 오류용 API를 탈때 응답 및 로그 남기는 방법

     

     

     

    01 REQUEST에 접근

    • @Around일때는 유효검사를 하고싶은 파라미터에 리퀘스트를 걸기만 하면 해결
    • 아닐때는? 아래를 보자
    	@Before("execution(* com.cos.aop.web..*Controller.*(..))")
    	public void beforeTest() {
    		HttpServletRequest request =
    				((ServletRequestAttributes)RequestContextHolder.currentRequestAttributes())
    				.getRequest();
    		System.out.println("주소: "+request.getRequestURL());
    		System.out.println("Before-Log saved.");
    	}
    • AOP를 써서 전처리를 위에처럼 가능하기도 하고 필터를 직접 구현해서 ....Application.java 파일 (프로젝트를 만들면 생기는 파일)에 @Bean 등록해서 넣어주면 된다
    • @Around가 아닌 전처리용은 이렇게 Request만 넣어주고 request가 가진 기능을 .get... 으로 불러써 쓰기만 하면 된다

     

    → 전처리를 하면서 필요한 로그들을 남겨보자 (들어온 사람들의 수, 어떤 요청이 제일 많이 오는 지 등)

    @Component
    @Aspect
    public class BindingAdvice {
    	
    	private static final Logger log = LoggerFactory.getLogger(BindingAdvice.class);
        ...

    ※ 보통 아이디 잘못 입력, 빈공간 등은 프론트에서 걸러내 줄 수 있다. 보통 서버에서 하는 로그남기는 잘못된 접근에 대한 것이다. (포스트맨, 자바 등 일반적이지 않은 요청)

     

    	@Around("execution(* com.cos.aop.web..*Controller.*(..))")
    	public Object validationCheck(ProceedingJoinPoint proceedingJoinPoint) throws Throwable { //메서드에 있는 모든걸 다들고와서 넣음
    		String type = proceedingJoinPoint.getSignature().getDeclaringTypeName();
    		String method = proceedingJoinPoint.getSignature().getName();
    		
    		System.out.println("type: "+type);
    		System.out.println("method: "+method);
    		
    		Object[] args = proceedingJoinPoint.getArgs();
    		
    		for (Object arg : args) {
    			if (arg instanceof BindingResult) {
    				BindingResult bindingResult = (BindingResult)arg;
    				if(bindingResult.hasErrors()) {
    					Map<String, String> errorMap = new HashMap<>();
    					
    					for(FieldError error:bindingResult.getFieldErrors()) {
    						errorMap.put(error.getField(), error.getDefaultMessage());
    						log.warn(type+"."+method+"() => 필드 :"+error.getField()+", 메시지: "+error.getDefaultMessage());
    					}
    					
    					return new CommonDto<>(HttpStatus.BAD_REQUEST.value(),errorMap);
    				}
    			}
    		}
    		return proceedingJoinPoint.proceed();
    	}
    }
    • 오류가 걸리는 부분에서 log를 써서 아래와 같이 나온다면 명확하게 어떤 오류인지 알기 좋다

     

    • 이해해야할 부분은 아래와 같다
    1. 로그 레벨을 어떻게 설정할 것인가?
      error → 가장 치명적인 오류 시
      warn → error 바로 전 단계로 치명적이게 바뀔 수 있는 것들
      info → 가장 노말하게 오류를 알려 주는 용
      debug → 개발 단계에서 사용
    2. 로그레벨 설정을 하면 그 이상으로만 값이 뜬다(예: info로 설정하면 error/warn/info 만 가져올수있음)

     

     

    02 로그 파일로 남겨보기

    • 로그 처리는 DB연결해서 DB에 남길수도 있고 파일(File file = new File())로도 남길수도 있다. 하지만 로그를 남기는 것이기 때문에 둘다 추천하지 않는다
    • 직접 만들어 보자

    xml 위치 무조건 여기로!!!

     

     

    • xml파일 설정에 대한 몇가지
    더보기

    <?xml version="1.0" encoding="UTF-8"?>
    <configuration>
        <property name="LOGS_ABSOLUTE_PATH" value="./logs" />

        <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
            <layout class="ch.qos.logback.classic.PatternLayout">
                <Pattern>[%d{yyyy-MM-dd HH:mm:ss}:%-3relative][%thread] %-5level %logger{36} - %msg%n</Pattern>
            </layout>
        </appender>

        <appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
            <file>${LOGS_ABSOLUTE_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_ABSOLUTE_PATH}/logback.%d{yyyy-MM-dd}.%i.log.gz</fileNamePattern>
                <timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
                    <maxFileSize>5MB</maxFileSize>
                </timeBasedFileNamingAndTriggeringPolicy>
                <maxHistory>30</maxHistory>
            </rollingPolicy>
        </appender>

    <root level="INFO">
         <appender-ref ref="STDOUT" />
        </root>
        
        <logger name="com.cos.AOP.config" level="WARN">
            <appender-ref ref="FILE" />
        </logger>

    </configuration>

    1. <property name="LOGS_ABSOLUTE_PATH" value="./logs" /> → .logs 파일이 xml적용 이후 실행하면 나타난다
    2. <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
      → 콘솔창에 뿌려지고(STDOUT)  ConsoleAppender를 사용
    3. <appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
      → 파일로 만들고(FILE) RollingFileAppender를 사용
    4. <pattern></pattern> 부분을 직접 세팅
    5. <maxFileSize>5MB</maxFileSize> 파일이 5MB를 초과할때마다 새 파일 생성
    6. <root level="INFO"><appender-ref ref="STDOUT" /></root>
      → 루트 레벨이 INFO 이상이면 콘솔에 뿌림
    7. <logger name="com.cos.AOP.config" level="WARN"><appender-ref ref="FILE" /></logger>
      → 로그 레벨이 WARN 이상이면 파일을 남김

     

    • 테스트

     

     

     

     

     

    03 디버그 뿌려보기

    <root level="DEBUG">
    <appender-ref ref="STDOUT" />
    </root>

Designed by Tistory.