Skip to content

Commit 4a8a184

Browse files
authored
[#1321] add logger request server serviceName/ip/port (#1322) (#1379)
1 parent dee2dc8 commit 4a8a184

File tree

9 files changed

+222
-2
lines changed

9 files changed

+222
-2
lines changed

spring-cloud-huawei-common/src/main/java/com/huaweicloud/common/configration/dynamic/GovernanceProperties.java

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,8 @@ public class GovernanceProperties {
3030

3131
public static final int WEB_FILTER_SERVICE_AUTH_ORDER = -60000;
3232

33+
public static final int WEB_FILTER_REQUEST_LOGGER_ORDER = -35000;
34+
3335
private static final int WEB_CLIENT_LOAD_BALANCE_BASE = 0;
3436

3537
public static final int WEB_CLIENT_FAULT_INJECTION_ORDER =
@@ -56,6 +58,9 @@ public class GovernanceProperties {
5658
public static final String WEBCLIENT_FAULT_INJECTION_ENABLED =
5759
PREFIX + "." + "webclient.faultInjection.enabled";
5860

61+
public static final String WEBCLIENT_REQUEST_LOGGER_ENABLED =
62+
PREFIX + "." + "webclient.requestLogger.enabled";
63+
5964
public static final String GATEWAY_GOVERNANCE_ENABLED = PREFIX + "." + "gateway.governance.enabled";
6065

6166
public static final String GATEWAY_RETRY_ENABLED = PREFIX + "." + "gateway.retry.enabled";
@@ -78,6 +83,12 @@ public class GovernanceProperties {
7883
public static final String WEBFLUX_CONTEXT_MAPPER_ENABLED =
7984
PREFIX + "." + "webflux.contextMapper.enabled";
8085

86+
public static final String WEBFLUX_REQUEST_LOGGER_ENABLED =
87+
PREFIX + "." + "webflux.requestLogger.enabled";
88+
89+
public static final String WEBMVC_REQUEST_LOGGER_ENABLED =
90+
PREFIX + "." + "webmvc.requestLogger.enabled";
91+
8192
public static final String WEBMVC_RATE_LIMITING_ENABLED =
8293
PREFIX + "." + "webmvc.rateLimiting.enabled";
8394

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
/*
2+
3+
* Copyright (C) 2020-2024 Huawei Technologies Co., Ltd. All rights reserved.
4+
5+
* Licensed under the Apache License, Version 2.0 (the "License");
6+
* you may not use this file except in compliance with the License.
7+
* You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*/
17+
18+
package com.huaweicloud.governance.adapters;
19+
20+
import org.slf4j.Logger;
21+
import org.slf4j.LoggerFactory;
22+
import org.springframework.cloud.client.ServiceInstance;
23+
24+
import com.huaweicloud.common.context.InvocationContext;
25+
import com.huaweicloud.governance.GovernanceConst;
26+
27+
public class RequestServiceInfoLoggerUtil {
28+
private static final Logger LOGGER = LoggerFactory.getLogger(RequestServiceInfoLoggerUtil.class);
29+
30+
public static void logServiceInfo(InvocationContext context, Throwable e) {
31+
if (context != null && context.getLocalContext(GovernanceConst.CONTEXT_CURRENT_INSTANCE) != null) {
32+
ServiceInstance instance = context.getLocalContext(GovernanceConst.CONTEXT_CURRENT_INSTANCE);
33+
LOGGER.error("request >>>>>>>>>>>>>> service {}[{}:{}] failed", instance.getServiceId(), instance.getHost(),
34+
instance.getPort(), e);
35+
}
36+
}
37+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
/*
2+
3+
* Copyright (C) 2020-2024 Huawei Technologies Co., Ltd. All rights reserved.
4+
5+
* Licensed under the Apache License, Version 2.0 (the "License");
6+
* you may not use this file except in compliance with the License.
7+
* You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*/
17+
package com.huaweicloud.governance.adapters.webclient;
18+
19+
import java.util.Optional;
20+
21+
import org.slf4j.Logger;
22+
import org.slf4j.LoggerFactory;
23+
import org.springframework.cloud.client.ServiceInstance;
24+
import org.springframework.core.Ordered;
25+
import org.springframework.web.reactive.function.client.ClientRequest;
26+
import org.springframework.web.reactive.function.client.ClientResponse;
27+
import org.springframework.web.reactive.function.client.ExchangeFilterFunction;
28+
import org.springframework.web.reactive.function.client.ExchangeFunction;
29+
30+
import com.huaweicloud.governance.adapters.loadbalancer.RetryContext;
31+
32+
import reactor.core.publisher.Mono;
33+
34+
public class ServiceInfoLoggerExchangeFilterFunction implements ExchangeFilterFunction, Ordered {
35+
private static final Logger LOGGER = LoggerFactory.getLogger(ServiceInfoLoggerExchangeFilterFunction.class);
36+
37+
@Override
38+
public Mono<ClientResponse> filter(ClientRequest request, ExchangeFunction next) {
39+
return next.exchange(request).map(response -> logServiceInfo(response, request));
40+
}
41+
42+
private ClientResponse logServiceInfo(ClientResponse response, ClientRequest request) {
43+
if (response.statusCode().value() != 200) {
44+
Optional<Object> invocationContext = request.attribute(RetryContext.RETRY_SERVICE_INSTANCE);
45+
if (invocationContext.isPresent() && invocationContext.get() instanceof ServiceInstance instance) {
46+
LOGGER.error("request >>>>>>>>>>>>>> service {}[{}:{}] failed", instance.getServiceId(), instance.getHost(),
47+
instance.getPort());
48+
}
49+
}
50+
return response;
51+
}
52+
53+
@Override
54+
public int getOrder() {
55+
return Integer.MAX_VALUE;
56+
}
57+
}

spring-cloud-huawei-governance/src/main/java/com/huaweicloud/governance/adapters/webclient/WebClientConfiguration.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,4 +70,11 @@ public ExchangeFilterFunction faultInjectionExchangeFilterFunction(FaultInjectio
7070
public StatusCodeExtractor clientResponseStatusCodeExtractor(Environment environment) {
7171
return new ClientResponseStatusCodeExtractor(environment);
7272
}
73+
74+
@Bean
75+
@ConditionalOnProperty(value = GovernanceProperties.WEBCLIENT_REQUEST_LOGGER_ENABLED,
76+
havingValue = "true", matchIfMissing = true)
77+
public ServiceInfoLoggerExchangeFilterFunction serviceInfoLoggerExchangeFilterFunction() {
78+
return new ServiceInfoLoggerExchangeFilterFunction();
79+
}
7380
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
/*
2+
3+
* Copyright (C) 2020-2024 Huawei Technologies Co., Ltd. All rights reserved.
4+
5+
* Licensed under the Apache License, Version 2.0 (the "License");
6+
* you may not use this file except in compliance with the License.
7+
* You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*/
17+
18+
package com.huaweicloud.governance.adapters.webflux;
19+
20+
import org.springframework.boot.web.reactive.filter.OrderedWebFilter;
21+
import org.springframework.web.server.ServerWebExchange;
22+
import org.springframework.web.server.WebFilterChain;
23+
24+
import com.huaweicloud.common.configration.dynamic.GovernanceProperties;
25+
import com.huaweicloud.common.context.InvocationContext;
26+
import com.huaweicloud.common.context.InvocationContextHolder;
27+
import com.huaweicloud.governance.adapters.RequestServiceInfoLoggerUtil;
28+
29+
import reactor.core.publisher.Mono;
30+
31+
public class RequestServiceInfoLoggerWebFilter implements OrderedWebFilter {
32+
@Override
33+
public Mono<Void> filter(ServerWebExchange exchange, WebFilterChain chain) {
34+
return chain.filter(exchange).onErrorResume(Exception.class, (t) -> {
35+
InvocationContext context = exchange.getAttribute(InvocationContextHolder.ATTRIBUTE_KEY);
36+
RequestServiceInfoLoggerUtil.logServiceInfo(context, t);
37+
return Mono.error(t);
38+
});
39+
}
40+
41+
@Override
42+
public int getOrder() {
43+
return GovernanceProperties.WEB_FILTER_REQUEST_LOGGER_ORDER;
44+
}
45+
}

spring-cloud-huawei-governance/src/main/java/com/huaweicloud/governance/adapters/webflux/WebFluxConfiguration.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,4 +73,11 @@ public WebFilter identifierRateLimitingWebFilter(IdentifierRateLimitingHandler i
7373
public WebFilter contextMapperWebFilter(@Qualifier("contextMapperHandler") MapperHandler mapperHandler) {
7474
return new ContextMapperWebFilter(mapperHandler);
7575
}
76+
77+
@Bean
78+
@ConditionalOnProperty(value = GovernanceProperties.WEBFLUX_REQUEST_LOGGER_ENABLED,
79+
havingValue = "true", matchIfMissing = true)
80+
public WebFilter requestServiceInfoLoggerWebFilter() {
81+
return new RequestServiceInfoLoggerWebFilter();
82+
}
7683
}

spring-cloud-huawei-governance/src/main/java/com/huaweicloud/governance/adapters/webmvc/IdentifierRateLimitingFilter.java

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -71,8 +71,7 @@ public void doFilter(ServletRequest request, ServletResponse response, FilterCha
7171
if (e instanceof RequestNotPermitted) {
7272
((HttpServletResponse) response).setStatus(429);
7373
response.getWriter().print("rate limited.");
74-
LOGGER.warn("the request is rate limit by policy : {}",
75-
e.getMessage());
74+
LOGGER.warn("the request is rate limit by policy : {}", e.getMessage());
7675
} else {
7776
throw e;
7877
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
/*
2+
3+
* Copyright (C) 2020-2024 Huawei Technologies Co., Ltd. All rights reserved.
4+
5+
* Licensed under the Apache License, Version 2.0 (the "License");
6+
* you may not use this file except in compliance with the License.
7+
* You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*/
17+
package com.huaweicloud.governance.adapters.webmvc;
18+
19+
import java.io.IOException;
20+
21+
import com.huaweicloud.common.context.InvocationContextHolder;
22+
import com.huaweicloud.governance.adapters.RequestServiceInfoLoggerUtil;
23+
24+
import jakarta.servlet.Filter;
25+
import jakarta.servlet.FilterChain;
26+
import jakarta.servlet.ServletException;
27+
import jakarta.servlet.ServletRequest;
28+
import jakarta.servlet.ServletResponse;
29+
30+
public class RequestServiceInfoLoggerFilter implements Filter {
31+
@Override
32+
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
33+
throws IOException, ServletException {
34+
try {
35+
if (WebMvcUtils.isNotHttpServlet(request, response)) {
36+
chain.doFilter(request, response);
37+
return;
38+
}
39+
chain.doFilter(request, response);
40+
} catch (Throwable e) {
41+
RequestServiceInfoLoggerUtil.logServiceInfo(InvocationContextHolder.getOrCreateInvocationContext(), e);
42+
throw e;
43+
}
44+
}
45+
}

spring-cloud-huawei-governance/src/main/java/com/huaweicloud/governance/adapters/webmvc/WebMvcConfiguration.java

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,18 @@ public FilterRegistrationBean<RateLimitingFilter> rateLimitingFilter(
5454
return registrationBean;
5555
}
5656

57+
@Bean
58+
@ConditionalOnProperty(value = GovernanceProperties.WEBMVC_REQUEST_LOGGER_ENABLED,
59+
havingValue = "true", matchIfMissing = true)
60+
public FilterRegistrationBean<RequestServiceInfoLoggerFilter> requestServiceInfoLoggerFilter() {
61+
FilterRegistrationBean<RequestServiceInfoLoggerFilter> registrationBean = new FilterRegistrationBean<>();
62+
registrationBean.setFilter(new RequestServiceInfoLoggerFilter());
63+
registrationBean.addUrlPatterns("/*");
64+
registrationBean.setOrder(GovernanceProperties.WEB_FILTER_REQUEST_LOGGER_ORDER);
65+
66+
return registrationBean;
67+
}
68+
5769
@Bean
5870
@ConditionalOnProperty(value = GovernanceProperties.WEBMVC_IDENTIFIER_RATE_LIMITING_ENABLED,
5971
havingValue = "true", matchIfMissing = true)

0 commit comments

Comments
 (0)