Skip to content

spring framework 7.x 에서의 xlog가 표시되지 않고, header 도 추출이 되지 않는 현상 #1055

Description

@kyongbok

xlog 가 찍히지 않아,

profile_http_header_enabled=false
를 설정했더니 xlog 에 기록은 되었으나, header 확인이 어려워

log 를 남겨 확인

A143 fail to deploy java.lang.IllegalAccessException: class scouter.agent.plugin.AbstractPlugin cannot access a member of class org.springframework.web.server.DefaultServerWebExchangeBuilder$MutativeDecorator with modifiers "public"

가 발생하였습니다.

기존에는 그렇지 않아, 비교를 해보니 spring framework 가 업데이트 되어 문제가 발생하였씁니다.
(spring framework version 6.x --> 7.x)


  • TraceMain.java 에서 startReactiveHttpService()

Scouter가 런타임 구현 클래스에서 메서드를 찾지 말고, public 인터페이스인 ServerWebExchange에서 메서드를 찾아 호출하도록 수정

기존소스 제거

Object req = AbstractPlugin.invokeMethod(exchange, "getRequest");
Object res = AbstractPlugin.invokeMethod(exchange, "getResponse");

수정

ClassLoader classLoader = exchange.getClass().getClassLoader();

Class<?> serverWebExchangeClass = Class.forName(
        "org.springframework.web.server.ServerWebExchange",
        false,
        classLoader
);

Object req = serverWebExchangeClass
        .getMethod("getRequest")
        .invoke(exchange);

Object res = serverWebExchangeClass
        .getMethod("getResponse")
        .invoke(exchange);

로 일단 위의 exception 은 해결하였고


  • WebfluxHttpTrace.java

두번째는 header 가 여전히 찍히지 않는 문제 인데
A143 Fail to deploy java.lang.nosuchmethoderror: 'javax.util.set org.springframework.http.httpheaders.entrySet()

가 발생하는데 이부분도 수정 (원인 spring 7.x jar 부터 일부 함수 없어짐 entrySet/keySet )

기존

public Enumeration getHeaderNames(Object req) {
    ServerHttpRequest request = (ServerHttpRequest) req;
    Set<String> strings = request.getHeaders().keySet();
    return Collections.enumeration(strings);
}

수정

public Enumeration getHeaderNames(Object req) {
    ServerHttpRequest request = (ServerHttpRequest) req;
    List<String> names = new ArrayList<String>();
    request.getHeaders().forEach((name, values) -> {
        names.add(name);
    });
    return Collections.enumeration(names);
}

그리고 dump() 함수에도 없어진 함수를 쓰는데 이부분도

if (conf.profile_http_header_enabled) {
    if (conf.profile_http_header_url_prefix == null
            || ctx.serviceName.indexOf(
                    conf.profile_http_header_url_prefix) >= 0) {

        final int startTime =
                (int) (System.currentTimeMillis() - ctx.startTime);

            request.getHeaders().forEach((key, values) -> {

                // 지정된 헤더만 수집
                if (conf._profile_http_header_keys != null
                        && !conf._profile_http_header_keys.isEmpty()
                        && !conf._profile_http_header_keys.contains(
                                key.toUpperCase(L))) {
                    return;
                }

                if (values == null || values.isEmpty()) {
                    return;
                }

                for (String headerValue : values) {
                    if (headerValue == null) {
                        continue;
                    }

                    String value = new StringBuilder()
                            .append("header: ")
                            .append(key)
                            .append("=")
                            .append(
                                StringUtil.limiting(
                                    headerValue,
                                    1024
                                )
                            )
                            .toString();

                    MessageStep step = new MessageStep(value);
                    step.start_time = startTime;

                    p.add(step);
                }
            });
}

식으로 변경해야 할것 같습니다.

테스트 결과 xlog 표시 및 클릭시 header 가 잘나온는것 확인하였습니다.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions