diff --git a/sermant-plugins/sermant-metrics/metrics-plugin/pom.xml b/sermant-plugins/sermant-metrics/metrics-plugin/pom.xml
index 524c6db844..3fb8e79365 100644
--- a/sermant-plugins/sermant-metrics/metrics-plugin/pom.xml
+++ b/sermant-plugins/sermant-metrics/metrics-plugin/pom.xml
@@ -20,9 +20,15 @@
2.5.7
2.7.3
4.0.1
+ 4.5.13
+ 2.7.5
+ 4.1.0
+ 3.0.1
+ 4.4
+ 8.0.28
-
+
com.huaweicloud.sermant
sermant-agentcore-core
@@ -40,6 +46,42 @@
${apache.dubbo.version}
provided
+
+ org.apache.httpcomponents
+ httpclient
+ ${httpclient.version}
+ provided
+
+
+ com.squareup.okhttp
+ okhttp
+ ${okhttp.version}
+ provided
+
+
+ com.squareup.okhttp3
+ okhttp
+ ${okhtt3.version}
+ provided
+
+
+ javax.servlet
+ javax.servlet-api
+ ${javax-servlet-api.version}
+ provided
+
+
+ mysql
+ mysql-connector-java
+ ${mysql.version}
+ provided
+
+
+
+ com.github.jsqlparser
+ jsqlparser
+ ${jsqlparser.version}
+
junit
diff --git a/sermant-plugins/sermant-metrics/metrics-plugin/src/main/java/com/huawei/metrics/common/Constants.java b/sermant-plugins/sermant-metrics/metrics-plugin/src/main/java/com/huawei/metrics/common/Constants.java
index f30b8fbc48..6a3076ddca 100644
--- a/sermant-plugins/sermant-metrics/metrics-plugin/src/main/java/com/huawei/metrics/common/Constants.java
+++ b/sermant-plugins/sermant-metrics/metrics-plugin/src/main/java/com/huawei/metrics/common/Constants.java
@@ -63,16 +63,6 @@ public class Constants {
*/
public static final String SSL_ENABLE = "sslEnabled";
- /**
- * 服务调用使用的CLIENT下表字段名
- */
- public static final String CLIENT_INDEX = "index";
-
- /**
- * CLIENT集合名称
- */
- public static final String CLIENTS_NAME = "clients";
-
/**
* DUBBO TCP协议集合
*/
@@ -81,12 +71,12 @@ public class Constants {
/**
* 连接信息头
*/
- public static final String LINK_HEAD = "sermant_l7_link";
+ public static final String RPC_HEADER = "sermant_l7_rpc";
/**
- * 连接信息头
+ * API连接信息头
*/
- public static final String RPC_HEAD = "sermant_l7_rpc";
+ public static final String RPC_API_HEADER = "sermant_l7_rpc_api";
/**
* SSL开启标识
@@ -104,49 +94,74 @@ public class Constants {
public static final String CONSUMER_SIDE = "consumer";
/**
- * 提供者标识
+ * 客户端 服务端标识的KEY
*/
- public static final String PROVIDER_SIDE = "provider";
+ public static final String SIDE_KEY = "side";
/**
- * 客户端 服务端标识的KEY
+ * RPC信息保存到context局部变量中的key
*/
- public static final String SIDE_KEY = "side";
+ public static final String RPC_INFO_KEY = "rpcInfo";
/**
- * 字符串写下标保存到context局部变量中的key
+ * 服务调用开始时间保存到context局部变量中的key
*/
- public static final String WRITE_INDEX_KEY = "writeIndex";
+ public static final String START_TIME_KEY = "startTime";
/**
- * 字符串读下标保存到context局部变量中的key
+ * 异常线程ID
*/
- public static final String READ_INDEX_KEY = "readIndex";
+ public static final String EXCEPTION_PID = "-1";
/**
- * 连接信息保存到context局部变量中的key
+ * 指标值的连接符
*/
- public static final String LINK_INFO_KEY = "linkInfo";
+ public static final String METRICS_LINK = "|";
/**
- * RPC信息保存到context局部变量中的key
+ * HTTPS协议
*/
- public static final String RPC_INFO_KEY = "rpcInfo";
+ public static final String HTTPS_PROTOCOL = "https";
/**
- * 服务调用开始时间保存到context局部变量中的key
+ * 最大成功响应编码
*/
- public static final String START_TIME_KEY = "startTime";
+ public static final int MAX_SUCCESS_CODE = 399;
/**
- * 异常线程ID
+ * 最大客户端失败编码
*/
- public static final String EXCEPTION_PID = "-1";
+ public static final int MAX_CLIENT_ERROR_CODE = 499;
/**
- * 指标值的连接符
+ * 最大服务端失败编码
*/
- public static final String METRICS_LINK = "|";
+ public static final int MAX_SERVER_ERROR_CODE = 599;
+
+ /**
+ * MYSQL 客户端异常编码
+ */
+ public static final int[][] MYSQL_CLIENT_ERROR = {{1, 999}, {2000, 2999}};
+
+ /**
+ * MYSQL 服务服务端编码
+ */
+ public static final int[][] MYSQL_SERVER_ERROR = {{1000, 1999}, {3000, 4000}};
+
+ /**
+ * http请求成功
+ */
+ public static final byte HTTP_OK = 20;
+
+ /**
+ * HTTP客户端异常编码
+ */
+ public static final byte[] HTTP_CLIENT_ERROR = {30, 40, 90};
+
+ /**
+ * HTTP异常编码
+ */
+ public static final byte[] HTTP_SERVER_ERROR = {31, 80, 50, 60, 70, 100};
private Constants() {
}
diff --git a/sermant-plugins/sermant-metrics/metrics-plugin/src/main/java/com/huawei/metrics/common/ResultType.java b/sermant-plugins/sermant-metrics/metrics-plugin/src/main/java/com/huawei/metrics/common/ResultType.java
new file mode 100644
index 0000000000..28c9eadcc8
--- /dev/null
+++ b/sermant-plugins/sermant-metrics/metrics-plugin/src/main/java/com/huawei/metrics/common/ResultType.java
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2023-2023 Huawei Technologies Co., Ltd. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.huawei.metrics.common;
+
+/**
+ * 结果类型
+ *
+ * @author zhp
+ * @since 2023-12-15
+ */
+public enum ResultType {
+ /**
+ * 请求成功
+ */
+ SUCCESS(0),
+
+ /**
+ * 客户端错误
+ */
+ CLIENT_ERROR(1),
+
+ /**
+ * 服务端错误
+ */
+ SERVER_ERROR(2),
+
+ /**
+ * 请求失败
+ */
+ ERROR(3);
+
+ private final int value;
+
+ ResultType(int value) {
+ this.value = value;
+ }
+
+ public int getValue() {
+ return value;
+ }
+}
diff --git a/sermant-plugins/sermant-metrics/metrics-plugin/src/main/java/com/huawei/metrics/declarer/alibaba/ExchangeCodecDeclarer.java b/sermant-plugins/sermant-metrics/metrics-plugin/src/main/java/com/huawei/metrics/declarer/alibaba/ExchangeCodecDeclarer.java
index 6667b1f27e..e9dd11101c 100644
--- a/sermant-plugins/sermant-metrics/metrics-plugin/src/main/java/com/huawei/metrics/declarer/alibaba/ExchangeCodecDeclarer.java
+++ b/sermant-plugins/sermant-metrics/metrics-plugin/src/main/java/com/huawei/metrics/declarer/alibaba/ExchangeCodecDeclarer.java
@@ -17,14 +17,14 @@
package com.huawei.metrics.declarer.alibaba;
import com.huawei.metrics.declarer.AbstractDeclarer;
-import com.huawei.metrics.interceptor.alibaba.ExchangeCodecInterceptor;
+import com.huawei.metrics.interceptor.dubbo.alibaba.ExchangeCodecInterceptor;
import com.huaweicloud.sermant.core.plugin.agent.declarer.InterceptDeclarer;
import com.huaweicloud.sermant.core.plugin.agent.matcher.ClassMatcher;
import com.huaweicloud.sermant.core.plugin.agent.matcher.MethodMatcher;
/**
- * dubbo报文转码、解码增强声明
+ * dubbo2.6.x报文转码、解码增强声明
*
* @author zhp
* @since 2023-10-17
@@ -32,11 +32,7 @@
public class ExchangeCodecDeclarer extends AbstractDeclarer {
private static final String ENHANCE_CLASS = "com.alibaba.dubbo.remoting.exchange.codec.ExchangeCodec";
- private static final String ENCODE_METHODS_NAMES = "encode";
-
- private static final String DECODE_METHODS_NAMES = "decode";
-
- private static final int ENCODE_PARAM_COUNT = 3;
+ private static final String DECODE_METHODS_NAMES = "decodeBody";
private static final int DECODE_PARAM_COUNT = 2;
@@ -47,10 +43,8 @@ public ClassMatcher getClassMatcher() {
@Override
public InterceptDeclarer[] getInterceptDeclarers(ClassLoader classLoader) {
- return new InterceptDeclarer[]{InterceptDeclarer.build(MethodMatcher.nameEquals(ENCODE_METHODS_NAMES)
- .and(MethodMatcher.paramCountEquals(ENCODE_PARAM_COUNT)), new ExchangeCodecInterceptor()),
- InterceptDeclarer.build(MethodMatcher.nameEquals(DECODE_METHODS_NAMES)
- .and(MethodMatcher.paramCountEquals(DECODE_PARAM_COUNT)), new ExchangeCodecInterceptor())
+ return new InterceptDeclarer[]{InterceptDeclarer.build(MethodMatcher.nameEquals(DECODE_METHODS_NAMES)
+ .and(MethodMatcher.paramCountEquals(DECODE_PARAM_COUNT)), new ExchangeCodecInterceptor())
};
}
}
diff --git a/sermant-plugins/sermant-metrics/metrics-plugin/src/main/java/com/huawei/metrics/declarer/alibaba/MonitorFilterDeclarer.java b/sermant-plugins/sermant-metrics/metrics-plugin/src/main/java/com/huawei/metrics/declarer/alibaba/MonitorFilterDeclarer.java
index 78f632730e..5ff3a41d03 100644
--- a/sermant-plugins/sermant-metrics/metrics-plugin/src/main/java/com/huawei/metrics/declarer/alibaba/MonitorFilterDeclarer.java
+++ b/sermant-plugins/sermant-metrics/metrics-plugin/src/main/java/com/huawei/metrics/declarer/alibaba/MonitorFilterDeclarer.java
@@ -17,14 +17,14 @@
package com.huawei.metrics.declarer.alibaba;
import com.huawei.metrics.declarer.AbstractDeclarer;
-import com.huawei.metrics.interceptor.alibaba.MonitorFilterInterceptor;
+import com.huawei.metrics.interceptor.dubbo.alibaba.MonitorFilterInterceptor;
import com.huaweicloud.sermant.core.plugin.agent.declarer.InterceptDeclarer;
import com.huaweicloud.sermant.core.plugin.agent.matcher.ClassMatcher;
import com.huaweicloud.sermant.core.plugin.agent.matcher.MethodMatcher;
/**
- * dubbo监控过滤器增强声明
+ * dubbo2.6.x监控过滤器增强声明
*
* @author zhp
* @since 2023-10-17
diff --git a/sermant-plugins/sermant-metrics/metrics-plugin/src/main/java/com/huawei/metrics/declarer/apache/ExchangeCodecDeclarer.java b/sermant-plugins/sermant-metrics/metrics-plugin/src/main/java/com/huawei/metrics/declarer/apache/ExchangeCodecDeclarer.java
index d0c9e62e1f..927d189917 100644
--- a/sermant-plugins/sermant-metrics/metrics-plugin/src/main/java/com/huawei/metrics/declarer/apache/ExchangeCodecDeclarer.java
+++ b/sermant-plugins/sermant-metrics/metrics-plugin/src/main/java/com/huawei/metrics/declarer/apache/ExchangeCodecDeclarer.java
@@ -17,14 +17,14 @@
package com.huawei.metrics.declarer.apache;
import com.huawei.metrics.declarer.AbstractDeclarer;
-import com.huawei.metrics.interceptor.apache.ExchangeCodecInterceptor;
+import com.huawei.metrics.interceptor.dubbo.apache.ExchangeCodecInterceptor;
import com.huaweicloud.sermant.core.plugin.agent.declarer.InterceptDeclarer;
import com.huaweicloud.sermant.core.plugin.agent.matcher.ClassMatcher;
import com.huaweicloud.sermant.core.plugin.agent.matcher.MethodMatcher;
/**
- * dubbo报文转码、解码增强声明
+ * dubbo2.7.x报文转码、解码增强声明
*
* @author zhp
* @since 2023-10-17
@@ -32,11 +32,7 @@
public class ExchangeCodecDeclarer extends AbstractDeclarer {
private static final String ENHANCE_CLASS = "org.apache.dubbo.remoting.exchange.codec.ExchangeCodec";
- private static final String ENCODE_METHODS_NAMES = "encode";
-
- private static final String DECODE_METHODS_NAMES = "decode";
-
- private static final int ENCODE_PARAM_COUNT = 3;
+ private static final String DECODE_METHODS_NAMES = "decodeBody";
private static final int DECODE_PARAM_COUNT = 2;
@@ -47,10 +43,8 @@ public ClassMatcher getClassMatcher() {
@Override
public InterceptDeclarer[] getInterceptDeclarers(ClassLoader classLoader) {
- return new InterceptDeclarer[]{InterceptDeclarer.build(MethodMatcher.nameEquals(ENCODE_METHODS_NAMES)
- .and(MethodMatcher.paramCountEquals(ENCODE_PARAM_COUNT)), new ExchangeCodecInterceptor()),
- InterceptDeclarer.build(MethodMatcher.nameEquals(DECODE_METHODS_NAMES)
- .and(MethodMatcher.paramCountEquals(DECODE_PARAM_COUNT)), new ExchangeCodecInterceptor())
+ return new InterceptDeclarer[]{InterceptDeclarer.build(MethodMatcher.nameEquals(DECODE_METHODS_NAMES)
+ .and(MethodMatcher.paramCountEquals(DECODE_PARAM_COUNT)), new ExchangeCodecInterceptor())
};
}
}
diff --git a/sermant-plugins/sermant-metrics/metrics-plugin/src/main/java/com/huawei/metrics/declarer/apache/MonitorFilterDeclarer.java b/sermant-plugins/sermant-metrics/metrics-plugin/src/main/java/com/huawei/metrics/declarer/apache/MonitorFilterDeclarer.java
index 21b2f936b2..e435637662 100644
--- a/sermant-plugins/sermant-metrics/metrics-plugin/src/main/java/com/huawei/metrics/declarer/apache/MonitorFilterDeclarer.java
+++ b/sermant-plugins/sermant-metrics/metrics-plugin/src/main/java/com/huawei/metrics/declarer/apache/MonitorFilterDeclarer.java
@@ -17,14 +17,14 @@
package com.huawei.metrics.declarer.apache;
import com.huawei.metrics.declarer.AbstractDeclarer;
-import com.huawei.metrics.interceptor.apache.MonitorFilterInterceptor;
+import com.huawei.metrics.interceptor.dubbo.apache.MonitorFilterInterceptor;
import com.huaweicloud.sermant.core.plugin.agent.declarer.InterceptDeclarer;
import com.huaweicloud.sermant.core.plugin.agent.matcher.ClassMatcher;
import com.huaweicloud.sermant.core.plugin.agent.matcher.MethodMatcher;
/**
- * dubbo监控过滤器增强声明
+ * dubbo2.7.x监控过滤器增强声明
*
* @author zhp
* @since 2023-10-17
diff --git a/sermant-plugins/sermant-metrics/metrics-plugin/src/main/java/com/huawei/metrics/declarer/httpclient/HttpClientDeclarer.java b/sermant-plugins/sermant-metrics/metrics-plugin/src/main/java/com/huawei/metrics/declarer/httpclient/HttpClientDeclarer.java
new file mode 100644
index 0000000000..0ae9139940
--- /dev/null
+++ b/sermant-plugins/sermant-metrics/metrics-plugin/src/main/java/com/huawei/metrics/declarer/httpclient/HttpClientDeclarer.java
@@ -0,0 +1,59 @@
+/*
+ * Copyright (C) 2023-2023 Huawei Technologies Co., Ltd. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.huawei.metrics.declarer.httpclient;
+
+import com.huawei.metrics.declarer.AbstractDeclarer;
+import com.huawei.metrics.interceptor.httpclient.HttpClientInterceptor;
+
+import com.huaweicloud.sermant.core.plugin.agent.declarer.InterceptDeclarer;
+import com.huaweicloud.sermant.core.plugin.agent.matcher.ClassMatcher;
+import com.huaweicloud.sermant.core.plugin.agent.matcher.MethodMatcher;
+
+/**
+ * HttpClient4.x请求方法拦截声明
+ *
+ * @author zhp
+ * @since 2023-12-15
+ */
+public class HttpClientDeclarer extends AbstractDeclarer {
+ /**
+ * 增强类的全限定名 http请求
+ */
+ private static final String[] ENHANCE_CLASSES = {
+ "org.apache.http.impl.client.AbstractHttpClient",
+ "org.apache.http.impl.client.DefaultRequestDirector",
+ "org.apache.http.impl.client.InternalHttpClient",
+ "org.apache.http.impl.client.MinimalHttpClient"
+ };
+
+ @Override
+ public ClassMatcher getClassMatcher() {
+ return ClassMatcher.nameContains(ENHANCE_CLASSES);
+ }
+
+ @Override
+ public InterceptDeclarer[] getInterceptDeclarers(ClassLoader classLoader) {
+ return new InterceptDeclarer[]{
+ InterceptDeclarer.build(MethodMatcher.nameContains("doExecute", "execute")
+ .and(MethodMatcher.paramTypesEqual(
+ "org.apache.http.HttpHost",
+ "org.apache.http.HttpRequest",
+ "org.apache.http.protocol.HttpContext")),
+ new HttpClientInterceptor())
+ };
+ }
+}
diff --git a/sermant-plugins/sermant-metrics/metrics-plugin/src/main/java/com/huawei/metrics/declarer/httpurlconnection/ConnectDeclarer.java b/sermant-plugins/sermant-metrics/metrics-plugin/src/main/java/com/huawei/metrics/declarer/httpurlconnection/ConnectDeclarer.java
new file mode 100644
index 0000000000..c6e66d092b
--- /dev/null
+++ b/sermant-plugins/sermant-metrics/metrics-plugin/src/main/java/com/huawei/metrics/declarer/httpurlconnection/ConnectDeclarer.java
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2023-2023 Huawei Technologies Co., Ltd. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.huawei.metrics.declarer.httpurlconnection;
+
+import com.huawei.metrics.declarer.AbstractDeclarer;
+import com.huawei.metrics.interceptor.httpurlconnection.ConnectorInterceptor;
+
+import com.huaweicloud.sermant.core.plugin.agent.declarer.InterceptDeclarer;
+import com.huaweicloud.sermant.core.plugin.agent.matcher.ClassMatcher;
+import com.huaweicloud.sermant.core.plugin.agent.matcher.MethodMatcher;
+
+/**
+ * HttpURLConnection1.7.x+链接方法拦截声明
+ *
+ * @author zhp
+ * @since 2023-12-15
+ */
+public class ConnectDeclarer extends AbstractDeclarer {
+ private static final String ENHANCE_CLASS = "sun.net.www.protocol.http.HttpURLConnection";
+
+ @Override
+ public ClassMatcher getClassMatcher() {
+ return ClassMatcher.nameEquals(ENHANCE_CLASS);
+ }
+
+ @Override
+ public InterceptDeclarer[] getInterceptDeclarers(ClassLoader classLoader) {
+ return new InterceptDeclarer[]{
+ InterceptDeclarer.build(MethodMatcher.nameEquals("connect"),
+ new ConnectorInterceptor())
+ };
+ }
+}
diff --git a/sermant-plugins/sermant-metrics/metrics-plugin/src/main/java/com/huawei/metrics/declarer/httpurlconnection/DisconnectDeclarer.java b/sermant-plugins/sermant-metrics/metrics-plugin/src/main/java/com/huawei/metrics/declarer/httpurlconnection/DisconnectDeclarer.java
new file mode 100644
index 0000000000..144c1b7118
--- /dev/null
+++ b/sermant-plugins/sermant-metrics/metrics-plugin/src/main/java/com/huawei/metrics/declarer/httpurlconnection/DisconnectDeclarer.java
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2023-2023 Huawei Technologies Co., Ltd. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.huawei.metrics.declarer.httpurlconnection;
+
+import com.huawei.metrics.declarer.AbstractDeclarer;
+import com.huawei.metrics.interceptor.httpurlconnection.DisconnectorInterceptor;
+
+import com.huaweicloud.sermant.core.plugin.agent.declarer.InterceptDeclarer;
+import com.huaweicloud.sermant.core.plugin.agent.matcher.ClassMatcher;
+import com.huaweicloud.sermant.core.plugin.agent.matcher.MethodMatcher;
+
+/**
+ * HttpURLConnection1.7.x+链接断开方法拦截声明
+ *
+ * @author zhp
+ * @since 2023-12-15
+ */
+public class DisconnectDeclarer extends AbstractDeclarer {
+ private static final String ENHANCE_CLASS = "sun.net.www.protocol.http.HttpURLConnection";
+
+ @Override
+ public ClassMatcher getClassMatcher() {
+ return ClassMatcher.nameEquals(ENHANCE_CLASS);
+ }
+
+ @Override
+ public InterceptDeclarer[] getInterceptDeclarers(ClassLoader classLoader) {
+ return new InterceptDeclarer[]{
+ InterceptDeclarer.build(MethodMatcher.nameEquals("disconnect"),
+ new DisconnectorInterceptor())
+ };
+ }
+}
diff --git a/sermant-plugins/sermant-metrics/metrics-plugin/src/main/java/com/huawei/metrics/declarer/okhttp/CallDeclarer.java b/sermant-plugins/sermant-metrics/metrics-plugin/src/main/java/com/huawei/metrics/declarer/okhttp/CallDeclarer.java
new file mode 100644
index 0000000000..6aed99a40a
--- /dev/null
+++ b/sermant-plugins/sermant-metrics/metrics-plugin/src/main/java/com/huawei/metrics/declarer/okhttp/CallDeclarer.java
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2023-2023 Huawei Technologies Co., Ltd. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.huawei.metrics.declarer.okhttp;
+
+import com.huawei.metrics.declarer.AbstractDeclarer;
+import com.huawei.metrics.interceptor.okhttp.CallInterceptor;
+
+import com.huaweicloud.sermant.core.plugin.agent.declarer.InterceptDeclarer;
+import com.huaweicloud.sermant.core.plugin.agent.matcher.ClassMatcher;
+import com.huaweicloud.sermant.core.plugin.agent.matcher.MethodMatcher;
+
+/**
+ * okhttp2.x服务调用拦截声明
+ *
+ * @author zhp
+ * @since 2023-12-15
+ */
+public class CallDeclarer extends AbstractDeclarer {
+ private static final String ENHANCE_CLASS = "com.squareup.okhttp.Call";
+
+ @Override
+ public ClassMatcher getClassMatcher() {
+ return ClassMatcher.nameEquals(ENHANCE_CLASS);
+ }
+
+ @Override
+ public InterceptDeclarer[] getInterceptDeclarers(ClassLoader classLoader) {
+ return new InterceptDeclarer[]{
+ InterceptDeclarer.build(MethodMatcher.nameEquals("getResponseWithInterceptorChain"),
+ new CallInterceptor())
+ };
+ }
+}
diff --git a/sermant-plugins/sermant-metrics/metrics-plugin/src/main/java/com/huawei/metrics/declarer/okhttp3/CallDeclarer.java b/sermant-plugins/sermant-metrics/metrics-plugin/src/main/java/com/huawei/metrics/declarer/okhttp3/CallDeclarer.java
new file mode 100644
index 0000000000..1a0c27bd98
--- /dev/null
+++ b/sermant-plugins/sermant-metrics/metrics-plugin/src/main/java/com/huawei/metrics/declarer/okhttp3/CallDeclarer.java
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2023-2023 Huawei Technologies Co., Ltd. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.huawei.metrics.declarer.okhttp3;
+
+import com.huawei.metrics.declarer.AbstractDeclarer;
+import com.huawei.metrics.interceptor.okhttp3.CallInterceptor;
+
+import com.huaweicloud.sermant.core.plugin.agent.declarer.InterceptDeclarer;
+import com.huaweicloud.sermant.core.plugin.agent.matcher.ClassMatcher;
+import com.huaweicloud.sermant.core.plugin.agent.matcher.MethodMatcher;
+
+/**
+ * okhttp3.x服务调用拦截声明
+ *
+ * @author zhp
+ * @since 2023-12-15
+ */
+public class CallDeclarer extends AbstractDeclarer {
+ private static final String[] ENHANCE_CLASSES = {
+ "okhttp3.RealCall",
+ "okhttp3.internal.connection.RealCall"
+ };
+
+ @Override
+ public ClassMatcher getClassMatcher() {
+ return ClassMatcher.nameContains(ENHANCE_CLASSES);
+ }
+
+ @Override
+ public InterceptDeclarer[] getInterceptDeclarers(ClassLoader classLoader) {
+ return new InterceptDeclarer[]{
+ InterceptDeclarer.build(MethodMatcher.nameEquals("getResponseWithInterceptorChain"),
+ new CallInterceptor())
+ };
+ }
+}
diff --git a/sermant-plugins/sermant-metrics/metrics-plugin/src/main/java/com/huawei/metrics/declarer/servlet/HttpServletDeclarer.java b/sermant-plugins/sermant-metrics/metrics-plugin/src/main/java/com/huawei/metrics/declarer/servlet/HttpServletDeclarer.java
new file mode 100644
index 0000000000..1f669394ab
--- /dev/null
+++ b/sermant-plugins/sermant-metrics/metrics-plugin/src/main/java/com/huawei/metrics/declarer/servlet/HttpServletDeclarer.java
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2023-2023 Huawei Technologies Co., Ltd. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.huawei.metrics.declarer.servlet;
+
+import com.huawei.metrics.declarer.AbstractDeclarer;
+import com.huawei.metrics.interceptor.servlet.HttpServletInterceptor;
+
+import com.huaweicloud.sermant.core.plugin.agent.declarer.InterceptDeclarer;
+import com.huaweicloud.sermant.core.plugin.agent.matcher.ClassMatcher;
+import com.huaweicloud.sermant.core.plugin.agent.matcher.MethodMatcher;
+
+/**
+ * HttpServlet3.0+服务处理拦截声明
+ *
+ * @author zhp
+ * @since 2023-12-15
+ */
+public class HttpServletDeclarer extends AbstractDeclarer {
+ private static final String ENHANCE_CLASS = "javax.servlet.http.HttpServlet";
+
+ @Override
+ public ClassMatcher getClassMatcher() {
+ return ClassMatcher.isExtendedFrom(ENHANCE_CLASS);
+ }
+
+ @Override
+ public InterceptDeclarer[] getInterceptDeclarers(ClassLoader classLoader) {
+ return new InterceptDeclarer[]{
+ InterceptDeclarer.build(MethodMatcher.nameEquals("service"),
+ new HttpServletInterceptor())
+ };
+ }
+}
diff --git a/sermant-plugins/sermant-metrics/metrics-plugin/src/main/java/com/huawei/metrics/entity/MetricsInfo.java b/sermant-plugins/sermant-metrics/metrics-plugin/src/main/java/com/huawei/metrics/entity/MetricsInfo.java
index bc5c035558..c1cb8d11a1 100644
--- a/sermant-plugins/sermant-metrics/metrics-plugin/src/main/java/com/huawei/metrics/entity/MetricsInfo.java
+++ b/sermant-plugins/sermant-metrics/metrics-plugin/src/main/java/com/huawei/metrics/entity/MetricsInfo.java
@@ -88,6 +88,11 @@ public class MetricsInfo {
*/
private String machineId;
+ /**
+ * URL信息
+ */
+ private String url;
+
public String getProcessId() {
return processId;
}
@@ -191,4 +196,12 @@ public String getMachineId() {
public void setMachineId(String machineId) {
this.machineId = machineId;
}
+
+ public String getUrl() {
+ return url;
+ }
+
+ public void setUrl(String url) {
+ this.url = url;
+ }
}
diff --git a/sermant-plugins/sermant-metrics/metrics-plugin/src/main/java/com/huawei/metrics/entity/MetricsLinkInfo.java b/sermant-plugins/sermant-metrics/metrics-plugin/src/main/java/com/huawei/metrics/entity/MetricsLinkInfo.java
deleted file mode 100644
index 23657af56d..0000000000
--- a/sermant-plugins/sermant-metrics/metrics-plugin/src/main/java/com/huawei/metrics/entity/MetricsLinkInfo.java
+++ /dev/null
@@ -1,80 +0,0 @@
-/*
- * Copyright (C) 2023-2023 Huawei Technologies Co., Ltd. All rights reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.huawei.metrics.entity;
-
-import java.util.concurrent.atomic.AtomicInteger;
-import java.util.concurrent.atomic.AtomicLong;
-
-/**
- * 连接信息
- *
- * @author zhp
- * @since 2023-10-17
- */
-public class MetricsLinkInfo extends MetricsInfo {
- /**
- * 发送的字节数
- */
- private AtomicLong sentBytes = new AtomicLong();
-
- /**
- * 接收的字节数
- */
- private AtomicLong receiveBytes = new AtomicLong();
-
- /**
- * 发送的报文数
- */
- private AtomicInteger sentMessages = new AtomicInteger();
-
- /**
- * 接收的报文数
- */
- private AtomicInteger receiveMessages = new AtomicInteger();
-
- public AtomicLong getSentBytes() {
- return sentBytes;
- }
-
- public void setSentBytes(AtomicLong sentBytes) {
- this.sentBytes = sentBytes;
- }
-
- public AtomicLong getReceiveBytes() {
- return receiveBytes;
- }
-
- public void setReceiveBytes(AtomicLong receiveBytes) {
- this.receiveBytes = receiveBytes;
- }
-
- public AtomicInteger getSentMessages() {
- return sentMessages;
- }
-
- public void setSentMessages(AtomicInteger sentMessages) {
- this.sentMessages = sentMessages;
- }
-
- public AtomicInteger getReceiveMessages() {
- return receiveMessages;
- }
-
- public void setReceiveMessages(AtomicInteger receiveMessages) {
- this.receiveMessages = receiveMessages;
- }
-}
diff --git a/sermant-plugins/sermant-metrics/metrics-plugin/src/main/java/com/huawei/metrics/entity/MetricsRpcInfo.java b/sermant-plugins/sermant-metrics/metrics-plugin/src/main/java/com/huawei/metrics/entity/MetricsRpcInfo.java
index f961d31e9f..3b281ef1f8 100644
--- a/sermant-plugins/sermant-metrics/metrics-plugin/src/main/java/com/huawei/metrics/entity/MetricsRpcInfo.java
+++ b/sermant-plugins/sermant-metrics/metrics-plugin/src/main/java/com/huawei/metrics/entity/MetricsRpcInfo.java
@@ -36,6 +36,10 @@ public class MetricsRpcInfo extends MetricsInfo {
private AtomicInteger reqErrorCount = new AtomicInteger();
+ private AtomicInteger clientErrorCount = new AtomicInteger();
+
+ private AtomicInteger serverErrorCount = new AtomicInteger();
+
private List latencyList = new CopyOnWriteArrayList<>();
public AtomicInteger getReqCount() {
@@ -77,4 +81,20 @@ public List getLatencyList() {
public void setLatencyList(List latencyList) {
this.latencyList = latencyList;
}
+
+ public AtomicInteger getClientErrorCount() {
+ return clientErrorCount;
+ }
+
+ public void setClientErrorCount(AtomicInteger clientErrorCount) {
+ this.clientErrorCount = clientErrorCount;
+ }
+
+ public AtomicInteger getServerErrorCount() {
+ return serverErrorCount;
+ }
+
+ public void setServerErrorCount(AtomicInteger serverErrorCount) {
+ this.serverErrorCount = serverErrorCount;
+ }
}
diff --git a/sermant-plugins/sermant-metrics/metrics-plugin/src/main/java/com/huawei/metrics/interceptor/AbstractCodecInterceptor.java b/sermant-plugins/sermant-metrics/metrics-plugin/src/main/java/com/huawei/metrics/interceptor/AbstractCodecInterceptor.java
index c677e956a4..77f25363eb 100644
--- a/sermant-plugins/sermant-metrics/metrics-plugin/src/main/java/com/huawei/metrics/interceptor/AbstractCodecInterceptor.java
+++ b/sermant-plugins/sermant-metrics/metrics-plugin/src/main/java/com/huawei/metrics/interceptor/AbstractCodecInterceptor.java
@@ -17,8 +17,9 @@
package com.huawei.metrics.interceptor;
import com.huawei.metrics.common.Constants;
-import com.huawei.metrics.entity.MetricsLinkInfo;
-import com.huawei.metrics.manager.MetricsManager;
+import com.huawei.metrics.common.ResultType;
+import com.huawei.metrics.entity.MetricsRpcInfo;
+import com.huawei.metrics.util.ResultJudgmentUtil;
import com.huaweicloud.sermant.core.plugin.agent.entity.ExecuteContext;
import com.huaweicloud.sermant.core.plugin.agent.interceptor.Interceptor;
@@ -44,25 +45,8 @@ public abstract class AbstractCodecInterceptor implements Interceptor {
}
};
- private static final String ENCODE_METHOD_NAME = "encode";
-
@Override
public ExecuteContext before(ExecuteContext context) {
- if (!isValid(context)) {
- return context;
- }
- MetricsLinkInfo metricsLinkInfo = initLinkInfo(context);
- initIndexInfo(context);
- context.setLocalFieldValue(Constants.LINK_INFO_KEY, metricsLinkInfo);
- return context;
- }
-
- @Override
- public ExecuteContext after(ExecuteContext context) {
- if (!isValid(context)) {
- return context;
- }
- fillMessageInfo(context);
return context;
}
@@ -81,22 +65,6 @@ private boolean isClientSide(String side) {
return Constants.CONSUMER_SIDE.equals(side);
}
- /**
- * 校验
- *
- * @param context 上下文信息
- * @return 校验结果
- */
- public abstract boolean isValid(ExecuteContext context);
-
- /**
- * 初始化连接信息
- *
- * @param context 上下文信息
- * @return 连接信息
- */
- public abstract MetricsLinkInfo initLinkInfo(ExecuteContext context);
-
/**
* 初始化连接信息
*
@@ -107,92 +75,57 @@ private boolean isClientSide(String side) {
* @param protocol 协议信息
* @return 连接信息
*/
- public MetricsLinkInfo initLinkInfo(InetSocketAddress localAddress, InetSocketAddress remoteAddress,
+ public MetricsRpcInfo initRpcInfo(InetSocketAddress localAddress, InetSocketAddress remoteAddress,
String side, boolean sslEnable, String protocol) {
- String metricsKey = localAddress.getHostName() + Constants.CONNECT + remoteAddress.getHostName()
- + Constants.CONNECT + remoteAddress.getPort();
- MetricsLinkInfo metricsLinkInfo = MetricsManager.getLinkInfo(metricsKey);
- if (!StringUtils.isEmpty(metricsLinkInfo.getClientIp())) {
- return metricsLinkInfo;
- }
- metricsLinkInfo.setProtocol(protocol);
+ MetricsRpcInfo metricsRpcInfo = new MetricsRpcInfo();
+ metricsRpcInfo.setProtocol(protocol);
if (isClientSide(side)) {
- initAddressAndRole(metricsLinkInfo, Constants.CLIENT_ROLE, localAddress, remoteAddress);
+ initAddressAndRole(metricsRpcInfo, Constants.CLIENT_ROLE, localAddress, remoteAddress);
} else {
- initAddressAndRole(metricsLinkInfo, Constants.SERVER_ROLE, remoteAddress, localAddress);
+ initAddressAndRole(metricsRpcInfo, Constants.SERVER_ROLE, remoteAddress, localAddress);
}
- if (TCP_PROTOCOL.contains(metricsLinkInfo.getProtocol())) {
- metricsLinkInfo.setL4Role(Constants.TCP_PROTOCOL + Constants.CONNECT + metricsLinkInfo.getL7Role());
+ if (TCP_PROTOCOL.contains(metricsRpcInfo.getProtocol())) {
+ metricsRpcInfo.setL4Role(Constants.TCP_PROTOCOL + Constants.CONNECT + metricsRpcInfo.getL7Role());
} else {
- metricsLinkInfo.setL4Role(Constants.UDP_PROTOCOL + Constants.CONNECT + metricsLinkInfo.getL7Role());
+ metricsRpcInfo.setL4Role(Constants.UDP_PROTOCOL + Constants.CONNECT + metricsRpcInfo.getL7Role());
}
- metricsLinkInfo.setEnableSsl(sslEnable);
- return metricsLinkInfo;
+ metricsRpcInfo.setEnableSsl(sslEnable);
+ return metricsRpcInfo;
}
/**
* 初始化地址和角色信息
*
- * @param metricsLinkInfo 连接信息
+ * @param metricsRpcInfo RPC指标信息
* @param role 角色信息
* @param clientAddress 客户端地址
* @param serverAddress 服务端地址
*/
- private void initAddressAndRole(MetricsLinkInfo metricsLinkInfo, String role, InetSocketAddress clientAddress,
+ private void initAddressAndRole(MetricsRpcInfo metricsRpcInfo, String role, InetSocketAddress clientAddress,
InetSocketAddress serverAddress) {
- metricsLinkInfo.setL7Role(role);
- metricsLinkInfo.setClientIp(clientAddress.getAddress().getHostAddress());
- metricsLinkInfo.setServerIp(serverAddress.getAddress().getHostAddress());
- metricsLinkInfo.setServerPort(StringUtils.getString(serverAddress.getPort()));
+ metricsRpcInfo.setL7Role(role);
+ metricsRpcInfo.setClientIp(clientAddress.getAddress().getHostAddress());
+ metricsRpcInfo.setServerIp(serverAddress.getAddress().getHostAddress());
+ metricsRpcInfo.setServerPort(StringUtils.getString(serverAddress.getPort()));
}
/**
- * 初始化渠道缓存的下标信息
- *
- * @param context 上下文信息
- */
- public abstract void initIndexInfo(ExecuteContext context);
-
- /**
- * 填充报文信息
+ * 填充错误统计信息
*
- * @param currentWriteIndex 当前读索引下标
- * @param currentReadIndex 当前写索引下标
- * @param context 上下文信息
+ * @param status 响应编码
+ * @param metricsRpcInfo 指标信息
*/
- protected void fillMessageInfo(int currentWriteIndex, int currentReadIndex, ExecuteContext context) {
- Object linkInfoObject = context.getLocalFieldValue(Constants.LINK_INFO_KEY);
- if (!(linkInfoObject instanceof MetricsLinkInfo)) {
- return;
- }
- MetricsLinkInfo metricsLinkInfo = (MetricsLinkInfo) linkInfoObject;
- if (StringUtils.equals(context.getMethod().getName(), ENCODE_METHOD_NAME)) {
- Object writeIndex = context.getLocalFieldValue(Constants.WRITE_INDEX_KEY);
- if (!(writeIndex instanceof Integer)) {
- return;
- }
- int addWriteIndex = currentWriteIndex - Integer.parseInt(StringUtils.getString(writeIndex));
- if (addWriteIndex > 0) {
- metricsLinkInfo.getSentBytes().addAndGet(addWriteIndex);
- metricsLinkInfo.getSentMessages().incrementAndGet();
- }
+ public void fillErrorCountInfo(byte status, MetricsRpcInfo metricsRpcInfo) {
+ int value = ResultJudgmentUtil.judgeDubboResult(status);
+ if (value == ResultType.SUCCESS.getValue()) {
return;
}
- Object readIndex = context.getLocalFieldValue(Constants.READ_INDEX_KEY);
- if (!(readIndex instanceof Integer)) {
+ if (value == ResultType.CLIENT_ERROR.getValue()) {
+ metricsRpcInfo.getClientErrorCount().getAndIncrement();
return;
}
- int addReadIndex = currentReadIndex - Integer.parseInt(StringUtils.getString(readIndex));
- if (addReadIndex > 0) {
- metricsLinkInfo.getReceiveBytes().addAndGet(addReadIndex);
- metricsLinkInfo.getReceiveMessages().incrementAndGet();
+ if (value == ResultType.SERVER_ERROR.getValue()) {
+ metricsRpcInfo.getServerErrorCount().getAndIncrement();
}
}
-
- /**
- * 填充报文信息
- *
- * @param context 上下文信息
- */
- protected abstract void fillMessageInfo(ExecuteContext context);
}
diff --git a/sermant-plugins/sermant-metrics/metrics-plugin/src/main/java/com/huawei/metrics/interceptor/AbstractFilterInterceptor.java b/sermant-plugins/sermant-metrics/metrics-plugin/src/main/java/com/huawei/metrics/interceptor/AbstractFilterInterceptor.java
index ad3ff95117..7bdc46dbdf 100644
--- a/sermant-plugins/sermant-metrics/metrics-plugin/src/main/java/com/huawei/metrics/interceptor/AbstractFilterInterceptor.java
+++ b/sermant-plugins/sermant-metrics/metrics-plugin/src/main/java/com/huawei/metrics/interceptor/AbstractFilterInterceptor.java
@@ -39,10 +39,7 @@ public ExecuteContext before(ExecuteContext context) {
return context;
}
long startTime = System.nanoTime();
- MetricsRpcInfo metricsRpcInfo = initRpcInfo(context);
- metricsRpcInfo.getReqCount().incrementAndGet();
context.setLocalFieldValue(Constants.START_TIME_KEY, startTime);
- context.setLocalFieldValue(Constants.RPC_INFO_KEY, metricsRpcInfo);
return context;
}
@@ -55,16 +52,13 @@ public ExecuteContext after(ExecuteContext context) {
if (!(startTimeObject instanceof Long)) {
return context;
}
- Object metrcisObject = context.getLocalFieldValue(Constants.RPC_INFO_KEY);
- if (!(metrcisObject instanceof MetricsRpcInfo)) {
- return context;
- }
- long startTime = Long.parseLong(StringUtils.getString(startTimeObject));
- MetricsRpcInfo metricsRpcInfo = (MetricsRpcInfo) metrcisObject;
+ MetricsRpcInfo metricsRpcInfo = initRpcInfo(context);
+ metricsRpcInfo.getReqCount().incrementAndGet();
metricsRpcInfo.getResponseCount().incrementAndGet();
- long latency = System.nanoTime() - startTime;
+ long latency = System.nanoTime() - (long) startTimeObject;
metricsRpcInfo.getSumLatency().addAndGet(latency);
metricsRpcInfo.getLatencyList().add(latency);
+ MetricsManager.saveRpcInfo(metricsRpcInfo);
return context;
}
@@ -120,12 +114,7 @@ private boolean isClientSide(String side) {
*/
public MetricsRpcInfo initRpcInfo(InetSocketAddress localAddress, InetSocketAddress remoteAddress,
String side, boolean sslEnable, String protocol) {
- String metricsKey = localAddress.getHostName() + Constants.CONNECT + remoteAddress.getHostName()
- + Constants.CONNECT + remoteAddress.getPort();
- MetricsRpcInfo metricsRpcInfo = MetricsManager.getRpcInfo(metricsKey);
- if (!StringUtils.isEmpty(metricsRpcInfo.getClientIp())) {
- return metricsRpcInfo;
- }
+ MetricsRpcInfo metricsRpcInfo = new MetricsRpcInfo();
metricsRpcInfo.setProtocol(protocol);
if (isClientSide(side)) {
initAddressAndRole(metricsRpcInfo, localAddress, remoteAddress, Constants.CLIENT_ROLE);
diff --git a/sermant-plugins/sermant-metrics/metrics-plugin/src/main/java/com/huawei/metrics/interceptor/AbstractHttpInterceptor.java b/sermant-plugins/sermant-metrics/metrics-plugin/src/main/java/com/huawei/metrics/interceptor/AbstractHttpInterceptor.java
new file mode 100644
index 0000000000..25392cdcad
--- /dev/null
+++ b/sermant-plugins/sermant-metrics/metrics-plugin/src/main/java/com/huawei/metrics/interceptor/AbstractHttpInterceptor.java
@@ -0,0 +1,107 @@
+/*
+ * Copyright (C) 2023-2023 Huawei Technologies Co., Ltd. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.huawei.metrics.interceptor;
+
+import com.huawei.metrics.common.Constants;
+import com.huawei.metrics.common.ResultType;
+import com.huawei.metrics.entity.MetricsRpcInfo;
+import com.huawei.metrics.util.ResultJudgmentUtil;
+
+import com.huaweicloud.sermant.core.plugin.agent.entity.ExecuteContext;
+import com.huaweicloud.sermant.core.plugin.agent.interceptor.Interceptor;
+import com.huaweicloud.sermant.core.utils.StringUtils;
+
+import java.net.InetAddress;
+import java.net.URL;
+import java.net.UnknownHostException;
+
+/**
+ * Http拦截器父类
+ *
+ * @author zhp
+ * @since 2023-12-15
+ */
+public abstract class AbstractHttpInterceptor implements Interceptor {
+ @Override
+ public ExecuteContext after(ExecuteContext context) throws Exception {
+ return collectMetrics(context);
+ }
+
+ /**
+ * 采集指标信息
+ *
+ * @param context 上下文信息
+ * @return ExecuteContext 上下文信息
+ * @throws Exception 指标采集异常
+ */
+ public abstract ExecuteContext collectMetrics(ExecuteContext context) throws Exception;
+
+ @Override
+ public ExecuteContext onThrow(ExecuteContext context) throws Exception {
+ return collectMetrics(context);
+ }
+
+ /**
+ * 初始化指标信息
+ *
+ * @param url 链接信息
+ * @param enableSsl 是否开启SSL加密
+ * @param latency 时延
+ * @param statusCode 结果编码
+ * @return 指标数据
+ * @throws UnknownHostException 未知域名异常
+ */
+ public MetricsRpcInfo initMetricsInfo(URL url, boolean enableSsl, long latency, int statusCode)
+ throws UnknownHostException {
+ MetricsRpcInfo metricsRpcInfo = new MetricsRpcInfo();
+ metricsRpcInfo.setClientIp(InetAddress.getLocalHost().getHostAddress());
+ metricsRpcInfo.setServerIp(url.getHost());
+ metricsRpcInfo.setServerPort(StringUtils.getString(url.getPort()));
+ metricsRpcInfo.setProtocol(url.getProtocol());
+ metricsRpcInfo.setEnableSsl(enableSsl);
+ metricsRpcInfo.setL7Role(Constants.CLIENT_ROLE);
+ metricsRpcInfo.setL4Role(Constants.TCP_PROTOCOL + Constants.CONNECT + metricsRpcInfo.getL7Role());
+ metricsRpcInfo.setUrl(url.getPath());
+ metricsRpcInfo.getReqCount().getAndIncrement();
+ metricsRpcInfo.getResponseCount().getAndIncrement();
+ metricsRpcInfo.getLatencyList().add(latency);
+ metricsRpcInfo.getSumLatency().getAndAdd(latency);
+ fillErrorCountInfo(statusCode, metricsRpcInfo);
+ return metricsRpcInfo;
+ }
+
+ /**
+ * 填充错误数量
+ *
+ * @param statusCode 状态编码
+ * @param metricsRpcInfo 指标数据
+ */
+ public void fillErrorCountInfo(int statusCode, MetricsRpcInfo metricsRpcInfo) {
+ int value = ResultJudgmentUtil.judgeHttpResult(statusCode);
+ if (value == ResultType.SUCCESS.getValue()) {
+ return;
+ }
+ metricsRpcInfo.getReqErrorCount().getAndIncrement();
+ if (value == ResultType.CLIENT_ERROR.getValue()) {
+ metricsRpcInfo.getClientErrorCount().getAndIncrement();
+ return;
+ }
+ if (value == ResultType.SERVER_ERROR.getValue()) {
+ metricsRpcInfo.getServerErrorCount().getAndIncrement();
+ }
+ }
+}
diff --git a/sermant-plugins/sermant-metrics/metrics-plugin/src/main/java/com/huawei/metrics/interceptor/alibaba/ExchangeCodecInterceptor.java b/sermant-plugins/sermant-metrics/metrics-plugin/src/main/java/com/huawei/metrics/interceptor/dubbo/alibaba/ExchangeCodecInterceptor.java
similarity index 50%
rename from sermant-plugins/sermant-metrics/metrics-plugin/src/main/java/com/huawei/metrics/interceptor/alibaba/ExchangeCodecInterceptor.java
rename to sermant-plugins/sermant-metrics/metrics-plugin/src/main/java/com/huawei/metrics/interceptor/dubbo/alibaba/ExchangeCodecInterceptor.java
index 596ef3be1b..467b74228d 100644
--- a/sermant-plugins/sermant-metrics/metrics-plugin/src/main/java/com/huawei/metrics/interceptor/alibaba/ExchangeCodecInterceptor.java
+++ b/sermant-plugins/sermant-metrics/metrics-plugin/src/main/java/com/huawei/metrics/interceptor/dubbo/alibaba/ExchangeCodecInterceptor.java
@@ -14,17 +14,17 @@
* limitations under the License.
*/
-package com.huawei.metrics.interceptor.alibaba;
+package com.huawei.metrics.interceptor.dubbo.alibaba;
import com.huawei.metrics.common.Constants;
-import com.huawei.metrics.entity.MetricsLinkInfo;
+import com.huawei.metrics.entity.MetricsRpcInfo;
import com.huawei.metrics.interceptor.AbstractCodecInterceptor;
import com.huaweicloud.sermant.core.plugin.agent.entity.ExecuteContext;
import com.alibaba.dubbo.common.URL;
import com.alibaba.dubbo.remoting.Channel;
-import com.alibaba.dubbo.remoting.buffer.ChannelBuffer;
+import com.alibaba.dubbo.remoting.exchange.Response;
/**
* dubbo报文转码、解码拦截器
@@ -33,42 +33,33 @@
* @since 2023-10-17
*/
public class ExchangeCodecInterceptor extends AbstractCodecInterceptor {
- private static final int PARAM_COUNT = 2;
-
- @Override
- public boolean isValid(ExecuteContext context) {
- Object[] arguments = context.getArguments();
- if (arguments == null || arguments.length < PARAM_COUNT) {
- return false;
- }
- if (!(arguments[0] instanceof Channel)) {
- return false;
- }
- if (!(arguments[1] instanceof ChannelBuffer)) {
- return false;
- }
- return ((Channel) arguments[0]).getUrl() != null;
- }
-
- @Override
- public MetricsLinkInfo initLinkInfo(ExecuteContext context) {
+ /**
+ * 初始化指标信息
+ *
+ * @param context 上下文信息
+ * @return 连接信息
+ */
+ private MetricsRpcInfo initRpcInfo(ExecuteContext context) {
Channel channel = (Channel) context.getArguments()[0];
URL url = channel.getUrl();
boolean sslEnable = Boolean.parseBoolean(url.getParameter(Constants.SSL_ENABLE));
- return initLinkInfo(channel.getLocalAddress(), channel.getRemoteAddress(),
+ MetricsRpcInfo metricsRpcInfo = initRpcInfo(channel.getLocalAddress(), channel.getRemoteAddress(),
url.getParameter(Constants.SIDE_KEY), sslEnable, url.getProtocol());
+ metricsRpcInfo.setUrl(url.getPath());
+ return metricsRpcInfo;
}
@Override
- public void initIndexInfo(ExecuteContext context) {
- ChannelBuffer buffer = (ChannelBuffer) context.getArguments()[1];
- context.setLocalFieldValue(Constants.WRITE_INDEX_KEY, buffer.writerIndex());
- context.setLocalFieldValue(Constants.READ_INDEX_KEY, buffer.readerIndex());
- }
-
- @Override
- protected void fillMessageInfo(ExecuteContext context) {
- ChannelBuffer buffer = (ChannelBuffer) context.getArguments()[1];
- fillMessageInfo(buffer.writerIndex(), buffer.readerIndex(), context);
+ public ExecuteContext after(ExecuteContext context) {
+ if (!(context.getResult() instanceof Response)) {
+ return context;
+ }
+ Response response = (Response) context.getResult();
+ if (response.isHeartbeat() || response.isEvent()) {
+ return context;
+ }
+ MetricsRpcInfo metricsRpcInfo = initRpcInfo(context);
+ fillErrorCountInfo(response.getStatus(), metricsRpcInfo);
+ return context;
}
}
diff --git a/sermant-plugins/sermant-metrics/metrics-plugin/src/main/java/com/huawei/metrics/interceptor/alibaba/MonitorFilterInterceptor.java b/sermant-plugins/sermant-metrics/metrics-plugin/src/main/java/com/huawei/metrics/interceptor/dubbo/alibaba/MonitorFilterInterceptor.java
similarity index 87%
rename from sermant-plugins/sermant-metrics/metrics-plugin/src/main/java/com/huawei/metrics/interceptor/alibaba/MonitorFilterInterceptor.java
rename to sermant-plugins/sermant-metrics/metrics-plugin/src/main/java/com/huawei/metrics/interceptor/dubbo/alibaba/MonitorFilterInterceptor.java
index c0afcbffeb..70d94883df 100644
--- a/sermant-plugins/sermant-metrics/metrics-plugin/src/main/java/com/huawei/metrics/interceptor/alibaba/MonitorFilterInterceptor.java
+++ b/sermant-plugins/sermant-metrics/metrics-plugin/src/main/java/com/huawei/metrics/interceptor/dubbo/alibaba/MonitorFilterInterceptor.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.huawei.metrics.interceptor.alibaba;
+package com.huawei.metrics.interceptor.dubbo.alibaba;
import com.huawei.metrics.common.Constants;
import com.huawei.metrics.entity.MetricsRpcInfo;
@@ -44,7 +44,9 @@ public MetricsRpcInfo initRpcInfo(ExecuteContext context) {
RpcContext rpcContext = RpcContext.getContext();
URL url = rpcContext.getUrl();
boolean sslEnable = Boolean.parseBoolean(url.getParameter(Constants.SSL_ENABLE));
- return initRpcInfo(rpcContext.getLocalAddress(), rpcContext.getRemoteAddress(),
+ MetricsRpcInfo metricsRpcInfo = initRpcInfo(rpcContext.getLocalAddress(), rpcContext.getRemoteAddress(),
url.getParameter(Constants.SIDE_KEY), sslEnable, url.getProtocol());
+ metricsRpcInfo.setUrl(url.getPath());
+ return metricsRpcInfo;
}
}
diff --git a/sermant-plugins/sermant-metrics/metrics-plugin/src/main/java/com/huawei/metrics/interceptor/apache/ExchangeCodecInterceptor.java b/sermant-plugins/sermant-metrics/metrics-plugin/src/main/java/com/huawei/metrics/interceptor/dubbo/apache/ExchangeCodecInterceptor.java
similarity index 50%
rename from sermant-plugins/sermant-metrics/metrics-plugin/src/main/java/com/huawei/metrics/interceptor/apache/ExchangeCodecInterceptor.java
rename to sermant-plugins/sermant-metrics/metrics-plugin/src/main/java/com/huawei/metrics/interceptor/dubbo/apache/ExchangeCodecInterceptor.java
index 9004828bab..0ff576a0f4 100644
--- a/sermant-plugins/sermant-metrics/metrics-plugin/src/main/java/com/huawei/metrics/interceptor/apache/ExchangeCodecInterceptor.java
+++ b/sermant-plugins/sermant-metrics/metrics-plugin/src/main/java/com/huawei/metrics/interceptor/dubbo/apache/ExchangeCodecInterceptor.java
@@ -14,17 +14,17 @@
* limitations under the License.
*/
-package com.huawei.metrics.interceptor.apache;
+package com.huawei.metrics.interceptor.dubbo.apache;
import com.huawei.metrics.common.Constants;
-import com.huawei.metrics.entity.MetricsLinkInfo;
+import com.huawei.metrics.entity.MetricsRpcInfo;
import com.huawei.metrics.interceptor.AbstractCodecInterceptor;
import com.huaweicloud.sermant.core.plugin.agent.entity.ExecuteContext;
import org.apache.dubbo.common.URL;
import org.apache.dubbo.remoting.Channel;
-import org.apache.dubbo.remoting.buffer.ChannelBuffer;
+import org.apache.dubbo.remoting.exchange.Response;
/**
* dubbo报文转码、解码拦截器
@@ -33,42 +33,33 @@
* @since 2023-10-17
*/
public class ExchangeCodecInterceptor extends AbstractCodecInterceptor {
- private static final int PARAM_COUNT = 2;
-
- @Override
- public boolean isValid(ExecuteContext context) {
- Object[] arguments = context.getArguments();
- if (arguments == null || arguments.length < PARAM_COUNT) {
- return false;
- }
- if (!(arguments[0] instanceof Channel)) {
- return false;
- }
- if (!(arguments[1] instanceof ChannelBuffer)) {
- return false;
- }
- return ((Channel) arguments[0]).getUrl() != null;
- }
-
- @Override
- public MetricsLinkInfo initLinkInfo(ExecuteContext context) {
+ /**
+ * 初始化指标信息
+ *
+ * @param context 上下文信息
+ * @return 连接信息
+ */
+ private MetricsRpcInfo initRpcInfo(ExecuteContext context) {
Channel channel = (Channel) context.getArguments()[0];
URL url = channel.getUrl();
boolean sslEnable = Boolean.parseBoolean(url.getParameter(Constants.SSL_ENABLE));
- return initLinkInfo(channel.getLocalAddress(), channel.getRemoteAddress(),
+ MetricsRpcInfo metricsRpcInfo = initRpcInfo(channel.getLocalAddress(), channel.getRemoteAddress(),
url.getParameter(Constants.SIDE_KEY), sslEnable, url.getProtocol());
+ metricsRpcInfo.setUrl(url.getPath());
+ return metricsRpcInfo;
}
@Override
- public void initIndexInfo(ExecuteContext context) {
- ChannelBuffer buffer = (ChannelBuffer) context.getArguments()[1];
- context.setLocalFieldValue(Constants.WRITE_INDEX_KEY, buffer.writerIndex());
- context.setLocalFieldValue(Constants.READ_INDEX_KEY, buffer.readerIndex());
- }
-
- @Override
- protected void fillMessageInfo(ExecuteContext context) {
- ChannelBuffer buffer = (ChannelBuffer) context.getArguments()[1];
- fillMessageInfo(buffer.writerIndex(), buffer.readerIndex(), context);
+ public ExecuteContext after(ExecuteContext context) {
+ if (!(context.getResult() instanceof Response)) {
+ return context;
+ }
+ Response response = (Response) context.getResult();
+ if (response.isHeartbeat() || response.isEvent()) {
+ return context;
+ }
+ MetricsRpcInfo metricsRpcInfo = initRpcInfo(context);
+ fillErrorCountInfo(response.getStatus(), metricsRpcInfo);
+ return context;
}
}
diff --git a/sermant-plugins/sermant-metrics/metrics-plugin/src/main/java/com/huawei/metrics/interceptor/apache/MonitorFilterInterceptor.java b/sermant-plugins/sermant-metrics/metrics-plugin/src/main/java/com/huawei/metrics/interceptor/dubbo/apache/MonitorFilterInterceptor.java
similarity index 87%
rename from sermant-plugins/sermant-metrics/metrics-plugin/src/main/java/com/huawei/metrics/interceptor/apache/MonitorFilterInterceptor.java
rename to sermant-plugins/sermant-metrics/metrics-plugin/src/main/java/com/huawei/metrics/interceptor/dubbo/apache/MonitorFilterInterceptor.java
index 70aa2efc5f..09d2e71eb5 100644
--- a/sermant-plugins/sermant-metrics/metrics-plugin/src/main/java/com/huawei/metrics/interceptor/apache/MonitorFilterInterceptor.java
+++ b/sermant-plugins/sermant-metrics/metrics-plugin/src/main/java/com/huawei/metrics/interceptor/dubbo/apache/MonitorFilterInterceptor.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.huawei.metrics.interceptor.apache;
+package com.huawei.metrics.interceptor.dubbo.apache;
import com.huawei.metrics.common.Constants;
import com.huawei.metrics.entity.MetricsRpcInfo;
@@ -44,7 +44,9 @@ public MetricsRpcInfo initRpcInfo(ExecuteContext context) {
RpcContext rpcContext = RpcContext.getContext();
URL url = rpcContext.getUrl();
boolean sslEnable = Boolean.parseBoolean(url.getParameter(Constants.SSL_ENABLE));
- return initRpcInfo(rpcContext.getLocalAddress(), rpcContext.getRemoteAddress(),
+ MetricsRpcInfo metricsRpcInfo = initRpcInfo(rpcContext.getLocalAddress(), rpcContext.getRemoteAddress(),
url.getParameter(Constants.SIDE_KEY), sslEnable, url.getProtocol());
+ metricsRpcInfo.setUrl(url.getPath());
+ return metricsRpcInfo;
}
}
diff --git a/sermant-plugins/sermant-metrics/metrics-plugin/src/main/java/com/huawei/metrics/interceptor/httpclient/HttpClientInterceptor.java b/sermant-plugins/sermant-metrics/metrics-plugin/src/main/java/com/huawei/metrics/interceptor/httpclient/HttpClientInterceptor.java
new file mode 100644
index 0000000000..5795406f02
--- /dev/null
+++ b/sermant-plugins/sermant-metrics/metrics-plugin/src/main/java/com/huawei/metrics/interceptor/httpclient/HttpClientInterceptor.java
@@ -0,0 +1,59 @@
+/*
+ * Copyright (C) 2023-2023 Huawei Technologies Co., Ltd. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.huawei.metrics.interceptor.httpclient;
+
+import com.huawei.metrics.common.Constants;
+import com.huawei.metrics.entity.MetricsRpcInfo;
+import com.huawei.metrics.interceptor.AbstractHttpInterceptor;
+import com.huawei.metrics.manager.MetricsManager;
+
+import com.huaweicloud.sermant.core.plugin.agent.entity.ExecuteContext;
+import com.huaweicloud.sermant.core.utils.StringUtils;
+
+import org.apache.http.HttpHost;
+import org.apache.http.HttpRequest;
+import org.apache.http.HttpResponse;
+
+import java.net.URI;
+
+/**
+ * HttpClient请求发送增强器
+ *
+ * @author zhp
+ * @since 2023-12-15
+ */
+public class HttpClientInterceptor extends AbstractHttpInterceptor {
+ @Override
+ public ExecuteContext before(ExecuteContext context) {
+ context.setLocalFieldValue(Constants.START_TIME_KEY, System.nanoTime());
+ return context;
+ }
+
+ @Override
+ public ExecuteContext collectMetrics(ExecuteContext context) throws Exception {
+ HttpHost httpHost = (HttpHost) context.getArguments()[0];
+ HttpRequest httpRequest = (HttpRequest) context.getArguments()[1];
+ URI uri = new URI(httpRequest.getRequestLine().getUri());
+ long latency = System.nanoTime() - (Long) context.getLocalFieldValue(Constants.START_TIME_KEY);
+ HttpResponse httpResponse = (HttpResponse) context.getResult();
+ int statusCode = httpResponse.getStatusLine().getStatusCode();
+ boolean enableSsl = StringUtils.equals(httpHost.getSchemeName(), Constants.HTTPS_PROTOCOL);
+ MetricsRpcInfo metricsRpcInfo = initMetricsInfo(uri.toURL(), enableSsl, latency, statusCode);
+ MetricsManager.saveRpcInfo(metricsRpcInfo);
+ return context;
+ }
+}
diff --git a/sermant-plugins/sermant-metrics/metrics-plugin/src/main/java/com/huawei/metrics/interceptor/httpurlconnection/ConnectorInterceptor.java b/sermant-plugins/sermant-metrics/metrics-plugin/src/main/java/com/huawei/metrics/interceptor/httpurlconnection/ConnectorInterceptor.java
new file mode 100644
index 0000000000..d3d4e8a55a
--- /dev/null
+++ b/sermant-plugins/sermant-metrics/metrics-plugin/src/main/java/com/huawei/metrics/interceptor/httpurlconnection/ConnectorInterceptor.java
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2023-2023 Huawei Technologies Co., Ltd. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.huawei.metrics.interceptor.httpurlconnection;
+
+import com.huawei.metrics.util.HttpUrlConnectionUtil;
+
+import com.huaweicloud.sermant.core.plugin.agent.entity.ExecuteContext;
+import com.huaweicloud.sermant.core.plugin.agent.interceptor.Interceptor;
+
+/**
+ * HttpUrlConnection连接方法增强器
+ *
+ * @author zhp
+ * @since 2023-12-15
+ */
+public class ConnectorInterceptor implements Interceptor {
+ @Override
+ public ExecuteContext before(ExecuteContext context) {
+ // 设置请求开始时间,链接断开时用于计算时延
+ HttpUrlConnectionUtil.setValue(System.nanoTime());
+ return context;
+ }
+
+ @Override
+ public ExecuteContext after(ExecuteContext context) {
+ return context;
+ }
+
+ @Override
+ public ExecuteContext onThrow(ExecuteContext context) {
+ return context;
+ }
+}
diff --git a/sermant-plugins/sermant-metrics/metrics-plugin/src/main/java/com/huawei/metrics/interceptor/httpurlconnection/DisconnectorInterceptor.java b/sermant-plugins/sermant-metrics/metrics-plugin/src/main/java/com/huawei/metrics/interceptor/httpurlconnection/DisconnectorInterceptor.java
new file mode 100644
index 0000000000..0a737839d8
--- /dev/null
+++ b/sermant-plugins/sermant-metrics/metrics-plugin/src/main/java/com/huawei/metrics/interceptor/httpurlconnection/DisconnectorInterceptor.java
@@ -0,0 +1,57 @@
+/*
+ * Copyright (C) 2023-2023 Huawei Technologies Co., Ltd. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.huawei.metrics.interceptor.httpurlconnection;
+
+import com.huawei.metrics.common.Constants;
+import com.huawei.metrics.entity.MetricsRpcInfo;
+import com.huawei.metrics.interceptor.AbstractHttpInterceptor;
+import com.huawei.metrics.manager.MetricsManager;
+import com.huawei.metrics.util.HttpUrlConnectionUtil;
+
+import com.huaweicloud.sermant.core.plugin.agent.entity.ExecuteContext;
+import com.huaweicloud.sermant.core.utils.StringUtils;
+
+import java.net.HttpURLConnection;
+import java.net.URL;
+
+/**
+ * 连接断开方法增强器
+ *
+ * @author zhp
+ * @since 2023-12-15
+ */
+public class DisconnectorInterceptor extends AbstractHttpInterceptor {
+ @Override
+ public ExecuteContext before(ExecuteContext context) {
+ return context;
+ }
+
+ @Override
+ public ExecuteContext collectMetrics(ExecuteContext context) throws Exception {
+ if (HttpUrlConnectionUtil.getValue() == null) {
+ return context;
+ }
+ HttpURLConnection httpUrlConnection = (HttpURLConnection) context.getObject();
+ URL url = httpUrlConnection.getURL();
+ boolean enableSsl = StringUtils.equals(url.getProtocol(), Constants.HTTPS_PROTOCOL);
+ long latency = System.nanoTime() - HttpUrlConnectionUtil.getValue();
+ MetricsRpcInfo metricsRpcInfo = initMetricsInfo(url, enableSsl, latency, httpUrlConnection.getResponseCode());
+ MetricsManager.saveRpcInfo(metricsRpcInfo);
+ HttpUrlConnectionUtil.remove();
+ return context;
+ }
+}
diff --git a/sermant-plugins/sermant-metrics/metrics-plugin/src/main/java/com/huawei/metrics/interceptor/okhttp/CallInterceptor.java b/sermant-plugins/sermant-metrics/metrics-plugin/src/main/java/com/huawei/metrics/interceptor/okhttp/CallInterceptor.java
new file mode 100644
index 0000000000..093e6c1305
--- /dev/null
+++ b/sermant-plugins/sermant-metrics/metrics-plugin/src/main/java/com/huawei/metrics/interceptor/okhttp/CallInterceptor.java
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 2023-2023 Huawei Technologies Co., Ltd. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.huawei.metrics.interceptor.okhttp;
+
+import com.huawei.metrics.common.Constants;
+import com.huawei.metrics.entity.MetricsRpcInfo;
+import com.huawei.metrics.interceptor.AbstractHttpInterceptor;
+import com.huawei.metrics.manager.MetricsManager;
+
+import com.huaweicloud.sermant.core.plugin.agent.entity.ExecuteContext;
+
+import com.squareup.okhttp.Request;
+import com.squareup.okhttp.Response;
+
+/**
+ * OKHttp请求发送增强器
+ *
+ * @author zhp
+ * @since 2023-12-15
+ */
+public class CallInterceptor extends AbstractHttpInterceptor {
+ @Override
+ public ExecuteContext before(ExecuteContext context) {
+ context.setLocalFieldValue(Constants.START_TIME_KEY, System.nanoTime());
+ return context;
+ }
+
+ @Override
+ public ExecuteContext collectMetrics(ExecuteContext context) throws Exception {
+ Response response = (Response) context.getResult();
+ Request request = response.request();
+ long latency = System.nanoTime() - (Long) context.getLocalFieldValue(Constants.START_TIME_KEY);
+ MetricsRpcInfo metricsRpcInfo = initMetricsInfo(request.url(), request.isHttps(), latency, response.code());
+ MetricsManager.saveRpcInfo(metricsRpcInfo);
+ return context;
+ }
+}
diff --git a/sermant-plugins/sermant-metrics/metrics-plugin/src/main/java/com/huawei/metrics/interceptor/okhttp3/CallInterceptor.java b/sermant-plugins/sermant-metrics/metrics-plugin/src/main/java/com/huawei/metrics/interceptor/okhttp3/CallInterceptor.java
new file mode 100644
index 0000000000..130ced297c
--- /dev/null
+++ b/sermant-plugins/sermant-metrics/metrics-plugin/src/main/java/com/huawei/metrics/interceptor/okhttp3/CallInterceptor.java
@@ -0,0 +1,56 @@
+/*
+ * Copyright (C) 2023-2023 Huawei Technologies Co., Ltd. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.huawei.metrics.interceptor.okhttp3;
+
+import com.huawei.metrics.common.Constants;
+import com.huawei.metrics.entity.MetricsRpcInfo;
+import com.huawei.metrics.interceptor.AbstractHttpInterceptor;
+import com.huawei.metrics.manager.MetricsManager;
+
+import com.huaweicloud.sermant.core.plugin.agent.entity.ExecuteContext;
+
+import okhttp3.Call;
+import okhttp3.Request;
+import okhttp3.Response;
+
+import java.net.URL;
+
+/**
+ * OKHttp3请求发送增强器
+ *
+ * @author zhp
+ * @since 2023-12-15
+ */
+public class CallInterceptor extends AbstractHttpInterceptor {
+ @Override
+ public ExecuteContext before(ExecuteContext context) {
+ context.setLocalFieldValue(Constants.START_TIME_KEY, System.nanoTime());
+ return context;
+ }
+
+ @Override
+ public ExecuteContext collectMetrics(ExecuteContext context) throws Exception {
+ Call realCall = (Call) context.getObject();
+ Request request = realCall.request();
+ URL url = request.url().url();
+ long latency = System.nanoTime() - (Long) context.getLocalFieldValue(Constants.START_TIME_KEY);
+ Response response = (Response) context.getResult();
+ MetricsRpcInfo metricsRpcInfo = initMetricsInfo(url, request.url().isHttps(), latency, response.code());
+ MetricsManager.saveRpcInfo(metricsRpcInfo);
+ return context;
+ }
+}
diff --git a/sermant-plugins/sermant-metrics/metrics-plugin/src/main/java/com/huawei/metrics/interceptor/servlet/HttpServletInterceptor.java b/sermant-plugins/sermant-metrics/metrics-plugin/src/main/java/com/huawei/metrics/interceptor/servlet/HttpServletInterceptor.java
new file mode 100644
index 0000000000..e83db99a79
--- /dev/null
+++ b/sermant-plugins/sermant-metrics/metrics-plugin/src/main/java/com/huawei/metrics/interceptor/servlet/HttpServletInterceptor.java
@@ -0,0 +1,78 @@
+/*
+ * Copyright (C) 2023-2023 Huawei Technologies Co., Ltd. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.huawei.metrics.interceptor.servlet;
+
+import com.huawei.metrics.common.Constants;
+import com.huawei.metrics.entity.MetricsRpcInfo;
+import com.huawei.metrics.interceptor.AbstractHttpInterceptor;
+import com.huawei.metrics.manager.MetricsManager;
+
+import com.huaweicloud.sermant.core.plugin.agent.entity.ExecuteContext;
+import com.huaweicloud.sermant.core.utils.StringUtils;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+/**
+ * HttpServlet服务调用拦截声明
+ *
+ * @author zhp
+ * @since 2023-12-15
+ */
+public class HttpServletInterceptor extends AbstractHttpInterceptor {
+ @Override
+ public ExecuteContext before(ExecuteContext context) {
+ context.setLocalFieldValue(Constants.START_TIME_KEY, System.nanoTime());
+ return context;
+ }
+
+ @Override
+ public ExecuteContext collectMetrics(ExecuteContext context) {
+ HttpServletRequest req = (HttpServletRequest) context.getArguments()[0];
+ long latency = System.nanoTime() - (Long) context.getLocalFieldValue(Constants.START_TIME_KEY);
+ HttpServletResponse resp = (HttpServletResponse) context.getArguments()[1];
+ MetricsRpcInfo metricsRpcInfo = initMetricsInfo(req, latency, resp.getStatus());
+ MetricsManager.saveRpcInfo(metricsRpcInfo);
+ return context;
+ }
+
+ /**
+ * 初始化指标信息
+ *
+ * @param req 请求数据
+ * @param latency 时延
+ * @param status 请求状态编码
+ * @return Rpc指标数据
+ */
+ private MetricsRpcInfo initMetricsInfo(HttpServletRequest req, long latency, int status) {
+ MetricsRpcInfo metricsRpcInfo = new MetricsRpcInfo();
+ metricsRpcInfo.setClientIp(req.getRemoteHost());
+ metricsRpcInfo.setServerIp(req.getLocalAddr());
+ metricsRpcInfo.setServerPort(StringUtils.getString(req.getLocalPort()));
+ metricsRpcInfo.setProtocol(req.getScheme());
+ metricsRpcInfo.setEnableSsl(Constants.HTTPS_PROTOCOL.equals(req.getScheme()));
+ metricsRpcInfo.setL7Role(Constants.SERVER_ROLE);
+ metricsRpcInfo.setL4Role(Constants.TCP_PROTOCOL + Constants.CONNECT + metricsRpcInfo.getL7Role());
+ metricsRpcInfo.setUrl(req.getRequestURI());
+ metricsRpcInfo.getReqCount().getAndIncrement();
+ metricsRpcInfo.getLatencyList().add(latency);
+ metricsRpcInfo.getSumLatency().getAndAdd(latency);
+ metricsRpcInfo.getResponseCount().getAndIncrement();
+ fillErrorCountInfo(status, metricsRpcInfo);
+ return metricsRpcInfo;
+ }
+}
diff --git a/sermant-plugins/sermant-metrics/metrics-plugin/src/main/java/com/huawei/metrics/manager/MetricsManager.java b/sermant-plugins/sermant-metrics/metrics-plugin/src/main/java/com/huawei/metrics/manager/MetricsManager.java
index d2010d6a04..c842c631a3 100644
--- a/sermant-plugins/sermant-metrics/metrics-plugin/src/main/java/com/huawei/metrics/manager/MetricsManager.java
+++ b/sermant-plugins/sermant-metrics/metrics-plugin/src/main/java/com/huawei/metrics/manager/MetricsManager.java
@@ -16,7 +16,8 @@
package com.huawei.metrics.manager;
-import com.huawei.metrics.entity.MetricsLinkInfo;
+import com.huawei.metrics.common.Constants;
+import com.huawei.metrics.entity.MetricsInfo;
import com.huawei.metrics.entity.MetricsRpcInfo;
import java.util.Map;
@@ -29,48 +30,59 @@
* @since 2023-10-17
*/
public class MetricsManager {
- private static final Map METRICS_LINK_INFO_MAP = new ConcurrentHashMap<>();
-
private static final Map METRICS_RPC_INFO_MAP = new ConcurrentHashMap<>();
private MetricsManager() {
}
/**
- * 获取全部连接信息
+ * 获取全部RPC信息
*
* @return 连接信息
*/
- public static Map getLinkInfoMap() {
- return METRICS_LINK_INFO_MAP;
+ public static Map getRpcInfoMap() {
+ return METRICS_RPC_INFO_MAP;
}
/**
- * 获取全部RPC信息
+ * 保存RPC信息
*
- * @return 连接信息
+ * @param metricsRpcInfo RPC信息
*/
- public static Map getRpcInfoMap() {
- return METRICS_RPC_INFO_MAP;
+ public static void saveRpcInfo(MetricsRpcInfo metricsRpcInfo) {
+ String key = getKey(metricsRpcInfo);
+ MetricsRpcInfo rpcInfo = METRICS_RPC_INFO_MAP.computeIfAbsent(key, s -> metricsRpcInfo);
+ if (rpcInfo != metricsRpcInfo) {
+ rpcInfo.getReqCount().getAndAdd(metricsRpcInfo.getReqCount().get());
+ rpcInfo.getResponseCount().getAndAdd(metricsRpcInfo.getResponseCount().get());
+ rpcInfo.getSumLatency().getAndAdd(metricsRpcInfo.getSumLatency().get());
+ rpcInfo.getLatencyList().addAll(metricsRpcInfo.getLatencyList());
+ rpcInfo.getReqErrorCount().getAndAdd(metricsRpcInfo.getReqErrorCount().get());
+ }
}
/**
- * 获取连接信息
+ * 获取Map的key
*
- * @param key MAP的密钥信息
- * @return 连接信息
+ * @param metricsInfo 指标信息
+ * @return key
*/
- public static MetricsLinkInfo getLinkInfo(String key) {
- return METRICS_LINK_INFO_MAP.computeIfAbsent(key, s -> new MetricsLinkInfo());
+ public static String getKey(MetricsInfo metricsInfo) {
+ return metricsInfo.getClientIp() + Constants.CONNECT + metricsInfo.getServerIp() + Constants.CONNECT
+ + metricsInfo.getServerPort() + Constants.CONNECT + metricsInfo.getProtocol() + Constants.CONNECT
+ + metricsInfo.getL4Role() + Constants.CONNECT + metricsInfo.isEnableSsl() + Constants.CONNECT
+ + metricsInfo.getUrl();
}
/**
- * 获取RPC信息
+ * 获取Map的key
*
- * @param key MAP的密钥信息
- * @return RPC信息
+ * @param metricsInfo 指标信息
+ * @return key
*/
- public static MetricsRpcInfo getRpcInfo(String key) {
- return METRICS_RPC_INFO_MAP.computeIfAbsent(key, s -> new MetricsRpcInfo());
+ public static String getRpcKey(MetricsInfo metricsInfo) {
+ return metricsInfo.getClientIp() + Constants.CONNECT + metricsInfo.getServerIp() + Constants.CONNECT
+ + metricsInfo.getServerPort() + Constants.CONNECT + metricsInfo.getProtocol() + Constants.CONNECT
+ + metricsInfo.getL4Role() + Constants.CONNECT + metricsInfo.isEnableSsl();
}
}
diff --git a/sermant-plugins/sermant-metrics/metrics-plugin/src/main/java/com/huawei/metrics/util/HttpUrlConnectionUtil.java b/sermant-plugins/sermant-metrics/metrics-plugin/src/main/java/com/huawei/metrics/util/HttpUrlConnectionUtil.java
new file mode 100644
index 0000000000..a7b9137f6c
--- /dev/null
+++ b/sermant-plugins/sermant-metrics/metrics-plugin/src/main/java/com/huawei/metrics/util/HttpUrlConnectionUtil.java
@@ -0,0 +1,61 @@
+/*
+ * Copyright (C) 2023-2023 Huawei Technologies Co., Ltd. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.huawei.metrics.util;
+
+/**
+ * HttpUrlConnection工具类,用于线程数据传递
+ *
+ * @author zhp
+ * @since 2023-12-15
+ */
+public class HttpUrlConnectionUtil {
+ /**
+ * 线程变量存储,主要存储请求开始时间
+ */
+ private static final ThreadLocal START_TIME_THREAD_LOCAL = new InheritableThreadLocal<>();
+
+ /**
+ * 构造函数
+ */
+ private HttpUrlConnectionUtil() {
+ }
+
+ /**
+ * 设置线程变量
+ *
+ * @param value 变量信息
+ */
+ public static void setValue(Long value) {
+ START_TIME_THREAD_LOCAL.set(value);
+ }
+
+ /**
+ * 获取线程变量
+ *
+ * @return 变量信息
+ */
+ public static Long getValue() {
+ return START_TIME_THREAD_LOCAL.get();
+ }
+
+ /**
+ * 删除线程变量信息
+ */
+ public static void remove() {
+ START_TIME_THREAD_LOCAL.remove();
+ }
+}
diff --git a/sermant-plugins/sermant-metrics/metrics-plugin/src/main/java/com/huawei/metrics/util/ResultJudgmentUtil.java b/sermant-plugins/sermant-metrics/metrics-plugin/src/main/java/com/huawei/metrics/util/ResultJudgmentUtil.java
new file mode 100644
index 0000000000..44045823d0
--- /dev/null
+++ b/sermant-plugins/sermant-metrics/metrics-plugin/src/main/java/com/huawei/metrics/util/ResultJudgmentUtil.java
@@ -0,0 +1,91 @@
+/*
+ * Copyright (C) 2023-2023 Huawei Technologies Co., Ltd. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.huawei.metrics.util;
+
+import com.huawei.metrics.common.Constants;
+import com.huawei.metrics.common.ResultType;
+
+/**
+ * 结果判断工具类
+ *
+ * @author zhp
+ * @since 2023-12-15
+ */
+public class ResultJudgmentUtil {
+ private ResultJudgmentUtil() {
+ }
+
+ /**
+ * 判断HTTP的请求结果
+ *
+ * @param statusCode 结果编码
+ * @return 结果类型
+ */
+ public static int judgeHttpResult(int statusCode) {
+ if (statusCode <= Constants.MAX_SUCCESS_CODE) {
+ return ResultType.SUCCESS.getValue();
+ }
+ if (statusCode <= Constants.MAX_CLIENT_ERROR_CODE) {
+ return ResultType.CLIENT_ERROR.getValue();
+ }
+ if (statusCode <= Constants.MAX_SERVER_ERROR_CODE) {
+ return ResultType.SERVER_ERROR.getValue();
+ }
+ return ResultType.ERROR.getValue();
+ }
+
+ /**
+ * 判断Dubbo的请求结果
+ *
+ * @param status 结果编码
+ * @return 结果类型
+ */
+ public static int judgeDubboResult(byte status) {
+ if (status == Constants.HTTP_OK) {
+ return ResultType.SUCCESS.getValue();
+ }
+ for (int i = 0; i < Constants.HTTP_CLIENT_ERROR.length; i++) {
+ if (status == Constants.HTTP_CLIENT_ERROR[i]) {
+ return ResultType.CLIENT_ERROR.getValue();
+ }
+ }
+ for (int i = 0; i < Constants.HTTP_SERVER_ERROR.length; i++) {
+ if (status == Constants.HTTP_SERVER_ERROR[i]) {
+ return ResultType.SERVER_ERROR.getValue();
+ }
+ }
+ return ResultType.ERROR.getValue();
+ }
+
+ /**
+ * 判断Mysql的请求结果
+ *
+ * @param status 结果编码
+ * @return 结果类型
+ */
+ public static int judgeMysqlResult(int status) {
+ if (status >= Constants.MYSQL_CLIENT_ERROR[0][0] && status <= Constants.MYSQL_CLIENT_ERROR[0][1]
+ || status >= Constants.MYSQL_CLIENT_ERROR[1][0] && status <= Constants.MYSQL_CLIENT_ERROR[1][1]) {
+ return ResultType.CLIENT_ERROR.getValue();
+ }
+ if (status >= Constants.MYSQL_SERVER_ERROR[0][0] && status <= Constants.MYSQL_SERVER_ERROR[0][1]
+ || status >= Constants.MYSQL_SERVER_ERROR[1][0] && status <= Constants.MYSQL_SERVER_ERROR[1][1]) {
+ return ResultType.SERVER_ERROR.getValue();
+ }
+ return ResultType.ERROR.getValue();
+ }
+}
diff --git a/sermant-plugins/sermant-metrics/metrics-plugin/src/main/resources/META-INF/services/com.huaweicloud.sermant.core.plugin.agent.declarer.PluginDeclarer b/sermant-plugins/sermant-metrics/metrics-plugin/src/main/resources/META-INF/services/com.huaweicloud.sermant.core.plugin.agent.declarer.PluginDeclarer
index 67b4daa9be..5a623188dc 100644
--- a/sermant-plugins/sermant-metrics/metrics-plugin/src/main/resources/META-INF/services/com.huaweicloud.sermant.core.plugin.agent.declarer.PluginDeclarer
+++ b/sermant-plugins/sermant-metrics/metrics-plugin/src/main/resources/META-INF/services/com.huaweicloud.sermant.core.plugin.agent.declarer.PluginDeclarer
@@ -18,4 +18,10 @@
com.huawei.metrics.declarer.alibaba.ExchangeCodecDeclarer
com.huawei.metrics.declarer.alibaba.MonitorFilterDeclarer
com.huawei.metrics.declarer.apache.ExchangeCodecDeclarer
-com.huawei.metrics.declarer.apache.MonitorFilterDeclarer
\ No newline at end of file
+com.huawei.metrics.declarer.apache.MonitorFilterDeclarer
+com.huawei.metrics.declarer.httpurlconnection.ConnectDeclarer
+com.huawei.metrics.declarer.httpurlconnection.DisconnectDeclarer
+com.huawei.metrics.declarer.httpclient.HttpClientDeclarer
+com.huawei.metrics.declarer.okhttp.CallDeclarer
+com.huawei.metrics.declarer.okhttp3.CallDeclarer
+com.huawei.metrics.declarer.servlet.HttpServletDeclarer
\ No newline at end of file
diff --git a/sermant-plugins/sermant-metrics/metrics-service/src/main/java/com/huawei/metrics/service/MetricsService.java b/sermant-plugins/sermant-metrics/metrics-service/src/main/java/com/huawei/metrics/service/MetricsService.java
index e33080fece..a980d23009 100644
--- a/sermant-plugins/sermant-metrics/metrics-service/src/main/java/com/huawei/metrics/service/MetricsService.java
+++ b/sermant-plugins/sermant-metrics/metrics-service/src/main/java/com/huawei/metrics/service/MetricsService.java
@@ -18,7 +18,6 @@
import com.huawei.metrics.common.Constants;
import com.huawei.metrics.config.MetricsConfig;
-import com.huawei.metrics.entity.MetricsLinkInfo;
import com.huawei.metrics.entity.MetricsRpcInfo;
import com.huawei.metrics.manager.MetricsManager;
@@ -30,19 +29,18 @@
import com.alibaba.fastjson.JSONObject;
-import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
-import java.io.InputStreamReader;
import java.io.RandomAccessFile;
import java.lang.management.ManagementFactory;
import java.lang.management.RuntimeMXBean;
import java.math.BigDecimal;
import java.math.RoundingMode;
-import java.net.InetAddress;
import java.nio.channels.FileLock;
-import java.nio.charset.Charset;
+import java.nio.charset.StandardCharsets;
+import java.util.HashMap;
import java.util.List;
+import java.util.Map;
import java.util.Map.Entry;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
@@ -61,14 +59,12 @@ public class MetricsService implements PluginService {
private static final MetricsConfig METRICS_CONFIG = PluginConfigManager.getPluginConfig(MetricsConfig.class);
- private static final int CONTAINER_NAME_INDEX = 2;
-
private static final int ENABLE_NUM = 2;
/**
- * 换行符。Gopher解析时需要用到 System.lineSeparator()在UNIX返回"\n" 在Windows 返回"\r\n". 因此不能修改为System.lineSeparator();
+ * 换行符。Gopher解析时需要用到。 System.lineSeparator()在UNIX返回"\n",在Windows 返回"\r\n".因此不能修改为System.lineSeparator();
*/
- private static final String LINE_BREAK = "|\r\n";
+ private static final String LINE_BREAK = "\r\n";
private static final BigDecimal MS_TO_S = new BigDecimal(1000);
@@ -83,31 +79,6 @@ public class MetricsService implements PluginService {
*/
private String pid;
- /**
- * 进程名称
- */
- private String processName;
-
- /**
- * 机器Id
- */
- private String machineId;
-
- /**
- * 容器ID
- */
- private String containerId;
-
- /**
- * 容器名称
- */
- private String containerName;
-
- /**
- * 容器IP
- */
- private String containerIp;
-
/**
* 文件名称
*/
@@ -125,13 +96,9 @@ public void start() {
int index = name.indexOf(Constants.PROCESS_NAME_LINK);
if (index != -1) {
pid = name.substring(0, index);
- processName = name.substring(index + 1);
} else {
pid = Constants.EXCEPTION_PID;
- processName = StringUtils.EMPTY;
}
- initMachineId();
- initContainerInfo();
String filePath = METRICS_CONFIG.getFilePath() + pid;
metricsFileName = filePath + Constants.FILE_PATH_LINK + METRICS_CONFIG.getFileName();
try {
@@ -141,7 +108,7 @@ public void start() {
return;
}
executorService = Executors.newScheduledThreadPool(1, new ThreadFactoryUtils("metrics"));
- executorService.scheduleAtFixedRate(this::writeMetricData, METRICS_CONFIG.getDelayTime(),
+ executorService.scheduleWithFixedDelay(this::writeMetricData, METRICS_CONFIG.getDelayTime(),
METRICS_CONFIG.getPeriod(), TimeUnit.MILLISECONDS);
}
@@ -156,171 +123,156 @@ public void stop() {
* 把指标数据写进文件里
*/
private void writeMetricData() {
- if (MetricsManager.getLinkInfoMap().isEmpty() && MetricsManager.getRpcInfoMap().isEmpty()) {
+ if (MetricsManager.getRpcInfoMap().isEmpty()) {
return;
}
try (RandomAccessFile raf = new RandomAccessFile(metricsFileName, "rw");
FileLock lock = raf.getChannel().lock()) {
raf.seek(raf.length());
- writeLinkData(raf);
- writeRpcData(raf);
+ reportData(raf);
} catch (IOException e) {
LOGGER.log(Level.SEVERE, "Exception writing indicator data to file.", e);
}
}
/**
- * 写连接数据
+ * 写RPC API数据
*
- * @param raf 文件连接
+ * @param raf 文件内容访问类
* @throws IOException 文件写入异常
*/
- private void writeLinkData(RandomAccessFile raf) throws IOException {
- StringBuilder stringBuilder = new StringBuilder(Constants.METRICS_LINK + Constants.LINK_HEAD);
- for (Entry entry : MetricsManager.getLinkInfoMap().entrySet()) {
- MetricsLinkInfo originalLinkInfo = entry.getValue();
- if (originalLinkInfo.getSentMessages().get() == 0 || originalLinkInfo.getReceiveMessages().get() == 0) {
+ private void reportData(RandomAccessFile raf) throws IOException {
+ Map rpcInfoMap = new HashMap<>();
+ StringBuilder stringBuilder = new StringBuilder();
+ for (Entry entry : MetricsManager.getRpcInfoMap().entrySet()) {
+ MetricsRpcInfo metricsRpcInfo = JSONObject.parseObject(JSONObject.toJSONString(entry.getValue()),
+ MetricsRpcInfo.class);
+ if (metricsRpcInfo.getReqCount().get() == 0 || metricsRpcInfo.getResponseCount().get() == 0
+ || metricsRpcInfo.getSumLatency().get() == 0) {
+ continue;
+ }
+ reportBaseInfo(metricsRpcInfo, raf, Constants.RPC_API_HEADER);
+ raf.write((metricsRpcInfo.getUrl() + Constants.METRICS_LINK).getBytes(StandardCharsets.UTF_8));
+ BigDecimal clientErrorCount = new BigDecimal(metricsRpcInfo.getClientErrorCount().get());
+ BigDecimal reqCount = new BigDecimal(metricsRpcInfo.getReqCount().get());
+ BigDecimal clientErrorRatio = clientErrorCount.multiply(TO_PERCENT)
+ .divide(reqCount, ENABLE_NUM, RoundingMode.HALF_UP);
+ BigDecimal serverErrorCount = new BigDecimal(metricsRpcInfo.getServerErrorCount().get());
+ BigDecimal serverErrorRatio = serverErrorCount.multiply(TO_PERCENT).divide(reqCount, ENABLE_NUM,
+ RoundingMode.HALF_UP);
+ BigDecimal errorCount = new BigDecimal(metricsRpcInfo.getReqErrorCount().get());
+ BigDecimal errorRatio = errorCount.multiply(TO_PERCENT).divide(reqCount, ENABLE_NUM, RoundingMode.HALF_UP);
+ stringBuilder.append(errorCount).append(Constants.METRICS_LINK).append(clientErrorCount)
+ .append(Constants.METRICS_LINK).append(serverErrorCount)
+ .append(Constants.METRICS_LINK).append(errorRatio).append(Constants.METRICS_LINK)
+ .append(clientErrorRatio).append(Constants.METRICS_LINK)
+ .append(serverErrorRatio).append(Constants.METRICS_LINK).append(LINE_BREAK);
+ reportCommonInfo(metricsRpcInfo, raf, stringBuilder.toString());
+ stringBuilder.setLength(0);
+ cleanReportData(metricsRpcInfo);
+ countDataInfo(metricsRpcInfo, rpcInfoMap);
+ }
+ for (Entry entry : rpcInfoMap.entrySet()) {
+ MetricsRpcInfo metricsRpcInfo = entry.getValue();
+ if (metricsRpcInfo.getReqCount().get() == 0 || metricsRpcInfo.getResponseCount().get() == 0
+ || metricsRpcInfo.getSumLatency().get() == 0) {
continue;
}
- MetricsLinkInfo metricsLinkInfo = JSONObject.parseObject(JSONObject.toJSONString(originalLinkInfo),
- MetricsLinkInfo.class);
- String metricsInfoStr = stringBuilder.append(Constants.METRICS_LINK).append(pid)
- .append(Constants.METRICS_LINK).append(metricsLinkInfo.getClientIp()).append(Constants.METRICS_LINK)
- .append(metricsLinkInfo.getServerIp()).append(Constants.METRICS_LINK)
- .append(metricsLinkInfo.getServerPort()).append(Constants.METRICS_LINK)
- .append(metricsLinkInfo.getL4Role()).append(Constants.METRICS_LINK)
- .append(metricsLinkInfo.getL7Role()).append(Constants.METRICS_LINK)
- .append(metricsLinkInfo.getProtocol()).append(Constants.METRICS_LINK)
- .append(metricsLinkInfo.isEnableSsl() ? Constants.SSL_OPEN : Constants.SSL_CLOSE)
- .append(Constants.METRICS_LINK).append(metricsLinkInfo.getSentBytes().get())
- .append(Constants.METRICS_LINK).append(metricsLinkInfo.getSentMessages().get())
- .append(Constants.METRICS_LINK)
- .append(metricsLinkInfo.getReceiveBytes().get()).append(Constants.METRICS_LINK)
- .append(metricsLinkInfo.getReceiveMessages().get()).toString();
- raf.write(metricsInfoStr.getBytes(Charset.defaultCharset()));
- raf.write(LINE_BREAK.getBytes(Charset.defaultCharset()));
+ reportBaseInfo(metricsRpcInfo, raf, Constants.RPC_HEADER);
+ BigDecimal reqCount = new BigDecimal(metricsRpcInfo.getReqCount().get());
+ BigDecimal errorCount = new BigDecimal(metricsRpcInfo.getReqErrorCount().get());
+ BigDecimal errorRatio = errorCount.multiply(TO_PERCENT).divide(reqCount, ENABLE_NUM, RoundingMode.HALF_UP);
+ stringBuilder.append(errorCount).append(Constants.METRICS_LINK).append(errorRatio)
+ .append(Constants.METRICS_LINK).append(LINE_BREAK);
+ reportCommonInfo(metricsRpcInfo, raf, stringBuilder.toString());
stringBuilder.setLength(0);
- originalLinkInfo.getReceiveMessages().getAndAdd(-metricsLinkInfo.getReceiveMessages().get());
- originalLinkInfo.getReceiveBytes().getAndAdd(-metricsLinkInfo.getReceiveBytes().get());
- originalLinkInfo.getSentMessages().getAndAdd(-metricsLinkInfo.getSentMessages().get());
- originalLinkInfo.getSentBytes().getAndAdd(-metricsLinkInfo.getSentBytes().get());
}
}
/**
- * 写RPC数据
+ * 清除本次上报的数据
+ *
+ * @param metricsRpcInfo 指标信息
+ */
+ private void cleanReportData(MetricsRpcInfo metricsRpcInfo) {
+ MetricsRpcInfo originalRpcInfo = MetricsManager.getRpcInfoMap().get(MetricsManager.getKey(metricsRpcInfo));
+ originalRpcInfo.getReqErrorCount().getAndAdd(-metricsRpcInfo.getReqErrorCount().get());
+ originalRpcInfo.getSumLatency().getAndAdd(-metricsRpcInfo.getSumLatency().get());
+ originalRpcInfo.getResponseCount().getAndAdd(-metricsRpcInfo.getResponseCount().get());
+ originalRpcInfo.getReqCount().getAndAdd(-metricsRpcInfo.getReqCount().get());
+ originalRpcInfo.getLatencyList().removeAll(metricsRpcInfo.getLatencyList());
+ }
+
+ /**
+ * 写RPC和RPC API的基础信息
*
- * @param raf 文件连接
+ * @param metricsRpcInfo 指标信息
+ * @param raf 文件内容访问类
+ * @param head 指标头信息
* @throws IOException 文件写入异常
*/
- private void writeRpcData(RandomAccessFile raf) throws IOException {
+ private void reportBaseInfo(MetricsRpcInfo metricsRpcInfo, RandomAccessFile raf, String head) throws IOException {
StringBuilder stringBuilder = new StringBuilder();
- for (Entry entry : MetricsManager.getRpcInfoMap().entrySet()) {
- MetricsRpcInfo originalRpcInfo = entry.getValue();
- if (originalRpcInfo.getReqCount().get() == 0 || originalRpcInfo.getResponseCount().get() == 0
- || originalRpcInfo.getSumLatency().get() == 0) {
- continue;
- }
- MetricsRpcInfo metricsRpcInfo = JSONObject.parseObject(JSONObject.toJSONString(originalRpcInfo),
- MetricsRpcInfo.class);
- BigDecimal reqCount = new BigDecimal(metricsRpcInfo.getReqCount().get());
- BigDecimal resCount = new BigDecimal(metricsRpcInfo.getResponseCount().get());
- BigDecimal errorCount = new BigDecimal(metricsRpcInfo.getReqErrorCount().get());
- BigDecimal errorRatio = errorCount.multiply(TO_PERCENT).divide(resCount, ENABLE_NUM, RoundingMode.HALF_UP);
- BigDecimal sumLatency = new BigDecimal(metricsRpcInfo.getSumLatency().get());
- BigDecimal avgLatency = sumLatency.divide(resCount, ENABLE_NUM, RoundingMode.HALF_UP);
- BigDecimal reqThroughout = reqCount.multiply(MS_TO_S).divide(new BigDecimal(METRICS_CONFIG.getDelayTime()),
- ENABLE_NUM, RoundingMode.HALF_UP);
- BigDecimal resThroughout = resCount.multiply(MS_TO_S).divide(new BigDecimal(METRICS_CONFIG.getDelayTime()),
- ENABLE_NUM, RoundingMode.HALF_UP);
- String latencyHistogram = getLatencyHistogram(metricsRpcInfo.getLatencyList());
- String sslFlag = metricsRpcInfo.isEnableSsl() ? Constants.SSL_OPEN : Constants.SSL_CLOSE;
- String metricsInfoStr = stringBuilder.append(Constants.METRICS_LINK).append(Constants.RPC_HEAD)
- .append(Constants.METRICS_LINK).append(pid).append(Constants.METRICS_LINK)
- .append(metricsRpcInfo.getClientIp()).append(Constants.METRICS_LINK)
- .append(metricsRpcInfo.getServerIp()).append(Constants.METRICS_LINK)
- .append(metricsRpcInfo.getServerPort()).append(Constants.METRICS_LINK)
- .append(metricsRpcInfo.getL4Role()).append(Constants.METRICS_LINK)
- .append(metricsRpcInfo.getL7Role()).append(Constants.METRICS_LINK)
- .append(metricsRpcInfo.getProtocol()).append(Constants.METRICS_LINK)
- .append(sslFlag).append(Constants.METRICS_LINK).append(reqThroughout).append(Constants.METRICS_LINK)
- .append(resThroughout).append(Constants.METRICS_LINK).append(reqCount)
- .append(Constants.METRICS_LINK).append(resCount).append(Constants.METRICS_LINK).append(avgLatency)
- .append(Constants.METRICS_LINK).append(latencyHistogram).append(Constants.METRICS_LINK)
- .append(sumLatency).append(Constants.METRICS_LINK).append(errorRatio).append(Constants.METRICS_LINK)
- .append(errorCount).toString();
- raf.write(metricsInfoStr.getBytes(Charset.defaultCharset()));
- raf.write(LINE_BREAK.getBytes(Charset.defaultCharset()));
- stringBuilder.setLength(0);
- originalRpcInfo.getReqErrorCount().getAndAdd(-metricsRpcInfo.getReqErrorCount().get());
- originalRpcInfo.getSumLatency().getAndAdd(-metricsRpcInfo.getSumLatency().get());
- originalRpcInfo.getResponseCount().getAndAdd(-metricsRpcInfo.getResponseCount().get());
- originalRpcInfo.getReqCount().getAndAdd(-metricsRpcInfo.getReqCount().get());
- originalRpcInfo.getLatencyList().removeAll(metricsRpcInfo.getLatencyList());
- }
+ String commonInfo = stringBuilder.append(Constants.METRICS_LINK).append(head)
+ .append(Constants.METRICS_LINK).append(pid).append(Constants.METRICS_LINK)
+ .append(metricsRpcInfo.getClientIp()).append(Constants.METRICS_LINK)
+ .append(metricsRpcInfo.getServerIp()).append(Constants.METRICS_LINK)
+ .append(metricsRpcInfo.getServerPort()).append(Constants.METRICS_LINK)
+ .append(metricsRpcInfo.getL4Role()).append(Constants.METRICS_LINK)
+ .append(metricsRpcInfo.getL7Role()).append(Constants.METRICS_LINK)
+ .append(metricsRpcInfo.getProtocol()).append(Constants.METRICS_LINK).toString();
+ raf.write(commonInfo.getBytes(StandardCharsets.UTF_8));
+ stringBuilder.setLength(0);
}
/**
- * 初始化机器Id
+ * 写RPC和RPC API的公共信息
+ *
+ * @param metricsRpcInfo 指标信息
+ * @param raf 文件内容访问类
+ * @param errorInfo 错误信息
+ * @throws IOException 文件写入异常
*/
- private void initMachineId() {
- try {
- ProcessBuilder processBuilder = new ProcessBuilder("/bin/sh", "-c", "dmidecode -s system-uuid");
- Process process = processBuilder.start();
- try (BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(process.getInputStream()))) {
- String line;
- while ((line = bufferedReader.readLine()) != null) {
- if (StringUtils.isExist(line)) {
- machineId = line.trim();
- break;
- }
- }
- }
- int exitCode = process.waitFor();
- if (exitCode != 0) {
- LOGGER.log(Level.WARNING, "Failed to execute command: dmidecode -s system-uuid.");
- }
- } catch (IOException e) {
- LOGGER.log(Level.SEVERE, "Error executing command: dmidecode -s system-uuid.", e);
- } catch (InterruptedException e) {
- Thread.currentThread().interrupt();
- LOGGER.log(Level.SEVERE, "Command execution interrupted.", e);
- }
- if (StringUtils.isEmpty(machineId)) {
- machineId = StringUtils.EMPTY;
- }
+ private void reportCommonInfo(MetricsRpcInfo metricsRpcInfo, RandomAccessFile raf, String errorInfo)
+ throws IOException {
+ BigDecimal reqCount = new BigDecimal(metricsRpcInfo.getReqCount().get());
+ BigDecimal resCount = new BigDecimal(metricsRpcInfo.getResponseCount().get());
+ BigDecimal sumLatency = new BigDecimal(metricsRpcInfo.getSumLatency().get());
+ BigDecimal avgLatency = sumLatency.divide(resCount, ENABLE_NUM, RoundingMode.HALF_UP);
+ BigDecimal reqThroughout = reqCount.multiply(MS_TO_S).divide(new BigDecimal(METRICS_CONFIG.getDelayTime()),
+ ENABLE_NUM, RoundingMode.HALF_UP);
+ BigDecimal resThroughout = resCount.multiply(MS_TO_S).divide(new BigDecimal(METRICS_CONFIG.getDelayTime()),
+ ENABLE_NUM, RoundingMode.HALF_UP);
+ String latencyHistogram = getLatencyHistogram(metricsRpcInfo.getLatencyList());
+ String sslFlag = metricsRpcInfo.isEnableSsl() ? Constants.SSL_OPEN : Constants.SSL_CLOSE;
+ StringBuilder stringBuilder = new StringBuilder();
+ String metricsRpcInfoStr = stringBuilder.append(sslFlag).append(Constants.METRICS_LINK)
+ .append(reqThroughout).append(Constants.METRICS_LINK)
+ .append(resThroughout).append(Constants.METRICS_LINK).append(reqCount)
+ .append(Constants.METRICS_LINK).append(resCount).append(Constants.METRICS_LINK).append(avgLatency)
+ .append(Constants.METRICS_LINK).append(latencyHistogram).append(Constants.METRICS_LINK)
+ .append(sumLatency).append(Constants.METRICS_LINK).append(errorInfo).toString();
+ raf.write(metricsRpcInfoStr.getBytes(StandardCharsets.UTF_8));
+ stringBuilder.setLength(0);
}
/**
- * 初始化容器信息
+ * 统计RPC数据,非API维度
+ *
+ * @param metricsRpcInfo 指标数据
+ * @param rpcInfoMap 保存统计后的RPC数据
*/
- private void initContainerInfo() {
- try {
- containerIp = InetAddress.getLocalHost().getHostAddress();
- ProcessBuilder processBuilder = new ProcessBuilder("cat", "/proc/self/cgroup");
- Process process = processBuilder.start();
- BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()));
- String line;
- while ((line = reader.readLine()) != null) {
- if (line.contains("docker") || line.contains("kubepods")) {
- String[] parts = line.split("/");
- containerId = parts[parts.length - 1];
- containerName = parts[parts.length - CONTAINER_NAME_INDEX];
- break;
- }
- }
- int exitCode = process.waitFor();
- if (exitCode != 0) {
- LOGGER.log(Level.WARNING, "Failed to get container ID.");
- }
- } catch (IOException | InterruptedException e) {
- LOGGER.log(Level.SEVERE, "Failed to get container ID.", e);
- }
- if (StringUtils.isEmpty(containerId)) {
- containerId = StringUtils.EMPTY;
- }
- if (StringUtils.isEmpty(containerName)) {
- containerName = StringUtils.EMPTY;
+ private void countDataInfo(MetricsRpcInfo metricsRpcInfo, Map rpcInfoMap) {
+ String rpcKey = MetricsManager.getRpcKey(metricsRpcInfo);
+ MetricsRpcInfo rpcInfo = rpcInfoMap.get(rpcKey);
+ if (rpcInfo == null) {
+ rpcInfoMap.put(MetricsManager.getRpcKey(metricsRpcInfo), metricsRpcInfo);
+ } else {
+ rpcInfo.getReqErrorCount().getAndAdd(metricsRpcInfo.getReqErrorCount().get());
+ rpcInfo.getSumLatency().getAndAdd(metricsRpcInfo.getSumLatency().get());
+ rpcInfo.getResponseCount().getAndAdd(metricsRpcInfo.getResponseCount().get());
+ rpcInfo.getReqCount().getAndAdd(metricsRpcInfo.getReqCount().get());
+ rpcInfo.getLatencyList().addAll(metricsRpcInfo.getLatencyList());
}
}
@@ -334,11 +286,15 @@ private void initContainerInfo() {
private void createTmpFile(String filePath, String fileName) throws IOException {
File dir = new File(filePath);
if (!dir.exists()) {
- dir.mkdirs();
+ boolean createDirFlag = dir.mkdirs();
+ LOGGER.log(Level.INFO, "The folder does not exist, created the folder {0}.",
+ createDirFlag ? "successfully" : "failed");
}
File file = new File(fileName);
if (!file.exists()) {
- file.createNewFile();
+ boolean createFileFlag = file.createNewFile();
+ LOGGER.log(Level.INFO, "{0} to create indicator collection file.",
+ createFileFlag ? "Successfully" : "Failed");
}
}