From 7a1f28b82bc132f733e6c90cc0a5de7c8e58ebc5 Mon Sep 17 00:00:00 2001 From: lanyuanxiaoyao Date: Wed, 31 Jan 2024 15:50:05 +0800 Subject: [PATCH] =?UTF-8?q?feat(forest):=20=E5=A2=9E=E5=8A=A0=E6=8E=A5?= =?UTF-8?q?=E5=8F=A3=E8=AE=BF=E9=97=AE=E6=8C=87=E6=A0=87?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../configuration/MetricsInterceptor.java | 107 ++++++++++++++++++ .../src/main/resources/application-forest.yml | 4 +- 2 files changed, 110 insertions(+), 1 deletion(-) create mode 100644 service-forest/src/main/java/com/lanyuanxiaoyao/service/forest/configuration/MetricsInterceptor.java diff --git a/service-forest/src/main/java/com/lanyuanxiaoyao/service/forest/configuration/MetricsInterceptor.java b/service-forest/src/main/java/com/lanyuanxiaoyao/service/forest/configuration/MetricsInterceptor.java new file mode 100644 index 0000000..a30bfc1 --- /dev/null +++ b/service-forest/src/main/java/com/lanyuanxiaoyao/service/forest/configuration/MetricsInterceptor.java @@ -0,0 +1,107 @@ +package com.lanyuanxiaoyao.service.forest.configuration; + +import cn.hutool.core.util.ObjectUtil; +import com.dtflys.forest.exceptions.ForestRuntimeException; +import com.dtflys.forest.http.ForestQueryMap; +import com.dtflys.forest.http.ForestRequest; +import com.dtflys.forest.http.ForestResponse; +import com.dtflys.forest.interceptor.Interceptor; +import io.micrometer.core.instrument.Counter; +import io.micrometer.core.instrument.MeterRegistry; +import io.micrometer.core.instrument.Tag; +import io.micrometer.core.instrument.Timer; +import java.util.Map; +import java.util.concurrent.TimeUnit; +import org.eclipse.collections.api.factory.Lists; +import org.eclipse.collections.api.factory.Maps; +import org.eclipse.collections.api.list.MutableList; +import org.eclipse.collections.api.map.MutableMap; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.stereotype.Component; + +/** + * 指标 + * + * @author lanyuanxiaoyao + * @date 2024-01-31 + */ +@SuppressWarnings("unchecked") +@Component +public class MetricsInterceptor implements Interceptor { + public static final String FOREST_SEND_REQUEST = "forest_send_request"; + public static final String FOREST_SEND_REQUEST_SECONDS = "forest_send_request_seconds"; + private static final Logger logger = LoggerFactory.getLogger(MetricsInterceptor.class); + private static final String PARSED_TAGS = "parsed_tags"; + private final MeterRegistry meterRegistry; + private final MutableMap counterCache = + Maps.mutable.empty().asSynchronized(); + private final MutableMap timerCache = + Maps.mutable.empty().asSynchronized(); + + public MetricsInterceptor(MeterRegistry meterRegistry) { + this.meterRegistry = meterRegistry; + } + + private Iterable parseTags(ForestRequest request) { + MutableList tags = Lists.mutable.of( + Tag.of("host", request.getHost()), + Tag.of("port", String.valueOf(request.getPort())), + Tag.of("path", request.getPath()), + Tag.of("schema", request.getScheme()) + ); + ForestQueryMap query = request.getQuery(); + if (ObjectUtil.isNotEmpty(query)) { + for (Map.Entry entry : query.entrySet()) { + tags.add(Tag.of("query_" + entry.getKey(), String.valueOf(entry.getValue()))); + } + } + return tags; + } + + private void increaseCounter(ForestRequest request, ForestResponse response, MutableList tags) { + Counter counter = counterCache.getIfAbsentPut( + request.getUrl(), + meterRegistry.counter( + MetricsInterceptor.FOREST_SEND_REQUEST, + tags.with(Tag.of("code", String.valueOf(response.getStatusCode()))) + ) + ); + counter.increment(); + } + + @Override + public boolean beforeExecute(ForestRequest request) { + addAttribute(request, PARSED_TAGS, parseTags(request)); + return Interceptor.super.beforeExecute(request); + } + + @Override + public void afterExecute(ForestRequest request, ForestResponse response) { + Interceptor.super.afterExecute(request, response); + + MutableList tags = (MutableList) getAttribute(request, PARSED_TAGS); + Timer timer = timerCache.getIfAbsentPut(request.getUrl(), meterRegistry.timer(FOREST_SEND_REQUEST_SECONDS, tags)); + timer.record(response.getTimeAsMillisecond(), TimeUnit.MILLISECONDS); + } + + @Override + public void onSuccess(Object data, ForestRequest request, ForestResponse response) { + Interceptor.super.onSuccess(data, request, response); + + MutableList tags = (MutableList) getAttribute(request, PARSED_TAGS); + if (ObjectUtil.isNotNull(tags)) { + increaseCounter(request, response, tags); + } + } + + @Override + public void onError(ForestRuntimeException ex, ForestRequest request, ForestResponse response) { + Interceptor.super.onError(ex, request, response); + + MutableList tags = (MutableList) getAttribute(request, PARSED_TAGS); + if (ObjectUtil.isNotNull(tags)) { + increaseCounter(request, response, tags); + } + } +} diff --git a/service-forest/src/main/resources/application-forest.yml b/service-forest/src/main/resources/application-forest.yml index b975ee7..40ecf30 100644 --- a/service-forest/src/main/resources/application-forest.yml +++ b/service-forest/src/main/resources/application-forest.yml @@ -2,4 +2,6 @@ forest: backend: httpclient timeout: 60000 log-enabled: false - interceptors: com.lanyuanxiaoyao.service.forest.configuration.SpringCloudDiscoveryInterceptor \ No newline at end of file + interceptors: + - com.lanyuanxiaoyao.service.forest.configuration.SpringCloudDiscoveryInterceptor + - com.lanyuanxiaoyao.service.forest.configuration.MetricsInterceptor \ No newline at end of file