Merge branch '3.3' into 3.3.0-beta.1-release
This commit is contained in:
commit
186ec674bf
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -25,6 +25,7 @@ notifications:
|
|||
|
||||
github:
|
||||
homepage: https://dubbo.apache.org/
|
||||
description: "The java implementation of Apache Dubbo. An RPC and microservice framework."
|
||||
features:
|
||||
# Enable wiki for documentation
|
||||
wiki: true
|
||||
|
|
@ -44,9 +45,13 @@ github:
|
|||
foo: bar
|
||||
labels:
|
||||
- java
|
||||
- rpc
|
||||
- microservices
|
||||
- framework
|
||||
- restful
|
||||
- distributed-systems
|
||||
- rpc
|
||||
- dubbo
|
||||
- service-mesh
|
||||
- http
|
||||
- grpc
|
||||
- web
|
||||
|
|
|
|||
|
|
@ -184,7 +184,7 @@ check 2.7.5 milestone for details.
|
|||
- Add a script to check dependencies license. [#3840](https://github.com/apache/dubbo/issues/3840)
|
||||
- Change DynamicConfiguration definition to better adapt to Apollo's namespace storage model.[#3266](https://github.com/apache/dubbo/issues/3266)
|
||||
- use equal explicit class to replace anonymous class [#4027](https://github.com/apache/dubbo/issues/4027)
|
||||
- Seperate Constants.java into some SubConstants Class [#3137](https://github.com/apache/dubbo/issues/3137)
|
||||
- Separate Constants.java into some SubConstants Class [#3137](https://github.com/apache/dubbo/issues/3137)
|
||||
- Need to enhance DecodeableRpcResult error message [#3994](https://github.com/apache/dubbo/issues/3994)
|
||||
- Provide more meaningful binary releases. [#2491](https://github.com/apache/dubbo/issues/2491)
|
||||
- remove useless module-dubbo-test-integration [#3573](https://github.com/apache/dubbo/issues/3573)
|
||||
|
|
@ -211,7 +211,7 @@ check 2.7.5 milestone for details.
|
|||
- Fix consumer will generate wrong stackTrace. [#4137](https://github.com/apache/dubbo/issues/4137)
|
||||
- nacos registry serviceName may conflict. [#4111](https://github.com/apache/dubbo/issues/4111)
|
||||
- The client loses the listener when the network is reconnected. [#4115](https://github.com/apache/dubbo/issues/4115)
|
||||
- fix registery urls increase forever when recreate reference proxy. [#4109](https://github.com/apache/dubbo/issues/4109)
|
||||
- fix registry urls increase forever when recreate reference proxy. [#4109](https://github.com/apache/dubbo/issues/4109)
|
||||
- In dubbo 2.7.1,the watcher processor of zookeeper client throw Nullpointexception. [#3866](https://github.com/apache/dubbo/issues/3866)
|
||||
- ReferenceConfig initialized not changed to false once subscribe throws exception [#4068](https://github.com/apache/dubbo/issues/4068)
|
||||
- dubbo registry extension compatibility with dubbo 2.6.x. [#3882](https://github.com/apache/dubbo/issues/3882)
|
||||
|
|
@ -400,7 +400,7 @@ Enhancement / New feature:
|
|||
* tag route. #3065
|
||||
* Use Netty4 as default Netty version. #3029
|
||||
* upporting Java 8 Date/Time type when serializing with Kryo #3519
|
||||
* supoort config telnet #3511
|
||||
* support config telnet #3511
|
||||
* add annotation driven in MethodConfig and ArgumentConfig #2603
|
||||
* add nacos-registry module #3296
|
||||
* add `protocol` attribute in `@Rerefence` #3555
|
||||
|
|
@ -416,7 +416,7 @@ BugFix:
|
|||
* SPI entires dup by 3 times #3315
|
||||
* fix Consumer throws RpcException after RegistryDirectory notify in high QPS #2016
|
||||
* fix NPE in @Reference when using Junit to test dubbo service #3429
|
||||
* fix consuer always catch java.lang.reflect.UndeclaredThrowableException for any exception throws in provider #3386
|
||||
* fix consumer always catch java.lang.reflect.UndeclaredThrowableException for any exception throws in provider #3386
|
||||
* fix the priority of `DubboConfigConfigurationSelector ` #2897
|
||||
* fix `@Rerefence#parameters()` not work #2301
|
||||
|
||||
|
|
|
|||
|
|
@ -1,21 +1,8 @@
|
|||
## What is the purpose of the change
|
||||
## What is the purpose of the change?
|
||||
|
||||
|
||||
|
||||
## Brief changelog
|
||||
|
||||
|
||||
## Verifying this change
|
||||
|
||||
|
||||
<!-- Follow this checklist to help us incorporate your contribution quickly and easily: -->
|
||||
|
||||
## Checklist
|
||||
- [x] Make sure there is a [GitHub_issue](https://github.com/apache/dubbo/issues) field for the change (usually before you start working on it). Trivial changes like typos do not require a GitHub issue. Your pull request should address just this issue, without pulling in other changes - one PR resolves one issue.
|
||||
- [ ] Each commit in the pull request should have a meaningful subject line and body.
|
||||
- [ ] Write a pull request description that is detailed enough to understand what the pull request does, how, and why.
|
||||
- [ ] Check if is necessary to patch to Dubbo 3 if you are work on Dubbo 2.7
|
||||
- [ ] Write necessary unit-test to verify your logic correction, more mock a little better when cross module dependency exist. If the new feature or significant change is committed, please remember to add sample in [dubbo samples](https://github.com/apache/dubbo-samples) project.
|
||||
- [ ] Add some description to [dubbo-website](https://github.com/apache/dubbo-website) project if you are requesting to add a feature.
|
||||
- [ ] GitHub Actions works fine on your own branch.
|
||||
- [ ] If this contribution is large, please follow the [Software Donation Guide](https://github.com/apache/dubbo/wiki/Software-donation-guide).
|
||||
- [x] Make sure there is a [GitHub_issue](https://github.com/apache/dubbo/issues) field for the change.
|
||||
- [x] Write a pull request description that is detailed enough to understand what the pull request does, how, and why.
|
||||
- [x] Write necessary unit-test to verify your logic correction. If the new feature or significant change is committed, please remember to add sample in [dubbo samples](https://github.com/apache/dubbo-samples) project.
|
||||
- [x] Make sure gitHub actions can pass. [Why the workflow is failing and how to fix it?](./CONTRIBUTING.md)
|
||||
|
|
|
|||
255
README.md
255
README.md
|
|
@ -10,236 +10,69 @@
|
|||
[](https://twitter.com/intent/follow?screen_name=ApacheDubbo)
|
||||
[](https://gitter.im/alibaba/dubbo?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge)
|
||||
|
||||
Apache Dubbo is a high-performance, Java-based open-source RPC framework. Please visit the [official site](http://dubbo.apache.org) for the quick start guide and documentation, as well as the [wiki](https://github.com/apache/dubbo/wiki) for news, FAQ, and release notes.
|
||||
Apache Dubbo is an easy-to-use Web and RPC framework that provides multiple
|
||||
language implementations(Java, [Go](https://github.com/apache/dubbo-go), [Rust](https://github.com/apache/dubbo-rust), [Node.js](https://github.com/apache/dubbo-js), [Web](https://github.com/apache/dubbo-js)) for communication, service discovery, traffic management,
|
||||
observability, security, tools, and best practices for building enterprise-ready microservices.
|
||||
|
||||
We are now collecting Dubbo user info to help us to improve Dubbo further. Kindly support us by providing your usage information on [issue#9436: Wanted: who's using dubbo](https://github.com/apache/dubbo/issues/9436), thanks :)
|
||||
Visit [the official website](https://dubbo.apache.org/) for more information.
|
||||
|
||||
## Architecture
|
||||
|
||||

|
||||
|
||||
## Features
|
||||
|
||||
* Transparent interface based RPC
|
||||
* Intelligent load balancing
|
||||
* Automatic service registration and discovery
|
||||
* High extensibility
|
||||
* Runtime traffic routing
|
||||
* Visualized service governance
|
||||
* Consumer and provider communicate with each other using RPC protocol like triple, tcp, rest, etc.
|
||||
* Consumers automatically trace provider instances registered in registries(Zookeeper, Nacos) and distribute traffic among them by following traffic strategies.
|
||||
* Rich features for monitoring and managing the cluster with dynamic configuration, metrics, tracing, security, and visualized console.
|
||||
|
||||
## Getting started
|
||||
Follow the instructions below to learn how to:
|
||||
|
||||
The following code snippet comes from [Dubbo Samples](https://github.com/apache/dubbo-samples.git). You may clone the sample project and step into the `dubbo-samples-api` subdirectory before proceeding.
|
||||
### Programming with lightweight RPC API
|
||||
[5 minutes step-by-step guide](https://dubbo.apache.org/zh-cn/overview/quickstart/rpc/java)
|
||||
|
||||
```bash
|
||||
git clone https://github.com/apache/dubbo-samples.git
|
||||
cd dubbo-samples/1-basic/dubbo-samples-api
|
||||
```
|
||||
|
||||
There's a [README](https://github.com/apache/dubbo-samples/blob/389cd612f1ea57ee6e575005b32f195c442c35a2/1-basic/dubbo-samples-api/README.md) file under `dubbo-samples-api` directory. We recommend referencing the samples in that directory by following the below-mentioned instructions:
|
||||
|
||||
### Maven dependency
|
||||
|
||||
```xml
|
||||
<properties>
|
||||
<dubbo.version>3.0.10</dubbo.version>
|
||||
</properties>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.apache.dubbo</groupId>
|
||||
<artifactId>dubbo</artifactId>
|
||||
<version>${dubbo.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.dubbo</groupId>
|
||||
<artifactId>dubbo-dependencies-zookeeper</artifactId>
|
||||
<version>${dubbo.version}</version>
|
||||
<type>pom</type>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
```
|
||||
|
||||
### Define service interfaces
|
||||
|
||||
```java
|
||||
package org.apache.dubbo.samples.api;
|
||||
|
||||
public interface GreetingsService {
|
||||
String sayHi(String name);
|
||||
}
|
||||
```
|
||||
|
||||
*See [api/GreetingsService.java](https://github.com/apache/dubbo-samples/blob/389cd612f1ea57ee6e575005b32f195c442c35a2/1-basic/dubbo-samples-api/src/main/java/org/apache/dubbo/samples/api/GreetingsService.java) on GitHub.*
|
||||
|
||||
### Implement service interface for the provider
|
||||
|
||||
```java
|
||||
package org.apache.dubbo.samples.provider;
|
||||
|
||||
import org.apache.dubbo.samples.api.GreetingsService;
|
||||
|
||||
public class GreetingsServiceImpl implements GreetingsService {
|
||||
@Override
|
||||
public String sayHi(String name) {
|
||||
return "hi, " + name;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
*See [provider/GreetingsServiceImpl.java](https://github.com/apache/dubbo-samples/blob/389cd612f1ea57ee6e575005b32f195c442c35a2/1-basic/dubbo-samples-api/src/main/java/org/apache/dubbo/samples/provider/GreetingsServiceImpl.java) on GitHub.*
|
||||
|
||||
### Start service provider
|
||||
|
||||
```java
|
||||
package org.apache.dubbo.samples.provider;
|
||||
Dubbo supports building RPC services with only a few lines of code while depending only on a lightweight SDK (<10MB). The protocol on the wire can be [Triple](https://dubbo.apache.org/zh-cn/overview/reference/protocols/triple/)(fully gRPC compatible and HTTP-friendly), Dubbo2(TCP), REST, or any protocol of your choice.
|
||||
|
||||
|
||||
import org.apache.dubbo.config.ApplicationConfig;
|
||||
import org.apache.dubbo.config.RegistryConfig;
|
||||
import org.apache.dubbo.config.ServiceConfig;
|
||||
import org.apache.dubbo.samples.api.GreetingsService;
|
||||
### Building a microservice application with Spring Boot
|
||||
[5 minutes step-by-step guide](https://dubbo.apache.org/zh-cn/overview/quickstart/microservice)
|
||||
|
||||
import java.util.concurrent.CountDownLatch;
|
||||
It's highly recommended to start your microservice application with the Spring Boot Starter `dubbo-spring-boot-starter` provided by Dubbo. With only a single dependency and yaml file, and optionally a bunch of other useful spring boot starters, you can enable all of the Dubo features like service discovery, observability, tracing, etc.
|
||||
|
||||
public class Application {
|
||||
private static String zookeeperHost = System.getProperty("zookeeper.address", "127.0.0.1");
|
||||
Next, learn how to [deploy](https://dubbo.apache.org/zh-cn/overview/tasks/deploy/), [monitor](https://dubbo.apache.org/zh-cn/overview/tasks/observability/), and [manage the traffic](https://dubbo.apache.org/zh-cn/overview/tasks/traffic-management/) of your Dubbo application and cluster.
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
ServiceConfig<GreetingsService> service = new ServiceConfig<>();
|
||||
service.setApplication(new ApplicationConfig("first-dubbo-provider"));
|
||||
service.setRegistry(new RegistryConfig("zookeeper://" + zookeeperHost + ":2181"));
|
||||
service.setInterface(GreetingsService.class);
|
||||
service.setRef(new GreetingsServiceImpl());
|
||||
service.export();
|
||||
## More Features
|
||||
Get more details by visiting the links below to get your hands dirty with some well-designed tasks on our website.
|
||||
|
||||
System.out.println("dubbo service started");
|
||||
new CountDownLatch(1).await();
|
||||
}
|
||||
}
|
||||
```
|
||||
* [Launch a Dubbo project](https://dubbo.apache.org/zh-cn/overview/tasks/develop/template/)
|
||||
* [RPC protocols](https://dubbo.apache.org/zh-cn/overview/core-features/protocols/)
|
||||
* [Traffic management](https://dubbo.apache.org/zh-cn/overview/core-features/traffic/)
|
||||
* [Service discovery](https://dubbo.apache.org/zh-cn/overview/core-features/service-discovery/)
|
||||
* [Observability](https://dubbo.apache.org/zh-cn/overview/core-features/observability/)
|
||||
* [Extensibility](https://dubbo.apache.org/zh-cn/overview/core-features/extensibility/)
|
||||
* [Security](https://dubbo.apache.org/zh-cn/overview/core-features/security/)
|
||||
* [Visualized console and control plane](https://dubbo.apache.org/zh-cn/overview/reference/admin/)
|
||||
* [Kubernetes and Service mesh](https://dubbo.apache.org/zh-cn/overview/core-features/service-mesh/)
|
||||
|
||||
*See [provider/Application.java](https://github.com/apache/dubbo-samples/blob/389cd612f1ea57ee6e575005b32f195c442c35a2/1-basic/dubbo-samples-spring-xml/src/main/java/org/apache/dubbo/samples/provider/Application.java) on GitHub.*
|
||||
## Which Dubbo version should I use?
|
||||
| **Dubbo3** | **JDK** | **Dependencies** | **Description** |
|
||||
| --- | --- | --- | --- |
|
||||
| 3.3.0-beta| 1.8 ~ 17 | [dependency list](https://github.com/apache/dubbo/blob/3.3/dubbo-dependencies-bom/pom.xml#L94) | **- Unstable version** <br/> **- Features** <br/> - Triple - gRPC and cURL compatible.<br/> - Rest-style programming support.<br/> - Spring Boot Starters. |
|
||||
| 3.2.5 | 1.8 ~ 17 | [dependency list](https://github.com/apache/dubbo/blob/dubbo-3.2.5/dubbo-dependencies-bom/pom.xml#L94) | **- Stable version (active)** <br/> **- Features** <br/> - Out-of-box metrics and tracing support.<br/> - Threadpool Isolation<br/> - 30% performance<br/> - Native Image|
|
||||
| 3.1.11 | 1.8 ~ 11 | [dependency list](https://github.com/apache/dubbo/blob/dubbo-3.2.11/dubbo-dependencies-bom/pom.xml#L94) | **Stable version (not active)** |
|
||||
|
||||
### Build and run the provider
|
||||
|
||||
```bash
|
||||
mvn clean package
|
||||
mvn -Djava.net.preferIPv4Stack=true -Dexec.mainClass=org.apache.dubbo.samples.provider.Application exec:java
|
||||
```
|
||||
|
||||
### Call remote service in the consumer
|
||||
|
||||
```java
|
||||
package org.apache.dubbo.samples.client;
|
||||
|
||||
|
||||
import org.apache.dubbo.config.ApplicationConfig;
|
||||
import org.apache.dubbo.config.ReferenceConfig;
|
||||
import org.apache.dubbo.config.RegistryConfig;
|
||||
import org.apache.dubbo.samples.api.GreetingsService;
|
||||
|
||||
public class Application {
|
||||
private static String zookeeperHost = System.getProperty("zookeeper.address", "127.0.0.1");
|
||||
|
||||
public static void main(String[] args) {
|
||||
ReferenceConfig<GreetingsService> reference = new ReferenceConfig<>();
|
||||
reference.setApplication(new ApplicationConfig("first-dubbo-consumer"));
|
||||
reference.setRegistry(new RegistryConfig("zookeeper://" + zookeeperHost + ":2181"));
|
||||
reference.setInterface(GreetingsService.class);
|
||||
GreetingsService service = reference.get();
|
||||
String message = service.sayHi("dubbo");
|
||||
System.out.println(message);
|
||||
}
|
||||
}
|
||||
```
|
||||
*See [client/Application.java](https://github.com/apache/dubbo-samples/blob/389cd612f1ea57ee6e575005b32f195c442c35a2/1-basic/dubbo-samples-api/src/main/java/org/apache/dubbo/samples/client/Application.java) on GitHub.*
|
||||
|
||||
### Build and run the consumer
|
||||
|
||||
```bash
|
||||
mvn clean package
|
||||
mvn -Djava.net.preferIPv4Stack=true -Dexec.mainClass=org.apache.dubbo.samples.client.Application exec:java
|
||||
```
|
||||
|
||||
The consumer will print out `hi, dubbo` on the screen.
|
||||
|
||||
|
||||
### Next steps
|
||||
|
||||
* [Your first Dubbo application](https://dubbo.apache.org/en/blog/2018/08/07/dubbo-101/) - A 101 tutorial to reveal more details, with the same code above.
|
||||
* [Dubbo user manual](https://dubbo.apache.org/en/overview/what/) - How to use Dubbo and all its features.
|
||||
* [Dubbo developer guide](https://dubbo.apache.org/en/docs3-v2/java-sdk/) - How to involve in Dubbo development.
|
||||
* [Dubbo admin manual](https://dubbo.apache.org/en/docs/v2.7/admin/ops/) - How to admin and manage Dubbo services.
|
||||
|
||||
## Building
|
||||
|
||||
If you want to try out the cutting-edge features, you can build with the following commands. (Java 1.8 is needed to build the master branch)
|
||||
|
||||
```
|
||||
mvn clean install
|
||||
```
|
||||
|
||||
## Recommended Test Environment
|
||||
To avoid intermittent test failures (i.e., flaky tests), it is recommended to have a machine or virtual machine with the following specifications:
|
||||
|
||||
* Minumum of 2CPUs.
|
||||
* Minimum of 2Gb of RAM.
|
||||
|
||||
## Contact
|
||||
|
||||
* Mailing list:
|
||||
* dev list: for dev/user discussion. [subscribe](mailto:dev-subscribe@dubbo.apache.org), [unsubscribe](mailto:dev-unsubscribe@dubbo.apache.org), [archive](https://lists.apache.org/list.html?dev@dubbo.apache.org), [guide](https://github.com/apache/dubbo/wiki/Mailing-list-subscription-guide)
|
||||
|
||||
* Bugs: [Issues](https://github.com/apache/dubbo/issues/new?template=dubbo-issue-report-template.md)
|
||||
* Gitter: [Gitter channel](https://gitter.im/alibaba/dubbo)
|
||||
* Twitter: [@ApacheDubbo](https://twitter.com/ApacheDubbo)
|
||||
| **Dubbo2** | **JDK** | **Dependencies** | **Description** |
|
||||
| --- | --- | --- | --- |
|
||||
| 2.7.23 | 1.8 | [dependency list](https://github.com/apache/dubbo/blob/dubbo-2.7.23/dubbo-dependencies-bom/pom.xml#L92) | EOL |
|
||||
| 2.6.x, 2.5.x | 1.6 ~ 1.7 | | EOL |
|
||||
|
||||
## Contributing
|
||||
See [CONTRIBUTING](https://github.com/apache/dubbo/blob/master/CONTRIBUTING.md) for details on submitting patches and the contribution workflow.
|
||||
|
||||
See [CONTRIBUTING](https://github.com/apache/dubbo/blob/master/CONTRIBUTING.md) for details on submitting patches and the contribution workflow.
|
||||
|
||||
### How can I contribute?
|
||||
|
||||
* Take a look at issues with tags marked [`Good first issue`](https://github.com/apache/dubbo/issues?q=is%3Aopen+is%3Aissue+label%3A%22good+first+issue%22) or [`Help wanted`](https://github.com/apache/dubbo/issues?q=is%3Aopen+is%3Aissue+label%3A%22help+wanted%22).
|
||||
* Join the discussion on the mailing list, subscription [guide](https://github.com/apache/dubbo/wiki/Mailing-list-subscription-guide).
|
||||
* Answer questions on [issues](https://github.com/apache/dubbo/issues).
|
||||
* Fix bugs reported on [issues](https://github.com/apache/dubbo/issues), and send us a pull request.
|
||||
* Review the existing [pull request](https://github.com/apache/dubbo/pulls).
|
||||
* Improve the [website](https://github.com/apache/dubbo-website), typically we need
|
||||
* blog post
|
||||
* translation on documentation
|
||||
* use cases around the integration of Dubbo in enterprise systems.
|
||||
* Improve the [dubbo-admin/dubbo-monitor](https://github.com/apache/dubbo-admin).
|
||||
* Contribute to the projects listed in [ecosystem](https://github.com/dubbo).
|
||||
* Other forms of contribution not explicitly enumerated above.
|
||||
* If you would like to contribute, please send an email to dev@dubbo.apache.org to let us know!
|
||||
|
||||
## Reporting bugs
|
||||
|
||||
Please follow the [template](https://github.com/apache/dubbo/issues/new?template=dubbo-issue-report-template.md) for reporting any issues.
|
||||
|
||||
## Reporting a security vulnerability
|
||||
|
||||
Please report security vulnerabilities to [us](mailto:security@dubbo.apache.org) privately.
|
||||
|
||||
## Dubbo ecosystem
|
||||
|
||||
* [Dubbo Ecosystem Entry](https://github.com/apache?utf8=%E2%9C%93&q=dubbo&type=&language=) - A GitHub group `dubbo` to gather all Dubbo relevant projects not appropriate in [apache](https://github.com/apache) group yet
|
||||
* [Dubbo Website](https://github.com/apache/dubbo-website) - Apache Dubbo official website
|
||||
* [Dubbo Samples](https://github.com/apache/dubbo-samples) - samples for Apache Dubbo
|
||||
* [Dubbo Spring Boot](https://github.com/apache/dubbo-spring-boot-project) - Spring Boot Project for Dubbo
|
||||
* [Dubbo Admin](https://github.com/apache/dubbo-admin) - The reference implementation for Dubbo admin
|
||||
* [Dubbo Awesome](https://github.com/apache/dubbo-awesome) - Dubbo's slides and video links in Meetup
|
||||
|
||||
#### Language
|
||||
|
||||
* [Go](https://github.com/dubbo/dubbo-go) (recommended)
|
||||
* [Node.js](https://github.com/apache/dubbo-js)
|
||||
* [Python](https://github.com/dubbo/py-client-for-apache-dubbo)
|
||||
* [PHP](https://github.com/apache/dubbo-php-framework)
|
||||
* [Erlang](https://github.com/apache/dubbo-erlang)
|
||||
## Contact
|
||||
* WeChat: apachedubbo
|
||||
* DingTalk group: 37290003945
|
||||
* Mailing list: [guide](https://dubbo.apache.org/zh-cn/contact/)
|
||||
* Twitter: [@ApacheDubbo](https://twitter.com/ApacheDubbo)
|
||||
* Security issues: please mail to [us](mailto:security@dubbo.apache.org) privately.
|
||||
|
||||
## License
|
||||
|
||||
Apache Dubbo software is licenced under the Apache License Version 2.0. See the [LICENSE](https://github.com/apache/dubbo/blob/master/LICENSE) file for details.
|
||||
Apache Dubbo is licensed under the Apache License Version 2.0. See the [LICENSE](https://github.com/apache/dubbo/blob/master/LICENSE) file for details.
|
||||
|
|
|
|||
|
|
@ -352,7 +352,7 @@ public abstract class AbstractDirectory<T> implements Directory<T> {
|
|||
}
|
||||
}, reconnectTaskPeriod, TimeUnit.MILLISECONDS);
|
||||
}
|
||||
MetricsEventBus.publish(RegistryEvent.refreshDirectoryEvent(applicationModel, getSummary()));
|
||||
MetricsEventBus.publish(RegistryEvent.refreshDirectoryEvent(applicationModel, getSummary(), getDirectoryMeta()));
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -366,7 +366,11 @@ public abstract class AbstractDirectory<T> implements Directory<T> {
|
|||
if (invokersInitialized) {
|
||||
refreshInvokerInternal();
|
||||
}
|
||||
MetricsEventBus.publish(RegistryEvent.refreshDirectoryEvent(applicationModel, getSummary()));
|
||||
MetricsEventBus.publish(RegistryEvent.refreshDirectoryEvent(applicationModel, getSummary(), getDirectoryMeta()));
|
||||
}
|
||||
|
||||
protected Map<String, String> getDirectoryMeta() {
|
||||
return Collections.emptyMap();
|
||||
}
|
||||
|
||||
private synchronized void refreshInvokerInternal() {
|
||||
|
|
@ -395,7 +399,7 @@ public abstract class AbstractDirectory<T> implements Directory<T> {
|
|||
removeValidInvoker(invoker);
|
||||
logger.info("Disable service address: " + invoker.getUrl() + ".");
|
||||
}
|
||||
MetricsEventBus.publish(RegistryEvent.refreshDirectoryEvent(applicationModel, getSummary()));
|
||||
MetricsEventBus.publish(RegistryEvent.refreshDirectoryEvent(applicationModel, getSummary(), getDirectoryMeta()));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -408,7 +412,7 @@ public abstract class AbstractDirectory<T> implements Directory<T> {
|
|||
|
||||
}
|
||||
}
|
||||
MetricsEventBus.publish(RegistryEvent.refreshDirectoryEvent(applicationModel, getSummary()));
|
||||
MetricsEventBus.publish(RegistryEvent.refreshDirectoryEvent(applicationModel, getSummary(), getDirectoryMeta()));
|
||||
}
|
||||
|
||||
protected final void refreshRouter(BitList<Invoker<T>> newlyInvokers, Runnable switchAction) {
|
||||
|
|
@ -465,7 +469,7 @@ public abstract class AbstractDirectory<T> implements Directory<T> {
|
|||
refreshInvokerInternal();
|
||||
this.invokersInitialized = true;
|
||||
|
||||
MetricsEventBus.publish(RegistryEvent.refreshDirectoryEvent(applicationModel, getSummary()));
|
||||
MetricsEventBus.publish(RegistryEvent.refreshDirectoryEvent(applicationModel, getSummary(), getDirectoryMeta()));
|
||||
}
|
||||
|
||||
protected void destroyInvokers() {
|
||||
|
|
@ -480,7 +484,7 @@ public abstract class AbstractDirectory<T> implements Directory<T> {
|
|||
synchronized (this.validInvokers) {
|
||||
result = this.validInvokers.add(invoker);
|
||||
}
|
||||
MetricsEventBus.publish(RegistryEvent.refreshDirectoryEvent(applicationModel, getSummary()));
|
||||
MetricsEventBus.publish(RegistryEvent.refreshDirectoryEvent(applicationModel, getSummary(), getDirectoryMeta()));
|
||||
return result;
|
||||
}
|
||||
|
||||
|
|
@ -489,7 +493,7 @@ public abstract class AbstractDirectory<T> implements Directory<T> {
|
|||
synchronized (this.validInvokers) {
|
||||
result = this.validInvokers.remove(invoker);
|
||||
}
|
||||
MetricsEventBus.publish(RegistryEvent.refreshDirectoryEvent(applicationModel, getSummary()));
|
||||
MetricsEventBus.publish(RegistryEvent.refreshDirectoryEvent(applicationModel, getSummary(), getDirectoryMeta()));
|
||||
return result;
|
||||
}
|
||||
|
||||
|
|
@ -519,18 +523,7 @@ public abstract class AbstractDirectory<T> implements Directory<T> {
|
|||
}
|
||||
|
||||
private Map<String, Integer> groupByServiceKey(Collection<Invoker<T>> invokers) {
|
||||
|
||||
Map<String, Integer> serviceNumMap = new HashMap<>();
|
||||
for (Invoker<T> invoker : invokers) {
|
||||
if (invoker.getClass().getSimpleName().contains("Mockito")) {
|
||||
return serviceNumMap;
|
||||
}
|
||||
}
|
||||
if (invokers.size() > 0) {
|
||||
serviceNumMap = invokers.stream().filter(invoker -> invoker.getInterface() != null).collect(Collectors.groupingBy(invoker -> invoker.getInterface().getName(), Collectors.reducing(0, e -> 1, Integer::sum)));
|
||||
}
|
||||
|
||||
return serviceNumMap;
|
||||
return Collections.singletonMap(getConsumerUrl().getServiceKey(), invokers.size());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
|||
|
|
@ -27,9 +27,12 @@ import org.apache.dubbo.rpc.cluster.RouterChain;
|
|||
import org.apache.dubbo.rpc.cluster.SingleRouterChain;
|
||||
import org.apache.dubbo.rpc.cluster.router.state.BitList;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import static org.apache.dubbo.common.constants.LoggerCodeConstants.CLUSTER_FAILED_SITE_SELECTION;
|
||||
import static org.apache.dubbo.common.constants.RegistryConstants.REGISTRY_KEY;
|
||||
|
||||
/**
|
||||
* StaticDirectory
|
||||
|
|
@ -125,4 +128,8 @@ public class StaticDirectory<T> extends AbstractDirectory<T> {
|
|||
return invokers;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Map<String, String> getDirectoryMeta() {
|
||||
return Collections.singletonMap(REGISTRY_KEY, "static");
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -33,6 +33,8 @@ public interface CommonConstants {
|
|||
|
||||
String CONSUMER = "consumer";
|
||||
|
||||
String CALLBACK = "callback";
|
||||
|
||||
String APPLICATION_KEY = "application";
|
||||
|
||||
String APPLICATION_VERSION_KEY = "application.version";
|
||||
|
|
@ -241,6 +243,8 @@ public interface CommonConstants {
|
|||
|
||||
String INTERFACE_REGISTER_MODE = "interface";
|
||||
|
||||
String INSTANCE_REGISTER_MODE = "instance";
|
||||
|
||||
String DEFAULT_REGISTER_MODE = "all";
|
||||
|
||||
String GENERIC_KEY = "generic";
|
||||
|
|
@ -637,8 +641,7 @@ public interface CommonConstants {
|
|||
|
||||
String REST_SERVICE_DEPLOYER_URL_ATTRIBUTE_KEY = "restServiceDeployerAttributeKey";
|
||||
|
||||
String SERVICE_DEPLOYER_ATTRIBUTE_KEY = "serviceDeployer";
|
||||
String RESTEASY_NETTY_HTTP_REQUEST_ATTRIBUTE_KEY = "resteasyNettyHttpRequest";
|
||||
String SERVICE_DEPLOYER_ATTRIBUTE_KEY = "serviceDeployer"; String RESTEASY_NETTY_HTTP_REQUEST_ATTRIBUTE_KEY = "resteasyNettyHttpRequest";
|
||||
|
||||
String DUBBO_MANUAL_REGISTER_KEY = "dubbo.application.manual-register";
|
||||
}
|
||||
|
|
|
|||
|
|
@ -47,6 +47,8 @@ public interface MetricsConstants {
|
|||
|
||||
String TAG_CHANGE_TYPE = "change.type";
|
||||
|
||||
String TAG_ERROR_CODE = "error";
|
||||
|
||||
String ENABLE_JVM_METRICS_KEY = "enable.jvm";
|
||||
|
||||
String AGGREGATION_COLLECTOR_KEY = "aggregation";
|
||||
|
|
|
|||
|
|
@ -14,24 +14,19 @@
|
|||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.apache.dubbo.tracing.exporter;
|
||||
|
||||
import brave.handler.SpanHandler;
|
||||
import io.opentelemetry.sdk.trace.export.SpanExporter;
|
||||
package org.apache.dubbo.common.logger;
|
||||
|
||||
public interface TraceExporter {
|
||||
/**
|
||||
* Loggers that can register to listen to log messages.
|
||||
*/
|
||||
public interface ListenableLogger extends ErrorTypeAwareLogger{
|
||||
|
||||
/**
|
||||
* for otel
|
||||
* Register a listener to this logger,and get notified when a log happens.
|
||||
*
|
||||
* @return
|
||||
* @param listener log listener
|
||||
*/
|
||||
SpanExporter getSpanExporter();
|
||||
void registerListen(LogListener listener);
|
||||
|
||||
/**
|
||||
* for brave
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
SpanHandler getSpanHandler();
|
||||
}
|
||||
|
|
@ -0,0 +1,27 @@
|
|||
/*
|
||||
* 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.common.logger;
|
||||
|
||||
/**
|
||||
* Log Listener, can registered to an {@link ListenableLogger}.
|
||||
*/
|
||||
public interface LogListener {
|
||||
|
||||
void onMessage(String code, String msg);
|
||||
|
||||
}
|
||||
|
|
@ -18,16 +18,22 @@
|
|||
package org.apache.dubbo.common.logger.support;
|
||||
|
||||
import org.apache.dubbo.common.Version;
|
||||
import org.apache.dubbo.common.logger.ErrorTypeAwareLogger;
|
||||
import org.apache.dubbo.common.logger.ListenableLogger;
|
||||
import org.apache.dubbo.common.logger.LogListener;
|
||||
import org.apache.dubbo.common.logger.Logger;
|
||||
import org.apache.dubbo.common.utils.NetUtils;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
/**
|
||||
* A fail-safe (ignoring exception thrown by logger) wrapper of error type aware logger.
|
||||
*/
|
||||
public class FailsafeErrorTypeAwareLogger extends FailsafeLogger implements ErrorTypeAwareLogger {
|
||||
public class FailsafeErrorTypeAwareLogger extends FailsafeLogger implements ListenableLogger {
|
||||
|
||||
/**
|
||||
* Template address for formatting.
|
||||
|
|
@ -36,6 +42,16 @@ public class FailsafeErrorTypeAwareLogger extends FailsafeLogger implements Erro
|
|||
|
||||
private static final Pattern ERROR_CODE_PATTERN = Pattern.compile("\\d+-\\d+");
|
||||
|
||||
/**
|
||||
* Listeners that listened to all Loggers.
|
||||
*/
|
||||
private static final List<LogListener> GLOBAL_LISTENERS = Collections.synchronizedList(new ArrayList<>());
|
||||
|
||||
/**
|
||||
* Listeners that listened to this listener.
|
||||
*/
|
||||
private final AtomicReference<List<LogListener>> listeners = new AtomicReference<>();
|
||||
|
||||
public FailsafeErrorTypeAwareLogger(Logger logger) {
|
||||
super(logger);
|
||||
}
|
||||
|
|
@ -80,6 +96,7 @@ public class FailsafeErrorTypeAwareLogger extends FailsafeLogger implements Erro
|
|||
}
|
||||
|
||||
try {
|
||||
onEvent(code, msg);
|
||||
getLogger().warn(appendContextMessageWithInstructions(code, cause, extendedInformation, msg));
|
||||
} catch (Throwable t) {
|
||||
// ignored.
|
||||
|
|
@ -93,6 +110,7 @@ public class FailsafeErrorTypeAwareLogger extends FailsafeLogger implements Erro
|
|||
}
|
||||
|
||||
try {
|
||||
onEvent(code, msg);
|
||||
getLogger().warn(appendContextMessageWithInstructions(code, cause, extendedInformation, msg), e);
|
||||
} catch (Throwable t) {
|
||||
// ignored.
|
||||
|
|
@ -106,6 +124,7 @@ public class FailsafeErrorTypeAwareLogger extends FailsafeLogger implements Erro
|
|||
}
|
||||
|
||||
try {
|
||||
onEvent(code, msg);
|
||||
getLogger().error(appendContextMessageWithInstructions(code, cause, extendedInformation, msg));
|
||||
} catch (Throwable t) {
|
||||
// ignored.
|
||||
|
|
@ -119,9 +138,45 @@ public class FailsafeErrorTypeAwareLogger extends FailsafeLogger implements Erro
|
|||
}
|
||||
|
||||
try {
|
||||
onEvent(code, msg);
|
||||
getLogger().error(appendContextMessageWithInstructions(code, cause, extendedInformation, msg), e);
|
||||
} catch (Throwable t) {
|
||||
// ignored.
|
||||
}
|
||||
}
|
||||
|
||||
public static void registerGlobalListen(LogListener listener) {
|
||||
GLOBAL_LISTENERS.add(listener);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void registerListen(LogListener listener) {
|
||||
listeners.getAndUpdate(logListeners -> {
|
||||
if (logListeners == null) {
|
||||
logListeners = Collections.synchronizedList(new ArrayList<>());
|
||||
}
|
||||
logListeners.add(listener);
|
||||
return logListeners;
|
||||
});
|
||||
}
|
||||
|
||||
private void onEvent(String code, String msg) {
|
||||
Optional.ofNullable(listeners.get()).ifPresent(
|
||||
logListeners -> logListeners.forEach(logListener -> {
|
||||
try {
|
||||
logListener.onMessage(code, msg);
|
||||
} catch (Exception e) {
|
||||
// ignored.
|
||||
}
|
||||
}));
|
||||
|
||||
GLOBAL_LISTENERS.forEach(logListener -> {
|
||||
try {
|
||||
logListener.onMessage(code, msg);
|
||||
} catch (Exception e) {
|
||||
// ignored.
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -159,7 +159,7 @@ public class DefaultSerializeClassChecker implements AllowClassNotifyListener {
|
|||
"Current mode is `WARN`, will disallow to deserialize it by default. " +
|
||||
"Please add it into security/serialize.allowlist or follow FAQ to configure it.";
|
||||
if (serializeSecurityManager.getWarnedClasses().add(className)) {
|
||||
logger.error(PROTOCOL_UNTRUSTED_SERIALIZE_CLASS, "", "", msg);
|
||||
logger.warn(PROTOCOL_UNTRUSTED_SERIALIZE_CLASS, "", "", msg);
|
||||
}
|
||||
|
||||
throw new IllegalArgumentException(msg);
|
||||
|
|
@ -180,7 +180,7 @@ public class DefaultSerializeClassChecker implements AllowClassNotifyListener {
|
|||
"Current mode is `WARN`, will disallow to deserialize it by default. " +
|
||||
"Please add it into security/serialize.allowlist or follow FAQ to configure it.";
|
||||
if (serializeSecurityManager.getWarnedClasses().add(className)) {
|
||||
logger.error(PROTOCOL_UNTRUSTED_SERIALIZE_CLASS, "", "", msg);
|
||||
logger.warn(PROTOCOL_UNTRUSTED_SERIALIZE_CLASS, "", "", msg);
|
||||
}
|
||||
|
||||
throw new IllegalArgumentException(msg);
|
||||
|
|
@ -189,7 +189,7 @@ public class DefaultSerializeClassChecker implements AllowClassNotifyListener {
|
|||
|
||||
Class<?> clazz = ClassUtils.forName(className, classLoader);
|
||||
if (serializeSecurityManager.getWarnedClasses().add(className)) {
|
||||
logger.error(PROTOCOL_UNTRUSTED_SERIALIZE_CLASS, "", "",
|
||||
logger.warn(PROTOCOL_UNTRUSTED_SERIALIZE_CLASS, "", "",
|
||||
"[Serialization Security] Serialized class " + className + " is not in allow list. " +
|
||||
"Current mode is `WARN`, will allow to deserialize it by default. " +
|
||||
"Dubbo will set to `STRICT` mode by default in the future. " +
|
||||
|
|
|
|||
|
|
@ -856,6 +856,23 @@ public final class StringUtils {
|
|||
return sb.toString();
|
||||
}
|
||||
|
||||
public static String join(final Object[] array, final char delimiter, final int startIndex, final int endIndex) {
|
||||
if (ArrayUtils.isEmpty(array)) {
|
||||
return EMPTY_STRING;
|
||||
}
|
||||
if (endIndex - startIndex <= 0) {
|
||||
return EMPTY_STRING;
|
||||
}
|
||||
StringBuilder sb = new StringBuilder();
|
||||
for (int i = startIndex; i < endIndex; i++) {
|
||||
if (i > 0) {
|
||||
sb.append(delimiter);
|
||||
}
|
||||
sb.append(array[i]);
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* parse key-value pair.
|
||||
*
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -24,4 +24,6 @@ public interface ModelConstants {
|
|||
* Keep Dubbo running when spring is stopped
|
||||
*/
|
||||
String KEEP_RUNNING_ON_SPRING_CLOSED = "keepRunningOnSpringClosed";
|
||||
|
||||
String KEEP_RUNNING_ON_SPRING_CLOSED_KEY = "dubbo.module.keepRunningOnSpringClosed";
|
||||
}
|
||||
|
|
|
|||
|
|
@ -227,6 +227,10 @@ class StringUtilsTest {
|
|||
assertEquals(StringUtils.join(s), "123");
|
||||
assertEquals(StringUtils.join(s, ','), "1,2,3");
|
||||
assertEquals(StringUtils.join(s, ","), "1,2,3");
|
||||
assertEquals(StringUtils.join(s, ',', 0, 1), "1");
|
||||
assertEquals(StringUtils.join(s, ',', 0, 2), "1,2");
|
||||
assertEquals(StringUtils.join(s, ',', 0, 3), "1,2,3");
|
||||
assertEquals("", StringUtils.join(s, ',', 2, 0), "1,2");
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
@ -502,4 +506,4 @@ class StringUtilsTest {
|
|||
assertTrue(startsWithIgnoreCase("Dubbo.application.name", "dubbo.application."));
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -463,7 +463,7 @@ public class ReferenceConfig<T> extends ReferenceConfigBase<T> {
|
|||
|
||||
if (logger.isInfoEnabled()) {
|
||||
logger.info("Referred dubbo service: [" + referenceParameters.get(INTERFACE_KEY) + "]." +
|
||||
(Boolean.parseBoolean(referenceParameters.get(GENERIC_KEY)) ?
|
||||
(ProtocolUtils.isGeneric(referenceParameters.get(GENERIC_KEY)) ?
|
||||
" it's GenericService reference" : " it's not GenericService reference"));
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -38,8 +38,6 @@ import org.apache.dubbo.config.invoker.DelegateProviderMetaDataInvoker;
|
|||
import org.apache.dubbo.config.support.Parameter;
|
||||
import org.apache.dubbo.config.utils.ConfigValidationUtils;
|
||||
import org.apache.dubbo.metadata.ServiceNameMapping;
|
||||
import org.apache.dubbo.metrics.event.MetricsEventBus;
|
||||
import org.apache.dubbo.metrics.registry.event.RegistryEvent;
|
||||
import org.apache.dubbo.registry.client.metadata.MetadataUtils;
|
||||
import org.apache.dubbo.rpc.Exporter;
|
||||
import org.apache.dubbo.rpc.Invoker;
|
||||
|
|
@ -193,7 +191,7 @@ public class ServiceConfig<T> extends ServiceConfigBase<T> {
|
|||
}
|
||||
|
||||
@Override
|
||||
public void unexport() {
|
||||
public synchronized void unexport() {
|
||||
if (!exported) {
|
||||
return;
|
||||
}
|
||||
|
|
@ -517,21 +515,17 @@ public class ServiceConfig<T> extends ServiceConfigBase<T> {
|
|||
List<URL> registryURLs = !Boolean.FALSE.equals(isRegister()) ?
|
||||
ConfigValidationUtils.loadRegistries(this, true) : Collections.emptyList();
|
||||
|
||||
MetricsEventBus.post(RegistryEvent.toRsEvent(getApplicationModel(), getUniqueServiceName(), protocols.size() * registryURLs.size()), () -> {
|
||||
for (ProtocolConfig protocolConfig : protocols) {
|
||||
String pathKey = URL.buildKey(getContextPath(protocolConfig)
|
||||
.map(p -> p + "/" + path)
|
||||
.orElse(path), group, version);
|
||||
// stub service will use generated service name
|
||||
if (!serverService) {
|
||||
// In case user specified path, registerImmediately service one more time to map it to path.
|
||||
repository.registerService(pathKey, interfaceClass);
|
||||
}
|
||||
doExportUrlsFor1Protocol(protocolConfig, registryURLs, registerType);
|
||||
}
|
||||
return null;
|
||||
for (ProtocolConfig protocolConfig : protocols) {
|
||||
String pathKey = URL.buildKey(getContextPath(protocolConfig)
|
||||
.map(p -> p + "/" + path)
|
||||
.orElse(path), group, version);
|
||||
// stub service will use generated service name
|
||||
if (!serverService) {
|
||||
// In case user specified path, register service one more time to map it to path.
|
||||
repository.registerService(pathKey, interfaceClass);
|
||||
}
|
||||
);
|
||||
doExportUrlsFor1Protocol(protocolConfig, registryURLs, registerType);
|
||||
}
|
||||
|
||||
providerModel.setServiceUrls(urls);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -55,7 +55,6 @@ import org.apache.dubbo.metadata.report.MetadataReportInstance;
|
|||
import org.apache.dubbo.metrics.collector.DefaultMetricsCollector;
|
||||
import org.apache.dubbo.metrics.config.event.ConfigCenterEvent;
|
||||
import org.apache.dubbo.metrics.event.MetricsEventBus;
|
||||
import org.apache.dubbo.metrics.registry.event.RegistryEvent;
|
||||
import org.apache.dubbo.metrics.report.DefaultMetricsReporterFactory;
|
||||
import org.apache.dubbo.metrics.report.MetricsReporter;
|
||||
import org.apache.dubbo.metrics.report.MetricsReporterFactory;
|
||||
|
|
@ -914,16 +913,12 @@ public class DefaultApplicationDeployer extends AbstractDeployer<ApplicationMode
|
|||
private void registerServiceInstance() {
|
||||
try {
|
||||
registered = true;
|
||||
MetricsEventBus.post(RegistryEvent.toRegisterEvent(applicationModel),
|
||||
() -> {
|
||||
|
||||
ServiceInstanceMetadataUtils.registerMetadataAndInstance(applicationModel);
|
||||
return null;
|
||||
}
|
||||
);
|
||||
|
||||
} catch (Exception e) {
|
||||
logger.error(CONFIG_REGISTER_INSTANCE_ERROR, "configuration server disconnected", "", "Register instance error.", e);
|
||||
}
|
||||
|
||||
if (registered) {
|
||||
// scheduled task for updating Metadata and ServiceInstance
|
||||
asyncMetadataFuture = frameworkExecutorRepository.getSharedScheduledExecutor().scheduleWithFixedDelay(() -> {
|
||||
|
|
|
|||
|
|
@ -335,6 +335,13 @@ public class DefaultModuleDeployer extends AbstractDeployer<ModuleModel> impleme
|
|||
|
||||
private void onModuleFailed(String msg, Throwable ex) {
|
||||
try {
|
||||
try {
|
||||
// un-export all services if start failure
|
||||
unexportServices();
|
||||
} catch (Throwable t) {
|
||||
logger.info("Failed to un-export services after module failed.", t);
|
||||
}
|
||||
|
||||
setFailed(ex);
|
||||
logger.error(CONFIG_FAILED_START_MODEL, "", "", "Model start failed: " + msg, ex);
|
||||
applicationDeployer.notifyModuleChanged(moduleModel, DeployState.FAILED);
|
||||
|
|
@ -450,8 +457,8 @@ public class DefaultModuleDeployer extends AbstractDeployer<ModuleModel> impleme
|
|||
try {
|
||||
configManager.removeConfig(sc);
|
||||
sc.unexport();
|
||||
} catch (Exception ignored) {
|
||||
// ignored
|
||||
} catch (Throwable t) {
|
||||
logger.info("Failed to un-export service. Service Key: " + sc.getUniqueServiceName(), t);
|
||||
}
|
||||
});
|
||||
exportedServices.clear();
|
||||
|
|
|
|||
|
|
@ -73,7 +73,7 @@
|
|||
<dependency>
|
||||
<groupId>org.aspectj</groupId>
|
||||
<artifactId>aspectjweaver</artifactId>
|
||||
<version>1.9.19</version>
|
||||
<version>1.9.20</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
|
|
|
|||
|
|
@ -16,6 +16,7 @@
|
|||
*/
|
||||
package org.apache.dubbo.config.spring.context;
|
||||
|
||||
import org.apache.dubbo.common.config.ConfigurationUtils;
|
||||
import org.apache.dubbo.common.deploy.DeployListenerAdapter;
|
||||
import org.apache.dubbo.common.deploy.DeployState;
|
||||
import org.apache.dubbo.common.deploy.ModuleDeployer;
|
||||
|
|
@ -169,6 +170,9 @@ public class DubboDeployApplicationListener implements ApplicationListener<Appli
|
|||
private void onContextClosedEvent(ContextClosedEvent event) {
|
||||
try {
|
||||
Object value = moduleModel.getAttribute(ModelConstants.KEEP_RUNNING_ON_SPRING_CLOSED);
|
||||
if (value == null) {
|
||||
value = ConfigurationUtils.getProperty(moduleModel, ModelConstants.KEEP_RUNNING_ON_SPRING_CLOSED_KEY);
|
||||
}
|
||||
boolean keepRunningOnClosed = Boolean.parseBoolean(String.valueOf(value));
|
||||
if (!keepRunningOnClosed && !moduleModel.isDestroyed()) {
|
||||
moduleModel.destroy();
|
||||
|
|
@ -182,7 +186,7 @@ public class DubboDeployApplicationListener implements ApplicationListener<Appli
|
|||
|
||||
@Override
|
||||
public int getOrder() {
|
||||
return HIGHEST_PRECEDENCE;
|
||||
return LOWEST_PRECEDENCE;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -25,6 +25,7 @@ import org.apache.dubbo.rpc.model.FrameworkModel;
|
|||
import org.apache.dubbo.rpc.model.ModuleModel;
|
||||
import org.apache.dubbo.rpc.model.ScopeModel;
|
||||
|
||||
import org.springframework.beans.factory.config.AutowireCapableBeanFactory;
|
||||
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
|
||||
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
|
|
@ -49,14 +50,14 @@ public class DubboSpringInitializer {
|
|||
|
||||
public static void initialize(BeanDefinitionRegistry registry) {
|
||||
|
||||
// prepare context and do customize
|
||||
DubboSpringInitContext context = new DubboSpringInitContext();
|
||||
|
||||
// Spring ApplicationContext may not ready at this moment (e.g. load from xml), so use registry as key
|
||||
if (contextMap.putIfAbsent(registry, new DubboSpringInitContext()) != null) {
|
||||
if (contextMap.putIfAbsent(registry, context) != null) {
|
||||
return;
|
||||
}
|
||||
|
||||
// prepare context and do customize
|
||||
DubboSpringInitContext context = contextMap.get(registry);
|
||||
|
||||
// find beanFactory
|
||||
ConfigurableListableBeanFactory beanFactory = findBeanFactory(registry);
|
||||
|
||||
|
|
@ -69,11 +70,12 @@ public class DubboSpringInitializer {
|
|||
}
|
||||
|
||||
public static boolean remove(ApplicationContext springContext) {
|
||||
AutowireCapableBeanFactory autowireCapableBeanFactory = springContext.getAutowireCapableBeanFactory();
|
||||
for (Map.Entry<BeanDefinitionRegistry, DubboSpringInitContext> entry : contextMap.entrySet()) {
|
||||
DubboSpringInitContext initContext = entry.getValue();
|
||||
if (initContext.getApplicationContext() == springContext ||
|
||||
initContext.getBeanFactory() == springContext.getAutowireCapableBeanFactory() ||
|
||||
initContext.getRegistry() == springContext.getAutowireCapableBeanFactory()
|
||||
initContext.getBeanFactory() == autowireCapableBeanFactory ||
|
||||
initContext.getRegistry() == autowireCapableBeanFactory
|
||||
) {
|
||||
DubboSpringInitContext context = contextMap.remove(entry.getKey());
|
||||
logger.info("Unbind " + safeGetModelDesc(context.getModuleModel()) + " from spring container: " +
|
||||
|
|
@ -89,8 +91,7 @@ public class DubboSpringInitializer {
|
|||
}
|
||||
|
||||
static DubboSpringInitContext findBySpringContext(ApplicationContext applicationContext) {
|
||||
for (Map.Entry<BeanDefinitionRegistry, DubboSpringInitContext> entry : contextMap.entrySet()) {
|
||||
DubboSpringInitContext initContext = entry.getValue();
|
||||
for (DubboSpringInitContext initContext : contextMap.values()) {
|
||||
if (initContext.getApplicationContext() == applicationContext) {
|
||||
return initContext;
|
||||
}
|
||||
|
|
@ -113,25 +114,26 @@ public class DubboSpringInitializer {
|
|||
if (findContextForApplication(ApplicationModel.defaultModel()) == null) {
|
||||
// first spring context use default application instance
|
||||
applicationModel = ApplicationModel.defaultModel();
|
||||
logger.info("Use default application: " + safeGetModelDesc(applicationModel));
|
||||
logger.info("Use default application: " + applicationModel.getDesc());
|
||||
} else {
|
||||
// create a new application instance for later spring context
|
||||
applicationModel = FrameworkModel.defaultModel().newApplication();
|
||||
logger.info("Create new application: " + safeGetModelDesc(applicationModel));
|
||||
logger.info("Create new application: " + applicationModel.getDesc());
|
||||
}
|
||||
|
||||
// init ModuleModel
|
||||
moduleModel = applicationModel.getDefaultModule();
|
||||
context.setModuleModel(moduleModel);
|
||||
logger.info("Use default module model of target application: " + safeGetModelDesc(moduleModel));
|
||||
logger.info("Use default module model of target application: " + moduleModel.getDesc());
|
||||
} else {
|
||||
logger.info("Use module model from customizer: " + safeGetModelDesc(moduleModel));
|
||||
logger.info("Use module model from customizer: " + moduleModel.getDesc());
|
||||
}
|
||||
logger.info("Bind " + safeGetModelDesc(moduleModel) + " to spring container: " + ObjectUtils.identityToString(registry));
|
||||
logger.info("Bind " + moduleModel.getDesc() + " to spring container: " + ObjectUtils.identityToString(registry));
|
||||
|
||||
// set module attributes
|
||||
if (context.getModuleAttributes().size() > 0) {
|
||||
context.getModuleModel().getAttributes().putAll(context.getModuleAttributes());
|
||||
Map<String, Object> moduleAttributes = context.getModuleAttributes();
|
||||
if (moduleAttributes.size() > 0) {
|
||||
moduleModel.getAttributes().putAll(moduleAttributes);
|
||||
}
|
||||
|
||||
// bind dubbo initialization context to spring context
|
||||
|
|
@ -207,7 +209,6 @@ public class DubboSpringInitializer {
|
|||
customizer.customize(context);
|
||||
}
|
||||
customizerHolder.clearCustomizers();
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
|
|
|||
|
|
@ -224,7 +224,7 @@
|
|||
<plugin>
|
||||
<groupId>org.graalvm.buildtools</groupId>
|
||||
<artifactId>native-maven-plugin</artifactId>
|
||||
<version>0.9.23</version>
|
||||
<version>0.9.24</version>
|
||||
<configuration>
|
||||
<classesDirectory>${project.build.outputDirectory}</classesDirectory>
|
||||
<metadataRepository>
|
||||
|
|
|
|||
|
|
@ -222,7 +222,7 @@
|
|||
<plugin>
|
||||
<groupId>org.graalvm.buildtools</groupId>
|
||||
<artifactId>native-maven-plugin</artifactId>
|
||||
<version>0.9.23</version>
|
||||
<version>0.9.24</version>
|
||||
<configuration>
|
||||
<classesDirectory>${project.build.outputDirectory}</classesDirectory>
|
||||
<metadataRepository>
|
||||
|
|
|
|||
|
|
@ -38,7 +38,7 @@
|
|||
<skip_maven_deploy>true</skip_maven_deploy>
|
||||
<spring-boot.version>2.7.14</spring-boot.version>
|
||||
<spring-boot-maven-plugin.version>2.7.14</spring-boot-maven-plugin.version>
|
||||
<micrometer-core.version>1.11.2</micrometer-core.version>
|
||||
<micrometer-core.version>1.11.3</micrometer-core.version>
|
||||
</properties>
|
||||
<dependencyManagement>
|
||||
<dependencies>
|
||||
|
|
|
|||
|
|
@ -94,7 +94,7 @@
|
|||
<spring_version>5.3.25</spring_version>
|
||||
<spring_security_version>5.8.5</spring_security_version>
|
||||
<javassist_version>3.29.2-GA</javassist_version>
|
||||
<bytebuddy.version>1.14.5</bytebuddy.version>
|
||||
<bytebuddy.version>1.14.6</bytebuddy.version>
|
||||
<netty_version>3.2.10.Final</netty_version>
|
||||
<netty4_version>4.1.95.Final</netty4_version>
|
||||
<mina_version>2.2.1</mina_version>
|
||||
|
|
@ -102,7 +102,7 @@
|
|||
<httpclient_version>4.5.14</httpclient_version>
|
||||
<httpcore_version>4.4.16</httpcore_version>
|
||||
<fastjson_version>1.2.83</fastjson_version>
|
||||
<fastjson2_version>2.0.35</fastjson2_version>
|
||||
<fastjson2_version>2.0.39</fastjson2_version>
|
||||
<zookeeper_version>3.4.14</zookeeper_version>
|
||||
<curator_version>4.3.0</curator_version>
|
||||
<curator_test_version>2.12.0</curator_test_version>
|
||||
|
|
@ -114,7 +114,7 @@
|
|||
<cxf_version>3.5.5</cxf_version>
|
||||
<thrift_version>0.18.1</thrift_version>
|
||||
<hessian_version>4.0.66</hessian_version>
|
||||
<protobuf-java_version>3.23.4</protobuf-java_version>
|
||||
<protobuf-java_version>3.24.1</protobuf-java_version>
|
||||
<javax_annotation-api_version>1.3.2</javax_annotation-api_version>
|
||||
<servlet_version>3.1.0</servlet_version>
|
||||
<jetty_version>9.4.51.v20230217</jetty_version>
|
||||
|
|
@ -129,18 +129,18 @@
|
|||
<fst_version>2.57</fst_version>
|
||||
<avro_version>1.11.1</avro_version>
|
||||
<apollo_client_version>2.1.0</apollo_client_version>
|
||||
<snakeyaml_version>2.0</snakeyaml_version>
|
||||
<snakeyaml_version>2.1</snakeyaml_version>
|
||||
<commons_lang3_version>3.12.0</commons_lang3_version>
|
||||
<protostuff_version>1.8.0</protostuff_version>
|
||||
<envoy_api_version>0.1.35</envoy_api_version>
|
||||
<micrometer.version>1.11.2</micrometer.version>
|
||||
<micrometer.version>1.11.3</micrometer.version>
|
||||
<opentelemetry.version>1.26.0</opentelemetry.version>
|
||||
<zipkin-reporter.version>2.16.4</zipkin-reporter.version>
|
||||
<micrometer-tracing.version>1.1.3</micrometer-tracing.version>
|
||||
<micrometer-tracing.version>1.1.4</micrometer-tracing.version>
|
||||
<t_digest.version>3.3</t_digest.version>
|
||||
<prometheus_client.version>0.16.0</prometheus_client.version>
|
||||
<reactive.version>1.0.4</reactive.version>
|
||||
<reactor.version>3.5.8</reactor.version>
|
||||
<reactor.version>3.5.9</reactor.version>
|
||||
<rxjava.version>2.2.21</rxjava.version>
|
||||
<okhttp_version>3.14.9</okhttp_version>
|
||||
|
||||
|
|
@ -152,7 +152,7 @@
|
|||
<nacos_version>2.2.4</nacos_version>
|
||||
<sentinel.version>1.8.6</sentinel.version>
|
||||
<seata.version>1.6.1</seata.version>
|
||||
<grpc.version>1.56.1</grpc.version>
|
||||
<grpc.version>1.57.2</grpc.version>
|
||||
<grpc_contrib_verdion>0.8.1</grpc_contrib_verdion>
|
||||
<jprotoc_version>1.2.2</jprotoc_version>
|
||||
<!-- Log libs -->
|
||||
|
|
@ -170,7 +170,7 @@
|
|||
<eureka.version>1.10.18</eureka.version>
|
||||
|
||||
<!-- Fabric8 for Kubernetes -->
|
||||
<fabric8_kubernetes_version>6.6.2</fabric8_kubernetes_version>
|
||||
<fabric8_kubernetes_version>6.8.1</fabric8_kubernetes_version>
|
||||
|
||||
<!-- Alibaba -->
|
||||
<alibaba_spring_context_support_version>1.0.11</alibaba_spring_context_support_version>
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
|
@ -695,6 +702,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>
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
|
|
|||
|
|
@ -101,4 +101,14 @@ public class MetadataIdentifier extends BaseServiceMetadataIdentifier implements
|
|||
return serviceInterface != null ? URL.buildKey(serviceInterface, getGroup(), getVersion()) : null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "MetadataIdentifier{" +
|
||||
"application='" + application + '\'' +
|
||||
", serviceInterface='" + serviceInterface + '\'' +
|
||||
", version='" + version + '\'' +
|
||||
", group='" + group + '\'' +
|
||||
", side='" + side + '\'' +
|
||||
'}';
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -40,6 +40,7 @@ import static java.util.Collections.emptyList;
|
|||
import static java.util.Collections.sort;
|
||||
import static java.util.Collections.unmodifiableMap;
|
||||
import static org.apache.dubbo.common.function.ThrowableFunction.execute;
|
||||
import static org.apache.dubbo.common.utils.AnnotationUtils.isAnnotationPresent;
|
||||
import static org.apache.dubbo.common.utils.AnnotationUtils.isAnyAnnotationPresent;
|
||||
import static org.apache.dubbo.common.utils.ClassUtils.forName;
|
||||
import static org.apache.dubbo.common.utils.ClassUtils.getAllInterfaces;
|
||||
|
|
@ -197,8 +198,9 @@ public abstract class AbstractServiceRestMetadataResolver implements ServiceRest
|
|||
for (Method serviceMethod : serviceMethods) {
|
||||
if (overrides(serviceMethod, declaredServiceMethod)) {
|
||||
serviceMethodsMap.put(serviceMethod, declaredServiceMethod);
|
||||
// once method match ,break for decrease loop times
|
||||
break;
|
||||
// override method count > 1
|
||||
// // once method match ,break for decrease loop times
|
||||
// break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -421,4 +423,16 @@ public abstract class AbstractServiceRestMetadataResolver implements ServiceRest
|
|||
|
||||
return supportedExtensionInstances;
|
||||
}
|
||||
|
||||
public static boolean isServiceMethodAnnotationPresent(Class<?> serviceImpl, String annotationClass) {
|
||||
List<Method> allMethods = getAllMethods(serviceImpl, excludedDeclaredClass(Object.class));
|
||||
|
||||
for (Method method : allMethods) {
|
||||
if (isAnnotationPresent(method, annotationClass)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -110,13 +110,17 @@ public class PathMatcher {
|
|||
}
|
||||
|
||||
public static PathMatcher getInvokeCreatePathMatcher(String path, String version, String group, Integer port, String method) {
|
||||
return new PathMatcher(path, version, group, port, method).noNeedHttpMethodCompare();
|
||||
return new PathMatcher(path, version, group, port, method).compareHttpMethod(false);
|
||||
}
|
||||
|
||||
public static PathMatcher getInvokeCreatePathMatcher(Method serviceMethod) {
|
||||
return new PathMatcher(serviceMethod).setNeedCompareServiceMethod(true);
|
||||
}
|
||||
|
||||
public static PathMatcher convertPathMatcher(PathMatcher pathMatcher) {
|
||||
return getInvokeCreatePathMatcher(pathMatcher.path, pathMatcher.version, pathMatcher.group, pathMatcher.port, pathMatcher.httpMethod);
|
||||
}
|
||||
|
||||
public boolean hasPathVariable() {
|
||||
return hasPathVariable;
|
||||
}
|
||||
|
|
@ -134,8 +138,8 @@ public class PathMatcher {
|
|||
return this;
|
||||
}
|
||||
|
||||
private PathMatcher noNeedHttpMethodCompare() {
|
||||
this.needCompareHttpMethod = false;
|
||||
public PathMatcher compareHttpMethod(boolean needCompareHttpMethod) {
|
||||
this.needCompareHttpMethod = needCompareHttpMethod;
|
||||
return this;
|
||||
}
|
||||
|
||||
|
|
@ -176,7 +180,7 @@ public class PathMatcher {
|
|||
* @return
|
||||
*/
|
||||
private boolean httpMethodMatch(PathMatcher that) {
|
||||
return !that.needCompareHttpMethod || !this.needCompareHttpMethod ? true: Objects.equals(this.httpMethod, that.httpMethod);
|
||||
return !that.needCompareHttpMethod || !this.needCompareHttpMethod ? true : Objects.equals(this.httpMethod, that.httpMethod);
|
||||
}
|
||||
|
||||
private boolean serviceMethodEqual(PathMatcher thatPathMatcher, PathMatcher thisPathMatcher) {
|
||||
|
|
|
|||
|
|
@ -49,7 +49,9 @@ public class JAXRSServiceRestMetadataResolver extends AbstractServiceRestMetadat
|
|||
|
||||
@Override
|
||||
protected boolean supports0(Class<?> serviceType) {
|
||||
return isAnnotationPresent(serviceType, PATH_ANNOTATION_CLASS_NAME);
|
||||
return isAnnotationPresent(serviceType, PATH_ANNOTATION_CLASS_NAME)
|
||||
// method @Path
|
||||
|| isServiceMethodAnnotationPresent(serviceType,PATH_ANNOTATION_CLASS_NAME);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
|||
|
|
@ -41,6 +41,7 @@ import static org.apache.dubbo.metadata.rest.RestMetadataConstants.SPRING_MVC.AN
|
|||
import static org.apache.dubbo.metadata.rest.RestMetadataConstants.SPRING_MVC.CONTROLLER_ANNOTATION_CLASS;
|
||||
import static org.apache.dubbo.metadata.rest.RestMetadataConstants.SPRING_MVC.FEIGN_CLIENT_CLASS;
|
||||
import static org.apache.dubbo.metadata.rest.RestMetadataConstants.SPRING_MVC.REQUEST_MAPPING_ANNOTATION_CLASS;
|
||||
import static org.apache.dubbo.metadata.rest.RestMetadataConstants.SPRING_MVC.REQUEST_MAPPING_ANNOTATION_CLASS_NAME;
|
||||
|
||||
/**
|
||||
* {@link ServiceRestMetadataResolver}
|
||||
|
|
@ -61,7 +62,8 @@ public class SpringMvcServiceRestMetadataResolver extends AbstractServiceRestMet
|
|||
// class @Controller or @RequestMapping
|
||||
return isAnnotationPresent(serviceType, CONTROLLER_ANNOTATION_CLASS)
|
||||
|| isAnnotationPresent(serviceType, FEIGN_CLIENT_CLASS)
|
||||
|| isAnnotationPresent(serviceType, REQUEST_MAPPING_ANNOTATION_CLASS);
|
||||
|| isAnnotationPresent(serviceType, REQUEST_MAPPING_ANNOTATION_CLASS)// method @RequestMapping
|
||||
|| isServiceMethodAnnotationPresent(serviceType, REQUEST_MAPPING_ANNOTATION_CLASS_NAME);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
|||
|
|
@ -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";
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -18,11 +18,12 @@
|
|||
package org.apache.dubbo.metrics.aggregate;
|
||||
|
||||
|
||||
import org.apache.dubbo.metrics.exception.MetricsNeverHappenException;
|
||||
|
||||
import com.tdunning.math.stats.Centroid;
|
||||
import com.tdunning.math.stats.ScaleFunction;
|
||||
import com.tdunning.math.stats.Sort;
|
||||
import com.tdunning.math.stats.TDigest;
|
||||
import org.apache.dubbo.metrics.exception.MetricsNeverHappenException;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
import java.util.AbstractCollection;
|
||||
|
|
@ -285,16 +286,17 @@ public class DubboMergingDigest extends DubboAbstractTDigest {
|
|||
throw new IllegalArgumentException("Cannot add NaN to t-digest");
|
||||
}
|
||||
|
||||
int where;
|
||||
synchronized (this) {
|
||||
// There is a small probability of entering here
|
||||
if (tempUsed.get() >= tempWeight.length - lastUsedCell.get() - 1) {
|
||||
mergeNewValues();
|
||||
}
|
||||
where = tempUsed.getAndIncrement();
|
||||
tempWeight[where] = w;
|
||||
tempMean[where] = x;
|
||||
unmergedWeight.addAndGet(w);
|
||||
}
|
||||
int where = tempUsed.getAndIncrement();
|
||||
tempWeight[where] = w;
|
||||
tempMean[where] = x;
|
||||
unmergedWeight.addAndGet(w);
|
||||
if (x < min) {
|
||||
min = x;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -34,7 +34,7 @@ import static org.apache.dubbo.metrics.MetricsConstants.SELF_INCREMENT_SIZE;
|
|||
|
||||
public abstract class CombMetricsCollector<E extends TimeCounterEvent> extends AbstractMetricsListener<E> implements ApplicationMetricsCollector<E>, ServiceMetricsCollector<E>, MethodMetricsCollector<E> {
|
||||
|
||||
private final BaseStatComposite stats;
|
||||
protected final BaseStatComposite stats;
|
||||
private MetricsEventMulticaster eventMulticaster;
|
||||
|
||||
|
||||
|
|
@ -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);
|
||||
|
|
@ -108,5 +112,9 @@ public abstract class CombMetricsCollector<E extends TimeCounterEvent> extends A
|
|||
public void onEventError(TimeCounterEvent event) {
|
||||
eventMulticaster.publishErrorEvent(event);
|
||||
}
|
||||
|
||||
protected BaseStatComposite getStats() {
|
||||
return stats;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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<>();
|
||||
|
|
|
|||
|
|
@ -18,8 +18,10 @@
|
|||
package org.apache.dubbo.metrics.data;
|
||||
|
||||
import org.apache.dubbo.metrics.collector.MetricsCollector;
|
||||
import org.apache.dubbo.metrics.model.ApplicationMetric;
|
||||
import org.apache.dubbo.metrics.model.MethodMetric;
|
||||
import org.apache.dubbo.metrics.model.MetricsCategory;
|
||||
import org.apache.dubbo.metrics.model.ServiceKeyMetric;
|
||||
import org.apache.dubbo.metrics.model.key.MetricsKey;
|
||||
import org.apache.dubbo.metrics.model.key.MetricsKeyWrapper;
|
||||
import org.apache.dubbo.metrics.model.sample.MetricSample;
|
||||
|
|
@ -29,6 +31,7 @@ import org.apache.dubbo.rpc.model.ApplicationModel;
|
|||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
|
||||
/**
|
||||
|
|
@ -70,11 +73,11 @@ public abstract class BaseStatComposite implements MetricsExport {
|
|||
}
|
||||
|
||||
public void calcApplicationRt(String registryOpType, Long responseTime) {
|
||||
rtStatComposite.calcApplicationRt(registryOpType, responseTime);
|
||||
rtStatComposite.calcServiceKeyRt(registryOpType, responseTime, new ApplicationMetric(rtStatComposite.getApplicationModel()));
|
||||
}
|
||||
|
||||
public void calcServiceKeyRt(String serviceKey, String registryOpType, Long responseTime) {
|
||||
rtStatComposite.calcServiceKeyRt(serviceKey, registryOpType, responseTime);
|
||||
rtStatComposite.calcServiceKeyRt(registryOpType, responseTime, new ServiceKeyMetric(rtStatComposite.getApplicationModel(), serviceKey));
|
||||
}
|
||||
|
||||
public void calcServiceKeyRt(Invocation invocation, String registryOpType, Long responseTime) {
|
||||
|
|
@ -89,6 +92,10 @@ public abstract class BaseStatComposite implements MetricsExport {
|
|||
serviceStatComposite.setServiceKey(metricsKey, serviceKey, num);
|
||||
}
|
||||
|
||||
public void setServiceKey(MetricsKeyWrapper metricsKey, String serviceKey, int num, Map<String, String> extra) {
|
||||
serviceStatComposite.setExtraServiceKey(metricsKey, serviceKey, num, extra);
|
||||
}
|
||||
|
||||
public void incrementApp(MetricsKey metricsKey, int size) {
|
||||
applicationStatComposite.incrementSize(metricsKey, size);
|
||||
}
|
||||
|
|
@ -97,6 +104,10 @@ public abstract class BaseStatComposite implements MetricsExport {
|
|||
serviceStatComposite.incrementServiceKey(metricsKeyWrapper, attServiceKey, size);
|
||||
}
|
||||
|
||||
public void incrementServiceKey(MetricsKeyWrapper metricsKeyWrapper, String attServiceKey, Map<String, String> extra, int size) {
|
||||
serviceStatComposite.incrementExtraServiceKey(metricsKeyWrapper, attServiceKey, extra, size);
|
||||
}
|
||||
|
||||
public void incrementMethodKey(MetricsKeyWrapper metricsKeyWrapper, MethodMetric methodMetric, int size) {
|
||||
methodStatComposite.incrementMethodKey(metricsKeyWrapper, methodMetric, size);
|
||||
}
|
||||
|
|
@ -118,4 +129,8 @@ public abstract class BaseStatComposite implements MetricsExport {
|
|||
public RtStatComposite getRtStatComposite() {
|
||||
return rtStatComposite;
|
||||
}
|
||||
|
||||
public void setAppKey(MetricsKey metricsKey, Long num) {
|
||||
applicationStatComposite.setAppKey(metricsKey, num);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -17,7 +17,6 @@
|
|||
|
||||
package org.apache.dubbo.metrics.data;
|
||||
|
||||
import org.apache.dubbo.metrics.model.ApplicationMetric;
|
||||
import org.apache.dubbo.metrics.model.MethodMetric;
|
||||
import org.apache.dubbo.metrics.model.Metric;
|
||||
import org.apache.dubbo.metrics.model.MetricsCategory;
|
||||
|
|
@ -89,20 +88,7 @@ public class RtStatComposite extends AbstractMetricsExport {
|
|||
return singleRtStats;
|
||||
}
|
||||
|
||||
public void calcApplicationRt(String registryOpType, Long responseTime) {
|
||||
ApplicationMetric key = new ApplicationMetric(getApplicationModel());
|
||||
for (LongContainer container : rtStats.get(registryOpType)) {
|
||||
Number current = (Number) container.get(key);
|
||||
if (current == null) {
|
||||
container.putIfAbsent(key, container.getInitFunc().apply(key));
|
||||
current = (Number) container.get(key);
|
||||
}
|
||||
container.getConsumerFunc().accept(responseTime, current);
|
||||
}
|
||||
}
|
||||
|
||||
public void calcServiceKeyRt(String serviceKey, String registryOpType, Long responseTime) {
|
||||
ServiceKeyMetric key = new ServiceKeyMetric(getApplicationModel(), serviceKey);
|
||||
public void calcServiceKeyRt(String registryOpType, Long responseTime, Metric key) {
|
||||
for (LongContainer container : rtStats.get(registryOpType)) {
|
||||
Number current = (Number) container.get(key);
|
||||
if (current == null) {
|
||||
|
|
|
|||
|
|
@ -53,21 +53,37 @@ public class ServiceStatComposite extends AbstractMetricsExport {
|
|||
}
|
||||
|
||||
public void incrementServiceKey(MetricsKeyWrapper wrapper, String serviceKey, int size) {
|
||||
incrementExtraServiceKey(wrapper, serviceKey, null, size);
|
||||
}
|
||||
|
||||
public void incrementExtraServiceKey(MetricsKeyWrapper wrapper, String serviceKey, Map<String, String> extra, int size) {
|
||||
if (!serviceWrapperNumStats.containsKey(wrapper)) {
|
||||
return;
|
||||
}
|
||||
serviceWrapperNumStats.get(wrapper).computeIfAbsent(new ServiceKeyMetric(getApplicationModel(), serviceKey), k -> new AtomicLong(0L)).getAndAdd(size);
|
||||
ServiceKeyMetric serviceKeyMetric = new ServiceKeyMetric(getApplicationModel(), serviceKey);
|
||||
if (extra != null) {
|
||||
serviceKeyMetric.setExtraInfo(extra);
|
||||
}
|
||||
serviceWrapperNumStats.get(wrapper).computeIfAbsent(serviceKeyMetric, k -> new AtomicLong(0L)).getAndAdd(size);
|
||||
// MetricsSupport.fillZero(serviceWrapperNumStats);
|
||||
}
|
||||
|
||||
public void setServiceKey(MetricsKeyWrapper wrapper, String serviceKey, int num) {
|
||||
setExtraServiceKey(wrapper, serviceKey, num, null);
|
||||
}
|
||||
|
||||
public void setExtraServiceKey(MetricsKeyWrapper wrapper, String serviceKey, int num, Map<String, String> extra) {
|
||||
if (!serviceWrapperNumStats.containsKey(wrapper)) {
|
||||
return;
|
||||
}
|
||||
serviceWrapperNumStats.get(wrapper).computeIfAbsent(new ServiceKeyMetric(getApplicationModel(), serviceKey), k -> new AtomicLong(0L)).set(num);
|
||||
// MetricsSupport.fillZero(serviceWrapperNumStats);
|
||||
ServiceKeyMetric serviceKeyMetric = new ServiceKeyMetric(getApplicationModel(), serviceKey);
|
||||
if (extra != null) {
|
||||
serviceKeyMetric.setExtraInfo(extra);
|
||||
}
|
||||
serviceWrapperNumStats.get(wrapper).computeIfAbsent(serviceKeyMetric, k -> new AtomicLong(0L)).set(num);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<MetricSample> export(MetricsCategory category) {
|
||||
List<MetricSample> list = new ArrayList<>();
|
||||
for (MetricsKeyWrapper wrapper : serviceWrapperNumStats.keySet()) {
|
||||
|
|
|
|||
|
|
@ -23,6 +23,7 @@ import org.apache.dubbo.metrics.model.MethodMetric;
|
|||
import org.apache.dubbo.metrics.model.key.TypeWrapper;
|
||||
import org.apache.dubbo.rpc.model.ApplicationModel;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.IdentityHashMap;
|
||||
import java.util.Map;
|
||||
|
||||
|
|
@ -40,7 +41,7 @@ public abstract class MetricsEvent {
|
|||
private final String appName;
|
||||
private final MetricsDispatcher metricsDispatcher;
|
||||
|
||||
private final Map<String, Object> attachment = new IdentityHashMap<>(8);
|
||||
private final Map<String, Object> attachments = new IdentityHashMap<>(8);
|
||||
|
||||
public MetricsEvent(ApplicationModel source, TypeWrapper typeWrapper) {
|
||||
this(source, null, null, typeWrapper);
|
||||
|
|
@ -82,11 +83,19 @@ public abstract class MetricsEvent {
|
|||
if (key == null) {
|
||||
throw new MetricsNeverHappenException("Attachment key is null");
|
||||
}
|
||||
return (T) attachment.get(key);
|
||||
return (T) attachments.get(key);
|
||||
}
|
||||
|
||||
public Map<String, Object> getAttachments() {
|
||||
return Collections.unmodifiableMap(attachments);
|
||||
}
|
||||
|
||||
public void putAttachment(String key, Object value) {
|
||||
attachment.put(key, value);
|
||||
attachments.put(key, value);
|
||||
}
|
||||
|
||||
public void putAttachments(Map<String, String> attachments) {
|
||||
this.attachments.putAll(attachments);
|
||||
}
|
||||
|
||||
public void setAvailable(boolean available) {
|
||||
|
|
|
|||
|
|
@ -17,15 +17,22 @@
|
|||
|
||||
package org.apache.dubbo.metrics.event;
|
||||
|
||||
import org.apache.dubbo.common.logger.ErrorTypeAwareLogger;
|
||||
import org.apache.dubbo.common.logger.LoggerFactory;
|
||||
|
||||
import java.util.Optional;
|
||||
import java.util.function.Function;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
import static org.apache.dubbo.common.constants.LoggerCodeConstants.COMMON_METRICS_COLLECTOR_EXCEPTION;
|
||||
|
||||
/**
|
||||
* Dispatches events to listeners, and provides ways for listeners to register themselves.
|
||||
*/
|
||||
public class MetricsEventBus {
|
||||
|
||||
private static final ErrorTypeAwareLogger logger = LoggerFactory.getErrorTypeAwareLogger(MetricsEventBus.class);
|
||||
|
||||
/**
|
||||
* Posts an event to all registered subscribers and only once.
|
||||
*
|
||||
|
|
@ -36,7 +43,9 @@ public class MetricsEventBus {
|
|||
return;
|
||||
}
|
||||
MetricsDispatcher dispatcher = event.getMetricsDispatcher();
|
||||
Optional.ofNullable(dispatcher).ifPresent(d -> d.publishEvent(event));
|
||||
Optional.ofNullable(dispatcher).ifPresent(d -> {
|
||||
tryInvoke(() -> d.publishEvent(event));
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -63,27 +72,35 @@ public class MetricsEventBus {
|
|||
*/
|
||||
public static <T> T post(MetricsEvent event, Supplier<T> targetSupplier, Function<T, Boolean> trFunction) {
|
||||
T result;
|
||||
before(event);
|
||||
tryInvoke(() -> before(event));
|
||||
if (trFunction == null) {
|
||||
try {
|
||||
result = targetSupplier.get();
|
||||
} catch (Throwable e) {
|
||||
error(event);
|
||||
tryInvoke(() -> error(event));
|
||||
throw e;
|
||||
}
|
||||
after(event, result);
|
||||
tryInvoke(() -> after(event, result));
|
||||
} else {
|
||||
// Custom failure status
|
||||
result = targetSupplier.get();
|
||||
if (trFunction.apply(result)) {
|
||||
after(event, result);
|
||||
tryInvoke(() -> after(event, result));
|
||||
} else {
|
||||
error(event);
|
||||
tryInvoke(() -> error(event));
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public static void tryInvoke(Runnable runnable) {
|
||||
try {
|
||||
runnable.run();
|
||||
} catch (Throwable e) {
|
||||
logger.warn(COMMON_METRICS_COLLECTOR_EXCEPTION, "", "", "invoke metric event error" + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Applicable to the scene where execution and return are separated,
|
||||
* eventSaveRunner saves the event, so that the calculation rt is introverted
|
||||
|
|
@ -91,20 +108,22 @@ public class MetricsEventBus {
|
|||
public static void before(MetricsEvent event) {
|
||||
MetricsDispatcher dispatcher = validate(event);
|
||||
if (dispatcher == null) return;
|
||||
dispatcher.publishEvent(event);
|
||||
tryInvoke(() -> dispatcher.publishEvent(event));
|
||||
}
|
||||
|
||||
public static void after(MetricsEvent event, Object result) {
|
||||
MetricsDispatcher dispatcher = validate(event);
|
||||
if (dispatcher == null) return;
|
||||
event.customAfterPost(result);
|
||||
dispatcher.publishFinishEvent((TimeCounterEvent) event);
|
||||
tryInvoke(() -> {
|
||||
event.customAfterPost(result);
|
||||
dispatcher.publishFinishEvent((TimeCounterEvent) event);
|
||||
});
|
||||
}
|
||||
|
||||
public static void error(MetricsEvent event) {
|
||||
MetricsDispatcher dispatcher = validate(event);
|
||||
if (dispatcher == null) return;
|
||||
dispatcher.publishErrorEvent((TimeCounterEvent) event);
|
||||
tryInvoke(() -> dispatcher.publishErrorEvent((TimeCounterEvent) event));
|
||||
}
|
||||
|
||||
private static MetricsDispatcher validate(MetricsEvent event) {
|
||||
|
|
|
|||
|
|
@ -27,6 +27,7 @@ import java.util.function.Consumer;
|
|||
/**
|
||||
* According to the event template of {@link MetricsEventBus},
|
||||
* build a consistent static method for general and custom monitoring consume methods
|
||||
*
|
||||
*/
|
||||
public abstract class AbstractMetricsKeyListener extends AbstractMetricsListener<TimeCounterEvent> implements MetricsLifeListener<TimeCounterEvent> {
|
||||
|
||||
|
|
|
|||
|
|
@ -28,7 +28,7 @@ public abstract class AbstractMetricsListener<E extends MetricsEvent> implements
|
|||
private final Map<Integer, Boolean> eventMatchCache = new ConcurrentHashMap<>();
|
||||
|
||||
/**
|
||||
* Whether to support the general determination of event points depends on the event type
|
||||
* Only interested in events of the current listener's generic parameter type
|
||||
*/
|
||||
public boolean isSupport(MetricsEvent event) {
|
||||
Boolean eventMatch = eventMatchCache.get(System.identityHashCode(event.getClass()));
|
||||
|
|
|
|||
|
|
@ -21,19 +21,37 @@ import org.apache.dubbo.metrics.collector.CombMetricsCollector;
|
|||
import org.apache.dubbo.metrics.model.key.MetricsKey;
|
||||
import org.apache.dubbo.metrics.model.key.MetricsPlaceValue;
|
||||
|
||||
/**
|
||||
* App-level listener type, in most cases, can use the static method
|
||||
* to produce an anonymous listener for general monitoring
|
||||
*/
|
||||
public class MetricsApplicationListener extends AbstractMetricsKeyListener {
|
||||
|
||||
public MetricsApplicationListener(MetricsKey metricsKey) {
|
||||
super(metricsKey);
|
||||
}
|
||||
|
||||
public static AbstractMetricsKeyListener onPostEventBuild(MetricsKey metricsKey, CombMetricsCollector collector) {
|
||||
/**
|
||||
* Perform auto-increment on the monitored key,
|
||||
* Can use a custom listener instead of this generic operation
|
||||
*
|
||||
* @param metricsKey Monitor key
|
||||
* @param collector Corresponding collector
|
||||
*/
|
||||
public static AbstractMetricsKeyListener onPostEventBuild(MetricsKey metricsKey, CombMetricsCollector<?> collector) {
|
||||
return AbstractMetricsKeyListener.onEvent(metricsKey,
|
||||
event -> collector.increment(metricsKey)
|
||||
event -> collector.increment(metricsKey)
|
||||
);
|
||||
}
|
||||
|
||||
public static AbstractMetricsKeyListener onFinishEventBuild(MetricsKey metricsKey, MetricsPlaceValue placeType, CombMetricsCollector collector) {
|
||||
/**
|
||||
* To end the monitoring normally, in addition to increasing the number of corresponding indicators,
|
||||
* use the introspection method to calculate the relevant rt indicators
|
||||
*
|
||||
* @param metricsKey Monitor key
|
||||
* @param collector Corresponding collector
|
||||
*/
|
||||
public static AbstractMetricsKeyListener onFinishEventBuild(MetricsKey metricsKey, MetricsPlaceValue placeType, CombMetricsCollector<?> collector) {
|
||||
return AbstractMetricsKeyListener.onFinish(metricsKey,
|
||||
event -> {
|
||||
collector.increment(metricsKey);
|
||||
|
|
@ -42,7 +60,10 @@ public class MetricsApplicationListener extends AbstractMetricsKeyListener {
|
|||
);
|
||||
}
|
||||
|
||||
public static AbstractMetricsKeyListener onErrorEventBuild(MetricsKey metricsKey, MetricsPlaceValue placeType, CombMetricsCollector collector) {
|
||||
/**
|
||||
* Similar to onFinishEventBuild
|
||||
*/
|
||||
public static AbstractMetricsKeyListener onErrorEventBuild(MetricsKey metricsKey, MetricsPlaceValue placeType, CombMetricsCollector<?> collector) {
|
||||
return AbstractMetricsKeyListener.onError(metricsKey,
|
||||
event -> {
|
||||
collector.increment(metricsKey);
|
||||
|
|
|
|||
|
|
@ -23,6 +23,11 @@ import org.apache.dubbo.metrics.model.MetricsSupport;
|
|||
import org.apache.dubbo.metrics.model.key.MetricsKey;
|
||||
import org.apache.dubbo.metrics.model.key.MetricsPlaceValue;
|
||||
|
||||
/**
|
||||
* Service-level listener type, in most cases, can use the static method
|
||||
* to produce an anonymous listener for general monitoring.
|
||||
* Similar to App-level
|
||||
*/
|
||||
public class MetricsServiceListener extends AbstractMetricsKeyListener {
|
||||
|
||||
public MetricsServiceListener(MetricsKey metricsKey) {
|
||||
|
|
|
|||
|
|
@ -17,25 +17,14 @@
|
|||
|
||||
package org.apache.dubbo.metrics.model;
|
||||
|
||||
import org.apache.dubbo.common.Version;
|
||||
import org.apache.dubbo.metrics.model.key.MetricsKey;
|
||||
import org.apache.dubbo.rpc.model.ApplicationModel;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
|
||||
import static org.apache.dubbo.common.constants.MetricsConstants.TAG_APPLICATION_NAME;
|
||||
import static org.apache.dubbo.common.constants.MetricsConstants.TAG_APPLICATION_VERSION_KEY;
|
||||
import static org.apache.dubbo.common.constants.MetricsConstants.TAG_HOSTNAME;
|
||||
import static org.apache.dubbo.common.constants.MetricsConstants.TAG_IP;
|
||||
import static org.apache.dubbo.common.utils.NetUtils.getLocalHost;
|
||||
import static org.apache.dubbo.common.utils.NetUtils.getLocalHostName;
|
||||
|
||||
public class ApplicationMetric implements Metric {
|
||||
private final ApplicationModel applicationModel;
|
||||
private static final String version = Version.getVersion();
|
||||
private static final String commitId = Version.getLastCommitId();
|
||||
protected Map<String, String> extraInfo;
|
||||
|
||||
public ApplicationMetric(ApplicationModel applicationModel) {
|
||||
this.applicationModel = applicationModel;
|
||||
|
|
@ -49,27 +38,29 @@ public class ApplicationMetric implements Metric {
|
|||
return getApplicationModel().getApplicationName();
|
||||
}
|
||||
|
||||
public String getData() {
|
||||
return version;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, String> getTags() {
|
||||
Map<String, String> tags = new HashMap<>();
|
||||
tags.put(TAG_IP, getLocalHost());
|
||||
tags.put(TAG_HOSTNAME, getLocalHostName());
|
||||
tags.put(TAG_APPLICATION_NAME, getApplicationName());
|
||||
tags.put(TAG_APPLICATION_VERSION_KEY, version);
|
||||
tags.put(MetricsKey.METADATA_GIT_COMMITID_METRIC.getName(), commitId);
|
||||
return tags;
|
||||
return MetricsSupport.applicationTags(applicationModel, getExtraInfo());
|
||||
}
|
||||
|
||||
public Map<String, String> getExtraInfo() {
|
||||
return extraInfo;
|
||||
}
|
||||
|
||||
public void setExtraInfo(Map<String, String> extraInfo) {
|
||||
this.extraInfo = extraInfo;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (!(o instanceof ApplicationMetric)) return false;
|
||||
if (this == o) {
|
||||
return true;
|
||||
}
|
||||
if (o == null || getClass() != o.getClass()) {
|
||||
return false;
|
||||
}
|
||||
ApplicationMetric that = (ApplicationMetric) o;
|
||||
return Objects.equals(getApplicationName(), that.applicationModel.getApplicationName());
|
||||
return getApplicationName().equals(that.applicationModel.getApplicationName()) && Objects.equals(extraInfo, that.extraInfo);
|
||||
}
|
||||
|
||||
private volatile int hashCode;
|
||||
|
|
@ -77,8 +68,9 @@ public class ApplicationMetric implements Metric {
|
|||
@Override
|
||||
public int hashCode() {
|
||||
if (hashCode == 0) {
|
||||
hashCode = Objects.hash(getApplicationName());
|
||||
hashCode = Objects.hash(getApplicationName(), extraInfo);
|
||||
}
|
||||
return hashCode;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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.dubbo.metrics.model;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import static org.apache.dubbo.common.constants.MetricsConstants.TAG_APPLICATION_NAME;
|
||||
import static org.apache.dubbo.common.constants.MetricsConstants.TAG_ERROR_CODE;
|
||||
|
||||
/**
|
||||
* ErrorCodeMetric. Provide tags for error code metrics.
|
||||
*/
|
||||
public class ErrorCodeMetric implements Metric {
|
||||
|
||||
private final String errorCode;
|
||||
|
||||
private final String applicationName;
|
||||
|
||||
public ErrorCodeMetric(String applicationName, String errorCode) {
|
||||
this.errorCode = errorCode;
|
||||
this.applicationName = applicationName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, String> getTags() {
|
||||
Map<String, String> tags = new HashMap<>();
|
||||
tags.put(TAG_ERROR_CODE, errorCode);
|
||||
tags.put(TAG_APPLICATION_NAME, applicationName);
|
||||
return tags;
|
||||
}
|
||||
|
||||
public String getErrorCode() {
|
||||
return errorCode;
|
||||
}
|
||||
}
|
||||
|
|
@ -29,4 +29,6 @@ public enum MetricsCategory {
|
|||
REGISTRY,
|
||||
METADATA,
|
||||
THREAD_POOL,
|
||||
ERROR_CODE,
|
||||
NETTY,
|
||||
}
|
||||
|
|
|
|||
|
|
@ -18,12 +18,12 @@
|
|||
package org.apache.dubbo.metrics.model;
|
||||
|
||||
import org.apache.dubbo.common.Version;
|
||||
import org.apache.dubbo.common.lang.Nullable;
|
||||
import org.apache.dubbo.common.utils.CollectionUtils;
|
||||
import org.apache.dubbo.metrics.collector.MethodMetricsCollector;
|
||||
import org.apache.dubbo.metrics.collector.ServiceMetricsCollector;
|
||||
import org.apache.dubbo.metrics.event.MetricsEvent;
|
||||
import org.apache.dubbo.metrics.event.TimeCounterEvent;
|
||||
import org.apache.dubbo.metrics.exception.MetricsNeverHappenException;
|
||||
import org.apache.dubbo.metrics.model.key.MetricsKey;
|
||||
import org.apache.dubbo.metrics.model.key.MetricsKeyWrapper;
|
||||
import org.apache.dubbo.metrics.model.key.MetricsPlaceValue;
|
||||
|
|
@ -62,6 +62,10 @@ public class MetricsSupport {
|
|||
private static final String commitId = Version.getLastCommitId();
|
||||
|
||||
public static Map<String, String> applicationTags(ApplicationModel applicationModel) {
|
||||
return applicationTags(applicationModel, null);
|
||||
}
|
||||
|
||||
public static Map<String, String> applicationTags(ApplicationModel applicationModel, @Nullable Map<String, String> extraInfo) {
|
||||
Map<String, String> tags = new HashMap<>();
|
||||
tags.put(TAG_IP, getLocalHost());
|
||||
tags.put(TAG_HOSTNAME, getLocalHostName());
|
||||
|
|
@ -69,23 +73,18 @@ public class MetricsSupport {
|
|||
tags.put(TAG_APPLICATION_MODULE, applicationModel.getInternalId());
|
||||
tags.put(TAG_APPLICATION_VERSION_KEY, version);
|
||||
tags.put(MetricsKey.METADATA_GIT_COMMITID_METRIC.getName(), commitId);
|
||||
if (CollectionUtils.isNotEmptyMap(extraInfo)) {
|
||||
tags.putAll(extraInfo);
|
||||
}
|
||||
return tags;
|
||||
}
|
||||
|
||||
public static Map<String, String> serviceTags(ApplicationModel applicationModel, String serviceKey) {
|
||||
Map<String, String> tags = applicationTags(applicationModel);
|
||||
public static Map<String, String> serviceTags(ApplicationModel applicationModel, String serviceKey, Map<String, String> extraInfo) {
|
||||
Map<String, String> tags = applicationTags(applicationModel, extraInfo);
|
||||
tags.put(TAG_INTERFACE_KEY, serviceKey);
|
||||
return tags;
|
||||
}
|
||||
|
||||
public static Map<String, String> methodTags(ApplicationModel applicationModel, String names) {
|
||||
String[] keys = names.split("_");
|
||||
if (keys.length != 2) {
|
||||
throw new MetricsNeverHappenException("Error names: " + names);
|
||||
}
|
||||
return methodTags(applicationModel, keys[0], keys[1]);
|
||||
}
|
||||
|
||||
public static Map<String, String> methodTags(ApplicationModel applicationModel, String serviceKey, String methodName) {
|
||||
Map<String, String> tags = applicationTags(applicationModel);
|
||||
tags.put(TAG_INTERFACE_KEY, serviceKey);
|
||||
|
|
@ -211,7 +210,6 @@ public class MetricsSupport {
|
|||
Invocation invocation = event.getAttachmentValue(INVOCATION);
|
||||
if (invocation != null) {
|
||||
collector.addServiceRt(invocation, placeType.getType(), event.getTimePair().calc());
|
||||
return;
|
||||
} else {
|
||||
collector.addServiceRt((String) event.getAttachmentValue(ATTACHMENT_KEY_SERVICE), placeType.getType(), event.getTimePair().calc());
|
||||
}
|
||||
|
|
@ -240,9 +238,9 @@ public class MetricsSupport {
|
|||
}
|
||||
|
||||
/**
|
||||
* Generate a complete indicator item for an interface/method
|
||||
* Generate a complete indicator item for an interface/method
|
||||
*/
|
||||
public static <T> void fillZero(Map<MetricsKeyWrapper, Map<T, AtomicLong>> data) {
|
||||
public static <T> void fillZero(Map<?, Map<T, AtomicLong>> data) {
|
||||
if (CollectionUtils.isEmptyMap(data)) {
|
||||
return;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -35,7 +35,7 @@ public class ServiceKeyMetric extends ApplicationMetric {
|
|||
|
||||
@Override
|
||||
public Map<String, String> getTags() {
|
||||
return MetricsSupport.serviceTags(getApplicationModel(), serviceKey);
|
||||
return MetricsSupport.serviceTags(getApplicationModel(), serviceKey, getExtraInfo());
|
||||
}
|
||||
|
||||
public String getServiceKey() {
|
||||
|
|
@ -47,16 +47,11 @@ public class ServiceKeyMetric extends ApplicationMetric {
|
|||
if (this == o) {
|
||||
return true;
|
||||
}
|
||||
if (o == null || getClass() != o.getClass()) {
|
||||
if (!(o instanceof ServiceKeyMetric)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
ServiceKeyMetric that = (ServiceKeyMetric) o;
|
||||
|
||||
if (!getApplicationName().equals(that.getApplicationName())) {
|
||||
return false;
|
||||
}
|
||||
return serviceKey.equals(that.serviceKey);
|
||||
return serviceKey.equals(that.serviceKey) && Objects.equals(extraInfo, that.extraInfo);
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -65,7 +60,7 @@ public class ServiceKeyMetric extends ApplicationMetric {
|
|||
@Override
|
||||
public int hashCode() {
|
||||
if (hashCode == 0) {
|
||||
hashCode = Objects.hash(getApplicationName(), serviceKey);
|
||||
hashCode = Objects.hash(getApplicationName(), serviceKey, extraInfo);
|
||||
}
|
||||
return hashCode;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -85,6 +85,7 @@ public class ThreadPoolMetric implements Metric{
|
|||
return Objects.hash(applicationName, threadPoolName);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, String> getTags() {
|
||||
Map<String, String> tags = new HashMap<>();
|
||||
tags.put(TAG_IP, getLocalHost());
|
||||
|
|
|
|||
|
|
@ -30,6 +30,7 @@ import static org.apache.dubbo.common.constants.MetricsConstants.TAG_HOSTNAME;
|
|||
import static org.apache.dubbo.common.constants.MetricsConstants.TAG_IP;
|
||||
|
||||
public class ThreadPoolRejectMetric implements Metric{
|
||||
|
||||
private String applicationName;
|
||||
|
||||
private String threadPoolName;
|
||||
|
|
@ -69,6 +70,7 @@ public class ThreadPoolRejectMetric implements Metric{
|
|||
return Objects.hash(applicationName, threadPoolName);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, String> getTags() {
|
||||
Map<String, String> tags = new HashMap<>();
|
||||
tags.put(TAG_IP, getLocalHost());
|
||||
|
|
|
|||
|
|
@ -43,7 +43,7 @@ public class MetricsCat {
|
|||
}
|
||||
|
||||
/**
|
||||
* @param tpFunc Ternary function, corresponding to finish and error events, because an additional record rt is required, and the type type of metricsKey is required
|
||||
* @param tpFunc Ternary function, corresponding to finish and error events, because an additional record rt is required, and the type of metricsKey is required
|
||||
*/
|
||||
public MetricsCat(MetricsKey metricsKey, TpFunction<MetricsKey, MetricsPlaceValue, CombMetricsCollector, AbstractMetricsKeyListener> tpFunc) {
|
||||
this.eventFunc = collector -> tpFunc.apply(metricsKey, placeType, collector);
|
||||
|
|
|
|||
|
|
@ -17,131 +17,160 @@
|
|||
|
||||
package org.apache.dubbo.metrics.model.key;
|
||||
|
||||
/**
|
||||
* Please follow a unified naming format as follows:
|
||||
* dubbo_type_action_unit_otherfun
|
||||
*/
|
||||
public enum MetricsKey {
|
||||
APPLICATION_METRIC_INFO("dubbo.application.info.total", "Total Application Info"),
|
||||
APPLICATION_METRIC_INFO("application.info.total", "Total Application Info"),
|
||||
|
||||
CONFIGCENTER_METRIC_TOTAL("dubbo.configcenter.total", "Config Changed Total"),
|
||||
CONFIGCENTER_METRIC_TOTAL("configcenter.total", "Config Changed Total"),
|
||||
|
||||
// provider metrics key
|
||||
METRIC_REQUESTS("dubbo.%s.requests.total", "Total Requests"),
|
||||
METRIC_REQUESTS_SUCCEED("dubbo.%s.requests.succeed.total", "Total Succeed Requests"),
|
||||
METRIC_REQUEST_BUSINESS_FAILED("dubbo.%s.requests.business.failed.total", "Total Failed Business Requests"),
|
||||
METRIC_REQUESTS("requests.total", "Total Requests"),
|
||||
METRIC_REQUESTS_SUCCEED("requests.succeed.total", "Total Succeed Requests"),
|
||||
METRIC_REQUEST_BUSINESS_FAILED("requests.business.failed.total", "Total Failed Business Requests"),
|
||||
|
||||
METRIC_REQUESTS_PROCESSING("dubbo.%s.requests.processing.total", "Processing Requests"),
|
||||
METRIC_REQUESTS_TIMEOUT("dubbo.%s.requests.timeout.total", "Total Timeout Failed Requests"),
|
||||
METRIC_REQUESTS_LIMIT("dubbo.%s.requests.limit.total", "Total Limit Failed Requests"),
|
||||
METRIC_REQUESTS_FAILED("dubbo.%s.requests.unknown.failed.total", "Total Unknown Failed Requests"),
|
||||
METRIC_REQUESTS_TOTAL_FAILED("dubbo.%s.requests.failed.total", "Total Failed Requests"),
|
||||
METRIC_REQUESTS_NETWORK_FAILED("dubbo.%s.requests.failed.network.total", "Total network Failed Requests"),
|
||||
METRIC_REQUESTS_SERVICE_UNAVAILABLE_FAILED("dubbo.%s.requests.failed.service.unavailable.total", "Total Service Unavailable Failed Requests"),
|
||||
METRIC_REQUESTS_CODEC_FAILED("dubbo.%s.requests.failed.codec.total", "Total Codec Failed Requests"),
|
||||
METRIC_REQUESTS_PROCESSING("requests.processing.total", "Processing Requests"),
|
||||
METRIC_REQUESTS_TIMEOUT("requests.timeout.total", "Total Timeout Failed Requests"),
|
||||
METRIC_REQUESTS_LIMIT("requests.limit.total", "Total Limit Failed Requests"),
|
||||
METRIC_REQUESTS_FAILED("requests.unknown.failed.total", "Total Unknown Failed Requests"),
|
||||
METRIC_REQUESTS_TOTAL_FAILED("requests.failed.total", "Total Failed Requests"),
|
||||
METRIC_REQUESTS_NETWORK_FAILED("requests.failed.network.total", "Total network Failed Requests"),
|
||||
METRIC_REQUESTS_SERVICE_UNAVAILABLE_FAILED("requests.failed.service.unavailable.total", "Total Service Unavailable Failed Requests"),
|
||||
METRIC_REQUESTS_CODEC_FAILED("requests.failed.codec.total", "Total Codec Failed Requests"),
|
||||
|
||||
METRIC_REQUESTS_TOTAL_AGG("dubbo.%s.requests.total.aggregate", "Aggregated Total Requests"),
|
||||
METRIC_REQUESTS_SUCCEED_AGG("dubbo.%s.requests.succeed.aggregate", "Aggregated Succeed Requests"),
|
||||
METRIC_REQUESTS_FAILED_AGG("dubbo.%s.requests.failed.aggregate", "Aggregated Failed Requests"),
|
||||
METRIC_REQUEST_BUSINESS_FAILED_AGG("dubbo.%s.requests.business.failed.aggregate", "Aggregated Business Failed Requests"),
|
||||
METRIC_REQUESTS_TIMEOUT_AGG("dubbo.%s.requests.timeout.failed.aggregate", "Aggregated timeout Failed Requests"),
|
||||
METRIC_REQUESTS_LIMIT_AGG("dubbo.%s.requests.limit.aggregate", "Aggregated limit Requests"),
|
||||
METRIC_REQUESTS_TOTAL_FAILED_AGG("dubbo.%s.requests.failed.total.aggregate", "Aggregated failed total Requests"),
|
||||
METRIC_REQUESTS_NETWORK_FAILED_AGG("dubbo.%s.requests.failed.network.total.aggregate", "Aggregated failed network total Requests"),
|
||||
METRIC_REQUESTS_CODEC_FAILED_AGG("dubbo.%s.requests.failed.codec.total.aggregate", "Aggregated failed codec total Requests"),
|
||||
METRIC_REQUESTS_TOTAL_SERVICE_UNAVAILABLE_FAILED_AGG("dubbo.%s.requests.failed.service.unavailable.total.aggregate", "Aggregated failed codec total Requests"),
|
||||
METRIC_REQUESTS_TOTAL_AGG("requests.total.aggregate", "Aggregated Total Requests"),
|
||||
METRIC_REQUESTS_SUCCEED_AGG("requests.succeed.aggregate", "Aggregated Succeed Requests"),
|
||||
METRIC_REQUESTS_FAILED_AGG("requests.failed.aggregate", "Aggregated Failed Requests"),
|
||||
METRIC_REQUEST_BUSINESS_FAILED_AGG("requests.business.failed.aggregate", "Aggregated Business Failed Requests"),
|
||||
METRIC_REQUESTS_TIMEOUT_AGG("requests.timeout.failed.aggregate", "Aggregated timeout Failed Requests"),
|
||||
METRIC_REQUESTS_LIMIT_AGG("requests.limit.aggregate", "Aggregated limit Requests"),
|
||||
METRIC_REQUESTS_TOTAL_FAILED_AGG("requests.failed.total.aggregate", "Aggregated failed total Requests"),
|
||||
METRIC_REQUESTS_NETWORK_FAILED_AGG("requests.failed.network.total.aggregate", "Aggregated failed network total Requests"),
|
||||
METRIC_REQUESTS_CODEC_FAILED_AGG("requests.failed.codec.total.aggregate", "Aggregated failed codec total Requests"),
|
||||
METRIC_REQUESTS_TOTAL_SERVICE_UNAVAILABLE_FAILED_AGG("requests.failed.service.unavailable.total.aggregate", "Aggregated failed codec total Requests"),
|
||||
|
||||
METRIC_QPS("dubbo.%s.qps.total", "Query Per Seconds"),
|
||||
METRIC_RT_LAST("dubbo.%s.rt.milliseconds.last", "Last Response Time"),
|
||||
METRIC_RT_MIN("dubbo.%s.rt.milliseconds.min", "Min Response Time"),
|
||||
METRIC_RT_MAX("dubbo.%s.rt.milliseconds.max", "Max Response Time"),
|
||||
METRIC_RT_SUM("dubbo.%s.rt.milliseconds.sum", "Sum Response Time"),
|
||||
METRIC_RT_AVG("dubbo.%s.rt.milliseconds.avg", "Average Response Time"),
|
||||
METRIC_RT_P99("dubbo.%s.rt.milliseconds.p99", "Response Time P99"),
|
||||
METRIC_RT_P95("dubbo.%s.rt.milliseconds.p95", "Response Time P95"),
|
||||
METRIC_RT_P90("dubbo.%s.rt.milliseconds.p90", "Response Time P90"),
|
||||
METRIC_RT_P50("dubbo.%s.rt.milliseconds.p50", "Response Time P50"),
|
||||
METRIC_RT_MIN_AGG("dubbo.%s.rt.min.milliseconds.aggregate", "Aggregated Min Response"),
|
||||
METRIC_RT_MAX_AGG("dubbo.%s.rt.max.milliseconds.aggregate", "Aggregated Max Response"),
|
||||
METRIC_RT_AVG_AGG("dubbo.%s.rt.avg.milliseconds.aggregate", "Aggregated Avg Response"),
|
||||
METRIC_QPS("qps.total", "Query Per Seconds"),
|
||||
METRIC_RT_LAST("rt.milliseconds.last", "Last Response Time"),
|
||||
METRIC_RT_MIN("rt.milliseconds.min", "Min Response Time"),
|
||||
METRIC_RT_MAX("rt.milliseconds.max", "Max Response Time"),
|
||||
METRIC_RT_SUM("rt.milliseconds.sum", "Sum Response Time"),
|
||||
METRIC_RT_AVG("rt.milliseconds.avg", "Average Response Time"),
|
||||
METRIC_RT_P99("rt.milliseconds.p99", "Response Time P99"),
|
||||
METRIC_RT_P95("rt.milliseconds.p95", "Response Time P95"),
|
||||
METRIC_RT_P90("rt.milliseconds.p90", "Response Time P90"),
|
||||
METRIC_RT_P50("rt.milliseconds.p50", "Response Time P50"),
|
||||
METRIC_RT_MIN_AGG("rt.milliseconds.min.aggregate", "Aggregated Min Response"),
|
||||
METRIC_RT_MAX_AGG("rt.milliseconds.max.aggregate", "Aggregated Max Response"),
|
||||
METRIC_RT_AVG_AGG("rt.milliseconds.avg.aggregate", "Aggregated Avg Response"),
|
||||
|
||||
// register metrics key
|
||||
REGISTER_METRIC_REQUESTS("dubbo.registry.register.requests.total", "Total Register Requests"),
|
||||
REGISTER_METRIC_REQUESTS_SUCCEED("dubbo.registry.register.requests.succeed.total", "Succeed Register Requests"),
|
||||
REGISTER_METRIC_REQUESTS_FAILED("dubbo.registry.register.requests.failed.total", "Failed Register Requests"),
|
||||
METRIC_RT_HISTOGRAM("dubbo.%s.rt.milliseconds.histogram", "Response Time Histogram"),
|
||||
REGISTER_METRIC_REQUESTS("registry.register.requests.total", "Total Register Requests"),
|
||||
REGISTER_METRIC_REQUESTS_SUCCEED("registry.register.requests.succeed.total", "Succeed Register Requests"),
|
||||
REGISTER_METRIC_REQUESTS_FAILED("registry.register.requests.failed.total", "Failed Register Requests"),
|
||||
METRIC_RT_HISTOGRAM("rt.milliseconds.histogram", "Response Time Histogram"),
|
||||
|
||||
|
||||
GENERIC_METRIC_REQUESTS("dubbo.%s.requests.total", "Total %s Requests"),
|
||||
GENERIC_METRIC_REQUESTS_SUCCEED("dubbo.%s.requests.succeed.total", "Succeed %s Requests"),
|
||||
GENERIC_METRIC_REQUESTS_FAILED("dubbo.%s.requests.failed.total", "Failed %s Requests"),
|
||||
GENERIC_METRIC_REQUESTS("requests.total", "Total %s Requests"),
|
||||
GENERIC_METRIC_REQUESTS_SUCCEED("requests.succeed.total", "Succeed %s Requests"),
|
||||
GENERIC_METRIC_REQUESTS_FAILED("requests.failed.total", "Failed %s Requests"),
|
||||
|
||||
// subscribe metrics key
|
||||
SUBSCRIBE_METRIC_NUM("dubbo.registry.subscribe.num.total", "Total Subscribe Num"),
|
||||
SUBSCRIBE_METRIC_NUM_SUCCEED("dubbo.registry.subscribe.num.succeed.total", "Succeed Subscribe Num"),
|
||||
SUBSCRIBE_METRIC_NUM_FAILED("dubbo.registry.subscribe.num.failed.total", "Failed Subscribe Num"),
|
||||
SUBSCRIBE_METRIC_NUM("registry.subscribe.num.total", "Total Subscribe Num"),
|
||||
SUBSCRIBE_METRIC_NUM_SUCCEED("registry.subscribe.num.succeed.total", "Succeed Subscribe Num"),
|
||||
SUBSCRIBE_METRIC_NUM_FAILED("registry.subscribe.num.failed.total", "Failed Subscribe Num"),
|
||||
|
||||
// directory metrics key
|
||||
DIRECTORY_METRIC_NUM_ALL("dubbo.registry.directory.num.all", "All Directory Urls"),
|
||||
DIRECTORY_METRIC_NUM_VALID("dubbo.registry.directory.num.valid.total", "Valid Directory Urls"),
|
||||
DIRECTORY_METRIC_NUM_TO_RECONNECT("dubbo.registry.directory.num.to_reconnect.total", "ToReconnect Directory Urls"),
|
||||
DIRECTORY_METRIC_NUM_DISABLE("dubbo.registry.directory.num.disable.total", "Disable Directory Urls"),
|
||||
DIRECTORY_METRIC_NUM_ALL("registry.directory.num.all", "All Directory Urls"),
|
||||
DIRECTORY_METRIC_NUM_VALID("registry.directory.num.valid.total", "Valid Directory Urls"),
|
||||
DIRECTORY_METRIC_NUM_TO_RECONNECT("registry.directory.num.to_reconnect.total", "ToReconnect Directory Urls"),
|
||||
DIRECTORY_METRIC_NUM_DISABLE("registry.directory.num.disable.total", "Disable Directory Urls"),
|
||||
|
||||
NOTIFY_METRIC_REQUESTS("dubbo.registry.notify.requests.total", "Total Notify Requests"),
|
||||
NOTIFY_METRIC_NUM_LAST("dubbo.registry.notify.num.last", "Last Notify Nums"),
|
||||
NOTIFY_METRIC_REQUESTS("registry.notify.requests.total", "Total Notify Requests"),
|
||||
NOTIFY_METRIC_NUM_LAST("registry.notify.num.last", "Last Notify Nums"),
|
||||
|
||||
THREAD_POOL_CORE_SIZE("dubbo.thread.pool.core.size", "Thread Pool Core Size"),
|
||||
THREAD_POOL_LARGEST_SIZE("dubbo.thread.pool.largest.size", "Thread Pool Largest Size"),
|
||||
THREAD_POOL_MAX_SIZE("dubbo.thread.pool.max.size", "Thread Pool Max Size"),
|
||||
THREAD_POOL_ACTIVE_SIZE("dubbo.thread.pool.active.size", "Thread Pool Active Size"),
|
||||
THREAD_POOL_THREAD_COUNT("dubbo.thread.pool.thread.count", "Thread Pool Thread Count"),
|
||||
THREAD_POOL_QUEUE_SIZE("dubbo.thread.pool.queue.size", "Thread Pool Queue Size"),
|
||||
THREAD_POOL_THREAD_REJECT_COUNT("dubbo.thread.pool.reject.thread.count", "Thread Pool Reject Thread Count"),
|
||||
THREAD_POOL_CORE_SIZE("thread.pool.core.size", "Thread Pool Core Size"),
|
||||
THREAD_POOL_LARGEST_SIZE("thread.pool.largest.size", "Thread Pool Largest Size"),
|
||||
THREAD_POOL_MAX_SIZE("thread.pool.max.size", "Thread Pool Max Size"),
|
||||
THREAD_POOL_ACTIVE_SIZE("thread.pool.active.size", "Thread Pool Active Size"),
|
||||
THREAD_POOL_THREAD_COUNT("thread.pool.thread.count", "Thread Pool Thread Count"),
|
||||
THREAD_POOL_QUEUE_SIZE("thread.pool.queue.size", "Thread Pool Queue Size"),
|
||||
THREAD_POOL_THREAD_REJECT_COUNT("thread.pool.reject.thread.count", "Thread Pool Reject Thread Count"),
|
||||
|
||||
// metadata push metrics key
|
||||
METADATA_PUSH_METRIC_NUM("dubbo.metadata.push.num.total", "Total Push Num"),
|
||||
METADATA_PUSH_METRIC_NUM_SUCCEED("dubbo.metadata.push.num.succeed.total", "Succeed Push Num"),
|
||||
METADATA_PUSH_METRIC_NUM_FAILED("dubbo.metadata.push.num.failed.total", "Failed Push Num"),
|
||||
METADATA_PUSH_METRIC_NUM("metadata.push.num.total", "Total Push Num"),
|
||||
METADATA_PUSH_METRIC_NUM_SUCCEED("metadata.push.num.succeed.total", "Succeed Push Num"),
|
||||
METADATA_PUSH_METRIC_NUM_FAILED("metadata.push.num.failed.total", "Failed Push Num"),
|
||||
|
||||
// metadata subscribe metrics key
|
||||
METADATA_SUBSCRIBE_METRIC_NUM("dubbo.metadata.subscribe.num.total", "Total Metadata Subscribe Num"),
|
||||
METADATA_SUBSCRIBE_METRIC_NUM_SUCCEED("dubbo.metadata.subscribe.num.succeed.total", "Succeed Metadata Subscribe Num"),
|
||||
METADATA_SUBSCRIBE_METRIC_NUM_FAILED("dubbo.metadata.subscribe.num.failed.total", "Failed Metadata Subscribe Num"),
|
||||
METADATA_SUBSCRIBE_METRIC_NUM("metadata.subscribe.num.total", "Total Metadata Subscribe Num"),
|
||||
METADATA_SUBSCRIBE_METRIC_NUM_SUCCEED("metadata.subscribe.num.succeed.total", "Succeed Metadata Subscribe Num"),
|
||||
METADATA_SUBSCRIBE_METRIC_NUM_FAILED("metadata.subscribe.num.failed.total", "Failed Metadata Subscribe Num"),
|
||||
|
||||
// register service metrics key
|
||||
SERVICE_REGISTER_METRIC_REQUESTS("dubbo.registry.register.service.total", "Total Service-Level Register Requests"),
|
||||
SERVICE_REGISTER_METRIC_REQUESTS_SUCCEED("dubbo.registry.register.service.succeed.total", "Succeed Service-Level Register Requests"),
|
||||
SERVICE_REGISTER_METRIC_REQUESTS_FAILED("dubbo.registry.register.service.failed.total", "Failed Service-Level Register Requests"),
|
||||
SERVICE_REGISTER_METRIC_REQUESTS("registry.total", "Total Service-Level Register Requests"),
|
||||
SERVICE_REGISTER_METRIC_REQUESTS_SUCCEED("registry.succeed.total", "Succeed Service-Level Register Requests"),
|
||||
SERVICE_REGISTER_METRIC_REQUESTS_FAILED("registry.failed.total", "Failed Service-Level Register Requests"),
|
||||
|
||||
// subscribe metrics key
|
||||
SERVICE_SUBSCRIBE_METRIC_NUM("dubbo.registry.subscribe.service.num.total", "Total Service-Level Subscribe Num"),
|
||||
SERVICE_SUBSCRIBE_METRIC_NUM_SUCCEED("dubbo.registry.subscribe.service.num.succeed.total", "Succeed Service-Level Num"),
|
||||
SERVICE_SUBSCRIBE_METRIC_NUM_FAILED("dubbo.registry.subscribe.service.num.failed.total", "Failed Service-Level Num"),
|
||||
SERVICE_SUBSCRIBE_METRIC_NUM("registry.subscribe.service.num.total", "Total Service-Level Subscribe Num"),
|
||||
SERVICE_SUBSCRIBE_METRIC_NUM_SUCCEED("registry.subscribe.service.num.succeed.total", "Succeed Service-Level Num"),
|
||||
SERVICE_SUBSCRIBE_METRIC_NUM_FAILED("registry.subscribe.service.num.failed.total", "Failed Service-Level Num"),
|
||||
// store provider metadata service key
|
||||
STORE_PROVIDER_METADATA("dubbo.metadata.store.provider.total", "Store Provider Metadata"),
|
||||
STORE_PROVIDER_METADATA("metadata.store.provider.total", "Store Provider Metadata"),
|
||||
|
||||
STORE_PROVIDER_METADATA_SUCCEED("dubbo.metadata.store.provider.succeed.total", "Succeed Store Provider Metadata"),
|
||||
STORE_PROVIDER_METADATA_SUCCEED("metadata.store.provider.succeed.total", "Succeed Store Provider Metadata"),
|
||||
|
||||
STORE_PROVIDER_METADATA_FAILED("dubbo.metadata.store.provider.failed.total", "Failed Store Provider Metadata"),
|
||||
STORE_PROVIDER_METADATA_FAILED("metadata.store.provider.failed.total", "Failed Store Provider Metadata"),
|
||||
METADATA_GIT_COMMITID_METRIC("git.commit.id", "Git Commit Id Metrics"),
|
||||
|
||||
// consumer metrics key
|
||||
INVOKER_NO_AVAILABLE_COUNT("dubbo.consumer.invoker.no.available.count", "Request Throw No Invoker Available Exception Count"),
|
||||
INVOKER_NO_AVAILABLE_COUNT("consumer.invoker.no.available.count", "Request Throw No Invoker Available Exception Count"),
|
||||
|
||||
// count the number of occurrences of each error code
|
||||
ERROR_CODE_COUNT("dubbo.error.code.count","The Count Of Occurrences for Each Error Code"),
|
||||
|
||||
// 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;
|
||||
private String nameSuffix;
|
||||
private String description;
|
||||
|
||||
public final String getName() {
|
||||
return this.name;
|
||||
return "dubbo." + nameSuffix;
|
||||
}
|
||||
|
||||
public final String getNameByType(String type) {
|
||||
return String.format(name, type);
|
||||
return "dubbo." + type + "." + nameSuffix;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
MetricsKey(String name, String description) {
|
||||
this.name = name;
|
||||
|
||||
MetricsKey(String nameSuffix, String description) {
|
||||
this.nameSuffix = nameSuffix;
|
||||
this.description = description;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -18,11 +18,8 @@
|
|||
package org.apache.dubbo.metrics.model.key;
|
||||
|
||||
import io.micrometer.common.lang.Nullable;
|
||||
import org.apache.dubbo.metrics.model.MetricsSupport;
|
||||
import org.apache.dubbo.metrics.model.sample.MetricSample;
|
||||
import org.apache.dubbo.rpc.model.ApplicationModel;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
|
|
@ -88,7 +85,7 @@ public class MetricsKeyWrapper {
|
|||
return metricsKey.getName();
|
||||
}
|
||||
try {
|
||||
return String.format(metricsKey.getName(), getType());
|
||||
return metricsKey.getNameByType(getType());
|
||||
} catch (Exception ignore) {
|
||||
return metricsKey.getName();
|
||||
}
|
||||
|
|
@ -105,19 +102,6 @@ public class MetricsKeyWrapper {
|
|||
}
|
||||
}
|
||||
|
||||
public Map<String, String> tagName(ApplicationModel applicationModel, String key) {
|
||||
MetricsLevel level = getLevel();
|
||||
switch (level) {
|
||||
case APP:
|
||||
return MetricsSupport.applicationTags(applicationModel);
|
||||
case SERVICE:
|
||||
return MetricsSupport.serviceTags(applicationModel, key);
|
||||
case METHOD:
|
||||
return MetricsSupport.methodTags(applicationModel, key);
|
||||
}
|
||||
return MetricsSupport.applicationTags(applicationModel);
|
||||
}
|
||||
|
||||
public static MetricsKeyWrapper wrapper(MetricsKey metricsKey) {
|
||||
return new MetricsKeyWrapper(metricsKey, null);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -18,5 +18,5 @@
|
|||
package org.apache.dubbo.metrics.model.key;
|
||||
|
||||
public enum MetricsLevel {
|
||||
APP, SERVICE, METHOD, CONFIG
|
||||
APP, SERVICE, METHOD, CONFIG, REGISTRY
|
||||
}
|
||||
|
|
|
|||
|
|
@ -18,6 +18,7 @@
|
|||
package org.apache.dubbo.metrics.aggregate;
|
||||
|
||||
import org.junit.jupiter.api.Assertions;
|
||||
import org.junit.jupiter.api.RepeatedTest;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.util.concurrent.ExecutorService;
|
||||
|
|
@ -37,6 +38,7 @@ class TimeWindowQuantileTest {
|
|||
}
|
||||
|
||||
@Test
|
||||
@RepeatedTest(100)
|
||||
void testMulti() {
|
||||
|
||||
ExecutorService executorService = Executors.newFixedThreadPool(200);
|
||||
|
|
@ -51,12 +53,14 @@ class TimeWindowQuantileTest {
|
|||
quantile.add(finalI));
|
||||
}
|
||||
index++;
|
||||
try {
|
||||
Thread.sleep(100);
|
||||
} catch (InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
// try {
|
||||
// Thread.sleep(1);
|
||||
// } catch (InterruptedException e) {
|
||||
// e.printStackTrace();
|
||||
// }
|
||||
}
|
||||
|
||||
executorService.shutdown();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -20,16 +20,16 @@ package org.apache.dubbo.metrics.collector;
|
|||
import org.apache.dubbo.common.constants.CommonConstants;
|
||||
import org.apache.dubbo.common.extension.Activate;
|
||||
import org.apache.dubbo.metrics.DefaultConstants;
|
||||
import org.apache.dubbo.metrics.collector.sample.MetricsCountSampleConfigurer;
|
||||
import org.apache.dubbo.metrics.collector.sample.ErrorCodeSampler;
|
||||
import org.apache.dubbo.metrics.collector.sample.MetricsSampler;
|
||||
import org.apache.dubbo.metrics.collector.sample.SimpleMetricsCountSampler;
|
||||
import org.apache.dubbo.metrics.collector.sample.ThreadPoolMetricsSampler;
|
||||
import org.apache.dubbo.metrics.collector.sample.MetricsCountSampleConfigurer;
|
||||
import org.apache.dubbo.metrics.data.BaseStatComposite;
|
||||
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;
|
||||
|
|
@ -54,9 +54,15 @@ public class DefaultMetricsCollector extends CombMetricsCollector<RequestEvent>
|
|||
private boolean collectEnabled = false;
|
||||
|
||||
private volatile boolean threadpoolCollectEnabled = false;
|
||||
|
||||
private final ThreadPoolMetricsSampler threadPoolSampler = new ThreadPoolMetricsSampler(this);
|
||||
|
||||
private final ErrorCodeSampler errorCodeSampler;
|
||||
|
||||
private String applicationName;
|
||||
|
||||
private final ApplicationModel applicationModel;
|
||||
|
||||
private final List<MetricsSampler> samplers = new ArrayList<>();
|
||||
|
||||
public DefaultMetricsCollector(ApplicationModel applicationModel) {
|
||||
|
|
@ -75,8 +81,9 @@ public class DefaultMetricsCollector extends CombMetricsCollector<RequestEvent>
|
|||
}
|
||||
});
|
||||
super.setEventMulticaster(new DefaultSubDispatcher(this));
|
||||
samplers.add(applicationSampler);
|
||||
samplers.add(threadPoolSampler);
|
||||
this.samplers.add(applicationSampler);
|
||||
this.samplers.add(threadPoolSampler);
|
||||
this.errorCodeSampler = new ErrorCodeSampler(this);
|
||||
this.applicationModel = applicationModel;
|
||||
}
|
||||
|
||||
|
|
@ -100,6 +107,7 @@ public class DefaultMetricsCollector extends CombMetricsCollector<RequestEvent>
|
|||
this.collectEnabled = collectEnabled;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isCollectEnabled() {
|
||||
return collectEnabled;
|
||||
}
|
||||
|
|
@ -138,7 +146,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>() {
|
||||
|
|
|
|||
|
|
@ -0,0 +1,41 @@
|
|||
/*
|
||||
* 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.collector.sample;
|
||||
|
||||
import org.apache.dubbo.common.logger.LogListener;
|
||||
import org.apache.dubbo.common.logger.support.FailsafeErrorTypeAwareLogger;
|
||||
import org.apache.dubbo.metrics.model.key.MetricsKey;
|
||||
|
||||
/**
|
||||
* Listen the log of all {@link FailsafeErrorTypeAwareLogger} instances, and add error code count to {@link ErrorCodeSampler}.
|
||||
*/
|
||||
public class ErrorCodeMetricsListenRegister implements LogListener {
|
||||
|
||||
private final ErrorCodeSampler errorCodeSampler;
|
||||
|
||||
public ErrorCodeMetricsListenRegister(ErrorCodeSampler errorCodeSampler){
|
||||
FailsafeErrorTypeAwareLogger.registerGlobalListen(this);
|
||||
this.errorCodeSampler = errorCodeSampler;
|
||||
this.errorCodeSampler.addMetricName(MetricsKey.ERROR_CODE_COUNT.getName());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onMessage(String code, String msg) {
|
||||
errorCodeSampler.inc(code, MetricsKey.ERROR_CODE_COUNT.getName());
|
||||
}
|
||||
}
|
||||
|
|
@ -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.dubbo.metrics.collector.sample;
|
||||
|
||||
import org.apache.dubbo.metrics.collector.DefaultMetricsCollector;
|
||||
import org.apache.dubbo.metrics.model.ErrorCodeMetric;
|
||||
import org.apache.dubbo.metrics.model.MetricsCategory;
|
||||
import org.apache.dubbo.metrics.model.key.MetricsKey;
|
||||
import org.apache.dubbo.metrics.model.sample.CounterMetricSample;
|
||||
import org.apache.dubbo.metrics.model.sample.MetricSample;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.atomic.AtomicLong;
|
||||
|
||||
/**
|
||||
* This sampler is used to count the number of occurrences of each error code.
|
||||
*/
|
||||
public class ErrorCodeSampler extends MetricsNameCountSampler<String, String, ErrorCodeMetric> {
|
||||
|
||||
private final ErrorCodeMetricsListenRegister register;
|
||||
|
||||
/**
|
||||
* Map<ErrorCode,Metric>
|
||||
*/
|
||||
private final Map<String, ErrorCodeMetric> errorCodeMetrics;
|
||||
|
||||
public ErrorCodeSampler(DefaultMetricsCollector collector) {
|
||||
super(collector, MetricsCategory.ERROR_CODE, MetricsKey.ERROR_CODE_COUNT);
|
||||
this.register = new ErrorCodeMetricsListenRegister(this);
|
||||
this.errorCodeMetrics = new ConcurrentHashMap<>();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected MetricSample provideMetricsSample(ErrorCodeMetric metric, AtomicLong count, MetricsKey metricsKey, MetricsCategory metricsCategory) {
|
||||
return new CounterMetricSample<>(
|
||||
metricsKey.getNameByType(metric.getErrorCode()),
|
||||
metricsKey.getDescription(),
|
||||
metric.getTags(),
|
||||
metricsCategory,
|
||||
count
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void countConfigure(MetricsCountSampleConfigurer<String, String, ErrorCodeMetric> sampleConfigure) {
|
||||
sampleConfigure.configureMetrics(configure -> {
|
||||
|
||||
String errorCode = configure.getSource();
|
||||
ErrorCodeMetric metric = errorCodeMetrics.get(errorCode);
|
||||
|
||||
if (metric == null) {
|
||||
metric = new ErrorCodeMetric(collector.getApplicationModel().getApplicationName(), errorCode);
|
||||
errorCodeMetrics.put(errorCode, metric);
|
||||
}
|
||||
return metric;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,69 @@
|
|||
/*
|
||||
* 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.collector.sample;
|
||||
|
||||
import org.apache.dubbo.common.utils.ConcurrentHashSet;
|
||||
import org.apache.dubbo.metrics.collector.DefaultMetricsCollector;
|
||||
import org.apache.dubbo.metrics.model.Metric;
|
||||
import org.apache.dubbo.metrics.model.MetricsCategory;
|
||||
import org.apache.dubbo.metrics.model.key.MetricsKey;
|
||||
import org.apache.dubbo.metrics.model.sample.MetricSample;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.atomic.AtomicLong;
|
||||
|
||||
public abstract class MetricsNameCountSampler<S, K, M extends Metric> extends SimpleMetricsCountSampler<S, K, M> {
|
||||
|
||||
protected final DefaultMetricsCollector collector;
|
||||
|
||||
protected final Set<K> metricNames = new ConcurrentHashSet<>();
|
||||
|
||||
protected final MetricsCategory metricsCategory;
|
||||
|
||||
protected final MetricsKey metricsKey;
|
||||
|
||||
public MetricsNameCountSampler(DefaultMetricsCollector collector,MetricsCategory metricsCategory,MetricsKey metricsKey) {
|
||||
this.metricsCategory = metricsCategory;
|
||||
this.metricsKey = metricsKey;
|
||||
this.collector = collector;
|
||||
this.collector.addSampler(this);
|
||||
}
|
||||
|
||||
public void addMetricName(K name) {
|
||||
this.metricNames.add(name);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<MetricSample> sample() {
|
||||
List<MetricSample> metricSamples = new ArrayList<>();
|
||||
metricNames.forEach(name -> collect(metricSamples, name));
|
||||
return metricSamples;
|
||||
}
|
||||
|
||||
private void collect(List<MetricSample> samples, K metricName) {
|
||||
getCount(metricName)
|
||||
.filter(e -> !e.isEmpty())
|
||||
.ifPresent(map -> map.forEach((k, v) ->
|
||||
samples.add(provideMetricsSample(k,v,metricsKey,metricsCategory))));
|
||||
}
|
||||
|
||||
protected abstract MetricSample provideMetricsSample(M metric,AtomicLong count,MetricsKey metricsKey,MetricsCategory metricsCategory);
|
||||
|
||||
}
|
||||
|
|
@ -36,6 +36,7 @@ public abstract class SimpleMetricsCountSampler<S, K, M extends Metric>
|
|||
implements MetricsCountSampler<S, K, M> {
|
||||
|
||||
private final ConcurrentMap<M, AtomicLong> EMPTY_COUNT = new ConcurrentHashMap<>();
|
||||
|
||||
private final Map<K, ConcurrentMap<M, AtomicLong>> metricCounter = new ConcurrentHashMap<>();
|
||||
|
||||
@Override
|
||||
|
|
|
|||
|
|
@ -16,65 +16,33 @@
|
|||
*/
|
||||
|
||||
package org.apache.dubbo.metrics.collector.sample;
|
||||
import org.apache.dubbo.common.utils.ConcurrentHashSet;
|
||||
|
||||
import org.apache.dubbo.metrics.collector.DefaultMetricsCollector;
|
||||
import org.apache.dubbo.metrics.model.Metric;
|
||||
import org.apache.dubbo.metrics.model.MetricsCategory;
|
||||
import org.apache.dubbo.metrics.model.key.MetricsKey;
|
||||
import org.apache.dubbo.metrics.model.ThreadPoolRejectMetric;
|
||||
import org.apache.dubbo.metrics.model.key.MetricsKey;
|
||||
import org.apache.dubbo.metrics.model.sample.GaugeMetricSample;
|
||||
import org.apache.dubbo.metrics.model.sample.MetricSample;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import java.util.concurrent.atomic.AtomicLong;
|
||||
import java.util.function.ToDoubleFunction;
|
||||
|
||||
import static org.apache.dubbo.metrics.model.MetricsCategory.THREAD_POOL;
|
||||
|
||||
public class ThreadRejectMetricsCountSampler extends SimpleMetricsCountSampler<String, String, ThreadPoolRejectMetric> {
|
||||
public class ThreadRejectMetricsCountSampler extends MetricsNameCountSampler<String, String, ThreadPoolRejectMetric> {
|
||||
|
||||
private final DefaultMetricsCollector collector;
|
||||
|
||||
private final Set<String> metricNames = new ConcurrentHashSet<>();
|
||||
public ThreadRejectMetricsCountSampler(DefaultMetricsCollector collector) {
|
||||
this.collector = collector;
|
||||
this.collector.addSampler(this);
|
||||
}
|
||||
|
||||
public void addMetricName(String name){
|
||||
this.metricNames.add(name);
|
||||
super(collector, THREAD_POOL,MetricsKey.THREAD_POOL_THREAD_REJECT_COUNT);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<MetricSample> sample() {
|
||||
List<MetricSample> metricSamples = new ArrayList<>();
|
||||
metricNames.stream().forEach(name->collect(metricSamples,name));
|
||||
return metricSamples;
|
||||
}
|
||||
|
||||
|
||||
private void collect(List<MetricSample> list, String metricName) {
|
||||
count(list, metricName, MetricsKey.THREAD_POOL_THREAD_REJECT_COUNT);
|
||||
}
|
||||
|
||||
private <T extends Metric> void count(List<MetricSample> list, String metricName, MetricsKey metricsKey) {
|
||||
getCount(metricName).filter(e -> !e.isEmpty())
|
||||
.ifPresent(map -> map.forEach((k, v) ->
|
||||
list.add(getGaugeMetricSample(metricsKey, k, THREAD_POOL, v, AtomicLong::get))));
|
||||
}
|
||||
|
||||
private <T> GaugeMetricSample<T> getGaugeMetricSample(MetricsKey metricsKey,
|
||||
ThreadPoolRejectMetric methodMetric,
|
||||
MetricsCategory metricsCategory,
|
||||
T value,
|
||||
ToDoubleFunction<T> apply) {
|
||||
protected MetricSample provideMetricsSample(ThreadPoolRejectMetric metric, AtomicLong count, MetricsKey metricsKey, MetricsCategory metricsCategory) {
|
||||
return new GaugeMetricSample<>(
|
||||
metricsKey.getNameByType(methodMetric.getThreadPoolName()),
|
||||
metricsKey.getNameByType(metric.getThreadPoolName()),
|
||||
metricsKey.getDescription(),
|
||||
methodMetric.getTags(),
|
||||
metric.getTags(),
|
||||
metricsCategory,
|
||||
value,
|
||||
apply);
|
||||
count,
|
||||
AtomicLong::get);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
});
|
||||
|
|
@ -97,6 +96,7 @@ public final class DefaultSubDispatcher extends SimpleMetricsEventMulticaster {
|
|||
MetricsSupport.incrAndAddRt(targetKey, dynamicPlaceType, (MethodMetricsCollector) collector, event);
|
||||
}
|
||||
)));
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -21,7 +21,6 @@ import io.micrometer.core.instrument.FunctionCounter;
|
|||
import io.micrometer.core.instrument.binder.MeterBinder;
|
||||
import org.apache.dubbo.common.URL;
|
||||
import org.apache.dubbo.common.beans.factory.ScopeBeanFactory;
|
||||
import org.apache.dubbo.common.constants.MetricsConstants;
|
||||
import org.apache.dubbo.common.lang.ShutdownHookCallbacks;
|
||||
import org.apache.dubbo.common.logger.ErrorTypeAwareLogger;
|
||||
import org.apache.dubbo.common.logger.LoggerFactory;
|
||||
|
|
@ -38,7 +37,6 @@ import org.apache.dubbo.rpc.model.ApplicationModel;
|
|||
import io.micrometer.core.instrument.Gauge;
|
||||
import io.micrometer.core.instrument.MeterRegistry;
|
||||
import io.micrometer.core.instrument.Tag;
|
||||
import io.micrometer.core.instrument.Tags;
|
||||
import io.micrometer.core.instrument.binder.jvm.ClassLoaderMetrics;
|
||||
import io.micrometer.core.instrument.binder.jvm.JvmGcMetrics;
|
||||
import io.micrometer.core.instrument.binder.jvm.JvmMemoryMetrics;
|
||||
|
|
@ -49,7 +47,6 @@ import io.micrometer.core.instrument.composite.CompositeMeterRegistry;
|
|||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.ScheduledExecutorService;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
|
@ -112,21 +109,19 @@ public abstract class AbstractMetricsReporter implements MetricsReporter {
|
|||
private void addJvmMetrics() {
|
||||
boolean enableJvmMetrics = url.getParameter(ENABLE_JVM_METRICS_KEY, false);
|
||||
if (enableJvmMetrics) {
|
||||
Tags extraTags = Tags.of(MetricsConstants.TAG_APPLICATION_NAME,
|
||||
Optional.ofNullable(applicationModel.getApplicationName()).orElse(""));
|
||||
new ClassLoaderMetrics(extraTags).bindTo(compositeRegistry);
|
||||
new JvmMemoryMetrics(extraTags).bindTo(compositeRegistry);
|
||||
new ClassLoaderMetrics().bindTo(compositeRegistry);
|
||||
new JvmMemoryMetrics().bindTo(compositeRegistry);
|
||||
|
||||
@SuppressWarnings("java:S2095")
|
||||
// Do not change JvmGcMetrics to try-with-resources as the JvmGcMetrics will not be available after (auto-)closing.
|
||||
// See https://github.com/micrometer-metrics/micrometer/issues/1492
|
||||
JvmGcMetrics jvmGcMetrics = new JvmGcMetrics(extraTags);
|
||||
JvmGcMetrics jvmGcMetrics = new JvmGcMetrics();
|
||||
jvmGcMetrics.bindTo(compositeRegistry);
|
||||
Runtime.getRuntime().addShutdownHook(new Thread(jvmGcMetrics::close));
|
||||
|
||||
bindTo(new ProcessorMetrics(extraTags));
|
||||
new JvmThreadMetrics(extraTags).bindTo(compositeRegistry);
|
||||
bindTo(new UptimeMetrics(extraTags));
|
||||
bindTo(new ProcessorMetrics());
|
||||
new JvmThreadMetrics().bindTo(compositeRegistry);
|
||||
bindTo(new UptimeMetrics());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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.dubbo.metrics.metrics.model.sample;
|
||||
|
||||
import org.apache.dubbo.common.utils.Assert;
|
||||
import org.apache.dubbo.common.utils.ReflectionUtils;
|
||||
import org.apache.dubbo.config.ApplicationConfig;
|
||||
import org.apache.dubbo.metrics.collector.DefaultMetricsCollector;
|
||||
import org.apache.dubbo.metrics.collector.sample.ErrorCodeMetricsListenRegister;
|
||||
import org.apache.dubbo.metrics.collector.sample.ErrorCodeSampler;
|
||||
import org.apache.dubbo.metrics.model.sample.CounterMetricSample;
|
||||
import org.apache.dubbo.metrics.model.sample.MetricSample;
|
||||
import org.apache.dubbo.rpc.model.ApplicationModel;
|
||||
import org.apache.dubbo.rpc.model.FrameworkModel;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.concurrent.atomic.AtomicLong;
|
||||
|
||||
public class ErrorCodeSampleTest {
|
||||
|
||||
@Test
|
||||
void testErrorCodeMetric() {
|
||||
FrameworkModel frameworkModel = FrameworkModel.defaultModel();
|
||||
ApplicationModel applicationModel = frameworkModel.newApplication();
|
||||
|
||||
ApplicationConfig applicationConfig = new ApplicationConfig();
|
||||
applicationConfig.setName("MyApplication1");
|
||||
|
||||
applicationModel.getApplicationConfigManager().setApplication(applicationConfig);
|
||||
|
||||
DefaultMetricsCollector defaultMetricsCollector = new DefaultMetricsCollector(applicationModel);
|
||||
defaultMetricsCollector.setCollectEnabled(true);
|
||||
|
||||
ErrorCodeSampler sampler = (ErrorCodeSampler) ReflectionUtils.getField(defaultMetricsCollector, "errorCodeSampler");
|
||||
|
||||
ErrorCodeMetricsListenRegister register = (ErrorCodeMetricsListenRegister) ReflectionUtils.getField(sampler, "register");
|
||||
|
||||
register.onMessage("0-1", null);
|
||||
register.onMessage("0-1", null);
|
||||
register.onMessage("0-2", null);
|
||||
register.onMessage("0-2", null);
|
||||
register.onMessage("1-2", null);
|
||||
register.onMessage("1-2", null);
|
||||
register.onMessage("1-3", null);
|
||||
register.onMessage("1-3", null);
|
||||
|
||||
List<MetricSample> samples = defaultMetricsCollector.collect();
|
||||
|
||||
Assert.assertTrue(samples.size() == 4,"Wrong number of samples.");
|
||||
samples.forEach(metricSample -> Assert.assertTrue(((AtomicLong)((CounterMetricSample<?>)metricSample).getValue()).get() == 2L,"Sample count error."));
|
||||
|
||||
System.out.println(samples);
|
||||
}
|
||||
}
|
||||
|
|
@ -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>
|
||||
|
|
@ -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);
|
||||
|
||||
}
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -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);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
@ -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);
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1 @@
|
|||
org.apache.dubbo.metrics.registry.collector.NettyMetricsCollector
|
||||
|
|
@ -80,7 +80,7 @@ class PrometheusMetricsReporterTest {
|
|||
Double d2 = prometheusRegistry.getPrometheusRegistry().getSampleValue("jvm_gc_memory_promoted_bytes_total",
|
||||
new String[]{"application_name"}, new String[]{name});
|
||||
Assertions.assertNull(d1);
|
||||
Assertions.assertNotNull(d2);
|
||||
Assertions.assertNull(d2);
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
|
|||
|
|
@ -23,6 +23,7 @@ import org.apache.dubbo.metrics.model.key.MetricsLevel;
|
|||
import org.apache.dubbo.metrics.model.key.MetricsPlaceValue;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import static org.apache.dubbo.metrics.model.key.MetricsKey.DIRECTORY_METRIC_NUM_ALL;
|
||||
|
|
@ -46,17 +47,23 @@ import static org.apache.dubbo.metrics.model.key.MetricsKey.SUBSCRIBE_METRIC_NUM
|
|||
|
||||
public interface RegistryMetricsConstants {
|
||||
|
||||
String ATTACHMENT_REGISTRY_KEY = "registryKey";
|
||||
String ATTACHMENT_REGISTRY_SINGLE_KEY = "registrySingleKey";
|
||||
|
||||
MetricsPlaceValue OP_TYPE_REGISTER = MetricsPlaceValue.of("register", MetricsLevel.APP);
|
||||
MetricsPlaceValue OP_TYPE_SUBSCRIBE = MetricsPlaceValue.of("subscribe", MetricsLevel.APP);
|
||||
MetricsPlaceValue OP_TYPE_NOTIFY = MetricsPlaceValue.of("notify", MetricsLevel.APP);
|
||||
MetricsPlaceValue OP_TYPE_DIRECTORY = MetricsPlaceValue.of("directory", MetricsLevel.APP);
|
||||
MetricsPlaceValue OP_TYPE_REGISTER_SERVICE = MetricsPlaceValue.of("register.service", MetricsLevel.SERVICE);
|
||||
MetricsPlaceValue OP_TYPE_REGISTER_SERVICE = MetricsPlaceValue.of("register.service", MetricsLevel.REGISTRY);
|
||||
MetricsPlaceValue OP_TYPE_SUBSCRIBE_SERVICE = MetricsPlaceValue.of("subscribe.service", MetricsLevel.SERVICE);
|
||||
|
||||
// App-level
|
||||
List<MetricsKey> APP_LEVEL_KEYS = Arrays.asList(REGISTER_METRIC_REQUESTS, REGISTER_METRIC_REQUESTS_SUCCEED, REGISTER_METRIC_REQUESTS_FAILED,
|
||||
SUBSCRIBE_METRIC_NUM, SUBSCRIBE_METRIC_NUM_SUCCEED, SUBSCRIBE_METRIC_NUM_FAILED,
|
||||
NOTIFY_METRIC_REQUESTS);
|
||||
List<MetricsKey> APP_LEVEL_KEYS = Collections.singletonList(NOTIFY_METRIC_REQUESTS);
|
||||
|
||||
// Registry-level
|
||||
List<MetricsKey> REGISTER_LEVEL_KEYS = Arrays.asList(REGISTER_METRIC_REQUESTS, REGISTER_METRIC_REQUESTS_SUCCEED, REGISTER_METRIC_REQUESTS_FAILED,
|
||||
SUBSCRIBE_METRIC_NUM, SUBSCRIBE_METRIC_NUM_SUCCEED, SUBSCRIBE_METRIC_NUM_FAILED
|
||||
);
|
||||
|
||||
// Service-level
|
||||
List<MetricsKeyWrapper> SERVICE_LEVEL_KEYS = Arrays.asList(
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@
|
|||
|
||||
package org.apache.dubbo.metrics.registry.collector;
|
||||
|
||||
import org.apache.dubbo.common.constants.RegistryConstants;
|
||||
import org.apache.dubbo.common.extension.Activate;
|
||||
import org.apache.dubbo.config.context.ConfigManager;
|
||||
import org.apache.dubbo.metrics.collector.CombMetricsCollector;
|
||||
|
|
@ -25,7 +26,11 @@ 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.ApplicationMetric;
|
||||
import org.apache.dubbo.metrics.model.MetricsCategory;
|
||||
import org.apache.dubbo.metrics.model.ServiceKeyMetric;
|
||||
import org.apache.dubbo.metrics.model.key.MetricsKey;
|
||||
import org.apache.dubbo.metrics.model.key.MetricsKeyWrapper;
|
||||
import org.apache.dubbo.metrics.model.sample.MetricSample;
|
||||
import org.apache.dubbo.metrics.registry.RegistryMetricsConstants;
|
||||
import org.apache.dubbo.metrics.registry.event.RegistryEvent;
|
||||
|
|
@ -33,7 +38,9 @@ import org.apache.dubbo.metrics.registry.event.RegistrySubDispatcher;
|
|||
import org.apache.dubbo.rpc.model.ApplicationModel;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
|
||||
import static org.apache.dubbo.metrics.registry.RegistryMetricsConstants.OP_TYPE_NOTIFY;
|
||||
|
|
@ -51,6 +58,7 @@ public class RegistryMetricsCollector extends CombMetricsCollector<RegistryEvent
|
|||
|
||||
private Boolean collectEnabled = null;
|
||||
private final ApplicationModel applicationModel;
|
||||
private final RegistryStatComposite internalStat;
|
||||
|
||||
public RegistryMetricsCollector(ApplicationModel applicationModel) {
|
||||
super(new BaseStatComposite(applicationModel) {
|
||||
|
|
@ -73,6 +81,7 @@ public class RegistryMetricsCollector extends CombMetricsCollector<RegistryEvent
|
|||
}
|
||||
});
|
||||
super.setEventMulticaster(new RegistrySubDispatcher(this));
|
||||
internalStat = new RegistryStatComposite(applicationModel);
|
||||
this.applicationModel = applicationModel;
|
||||
}
|
||||
|
||||
|
|
@ -99,7 +108,45 @@ public class RegistryMetricsCollector extends CombMetricsCollector<RegistryEvent
|
|||
return list;
|
||||
}
|
||||
list.addAll(super.export(MetricsCategory.REGISTRY));
|
||||
list.addAll(internalStat.export(MetricsCategory.REGISTRY));
|
||||
return list;
|
||||
}
|
||||
|
||||
public void incrMetricsNum(MetricsKey metricsKey, List<String> registryClusterNames) {
|
||||
registryClusterNames.forEach(name -> internalStat.incrMetricsNum(metricsKey, name));
|
||||
}
|
||||
|
||||
public void incrRegisterFinishNum(MetricsKey metricsKey, String registryOpType, List<String> registryClusterNames, Long responseTime) {
|
||||
registryClusterNames.forEach(name ->
|
||||
{
|
||||
ApplicationMetric applicationMetric = new ApplicationMetric(applicationModel);
|
||||
applicationMetric.setExtraInfo(Collections.singletonMap(RegistryConstants.REGISTRY_CLUSTER_KEY.toLowerCase(), name));
|
||||
internalStat.incrMetricsNum(metricsKey, name);
|
||||
getStats().getRtStatComposite().calcServiceKeyRt(registryOpType, responseTime, applicationMetric);
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
public void incrServiceRegisterNum(MetricsKeyWrapper wrapper, String serviceKey, List<String> registryClusterNames, int size) {
|
||||
registryClusterNames.forEach(name ->
|
||||
stats.incrementServiceKey(wrapper, serviceKey, Collections.singletonMap(RegistryConstants.REGISTRY_CLUSTER_KEY.toLowerCase(), name), size)
|
||||
);
|
||||
}
|
||||
|
||||
public void incrServiceRegisterFinishNum(MetricsKeyWrapper wrapper, String serviceKey, List<String> registryClusterNames, int size, Long responseTime) {
|
||||
registryClusterNames.forEach(name ->
|
||||
{
|
||||
Map<String, String> extraInfo = Collections.singletonMap(RegistryConstants.REGISTRY_CLUSTER_KEY.toLowerCase(), name);
|
||||
ServiceKeyMetric serviceKeyMetric = new ServiceKeyMetric(applicationModel, serviceKey);
|
||||
serviceKeyMetric.setExtraInfo(extraInfo);
|
||||
stats.incrementServiceKey(wrapper, serviceKey, extraInfo, size);
|
||||
getStats().getRtStatComposite().calcServiceKeyRt(wrapper.getType(), responseTime, serviceKeyMetric);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
public void setNum(MetricsKeyWrapper metricsKey, String serviceKey, int num, Map<String, String> attachments) {
|
||||
this.stats.setServiceKey(metricsKey, serviceKey, num, attachments);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,81 @@
|
|||
/*
|
||||
* 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.constants.RegistryConstants;
|
||||
import org.apache.dubbo.common.utils.CollectionUtils;
|
||||
import org.apache.dubbo.metrics.model.ApplicationMetric;
|
||||
import org.apache.dubbo.metrics.model.MetricsCategory;
|
||||
import org.apache.dubbo.metrics.model.MetricsSupport;
|
||||
import org.apache.dubbo.metrics.model.key.MetricsKey;
|
||||
import org.apache.dubbo.metrics.model.sample.GaugeMetricSample;
|
||||
import org.apache.dubbo.metrics.model.sample.MetricSample;
|
||||
import org.apache.dubbo.metrics.registry.RegistryMetricsConstants;
|
||||
import org.apache.dubbo.metrics.report.AbstractMetricsExport;
|
||||
import org.apache.dubbo.rpc.model.ApplicationModel;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.atomic.AtomicLong;
|
||||
|
||||
import static org.apache.dubbo.metrics.MetricsConstants.SELF_INCREMENT_SIZE;
|
||||
|
||||
public class RegistryStatComposite extends AbstractMetricsExport {
|
||||
|
||||
private final Map<MetricsKey, Map<ApplicationMetric, AtomicLong>> appStats = new ConcurrentHashMap<>();
|
||||
|
||||
public RegistryStatComposite(ApplicationModel applicationModel) {
|
||||
super(applicationModel);
|
||||
init(RegistryMetricsConstants.REGISTER_LEVEL_KEYS);
|
||||
}
|
||||
|
||||
public void init(List<MetricsKey> appKeys) {
|
||||
if (CollectionUtils.isEmpty(appKeys)) {
|
||||
return;
|
||||
}
|
||||
appKeys.forEach(appKey -> appStats.put(appKey, new ConcurrentHashMap<>()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<MetricSample> export(MetricsCategory category) {
|
||||
List<MetricSample> list = new ArrayList<>();
|
||||
for (MetricsKey metricsKey : appStats.keySet()) {
|
||||
Map<ApplicationMetric, AtomicLong> stringAtomicLongMap = appStats.get(metricsKey);
|
||||
for (ApplicationMetric registerKeyMetric : stringAtomicLongMap.keySet()) {
|
||||
list.add(new GaugeMetricSample<>(metricsKey, registerKeyMetric.getTags(), category, stringAtomicLongMap, value -> value.get(registerKeyMetric).get()));
|
||||
}
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
public void incrMetricsNum(MetricsKey metricsKey, String name) {
|
||||
if (!appStats.containsKey(metricsKey)) {
|
||||
return;
|
||||
}
|
||||
ApplicationMetric applicationMetric = new ApplicationMetric(getApplicationModel());
|
||||
applicationMetric.setExtraInfo(Collections.singletonMap(RegistryConstants.REGISTRY_CLUSTER_KEY.toLowerCase(), name));
|
||||
appStats.get(metricsKey).computeIfAbsent(applicationMetric, k -> new AtomicLong(0L)).getAndAdd(SELF_INCREMENT_SIZE);
|
||||
MetricsSupport.fillZero(appStats);
|
||||
}
|
||||
|
||||
public Map<MetricsKey, Map<ApplicationMetric, AtomicLong>> getAppStats() {
|
||||
return appStats;
|
||||
}
|
||||
}
|
||||
|
|
@ -22,9 +22,12 @@ import org.apache.dubbo.metrics.event.TimeCounterEvent;
|
|||
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.metrics.registry.RegistryMetricsConstants;
|
||||
import org.apache.dubbo.metrics.registry.collector.RegistryMetricsCollector;
|
||||
import org.apache.dubbo.rpc.model.ApplicationModel;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import static org.apache.dubbo.metrics.MetricsConstants.ATTACHMENT_DIRECTORY_MAP;
|
||||
|
|
@ -48,18 +51,25 @@ public class RegistryEvent extends TimeCounterEvent {
|
|||
}
|
||||
|
||||
private static final TypeWrapper REGISTER_EVENT = new TypeWrapper(MetricsLevel.APP, MetricsKey.REGISTER_METRIC_REQUESTS, MetricsKey.REGISTER_METRIC_REQUESTS_SUCCEED, MetricsKey.REGISTER_METRIC_REQUESTS_FAILED);
|
||||
public static RegistryEvent toRegisterEvent(ApplicationModel applicationModel) {
|
||||
return new RegistryEvent(applicationModel, REGISTER_EVENT);
|
||||
|
||||
public static RegistryEvent toRegisterEvent(ApplicationModel applicationModel, List<String> registryClusterNames) {
|
||||
RegistryEvent registryEvent = new RegistryEvent(applicationModel, REGISTER_EVENT);
|
||||
registryEvent.putAttachment(RegistryMetricsConstants.ATTACHMENT_REGISTRY_KEY, registryClusterNames);
|
||||
return registryEvent;
|
||||
}
|
||||
|
||||
|
||||
private static final TypeWrapper SUBSCRIBE_EVENT = new TypeWrapper(MetricsLevel.APP, MetricsKey.SUBSCRIBE_METRIC_NUM, MetricsKey.SUBSCRIBE_METRIC_NUM_SUCCEED, MetricsKey.SUBSCRIBE_METRIC_NUM_FAILED);
|
||||
public static RegistryEvent toSubscribeEvent(ApplicationModel applicationModel) {
|
||||
return new RegistryEvent(applicationModel, SUBSCRIBE_EVENT);
|
||||
|
||||
public static RegistryEvent toSubscribeEvent(ApplicationModel applicationModel, String registryClusterName) {
|
||||
RegistryEvent ddEvent = new RegistryEvent(applicationModel, SUBSCRIBE_EVENT);
|
||||
ddEvent.putAttachment(RegistryMetricsConstants.ATTACHMENT_REGISTRY_KEY, Collections.singletonList(registryClusterName));
|
||||
return ddEvent;
|
||||
}
|
||||
|
||||
|
||||
private static final TypeWrapper NOTIFY_EVENT = new TypeWrapper(MetricsLevel.APP, MetricsKey.NOTIFY_METRIC_REQUESTS, MetricsKey.NOTIFY_METRIC_NUM_LAST, (MetricsKey) null);
|
||||
|
||||
public static RegistryEvent toNotifyEvent(ApplicationModel applicationModel) {
|
||||
return new RegistryEvent(applicationModel, NOTIFY_EVENT) {
|
||||
@Override
|
||||
|
|
@ -70,24 +80,31 @@ public class RegistryEvent extends TimeCounterEvent {
|
|||
}
|
||||
|
||||
private static final TypeWrapper RS_EVENT = new TypeWrapper(MetricsLevel.SERVICE, MetricsKey.SERVICE_REGISTER_METRIC_REQUESTS, MetricsKey.SERVICE_REGISTER_METRIC_REQUESTS_SUCCEED, MetricsKey.SERVICE_REGISTER_METRIC_REQUESTS_FAILED);
|
||||
public static RegistryEvent toRsEvent(ApplicationModel applicationModel, String serviceKey, int size) {
|
||||
|
||||
public static RegistryEvent toRsEvent(ApplicationModel applicationModel, String serviceKey, int size, List<String> serviceDiscoveryNames) {
|
||||
RegistryEvent ddEvent = new RegistryEvent(applicationModel, RS_EVENT);
|
||||
ddEvent.putAttachment(ATTACHMENT_KEY_SERVICE, serviceKey);
|
||||
ddEvent.putAttachment(ATTACHMENT_KEY_SIZE, size);
|
||||
ddEvent.putAttachment(RegistryMetricsConstants.ATTACHMENT_REGISTRY_KEY, serviceDiscoveryNames);
|
||||
return ddEvent;
|
||||
}
|
||||
|
||||
private static final TypeWrapper SS_EVENT = new TypeWrapper(MetricsLevel.SERVICE, MetricsKey.SERVICE_SUBSCRIBE_METRIC_NUM, MetricsKey.SERVICE_SUBSCRIBE_METRIC_NUM_SUCCEED, MetricsKey.SERVICE_SUBSCRIBE_METRIC_NUM_FAILED);
|
||||
public static RegistryEvent toSsEvent(ApplicationModel applicationModel, String serviceKey) {
|
||||
|
||||
public static RegistryEvent toSsEvent(ApplicationModel applicationModel, String serviceKey, List<String> serviceDiscoveryNames) {
|
||||
RegistryEvent ddEvent = new RegistryEvent(applicationModel, SS_EVENT);
|
||||
ddEvent.putAttachment(ATTACHMENT_KEY_SERVICE, serviceKey);
|
||||
ddEvent.putAttachment(ATTACHMENT_KEY_SIZE, 1);
|
||||
ddEvent.putAttachment(RegistryMetricsConstants.ATTACHMENT_REGISTRY_KEY, serviceDiscoveryNames);
|
||||
return ddEvent;
|
||||
}
|
||||
|
||||
private static final TypeWrapper DIRECTORY_EVENT = new TypeWrapper(MetricsLevel.APP, MetricsKey.DIRECTORY_METRIC_NUM_VALID, null, null);
|
||||
public static RegistryEvent refreshDirectoryEvent(ApplicationModel applicationModel, Map<MetricsKey, Map<String, Integer>> summaryMap) {
|
||||
|
||||
public static RegistryEvent refreshDirectoryEvent(ApplicationModel applicationModel, Map<MetricsKey, Map<String, Integer>> summaryMap, Map<String, String> attachments) {
|
||||
RegistryEvent registryEvent = new RegistryEvent(applicationModel, DIRECTORY_EVENT);
|
||||
registryEvent.putAttachment(ATTACHMENT_DIRECTORY_MAP, summaryMap);
|
||||
registryEvent.putAttachments(attachments);
|
||||
return registryEvent;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,154 @@
|
|||
/*
|
||||
* 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.utils.CollectionUtils;
|
||||
import org.apache.dubbo.metrics.collector.CombMetricsCollector;
|
||||
import org.apache.dubbo.metrics.event.MetricsEvent;
|
||||
import org.apache.dubbo.metrics.listener.AbstractMetricsKeyListener;
|
||||
import org.apache.dubbo.metrics.listener.MetricsApplicationListener;
|
||||
import org.apache.dubbo.metrics.model.key.MetricsKey;
|
||||
import org.apache.dubbo.metrics.model.key.MetricsKeyWrapper;
|
||||
import org.apache.dubbo.metrics.model.key.MetricsPlaceValue;
|
||||
import org.apache.dubbo.metrics.registry.RegistryMetricsConstants;
|
||||
import org.apache.dubbo.metrics.registry.collector.RegistryMetricsCollector;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
|
||||
import static org.apache.dubbo.metrics.MetricsConstants.ATTACHMENT_DIRECTORY_MAP;
|
||||
import static org.apache.dubbo.metrics.MetricsConstants.ATTACHMENT_KEY_LAST_NUM_MAP;
|
||||
import static org.apache.dubbo.metrics.MetricsConstants.ATTACHMENT_KEY_SERVICE;
|
||||
import static org.apache.dubbo.metrics.MetricsConstants.ATTACHMENT_KEY_SIZE;
|
||||
import static org.apache.dubbo.metrics.registry.RegistryMetricsConstants.OP_TYPE_DIRECTORY;
|
||||
import static org.apache.dubbo.metrics.registry.RegistryMetricsConstants.OP_TYPE_NOTIFY;
|
||||
import static org.apache.dubbo.metrics.registry.RegistryMetricsConstants.OP_TYPE_REGISTER;
|
||||
|
||||
/**
|
||||
* Different from the general-purpose listener constructor {@link MetricsApplicationListener} ,
|
||||
* it provides registry custom listeners
|
||||
*/
|
||||
public class RegistrySpecListener {
|
||||
|
||||
/**
|
||||
* Perform auto-increment on the monitored key,
|
||||
* Can use a custom listener instead of this generic operation
|
||||
*/
|
||||
public static AbstractMetricsKeyListener onPost(MetricsKey metricsKey, CombMetricsCollector<?> collector) {
|
||||
return AbstractMetricsKeyListener.onEvent(metricsKey,
|
||||
event -> ((RegistryMetricsCollector) collector).incrMetricsNum(metricsKey, getRgs(event))
|
||||
);
|
||||
}
|
||||
|
||||
public static AbstractMetricsKeyListener onFinish(MetricsKey metricsKey, CombMetricsCollector<?> collector) {
|
||||
return AbstractMetricsKeyListener.onFinish(metricsKey,
|
||||
event -> ((RegistryMetricsCollector) collector).incrRegisterFinishNum(metricsKey, OP_TYPE_REGISTER.getType(), getRgs(event), event.getTimePair().calc())
|
||||
);
|
||||
}
|
||||
|
||||
public static AbstractMetricsKeyListener onError(MetricsKey metricsKey, CombMetricsCollector<?> collector) {
|
||||
return AbstractMetricsKeyListener.onError(metricsKey,
|
||||
event -> ((RegistryMetricsCollector) collector).incrRegisterFinishNum(metricsKey, OP_TYPE_REGISTER.getType(), getRgs(event), event.getTimePair().calc())
|
||||
);
|
||||
}
|
||||
|
||||
public static AbstractMetricsKeyListener onPostOfService(MetricsKey metricsKey, MetricsPlaceValue placeType, CombMetricsCollector<?> collector) {
|
||||
return AbstractMetricsKeyListener.onEvent(metricsKey,
|
||||
event -> ((RegistryMetricsCollector) collector).incrServiceRegisterNum(new MetricsKeyWrapper(metricsKey, placeType), getServiceKey(event), getRgs(event), getSize(event))
|
||||
);
|
||||
}
|
||||
|
||||
public static AbstractMetricsKeyListener onFinishOfService(MetricsKey metricsKey, MetricsPlaceValue placeType, CombMetricsCollector<?> collector) {
|
||||
return AbstractMetricsKeyListener.onFinish(metricsKey,
|
||||
event -> ((RegistryMetricsCollector) collector).incrServiceRegisterFinishNum(new MetricsKeyWrapper(metricsKey, placeType), getServiceKey(event), getRgs(event), getSize(event), event.getTimePair().calc())
|
||||
);
|
||||
}
|
||||
|
||||
public static AbstractMetricsKeyListener onErrorOfService(MetricsKey metricsKey, MetricsPlaceValue placeType, CombMetricsCollector<?> collector) {
|
||||
return AbstractMetricsKeyListener.onError(metricsKey,
|
||||
event -> ((RegistryMetricsCollector) collector).incrServiceRegisterFinishNum(new MetricsKeyWrapper(metricsKey, placeType), getServiceKey(event), getRgs(event), getSize(event), event.getTimePair().calc())
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Every time an event is triggered, multiple serviceKey related to notify are increment
|
||||
*/
|
||||
public static AbstractMetricsKeyListener onFinishOfNotify(MetricsKey metricsKey, MetricsPlaceValue placeType, CombMetricsCollector<?> collector) {
|
||||
return AbstractMetricsKeyListener.onFinish(metricsKey,
|
||||
event ->
|
||||
{
|
||||
collector.addServiceRt(event.appName(), placeType.getType(), event.getTimePair().calc());
|
||||
Map<String, Integer> lastNumMap = Collections.unmodifiableMap(event.getAttachmentValue(ATTACHMENT_KEY_LAST_NUM_MAP));
|
||||
lastNumMap.forEach(
|
||||
(k, v) -> collector.setNum(new MetricsKeyWrapper(metricsKey, OP_TYPE_NOTIFY), k, v));
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Every time an event is triggered, multiple fixed key related to directory are increment, which has nothing to do with the monitored key
|
||||
*/
|
||||
public static AbstractMetricsKeyListener onPostOfDirectory(MetricsKey metricsKey, CombMetricsCollector<?> collector) {
|
||||
return AbstractMetricsKeyListener.onEvent(metricsKey,
|
||||
event -> {
|
||||
Map<MetricsKey, Map<String, Integer>> summaryMap = event.getAttachmentValue(ATTACHMENT_DIRECTORY_MAP);
|
||||
Map<String, String> otherAttachments = new HashMap<>();
|
||||
for (Map.Entry<String, Object> entry : event.getAttachments().entrySet()) {
|
||||
if (entry.getValue() instanceof String) {
|
||||
otherAttachments.put(entry.getKey().toLowerCase(Locale.ROOT), (String) entry.getValue());
|
||||
}
|
||||
}
|
||||
summaryMap.forEach((summaryKey, map) ->
|
||||
map.forEach(
|
||||
(k, v) ->
|
||||
{
|
||||
if (CollectionUtils.isEmptyMap(otherAttachments)) {
|
||||
collector.setNum(new MetricsKeyWrapper(summaryKey, OP_TYPE_DIRECTORY), k, v);
|
||||
} else {
|
||||
((RegistryMetricsCollector) collector).setNum(new MetricsKeyWrapper(summaryKey, OP_TYPE_DIRECTORY), k, v, otherAttachments);
|
||||
}
|
||||
}
|
||||
|
||||
));
|
||||
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get the number of multiple registries
|
||||
*/
|
||||
public static List<String> getRgs(MetricsEvent event) {
|
||||
return event.getAttachmentValue(RegistryMetricsConstants.ATTACHMENT_REGISTRY_KEY);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the exposed number of the protocol
|
||||
*/
|
||||
public static int getSize(MetricsEvent event) {
|
||||
return event.getAttachmentValue(ATTACHMENT_KEY_SIZE);
|
||||
}
|
||||
|
||||
public static String getServiceKey(MetricsEvent event) {
|
||||
return event.getAttachmentValue(ATTACHMENT_KEY_SERVICE);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -18,22 +18,15 @@
|
|||
package org.apache.dubbo.metrics.registry.event;
|
||||
|
||||
import org.apache.dubbo.metrics.event.SimpleMetricsEventMulticaster;
|
||||
import org.apache.dubbo.metrics.listener.AbstractMetricsKeyListener;
|
||||
import org.apache.dubbo.metrics.listener.MetricsApplicationListener;
|
||||
import org.apache.dubbo.metrics.listener.MetricsServiceListener;
|
||||
import org.apache.dubbo.metrics.model.key.CategoryOverall;
|
||||
import org.apache.dubbo.metrics.model.key.MetricsCat;
|
||||
import org.apache.dubbo.metrics.model.key.MetricsKey;
|
||||
import org.apache.dubbo.metrics.model.key.MetricsKeyWrapper;
|
||||
import org.apache.dubbo.metrics.registry.collector.RegistryMetricsCollector;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import static org.apache.dubbo.metrics.MetricsConstants.ATTACHMENT_DIRECTORY_MAP;
|
||||
import static org.apache.dubbo.metrics.MetricsConstants.ATTACHMENT_KEY_LAST_NUM_MAP;
|
||||
import static org.apache.dubbo.metrics.registry.RegistryMetricsConstants.OP_TYPE_DIRECTORY;
|
||||
import static org.apache.dubbo.metrics.registry.RegistryMetricsConstants.OP_TYPE_NOTIFY;
|
||||
import static org.apache.dubbo.metrics.registry.RegistryMetricsConstants.OP_TYPE_REGISTER;
|
||||
|
|
@ -74,55 +67,37 @@ public final class RegistrySubDispatcher extends SimpleMetricsEventMulticaster {
|
|||
|
||||
|
||||
/**
|
||||
* {@link MetricsCat} MetricsCat collection, for better classification processing
|
||||
* Except for a few custom functions, most of them can build standard event listening functions through the static methods of MetricsApplicationListener
|
||||
* {@link MetricsCat} MetricsCat collection, for better classification processing
|
||||
* Except for a few custom functions, most of them can build standard event listening functions through the static methods of MetricsApplicationListener
|
||||
*/
|
||||
interface MCat {
|
||||
// MetricsRegisterListener
|
||||
MetricsCat APPLICATION_REGISTER_POST = new MetricsCat(MetricsKey.REGISTER_METRIC_REQUESTS, MetricsApplicationListener::onPostEventBuild);
|
||||
MetricsCat APPLICATION_REGISTER_FINISH = new MetricsCat(MetricsKey.REGISTER_METRIC_REQUESTS_SUCCEED, MetricsApplicationListener::onFinishEventBuild);
|
||||
MetricsCat APPLICATION_REGISTER_ERROR = new MetricsCat(MetricsKey.REGISTER_METRIC_REQUESTS_FAILED, MetricsApplicationListener::onErrorEventBuild);
|
||||
MetricsCat APPLICATION_REGISTER_POST = new MetricsCat(MetricsKey.REGISTER_METRIC_REQUESTS, RegistrySpecListener::onPost);
|
||||
MetricsCat APPLICATION_REGISTER_FINISH = new MetricsCat(MetricsKey.REGISTER_METRIC_REQUESTS_SUCCEED, RegistrySpecListener::onFinish);
|
||||
MetricsCat APPLICATION_REGISTER_ERROR = new MetricsCat(MetricsKey.REGISTER_METRIC_REQUESTS_FAILED, RegistrySpecListener::onError);
|
||||
|
||||
// MetricsSubscribeListener
|
||||
MetricsCat APPLICATION_SUBSCRIBE_POST = new MetricsCat(MetricsKey.SUBSCRIBE_METRIC_NUM, MetricsApplicationListener::onPostEventBuild);
|
||||
MetricsCat APPLICATION_SUBSCRIBE_FINISH = new MetricsCat(MetricsKey.SUBSCRIBE_METRIC_NUM_SUCCEED, MetricsApplicationListener::onFinishEventBuild);
|
||||
MetricsCat APPLICATION_SUBSCRIBE_ERROR = new MetricsCat(MetricsKey.SUBSCRIBE_METRIC_NUM_FAILED, MetricsApplicationListener::onErrorEventBuild);
|
||||
MetricsCat APPLICATION_SUBSCRIBE_POST = new MetricsCat(MetricsKey.SUBSCRIBE_METRIC_NUM, RegistrySpecListener::onPost);
|
||||
MetricsCat APPLICATION_SUBSCRIBE_FINISH = new MetricsCat(MetricsKey.SUBSCRIBE_METRIC_NUM_SUCCEED, RegistrySpecListener::onFinish);
|
||||
MetricsCat APPLICATION_SUBSCRIBE_ERROR = new MetricsCat(MetricsKey.SUBSCRIBE_METRIC_NUM_FAILED, RegistrySpecListener::onError);
|
||||
|
||||
// MetricsNotifyListener
|
||||
MetricsCat APPLICATION_NOTIFY_POST = new MetricsCat(MetricsKey.NOTIFY_METRIC_REQUESTS, MetricsApplicationListener::onPostEventBuild);
|
||||
MetricsCat APPLICATION_NOTIFY_FINISH = new MetricsCat(MetricsKey.NOTIFY_METRIC_NUM_LAST,
|
||||
(key, placeType, collector) -> AbstractMetricsKeyListener.onFinish(key,
|
||||
event -> {
|
||||
collector.addServiceRt(event.appName(), placeType.getType(), event.getTimePair().calc());
|
||||
Map<String, Integer> lastNumMap = Collections.unmodifiableMap(event.getAttachmentValue(ATTACHMENT_KEY_LAST_NUM_MAP));
|
||||
lastNumMap.forEach(
|
||||
(k, v) -> collector.setNum(new MetricsKeyWrapper(key, OP_TYPE_NOTIFY), k, v));
|
||||
MetricsCat APPLICATION_NOTIFY_FINISH = new MetricsCat(MetricsKey.NOTIFY_METRIC_NUM_LAST, RegistrySpecListener::onFinishOfNotify);
|
||||
|
||||
}
|
||||
));
|
||||
|
||||
|
||||
MetricsCat APPLICATION_DIRECTORY_POST = new MetricsCat(MetricsKey.DIRECTORY_METRIC_NUM_VALID, (key, placeType, collector) -> AbstractMetricsKeyListener.onEvent(key,
|
||||
event ->
|
||||
{
|
||||
Map<MetricsKey, Map<String, Integer>> summaryMap = event.getAttachmentValue(ATTACHMENT_DIRECTORY_MAP);
|
||||
summaryMap.forEach((metricsKey, map) ->
|
||||
map.forEach(
|
||||
(k, v) -> collector.setNum(new MetricsKeyWrapper(metricsKey, OP_TYPE_DIRECTORY), k, v)));
|
||||
}
|
||||
));
|
||||
MetricsCat APPLICATION_DIRECTORY_POST = new MetricsCat(MetricsKey.DIRECTORY_METRIC_NUM_VALID, RegistrySpecListener::onPostOfDirectory);
|
||||
|
||||
|
||||
// MetricsServiceRegisterListener
|
||||
MetricsCat SERVICE_REGISTER_POST = new MetricsCat(MetricsKey.SERVICE_REGISTER_METRIC_REQUESTS, MetricsServiceListener::onPostEventBuild);
|
||||
MetricsCat SERVICE_REGISTER_FINISH = new MetricsCat(MetricsKey.SERVICE_REGISTER_METRIC_REQUESTS_SUCCEED, MetricsServiceListener::onFinishEventBuild);
|
||||
MetricsCat SERVICE_REGISTER_ERROR = new MetricsCat(MetricsKey.SERVICE_REGISTER_METRIC_REQUESTS_FAILED, MetricsServiceListener::onErrorEventBuild);
|
||||
MetricsCat SERVICE_REGISTER_POST = new MetricsCat(MetricsKey.SERVICE_REGISTER_METRIC_REQUESTS, RegistrySpecListener::onPostOfService);
|
||||
MetricsCat SERVICE_REGISTER_FINISH = new MetricsCat(MetricsKey.SERVICE_REGISTER_METRIC_REQUESTS_SUCCEED, RegistrySpecListener::onFinishOfService);
|
||||
MetricsCat SERVICE_REGISTER_ERROR = new MetricsCat(MetricsKey.SERVICE_REGISTER_METRIC_REQUESTS_FAILED, RegistrySpecListener::onErrorOfService);
|
||||
|
||||
|
||||
// MetricsServiceSubscribeListener
|
||||
MetricsCat SERVICE_SUBSCRIBE_POST = new MetricsCat(MetricsKey.SERVICE_SUBSCRIBE_METRIC_NUM, MetricsServiceListener::onPostEventBuild);
|
||||
MetricsCat SERVICE_SUBSCRIBE_FINISH = new MetricsCat(MetricsKey.SERVICE_SUBSCRIBE_METRIC_NUM_SUCCEED, MetricsServiceListener::onFinishEventBuild);
|
||||
MetricsCat SERVICE_SUBSCRIBE_ERROR = new MetricsCat(MetricsKey.SERVICE_SUBSCRIBE_METRIC_NUM_FAILED, MetricsServiceListener::onErrorEventBuild);
|
||||
MetricsCat SERVICE_SUBSCRIBE_POST = new MetricsCat(MetricsKey.SERVICE_SUBSCRIBE_METRIC_NUM, RegistrySpecListener::onPostOfService);
|
||||
MetricsCat SERVICE_SUBSCRIBE_FINISH = new MetricsCat(MetricsKey.SERVICE_SUBSCRIBE_METRIC_NUM_SUCCEED, RegistrySpecListener::onFinishOfService);
|
||||
MetricsCat SERVICE_SUBSCRIBE_ERROR = new MetricsCat(MetricsKey.SERVICE_SUBSCRIBE_METRIC_NUM_FAILED, RegistrySpecListener::onErrorOfService);
|
||||
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@
|
|||
|
||||
package org.apache.dubbo.metrics.registry.metrics.collector;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
import org.apache.dubbo.config.ApplicationConfig;
|
||||
import org.apache.dubbo.metrics.event.MetricsDispatcher;
|
||||
import org.apache.dubbo.metrics.event.MetricsEventBus;
|
||||
|
|
@ -30,12 +31,12 @@ import org.apache.dubbo.metrics.registry.collector.RegistryMetricsCollector;
|
|||
import org.apache.dubbo.metrics.registry.event.RegistryEvent;
|
||||
import org.apache.dubbo.rpc.model.ApplicationModel;
|
||||
import org.apache.dubbo.rpc.model.FrameworkModel;
|
||||
|
||||
import org.junit.jupiter.api.AfterEach;
|
||||
import org.junit.jupiter.api.Assertions;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
|
@ -43,9 +44,11 @@ import java.util.Objects;
|
|||
import java.util.stream.Collectors;
|
||||
|
||||
import static org.apache.dubbo.common.constants.MetricsConstants.TAG_APPLICATION_NAME;
|
||||
import static org.apache.dubbo.metrics.registry.RegistryMetricsConstants.APP_LEVEL_KEYS;
|
||||
import static org.apache.dubbo.metrics.registry.RegistryMetricsConstants.OP_TYPE_REGISTER;
|
||||
import static org.apache.dubbo.metrics.registry.RegistryMetricsConstants.OP_TYPE_REGISTER_SERVICE;
|
||||
import static org.apache.dubbo.metrics.registry.RegistryMetricsConstants.OP_TYPE_SUBSCRIBE_SERVICE;
|
||||
import static org.apache.dubbo.metrics.registry.RegistryMetricsConstants.REGISTER_LEVEL_KEYS;
|
||||
|
||||
|
||||
class RegistryMetricsCollectorTest {
|
||||
|
|
@ -74,12 +77,12 @@ class RegistryMetricsCollectorTest {
|
|||
@Test
|
||||
void testRegisterMetrics() {
|
||||
|
||||
RegistryEvent registryEvent = RegistryEvent.toRegisterEvent(applicationModel);
|
||||
RegistryEvent registryEvent = RegistryEvent.toRegisterEvent(applicationModel, Lists.newArrayList("reg1"));
|
||||
MetricsEventBus.post(registryEvent,
|
||||
() -> {
|
||||
List<MetricSample> metricSamples = collector.collect();
|
||||
// push success +1 -> other default 0 = RegistryMetricsConstants.APP_LEVEL_KEYS.size()
|
||||
Assertions.assertEquals(RegistryMetricsConstants.APP_LEVEL_KEYS.size(), metricSamples.size());
|
||||
// push success +1 -> other default 0 = APP_LEVEL_KEYS.size()
|
||||
Assertions.assertEquals(APP_LEVEL_KEYS.size() + REGISTER_LEVEL_KEYS.size(), metricSamples.size());
|
||||
Assertions.assertTrue(metricSamples.stream().allMatch(metricSample -> metricSample instanceof GaugeMetricSample));
|
||||
Assertions.assertTrue(metricSamples.stream().anyMatch(metricSample -> ((GaugeMetricSample) metricSample).applyAsDouble() == 1));
|
||||
return null;
|
||||
|
|
@ -88,12 +91,12 @@ class RegistryMetricsCollectorTest {
|
|||
|
||||
// push finish rt +1
|
||||
List<MetricSample> metricSamples = collector.collect();
|
||||
// RegistryMetricsConstants.APP_LEVEL_KEYS.size() + rt(5) = 12
|
||||
Assertions.assertEquals(RegistryMetricsConstants.APP_LEVEL_KEYS.size() + 5, metricSamples.size());
|
||||
// APP_LEVEL_KEYS.size() + rt(5) = 12
|
||||
Assertions.assertEquals(APP_LEVEL_KEYS.size() + REGISTER_LEVEL_KEYS.size() + 5, metricSamples.size());
|
||||
long c1 = registryEvent.getTimePair().calc();
|
||||
|
||||
|
||||
registryEvent = RegistryEvent.toRegisterEvent(applicationModel);
|
||||
registryEvent = RegistryEvent.toRegisterEvent(applicationModel, Lists.newArrayList("reg1"));
|
||||
TimePair lastTimePair = registryEvent.getTimePair();
|
||||
MetricsEventBus.post(registryEvent,
|
||||
() -> {
|
||||
|
|
@ -111,7 +114,7 @@ class RegistryMetricsCollectorTest {
|
|||
metricSamples = collector.collect();
|
||||
|
||||
// num(total+success+error) + rt(5)
|
||||
Assertions.assertEquals(RegistryMetricsConstants.APP_LEVEL_KEYS.size() + 5, metricSamples.size());
|
||||
Assertions.assertEquals(APP_LEVEL_KEYS.size() + REGISTER_LEVEL_KEYS.size() + 5, metricSamples.size());
|
||||
|
||||
// calc rt
|
||||
for (MetricSample sample : metricSamples) {
|
||||
|
|
@ -134,8 +137,9 @@ class RegistryMetricsCollectorTest {
|
|||
void testServicePushMetrics() {
|
||||
|
||||
String serviceName = "demo.gameService";
|
||||
List<String> rcNames = Lists.newArrayList("demo1");
|
||||
|
||||
RegistryEvent registryEvent = RegistryEvent.toRsEvent(applicationModel, serviceName, 2);
|
||||
RegistryEvent registryEvent = RegistryEvent.toRsEvent(applicationModel, serviceName, 2, rcNames);
|
||||
MetricsEventBus.post(registryEvent,
|
||||
() -> {
|
||||
List<MetricSample> metricSamples = collector.collect();
|
||||
|
|
@ -154,7 +158,7 @@ class RegistryMetricsCollectorTest {
|
|||
Assertions.assertEquals(RegistryMetricsConstants.APP_LEVEL_KEYS.size() + 5 + 2, metricSamples.size());
|
||||
|
||||
long c1 = registryEvent.getTimePair().calc();
|
||||
registryEvent = RegistryEvent.toRsEvent(applicationModel, serviceName, 2);
|
||||
registryEvent = RegistryEvent.toRsEvent(applicationModel, serviceName, 2, rcNames);
|
||||
TimePair lastTimePair = registryEvent.getTimePair();
|
||||
MetricsEventBus.post(registryEvent,
|
||||
() -> {
|
||||
|
|
@ -196,7 +200,7 @@ class RegistryMetricsCollectorTest {
|
|||
|
||||
String serviceName = "demo.gameService";
|
||||
|
||||
RegistryEvent subscribeEvent = RegistryEvent.toSsEvent(applicationModel, serviceName);
|
||||
RegistryEvent subscribeEvent = RegistryEvent.toSsEvent(applicationModel, serviceName, Collections.singletonList("demo1"));
|
||||
MetricsEventBus.post(subscribeEvent,
|
||||
() -> {
|
||||
List<MetricSample> metricSamples = collector.collect();
|
||||
|
|
@ -216,7 +220,7 @@ class RegistryMetricsCollectorTest {
|
|||
Assertions.assertEquals(RegistryMetricsConstants.APP_LEVEL_KEYS.size() + 5 + 2, metricSamples.size());
|
||||
|
||||
long c1 = subscribeEvent.getTimePair().calc();
|
||||
subscribeEvent = RegistryEvent.toSsEvent(applicationModel, serviceName);
|
||||
subscribeEvent = RegistryEvent.toSsEvent(applicationModel, serviceName, Collections.singletonList("demo1"));
|
||||
TimePair lastTimePair = subscribeEvent.getTimePair();
|
||||
MetricsEventBus.post(subscribeEvent,
|
||||
() -> {
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@
|
|||
|
||||
package org.apache.dubbo.metrics.registry.metrics.collector;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
import org.apache.dubbo.config.ApplicationConfig;
|
||||
import org.apache.dubbo.config.MetricsConfig;
|
||||
import org.apache.dubbo.config.context.ConfigManager;
|
||||
|
|
@ -24,11 +25,11 @@ import org.apache.dubbo.config.nested.AggregationConfig;
|
|||
import org.apache.dubbo.metrics.model.key.MetricsKey;
|
||||
import org.apache.dubbo.metrics.model.sample.GaugeMetricSample;
|
||||
import org.apache.dubbo.metrics.model.sample.MetricSample;
|
||||
import org.apache.dubbo.metrics.registry.RegistryMetricsConstants;
|
||||
import org.apache.dubbo.metrics.registry.collector.RegistryMetricsCollector;
|
||||
import org.apache.dubbo.metrics.registry.event.RegistryEvent;
|
||||
import org.apache.dubbo.rpc.model.ApplicationModel;
|
||||
import org.apache.dubbo.rpc.model.FrameworkModel;
|
||||
|
||||
import org.junit.jupiter.api.Assertions;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
|
@ -221,9 +222,9 @@ public class RegistryMetricsTest {
|
|||
}
|
||||
List<MetricSample> samples = collector.collect();
|
||||
|
||||
GaugeMetricSample<?> succeedRequests = getSample(MetricsKey.SERVICE_REGISTER_METRIC_REQUESTS_SUCCEED.getName(), samples);
|
||||
GaugeMetricSample<?> failedRequests = getSample(MetricsKey.SERVICE_REGISTER_METRIC_REQUESTS_FAILED.getName(), samples);
|
||||
GaugeMetricSample<?> totalRequests = getSample(MetricsKey.SERVICE_REGISTER_METRIC_REQUESTS.getName(), samples);
|
||||
GaugeMetricSample<?> succeedRequests = getSample(MetricsKey.SERVICE_REGISTER_METRIC_REQUESTS_SUCCEED.getNameByType(RegistryMetricsConstants.OP_TYPE_REGISTER_SERVICE.getType()), samples);
|
||||
GaugeMetricSample<?> failedRequests = getSample(MetricsKey.SERVICE_REGISTER_METRIC_REQUESTS_FAILED.getNameByType(RegistryMetricsConstants.OP_TYPE_REGISTER_SERVICE.getType()), samples);
|
||||
GaugeMetricSample<?> totalRequests = getSample(MetricsKey.SERVICE_REGISTER_METRIC_REQUESTS.getNameByType(RegistryMetricsConstants.OP_TYPE_REGISTER_SERVICE.getType()), samples);
|
||||
|
||||
Assertions.assertEquals(5L, succeedRequests.applyAsLong());
|
||||
Assertions.assertEquals(5L, failedRequests.applyAsLong());
|
||||
|
|
@ -289,19 +290,20 @@ public class RegistryMetricsTest {
|
|||
}
|
||||
|
||||
RegistryEvent registerEvent() {
|
||||
RegistryEvent event = RegistryEvent.toRegisterEvent(applicationModel);
|
||||
RegistryEvent event = RegistryEvent.toRegisterEvent(applicationModel, Lists.newArrayList("reg1"));
|
||||
event.setAvailable(true);
|
||||
return event;
|
||||
}
|
||||
|
||||
RegistryEvent rsEvent() {
|
||||
RegistryEvent event = RegistryEvent.toRsEvent(applicationModel, "TestServiceInterface1", 1);
|
||||
List<String> rcNames = Lists.newArrayList("demo1");
|
||||
RegistryEvent event = RegistryEvent.toRsEvent(applicationModel, "TestServiceInterface1", 1, rcNames);
|
||||
event.setAvailable(true);
|
||||
return event;
|
||||
}
|
||||
|
||||
RegistryEvent subscribeEvent() {
|
||||
RegistryEvent event = RegistryEvent.toSubscribeEvent(applicationModel);
|
||||
RegistryEvent event = RegistryEvent.toSubscribeEvent(applicationModel, "registryClusterName_test");
|
||||
event.setAvailable(true);
|
||||
return event;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@
|
|||
|
||||
package org.apache.dubbo.metrics.registry.metrics.collector;
|
||||
|
||||
import org.apache.dubbo.common.constants.RegistryConstants;
|
||||
import org.apache.dubbo.config.ApplicationConfig;
|
||||
import org.apache.dubbo.metrics.data.ApplicationStatComposite;
|
||||
import org.apache.dubbo.metrics.data.BaseStatComposite;
|
||||
|
|
@ -29,12 +30,15 @@ import org.apache.dubbo.metrics.model.container.LongContainer;
|
|||
import org.apache.dubbo.metrics.model.sample.GaugeMetricSample;
|
||||
import org.apache.dubbo.metrics.model.sample.MetricSample;
|
||||
import org.apache.dubbo.metrics.registry.RegistryMetricsConstants;
|
||||
import org.apache.dubbo.metrics.registry.collector.RegistryStatComposite;
|
||||
import org.apache.dubbo.rpc.model.ApplicationModel;
|
||||
import org.apache.dubbo.rpc.model.FrameworkModel;
|
||||
|
||||
import org.junit.jupiter.api.Assertions;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
|
|
@ -55,6 +59,7 @@ public class RegistryStatCompositeTest {
|
|||
private ApplicationModel applicationModel;
|
||||
private String applicationName;
|
||||
private BaseStatComposite statComposite;
|
||||
private RegistryStatComposite regStatComposite;
|
||||
|
||||
@BeforeEach
|
||||
public void setup() {
|
||||
|
|
@ -83,6 +88,7 @@ public class RegistryStatCompositeTest {
|
|||
rtStatComposite.init(OP_TYPE_REGISTER, OP_TYPE_SUBSCRIBE, OP_TYPE_NOTIFY, OP_TYPE_REGISTER_SERVICE, OP_TYPE_SUBSCRIBE_SERVICE);
|
||||
}
|
||||
};
|
||||
regStatComposite = new RegistryStatComposite(applicationModel);
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
@ -102,8 +108,10 @@ public class RegistryStatCompositeTest {
|
|||
|
||||
@Test
|
||||
void testIncrement() {
|
||||
statComposite.incrementApp(REGISTER_METRIC_REQUESTS, 1);
|
||||
Assertions.assertEquals(1L, statComposite.getApplicationStatComposite().getApplicationNumStats().get(REGISTER_METRIC_REQUESTS).get());
|
||||
regStatComposite.incrMetricsNum(REGISTER_METRIC_REQUESTS, "beijing");
|
||||
ApplicationMetric applicationMetric = new ApplicationMetric(applicationModel);
|
||||
applicationMetric.setExtraInfo(Collections.singletonMap(RegistryConstants.REGISTRY_CLUSTER_KEY.toLowerCase(), "beijing"));
|
||||
Assertions.assertEquals(1L, regStatComposite.getAppStats().get(REGISTER_METRIC_REQUESTS).get(applicationMetric).get());
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
|
|||
|
|
@ -107,5 +107,12 @@
|
|||
<artifactId>zipkin-reporter-brave</artifactId>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
|
||||
<!-- sender -->
|
||||
<dependency>
|
||||
<groupId>io.zipkin.reporter2</groupId>
|
||||
<artifactId>zipkin-sender-urlconnection</artifactId>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</project>
|
||||
|
|
@ -1,66 +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.tracing.exporter;
|
||||
|
||||
import org.apache.dubbo.common.logger.ErrorTypeAwareLogger;
|
||||
import org.apache.dubbo.common.logger.LoggerFactory;
|
||||
import org.apache.dubbo.common.utils.StringUtils;
|
||||
import org.apache.dubbo.config.nested.ExporterConfig;
|
||||
import org.apache.dubbo.rpc.model.ApplicationModel;
|
||||
import org.apache.dubbo.tracing.exporter.otlp.OTlpExporter;
|
||||
import org.apache.dubbo.tracing.exporter.zipkin.ZipkinExporter;
|
||||
|
||||
import brave.handler.SpanHandler;
|
||||
import io.opentelemetry.sdk.trace.export.SpanExporter;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class TraceExporterFactory {
|
||||
|
||||
private final static ErrorTypeAwareLogger LOGGER = LoggerFactory.getErrorTypeAwareLogger(TraceExporterFactory.class);
|
||||
|
||||
/**
|
||||
* for OTel
|
||||
*/
|
||||
public static List<SpanExporter> getSpanExporters(ApplicationModel applicationModel, ExporterConfig exporterConfig) {
|
||||
ExporterConfig.ZipkinConfig zipkinConfig = exporterConfig.getZipkinConfig();
|
||||
ExporterConfig.OtlpConfig otlpConfig = exporterConfig.getOtlpConfig();
|
||||
List<SpanExporter> res = new ArrayList<>();
|
||||
if (zipkinConfig != null && StringUtils.isNotEmpty(zipkinConfig.getEndpoint())) {
|
||||
ZipkinExporter zipkinExporter = new ZipkinExporter(applicationModel, zipkinConfig);
|
||||
LOGGER.info("Create zipkin span exporter.");
|
||||
res.add(zipkinExporter.getSpanExporter());
|
||||
}
|
||||
if (otlpConfig != null && StringUtils.isNotEmpty(otlpConfig.getEndpoint())) {
|
||||
OTlpExporter otlpExporter = new OTlpExporter(applicationModel, otlpConfig);
|
||||
LOGGER.info("Create OTlp span exporter.");
|
||||
res.add(otlpExporter.getSpanExporter());
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
/**
|
||||
* for Brave
|
||||
*/
|
||||
public static List<SpanHandler> getSpanHandlers(ApplicationModel applicationModel, ExporterConfig exporterConfig) {
|
||||
List<SpanHandler> res = new ArrayList<>();
|
||||
// TODO brave SpanHandler impl
|
||||
return res;
|
||||
}
|
||||
}
|
||||
|
|
@ -18,9 +18,7 @@ package org.apache.dubbo.tracing.exporter.otlp;
|
|||
|
||||
import org.apache.dubbo.config.nested.ExporterConfig;
|
||||
import org.apache.dubbo.rpc.model.ApplicationModel;
|
||||
import org.apache.dubbo.tracing.exporter.TraceExporter;
|
||||
|
||||
import brave.handler.SpanHandler;
|
||||
import io.opentelemetry.exporter.otlp.http.trace.OtlpHttpSpanExporter;
|
||||
import io.opentelemetry.exporter.otlp.trace.OtlpGrpcSpanExporter;
|
||||
import io.opentelemetry.exporter.otlp.trace.OtlpGrpcSpanExporterBuilder;
|
||||
|
|
@ -28,18 +26,12 @@ import io.opentelemetry.sdk.trace.export.SpanExporter;
|
|||
|
||||
import java.util.Map;
|
||||
|
||||
public class OTlpExporter implements TraceExporter {
|
||||
/**
|
||||
* OTlp span exporter for OTel.
|
||||
*/
|
||||
public class OTlpSpanExporter {
|
||||
|
||||
private final ApplicationModel applicationModel;
|
||||
private final ExporterConfig.OtlpConfig otlpConfig;
|
||||
|
||||
public OTlpExporter(ApplicationModel applicationModel, ExporterConfig.OtlpConfig otlpConfig) {
|
||||
this.applicationModel = applicationModel;
|
||||
this.otlpConfig = otlpConfig;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SpanExporter getSpanExporter() {
|
||||
public static SpanExporter getSpanExporter(ApplicationModel applicationModel, ExporterConfig.OtlpConfig otlpConfig) {
|
||||
OtlpGrpcSpanExporter externalOTlpGrpcSpanExporter = applicationModel.getBeanFactory().getBean(OtlpGrpcSpanExporter.class);
|
||||
if (externalOTlpGrpcSpanExporter != null) {
|
||||
return externalOTlpGrpcSpanExporter;
|
||||
|
|
@ -57,10 +49,4 @@ public class OTlpExporter implements TraceExporter {
|
|||
}
|
||||
return builder.build();
|
||||
}
|
||||
|
||||
@Override
|
||||
public SpanHandler getSpanHandler() {
|
||||
// OTlp is only belong to OTel.
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
|
@ -18,43 +18,26 @@ package org.apache.dubbo.tracing.exporter.zipkin;
|
|||
|
||||
import org.apache.dubbo.config.nested.ExporterConfig;
|
||||
import org.apache.dubbo.rpc.model.ApplicationModel;
|
||||
import org.apache.dubbo.tracing.exporter.TraceExporter;
|
||||
|
||||
import brave.handler.SpanHandler;
|
||||
import io.opentelemetry.exporter.zipkin.ZipkinSpanExporter;
|
||||
import io.opentelemetry.sdk.trace.export.SpanExporter;
|
||||
import zipkin2.Span;
|
||||
import zipkin2.codec.BytesEncoder;
|
||||
import zipkin2.codec.SpanBytesEncoder;
|
||||
|
||||
public class ZipkinExporter implements TraceExporter {
|
||||
/**
|
||||
* Zipkin span exporter for OTel.
|
||||
*/
|
||||
public class ZipkinSpanExporter {
|
||||
|
||||
private final ApplicationModel applicationModel;
|
||||
private final ExporterConfig.ZipkinConfig zipkinConfig;
|
||||
|
||||
public ZipkinExporter(ApplicationModel applicationModel, ExporterConfig.ZipkinConfig zipkinConfig) {
|
||||
this.applicationModel = applicationModel;
|
||||
this.zipkinConfig = zipkinConfig;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SpanExporter getSpanExporter() {
|
||||
BytesEncoder<Span> encoder = getSpanBytesEncoder();
|
||||
return ZipkinSpanExporter.builder()
|
||||
.setEncoder(encoder)
|
||||
public static io.opentelemetry.sdk.trace.export.SpanExporter getSpanExporter(ApplicationModel applicationModel, ExporterConfig.ZipkinConfig zipkinConfig) {
|
||||
return io.opentelemetry.exporter.zipkin.ZipkinSpanExporter.builder()
|
||||
.setEncoder(getSpanBytesEncoder(applicationModel))
|
||||
.setEndpoint(zipkinConfig.getEndpoint())
|
||||
.setReadTimeout(zipkinConfig.getReadTimeout())
|
||||
.build();
|
||||
}
|
||||
|
||||
@Override
|
||||
public SpanHandler getSpanHandler() {
|
||||
// TODO SpanHandler of Brave impl
|
||||
return null;
|
||||
}
|
||||
|
||||
private BytesEncoder<Span> getSpanBytesEncoder() {
|
||||
BytesEncoder<Span> encoder = applicationModel.getBeanFactory().getBean(BytesEncoder.class);
|
||||
private static BytesEncoder<Span> getSpanBytesEncoder(ApplicationModel applicationModel) {
|
||||
BytesEncoder<zipkin2.Span> encoder = applicationModel.getBeanFactory().getBean(BytesEncoder.class);
|
||||
return encoder == null ? SpanBytesEncoder.JSON_V2 : encoder;
|
||||
}
|
||||
}
|
||||
|
|
@ -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.tracing.exporter.zipkin;
|
||||
|
||||
import org.apache.dubbo.config.nested.ExporterConfig;
|
||||
import org.apache.dubbo.rpc.model.ApplicationModel;
|
||||
|
||||
import brave.handler.SpanHandler;
|
||||
import zipkin2.Span;
|
||||
import zipkin2.codec.BytesEncoder;
|
||||
import zipkin2.codec.SpanBytesEncoder;
|
||||
import zipkin2.reporter.AsyncReporter;
|
||||
import zipkin2.reporter.urlconnection.URLConnectionSender;
|
||||
|
||||
/**
|
||||
* Zipkin span handler for Brave.
|
||||
*/
|
||||
public class ZipkinSpanHandler {
|
||||
|
||||
public static SpanHandler getSpanHandler(ApplicationModel applicationModel, ExporterConfig.ZipkinConfig zipkinConfig) {
|
||||
URLConnectionSender sender = applicationModel.getBeanFactory().getBean(URLConnectionSender.class);
|
||||
if (sender == null) {
|
||||
URLConnectionSender.Builder builder = URLConnectionSender.newBuilder();
|
||||
builder.connectTimeout((int) zipkinConfig.getConnectTimeout().toMillis());
|
||||
builder.readTimeout((int) zipkinConfig.getReadTimeout().toMillis());
|
||||
builder.endpoint(zipkinConfig.getEndpoint());
|
||||
|
||||
sender = builder.build();
|
||||
}
|
||||
|
||||
AsyncReporter<Span> spanReporter = AsyncReporter.builder(sender).build(getSpanBytesEncoder(applicationModel));
|
||||
return zipkin2.reporter.brave.ZipkinSpanHandler.newBuilder(spanReporter).build();
|
||||
}
|
||||
|
||||
private static BytesEncoder<zipkin2.Span> getSpanBytesEncoder(ApplicationModel applicationModel) {
|
||||
BytesEncoder<zipkin2.Span> encoder = applicationModel.getBeanFactory().getBean(BytesEncoder.class);
|
||||
return encoder == null ? SpanBytesEncoder.JSON_V2 : encoder;
|
||||
}
|
||||
}
|
||||
|
|
@ -18,14 +18,20 @@ package org.apache.dubbo.tracing.tracer.brave;
|
|||
|
||||
import org.apache.dubbo.tracing.tracer.PropagatorProvider;
|
||||
|
||||
import io.micrometer.tracing.brave.bridge.BravePropagator;
|
||||
import io.micrometer.tracing.propagation.Propagator;
|
||||
|
||||
|
||||
public class BravePropagatorProvider implements PropagatorProvider {
|
||||
|
||||
private static Propagator propagator;
|
||||
|
||||
@Override
|
||||
public Propagator getPropagator() {
|
||||
// TODO impl
|
||||
return null;
|
||||
return propagator;
|
||||
}
|
||||
|
||||
protected static void createMicrometerPropagator(brave.Tracing tracing) {
|
||||
propagator = new BravePropagator(tracing);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -16,15 +16,40 @@
|
|||
*/
|
||||
package org.apache.dubbo.tracing.tracer.brave;
|
||||
|
||||
import org.apache.dubbo.common.logger.ErrorTypeAwareLogger;
|
||||
import org.apache.dubbo.common.logger.LoggerFactory;
|
||||
import org.apache.dubbo.common.utils.StringUtils;
|
||||
import org.apache.dubbo.config.ApplicationConfig;
|
||||
import org.apache.dubbo.config.TracingConfig;
|
||||
import org.apache.dubbo.config.nested.BaggageConfig;
|
||||
import org.apache.dubbo.config.nested.ExporterConfig;
|
||||
import org.apache.dubbo.rpc.model.ApplicationModel;
|
||||
import org.apache.dubbo.tracing.exporter.zipkin.ZipkinSpanHandler;
|
||||
import org.apache.dubbo.tracing.tracer.TracerProvider;
|
||||
import org.apache.dubbo.tracing.utils.PropagationType;
|
||||
|
||||
import io.micrometer.tracing.CurrentTraceContext;
|
||||
import io.micrometer.tracing.Tracer;
|
||||
import io.micrometer.tracing.brave.bridge.BraveBaggageManager;
|
||||
import io.micrometer.tracing.brave.bridge.BraveCurrentTraceContext;
|
||||
import io.micrometer.tracing.brave.bridge.BraveTracer;
|
||||
import io.micrometer.tracing.brave.bridge.W3CPropagation;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
|
||||
import static org.apache.dubbo.tracing.utils.ObservationConstants.DEFAULT_APPLICATION_NAME;
|
||||
import static org.apache.dubbo.tracing.utils.ObservationSupportUtil.isSupportBraveURLSender;
|
||||
|
||||
|
||||
public class BraveProvider implements TracerProvider {
|
||||
|
||||
private final static ErrorTypeAwareLogger LOGGER = LoggerFactory.getErrorTypeAwareLogger(BraveProvider.class);
|
||||
|
||||
private static final BraveBaggageManager BRAVE_BAGGAGE_MANAGER = new BraveBaggageManager();
|
||||
|
||||
private final ApplicationModel applicationModel;
|
||||
private final TracingConfig tracingConfig;
|
||||
|
||||
|
|
@ -35,7 +60,139 @@ public class BraveProvider implements TracerProvider {
|
|||
|
||||
@Override
|
||||
public Tracer getTracer() {
|
||||
// TODO impl
|
||||
return null;
|
||||
// [Brave component] SpanHandler is a component that gets called when a span is finished.
|
||||
List<brave.handler.SpanHandler> spanHandlerList = getSpanHandlers();
|
||||
|
||||
String applicationName = applicationModel.getApplicationConfigManager().getApplication()
|
||||
.map(ApplicationConfig::getName)
|
||||
.orElse(DEFAULT_APPLICATION_NAME);
|
||||
|
||||
// [Brave component] CurrentTraceContext is a Brave component that allows you to
|
||||
// retrieve the current TraceContext.
|
||||
brave.propagation.ThreadLocalCurrentTraceContext braveCurrentTraceContext = brave.propagation.ThreadLocalCurrentTraceContext.newBuilder()
|
||||
.addScopeDecorator(correlationScopeDecorator()) // Brave's automatic MDC setup
|
||||
.build();
|
||||
|
||||
// [Micrometer Tracing component] A Micrometer Tracing wrapper for Brave's CurrentTraceContext
|
||||
CurrentTraceContext bridgeContext = new BraveCurrentTraceContext(braveCurrentTraceContext);
|
||||
|
||||
|
||||
// [Brave component] Tracing is the root component that allows to configure the
|
||||
// tracer, handlers, context propagation etc.
|
||||
brave.Tracing.Builder builder = brave.Tracing.newBuilder()
|
||||
.currentTraceContext(braveCurrentTraceContext)
|
||||
.supportsJoin(false)
|
||||
.traceId128Bit(true)
|
||||
.localServiceName(applicationName)
|
||||
// For Baggage to work you need to provide a list of fields to propagate
|
||||
.propagationFactory(PropagatorFactory.getPropagationFactory(tracingConfig))
|
||||
.sampler(getSampler());
|
||||
spanHandlerList.forEach(builder::addSpanHandler);
|
||||
|
||||
brave.Tracing tracing = builder.build();
|
||||
|
||||
BravePropagatorProvider.createMicrometerPropagator(tracing);
|
||||
|
||||
// [Brave component] Tracer is a component that handles the life-cycle of a span
|
||||
brave.Tracer braveTracer = tracing.tracer();
|
||||
|
||||
// [Micrometer Tracing component] A Micrometer Tracing wrapper for Brave's Tracer
|
||||
return new BraveTracer(braveTracer, bridgeContext, BRAVE_BAGGAGE_MANAGER);
|
||||
}
|
||||
|
||||
private List<brave.handler.SpanHandler> getSpanHandlers() {
|
||||
ExporterConfig exporterConfig = tracingConfig.getTracingExporter();
|
||||
List<brave.handler.SpanHandler> res = new ArrayList<>();
|
||||
if (!isSupportBraveURLSender()) {
|
||||
return res;
|
||||
}
|
||||
ExporterConfig.ZipkinConfig zipkinConfig = exporterConfig.getZipkinConfig();
|
||||
if (zipkinConfig != null && StringUtils.isNotEmpty(zipkinConfig.getEndpoint())) {
|
||||
LOGGER.info("Create zipkin span handler.");
|
||||
res.add(ZipkinSpanHandler.getSpanHandler(applicationModel, zipkinConfig));
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
private brave.sampler.Sampler getSampler() {
|
||||
return brave.sampler.Sampler.create(tracingConfig.getSampling().getProbability());
|
||||
}
|
||||
|
||||
private Optional<brave.baggage.CorrelationScopeCustomizer> correlationFieldsCorrelationScopeCustomizer() {
|
||||
BaggageConfig.Correlation correlation = tracingConfig.getBaggage().getCorrelation();
|
||||
boolean enabled = correlation.isEnabled();
|
||||
if (!enabled) {
|
||||
return Optional.empty();
|
||||
}
|
||||
return Optional.of((builder) -> {
|
||||
List<String> correlationFields = correlation.getFields();
|
||||
for (String field : correlationFields) {
|
||||
builder.add(brave.baggage.CorrelationScopeConfig.SingleCorrelationField.newBuilder(brave.baggage.BaggageField.create(field))
|
||||
.flushOnUpdate().build());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private brave.propagation.CurrentTraceContext.ScopeDecorator correlationScopeDecorator() {
|
||||
brave.baggage.CorrelationScopeDecorator.Builder builder = brave.context.slf4j.MDCScopeDecorator.newBuilder();
|
||||
correlationFieldsCorrelationScopeCustomizer().ifPresent((customizer) -> customizer.customize(builder));
|
||||
return builder.build();
|
||||
}
|
||||
|
||||
static class PropagatorFactory {
|
||||
|
||||
public static brave.propagation.Propagation.Factory getPropagationFactory(TracingConfig tracingConfig) {
|
||||
BaggageConfig baggageConfig = tracingConfig.getBaggage();
|
||||
if (baggageConfig == null || !baggageConfig.getEnabled()) {
|
||||
return getPropagationFactoryWithoutBaggage(tracingConfig);
|
||||
}
|
||||
return getPropagationFactoryWithBaggage(tracingConfig);
|
||||
}
|
||||
|
||||
private static brave.propagation.Propagation.Factory getPropagationFactoryWithoutBaggage(TracingConfig tracingConfig) {
|
||||
PropagationType propagationType = PropagationType.forValue(tracingConfig.getPropagation().getType());
|
||||
if (PropagationType.W3C == propagationType) {
|
||||
return new io.micrometer.tracing.brave.bridge.W3CPropagation();
|
||||
} else {
|
||||
// Brave default propagation is B3
|
||||
return brave.propagation.B3Propagation.newFactoryBuilder().injectFormat(brave.propagation.B3Propagation.Format.SINGLE_NO_PARENT).build();
|
||||
}
|
||||
}
|
||||
|
||||
private static brave.propagation.Propagation.Factory getPropagationFactoryWithBaggage(TracingConfig tracingConfig) {
|
||||
PropagationType propagationType = PropagationType.forValue(tracingConfig.getPropagation().getType());
|
||||
brave.propagation.Propagation.Factory delegate;
|
||||
if (PropagationType.W3C == propagationType) {
|
||||
delegate = new W3CPropagation(BRAVE_BAGGAGE_MANAGER, Collections.emptyList());
|
||||
} else {
|
||||
// Brave default propagation is B3
|
||||
delegate = brave.propagation.B3Propagation.newFactoryBuilder().injectFormat(brave.propagation.B3Propagation.Format.SINGLE_NO_PARENT).build();
|
||||
}
|
||||
return getBaggageFactoryBuilder(delegate, tracingConfig).build();
|
||||
}
|
||||
|
||||
private static brave.baggage.BaggagePropagation.FactoryBuilder getBaggageFactoryBuilder(brave.propagation.Propagation.Factory delegate, TracingConfig tracingConfig) {
|
||||
brave.baggage.BaggagePropagation.FactoryBuilder builder = brave.baggage.BaggagePropagation.newFactoryBuilder(delegate);
|
||||
|
||||
getBaggagePropagationCustomizers(tracingConfig).forEach((customizer) -> customizer.customize(builder));
|
||||
return builder;
|
||||
}
|
||||
|
||||
private static List<brave.baggage.BaggagePropagationCustomizer> getBaggagePropagationCustomizers(TracingConfig tracingConfig) {
|
||||
List<brave.baggage.BaggagePropagationCustomizer> res = new ArrayList<>();
|
||||
if (tracingConfig.getBaggage().getCorrelation().isEnabled()) {
|
||||
res.add(remoteFieldsBaggagePropagationCustomizer(tracingConfig));
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
private static brave.baggage.BaggagePropagationCustomizer remoteFieldsBaggagePropagationCustomizer(TracingConfig tracingConfig) {
|
||||
return (builder) -> {
|
||||
List<String> remoteFields = tracingConfig.getBaggage().getRemoteFields();
|
||||
for (String fieldName : remoteFields) {
|
||||
builder.add(brave.baggage.BaggagePropagationConfig.SingleBaggageField.remote(brave.baggage.BaggageField.create(fieldName)));
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -18,13 +18,19 @@ package org.apache.dubbo.tracing.tracer.otel;
|
|||
|
||||
import org.apache.dubbo.common.Version;
|
||||
import org.apache.dubbo.common.lang.Nullable;
|
||||
import org.apache.dubbo.common.logger.ErrorTypeAwareLogger;
|
||||
import org.apache.dubbo.common.logger.LoggerFactory;
|
||||
import org.apache.dubbo.common.utils.StringUtils;
|
||||
import org.apache.dubbo.config.ApplicationConfig;
|
||||
import org.apache.dubbo.config.TracingConfig;
|
||||
import org.apache.dubbo.config.nested.BaggageConfig;
|
||||
import org.apache.dubbo.config.nested.ExporterConfig;
|
||||
import org.apache.dubbo.config.nested.PropagationConfig;
|
||||
import org.apache.dubbo.rpc.model.ApplicationModel;
|
||||
import org.apache.dubbo.tracing.exporter.TraceExporterFactory;
|
||||
import org.apache.dubbo.tracing.exporter.otlp.OTlpSpanExporter;
|
||||
import org.apache.dubbo.tracing.exporter.zipkin.ZipkinSpanExporter;
|
||||
import org.apache.dubbo.tracing.tracer.TracerProvider;
|
||||
import org.apache.dubbo.tracing.utils.PropagationType;
|
||||
|
||||
import io.micrometer.tracing.Tracer;
|
||||
import io.micrometer.tracing.otel.bridge.CompositeSpanExporter;
|
||||
|
|
@ -36,28 +42,17 @@ import io.micrometer.tracing.otel.bridge.OtelTracer;
|
|||
import io.micrometer.tracing.otel.bridge.Slf4JBaggageEventListener;
|
||||
import io.micrometer.tracing.otel.bridge.Slf4JEventListener;
|
||||
import io.micrometer.tracing.otel.propagation.BaggageTextMapPropagator;
|
||||
import io.opentelemetry.api.baggage.propagation.W3CBaggagePropagator;
|
||||
import io.opentelemetry.api.common.Attributes;
|
||||
import io.opentelemetry.api.trace.propagation.W3CTraceContextPropagator;
|
||||
import io.opentelemetry.context.ContextStorage;
|
||||
import io.opentelemetry.context.propagation.ContextPropagators;
|
||||
import io.opentelemetry.context.propagation.TextMapPropagator;
|
||||
import io.opentelemetry.extension.trace.propagation.B3Propagator;
|
||||
import io.opentelemetry.sdk.OpenTelemetrySdk;
|
||||
import io.opentelemetry.sdk.resources.Resource;
|
||||
import io.opentelemetry.sdk.trace.SdkTracerProvider;
|
||||
import io.opentelemetry.sdk.trace.export.BatchSpanProcessor;
|
||||
import io.opentelemetry.sdk.trace.export.SpanExporter;
|
||||
import io.opentelemetry.sdk.trace.samplers.Sampler;
|
||||
import io.opentelemetry.semconv.resource.attributes.ResourceAttributes;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import static org.apache.dubbo.tracing.utils.ObservationConstants.DEFAULT_APPLICATION_NAME;
|
||||
|
||||
public class OpenTelemetryProvider implements TracerProvider {
|
||||
|
||||
private static final String DEFAULT_APPLICATION_NAME = "dubbo-application";
|
||||
private final static ErrorTypeAwareLogger LOGGER = LoggerFactory.getErrorTypeAwareLogger(OpenTelemetryProvider.class);
|
||||
|
||||
private final ApplicationModel applicationModel;
|
||||
private final TracingConfig tracingConfig;
|
||||
|
||||
|
|
@ -72,7 +67,7 @@ public class OpenTelemetryProvider implements TracerProvider {
|
|||
@Override
|
||||
public Tracer getTracer() {
|
||||
// [OTel component] SpanExporter is a component that gets called when a span is finished.
|
||||
List<SpanExporter> spanExporters = TraceExporterFactory.getSpanExporters(applicationModel, tracingConfig.getTracingExporter());
|
||||
List<io.opentelemetry.sdk.trace.export.SpanExporter> spanExporters = getSpanExporters();
|
||||
|
||||
String applicationName = applicationModel.getApplicationConfigManager().getApplication()
|
||||
.map(ApplicationConfig::getName)
|
||||
|
|
@ -84,18 +79,18 @@ public class OpenTelemetryProvider implements TracerProvider {
|
|||
this.otelCurrentTraceContext = createCurrentTraceContext();
|
||||
|
||||
// [OTel component] SdkTracerProvider is an SDK implementation for TracerProvider
|
||||
SdkTracerProvider sdkTracerProvider = SdkTracerProvider.builder()
|
||||
io.opentelemetry.sdk.trace.SdkTracerProvider sdkTracerProvider = io.opentelemetry.sdk.trace.SdkTracerProvider.builder()
|
||||
.setSampler(getSampler())
|
||||
.setResource(Resource.create(Attributes.of(ResourceAttributes.SERVICE_NAME, applicationName)))
|
||||
.addSpanProcessor(BatchSpanProcessor
|
||||
.setResource(io.opentelemetry.sdk.resources.Resource.create(io.opentelemetry.api.common.Attributes.of(io.opentelemetry.semconv.resource.attributes.ResourceAttributes.SERVICE_NAME, applicationName)))
|
||||
.addSpanProcessor(io.opentelemetry.sdk.trace.export.BatchSpanProcessor
|
||||
.builder(new CompositeSpanExporter(spanExporters, null, null, null))
|
||||
.build())
|
||||
.build();
|
||||
|
||||
ContextPropagators otelContextPropagators = createOtelContextPropagators();
|
||||
io.opentelemetry.context.propagation.ContextPropagators otelContextPropagators = createOtelContextPropagators();
|
||||
|
||||
// [OTel component] The SDK implementation of OpenTelemetry
|
||||
OpenTelemetrySdk openTelemetrySdk = OpenTelemetrySdk.builder()
|
||||
io.opentelemetry.sdk.OpenTelemetrySdk openTelemetrySdk = io.opentelemetry.sdk.OpenTelemetrySdk.builder()
|
||||
.setTracerProvider(sdkTracerProvider)
|
||||
.setPropagators(otelContextPropagators)
|
||||
.build();
|
||||
|
|
@ -113,14 +108,31 @@ public class OpenTelemetryProvider implements TracerProvider {
|
|||
Collections.emptyList()));
|
||||
}
|
||||
|
||||
private List<io.opentelemetry.sdk.trace.export.SpanExporter> getSpanExporters() {
|
||||
ExporterConfig exporterConfig = tracingConfig.getTracingExporter();
|
||||
ExporterConfig.ZipkinConfig zipkinConfig = exporterConfig.getZipkinConfig();
|
||||
ExporterConfig.OtlpConfig otlpConfig = exporterConfig.getOtlpConfig();
|
||||
List<io.opentelemetry.sdk.trace.export.SpanExporter> res = new ArrayList<>();
|
||||
if (zipkinConfig != null && StringUtils.isNotEmpty(zipkinConfig.getEndpoint())) {
|
||||
LOGGER.info("Create zipkin span exporter.");
|
||||
res.add(ZipkinSpanExporter.getSpanExporter(applicationModel, zipkinConfig));
|
||||
}
|
||||
if (otlpConfig != null && StringUtils.isNotEmpty(otlpConfig.getEndpoint())) {
|
||||
LOGGER.info("Create OTlp span exporter.");
|
||||
res.add(OTlpSpanExporter.getSpanExporter(applicationModel, otlpConfig));
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
/**
|
||||
* sampler with probability
|
||||
*
|
||||
* @return sampler
|
||||
*/
|
||||
private Sampler getSampler() {
|
||||
Sampler rootSampler = Sampler.traceIdRatioBased(tracingConfig.getSampling().getProbability());
|
||||
return Sampler.parentBased(rootSampler);
|
||||
private io.opentelemetry.sdk.trace.samplers.Sampler getSampler() {
|
||||
io.opentelemetry.sdk.trace.samplers.Sampler rootSampler = io.opentelemetry.sdk.trace.samplers.Sampler.traceIdRatioBased(tracingConfig.getSampling().getProbability());
|
||||
return io.opentelemetry.sdk.trace.samplers.Sampler.parentBased(rootSampler);
|
||||
}
|
||||
|
||||
private List<EventListener> getEventListeners() {
|
||||
|
|
@ -141,13 +153,13 @@ public class OpenTelemetryProvider implements TracerProvider {
|
|||
}
|
||||
|
||||
private OtelCurrentTraceContext createCurrentTraceContext() {
|
||||
ContextStorage.addWrapper(new EventPublishingContextWrapper(publisher));
|
||||
io.opentelemetry.context.ContextStorage.addWrapper(new EventPublishingContextWrapper(publisher));
|
||||
return new OtelCurrentTraceContext();
|
||||
}
|
||||
|
||||
private ContextPropagators createOtelContextPropagators() {
|
||||
return ContextPropagators.create(
|
||||
TextMapPropagator.composite(
|
||||
private io.opentelemetry.context.propagation.ContextPropagators createOtelContextPropagators() {
|
||||
return io.opentelemetry.context.propagation.ContextPropagators.create(
|
||||
io.opentelemetry.context.propagation.TextMapPropagator.composite(
|
||||
PropagatorFactory.getPropagator(tracingConfig.getPropagation(),
|
||||
tracingConfig.getBaggage(),
|
||||
otelCurrentTraceContext
|
||||
|
|
@ -172,41 +184,44 @@ public class OpenTelemetryProvider implements TracerProvider {
|
|||
|
||||
static class PropagatorFactory {
|
||||
|
||||
public static TextMapPropagator getPropagator(PropagationConfig propagationConfig,
|
||||
@Nullable BaggageConfig baggageConfig,
|
||||
@Nullable OtelCurrentTraceContext currentTraceContext) {
|
||||
public static io.opentelemetry.context.propagation.TextMapPropagator getPropagator(PropagationConfig propagationConfig,
|
||||
@Nullable BaggageConfig baggageConfig,
|
||||
@Nullable OtelCurrentTraceContext currentTraceContext) {
|
||||
if (baggageConfig == null || !baggageConfig.getEnabled()) {
|
||||
return getPropagatorWithoutBaggage(propagationConfig);
|
||||
}
|
||||
return getPropagatorWithBaggage(propagationConfig, baggageConfig, currentTraceContext);
|
||||
}
|
||||
|
||||
private static TextMapPropagator getPropagatorWithoutBaggage(PropagationConfig propagationConfig) {
|
||||
private static io.opentelemetry.context.propagation.TextMapPropagator getPropagatorWithoutBaggage(PropagationConfig propagationConfig) {
|
||||
String type = propagationConfig.getType();
|
||||
if ("B3".equals(type)) {
|
||||
return B3Propagator.injectingSingleHeader();
|
||||
} else if ("W3C".equals(type)) {
|
||||
return W3CTraceContextPropagator.getInstance();
|
||||
PropagationType propagationType = PropagationType.forValue(type);
|
||||
|
||||
if (PropagationType.B3 == propagationType) {
|
||||
return io.opentelemetry.extension.trace.propagation.B3Propagator.injectingSingleHeader();
|
||||
} else if (PropagationType.W3C == propagationType) {
|
||||
return io.opentelemetry.api.trace.propagation.W3CTraceContextPropagator.getInstance();
|
||||
}
|
||||
return TextMapPropagator.noop();
|
||||
return io.opentelemetry.context.propagation.TextMapPropagator.noop();
|
||||
}
|
||||
|
||||
private static TextMapPropagator getPropagatorWithBaggage(PropagationConfig propagationConfig,
|
||||
BaggageConfig baggageConfig,
|
||||
OtelCurrentTraceContext currentTraceContext) {
|
||||
private static io.opentelemetry.context.propagation.TextMapPropagator getPropagatorWithBaggage(PropagationConfig propagationConfig,
|
||||
BaggageConfig baggageConfig,
|
||||
OtelCurrentTraceContext currentTraceContext) {
|
||||
String type = propagationConfig.getType();
|
||||
if ("B3".equals(type)) {
|
||||
PropagationType propagationType = PropagationType.forValue(type);
|
||||
if (PropagationType.B3 == propagationType) {
|
||||
List<String> remoteFields = baggageConfig.getRemoteFields();
|
||||
return TextMapPropagator.composite(B3Propagator.injectingSingleHeader(),
|
||||
return io.opentelemetry.context.propagation.TextMapPropagator.composite(io.opentelemetry.extension.trace.propagation.B3Propagator.injectingSingleHeader(),
|
||||
new BaggageTextMapPropagator(remoteFields,
|
||||
new OtelBaggageManager(currentTraceContext, remoteFields, Collections.emptyList())));
|
||||
} else if ("W3C".equals(type)) {
|
||||
} else if (PropagationType.W3C == propagationType) {
|
||||
List<String> remoteFields = baggageConfig.getRemoteFields();
|
||||
return TextMapPropagator.composite(W3CTraceContextPropagator.getInstance(),
|
||||
W3CBaggagePropagator.getInstance(), new BaggageTextMapPropagator(remoteFields,
|
||||
return io.opentelemetry.context.propagation.TextMapPropagator.composite(io.opentelemetry.api.trace.propagation.W3CTraceContextPropagator.getInstance(),
|
||||
io.opentelemetry.api.baggage.propagation.W3CBaggagePropagator.getInstance(), new BaggageTextMapPropagator(remoteFields,
|
||||
new OtelBaggageManager(currentTraceContext, remoteFields, Collections.emptyList())));
|
||||
}
|
||||
return TextMapPropagator.noop();
|
||||
return io.opentelemetry.context.propagation.TextMapPropagator.noop();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,23 @@
|
|||
/*
|
||||
* 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.tracing.utils;
|
||||
|
||||
public class ObservationConstants {
|
||||
|
||||
public static final String DEFAULT_APPLICATION_NAME = "dubbo-application";
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue