chore(project): 添加项目配置文件和忽略规则
- 添加 Babel 配置文件支持 ES6+ 语法转换 - 添加 ESLint 忽略规则和配置文件 - 添加 Git 忽略规则文件 - 添加 Travis CI 配置文件 - 添加 1.4.2 版本变更日志文件 - 添加 Helm 图表辅助模板文件 - 添加 Helm 忽略规则文件
This commit is contained in:
131
metrics/README.md
Normal file
131
metrics/README.md
Normal file
@@ -0,0 +1,131 @@
|
||||
### Metrics
|
||||
#### 设计思路
|
||||
1. Seata作为一个被集成的数据一致性框架,Metrics模块将尽可能少的使用第三方依赖以降低发生冲突的风险;
|
||||
2. Metrics模块将竭力争取更高的度量性能和更低的资源开销,尽可能降低开启后带来的副作用;
|
||||
3. 配置式,Metrics是否激活、数据如何发布,取决于对应的配置;
|
||||
4. 不使用Spring,使用SPI(Service Provider Interface)加载扩展;
|
||||
5. 初始仅发布核心Transaction相关指标,之后结合社区的需求,逐步完善运维方面的所有其他指标。
|
||||
|
||||
#### 模块说明
|
||||
由2个核心API模块`seata-metrics-api`和`seata-metrics-core`,以及N个实现模块例如`seata-metrics-registry-compact`、`seata-metrics-exporter-prometheus`构成:
|
||||
|
||||
- seata-metrics-api模块
|
||||
|
||||
此模块是Metrics的核心,将作为Seata基础架构的一部分被TC、TM和RM引用,它内部**没有任何具体实现代码**,仅包含接口定义,定义的内容包括:
|
||||
1. Meter类接口:`Gauge`、`Counter`、`Timer`...
|
||||
2. 注册容器接口`Registry`
|
||||
3. Measurement数据导出接口`Exporter`
|
||||
|
||||
>提示:Metrics本身在开源领域也已有很多实现,例如
|
||||
>1. [Netflix-Spectator](https://github.com/Netflix/spectator)
|
||||
>2. [Dropwizard-Metrics](https://github.com/dropwizard/metrics)
|
||||
>3. [Dubbo-Metrics](https://github.com/dubbo/dubbo-metrics)
|
||||
|
||||
>它们有的轻而敏捷,有的重而强大,由于也是“实现”,因此不会纳入`seata-metrics-api`中,避免实现绑定。
|
||||
|
||||
- seata-metrics-core模块
|
||||
|
||||
Metrics核心模块,根据配置组织(加载)1个Registry和N个Exporter;
|
||||
|
||||
- seata-metrics-registry-compact模块
|
||||
|
||||
这是我们提供的默认(内置)的Registry实现,不使用其它Metrics开源库,轻量级的实现了以下四种Meter:
|
||||
|
||||
| Meter类型 | 描述 |
|
||||
| --------- | ------------------------------------------------------------ |
|
||||
| CompactGauge | 单一最新值度量器 |
|
||||
| CompactCounter | 单一累加度量器,可增可减 |
|
||||
| CompactSummary | 多Measurement输出计数器,将输出`total`(合计)、`count`(计数)、`max`(最大)、`average`(合计/计数)和`tps`(合计/时间间隔),无单位 |
|
||||
| CompactTimer | 多Measurement输出计时器,将输出`total`(合计)、`count`(计数)、`max`(最大)和`average`(合计/计数),支持微秒为单位累计 |
|
||||
|
||||
其中包含的Registry,即`CompactRegistry`,它只有接受measure()方法调用的时候才计算度量值,因此计算窗口完全取决于Exporter的实现,故目前不太适合需要多Exporter的场景使用(如何扩展请参见后文)。
|
||||
|
||||
>说明:
|
||||
>1. 未来可能增加更丰富复杂的度量器例如Histogram,这是一种可以本地统计聚合75th, 90th, 95th, 98th, 99th,99.9th...的度量器,适合某些场合,但需要更多内存。
|
||||
>2. 所有的计量器都将继承自Meter,所有的计量器执行measure()方法后,都将归一化的生成1或N个Measurement结果。
|
||||
|
||||
- seata-metrics-exporter-prometheus模块
|
||||
|
||||
Prometheus发布器`PrometheusExporter`,将度量数据同步给Prometheus。
|
||||
|
||||
>说明:不同的监控系统,采集度量数据的方式不尽相同,例如Zabbix支持用zabbix-agent推送,Prometheus则推荐使用prometheus-server[拉取](https://prometheus.io/docs/practices/pushing/)的方式;同样数据交换协议也不同,因此往往需要逐一适配。
|
||||
|
||||
#### 如何使用
|
||||
如果需要开启TC的Metrics,需要在其配置中增加配置项:
|
||||
```text
|
||||
## metrics settings
|
||||
metrics {
|
||||
registry-type = "compact"
|
||||
# multi exporters use comma divided
|
||||
exporter-list = "prometheus"
|
||||
exporter-prometheus-port = 9898
|
||||
}
|
||||
```
|
||||
|
||||
启动TC,即可在`http://tc-server-ip:9898/metrics`上获取到Metrics的文本格式数据。
|
||||
|
||||
>提示:默认使用`9898`端口,Prometheus已登记的端口列表[在此](https://github.com/prometheus/prometheus/wiki/Default-port-allocations),如果想更换端口,可通过`metrics.exporter-prometheus-port`配置修改。
|
||||
|
||||
##### 下载并启动Prometheus
|
||||
下载完毕后,修改Prometheus的配置文件`prometheus.yml`,在`scrape_configs`中增加一项抓取Seata的度量数据:
|
||||
```yaml
|
||||
scrape_configs:
|
||||
# The job name is added as a label `job=<job_name>` to any timeseries scraped from this config.
|
||||
- job_name: 'prometheus'
|
||||
|
||||
# metrics_path defaults to '/metrics'
|
||||
# scheme defaults to 'http'.
|
||||
|
||||
static_configs:
|
||||
- targets: ['localhost:9090']
|
||||
|
||||
- job_name: 'seata'
|
||||
|
||||
# metrics_path defaults to '/metrics'
|
||||
# scheme defaults to 'http'.
|
||||
|
||||
static_configs:
|
||||
- targets: ['tc-server-ip:9898']
|
||||
```
|
||||
|
||||
##### 查看数据输出
|
||||
推荐结合配置[Grafana](https://prometheus.io/docs/visualization/grafana/)获得更好的查询效果,初期Seata导出的Metrics包括:
|
||||
|
||||
- TC :
|
||||
|
||||
| Metrics | 描述 |
|
||||
| ------ | --------- |
|
||||
| seata.transaction(role=tc,meter=counter,status=active/committed/rollback) | 当前活动中/已提交/已回滚的事务总数 |
|
||||
| seata.transaction(role=tc,meter=summary,statistic=count,status=committed/rollback) | 当前周期内提交/回滚的事务数 |
|
||||
| seata.transaction(role=tc,meter=summary,statistic=tps,status=committed/rollback) | 当前周期内提交/回滚的事务TPS(transaction per second) |
|
||||
| seata.transaction(role=tc,meter=timer,statistic=total,status=committed/rollback) | 当前周期内提交/回滚的事务耗时总和 |
|
||||
| seata.transaction(role=tc,meter=timer,statistic=count,status=committed/rollback) | 当前周期内提交/回滚的事务数 |
|
||||
| seata.transaction(role=tc,meter=timer,statistic=average,status=committed/rollback) | 当前周期内提交/回滚的事务平均耗时 |
|
||||
| seata.transaction(role=tc,meter=timer,statistic=max,status=committed/rollback) | 当前周期内提交/回滚的事务最大耗时 |
|
||||
|
||||
>提示:seata.transaction(role=tc,meter=summary,statistic=count,status=committed/rollback)和seata.transaction(role=tc,meter=timer,statistic=count,status=committed/rollback)的值可能相同,但它们来源于两个不同的度量器。
|
||||
|
||||
- TM:
|
||||
|
||||
稍后实现,包括诸如:
|
||||
seata.transaction(role=tm,name={GlobalTransactionalName},meter=counter,status=active/committed/rollback) : 以GlobalTransactionalName为维度区分不同Transactional的状态。
|
||||
|
||||
- RM:
|
||||
|
||||
稍后实现,包括诸如:
|
||||
seata.transaction(role=rm,name={BranchTransactionalName},mode=at/mt,meter=counter,status=active/committed/rollback):以BranchTransactionalName为维度以及AT/MT维度区分不同分支Transactional的状态。
|
||||
|
||||
#### 如何扩展
|
||||
如果有下面几种情况:
|
||||
|
||||
1. 您不是使用Prometheus作为运维监控系统,但希望能够将Seata的Metrics数据集成进Dashboard中;
|
||||
|
||||
您需要实现新的Exporter,例如如果需要对接Zabbix,创建`seata-metrics-exporter-zabbix`模块,然后在ExporterType中添加新的Exporter类型,最后在`metrics.exporter-list`中配置。
|
||||
|
||||
2. 您需要更复杂强大的度量器类型,这些度量器在其他Metrics实现库中已有,希望集成这些第三方依赖直接使用;
|
||||
|
||||
您可以不使用内置的CompactRegistry的实现,完全扩展一个新的Registry库,例如希望使用Netflix Spectator的实现,扩展名为`seata-metrics-registry-spectator`的模块,然后在RegistryType中添加新的Registry类型,开发完成后,设置`metrics.registry-type`为对应的类型。
|
||||
|
||||
3. 您需要改变默认Metric的Measurement输出,例如在Timer中增加一个`min`或`sd`(方差);
|
||||
|
||||
您可以修改对应Meter的实现,包括`measure()`方法返回的Measurement列表。
|
||||
38
metrics/pom.xml
Normal file
38
metrics/pom.xml
Normal file
@@ -0,0 +1,38 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
~ Copyright 1999-2019 Seata.io Group.
|
||||
~
|
||||
~ Licensed under the Apache License, Version 2.0 (the "License");
|
||||
~ you may not use this file except in compliance with the License.
|
||||
~ You may obtain a copy of the License at
|
||||
~
|
||||
~ http://www.apache.org/licenses/LICENSE-2.0
|
||||
~
|
||||
~ Unless required by applicable law or agreed to in writing, software
|
||||
~ distributed under the License is distributed on an "AS IS" BASIS,
|
||||
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
~ See the License for the specific language governing permissions and
|
||||
~ limitations under the License.
|
||||
-->
|
||||
<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/xsd/maven-4.0.0.xsd">
|
||||
<parent>
|
||||
<groupId>io.seata</groupId>
|
||||
<artifactId>seata-parent</artifactId>
|
||||
<version>${revision}</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<packaging>pom</packaging>
|
||||
<artifactId>seata-metrics</artifactId>
|
||||
<name>seata-metrics ${project.version}</name>
|
||||
|
||||
<modules>
|
||||
<module>seata-metrics-all</module>
|
||||
<module>seata-metrics-api</module>
|
||||
<module>seata-metrics-core</module>
|
||||
<module>seata-metrics-registry-compact</module>
|
||||
<module>seata-metrics-exporter-prometheus</module>
|
||||
</modules>
|
||||
|
||||
</project>
|
||||
52
metrics/seata-metrics-all/pom.xml
Normal file
52
metrics/seata-metrics-all/pom.xml
Normal file
@@ -0,0 +1,52 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
~ Copyright 1999-2019 Seata.io Group.
|
||||
~
|
||||
~ Licensed under the Apache License, Version 2.0 (the "License");
|
||||
~ you may not use this file except in compliance with the License.
|
||||
~ You may obtain a copy of the License at
|
||||
~
|
||||
~ http://www.apache.org/licenses/LICENSE-2.0
|
||||
~
|
||||
~ Unless required by applicable law or agreed to in writing, software
|
||||
~ distributed under the License is distributed on an "AS IS" BASIS,
|
||||
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
~ See the License for the specific language governing permissions and
|
||||
~ limitations under the License.
|
||||
-->
|
||||
<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/xsd/maven-4.0.0.xsd">
|
||||
<parent>
|
||||
<artifactId>seata-metrics</artifactId>
|
||||
<groupId>io.seata</groupId>
|
||||
<version>${revision}</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<artifactId>seata-metrics-all</artifactId>
|
||||
<name>seata-metrics-all ${project.version}</name>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>${project.groupId}</groupId>
|
||||
<artifactId>seata-metrics-api</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>${project.groupId}</groupId>
|
||||
<artifactId>seata-metrics-core</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>${project.groupId}</groupId>
|
||||
<artifactId>seata-metrics-registry-compact</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>${project.groupId}</groupId>
|
||||
<artifactId>seata-metrics-exporter-prometheus</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
</project>
|
||||
29
metrics/seata-metrics-api/pom.xml
Normal file
29
metrics/seata-metrics-api/pom.xml
Normal file
@@ -0,0 +1,29 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
~ Copyright 1999-2019 Seata.io Group.
|
||||
~
|
||||
~ Licensed under the Apache License, Version 2.0 (the "License");
|
||||
~ you may not use this file except in compliance with the License.
|
||||
~ You may obtain a copy of the License at
|
||||
~
|
||||
~ http://www.apache.org/licenses/LICENSE-2.0
|
||||
~
|
||||
~ Unless required by applicable law or agreed to in writing, software
|
||||
~ distributed under the License is distributed on an "AS IS" BASIS,
|
||||
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
~ See the License for the specific language governing permissions and
|
||||
~ limitations under the License.
|
||||
-->
|
||||
<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/xsd/maven-4.0.0.xsd">
|
||||
<parent>
|
||||
<artifactId>seata-metrics</artifactId>
|
||||
<groupId>io.seata</groupId>
|
||||
<version>${revision}</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<artifactId>seata-metrics-api</artifactId>
|
||||
<name>seata-metrics-api ${project.version}</name>
|
||||
</project>
|
||||
@@ -0,0 +1,25 @@
|
||||
/*
|
||||
* Copyright 1999-2019 Seata.io Group.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package io.seata.metrics;
|
||||
|
||||
/**
|
||||
* Clock interface for metrics
|
||||
*
|
||||
* @author zhengyangyong
|
||||
*/
|
||||
public interface Clock {
|
||||
double getCurrentMilliseconds();
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
/*
|
||||
* Copyright 1999-2019 Seata.io Group.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package io.seata.metrics;
|
||||
|
||||
/**
|
||||
* Counter interface for metrics
|
||||
*
|
||||
* @author zhengyangyong
|
||||
*/
|
||||
public interface Counter extends Meter {
|
||||
long increase(long value);
|
||||
|
||||
long decrease(long value);
|
||||
|
||||
long get();
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
/*
|
||||
* Copyright 1999-2019 Seata.io Group.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package io.seata.metrics;
|
||||
|
||||
/**
|
||||
* Gauge interface for metrics
|
||||
*
|
||||
* @author zhengyangyong
|
||||
*/
|
||||
public interface Gauge<T extends Number> extends Meter {
|
||||
T get();
|
||||
}
|
||||
@@ -0,0 +1,86 @@
|
||||
/*
|
||||
* Copyright 1999-2019 Seata.io Group.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package io.seata.metrics;
|
||||
|
||||
import java.util.Map.Entry;
|
||||
import java.util.SortedMap;
|
||||
import java.util.TreeMap;
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
* Meter id
|
||||
*
|
||||
* @author zhengyangyong
|
||||
*/
|
||||
public class Id {
|
||||
private final UUID id;
|
||||
|
||||
private final String name;
|
||||
|
||||
private final SortedMap<String, String> tags;
|
||||
|
||||
public UUID getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public Iterable<Entry<String, String>> getTags() {
|
||||
return tags.entrySet();
|
||||
}
|
||||
|
||||
public int getTagCount() {
|
||||
return tags.size();
|
||||
}
|
||||
|
||||
public Id(String name) {
|
||||
this.id = UUID.randomUUID();
|
||||
this.name = name;
|
||||
this.tags = new TreeMap<>();
|
||||
}
|
||||
|
||||
public Id withTag(String name, String value) {
|
||||
this.tags.put(name, value);
|
||||
return this;
|
||||
}
|
||||
|
||||
public Id withTag(Iterable<Entry<String, String>> tags) {
|
||||
if (tags != null) {
|
||||
for (Entry<String, String> tag : tags) {
|
||||
this.tags.put(tag.getKey(), tag.getValue());
|
||||
}
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
StringBuilder builder = new StringBuilder(name);
|
||||
builder.append("(");
|
||||
if (tags.size() == 0) {
|
||||
builder.append(")");
|
||||
return builder.toString();
|
||||
}
|
||||
for (Entry<String, String> tag : tags.entrySet()) {
|
||||
builder.append(String.format("%s=%s,", tag.getKey(), tag.getValue()));
|
||||
}
|
||||
builder.delete(builder.length() - 1, builder.length());
|
||||
builder.append(")");
|
||||
return builder.toString();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,69 @@
|
||||
/*
|
||||
* Copyright 1999-2019 Seata.io Group.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package io.seata.metrics;
|
||||
|
||||
/**
|
||||
* Seata metrics constants for id
|
||||
*
|
||||
* @author zhengyangyong
|
||||
*/
|
||||
public interface IdConstants {
|
||||
String SEATA_TRANSACTION = "seata.transaction";
|
||||
|
||||
String APP_ID_KEY = "applicationId";
|
||||
|
||||
String GROUP_KEY = "group";
|
||||
|
||||
String NAME_KEY = "name";
|
||||
|
||||
String ROLE_KEY = "role";
|
||||
|
||||
String METER_KEY = "meter";
|
||||
|
||||
String STATISTIC_KEY = "statistic";
|
||||
|
||||
String STATUS_KEY = "status";
|
||||
|
||||
String ROLE_VALUE_TC = "tc";
|
||||
|
||||
String ROLE_VALUE_TM = "tm";
|
||||
|
||||
String ROLE_VALUE_RM = "rm";
|
||||
|
||||
String METER_VALUE_GAUGE = "gauge";
|
||||
|
||||
String METER_VALUE_COUNTER = "counter";
|
||||
|
||||
String METER_VALUE_SUMMARY = "summary";
|
||||
|
||||
String METER_VALUE_TIMER = "timer";
|
||||
|
||||
String STATISTIC_VALUE_COUNT = "count";
|
||||
|
||||
String STATISTIC_VALUE_TOTAL = "total";
|
||||
|
||||
String STATISTIC_VALUE_TPS = "tps";
|
||||
|
||||
String STATISTIC_VALUE_MAX = "max";
|
||||
|
||||
String STATISTIC_VALUE_AVERAGE = "average";
|
||||
|
||||
String STATUS_VALUE_ACTIVE = "active";
|
||||
|
||||
String STATUS_VALUE_COMMITTED = "committed";
|
||||
|
||||
String STATUS_VALUE_ROLLBACKED = "rollbacked";
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
/*
|
||||
* Copyright 1999-2019 Seata.io Group.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package io.seata.metrics;
|
||||
|
||||
/**
|
||||
* Value of meter
|
||||
*
|
||||
* @author zhengyangyong
|
||||
*/
|
||||
public class Measurement {
|
||||
private final Id id;
|
||||
|
||||
private final double timestamp;
|
||||
|
||||
private final double value;
|
||||
|
||||
public Id getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public double getTimestamp() {
|
||||
return timestamp;
|
||||
}
|
||||
|
||||
public double getValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
public Measurement(Id id, double timestamp, double value) {
|
||||
this.id = id;
|
||||
this.timestamp = timestamp;
|
||||
this.value = value;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
/*
|
||||
* Copyright 1999-2019 Seata.io Group.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package io.seata.metrics;
|
||||
|
||||
/**
|
||||
* Meter interface for metrics
|
||||
*
|
||||
* @author zhengyangyong
|
||||
*/
|
||||
public interface Meter {
|
||||
Id getId();
|
||||
|
||||
Iterable<Measurement> measure();
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
/*
|
||||
* Copyright 1999-2019 Seata.io Group.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package io.seata.metrics;
|
||||
|
||||
/**
|
||||
* Summary interface for metrics
|
||||
*
|
||||
* @author zhengyangyong
|
||||
*/
|
||||
public interface Summary extends Meter {
|
||||
default void increase() {
|
||||
increase(1);
|
||||
}
|
||||
|
||||
void increase(long value);
|
||||
|
||||
long total();
|
||||
|
||||
long count();
|
||||
|
||||
double tps();
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
/*
|
||||
* Copyright 1999-2019 Seata.io Group.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package io.seata.metrics;
|
||||
|
||||
/**
|
||||
* Default clock implement use system
|
||||
*
|
||||
* @author zhengyangyong
|
||||
*/
|
||||
public class SystemClock implements Clock {
|
||||
public static final Clock INSTANCE = new SystemClock();
|
||||
|
||||
@Override
|
||||
public double getCurrentMilliseconds() {
|
||||
return System.currentTimeMillis();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
/*
|
||||
* Copyright 1999-2019 Seata.io Group.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package io.seata.metrics;
|
||||
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
/**
|
||||
* Default clock implement use system
|
||||
*
|
||||
* @author zhengyangyong
|
||||
*/
|
||||
public interface Timer extends Meter {
|
||||
void record(long value, TimeUnit unit);
|
||||
|
||||
long count();
|
||||
|
||||
long total();
|
||||
|
||||
long max();
|
||||
|
||||
double average();
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
/*
|
||||
* Copyright 1999-2019 Seata.io Group.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package io.seata.metrics.exporter;
|
||||
|
||||
import java.io.Closeable;
|
||||
|
||||
import io.seata.metrics.registry.Registry;
|
||||
|
||||
/**
|
||||
* Exporter interface for metrics
|
||||
*
|
||||
* @author zhengyangyong
|
||||
*/
|
||||
public interface Exporter extends Closeable {
|
||||
void setRegistry(Registry registry);
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
/*
|
||||
* Copyright 1999-2019 Seata.io Group.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package io.seata.metrics.registry;
|
||||
|
||||
import java.util.function.Supplier;
|
||||
|
||||
import io.seata.metrics.Counter;
|
||||
import io.seata.metrics.Gauge;
|
||||
import io.seata.metrics.Id;
|
||||
import io.seata.metrics.Measurement;
|
||||
import io.seata.metrics.Summary;
|
||||
import io.seata.metrics.Timer;
|
||||
|
||||
/**
|
||||
* Registry interface for metrics
|
||||
*
|
||||
* @author zhengyangyong
|
||||
*/
|
||||
public interface Registry {
|
||||
<T extends Number> Gauge<T> getGauge(Id id, Supplier<T> supplier);
|
||||
|
||||
Counter getCounter(Id id);
|
||||
|
||||
Summary getSummary(Id id);
|
||||
|
||||
Timer getTimer(Id id);
|
||||
|
||||
Iterable<Measurement> measure();
|
||||
}
|
||||
43
metrics/seata-metrics-core/pom.xml
Normal file
43
metrics/seata-metrics-core/pom.xml
Normal file
@@ -0,0 +1,43 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
~ Copyright 1999-2019 Seata.io Group.
|
||||
~
|
||||
~ Licensed under the Apache License, Version 2.0 (the "License");
|
||||
~ you may not use this file except in compliance with the License.
|
||||
~ You may obtain a copy of the License at
|
||||
~
|
||||
~ http://www.apache.org/licenses/LICENSE-2.0
|
||||
~
|
||||
~ Unless required by applicable law or agreed to in writing, software
|
||||
~ distributed under the License is distributed on an "AS IS" BASIS,
|
||||
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
~ See the License for the specific language governing permissions and
|
||||
~ limitations under the License.
|
||||
-->
|
||||
<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/xsd/maven-4.0.0.xsd">
|
||||
<parent>
|
||||
<artifactId>seata-metrics</artifactId>
|
||||
<groupId>io.seata</groupId>
|
||||
<version>${revision}</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<artifactId>seata-metrics-core</artifactId>
|
||||
<name>seata-metrics-core ${project.version}</name>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>io.seata</groupId>
|
||||
<artifactId>seata-metrics-api</artifactId>
|
||||
<version>${project.parent.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>${project.groupId}</groupId>
|
||||
<artifactId>seata-core</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
</project>
|
||||
@@ -0,0 +1,56 @@
|
||||
/*
|
||||
* Copyright 1999-2019 Seata.io Group.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package io.seata.metrics.exporter;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
import io.seata.common.loader.EnhancedServiceLoader;
|
||||
import io.seata.common.util.StringUtils;
|
||||
import io.seata.config.ConfigurationFactory;
|
||||
import io.seata.core.constants.ConfigurationKeys;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
/**
|
||||
* Exporter Factory for load all configured exporters
|
||||
*
|
||||
* @author zhengyangyong
|
||||
*/
|
||||
public class ExporterFactory {
|
||||
private static final Logger LOGGER = LoggerFactory.getLogger(ExporterFactory.class);
|
||||
|
||||
public static List<Exporter> getInstanceList() {
|
||||
List<Exporter> exporters = new ArrayList<>();
|
||||
String exporterTypeNameList = ConfigurationFactory.getInstance().getConfig(
|
||||
ConfigurationKeys.METRICS_PREFIX + ConfigurationKeys.METRICS_EXPORTER_LIST, null);
|
||||
if (!StringUtils.isNullOrEmpty(exporterTypeNameList)) {
|
||||
String[] exporterTypeNames = exporterTypeNameList.split(",");
|
||||
for (String exporterTypeName : exporterTypeNames) {
|
||||
ExporterType exporterType;
|
||||
try {
|
||||
exporterType = ExporterType.getType(exporterTypeName);
|
||||
exporters.add(
|
||||
EnhancedServiceLoader.load(Exporter.class, Objects.requireNonNull(exporterType).getName()));
|
||||
} catch (Exception exx) {
|
||||
LOGGER.error("not support metrics exporter type: {}",exporterTypeName, exx);
|
||||
}
|
||||
}
|
||||
}
|
||||
return exporters;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
/*
|
||||
* Copyright 1999-2019 Seata.io Group.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package io.seata.metrics.exporter;
|
||||
|
||||
/**
|
||||
* Supported metrics exporter type
|
||||
*
|
||||
* @author zhengyangyong
|
||||
*/
|
||||
public enum ExporterType {
|
||||
/**
|
||||
* Export metrics data to Prometheus
|
||||
*/
|
||||
PROMETHEUS("prometheus");
|
||||
|
||||
private String name;
|
||||
|
||||
ExporterType(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public static ExporterType getType(String name) {
|
||||
if (PROMETHEUS.name().equalsIgnoreCase(name)) {
|
||||
return PROMETHEUS;
|
||||
} else {
|
||||
throw new IllegalArgumentException("not support exporter type: " + name);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
/*
|
||||
* Copyright 1999-2019 Seata.io Group.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package io.seata.metrics.registry;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
import io.seata.common.exception.NotSupportYetException;
|
||||
import io.seata.common.loader.EnhancedServiceLoader;
|
||||
import io.seata.common.util.StringUtils;
|
||||
import io.seata.config.ConfigurationFactory;
|
||||
import io.seata.core.constants.ConfigurationKeys;
|
||||
|
||||
/**
|
||||
* Registry Factory for load configured metrics registry
|
||||
*
|
||||
* @author zhengyangyong
|
||||
*/
|
||||
public class RegistryFactory {
|
||||
public static Registry getInstance() {
|
||||
RegistryType registryType;
|
||||
String registryTypeName = ConfigurationFactory.getInstance().getConfig(
|
||||
ConfigurationKeys.METRICS_PREFIX + ConfigurationKeys.METRICS_REGISTRY_TYPE, null);
|
||||
if (!StringUtils.isNullOrEmpty(registryTypeName)) {
|
||||
try {
|
||||
registryType = RegistryType.getType(registryTypeName);
|
||||
} catch (Exception exx) {
|
||||
throw new NotSupportYetException("not support metrics registry type: " + registryTypeName);
|
||||
}
|
||||
return EnhancedServiceLoader.load(Registry.class, Objects.requireNonNull(registryType).getName());
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
/*
|
||||
* Copyright 1999-2019 Seata.io Group.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package io.seata.metrics.registry;
|
||||
|
||||
/**
|
||||
* Supported metrics registry type
|
||||
*
|
||||
* @author zhengyangyong
|
||||
*/
|
||||
public enum RegistryType {
|
||||
/**
|
||||
* Built-in compact metrics registry
|
||||
*/
|
||||
COMPACT("compact");
|
||||
|
||||
private String name;
|
||||
|
||||
RegistryType(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public static RegistryType getType(String name) {
|
||||
if (COMPACT.name().equalsIgnoreCase(name)) {
|
||||
return COMPACT;
|
||||
} else {
|
||||
throw new IllegalArgumentException("not support registry type: " + name);
|
||||
}
|
||||
}
|
||||
}
|
||||
54
metrics/seata-metrics-exporter-prometheus/pom.xml
Normal file
54
metrics/seata-metrics-exporter-prometheus/pom.xml
Normal file
@@ -0,0 +1,54 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
~ Copyright 1999-2019 Seata.io Group.
|
||||
~
|
||||
~ Licensed under the Apache License, Version 2.0 (the "License");
|
||||
~ you may not use this file except in compliance with the License.
|
||||
~ You may obtain a copy of the License at
|
||||
~
|
||||
~ http://www.apache.org/licenses/LICENSE-2.0
|
||||
~
|
||||
~ Unless required by applicable law or agreed to in writing, software
|
||||
~ distributed under the License is distributed on an "AS IS" BASIS,
|
||||
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
~ See the License for the specific language governing permissions and
|
||||
~ limitations under the License.
|
||||
-->
|
||||
<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/xsd/maven-4.0.0.xsd">
|
||||
<parent>
|
||||
<artifactId>seata-metrics</artifactId>
|
||||
<groupId>io.seata</groupId>
|
||||
<version>${revision}</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<artifactId>seata-metrics-exporter-prometheus</artifactId>
|
||||
<name>seata-metrics-exporter-prometheus ${project.version}</name>
|
||||
|
||||
<properties>
|
||||
<prometheus.client.version>0.6.0</prometheus.client.version>
|
||||
</properties>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>${project.groupId}</groupId>
|
||||
<artifactId>seata-metrics-api</artifactId>
|
||||
<version>${project.parent.version}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>${project.groupId}</groupId>
|
||||
<artifactId>seata-core</artifactId>
|
||||
<version>${project.parent.version}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.prometheus</groupId>
|
||||
<artifactId>simpleclient_httpserver</artifactId>
|
||||
<version>${prometheus.client.version}</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
</project>
|
||||
@@ -0,0 +1,96 @@
|
||||
/*
|
||||
* Copyright 1999-2019 Seata.io Group.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package io.seata.metrics.exporter.prometheus;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map.Entry;
|
||||
|
||||
import io.prometheus.client.Collector;
|
||||
import io.prometheus.client.Collector.MetricFamilySamples.Sample;
|
||||
import io.prometheus.client.exporter.HTTPServer;
|
||||
import io.seata.common.loader.LoadLevel;
|
||||
import io.seata.config.ConfigurationFactory;
|
||||
import io.seata.core.constants.ConfigurationKeys;
|
||||
import io.seata.metrics.Measurement;
|
||||
import io.seata.metrics.exporter.Exporter;
|
||||
import io.seata.metrics.registry.Registry;
|
||||
|
||||
import static io.seata.core.constants.ConfigurationKeys.METRICS_EXPORTER_PROMETHEUS_PORT;
|
||||
|
||||
/**
|
||||
* Exporter for Prometheus
|
||||
*
|
||||
* @author zhengyangyong
|
||||
*/
|
||||
@LoadLevel(name = "prometheus", order = 1)
|
||||
public class PrometheusExporter extends Collector implements Collector.Describable, Exporter {
|
||||
|
||||
private final HTTPServer server;
|
||||
|
||||
private Registry registry;
|
||||
|
||||
public PrometheusExporter() throws IOException {
|
||||
int port = ConfigurationFactory.getInstance().getInt(
|
||||
ConfigurationKeys.METRICS_PREFIX + METRICS_EXPORTER_PROMETHEUS_PORT, 9898);
|
||||
this.server = new HTTPServer(port, true);
|
||||
this.register();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setRegistry(Registry registry) {
|
||||
this.registry = registry;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<MetricFamilySamples> collect() {
|
||||
List<MetricFamilySamples> familySamples = new ArrayList<>();
|
||||
if (registry != null) {
|
||||
Iterable<Measurement> measurements = registry.measure();
|
||||
List<Sample> samples = new ArrayList<>();
|
||||
measurements.forEach(measurement -> samples.add(convertMeasurementToSample(measurement)));
|
||||
|
||||
if (!samples.isEmpty()) {
|
||||
familySamples.add(new MetricFamilySamples("seata", Type.UNTYPED, "seata", samples));
|
||||
}
|
||||
}
|
||||
return familySamples;
|
||||
}
|
||||
|
||||
private Sample convertMeasurementToSample(Measurement measurement) {
|
||||
String prometheusName = measurement.getId().getName().replace(".", "_");
|
||||
List<String> labelNames = new ArrayList<>();
|
||||
List<String> labelValues = new ArrayList<>();
|
||||
for (Entry<String, String> tag : measurement.getId().getTags()) {
|
||||
labelNames.add(tag.getKey());
|
||||
labelValues.add(tag.getValue());
|
||||
}
|
||||
return new Sample(prometheusName, labelNames, labelValues, measurement.getValue(),
|
||||
(long)measurement.getTimestamp());
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<MetricFamilySamples> describe() {
|
||||
return collect();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() {
|
||||
server.stop();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
io.seata.metrics.exporter.prometheus.PrometheusExporter
|
||||
43
metrics/seata-metrics-registry-compact/pom.xml
Normal file
43
metrics/seata-metrics-registry-compact/pom.xml
Normal file
@@ -0,0 +1,43 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
~ Copyright 1999-2019 Seata.io Group.
|
||||
~
|
||||
~ Licensed under the Apache License, Version 2.0 (the "License");
|
||||
~ you may not use this file except in compliance with the License.
|
||||
~ You may obtain a copy of the License at
|
||||
~
|
||||
~ http://www.apache.org/licenses/LICENSE-2.0
|
||||
~
|
||||
~ Unless required by applicable law or agreed to in writing, software
|
||||
~ distributed under the License is distributed on an "AS IS" BASIS,
|
||||
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
~ See the License for the specific language governing permissions and
|
||||
~ limitations under the License.
|
||||
-->
|
||||
<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/xsd/maven-4.0.0.xsd">
|
||||
<parent>
|
||||
<artifactId>seata-metrics</artifactId>
|
||||
<groupId>io.seata</groupId>
|
||||
<version>${revision}</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<artifactId>seata-metrics-registry-compact</artifactId>
|
||||
<name>seata-metrics-registry-compact ${project.version}</name>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>io.seata</groupId>
|
||||
<artifactId>seata-metrics-api</artifactId>
|
||||
<version>${project.parent.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>io.seata</groupId>
|
||||
<artifactId>seata-common</artifactId>
|
||||
<version>${project.parent.version}</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
</project>
|
||||
@@ -0,0 +1,73 @@
|
||||
/*
|
||||
* Copyright 1999-2019 Seata.io Group.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package io.seata.metrics.registry.compact;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.concurrent.atomic.AtomicLong;
|
||||
|
||||
import io.seata.metrics.Clock;
|
||||
import io.seata.metrics.Counter;
|
||||
import io.seata.metrics.Id;
|
||||
import io.seata.metrics.Measurement;
|
||||
import io.seata.metrics.SystemClock;
|
||||
|
||||
/**
|
||||
* Compact Counter implement with AtomicLong
|
||||
*
|
||||
* @author zhengyangyong
|
||||
*/
|
||||
public class CompactCounter implements Counter {
|
||||
private final Id id;
|
||||
|
||||
private final AtomicLong counter;
|
||||
|
||||
private final Clock clock;
|
||||
|
||||
public CompactCounter(Id id) {
|
||||
this(id, SystemClock.INSTANCE);
|
||||
}
|
||||
|
||||
public CompactCounter(Id id, Clock clock) {
|
||||
this.id = id;
|
||||
this.counter = new AtomicLong(0);
|
||||
this.clock = clock;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Id getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long increase(long value) {
|
||||
return counter.addAndGet(value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public long decrease(long value) {
|
||||
return increase(-1 * value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public long get() {
|
||||
return counter.get();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterable<Measurement> measure() {
|
||||
return Collections.singletonList(new Measurement(id, clock.getCurrentMilliseconds(), counter.get()));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,63 @@
|
||||
/*
|
||||
* Copyright 1999-2019 Seata.io Group.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package io.seata.metrics.registry.compact;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
import io.seata.metrics.Clock;
|
||||
import io.seata.metrics.Gauge;
|
||||
import io.seata.metrics.Id;
|
||||
import io.seata.metrics.Measurement;
|
||||
import io.seata.metrics.SystemClock;
|
||||
|
||||
/**
|
||||
* Compact Gauge implement with Supplier
|
||||
*
|
||||
* @author zhengyangyong
|
||||
*/
|
||||
public class CompactGauge<T extends Number> implements Gauge<T> {
|
||||
private final Id id;
|
||||
|
||||
private final Supplier<T> supplier;
|
||||
|
||||
private final Clock clock;
|
||||
|
||||
public CompactGauge(Id id, Supplier<T> supplier) {
|
||||
this(id, supplier, SystemClock.INSTANCE);
|
||||
}
|
||||
|
||||
public CompactGauge(Id id, Supplier<T> supplier, Clock clock) {
|
||||
this.id = id;
|
||||
this.supplier = supplier;
|
||||
this.clock = clock;
|
||||
}
|
||||
|
||||
@Override
|
||||
public T get() {
|
||||
return supplier.get();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Id getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterable<Measurement> measure() {
|
||||
return Collections.singletonList(new Measurement(id, clock.getCurrentMilliseconds(), get().doubleValue()));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,75 @@
|
||||
/*
|
||||
* Copyright 1999-2019 Seata.io Group.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package io.seata.metrics.registry.compact;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
import io.seata.common.loader.LoadLevel;
|
||||
import io.seata.common.util.CollectionUtils;
|
||||
import io.seata.metrics.Counter;
|
||||
import io.seata.metrics.Gauge;
|
||||
import io.seata.metrics.Id;
|
||||
import io.seata.metrics.Measurement;
|
||||
import io.seata.metrics.Meter;
|
||||
import io.seata.metrics.registry.Registry;
|
||||
import io.seata.metrics.Summary;
|
||||
import io.seata.metrics.Timer;
|
||||
|
||||
/**
|
||||
* Compact Registry implement, this registry only compute all Measurements when call measure method and do not cache
|
||||
*
|
||||
* @author zhengyangyong
|
||||
*/
|
||||
@LoadLevel(name = "compact", order = 1)
|
||||
public class CompactRegistry implements Registry {
|
||||
private static final Map<UUID, Meter> METERS = new ConcurrentHashMap<>();
|
||||
|
||||
@Override
|
||||
public <T extends Number> Gauge<T> getGauge(Id id, Supplier<T> supplier) {
|
||||
return (Gauge<T>)CollectionUtils.computeIfAbsent(METERS, id.getId(), key -> new CompactGauge<>(id, supplier));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Counter getCounter(Id id) {
|
||||
return (Counter)CollectionUtils.computeIfAbsent(METERS, id.getId(), key -> new CompactCounter(id));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Summary getSummary(Id id) {
|
||||
return (Summary)CollectionUtils.computeIfAbsent(METERS, id.getId(), key -> new CompactSummary(id));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Timer getTimer(Id id) {
|
||||
return (Timer)CollectionUtils.computeIfAbsent(METERS, id.getId(), key -> new CompactTimer(id));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterable<Measurement> measure() {
|
||||
final List<Measurement> measurements = new ArrayList<>();
|
||||
if (METERS.isEmpty()) {
|
||||
return measurements;
|
||||
}
|
||||
METERS.values().iterator()
|
||||
.forEachRemaining(meter -> meter.measure().forEach(measurements::add));
|
||||
return measurements;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,95 @@
|
||||
/*
|
||||
* Copyright 1999-2019 Seata.io Group.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package io.seata.metrics.registry.compact;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
import io.seata.metrics.Clock;
|
||||
import io.seata.metrics.Id;
|
||||
import io.seata.metrics.Measurement;
|
||||
import io.seata.metrics.Summary;
|
||||
import io.seata.metrics.SystemClock;
|
||||
import io.seata.metrics.IdConstants;
|
||||
|
||||
/**
|
||||
* Compact Summary implement with SummaryValue
|
||||
*
|
||||
* @author zhengyangyong
|
||||
*/
|
||||
public class CompactSummary implements Summary {
|
||||
private final Id id;
|
||||
|
||||
private final Id countId;
|
||||
|
||||
private final Id totalId;
|
||||
|
||||
private final Id tpsId;
|
||||
|
||||
private volatile SummaryValue value;
|
||||
|
||||
private final Clock clock;
|
||||
|
||||
public CompactSummary(Id id) {
|
||||
this(id, SystemClock.INSTANCE);
|
||||
}
|
||||
|
||||
public CompactSummary(Id id, Clock clock) {
|
||||
this.id = id;
|
||||
this.countId = new Id(id.getName()).withTag(id.getTags())
|
||||
.withTag(IdConstants.STATISTIC_KEY, IdConstants.STATISTIC_VALUE_COUNT);
|
||||
this.totalId = new Id(id.getName()).withTag(id.getTags())
|
||||
.withTag(IdConstants.STATISTIC_KEY, IdConstants.STATISTIC_VALUE_TOTAL);
|
||||
this.tpsId = new Id(id.getName()).withTag(id.getTags())
|
||||
.withTag(IdConstants.STATISTIC_KEY, IdConstants.STATISTIC_VALUE_TPS);
|
||||
this.value = new SummaryValue(clock.getCurrentMilliseconds());
|
||||
this.clock = clock;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Id getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void increase(long value) {
|
||||
this.value.increase(value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public long total() {
|
||||
return this.value.getTotal();
|
||||
}
|
||||
|
||||
@Override
|
||||
public long count() {
|
||||
return this.value.getCount();
|
||||
}
|
||||
|
||||
@Override
|
||||
public double tps() {
|
||||
return this.value.getTps(clock.getCurrentMilliseconds());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterable<Measurement> measure() {
|
||||
SummaryValue value = this.value;
|
||||
double time = clock.getCurrentMilliseconds();
|
||||
this.value = new SummaryValue(time);
|
||||
return Arrays.asList(new Measurement(countId, time, value.getCount()),
|
||||
new Measurement(totalId, time, value.getTotal()),
|
||||
new Measurement(tpsId, time, value.getTps(time)));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,107 @@
|
||||
/*
|
||||
* Copyright 1999-2019 Seata.io Group.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package io.seata.metrics.registry.compact;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import io.seata.metrics.Clock;
|
||||
import io.seata.metrics.Id;
|
||||
import io.seata.metrics.Measurement;
|
||||
import io.seata.metrics.SystemClock;
|
||||
import io.seata.metrics.Timer;
|
||||
import io.seata.metrics.IdConstants;
|
||||
|
||||
/**
|
||||
* Compact Timer implement with TimerValue
|
||||
*
|
||||
* @author zhengyangyong
|
||||
*/
|
||||
public class CompactTimer implements Timer {
|
||||
private final Id id;
|
||||
|
||||
private final Id countId;
|
||||
|
||||
private final Id totalId;
|
||||
|
||||
private final Id maxId;
|
||||
|
||||
private final Id averageId;
|
||||
|
||||
private volatile TimerValue value;
|
||||
|
||||
private final Clock clock;
|
||||
|
||||
public CompactTimer(Id id) {
|
||||
this(id, SystemClock.INSTANCE);
|
||||
}
|
||||
|
||||
public CompactTimer(Id id, Clock clock) {
|
||||
this.id = id;
|
||||
this.countId = new Id(id.getName()).withTag(id.getTags())
|
||||
.withTag(IdConstants.STATISTIC_KEY, IdConstants.STATISTIC_VALUE_COUNT);
|
||||
this.totalId = new Id(id.getName()).withTag(id.getTags())
|
||||
.withTag(IdConstants.STATISTIC_KEY, IdConstants.STATISTIC_VALUE_TOTAL);
|
||||
this.maxId = new Id(id.getName()).withTag(id.getTags())
|
||||
.withTag(IdConstants.STATISTIC_KEY, IdConstants.STATISTIC_VALUE_MAX);
|
||||
this.averageId = new Id(id.getName()).withTag(id.getTags())
|
||||
.withTag(IdConstants.STATISTIC_KEY, IdConstants.STATISTIC_VALUE_AVERAGE);
|
||||
this.value = new TimerValue();
|
||||
this.clock = clock;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Id getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void record(long value, TimeUnit unit) {
|
||||
this.value.record(value, unit);
|
||||
}
|
||||
|
||||
@Override
|
||||
public long count() {
|
||||
return this.value.getCount();
|
||||
}
|
||||
|
||||
@Override
|
||||
public long total() {
|
||||
return this.value.getTotal();
|
||||
}
|
||||
|
||||
@Override
|
||||
public long max() {
|
||||
return this.value.getMax();
|
||||
}
|
||||
|
||||
@Override
|
||||
public double average() {
|
||||
return this.value.getAverage();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterable<Measurement> measure() {
|
||||
//reset value when measure
|
||||
double time = clock.getCurrentMilliseconds();
|
||||
TimerValue value = this.value;
|
||||
this.value = new TimerValue();
|
||||
return Arrays.asList(new Measurement(countId, time, value.getCount()),
|
||||
new Measurement(totalId, time, value.getTotal() * 0.001),
|
||||
new Measurement(maxId, time, value.getMax() * 0.001),
|
||||
new Measurement(averageId, time, value.getAverage() * 0.001));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,64 @@
|
||||
/*
|
||||
* Copyright 1999-2019 Seata.io Group.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package io.seata.metrics.registry.compact;
|
||||
|
||||
import java.util.concurrent.atomic.LongAdder;
|
||||
|
||||
/**
|
||||
* Record container for CompactSummary
|
||||
*
|
||||
* @author zhengyangyong
|
||||
*/
|
||||
public class SummaryValue {
|
||||
private final LongAdder count;
|
||||
|
||||
private final LongAdder total;
|
||||
|
||||
private final double startMilliseconds;
|
||||
|
||||
public long getCount() {
|
||||
return count.longValue();
|
||||
}
|
||||
|
||||
public long getTotal() {
|
||||
return total.longValue();
|
||||
}
|
||||
|
||||
public double getTps(double currentMilliseconds) {
|
||||
if (currentMilliseconds <= startMilliseconds) {
|
||||
return 0;
|
||||
}
|
||||
return total.doubleValue() / (currentMilliseconds - startMilliseconds) * 1000.0;
|
||||
}
|
||||
|
||||
public SummaryValue(double startMilliseconds) {
|
||||
this.count = new LongAdder();
|
||||
this.total = new LongAdder();
|
||||
this.startMilliseconds = startMilliseconds;
|
||||
}
|
||||
|
||||
public void increase() {
|
||||
this.increase(1);
|
||||
}
|
||||
|
||||
public void increase(long value) {
|
||||
if (value < 0) {
|
||||
return;
|
||||
}
|
||||
this.count.increment();
|
||||
this.total.add(value);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,67 @@
|
||||
/*
|
||||
* Copyright 1999-2019 Seata.io Group.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package io.seata.metrics.registry.compact;
|
||||
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.atomic.AtomicLong;
|
||||
import java.util.concurrent.atomic.LongAdder;
|
||||
|
||||
/**
|
||||
* Record container for CompactTimer
|
||||
*
|
||||
* @author zhengyangyong
|
||||
*/
|
||||
public class TimerValue {
|
||||
private final LongAdder count;
|
||||
|
||||
private final LongAdder total;
|
||||
|
||||
private final AtomicLong max;
|
||||
|
||||
public long getCount() {
|
||||
return count.longValue();
|
||||
}
|
||||
|
||||
public long getTotal() {
|
||||
return total.longValue();
|
||||
}
|
||||
|
||||
public long getMax() {
|
||||
return max.get();
|
||||
}
|
||||
|
||||
public double getAverage() {
|
||||
double count = this.count.doubleValue();
|
||||
double total = this.total.doubleValue();
|
||||
return count == 0 ? 0 : total / count;
|
||||
}
|
||||
|
||||
public TimerValue() {
|
||||
this.count = new LongAdder();
|
||||
this.total = new LongAdder();
|
||||
this.max = new AtomicLong(0);
|
||||
}
|
||||
|
||||
public void record(long value, TimeUnit unit) {
|
||||
if (value < 0) {
|
||||
return;
|
||||
}
|
||||
long changeValue = unit == TimeUnit.MICROSECONDS ? value : TimeUnit.MICROSECONDS.convert(value, unit);
|
||||
this.count.increment();
|
||||
this.total.add(changeValue);
|
||||
this.max.accumulateAndGet(changeValue, Math::max);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
io.seata.metrics.registry.compact.CompactRegistry
|
||||
Reference in New Issue
Block a user