add netty4 metrics. (#12695)

This commit is contained in:
胡俊 2023-08-09 15:46:03 +08:00 committed by GitHub
parent 059fdf2613
commit 04f3fe7d2b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
28 changed files with 437 additions and 68 deletions

View File

@ -65,6 +65,7 @@ dubbo-metrics-metadata
dubbo-metrics-prometheus
dubbo-metrics-registry
dubbo-metrics-config-center
dubbo-metrics-netty
dubbo-monitor
dubbo-monitor-api
dubbo-monitor-common

View File

@ -61,6 +61,11 @@ public class MetricsConfig extends AbstractConfig {
*/
private Boolean exportMetricsService;
/**
* Enable netty metrics.
*/
private Boolean enableNetty;
/**
* @deprecated After metrics config is refactored.
* This parameter should no longer use and will be deleted in the future.
@ -223,4 +228,12 @@ public class MetricsConfig extends AbstractConfig {
public void setEnableRpc(Boolean enableRpc) {
this.enableRpc = enableRpc;
}
public Boolean getEnableNetty() {
return enableNetty;
}
public void setEnableNetty(Boolean enableNetty) {
this.enableNetty = enableNetty;
}
}

View File

@ -1092,6 +1092,12 @@
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="enable-netty" type="xsd:boolean" default="true">
<xsd:annotation>
<xsd:documentation><![CDATA[ Enable netty metrics when collecting. ]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="export-metrics-service" type="xsd:boolean" default="true">
<xsd:annotation>
<xsd:documentation><![CDATA[ Enable export metrics service. ]]></xsd:documentation>

View File

@ -232,6 +232,13 @@
<scope>compile</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-metrics-netty</artifactId>
<version>${project.version}</version>
<scope>compile</scope>
<optional>true</optional>
</dependency>
<!-- tracing -->
<dependency>
@ -688,6 +695,7 @@
<include>org.apache.dubbo:dubbo-metrics-registry</include>
<include>org.apache.dubbo:dubbo-metrics-metadata</include>
<include>org.apache.dubbo:dubbo-metrics-config-center</include>
<include>org.apache.dubbo:dubbo-metrics-netty</include>
<include>org.apache.dubbo:dubbo-metrics-prometheus</include>
<include>org.apache.dubbo:dubbo-tracing</include>
<include>org.apache.dubbo:dubbo-monitor-api</include>

View File

@ -276,6 +276,11 @@
<artifactId>dubbo-metrics-config-center</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-metrics-netty</artifactId>
<version>${project.version}</version>
</dependency>
<!-- tracing -->
<dependency>

View File

@ -22,8 +22,8 @@ public interface MetricsConstants {
String INVOCATION = "metric_filter_invocation";
String METHOD_METRICS = "metric_filter_method_metrics";
String INVOCATION_METRICS_COUNTER = "metric_filter_invocation_counter";
String INVOCATION_SIDE = "metric_filter_side";
String INVOCATION_REQUEST_ERROR = "metric_request_error";
String ATTACHMENT_KEY_SERVICE = "serviceKey";
String ATTACHMENT_KEY_SIZE = "size";
@ -32,4 +32,6 @@ public interface MetricsConstants {
int SELF_INCREMENT_SIZE = 1;
String NETTY_METRICS_MAP = "nettyMetricsMap";
}

View File

@ -80,6 +80,10 @@ public abstract class CombMetricsCollector<E extends TimeCounterEvent> extends A
stats.calcMethodKeyRt(invocation, registryOpType, responseTime);
}
public void setAppNum(MetricsKey metricsKey,Long num) {
stats.setAppKey(metricsKey, num);
}
@Override
public void increment(MethodMetric methodMetric, MetricsKeyWrapper wrapper, int size) {
this.stats.incrementMethodKey(wrapper, methodMetric, size);

View File

@ -60,6 +60,12 @@ public class ApplicationStatComposite extends AbstractMetricsExport {
applicationNumStats.get(metricsKey).getAndAdd(size);
}
public void setAppKey(MetricsKey metricsKey, Long num){
if (!applicationNumStats.containsKey(metricsKey)) {
return;
}
applicationNumStats.get(metricsKey).set(num);
}
public List<MetricSample> export(MetricsCategory category) {
List<MetricSample> list = new ArrayList<>();

View File

@ -118,4 +118,8 @@ public abstract class BaseStatComposite implements MetricsExport {
public RtStatComposite getRtStatComposite() {
return rtStatComposite;
}
public void setAppKey(MetricsKey metricsKey, Long num) {
applicationStatComposite.setAppKey(metricsKey, num);
}
}

View File

@ -29,4 +29,5 @@ public enum MetricsCategory {
REGISTRY,
METADATA,
THREAD_POOL,
NETTY,
}

View File

@ -123,6 +123,18 @@ public enum MetricsKey {
// consumer metrics key
INVOKER_NO_AVAILABLE_COUNT("dubbo.consumer.invoker.no.available.count", "Request Throw No Invoker Available Exception Count"),
// netty metrics key
NETTY_ALLOCATOR_HEAP_MEMORY_USED("netty.allocator.memory.used", "Netty Allocator Memory Used"),
NETTY_ALLOCATOR_DIRECT_MEMORY_USED("netty.allocator.direct.memory.used", "Netty Allocator Direct Memory Used"),
NETTY_ALLOCATOR_PINNED_DIRECT_MEMORY("netty.allocator.pinned.direct.memory", "Netty Allocator Pinned Direct Memory"),
NETTY_ALLOCATOR_PINNED_HEAP_MEMORY("netty.allocator.pinned.heap.memory", "Netty Allocator Pinned Heap Memory"),
NETTY_ALLOCATOR_HEAP_ARENAS_NUM("netty.allocator.heap.arenas.num", "Netty Allocator Heap Arenas Num"),
NETTY_ALLOCATOR_DIRECT_ARENAS_NUM("netty.allocator.direct.arenas.num", "Netty Allocator Direct Arenas Num"),
NETTY_ALLOCATOR_NORMAL_CACHE_SIZE("netty.allocator.normal.cache.size", "Netty Allocator Normal Cache Size"),
NETTY_ALLOCATOR_SMALL_CACHE_SIZE("netty.allocator.small.cache.size", "Netty Allocator Small Cache Size"),
NETTY_ALLOCATOR_THREAD_LOCAL_CACHES_NUM("netty.allocator.thread.local.caches.num", "Netty Allocator Thread Local Caches Num"),
NETTY_ALLOCATOR_CHUNK_SIZE("netty.allocator.chunk.size", "Netty Allocator Chunk Size"),
;
private String name;
@ -136,6 +148,15 @@ public enum MetricsKey {
return String.format(name, type);
}
public static MetricsKey getMetricsByName(String name){
for (MetricsKey metricsKey : MetricsKey.values()) {
if (metricsKey.getName().equals(name)) {
return metricsKey;
}
}
return null;
}
public final String getDescription() {
return this.description;
}

View File

@ -29,7 +29,6 @@ import org.apache.dubbo.metrics.data.MethodStatComposite;
import org.apache.dubbo.metrics.data.RtStatComposite;
import org.apache.dubbo.metrics.event.DefaultSubDispatcher;
import org.apache.dubbo.metrics.event.MetricsEvent;
import org.apache.dubbo.metrics.event.RequestBeforeEvent;
import org.apache.dubbo.metrics.event.RequestEvent;
import org.apache.dubbo.metrics.model.ApplicationMetric;
import org.apache.dubbo.metrics.model.MetricsCategory;
@ -138,7 +137,7 @@ public class DefaultMetricsCollector extends CombMetricsCollector<RequestEvent>
@Override
public boolean isSupport(MetricsEvent event) {
return event instanceof RequestEvent || event instanceof RequestBeforeEvent;
return event instanceof RequestEvent;
}
public SimpleMetricsCountSampler<String, MetricsEvent.Type, ApplicationMetric> applicationSampler = new SimpleMetricsCountSampler<String, MetricsEvent.Type, ApplicationMetric>() {

View File

@ -43,17 +43,16 @@ public final class DefaultSubDispatcher extends SimpleMetricsEventMulticaster {
super.addListener(categoryOverall.getFinish().getEventFunc().apply(collector));
super.addListener(categoryOverall.getError().getEventFunc().apply(collector));
super.addListener(new MetricsListener<RequestBeforeEvent>() {
super.addListener(new MetricsListener<RequestEvent>() {
@Override
public boolean isSupport(MetricsEvent event) {
return event instanceof RequestBeforeEvent;
return event instanceof RequestEvent && ((RequestEvent) event).isRequestErrorEvent();
}
private final MetricsPlaceValue dynamicPlaceType = MetricsPlaceValue.of(CommonConstants.CONSUMER, MetricsLevel.METHOD);
@Override
public void onEvent(RequestBeforeEvent event) {
public void onEvent(RequestEvent event) {
MetricsSupport.increment(METRIC_REQUESTS_SERVICE_UNAVAILABLE_FAILED, dynamicPlaceType, (MethodMetricsCollector) collector, event);
}
});

View File

@ -1,51 +0,0 @@
/*
* 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.dubbo.metrics.event;
import org.apache.dubbo.metrics.MetricsConstants;
import org.apache.dubbo.metrics.model.MethodMetric;
import org.apache.dubbo.metrics.model.MetricsSupport;
import org.apache.dubbo.metrics.model.key.MetricsKey;
import org.apache.dubbo.metrics.model.key.MetricsLevel;
import org.apache.dubbo.metrics.model.key.TypeWrapper;
import org.apache.dubbo.rpc.Invocation;
import org.apache.dubbo.rpc.model.ApplicationModel;
import static org.apache.dubbo.metrics.MetricsConstants.ATTACHMENT_KEY_SERVICE;
/**
* Acts on MetricsClusterFilter to monitor exceptions that occur before request execution
*/
public class RequestBeforeEvent extends TimeCounterEvent {
public RequestBeforeEvent(ApplicationModel source, String appName, MetricsDispatcher metricsDispatcher, TypeWrapper typeWrapper) {
super(source, appName, metricsDispatcher, typeWrapper);
}
private static final TypeWrapper REQUEST_BEFORE_EVENT = new TypeWrapper(MetricsLevel.METHOD, MetricsKey.METRIC_REQUESTS);
public static RequestBeforeEvent toEvent(ApplicationModel applicationModel, String appName, MetricsDispatcher metricsDispatcher, Invocation invocation, String side) {
RequestBeforeEvent event = new RequestBeforeEvent(applicationModel, appName, metricsDispatcher, REQUEST_BEFORE_EVENT);
event.putAttachment(ATTACHMENT_KEY_SERVICE, MetricsSupport.getInterfaceName(invocation));
event.putAttachment(MetricsConstants.INVOCATION_SIDE, side);
event.putAttachment(MetricsConstants.INVOCATION, invocation);
event.putAttachment(MetricsConstants.METHOD_METRICS, new MethodMetric(applicationModel, invocation));
return event;
}
}

View File

@ -23,6 +23,7 @@ import org.apache.dubbo.metrics.collector.DefaultMetricsCollector;
import org.apache.dubbo.metrics.exception.MetricsNeverHappenException;
import org.apache.dubbo.metrics.model.MethodMetric;
import org.apache.dubbo.metrics.model.MetricsSupport;
import org.apache.dubbo.metrics.model.key.MetricsKey;
import org.apache.dubbo.metrics.model.key.MetricsLevel;
import org.apache.dubbo.metrics.model.key.TypeWrapper;
import org.apache.dubbo.rpc.Invocation;
@ -39,7 +40,8 @@ import static org.apache.dubbo.metrics.model.key.MetricsKey.METRIC_REQUEST_BUSIN
* Request related events
*/
public class RequestEvent extends TimeCounterEvent {
private static final TypeWrapper TYPE_WRAPPER = new TypeWrapper(MetricsLevel.SERVICE, METRIC_REQUESTS, METRIC_REQUESTS_SUCCEED, METRIC_REQUEST_BUSINESS_FAILED);
private static final TypeWrapper REQUEST_EVENT = new TypeWrapper(MetricsLevel.SERVICE, METRIC_REQUESTS, METRIC_REQUESTS_SUCCEED, METRIC_REQUEST_BUSINESS_FAILED);
private static final TypeWrapper REQUEST_ERROR_EVENT = new TypeWrapper(MetricsLevel.METHOD, MetricsKey.METRIC_REQUESTS);
public RequestEvent(ApplicationModel applicationModel, String appName, MetricsDispatcher metricsDispatcher, DefaultMetricsCollector collector, TypeWrapper TYPE_WRAPPER) {
super(applicationModel, appName, metricsDispatcher, TYPE_WRAPPER);
@ -56,7 +58,7 @@ public class RequestEvent extends TimeCounterEvent {
MetricsDispatcher metricsDispatcher, DefaultMetricsCollector collector,
Invocation invocation, String side) {
MethodMetric methodMetric = new MethodMetric(applicationModel, invocation);
RequestEvent requestEvent = new RequestEvent(applicationModel, appName, metricsDispatcher, collector, TYPE_WRAPPER);
RequestEvent requestEvent = new RequestEvent(applicationModel, appName, metricsDispatcher, collector, REQUEST_EVENT);
requestEvent.putAttachment(MetricsConstants.INVOCATION, invocation);
requestEvent.putAttachment(MetricsConstants.METHOD_METRICS, methodMetric);
requestEvent.putAttachment(ATTACHMENT_KEY_SERVICE, MetricsSupport.getInterfaceName(invocation));
@ -74,4 +76,21 @@ public class RequestEvent extends TimeCounterEvent {
}
super.putAttachment(METRIC_THROWABLE, ((Result) postResult).getException());
}
/**
* Acts on MetricsClusterFilter to monitor exceptions that occur before request execution
*/
public static RequestEvent toRequestErrorEvent(ApplicationModel applicationModel, String appName, MetricsDispatcher metricsDispatcher, Invocation invocation, String side, int code) {
RequestEvent event = new RequestEvent(applicationModel, appName, metricsDispatcher, null, REQUEST_ERROR_EVENT);
event.putAttachment(ATTACHMENT_KEY_SERVICE, MetricsSupport.getInterfaceName(invocation));
event.putAttachment(MetricsConstants.INVOCATION_SIDE, side);
event.putAttachment(MetricsConstants.INVOCATION, invocation);
event.putAttachment(MetricsConstants.INVOCATION_REQUEST_ERROR, code);
event.putAttachment(MetricsConstants.METHOD_METRICS, new MethodMetric(applicationModel, invocation));
return event;
}
public boolean isRequestErrorEvent(){
return super.getAttachmentValue(MetricsConstants.INVOCATION_REQUEST_ERROR) != null;
}
}

View File

@ -22,7 +22,7 @@ import org.apache.dubbo.common.extension.Activate;
import org.apache.dubbo.metrics.collector.DefaultMetricsCollector;
import org.apache.dubbo.metrics.event.MetricsDispatcher;
import org.apache.dubbo.metrics.event.MetricsEventBus;
import org.apache.dubbo.metrics.event.RequestBeforeEvent;
import org.apache.dubbo.metrics.event.RequestEvent;
import org.apache.dubbo.rpc.BaseFilter;
import org.apache.dubbo.rpc.Invocation;
import org.apache.dubbo.rpc.Invoker;
@ -73,7 +73,7 @@ public class MetricsClusterFilter implements ClusterFilter, BaseFilter.Listener,
if (t instanceof RpcException) {
RpcException e = (RpcException) t;
if (e.isForbidden()) {
MetricsEventBus.publish(RequestBeforeEvent.toEvent(applicationModel, appName, metricsDispatcher, invocation, CONSUMER_SIDE));
MetricsEventBus.publish(RequestEvent.toRequestErrorEvent(applicationModel, appName, metricsDispatcher, invocation, CONSUMER_SIDE, e.getCode()));
}
}
}

View File

@ -31,7 +31,6 @@ import org.apache.dubbo.metrics.TestMetricsInvoker;
import org.apache.dubbo.metrics.aggregate.TimeWindowCounter;
import org.apache.dubbo.metrics.event.MetricsDispatcher;
import org.apache.dubbo.metrics.event.MetricsEventBus;
import org.apache.dubbo.metrics.event.RequestBeforeEvent;
import org.apache.dubbo.metrics.event.RequestEvent;
import org.apache.dubbo.metrics.filter.MetricsFilter;
import org.apache.dubbo.metrics.listener.MetricsListener;
@ -143,9 +142,10 @@ class AggregateMetricsCollectorTest {
void testListener() {
AggregateMetricsCollector metricsCollector = new AggregateMetricsCollector(applicationModel);
RequestEvent event = RequestEvent.toRequestEvent(applicationModel, null, null, null, invocation, MetricsSupport.getSide(invocation));
RequestBeforeEvent beforeEvent = new RequestBeforeEvent(applicationModel, null, null, new TypeWrapper(MetricsLevel.METHOD, MetricsKey.METRIC_REQUESTS));
RequestEvent beforeEvent = RequestEvent.toRequestErrorEvent(applicationModel, null, null, invocation, MetricsSupport.getSide(invocation), RpcException.FORBIDDEN_EXCEPTION);
Assertions.assertTrue(metricsCollector.isSupport(event));
Assertions.assertFalse(metricsCollector.isSupport(beforeEvent));
Assertions.assertTrue(metricsCollector.isSupport(beforeEvent));
}
@AfterEach

View File

@ -22,7 +22,6 @@ import org.apache.dubbo.common.constants.CommonConstants;
import org.apache.dubbo.config.ApplicationConfig;
import org.apache.dubbo.metrics.TestMetricsInvoker;
import org.apache.dubbo.metrics.event.MetricsDispatcher;
import org.apache.dubbo.metrics.event.RequestBeforeEvent;
import org.apache.dubbo.metrics.event.RequestEvent;
import org.apache.dubbo.metrics.filter.MetricsFilter;
import org.apache.dubbo.metrics.model.MetricsSupport;
@ -114,7 +113,8 @@ class DefaultCollectorTest {
void testListener() {
DefaultMetricsCollector metricsCollector = new DefaultMetricsCollector(applicationModel);
RequestEvent event = RequestEvent.toRequestEvent(applicationModel, null, null, null, invocation, MetricsSupport.getSide(invocation));
RequestBeforeEvent beforeEvent = new RequestBeforeEvent(applicationModel, null, null, new TypeWrapper(MetricsLevel.METHOD, MetricsKey.METRIC_REQUESTS));
RequestEvent beforeEvent = RequestEvent.toRequestErrorEvent(applicationModel, null, null, invocation, MetricsSupport.getSide(invocation), RpcException.FORBIDDEN_EXCEPTION);
Assertions.assertTrue(metricsCollector.isSupport(event));
Assertions.assertTrue(metricsCollector.isSupport(beforeEvent));
}

View File

@ -0,0 +1,40 @@
<!--
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.
-->
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-metrics</artifactId>
<version>${revision}</version>
<relativePath>../pom.xml</relativePath>
</parent>
<artifactId>dubbo-metrics-netty</artifactId>
<packaging>jar</packaging>
<name>${project.artifactId}</name>
<description>The metrics module of dubbo project</description>
<properties>
<skip_maven_deploy>false</skip_maven_deploy>
</properties>
<dependencies>
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-metrics-api</artifactId>
<version>${project.parent.version}</version>
</dependency>
</dependencies>
</project>

View File

@ -0,0 +1,44 @@
/*
* 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.dubbo.metrics.registry;
import org.apache.dubbo.metrics.model.key.MetricsKey;
import java.util.Arrays;
import java.util.List;
import static org.apache.dubbo.metrics.model.key.MetricsKey.NETTY_ALLOCATOR_CHUNK_SIZE;
import static org.apache.dubbo.metrics.model.key.MetricsKey.NETTY_ALLOCATOR_DIRECT_ARENAS_NUM;
import static org.apache.dubbo.metrics.model.key.MetricsKey.NETTY_ALLOCATOR_DIRECT_MEMORY_USED;
import static org.apache.dubbo.metrics.model.key.MetricsKey.NETTY_ALLOCATOR_HEAP_ARENAS_NUM;
import static org.apache.dubbo.metrics.model.key.MetricsKey.NETTY_ALLOCATOR_HEAP_MEMORY_USED;
import static org.apache.dubbo.metrics.model.key.MetricsKey.NETTY_ALLOCATOR_NORMAL_CACHE_SIZE;
import static org.apache.dubbo.metrics.model.key.MetricsKey.NETTY_ALLOCATOR_PINNED_DIRECT_MEMORY;
import static org.apache.dubbo.metrics.model.key.MetricsKey.NETTY_ALLOCATOR_PINNED_HEAP_MEMORY;
import static org.apache.dubbo.metrics.model.key.MetricsKey.NETTY_ALLOCATOR_SMALL_CACHE_SIZE;
import static org.apache.dubbo.metrics.model.key.MetricsKey.NETTY_ALLOCATOR_THREAD_LOCAL_CACHES_NUM;
public interface NettyMetricsConstants {
// App-level
List<MetricsKey> APP_LEVEL_KEYS = Arrays.asList(NETTY_ALLOCATOR_HEAP_MEMORY_USED,NETTY_ALLOCATOR_DIRECT_MEMORY_USED
,NETTY_ALLOCATOR_PINNED_DIRECT_MEMORY,NETTY_ALLOCATOR_PINNED_HEAP_MEMORY,NETTY_ALLOCATOR_HEAP_ARENAS_NUM
,NETTY_ALLOCATOR_DIRECT_ARENAS_NUM,NETTY_ALLOCATOR_NORMAL_CACHE_SIZE,NETTY_ALLOCATOR_SMALL_CACHE_SIZE,NETTY_ALLOCATOR_THREAD_LOCAL_CACHES_NUM
,NETTY_ALLOCATOR_CHUNK_SIZE);
}

View File

@ -0,0 +1,97 @@
/*
* 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.dubbo.metrics.registry.collector;
import org.apache.dubbo.common.extension.Activate;
import org.apache.dubbo.config.context.ConfigManager;
import org.apache.dubbo.metrics.collector.CombMetricsCollector;
import org.apache.dubbo.metrics.collector.MetricsCollector;
import org.apache.dubbo.metrics.data.ApplicationStatComposite;
import org.apache.dubbo.metrics.data.BaseStatComposite;
import org.apache.dubbo.metrics.data.RtStatComposite;
import org.apache.dubbo.metrics.data.ServiceStatComposite;
import org.apache.dubbo.metrics.model.MetricsCategory;
import org.apache.dubbo.metrics.model.sample.MetricSample;
import org.apache.dubbo.metrics.registry.NettyMetricsConstants;
import org.apache.dubbo.metrics.registry.event.NettyEvent;
import org.apache.dubbo.metrics.registry.event.NettySubDispatcher;
import org.apache.dubbo.rpc.model.ApplicationModel;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
/**
* Netty implementation of {@link MetricsCollector}
*/
@Activate
public class NettyMetricsCollector extends CombMetricsCollector<NettyEvent> {
private Boolean collectEnabled = null;
private final ApplicationModel applicationModel;
public NettyMetricsCollector(ApplicationModel applicationModel) {
super(new BaseStatComposite(applicationModel) {
@Override
protected void init(ApplicationStatComposite applicationStatComposite) {
super.init(applicationStatComposite);
applicationStatComposite.init(NettyMetricsConstants.APP_LEVEL_KEYS);
}
@Override
protected void init(ServiceStatComposite serviceStatComposite) {
super.init(serviceStatComposite);
}
@Override
protected void init(RtStatComposite rtStatComposite) {
super.init(rtStatComposite);
}
});
super.setEventMulticaster(new NettySubDispatcher(this));
this.applicationModel = applicationModel;
}
public void setCollectEnabled(Boolean collectEnabled) {
if (collectEnabled != null) {
this.collectEnabled = collectEnabled;
}
}
@Override
public boolean isCollectEnabled() {
if (collectEnabled == null) {
ConfigManager configManager = applicationModel.getApplicationConfigManager();
configManager.getMetrics().ifPresent(metricsConfig -> setCollectEnabled(metricsConfig.getEnableNetty()));
}
return Optional.ofNullable(collectEnabled).orElse(true);
}
@Override
public List<MetricSample> collect() {
List<MetricSample> list = new ArrayList<>();
if (!isCollectEnabled()) {
return list;
}
list.addAll(super.export(MetricsCategory.NETTY));
return list;
}
}

View File

@ -0,0 +1,54 @@
/*
* 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.dubbo.metrics.registry.event;
import org.apache.dubbo.common.beans.factory.ScopeBeanFactory;
import org.apache.dubbo.metrics.event.TimeCounterEvent;
import org.apache.dubbo.metrics.model.key.MetricsLevel;
import org.apache.dubbo.metrics.model.key.TypeWrapper;
import org.apache.dubbo.metrics.registry.collector.NettyMetricsCollector;
import org.apache.dubbo.rpc.model.ApplicationModel;
import static org.apache.dubbo.metrics.MetricsConstants.NETTY_METRICS_MAP;
/**
* Netty related events
*/
public class NettyEvent extends TimeCounterEvent {
public NettyEvent(ApplicationModel applicationModel, TypeWrapper typeWrapper) {
super(applicationModel,typeWrapper);
ScopeBeanFactory beanFactory = getSource().getBeanFactory();
NettyMetricsCollector collector;
if (!beanFactory.isDestroyed()) {
collector = beanFactory.getBean(NettyMetricsCollector.class);
super.setAvailable(collector != null && collector.isCollectEnabled());
}
}
public static NettyEvent toNettyEvent(ApplicationModel applicationModel) {
return new NettyEvent(applicationModel, new TypeWrapper(MetricsLevel.APP, null,null, null)) {
@Override
public void customAfterPost(Object postResult) {
super.putAttachment(NETTY_METRICS_MAP, postResult);
}
};
}
}

View File

@ -0,0 +1,53 @@
/*
* 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.dubbo.metrics.registry.event;
import org.apache.dubbo.metrics.event.MetricsEvent;
import org.apache.dubbo.metrics.event.SimpleMetricsEventMulticaster;
import org.apache.dubbo.metrics.event.TimeCounterEvent;
import org.apache.dubbo.metrics.listener.AbstractMetricsKeyListener;
import org.apache.dubbo.metrics.model.key.MetricsKey;
import org.apache.dubbo.metrics.registry.collector.NettyMetricsCollector;
import java.util.Collections;
import java.util.Map;
import static org.apache.dubbo.metrics.MetricsConstants.NETTY_METRICS_MAP;
public final class NettySubDispatcher extends SimpleMetricsEventMulticaster {
public NettySubDispatcher(NettyMetricsCollector collector) {
super.addListener(new AbstractMetricsKeyListener(null) {
@Override
public boolean isSupport(MetricsEvent event) {
return true;
}
@Override
public void onEventFinish(TimeCounterEvent event) {
Map<String, Long> lastNumMap = Collections.unmodifiableMap(event.getAttachmentValue(NETTY_METRICS_MAP));
lastNumMap.forEach(
(k, v) -> {
MetricsKey metricsKey = MetricsKey.getMetricsByName(k);
collector.setAppNum(metricsKey, v);
});
}
});
}
}

View File

@ -0,0 +1 @@
org.apache.dubbo.metrics.registry.collector.NettyMetricsCollector

View File

@ -25,6 +25,7 @@
<module>dubbo-metrics-prometheus</module>
<module>dubbo-metrics-config-center</module>
<module>dubbo-tracing</module>
<module>dubbo-metrics-netty</module>
</modules>
<parent>
<groupId>org.apache.dubbo</groupId>

View File

@ -40,7 +40,16 @@
<artifactId>dubbo-remoting-api</artifactId>
<version>${project.parent.version}</version>
</dependency>
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-metrics-api</artifactId>
<version>${project.parent.version}</version>
</dependency>
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-metrics-netty</artifactId>
<version>${project.parent.version}</version>
</dependency>
<dependency>
<groupId>io.netty</groupId>
<artifactId>netty-handler-proxy</artifactId>

View File

@ -20,8 +20,12 @@ import org.apache.dubbo.common.URL;
import org.apache.dubbo.common.config.ConfigurationUtils;
import org.apache.dubbo.common.logger.ErrorTypeAwareLogger;
import org.apache.dubbo.common.logger.LoggerFactory;
import org.apache.dubbo.common.utils.ClassUtils;
import org.apache.dubbo.common.utils.CollectionUtils;
import org.apache.dubbo.common.utils.NetUtils;
import org.apache.dubbo.metrics.event.MetricsEventBus;
import org.apache.dubbo.metrics.model.key.MetricsKey;
import org.apache.dubbo.metrics.registry.event.NettyEvent;
import org.apache.dubbo.remoting.Channel;
import org.apache.dubbo.remoting.ChannelHandler;
import org.apache.dubbo.remoting.Constants;
@ -30,6 +34,7 @@ import org.apache.dubbo.remoting.transport.AbstractServer;
import org.apache.dubbo.remoting.transport.dispatcher.ChannelHandlers;
import org.apache.dubbo.remoting.transport.netty4.ssl.SslServerTlsHandler;
import org.apache.dubbo.remoting.utils.UrlUtils;
import org.apache.dubbo.rpc.model.ApplicationModel;
import io.netty.bootstrap.ServerBootstrap;
import io.netty.buffer.PooledByteBufAllocator;
@ -44,6 +49,7 @@ import io.netty.util.concurrent.Future;
import java.net.InetSocketAddress;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import static java.util.concurrent.TimeUnit.MILLISECONDS;
@ -109,6 +115,26 @@ public class NettyServer extends AbstractServer {
channelFuture.syncUninterruptibly();
channel = channelFuture.channel();
// metrics
if (isSupportMetrics()) {
ApplicationModel applicationModel = ApplicationModel.defaultModel();
MetricsEventBus.post(NettyEvent.toNettyEvent(applicationModel), () -> {
Map<String, Long> dataMap = new HashMap<>();
dataMap.put(MetricsKey.NETTY_ALLOCATOR_HEAP_MEMORY_USED.getName(), PooledByteBufAllocator.DEFAULT.metric().usedHeapMemory());
dataMap.put(MetricsKey.NETTY_ALLOCATOR_DIRECT_MEMORY_USED.getName(), PooledByteBufAllocator.DEFAULT.metric().usedDirectMemory());
dataMap.put(MetricsKey.NETTY_ALLOCATOR_HEAP_ARENAS_NUM.getName(), (long) PooledByteBufAllocator.DEFAULT.numHeapArenas());
dataMap.put(MetricsKey.NETTY_ALLOCATOR_DIRECT_ARENAS_NUM.getName(), (long) PooledByteBufAllocator.DEFAULT.numDirectArenas());
dataMap.put(MetricsKey.NETTY_ALLOCATOR_NORMAL_CACHE_SIZE.getName(), (long) PooledByteBufAllocator.DEFAULT.normalCacheSize());
dataMap.put(MetricsKey.NETTY_ALLOCATOR_SMALL_CACHE_SIZE.getName(), (long) PooledByteBufAllocator.DEFAULT.smallCacheSize());
dataMap.put(MetricsKey.NETTY_ALLOCATOR_THREAD_LOCAL_CACHES_NUM.getName(), (long) PooledByteBufAllocator.DEFAULT.numThreadLocalCaches());
dataMap.put(MetricsKey.NETTY_ALLOCATOR_CHUNK_SIZE.getName(), (long) PooledByteBufAllocator.DEFAULT.chunkSize());
return dataMap;
});
}
}
private boolean isSupportMetrics() {
return ClassUtils.isPresent("io.netty.buffer.PooledByteBufAllocatorMetric", NettyServer.class.getClassLoader());
}
protected EventLoopGroup createBossGroup() {

View File

@ -203,6 +203,13 @@
<artifactId>dubbo-metrics-config-center</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-metrics-netty</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-metrics-prometheus</artifactId>