인프런 커뮤니티 질문&답변

khss4008님의 프로필 이미지
khss4008

작성한 질문수

Spring Cloud로 개발하는 마이크로서비스 애플리케이션(MSA)

Spring Cloud Gateway - Logging Filter

cannot resolve property

작성

·

2.3K

0

application.yml 파일에서 글로벌 필터의 속성 ( baseMessage, preLogger, postLogger) 는 인식하는데 로깅 필터의 속성은 인식하지 못해 cannot resolve property 에러가 납니다. 왜인지 이유를 알 수 없어 질문드립니다.

LoggingFilter.java 파일입니다.

package com.todaypills.apigatewayservice.Filter;

import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.springframework.cloud.gateway.filter.GatewayFilter;
import org.springframework.cloud.gateway.filter.OrderedGatewayFilter;
import org.springframework.cloud.gateway.filter.factory.AbstractGatewayFilterFactory;
import org.springframework.core.Ordered;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.stereotype.Component;
import reactor.core.publisher.Mono;

@Slf4j //for print log
@Component /**커스텀 필터의 일종임, 단지 로그를 찍기 위한 필터이므로 이름을 Logging 이라고 지은 것*/
public class LoggingFilter extends AbstractGatewayFilterFactory<LoggingFilter.Config> {

    public LoggingFilter() { super(Config.class); }

    @Override
    public GatewayFilter apply(Config config) {
        /**
         * 위쪽 주석부분은 람다 표현식으로 바로 리턴한 것이고 이것은 람다를 사용하지 않고 리턴한 것임,
         * 따라서 인스턴스부터 만들어주어야 하고 GatewayFilter는 인터페이스이기 때문에 직접 인스턴스를 생성할 수는 없고, OrderedGatewayFilter() 를 이용하여 인스턴스를 만들어주어야함
         * */
        GatewayFilter filter = new OrderedGatewayFilter(((exchange, chain) -> { /** exchange: request와 response 객체를 얻기 위함 */
            ServerHttpRequest request = exchange.getRequest();
            ServerHttpResponse response = exchange.getResponse();

            log.info("logging filter: request id -> {}", config.getBaseMessage());

            if(config.isPreLogger()){
                log.info("logging pre filter start: request id -> {}", request.getId());
            }

            return chain.filter(exchange).then(Mono.fromRunnable(() -> {
                if(config.isPostLogger()){
                    //Mono 객체: 웹플럭스(스프링5)에서 지원하는 기능으로 비동기방식의 서버에서 단일값을 전달할 때 모노타입으로 전달
                    log.info("logging post filter end: response code -> {}", response.getStatusCode());
                }
            }));
        }), Ordered.HIGHEST_PRECEDENCE); //HIGHEST_PRECEDENCE 는 적용할 필터가 여러개일 때 어느것이 먼저 실행될지 우선순위를 부여함
        return filter;
    }
    @Data // setter getter 함수 생성 (isPreLogger(), isPostLogger() 등)
    public static class Config{
        // 여기에 configuration 이 있다면 삽입
        private String baseMessage;
        private boolean preLogger;
        private boolean postLogger;
    }
}

 

application.yml 파일입니다.

server:
  port: 8000
eureka:
  client:
    register-with-eureka: true
    fetch-registry: true
    service-url:
      defaultZone: http://localhost:8761/eureka
spring:
  application:
    name: apigateway-service
  cloud:
    gateway:
      default-filters:
        - name: GlobalFilter
          args: # 우리가 정의한 변수
            baseMessage: 게이트웨이 글로벌 필터입니다.
            preLogger: true #prefilter의 유무
            postLogger: true
      routes: #FilterConfig의 라우팅 정보를 yml 파일로도 설정할 수 있음
        - id: nutrients-service
          uri: http://localhost:8081/
          predicates:
            - Path=/nutrients-service/**
          filters:
#            - AddRequestHeader=nutrients-request, nutrients-request-heaer-value
#            - AddResponseHeader=nutrients-response, nutrients-response-header-value
            - name: CustomFilter
            - name: LoggingFilter
              args:
                baseMessage: 커스텀 로깅 필터입니다.
                preLogger: true
                postLogger: true

답변 3

0

저도 동일한 문제가 발생하여서 강사님 말씀대로 빌드를 새로 해보았는데 안되네요 ㅜㅜ

0

동일한 오류발생했는데 yml 에서 LoggingFilter 부분을 아래와 같이 default-filters 아래로 위치시켜 해결했습니다. 혹시나 다른분들에게 도움될까 남깁니다.

server:
  port: 8000

eureka:
  client:
    register-with-eureka: false
    fetch-registry: false
    service-url:
      defaultZone: http://localhost:8761/eureka

spring:
  application:
    name: apigateway-service
  cloud:
    gateway:
      default-filters:
        - name: GlobalFilter
          args:
            baseMessage: spring Cloud Gateway Global Filter
            preLogger: true
            postLogger: true
        - name: LoggingFilter
          args:
              baseMessage: Hi, there.
              preLogger: true
              postLogger: true
      routes:
        - id: first-service
          uri: http://localhost:8081/
          predicates:
            - Path=/first-service/**
          filters:
            #            - AddRequestHeader=first-request, first-request-header2
            #            - AddResponseHeader=first-response, first-response-header2
            - CustomFilter
        - id: second-service
          uri: http://localhost:8082/
          predicates:
            - Path=/second-service/**
          filters:
            #            - AddRequestHeader=second-request, second-request-header2
            #            - AddResponseHeader=second-response, second-response-header2
            - name: CustomFilter



0

Dowon Lee님의 프로필 이미지
Dowon Lee
지식공유자

안녕하세요, 이도원입니다.

올려주신 application.yml 파일과 LoggingFilter.java 파일로 apigateway-service를 실행시켜 보니 아래와 같이 정상 실행되었습니다 (LoggingFilter가 GlobalFilter보다 먼저 출력된 건 우선순위에 의해서 그렇습니다).

image

image

image

프로젝트 빌드를 새로 해 보시고 진행해 보시면 좋을 것 같습니다.

감사합니다.

khss4008님의 프로필 이미지
khss4008

작성한 질문수

질문하기