[
https://issues.apache.org/jira/browse/SCB-894?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=16606646#comment-16606646
]
ASF GitHub Bot commented on SCB-894:
------------------------------------
liubao68 closed pull request #896: [SCB-894] measure httpServer and httpClient
URL: https://github.com/apache/incubator-servicecomb-java-chassis/pull/896
This is a PR merged from a forked repository.
As GitHub hides the original diff on merge, it is displayed below for
the sake of provenance:
As this is a foreign pull request (from a fork), the diff is supplied
below (as it won't show otherwise due to GitHub magic):
diff --git
a/foundations/foundation-vertx/src/main/java/org/apache/servicecomb/foundation/vertx/metrics/DefaultHttpClientMetrics.java
b/foundations/foundation-vertx/src/main/java/org/apache/servicecomb/foundation/vertx/metrics/DefaultHttpClientMetrics.java
new file mode 100644
index 000000000..98f5fd205
--- /dev/null
+++
b/foundations/foundation-vertx/src/main/java/org/apache/servicecomb/foundation/vertx/metrics/DefaultHttpClientMetrics.java
@@ -0,0 +1,168 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 org.apache.servicecomb.foundation.vertx.metrics;
+
+import
org.apache.servicecomb.foundation.vertx.metrics.metric.DefaultClientEndpointMetric;
+import
org.apache.servicecomb.foundation.vertx.metrics.metric.DefaultClientEndpointMetricManager;
+import
org.apache.servicecomb.foundation.vertx.metrics.metric.DefaultHttpSocketMetric;
+
+import io.vertx.core.http.HttpClient;
+import io.vertx.core.http.HttpClientOptions;
+import io.vertx.core.http.HttpClientRequest;
+import io.vertx.core.http.HttpClientResponse;
+import io.vertx.core.http.WebSocket;
+import io.vertx.core.net.SocketAddress;
+import io.vertx.core.net.impl.SocketAddressImpl;
+import io.vertx.core.spi.metrics.HttpClientMetrics;
+
+/**
+ * important: not singleton, every HttpClient instance relate to a
HttpClientMetrics instance
+ */
+public class DefaultHttpClientMetrics implements
+ HttpClientMetrics<DefaultHttpSocketMetric, Object,
DefaultHttpSocketMetric, DefaultClientEndpointMetric, Object> {
+ private final DefaultClientEndpointMetricManager clientEndpointMetricManager;
+
+ private final HttpClient client;
+
+ private final HttpClientOptions options;
+
+ public DefaultHttpClientMetrics(DefaultClientEndpointMetricManager
clientEndpointMetricManager,
+ HttpClient client, HttpClientOptions options) {
+ this.clientEndpointMetricManager = clientEndpointMetricManager;
+ this.client = client;
+ this.options = options;
+ }
+
+ public HttpClient getClient() {
+ return client;
+ }
+
+ public HttpClientOptions getOptions() {
+ return options;
+ }
+
+ @Override
+ public DefaultClientEndpointMetric createEndpoint(String host, int port, int
maxPoolSize) {
+ SocketAddress address = new SocketAddressImpl(port, host);
+ return
clientEndpointMetricManager.getOrCreateClientEndpointMetric(address);
+ }
+
+ @Override
+ public void closeEndpoint(String host, int port, DefaultClientEndpointMetric
endpointMetric) {
+ endpointMetric.decRefCount();
+ }
+
+ @Override
+ public Object enqueueRequest(DefaultClientEndpointMetric endpointMetric) {
+ return null;
+ }
+
+ @Override
+ public void dequeueRequest(DefaultClientEndpointMetric endpointMetric,
Object taskMetric) {
+ }
+
+ @Override
+ public void endpointConnected(DefaultClientEndpointMetric endpointMetric,
DefaultHttpSocketMetric socketMetric) {
+ socketMetric.setEndpointMetric(endpointMetric);
+ endpointMetric.onConnect();
+ }
+
+ @Override
+ public void endpointDisconnected(DefaultClientEndpointMetric endpointMetric,
DefaultHttpSocketMetric socketMetric) {
+ endpointMetric.onDisconnect();
+ socketMetric.setConnected(false);
+ }
+
+ @Override
+ public DefaultHttpSocketMetric requestBegin(DefaultClientEndpointMetric
endpointMetric,
+ DefaultHttpSocketMetric socketMetric, SocketAddress localAddress,
SocketAddress remoteAddress,
+ HttpClientRequest request) {
+ socketMetric.requestBegin();
+ return socketMetric;
+ }
+
+ @Override
+ public void requestEnd(DefaultHttpSocketMetric requestMetric) {
+ requestMetric.requestEnd();
+ }
+
+ @Override
+ public void responseBegin(DefaultHttpSocketMetric requestMetric,
HttpClientResponse response) {
+ }
+
+ @Override
+ public DefaultHttpSocketMetric responsePushed(DefaultClientEndpointMetric
endpointMetric,
+ DefaultHttpSocketMetric socketMetric,
+ SocketAddress localAddress,
+ SocketAddress remoteAddress, HttpClientRequest request) {
+ return null;
+ }
+
+ @Override
+ public void requestReset(DefaultHttpSocketMetric requestMetric) {
+ }
+
+ @Override
+ public void responseEnd(DefaultHttpSocketMetric requestMetric,
HttpClientResponse response) {
+ }
+
+ @Override
+ public Object connected(DefaultClientEndpointMetric endpointMetric,
DefaultHttpSocketMetric socketMetric,
+ WebSocket webSocket) {
+ return null;
+ }
+
+ @Override
+ public void disconnected(Object webSocketMetric) {
+
+ }
+
+ @Override
+ public DefaultHttpSocketMetric connected(SocketAddress remoteAddress, String
remoteName) {
+ return new DefaultHttpSocketMetric(null);
+ }
+
+ @Override
+ public void disconnected(DefaultHttpSocketMetric socketMetric, SocketAddress
remoteAddress) {
+ }
+
+ @Override
+ public void bytesRead(DefaultHttpSocketMetric socketMetric, SocketAddress
remoteAddress, long numberOfBytes) {
+ socketMetric.getEndpointMetric().addBytesRead(numberOfBytes);
+ }
+
+ @Override
+ public void bytesWritten(DefaultHttpSocketMetric socketMetric, SocketAddress
remoteAddress, long numberOfBytes) {
+ socketMetric.getEndpointMetric().addBytesWritten(numberOfBytes);
+ }
+
+ @Override
+ public void exceptionOccurred(DefaultHttpSocketMetric socketMetric,
SocketAddress remoteAddress, Throwable t) {
+
+ }
+
+ @Override
+ @Deprecated
+ public boolean isEnabled() {
+ return true;
+ }
+
+ @Override
+ public void close() {
+
+ }
+}
diff --git
a/foundations/foundation-vertx/src/main/java/org/apache/servicecomb/foundation/vertx/metrics/DefaultHttpServerMetrics.java
b/foundations/foundation-vertx/src/main/java/org/apache/servicecomb/foundation/vertx/metrics/DefaultHttpServerMetrics.java
new file mode 100644
index 000000000..ddfb95870
--- /dev/null
+++
b/foundations/foundation-vertx/src/main/java/org/apache/servicecomb/foundation/vertx/metrics/DefaultHttpServerMetrics.java
@@ -0,0 +1,140 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 org.apache.servicecomb.foundation.vertx.metrics;
+
+import
org.apache.servicecomb.foundation.vertx.metrics.metric.DefaultEndpointMetric;
+import
org.apache.servicecomb.foundation.vertx.metrics.metric.DefaultHttpSocketMetric;
+
+import io.vertx.core.http.HttpMethod;
+import io.vertx.core.http.HttpServer;
+import io.vertx.core.http.HttpServerOptions;
+import io.vertx.core.http.HttpServerRequest;
+import io.vertx.core.http.HttpServerResponse;
+import io.vertx.core.http.ServerWebSocket;
+import io.vertx.core.net.SocketAddress;
+import io.vertx.core.spi.metrics.HttpServerMetrics;
+
+/**
+ * important: not singleton, every HttpServer instance relate to a
HttpServerMetrics instance
+ */
+public class DefaultHttpServerMetrics implements HttpServerMetrics<Object,
Object, DefaultHttpSocketMetric> {
+ private final DefaultEndpointMetric endpointMetric;
+
+ private final HttpServer server;
+
+ private final SocketAddress localAddress;
+
+ private final HttpServerOptions options;
+
+ public DefaultHttpServerMetrics(DefaultEndpointMetric endpointMetric,
HttpServer server,
+ SocketAddress localAddress, HttpServerOptions options) {
+ this.endpointMetric = endpointMetric;
+ this.server = server;
+ this.localAddress = localAddress;
+ this.options = options;
+ }
+
+ public DefaultEndpointMetric getEndpointMetric() {
+ return endpointMetric;
+ }
+
+ public HttpServer getServer() {
+ return server;
+ }
+
+ public SocketAddress getLocalAddress() {
+ return localAddress;
+ }
+
+ public HttpServerOptions getOptions() {
+ return options;
+ }
+
+ @Override
+ public Object requestBegin(DefaultHttpSocketMetric socketMetric,
HttpServerRequest request) {
+ return null;
+ }
+
+ @Override
+ public void requestReset(Object requestMetric) {
+
+ }
+
+ @Override
+ public Object responsePushed(DefaultHttpSocketMetric socketMetric,
HttpMethod method, String uri,
+ HttpServerResponse response) {
+ return null;
+ }
+
+ @Override
+ public void responseEnd(Object requestMetric, HttpServerResponse response) {
+
+ }
+
+ @Override
+ public Object upgrade(Object requestMetric, ServerWebSocket serverWebSocket)
{
+ return null;
+ }
+
+ @Override
+ public Object connected(DefaultHttpSocketMetric socketMetric,
ServerWebSocket serverWebSocket) {
+ return null;
+ }
+
+ @Override
+ public void disconnected(Object serverWebSocketMetric) {
+
+ }
+
+ @Override
+ public DefaultHttpSocketMetric connected(SocketAddress remoteAddress, String
remoteName) {
+ endpointMetric.onConnect();
+ return new DefaultHttpSocketMetric(endpointMetric);
+ }
+
+ @Override
+ public void disconnected(DefaultHttpSocketMetric socketMetric, SocketAddress
remoteAddress) {
+ endpointMetric.onDisconnect();
+ socketMetric.setConnected(false);
+ }
+
+ @Override
+ public void bytesRead(DefaultHttpSocketMetric socketMetric, SocketAddress
remoteAddress, long numberOfBytes) {
+ endpointMetric.addBytesRead(numberOfBytes);
+ }
+
+ @Override
+ public void bytesWritten(DefaultHttpSocketMetric socketMetric, SocketAddress
remoteAddress, long numberOfBytes) {
+ endpointMetric.addBytesWritten(numberOfBytes);
+ }
+
+ @Override
+ public void exceptionOccurred(DefaultHttpSocketMetric socketMetric,
SocketAddress remoteAddress, Throwable t) {
+
+ }
+
+ @Override
+ @Deprecated
+ public boolean isEnabled() {
+ return true;
+ }
+
+ @Override
+ public void close() {
+
+ }
+}
diff --git
a/foundations/foundation-vertx/src/main/java/org/apache/servicecomb/foundation/vertx/metrics/DefaultVertxMetrics.java
b/foundations/foundation-vertx/src/main/java/org/apache/servicecomb/foundation/vertx/metrics/DefaultVertxMetrics.java
new file mode 100644
index 000000000..e0dfcee9d
--- /dev/null
+++
b/foundations/foundation-vertx/src/main/java/org/apache/servicecomb/foundation/vertx/metrics/DefaultVertxMetrics.java
@@ -0,0 +1,91 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 org.apache.servicecomb.foundation.vertx.metrics;
+
+import java.util.Map;
+
+import org.apache.servicecomb.foundation.common.concurrent.ConcurrentHashMapEx;
+import
org.apache.servicecomb.foundation.vertx.metrics.metric.DefaultClientEndpointMetricManager;
+import
org.apache.servicecomb.foundation.vertx.metrics.metric.DefaultEndpointMetric;
+
+import io.vertx.core.Vertx;
+import io.vertx.core.VertxOptions;
+import io.vertx.core.http.HttpClient;
+import io.vertx.core.http.HttpClientOptions;
+import io.vertx.core.http.HttpServer;
+import io.vertx.core.http.HttpServerOptions;
+import io.vertx.core.metrics.impl.DummyVertxMetrics;
+import io.vertx.core.net.SocketAddress;
+import io.vertx.core.spi.metrics.HttpClientMetrics;
+import io.vertx.core.spi.metrics.HttpServerMetrics;
+
+public class DefaultVertxMetrics extends DummyVertxMetrics {
+ private final Vertx vertx;
+
+ private VertxOptions vertxOptions;
+
+ // to support listen multiple addresses, must use a map to manage the metric
+ private Map<SocketAddress, DefaultEndpointMetric> serverEndpointMetricMap =
new ConcurrentHashMapEx<>();
+
+ private volatile DefaultClientEndpointMetricManager
clientEndpointMetricManager;
+
+ public DefaultVertxMetrics(Vertx vertx, VertxOptions vertxOptions) {
+ this.vertx = vertx;
+ this.vertxOptions = vertxOptions;
+ }
+
+ public Vertx getVertx() {
+ return vertx;
+ }
+
+ public DefaultClientEndpointMetricManager getClientEndpointMetricManager() {
+ return clientEndpointMetricManager;
+ }
+
+ @Override
+ public HttpServerMetrics<?, ?, ?> createMetrics(HttpServer server,
SocketAddress localAddress,
+ HttpServerOptions options) {
+ DefaultEndpointMetric endpointMetric = serverEndpointMetricMap
+ .computeIfAbsent(localAddress, DefaultEndpointMetric::new);
+ return new DefaultHttpServerMetrics(endpointMetric, server, localAddress,
options);
+ }
+
+ @Override
+ public HttpClientMetrics<?, ?, ?, ?, ?> createMetrics(HttpClient client,
HttpClientOptions options) {
+ if (clientEndpointMetricManager == null) {
+ synchronized (vertx) {
+ if (clientEndpointMetricManager == null) {
+ clientEndpointMetricManager = new
DefaultClientEndpointMetricManager(vertx,
+ (MetricsOptionsEx) vertxOptions.getMetricsOptions());
+ }
+ }
+ }
+
+ return new DefaultHttpClientMetrics(clientEndpointMetricManager, client,
options);
+ }
+
+ @Override
+ public boolean isMetricsEnabled() {
+ return true;
+ }
+
+ @Deprecated
+ @Override
+ public boolean isEnabled() {
+ return true;
+ }
+}
diff --git
a/foundations/foundation-vertx/src/main/java/org/apache/servicecomb/foundation/vertx/metrics/DefaultVertxMetricsFactory.java
b/foundations/foundation-vertx/src/main/java/org/apache/servicecomb/foundation/vertx/metrics/DefaultVertxMetricsFactory.java
new file mode 100644
index 000000000..1ceb91684
--- /dev/null
+++
b/foundations/foundation-vertx/src/main/java/org/apache/servicecomb/foundation/vertx/metrics/DefaultVertxMetricsFactory.java
@@ -0,0 +1,61 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 org.apache.servicecomb.foundation.vertx.metrics;
+
+import io.vertx.core.Vertx;
+import io.vertx.core.VertxOptions;
+import io.vertx.core.metrics.MetricsOptions;
+import io.vertx.core.spi.VertxMetricsFactory;
+import io.vertx.core.spi.metrics.VertxMetrics;
+
+/**
+ * <pre>
+ * only for one vertx instance
+ * DO NOT inject to vertx by SPI
+ * typical usage:
+ * DefaultVertxMetricsFactory factory = new DefaultVertxMetricsFactory();
+ * MetricsOptionsEx metricsOptionsEx = (MetricsOptionsEx)
factory.newOptions();
+ *
+ * VertxOptions vertxOptions = new VertxOptions();
+ * vertxOptions.setMetricsOptions(metricsOptionsEx);
+ *
+ * Vertx vertx = Vertx.vertx(vertxOptions);
+ * </pre>
+ */
+public class DefaultVertxMetricsFactory implements VertxMetricsFactory {
+ private DefaultVertxMetrics vertxMetrics;
+
+ public DefaultVertxMetrics getVertxMetrics() {
+ return vertxMetrics;
+ }
+
+ @Override
+ public synchronized VertxMetrics metrics(Vertx vertx, VertxOptions options) {
+ if (vertxMetrics == null) {
+ vertxMetrics = new DefaultVertxMetrics(vertx, options);
+ }
+ return vertxMetrics;
+ }
+
+ @Override
+ public MetricsOptions newOptions() {
+ MetricsOptionsEx metricsOptions = new MetricsOptionsEx();
+ metricsOptions.setFactory(this);
+ metricsOptions.setEnabled(true);
+ return metricsOptions;
+ }
+}
diff --git
a/foundations/foundation-vertx/src/main/java/org/apache/servicecomb/foundation/vertx/metrics/MetricsOptionsEx.java
b/foundations/foundation-vertx/src/main/java/org/apache/servicecomb/foundation/vertx/metrics/MetricsOptionsEx.java
new file mode 100644
index 000000000..702ca64d8
--- /dev/null
+++
b/foundations/foundation-vertx/src/main/java/org/apache/servicecomb/foundation/vertx/metrics/MetricsOptionsEx.java
@@ -0,0 +1,47 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 org.apache.servicecomb.foundation.vertx.metrics;
+
+import java.util.concurrent.TimeUnit;
+
+import io.vertx.core.metrics.MetricsOptions;
+
+public class MetricsOptionsEx extends MetricsOptions {
+ private long checkClientEndpointMetricIntervalInMilliseconds =
TimeUnit.MINUTES.toMillis(1);
+
+ private long checkClientEndpointMetricExpiredInNano =
TimeUnit.MINUTES.toNanos(30);
+
+ public long getCheckClientEndpointMetricIntervalInMilliseconds() {
+ return checkClientEndpointMetricIntervalInMilliseconds;
+ }
+
+ public void setCheckClientEndpointMetricIntervalInMinute(long minute) {
+ this.checkClientEndpointMetricIntervalInMilliseconds =
TimeUnit.MINUTES.toMillis(minute);
+ }
+
+ public long getCheckClientEndpointMetricExpiredInNano() {
+ return checkClientEndpointMetricExpiredInNano;
+ }
+
+ public void setCheckClientEndpointMetricExpiredInNano(long nanoTime) {
+ this.checkClientEndpointMetricExpiredInNano = nanoTime;
+ }
+
+ public void setCheckClientEndpointMetricExpiredInMinute(long minute) {
+ this.checkClientEndpointMetricExpiredInNano =
TimeUnit.MINUTES.toNanos(minute);
+ }
+}
diff --git
a/foundations/foundation-vertx/src/main/java/org/apache/servicecomb/foundation/vertx/metrics/metric/DefaultClientEndpointMetric.java
b/foundations/foundation-vertx/src/main/java/org/apache/servicecomb/foundation/vertx/metrics/metric/DefaultClientEndpointMetric.java
new file mode 100644
index 000000000..e4c1bfd88
--- /dev/null
+++
b/foundations/foundation-vertx/src/main/java/org/apache/servicecomb/foundation/vertx/metrics/metric/DefaultClientEndpointMetric.java
@@ -0,0 +1,61 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 org.apache.servicecomb.foundation.vertx.metrics.metric;
+
+import java.util.concurrent.atomic.AtomicLong;
+
+import io.vertx.core.net.SocketAddress;
+
+
+/**
+ * for one listen address, include multiple httpClient or httpServer
+ */
+public class DefaultClientEndpointMetric extends DefaultEndpointMetric {
+ // control if the metric instance will be expired
+ // all invoker about incRefCount/isExpired, must lock:
DefaultClientEndpointMetricManager
+ // decRefCount no need to lock, because that only cause to be expired later.
+ private long lastNanoTime;
+
+ private AtomicLong refCount = new AtomicLong();
+
+ public DefaultClientEndpointMetric(SocketAddress address) {
+ super(address);
+ }
+
+ public long getLastNanoTime() {
+ return lastNanoTime;
+ }
+
+ public long getRefCount() {
+ return refCount.get();
+ }
+
+ public void incRefCount() {
+ lastNanoTime = System.nanoTime();
+ refCount.incrementAndGet();
+ }
+
+ public void decRefCount() {
+ lastNanoTime = System.nanoTime();
+ refCount.decrementAndGet();
+ }
+
+ public boolean isExpired(long nsTimeout) {
+ return refCount.get() == 0
+ && (System.nanoTime() - lastNanoTime) > nsTimeout;
+ }
+}
diff --git
a/foundations/foundation-vertx/src/main/java/org/apache/servicecomb/foundation/vertx/metrics/metric/DefaultClientEndpointMetricManager.java
b/foundations/foundation-vertx/src/main/java/org/apache/servicecomb/foundation/vertx/metrics/metric/DefaultClientEndpointMetricManager.java
new file mode 100644
index 000000000..8874c0382
--- /dev/null
+++
b/foundations/foundation-vertx/src/main/java/org/apache/servicecomb/foundation/vertx/metrics/metric/DefaultClientEndpointMetricManager.java
@@ -0,0 +1,74 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 org.apache.servicecomb.foundation.vertx.metrics.metric;
+
+import java.util.Map;
+
+import org.apache.servicecomb.foundation.common.concurrent.ConcurrentHashMapEx;
+import org.apache.servicecomb.foundation.vertx.metrics.MetricsOptionsEx;
+
+import com.google.common.annotations.VisibleForTesting;
+
+import io.vertx.core.Vertx;
+import io.vertx.core.net.SocketAddress;
+
+public class DefaultClientEndpointMetricManager {
+ private final MetricsOptionsEx metricsOptionsEx;
+
+ // to avoid save too many endpoint that not exist any more
+ // must check expired periodically
+ private Map<SocketAddress, DefaultClientEndpointMetric>
clientEndpointMetricMap = new ConcurrentHashMapEx<>();
+
+ private final Object lock = new Object();
+
+ public DefaultClientEndpointMetricManager(Vertx vertx, MetricsOptionsEx
metricsOptionsEx) {
+ this.metricsOptionsEx = metricsOptionsEx;
+
vertx.setPeriodic(metricsOptionsEx.getCheckClientEndpointMetricIntervalInMilliseconds(),
+ this::onCheckClientEndpointMetricExpired);
+ }
+
+ @VisibleForTesting
+ public Map<SocketAddress, DefaultClientEndpointMetric>
getClientEndpointMetricMap() {
+ return clientEndpointMetricMap;
+ }
+
+ public DefaultClientEndpointMetric
getOrCreateClientEndpointMetric(SocketAddress serverAddress) {
+ synchronized (lock) {
+ DefaultClientEndpointMetric metric = clientEndpointMetricMap
+ .computeIfAbsent(serverAddress, DefaultClientEndpointMetric::new);
+ metric.incRefCount();
+ return metric;
+ }
+ }
+
+ public DefaultClientEndpointMetric getClientEndpointMetric(SocketAddress
serverAddress) {
+ return clientEndpointMetricMap.get(serverAddress);
+ }
+
+ @VisibleForTesting
+ public void onCheckClientEndpointMetricExpired(long periodic) {
+ for (DefaultClientEndpointMetric metric :
clientEndpointMetricMap.values()) {
+ if
(metric.isExpired(metricsOptionsEx.getCheckClientEndpointMetricExpiredInNano()))
{
+ synchronized (lock) {
+ if
(metric.isExpired(metricsOptionsEx.getCheckClientEndpointMetricExpiredInNano()))
{
+ clientEndpointMetricMap.remove(metric.getAddress());
+ }
+ }
+ }
+ }
+ }
+}
diff --git
a/foundations/foundation-vertx/src/main/java/org/apache/servicecomb/foundation/vertx/metrics/metric/DefaultEndpointMetric.java
b/foundations/foundation-vertx/src/main/java/org/apache/servicecomb/foundation/vertx/metrics/metric/DefaultEndpointMetric.java
new file mode 100644
index 000000000..f25ca64e4
--- /dev/null
+++
b/foundations/foundation-vertx/src/main/java/org/apache/servicecomb/foundation/vertx/metrics/metric/DefaultEndpointMetric.java
@@ -0,0 +1,84 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 org.apache.servicecomb.foundation.vertx.metrics.metric;
+
+import java.util.concurrent.atomic.AtomicLong;
+
+import io.vertx.core.net.SocketAddress;
+
+/**
+ * for one listen address, include multiple httpClient or httpServer
+ */
+public class DefaultEndpointMetric {
+ private SocketAddress address;
+
+ // summary of connect times from boot
+ // by this, we can know how many new connections connected recently
+ private AtomicLong connectCount = new AtomicLong();
+
+ // summary of disconnect times from boot
+ // by this, we can know how many connections disconnected recently
+ private AtomicLong disconnectCount = new AtomicLong();
+
+ private AtomicLong bytesRead = new AtomicLong();
+
+ private AtomicLong bytesWritten = new AtomicLong();
+
+ public DefaultEndpointMetric(SocketAddress address) {
+ this.address = address;
+ }
+
+ public SocketAddress getAddress() {
+ return address;
+ }
+
+ public long getConnectCount() {
+ return connectCount.get();
+ }
+
+ public long getDisconnectCount() {
+ return disconnectCount.get();
+ }
+
+ public long getCurrentConnectionCount() {
+ return connectCount.get() - disconnectCount.get();
+ }
+
+ public void onConnect() {
+ connectCount.incrementAndGet();
+ }
+
+ public void onDisconnect() {
+ disconnectCount.incrementAndGet();
+ }
+
+ public long getBytesRead() {
+ return bytesRead.get();
+ }
+
+ public long addBytesRead(long bytes) {
+ return bytesRead.addAndGet(bytes);
+ }
+
+ public long getBytesWritten() {
+ return bytesWritten.get();
+ }
+
+ public long addBytesWritten(long bytes) {
+ return bytesWritten.addAndGet(bytes);
+ }
+}
diff --git
a/foundations/foundation-vertx/src/main/java/org/apache/servicecomb/foundation/vertx/metrics/metric/DefaultHttpSocketMetric.java
b/foundations/foundation-vertx/src/main/java/org/apache/servicecomb/foundation/vertx/metrics/metric/DefaultHttpSocketMetric.java
new file mode 100644
index 000000000..b486b622b
--- /dev/null
+++
b/foundations/foundation-vertx/src/main/java/org/apache/servicecomb/foundation/vertx/metrics/metric/DefaultHttpSocketMetric.java
@@ -0,0 +1,70 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 org.apache.servicecomb.foundation.vertx.metrics.metric;
+
+public class DefaultHttpSocketMetric {
+ private DefaultEndpointMetric endpointMetric;
+
+ private boolean connected = true;
+
+ private long connectedTime = System.nanoTime();
+
+ private long requestBeginTime;
+
+ private long requestEndTime;
+
+ public DefaultHttpSocketMetric(DefaultEndpointMetric endpointMetric) {
+ this.endpointMetric = endpointMetric;
+ }
+
+ public void setEndpointMetric(DefaultEndpointMetric endpointMetric) {
+ this.endpointMetric = endpointMetric;
+ }
+
+ @SuppressWarnings("unchecked")
+ public <T extends DefaultEndpointMetric> T getEndpointMetric() {
+ return (T) endpointMetric;
+ }
+
+ public boolean isConnected() {
+ return connected;
+ }
+
+ public void setConnected(boolean connected) {
+ this.connected = connected;
+ }
+
+ public long getConnectedTime() {
+ return connectedTime;
+ }
+
+ public long getRequestBeginTime() {
+ return requestBeginTime;
+ }
+
+ public void requestBegin() {
+ this.requestBeginTime = System.nanoTime();
+ }
+
+ public long getRequestEndTime() {
+ return requestEndTime;
+ }
+
+ public void requestEnd() {
+ this.requestEndTime = System.nanoTime();
+ }
+}
diff --git
a/foundations/foundation-vertx/src/test/java/org/apache/servicecomb/foundation/vertx/metrics/TestDefaultHttpClientMetrics.java
b/foundations/foundation-vertx/src/test/java/org/apache/servicecomb/foundation/vertx/metrics/TestDefaultHttpClientMetrics.java
new file mode 100644
index 000000000..0f1de3188
--- /dev/null
+++
b/foundations/foundation-vertx/src/test/java/org/apache/servicecomb/foundation/vertx/metrics/TestDefaultHttpClientMetrics.java
@@ -0,0 +1,313 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 org.apache.servicecomb.foundation.vertx.metrics;
+
+import
org.apache.servicecomb.foundation.vertx.metrics.metric.DefaultClientEndpointMetric;
+import
org.apache.servicecomb.foundation.vertx.metrics.metric.DefaultHttpSocketMetric;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+import io.vertx.core.Vertx;
+import io.vertx.core.VertxOptions;
+import io.vertx.core.http.HttpClient;
+import io.vertx.core.http.HttpClientOptions;
+import io.vertx.core.http.HttpClientRequest;
+import io.vertx.core.net.SocketAddress;
+import io.vertx.core.net.impl.SocketAddressImpl;
+import mockit.Mock;
+import mockit.MockUp;
+import mockit.Mocked;
+
+public class TestDefaultHttpClientMetrics {
+ @Mocked
+ Vertx vertx;
+
+ VertxOptions vertxOptions = new VertxOptions();
+
+ MetricsOptionsEx metricsOptionsEx = new MetricsOptionsEx();
+
+ @Mocked
+ HttpClient anyHttpClient;
+
+ HttpClientOptions options = new HttpClientOptions();
+
+ DefaultVertxMetrics defaultVertxMetrics;
+
+ DefaultHttpClientMetrics clientMetrics_a;
+
+ DefaultHttpClientMetrics clientMetrics_b;
+
+ String host = "host";
+
+ int port1 = 1;
+
+ int port2 = 2;
+
+ int maxPoolSize = 5;
+
+ SocketAddress address1 = new SocketAddressImpl(port1, host);
+
+ SocketAddress address2 = new SocketAddressImpl(port2, host);
+
+ DefaultClientEndpointMetric endpointMetric_a_1;
+
+ DefaultClientEndpointMetric endpointMetric_a_2;
+
+ DefaultClientEndpointMetric endpointMetric_b_1;
+
+ DefaultClientEndpointMetric endpointMetric_b_2;
+
+ static long nanoTime = 1;
+
+ @BeforeClass
+ public static void classSetup() {
+ new MockUp<System>() {
+ @Mock
+ long nanoTime() {
+ return nanoTime;
+ }
+ };
+ }
+
+ @Before
+ public void setup() {
+ vertxOptions.setMetricsOptions(metricsOptionsEx);
+ defaultVertxMetrics = new DefaultVertxMetrics(vertx, vertxOptions);
+ clientMetrics_a = (DefaultHttpClientMetrics)
defaultVertxMetrics.createMetrics(anyHttpClient, options);
+ clientMetrics_b = (DefaultHttpClientMetrics)
defaultVertxMetrics.createMetrics(anyHttpClient, options);
+
+ endpointMetric_a_1 = clientMetrics_a.createEndpoint(host, port1,
maxPoolSize);
+ endpointMetric_a_2 = clientMetrics_a.createEndpoint(host, port2,
maxPoolSize);
+
+ endpointMetric_b_1 = clientMetrics_b.createEndpoint(host, port1,
maxPoolSize);
+ endpointMetric_b_2 = clientMetrics_b.createEndpoint(host, port2,
maxPoolSize);
+ }
+
+ @Test
+ public void createMetrics() {
+ Assert.assertNotSame(clientMetrics_a, clientMetrics_b);
+ }
+
+ @Test
+ public void createEndpoint() {
+ Assert.assertSame(endpointMetric_a_1, endpointMetric_b_1);
+ Assert.assertNotSame(endpointMetric_a_1, endpointMetric_a_2);
+
+ Assert.assertNotSame(endpointMetric_a_2, endpointMetric_b_1);
+ Assert.assertSame(endpointMetric_a_2, endpointMetric_b_2);
+
+ Assert.assertEquals(1, endpointMetric_a_1.getLastNanoTime());
+ Assert.assertEquals(2, endpointMetric_a_1.getRefCount());
+
+ Assert.assertEquals(1, endpointMetric_a_2.getLastNanoTime());
+ Assert.assertEquals(2, endpointMetric_a_2.getRefCount());
+ }
+
+ @Test
+ public void closeEndpoint() {
+ nanoTime = 2;
+ endpointMetric_a_1.decRefCount();
+
+ Assert.assertEquals(2, endpointMetric_a_1.getLastNanoTime());
+ Assert.assertEquals(1, endpointMetric_a_1.getRefCount());
+ }
+
+ @Test
+ public void expire() {
+ metricsOptionsEx.setCheckClientEndpointMetricExpiredInNano(10);
+
+ nanoTime = 2;
+ clientMetrics_a.closeEndpoint(host, port1, endpointMetric_a_1);
+ clientMetrics_a.closeEndpoint(host, port1, endpointMetric_a_2);
+
+ nanoTime = 13;
+
defaultVertxMetrics.getClientEndpointMetricManager().onCheckClientEndpointMetricExpired(0);
+
Assert.assertNotNull(defaultVertxMetrics.getClientEndpointMetricManager().getClientEndpointMetric(address1));
+
Assert.assertNotNull(defaultVertxMetrics.getClientEndpointMetricManager().getClientEndpointMetric(address2));
+
+ clientMetrics_b.closeEndpoint(host, port1, endpointMetric_b_1);
+ clientMetrics_b.closeEndpoint(host, port1, endpointMetric_b_2);
+
+ nanoTime = 23;
+
defaultVertxMetrics.getClientEndpointMetricManager().onCheckClientEndpointMetricExpired(0);
+
Assert.assertNotNull(defaultVertxMetrics.getClientEndpointMetricManager().getClientEndpointMetric(address1));
+
Assert.assertNotNull(defaultVertxMetrics.getClientEndpointMetricManager().getClientEndpointMetric(address2));
+
+ nanoTime = 24;
+
defaultVertxMetrics.getClientEndpointMetricManager().onCheckClientEndpointMetricExpired(0);
+
Assert.assertNull(defaultVertxMetrics.getClientEndpointMetricManager().getClientEndpointMetric(address1));
+
Assert.assertNull(defaultVertxMetrics.getClientEndpointMetricManager().getClientEndpointMetric(address2));
+ }
+
+ @Test
+ public void connect() {
+ {
+ nanoTime = 1;
+ DefaultHttpSocketMetric socketMetric =
clientMetrics_a.connected(address1, host);
+ clientMetrics_a.endpointConnected(endpointMetric_a_1, socketMetric);
+
+ Assert.assertSame(endpointMetric_a_1, socketMetric.getEndpointMetric());
+ Assert.assertTrue(socketMetric.isConnected());
+ Assert.assertEquals(1, socketMetric.getConnectedTime());
+ Assert.assertEquals(1,
socketMetric.getEndpointMetric().getConnectCount());
+ Assert.assertEquals(0,
socketMetric.getEndpointMetric().getDisconnectCount());
+ Assert.assertEquals(1,
socketMetric.getEndpointMetric().getCurrentConnectionCount());
+
+ nanoTime = 2;
+ clientMetrics_a.endpointDisconnected(socketMetric.getEndpointMetric(),
socketMetric);
+
+ Assert.assertFalse(socketMetric.isConnected());
+ Assert.assertEquals(1, socketMetric.getConnectedTime());
+ Assert.assertEquals(1,
socketMetric.getEndpointMetric().getConnectCount());
+ Assert.assertEquals(1,
socketMetric.getEndpointMetric().getDisconnectCount());
+ Assert.assertEquals(0,
socketMetric.getEndpointMetric().getCurrentConnectionCount());
+ }
+
+ {
+ nanoTime = 3;
+ DefaultHttpSocketMetric socketMetric =
clientMetrics_a.connected(address2, host);
+ clientMetrics_a.endpointConnected(endpointMetric_a_2, socketMetric);
+
+ Assert.assertSame(endpointMetric_a_2, socketMetric.getEndpointMetric());
+ Assert.assertTrue(socketMetric.isConnected());
+ Assert.assertEquals(3, socketMetric.getConnectedTime());
+ Assert.assertEquals(1,
socketMetric.getEndpointMetric().getConnectCount());
+ Assert.assertEquals(0,
socketMetric.getEndpointMetric().getDisconnectCount());
+ Assert.assertEquals(1,
socketMetric.getEndpointMetric().getCurrentConnectionCount());
+
+ nanoTime = 4;
+ clientMetrics_a.endpointDisconnected(socketMetric.getEndpointMetric(),
socketMetric);
+
+ Assert.assertFalse(socketMetric.isConnected());
+ Assert.assertEquals(3, socketMetric.getConnectedTime());
+ Assert.assertEquals(1,
socketMetric.getEndpointMetric().getConnectCount());
+ Assert.assertEquals(1,
socketMetric.getEndpointMetric().getDisconnectCount());
+ Assert.assertEquals(0,
socketMetric.getEndpointMetric().getCurrentConnectionCount());
+ }
+
+ {
+ nanoTime = 5;
+ DefaultHttpSocketMetric socketMetric =
clientMetrics_b.connected(address1, host);
+ clientMetrics_b.endpointConnected(endpointMetric_b_1, socketMetric);
+
+ Assert.assertSame(endpointMetric_b_1, socketMetric.getEndpointMetric());
+ Assert.assertTrue(socketMetric.isConnected());
+ Assert.assertEquals(5, socketMetric.getConnectedTime());
+ Assert.assertEquals(2,
socketMetric.getEndpointMetric().getConnectCount());
+ Assert.assertEquals(1,
socketMetric.getEndpointMetric().getDisconnectCount());
+ Assert.assertEquals(1,
socketMetric.getEndpointMetric().getCurrentConnectionCount());
+
+ nanoTime = 6;
+ clientMetrics_b.endpointDisconnected(socketMetric.getEndpointMetric(),
socketMetric);
+
+ Assert.assertFalse(socketMetric.isConnected());
+ Assert.assertEquals(5, socketMetric.getConnectedTime());
+ Assert.assertEquals(2,
socketMetric.getEndpointMetric().getConnectCount());
+ Assert.assertEquals(2,
socketMetric.getEndpointMetric().getDisconnectCount());
+ Assert.assertEquals(0,
socketMetric.getEndpointMetric().getCurrentConnectionCount());
+ }
+
+ {
+ nanoTime = 6;
+ DefaultHttpSocketMetric socketMetric =
clientMetrics_b.connected(address2, host);
+ clientMetrics_b.endpointConnected(endpointMetric_b_2, socketMetric);
+
+ Assert.assertSame(endpointMetric_b_2, socketMetric.getEndpointMetric());
+ Assert.assertTrue(socketMetric.isConnected());
+ Assert.assertEquals(6, socketMetric.getConnectedTime());
+ Assert.assertEquals(2,
socketMetric.getEndpointMetric().getConnectCount());
+ Assert.assertEquals(1,
socketMetric.getEndpointMetric().getDisconnectCount());
+ Assert.assertEquals(1,
socketMetric.getEndpointMetric().getCurrentConnectionCount());
+
+ nanoTime = 7;
+ clientMetrics_b.endpointDisconnected(socketMetric.getEndpointMetric(),
socketMetric);
+
+ Assert.assertFalse(socketMetric.isConnected());
+ Assert.assertEquals(6, socketMetric.getConnectedTime());
+ Assert.assertEquals(2,
socketMetric.getEndpointMetric().getConnectCount());
+ Assert.assertEquals(2,
socketMetric.getEndpointMetric().getDisconnectCount());
+ Assert.assertEquals(0,
socketMetric.getEndpointMetric().getCurrentConnectionCount());
+ }
+ }
+
+ @Test
+ public void bytesReadAndWritten() {
+ DefaultHttpSocketMetric socketMetric = clientMetrics_a.connected(address1,
host);
+ clientMetrics_a.endpointConnected(endpointMetric_a_1, socketMetric);
+ clientMetrics_a.bytesRead(socketMetric, address1, 1);
+ clientMetrics_a.bytesWritten(socketMetric, address1, 1);
+
+ socketMetric = clientMetrics_a.connected(address2, host);
+ clientMetrics_a.endpointConnected(endpointMetric_a_2, socketMetric);
+ clientMetrics_a.bytesRead(socketMetric, address2, 1);
+ clientMetrics_a.bytesWritten(socketMetric, address2, 1);
+
+ socketMetric = clientMetrics_b.connected(address1, host);
+ clientMetrics_b.endpointConnected(endpointMetric_b_1, socketMetric);
+ clientMetrics_b.bytesRead(socketMetric, address1, 1);
+ clientMetrics_b.bytesWritten(socketMetric, address1, 1);
+
+ socketMetric = clientMetrics_b.connected(address2, host);
+ clientMetrics_b.endpointConnected(endpointMetric_b_2, socketMetric);
+ clientMetrics_b.bytesRead(socketMetric, address2, 1);
+ clientMetrics_b.bytesWritten(socketMetric, address2, 1);
+
+ Assert.assertEquals(2, endpointMetric_a_1.getBytesRead());
+ Assert.assertEquals(2, endpointMetric_a_2.getBytesRead());
+ Assert.assertEquals(2, endpointMetric_a_1.getBytesWritten());
+ Assert.assertEquals(2, endpointMetric_a_2.getBytesWritten());
+ }
+
+ @Test
+ public void requestBegin(@Mocked HttpClientRequest request) {
+ DefaultHttpSocketMetric socketMetric = clientMetrics_a.connected(address1,
host);
+
+ nanoTime = 2;
+ clientMetrics_a.requestBegin(endpointMetric_a_1, socketMetric, address1,
address1, request);
+ nanoTime = 3;
+ clientMetrics_a.requestEnd(socketMetric);
+
+ Assert.assertEquals(2, socketMetric.getRequestBeginTime());
+ Assert.assertEquals(3, socketMetric.getRequestEndTime());
+ }
+
+ @SuppressWarnings("deprecation")
+ @Test
+ public void meaningless() {
+ Assert.assertSame(anyHttpClient, clientMetrics_a.getClient());
+ Assert.assertSame(anyHttpClient, clientMetrics_b.getClient());
+
+ Assert.assertSame(options, clientMetrics_a.getOptions());
+ Assert.assertSame(options, clientMetrics_b.getOptions());
+
+ Assert.assertTrue(clientMetrics_a.isEnabled());
+
+ clientMetrics_a.enqueueRequest(endpointMetric_a_1);
+ clientMetrics_a.dequeueRequest(endpointMetric_a_1, null);
+ clientMetrics_a.responseBegin(null, null);
+ clientMetrics_a.responsePushed(null, null, null, null, null);
+ clientMetrics_a.requestReset(null);
+ clientMetrics_a.responseEnd(null, null);
+ clientMetrics_a.connected(null, null, null);
+ clientMetrics_a.disconnected(null);
+ clientMetrics_a.disconnected(null, null);
+ clientMetrics_a.exceptionOccurred(null, null, null);
+ clientMetrics_a.close();
+ }
+}
diff --git
a/foundations/foundation-vertx/src/test/java/org/apache/servicecomb/foundation/vertx/metrics/TestDefaultHttpServerMetrics.java
b/foundations/foundation-vertx/src/test/java/org/apache/servicecomb/foundation/vertx/metrics/TestDefaultHttpServerMetrics.java
new file mode 100644
index 000000000..b039cdd91
--- /dev/null
+++
b/foundations/foundation-vertx/src/test/java/org/apache/servicecomb/foundation/vertx/metrics/TestDefaultHttpServerMetrics.java
@@ -0,0 +1,209 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 org.apache.servicecomb.foundation.vertx.metrics;
+
+import java.util.IdentityHashMap;
+import java.util.Map;
+
+import
org.apache.servicecomb.foundation.vertx.metrics.metric.DefaultEndpointMetric;
+import
org.apache.servicecomb.foundation.vertx.metrics.metric.DefaultHttpSocketMetric;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+
+import io.vertx.core.Vertx;
+import io.vertx.core.VertxOptions;
+import io.vertx.core.http.HttpServer;
+import io.vertx.core.http.HttpServerOptions;
+import io.vertx.core.net.SocketAddress;
+import mockit.Mocked;
+
+public class TestDefaultHttpServerMetrics {
+ @Mocked
+ Vertx vertx;
+
+ VertxOptions vertxOptions = new VertxOptions();
+
+ MetricsOptionsEx metricsOptionsEx = new MetricsOptionsEx();
+
+ DefaultVertxMetrics defaultVertxMetrics;
+
+ @Mocked
+ HttpServer listen1_server1;
+
+ @Mocked
+ HttpServer listen1_server2;
+
+ @Mocked
+ SocketAddress listen1_addr;
+
+ @Mocked
+ HttpServer listen2_server1;
+
+ @Mocked
+ HttpServer listen2_server2;
+
+ @Mocked
+ SocketAddress listen2_addr;
+
+ @Mocked
+ HttpServerOptions options;
+
+ @Mocked
+ SocketAddress anyRemoteAddr;
+
+ DefaultHttpServerMetrics metrics_listen1_server1;
+
+ DefaultHttpServerMetrics metrics_listen1_server2;
+
+ DefaultEndpointMetric endpointMetric1;
+
+ DefaultHttpServerMetrics metrics_listen2_server1;
+
+ DefaultHttpServerMetrics metrics_listen2_server2;
+
+ DefaultEndpointMetric endpointMetric2;
+
+ String remoteName = "remote";
+
+ DefaultHttpSocketMetric socketMetric_listen1_1;
+
+ DefaultHttpSocketMetric socketMetric_listen1_2;
+
+ DefaultHttpSocketMetric socketMetric_listen2_1;
+
+ DefaultHttpSocketMetric socketMetric_listen2_2;
+
+ DefaultHttpSocketMetric socketMetric_listen2_3;
+
+ @Before
+ public void setup() {
+ vertxOptions.setMetricsOptions(metricsOptionsEx);
+ defaultVertxMetrics = new DefaultVertxMetrics(vertx, vertxOptions);
+
+ metrics_listen1_server1 = (DefaultHttpServerMetrics) defaultVertxMetrics
+ .createMetrics(listen1_server1, listen1_addr, options);
+ metrics_listen1_server2 = (DefaultHttpServerMetrics) defaultVertxMetrics
+ .createMetrics(listen1_server2, listen1_addr, options);
+ endpointMetric1 = metrics_listen1_server1.getEndpointMetric();
+
+ metrics_listen2_server1 = (DefaultHttpServerMetrics) defaultVertxMetrics
+ .createMetrics(listen2_server1, listen2_addr, options);
+ metrics_listen2_server2 = (DefaultHttpServerMetrics) defaultVertxMetrics
+ .createMetrics(listen2_server2, listen2_addr, options);
+ endpointMetric2 = metrics_listen2_server1.getEndpointMetric();
+
+ socketMetric_listen1_1 = metrics_listen1_server1.connected(anyRemoteAddr,
remoteName);
+ socketMetric_listen1_2 = metrics_listen1_server2.connected(anyRemoteAddr,
remoteName);
+ socketMetric_listen2_1 = metrics_listen2_server1.connected(anyRemoteAddr,
remoteName);
+ socketMetric_listen2_2 = metrics_listen2_server2.connected(anyRemoteAddr,
remoteName);
+ socketMetric_listen2_3 = metrics_listen2_server2.connected(anyRemoteAddr,
remoteName);
+ }
+
+ @Test
+ public void createMetrics() {
+ Map<Object, Object> instances = new IdentityHashMap<>();
+ instances.put(metrics_listen1_server1, null);
+ instances.put(metrics_listen1_server2, null);
+ instances.put(metrics_listen2_server1, null);
+ instances.put(metrics_listen2_server2, null);
+ Assert.assertEquals(4, instances.size());
+
+ Assert.assertSame(metrics_listen1_server1.getEndpointMetric(),
metrics_listen1_server2.getEndpointMetric());
+ Assert.assertNotSame(metrics_listen1_server1.getEndpointMetric(),
metrics_listen2_server1.getEndpointMetric());
+ Assert.assertSame(metrics_listen2_server1.getEndpointMetric(),
metrics_listen2_server2.getEndpointMetric());
+ }
+
+ @Test
+ public void connectionCount() {
+ Map<Object, Object> instances = new IdentityHashMap<>();
+ instances.put(socketMetric_listen1_1, null);
+ instances.put(socketMetric_listen1_2, null);
+ instances.put(socketMetric_listen2_1, null);
+ instances.put(socketMetric_listen2_2, null);
+ instances.put(socketMetric_listen2_3, null);
+ Assert.assertEquals(5, instances.size());
+
+ Assert.assertTrue(socketMetric_listen1_1.isConnected());
+ Assert.assertTrue(socketMetric_listen1_2.isConnected());
+ Assert.assertTrue(socketMetric_listen2_1.isConnected());
+ Assert.assertTrue(socketMetric_listen2_2.isConnected());
+ Assert.assertTrue(socketMetric_listen2_3.isConnected());
+
+ Assert.assertEquals(2, endpointMetric1.getCurrentConnectionCount());
+ Assert.assertEquals(3, endpointMetric2.getCurrentConnectionCount());
+
+ // disconnect
+ metrics_listen1_server1.disconnected(socketMetric_listen1_1,
anyRemoteAddr);
+ metrics_listen1_server2.disconnected(socketMetric_listen1_2,
anyRemoteAddr);
+ metrics_listen2_server1.disconnected(socketMetric_listen2_1,
anyRemoteAddr);
+ metrics_listen2_server2.disconnected(socketMetric_listen2_2,
anyRemoteAddr);
+ metrics_listen2_server2.disconnected(socketMetric_listen2_3,
anyRemoteAddr);
+
+ Assert.assertFalse(socketMetric_listen1_1.isConnected());
+ Assert.assertFalse(socketMetric_listen1_2.isConnected());
+ Assert.assertFalse(socketMetric_listen2_1.isConnected());
+ Assert.assertFalse(socketMetric_listen2_2.isConnected());
+ Assert.assertFalse(socketMetric_listen2_3.isConnected());
+
+ Assert.assertEquals(0, endpointMetric1.getCurrentConnectionCount());
+ Assert.assertEquals(0, endpointMetric2.getCurrentConnectionCount());
+ }
+
+ @Test
+ public void bytesRead() {
+ metrics_listen1_server1.bytesRead(socketMetric_listen1_1, anyRemoteAddr,
1);
+ metrics_listen1_server2.bytesRead(socketMetric_listen1_2, anyRemoteAddr,
2);
+ metrics_listen2_server1.bytesRead(socketMetric_listen2_1, anyRemoteAddr,
3);
+ metrics_listen2_server2.bytesRead(socketMetric_listen2_2, anyRemoteAddr,
4);
+ metrics_listen2_server2.bytesRead(socketMetric_listen2_3, anyRemoteAddr,
5);
+
+ Assert.assertEquals(3, endpointMetric1.getBytesRead());
+ Assert.assertEquals(12, endpointMetric2.getBytesRead());
+ }
+
+ @Test
+ public void bytesWritten() {
+ metrics_listen1_server1.bytesWritten(socketMetric_listen1_1,
anyRemoteAddr, 1);
+ metrics_listen1_server2.bytesWritten(socketMetric_listen1_2,
anyRemoteAddr, 2);
+ metrics_listen2_server1.bytesWritten(socketMetric_listen2_1,
anyRemoteAddr, 3);
+ metrics_listen2_server2.bytesWritten(socketMetric_listen2_2,
anyRemoteAddr, 4);
+ metrics_listen2_server2.bytesWritten(socketMetric_listen2_3,
anyRemoteAddr, 5);
+
+ Assert.assertEquals(3, endpointMetric1.getBytesWritten());
+ Assert.assertEquals(12, endpointMetric2.getBytesWritten());
+ }
+
+ @SuppressWarnings("deprecation")
+ @Test
+ public void meaningless() {
+ Assert.assertSame(listen1_server1, metrics_listen1_server1.getServer());
+ Assert.assertSame(listen1_addr, metrics_listen1_server1.getLocalAddress());
+ Assert.assertSame(options, metrics_listen1_server1.getOptions());
+ Assert.assertTrue(metrics_listen1_server1.isEnabled());
+
+ metrics_listen1_server1.requestBegin(null, null);
+ metrics_listen1_server1.requestReset(null);
+ metrics_listen1_server1.responsePushed(null, null, null, null);
+ metrics_listen1_server1.responseEnd(null, null);
+ metrics_listen1_server1.upgrade(null, null);
+ metrics_listen1_server1.connected((DefaultHttpSocketMetric) null, null);
+ metrics_listen1_server1.disconnected(null);
+ metrics_listen1_server1.exceptionOccurred(null, null, null);
+ metrics_listen1_server1.close();
+ }
+}
diff --git
a/foundations/foundation-vertx/src/test/java/org/apache/servicecomb/foundation/vertx/metrics/TestDefaultVertxMetricsFactory.java
b/foundations/foundation-vertx/src/test/java/org/apache/servicecomb/foundation/vertx/metrics/TestDefaultVertxMetricsFactory.java
new file mode 100644
index 000000000..a96f23c7f
--- /dev/null
+++
b/foundations/foundation-vertx/src/test/java/org/apache/servicecomb/foundation/vertx/metrics/TestDefaultVertxMetricsFactory.java
@@ -0,0 +1,51 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 org.apache.servicecomb.foundation.vertx.metrics;
+
+import org.junit.Assert;
+import org.junit.Test;
+
+import io.vertx.core.Vertx;
+import io.vertx.core.VertxOptions;
+import io.vertx.core.metrics.MetricsOptions;
+import io.vertx.core.spi.metrics.VertxMetrics;
+import mockit.Mocked;
+
+public class TestDefaultVertxMetricsFactory {
+ @Mocked
+ Vertx vertx;
+
+ VertxOptions options = new VertxOptions();
+
+ DefaultVertxMetricsFactory factory = new DefaultVertxMetricsFactory();
+
+ @SuppressWarnings("deprecation")
+ @Test
+ public void metrics() {
+ MetricsOptions metricsOptions = factory.newOptions();
+ options.setMetricsOptions(metricsOptions);
+ VertxMetrics vertxMetrics = factory.metrics(vertx, options);
+
+ Assert.assertSame(factory, metricsOptions.getFactory());
+ Assert.assertTrue(metricsOptions.isEnabled());
+
+ Assert.assertSame(factory.getVertxMetrics(), vertxMetrics);
+ Assert.assertSame(vertx, ((DefaultVertxMetrics) vertxMetrics).getVertx());
+ Assert.assertTrue(vertxMetrics.isMetricsEnabled());
+ Assert.assertTrue(vertxMetrics.isEnabled());
+ }
+}
diff --git
a/foundations/foundation-vertx/src/test/java/org/apache/servicecomb/foundation/vertx/metrics/TestMetricsOptionsEx.java
b/foundations/foundation-vertx/src/test/java/org/apache/servicecomb/foundation/vertx/metrics/TestMetricsOptionsEx.java
new file mode 100644
index 000000000..cced3533b
--- /dev/null
+++
b/foundations/foundation-vertx/src/test/java/org/apache/servicecomb/foundation/vertx/metrics/TestMetricsOptionsEx.java
@@ -0,0 +1,47 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 org.apache.servicecomb.foundation.vertx.metrics;
+
+import java.util.concurrent.TimeUnit;
+
+import org.junit.Assert;
+import org.junit.Test;
+
+public class TestMetricsOptionsEx {
+ MetricsOptionsEx metricsOptionsEx = new MetricsOptionsEx();
+
+ @Test
+ public void interval() {
+ Assert.assertEquals(TimeUnit.MINUTES.toMillis(1),
+ metricsOptionsEx.getCheckClientEndpointMetricIntervalInMilliseconds());
+
+ metricsOptionsEx.setCheckClientEndpointMetricIntervalInMinute(2);
+ Assert.assertEquals(TimeUnit.MINUTES.toMillis(2),
+ metricsOptionsEx.getCheckClientEndpointMetricIntervalInMilliseconds());
+ }
+
+ @Test
+ public void expired() {
+ Assert.assertEquals(TimeUnit.MINUTES.toNanos(30),
metricsOptionsEx.getCheckClientEndpointMetricExpiredInNano());
+
+ metricsOptionsEx.setCheckClientEndpointMetricExpiredInNano(10);
+ Assert.assertEquals(10,
metricsOptionsEx.getCheckClientEndpointMetricExpiredInNano());
+
+ metricsOptionsEx.setCheckClientEndpointMetricExpiredInMinute(60);
+ Assert.assertEquals(TimeUnit.MINUTES.toNanos(60),
metricsOptionsEx.getCheckClientEndpointMetricExpiredInNano());
+ }
+}
----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on GitHub and use the
URL above to go to the specific comment.
For queries about this service, please contact Infrastructure at:
[email protected]
> measure httpServer and httpClient
> ---------------------------------
>
> Key: SCB-894
> URL: https://issues.apache.org/jira/browse/SCB-894
> Project: Apache ServiceComb
> Issue Type: Sub-task
> Components: Java-Chassis
> Reporter: wujimin
> Assignee: wujimin
> Priority: Major
> Fix For: java-chassis-1.1.0
>
>
> * http server endpoint for each listen address
> ** summary of connect count
> ** summary of disconnect count
> ** current connection count: connect - disconnect
> ** summary of bytes read
> ** summary of bytes written
> * http server socket
> ** connected flag
> ** connected nano time
> * http client endpoint for each remote address
> ** same to http server endpoint
> ** expired check after connection pool closed
> * http client socket
> ** same to http server socket
> ** nano time of got a connection from pool, by this we can know how long did
> it take to got a connection
> ** nano time of written request to netty queue
--
This message was sent by Atlassian JIRA
(v7.6.3#76005)