chore(project): 添加项目配置文件和忽略规则

- 添加 Babel 配置文件支持 ES6+ 语法转换
- 添加 ESLint 忽略规则和配置文件
- 添加 Git 忽略规则文件
- 添加 Travis CI 配置文件
- 添加 1.4.2 版本变更日志文件
- 添加 Helm 图表辅助模板文件
- 添加 Helm 忽略规则文件
This commit is contained in:
2026-03-27 17:36:48 +08:00
commit c2453d6434
1703 changed files with 277582 additions and 0 deletions

131
metrics/README.md Normal file
View 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
View 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>

View 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>

View 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>

View File

@@ -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();
}

View File

@@ -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();
}

View File

@@ -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();
}

View File

@@ -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();
}
}

View File

@@ -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";
}

View File

@@ -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;
}
}

View File

@@ -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();
}

View File

@@ -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();
}

View File

@@ -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();
}
}

View File

@@ -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();
}

View File

@@ -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);
}

View File

@@ -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();
}

View 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>

View File

@@ -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;
}
}

View File

@@ -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);
}
}
}

View File

@@ -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;
}
}

View File

@@ -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);
}
}
}

View 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>

View File

@@ -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();
}
}

View File

@@ -0,0 +1 @@
io.seata.metrics.exporter.prometheus.PrometheusExporter

View 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>

View File

@@ -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()));
}
}

View File

@@ -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()));
}
}

View File

@@ -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;
}
}

View File

@@ -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)));
}
}

View File

@@ -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));
}
}

View File

@@ -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);
}
}

View File

@@ -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);
}
}

View File

@@ -0,0 +1 @@
io.seata.metrics.registry.compact.CompactRegistry