mirror of
https://github.com/didi/KnowStreaming.git
synced 2025-12-24 20:22:12 +08:00
Compare commits
46 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f8ca797f16 | ||
|
|
ff78a9cc35 | ||
|
|
3fea5c9c8c | ||
|
|
aea63cad52 | ||
|
|
800abe9920 | ||
|
|
dd6069e41a | ||
|
|
90d31aeff0 | ||
|
|
4d9a327b1f | ||
|
|
06a97ef076 | ||
|
|
76c2477387 | ||
|
|
bc4dac9cad | ||
|
|
36e3d6c18a | ||
|
|
edfd84a8e3 | ||
|
|
fb20cf6069 | ||
|
|
abbe47f6b9 | ||
|
|
f84d250134 | ||
|
|
3ffb4b8990 | ||
|
|
f70cfabede | ||
|
|
3a81783d77 | ||
|
|
237a4a90ff | ||
|
|
99c7dfc98d | ||
|
|
48aba34370 | ||
|
|
29cca36f2c | ||
|
|
0f5819f5c2 | ||
|
|
373772de2d | ||
|
|
7f5bbe8b5f | ||
|
|
daee57167b | ||
|
|
03467196b9 | ||
|
|
d3f3531cdb | ||
|
|
883b694592 | ||
|
|
6c89d66af9 | ||
|
|
fb0a76b418 | ||
|
|
64f77fca5b | ||
|
|
b1fca2c5be | ||
|
|
108d705f09 | ||
|
|
a77242e66c | ||
|
|
8b153113ff | ||
|
|
6d0ec37135 | ||
|
|
603dadff35 | ||
|
|
1a4ef3d9c1 | ||
|
|
788468054a | ||
|
|
bdb44c6dce | ||
|
|
251086f9e9 | ||
|
|
b22aa62046 | ||
|
|
c6e4b60424 | ||
|
|
28d985aaf1 |
16
.gitignore
vendored
16
.gitignore
vendored
@@ -56,6 +56,7 @@ fabric.properties
|
||||
*.jar
|
||||
*.war
|
||||
*.ear
|
||||
*.tar.gz
|
||||
|
||||
# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
|
||||
hs_err_pid*
|
||||
@@ -99,13 +100,14 @@ target/
|
||||
*/velocity.log*
|
||||
*/*.log
|
||||
*/*.log.*
|
||||
web/node_modules/
|
||||
web/node_modules/*
|
||||
node_modules/
|
||||
node_modules/*
|
||||
workspace.xml
|
||||
/output/*
|
||||
.gitversion
|
||||
*/node_modules/*
|
||||
web/src/main/resources/templates/*
|
||||
*/out/*
|
||||
*/dist/*
|
||||
.DS_Store
|
||||
node_modules/*
|
||||
out/*
|
||||
dist/
|
||||
dist/*
|
||||
kafka-manager-web/src/main/resources/templates/
|
||||
.DS_Store
|
||||
|
||||
@@ -1,7 +0,0 @@
|
||||
FROM fabric8/java-alpine-openjdk8-jdk
|
||||
MAINTAINER xuzhengxi
|
||||
ENV LANG=C.UTF-8 LC_ALL=C.UTF-8
|
||||
ADD ./web/target/kafka-manager-web-1.1.0-SNAPSHOT.jar kafka-manager-web.jar
|
||||
ADD ./docker/kafka-manager/application-standalone.yml application.yml
|
||||
ENTRYPOINT ["java","-jar","/kafka-manager-web.jar","--spring.config.location=./application.yml"]
|
||||
EXPOSE 8080
|
||||
97
README.md
97
README.md
@@ -1,7 +1,7 @@
|
||||
|
||||
---
|
||||
|
||||

|
||||

|
||||
|
||||
**一站式`Apache Kafka`集群指标监控与运维管控平台**
|
||||
|
||||
@@ -12,110 +12,39 @@
|
||||
|
||||
### 集群监控维度
|
||||
|
||||
- 多版本集群管控,支持从`0.10.2`到`2.4`版本;
|
||||
- 多版本集群管控,支持从`0.10.2`到`2.x`版本;
|
||||
- 集群Topic、Broker等多维度历史与实时关键指标查看;
|
||||
|
||||
|
||||
### 集群管控维度
|
||||
|
||||
- 集群运维,包括逻辑Region方式管理集群;
|
||||
- Broker运维,包括优先副本选举;
|
||||
- 集群运维,包括逻辑Region方式管理集群
|
||||
- Broker运维,包括优先副本选举
|
||||
- Topic运维,包括创建、查询、扩容、修改属性、数据采样及迁移等;
|
||||
- 消费组运维,包括指定时间或指定偏移两种方式进行重置消费偏移;
|
||||
- 消费组运维,包括指定时间或指定偏移两种方式进行重置消费偏移
|
||||
|
||||
|
||||
### 用户使用维度
|
||||
|
||||
- 管理员用户与普通用户视角区分;
|
||||
- 管理员用户与普通用户权限区分;
|
||||
- Kafka用户、Kafka研发、Kafka运维 视角区分
|
||||
- Kafka用户、Kafka研发、Kafka运维 权限区分
|
||||
|
||||
---
|
||||
|
||||
## kafka-manager架构图
|
||||
|
||||

|
||||

|
||||
|
||||
|
||||
---
|
||||
|
||||
## 安装手册
|
||||
|
||||
### 环境依赖
|
||||
|
||||
- `Maven 3.5.0+`(后端打包依赖)
|
||||
- `node v8.12.0+`(前端打包依赖)
|
||||
- `Java 8+`(运行环境需要)
|
||||
- `MySQL` 或 `PostgreSQL`(数据存储)
|
||||
|
||||
---
|
||||
|
||||
### 环境初始化
|
||||
|
||||
**MySQL**
|
||||
|
||||
执行[create_mysql_table.sql](doc/create_mysql_table.sql)中的SQL命令,从而创建所需的MySQL库及表,默认创建的库名是`kafka_manager`。
|
||||
|
||||
```
|
||||
############# 示例:
|
||||
mysql -uXXXX -pXXX -h XXX.XXX.XXX.XXX -PXXXX < ./create_mysql_table.sql
|
||||
```
|
||||
|
||||
**PostgreSQL**
|
||||
|
||||
执行[create_postgresql_table.sql](doc/create_postgresql_table.sql)中的SQL命令,从而创建所需的PostgreSQL表。
|
||||
|
||||
```
|
||||
############# 示例:
|
||||
psql -h XXX.XXX.XXX.XXX -U XXXX -d kafka_manager -f ./create_postgresql_table.sql
|
||||
```
|
||||
|
||||
*PostgreSQL 用户、数据库创建方式*
|
||||
|
||||
```sql
|
||||
create user admin encrypted password 'admin';
|
||||
create database kafka_manager owner=admin template=template0 encoding='UTF-8' lc_collate='zh_CN.UTF-8' lc_ctype='zh_CN.UTF-8';
|
||||
```
|
||||
|
||||
***默认配置使用 MySQL 数据库,若要使用 PostgreSQL 数据库,使用 `-Dspring.profiles.active=pg` 指定 `application-pg.yml` 配置文件。***
|
||||
|
||||
---
|
||||
|
||||
|
||||
### 打包
|
||||
|
||||
执行`mvn install`命令即可。
|
||||
|
||||
备注:每一次执行`mvn install`命令,都将在`web/src/main/resources/templates`下面生成最新的前端资源文件,如果`console`模块下的代码没有变更,可以修改`./pom.xml`文件,忽略对`console`模块的打包。
|
||||
|
||||
---
|
||||
|
||||
### 启动
|
||||
|
||||
```
|
||||
############# application.yml 是配置文件
|
||||
cp web/src/main/resources/application.yml web/target/
|
||||
cd web/target/
|
||||
nohup java -jar kafka-manager-web-1.1.0-SNAPSHOT.jar --spring.config.location=./application.yml > /dev/null 2>&1 &
|
||||
```
|
||||
|
||||
### 使用
|
||||
|
||||
本地启动的话,访问`http://localhost:8080`,输入帐号及密码进行登录。更多参考:[kafka-manager使用手册](doc/user_cn_guide.md)
|
||||
|
||||
|
||||
---
|
||||
|
||||
## 相关文档
|
||||
|
||||
- [kafka-manager使用手册](doc/user_cn_guide.md)
|
||||
|
||||
- [kafka-manager 安装手册](docs/install_guide/install_guide_cn.md)
|
||||
- [kafka-manager 接入集群](docs/user_guide/add_cluster/add_cluster.md)
|
||||
- [kafka-manager 用户使用手册](docs/user_guide/user_guide_cn.md)
|
||||
- [kafka-manager FAQ](docs/user_guide/faq.md)
|
||||
|
||||
## 钉钉交流群
|
||||
|
||||
搜索群号:`32821440` 或者扫码可入群交流. 备注:在钉钉搜索框搜索`32821440`,然后搜索结果中点击 "网络查找手机/邮箱/钉钉号" 即可看到我们的钉钉群:滴滴KafkaManager开源用户群。
|
||||
|
||||
|
||||

|
||||

|
||||
|
||||
|
||||
## 项目成员
|
||||
|
||||
91
build.sh
Normal file
91
build.sh
Normal file
@@ -0,0 +1,91 @@
|
||||
#!/bin/bash
|
||||
workspace=$(cd $(dirname $0) && pwd -P)
|
||||
cd $workspace
|
||||
|
||||
## constant
|
||||
app_name=kafka-manager
|
||||
output_dir=output
|
||||
|
||||
gitversion=.gitversion
|
||||
control=./control.sh
|
||||
create_mysql_table=./docs/install_guide/create_mysql_table.sql
|
||||
app_config_file=./kafka-manager-web/src/main/resources/application.yml
|
||||
|
||||
## function
|
||||
function build() {
|
||||
# 进行编译
|
||||
# # cmd 设置使用的JDK, 按需选择, 默认已安装了JDK 8
|
||||
# JVERSION=`java -version 2>&1 | awk 'NR==1{gsub(/"/,"");print $3}'`
|
||||
# major=`echo $JVERSION | awk -F. '{print $1}'`
|
||||
# mijor=`echo $JVERSION | awk -F. '{print $2}'`
|
||||
# if [ $major -le 1 ] && [ $mijor -lt 8 ]; then
|
||||
# export JAVA_HOME=/usr/local/jdk1.8.0_65 #(使用jdk8请设置)
|
||||
# export PATH=$JAVA_HOME/bin:$PATH
|
||||
# fi
|
||||
|
||||
# 编译命令
|
||||
mvn -U clean package -Dmaven.test.skip=true
|
||||
|
||||
local sc=$?
|
||||
if [ $sc -ne 0 ];then
|
||||
## 编译失败, 退出码为 非0
|
||||
echo "$app_name build error"
|
||||
exit $sc
|
||||
else
|
||||
echo -n "$app_name build ok, vsn="`gitversion`
|
||||
fi
|
||||
}
|
||||
|
||||
function make_output() {
|
||||
# 新建output目录
|
||||
rm -rf $output_dir &>/dev/null
|
||||
mkdir -p $output_dir &>/dev/null
|
||||
|
||||
# 填充output目录, output内的内容 即为 线上部署内容
|
||||
(
|
||||
# cp -rf $control $output_dir && # 拷贝 control.sh 脚本 至output目录
|
||||
cp -rf $create_mysql_table $output_dir && # 拷贝 sql 初始化脚本 至output目录
|
||||
cp -rf $app_config_file $output_dir && # 拷贝 application.yml 至output目录
|
||||
|
||||
# 拷贝程序包到output路径
|
||||
cp kafka-manager-web/target/${app_name}-*-SNAPSHOT.jar ${output_dir}/${app_name}.jar
|
||||
echo -e "make output ok."
|
||||
) || { echo -e "make output error"; exit 2; } # 填充output目录失败后, 退出码为 非0
|
||||
}
|
||||
|
||||
function make_package() {
|
||||
# 压缩output目录
|
||||
(
|
||||
tar cvzf ${app_name}.tar.gz ${output_dir}
|
||||
echo -e "make package ok."
|
||||
) || { echo -e "make package error"; exit 2; } # 压缩output目录失败后, 退出码为 非0
|
||||
}
|
||||
|
||||
## internals
|
||||
function gitversion() {
|
||||
git log -1 --pretty=%h > $gitversion
|
||||
local gv=`cat $gitversion`
|
||||
echo "$gv"
|
||||
}
|
||||
|
||||
|
||||
##########################################
|
||||
## main
|
||||
## 其中,
|
||||
## 1.进行编译
|
||||
## 2.生成部署包output
|
||||
## 3.生成tar.gz压缩包
|
||||
##########################################
|
||||
|
||||
# 1.进行编译
|
||||
build
|
||||
|
||||
# 2.生成部署包output
|
||||
make_output
|
||||
|
||||
# 3.生成tar.gz压缩包
|
||||
make_package
|
||||
|
||||
# 编译成功
|
||||
echo -e "build done"
|
||||
exit 0
|
||||
@@ -1,21 +0,0 @@
|
||||
package com.xiaojukeji.kafka.manager.common.constant;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
/**
|
||||
* @author zengqiao
|
||||
* @date 20/2/28
|
||||
*/
|
||||
public class Constant {
|
||||
public static final String KAFKA_MANAGER_INNER_ERROR = "kafka-manager inner error";
|
||||
|
||||
public final static Map<Integer, List<String>> BROKER_METRICS_TYPE_MBEAN_NAME_MAP = new ConcurrentHashMap<>();
|
||||
|
||||
public final static Map<Integer, List<String>> TOPIC_METRICS_TYPE_MBEAN_NAME_MAP = new ConcurrentHashMap<>();
|
||||
|
||||
public static final String COLLECTOR_METRICS_LOGGER = "COLLECTOR_METRICS_LOGGER";
|
||||
|
||||
public static final String API_METRICS_LOGGER = "API_METRICS_LOGGER";
|
||||
}
|
||||
@@ -1,23 +0,0 @@
|
||||
package com.xiaojukeji.kafka.manager.common.constant;
|
||||
|
||||
public class MetricsType {
|
||||
/**
|
||||
* Broker流量详情
|
||||
*/
|
||||
public static final int BROKER_FLOW_DETAIL = 0;
|
||||
public static final int BROKER_TO_DB_METRICS = 1; // Broker入DB的Metrics指标
|
||||
public static final int BROKER_REAL_TIME_METRICS = 2; // Broker入DB的Metrics指标
|
||||
public static final int BROKER_OVER_VIEW_METRICS = 3; // Broker状态概览的指标
|
||||
public static final int BROKER_OVER_ALL_METRICS = 4; // Broker状态总揽的指标
|
||||
public static final int BROKER_ANALYSIS_METRICS = 5; // Broker分析的指标
|
||||
public static final int BROKER_TOPIC_ANALYSIS_METRICS = 6; // Broker分析的指标
|
||||
|
||||
/**
|
||||
* Topic流量详情
|
||||
*/
|
||||
public static final int TOPIC_FLOW_DETAIL = 100;
|
||||
public static final int TOPIC_FLOW_OVERVIEW = 101;
|
||||
public static final int TOPIC_METRICS_TO_DB = 102;
|
||||
|
||||
|
||||
}
|
||||
@@ -1,35 +0,0 @@
|
||||
package com.xiaojukeji.kafka.manager.common.constant;
|
||||
|
||||
/**
|
||||
* @author limeng
|
||||
* @date 2017/11/21
|
||||
*/
|
||||
public enum OffsetStoreLocation {
|
||||
|
||||
ZOOKEEPER("zookeeper"),
|
||||
|
||||
BROKER("broker");
|
||||
|
||||
private final String location;
|
||||
|
||||
OffsetStoreLocation(String location) {
|
||||
this.location = location;
|
||||
}
|
||||
|
||||
public String getLocation() {
|
||||
return location;
|
||||
}
|
||||
|
||||
public static OffsetStoreLocation getOffsetStoreLocation(String location) {
|
||||
if (location == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
for (OffsetStoreLocation offsetStoreLocation: OffsetStoreLocation.values()) {
|
||||
if (offsetStoreLocation.location.equals(location)) {
|
||||
return offsetStoreLocation;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -1,35 +0,0 @@
|
||||
package com.xiaojukeji.kafka.manager.common.constant;
|
||||
|
||||
public class StatusCode {
|
||||
/*
|
||||
* kafka-manager status code: 17000 ~ 17999
|
||||
*
|
||||
* 正常 - 0
|
||||
* 参数错误 - 10000
|
||||
* 资源未就绪 - 10001
|
||||
*/
|
||||
|
||||
/*
|
||||
* 已约定的状态码
|
||||
*/
|
||||
public static final Integer SUCCESS = 0;
|
||||
public static final Integer PARAM_ERROR = 10000; //参数错误
|
||||
public static final Integer RES_UNREADY = 10001; //资源未就绪
|
||||
|
||||
public static final Integer MY_SQL_SELECT_ERROR = 17210; // MySQL 查询数据异常
|
||||
public static final Integer MY_SQL_INSERT_ERROR = 17211; // MySQL 插入数据异常
|
||||
public static final Integer MY_SQL_DELETE_ERROR = 17212; // MySQL 删除数据异常
|
||||
public static final Integer MY_SQL_UPDATE_ERROR = 17213; // MySQL 更新数据异常
|
||||
public static final Integer MY_SQL_REPLACE_ERROR = 17214; // MySQL 替换数据异常
|
||||
|
||||
public static final Integer OPERATION_ERROR = 17300; // 请求操作异常
|
||||
|
||||
|
||||
/**
|
||||
* Topic相关的异常
|
||||
*/
|
||||
public static final Integer TOPIC_EXISTED = 17400; //Topic已经存在了
|
||||
|
||||
public static final Integer PARTIAL_SUCESS = 17700; //操作部分成功
|
||||
|
||||
}
|
||||
@@ -1,71 +0,0 @@
|
||||
package com.xiaojukeji.kafka.manager.common.constant.monitor;
|
||||
|
||||
import java.util.AbstractMap;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 条件类型
|
||||
* @author zengqiao
|
||||
* @date 19/5/12
|
||||
*/
|
||||
public enum MonitorConditionType {
|
||||
BIGGER(">", "大于"),
|
||||
EQUAL("=", "等于"),
|
||||
LESS("<", "小于"),
|
||||
NOT_EQUAL("!=", "不等于");
|
||||
|
||||
private String name;
|
||||
|
||||
private String message;
|
||||
|
||||
MonitorConditionType(String name, String message) {
|
||||
this.name = name;
|
||||
this.message = message;
|
||||
}
|
||||
|
||||
public static boolean legal(String name) {
|
||||
for (MonitorConditionType elem: MonitorConditionType.values()) {
|
||||
if (elem.name.equals(name)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "ConditionType{" +
|
||||
"name='" + name + '\'' +
|
||||
", message='" + message + '\'' +
|
||||
'}';
|
||||
}
|
||||
|
||||
public static List<AbstractMap.SimpleEntry<String, String>> toList() {
|
||||
List<AbstractMap.SimpleEntry<String, String>> conditionTypeList = new ArrayList<>();
|
||||
for (MonitorConditionType elem: MonitorConditionType.values()) {
|
||||
conditionTypeList.add(new AbstractMap.SimpleEntry<>(elem.name, elem.message));
|
||||
}
|
||||
return conditionTypeList;
|
||||
}
|
||||
|
||||
/**
|
||||
* 计算 operation(data1, data2) 是否为true
|
||||
* @param data1
|
||||
* @param data2
|
||||
* @param operation
|
||||
* @author zengqiao
|
||||
* @date 19/5/12
|
||||
* @return boolean
|
||||
*/
|
||||
public static boolean matchCondition(Double data1, Double data2, String operation) {
|
||||
switch (operation) {
|
||||
case ">": return data1 > data2;
|
||||
case "<": return data1 < data2;
|
||||
case "=": return data1.equals(data2);
|
||||
case "!=": return !data1.equals(data2);
|
||||
default:
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -1,19 +0,0 @@
|
||||
package com.xiaojukeji.kafka.manager.common.constant.monitor;
|
||||
|
||||
/**
|
||||
* @author zengqiao
|
||||
* @date 20/3/18
|
||||
*/
|
||||
public enum MonitorMatchStatus {
|
||||
UNKNOWN(0),
|
||||
|
||||
YES(1),
|
||||
|
||||
NO(2);
|
||||
|
||||
public Integer status;
|
||||
|
||||
MonitorMatchStatus(Integer status) {
|
||||
this.status = status;
|
||||
}
|
||||
}
|
||||
@@ -1,59 +0,0 @@
|
||||
package com.xiaojukeji.kafka.manager.common.constant.monitor;
|
||||
|
||||
import java.util.AbstractMap;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 指标类型
|
||||
* @author zengqiao
|
||||
* @date 19/5/12
|
||||
*/
|
||||
public enum MonitorMetricsType {
|
||||
BYTES_IN("BytesIn", "流入流量"),
|
||||
BYTES_OUT("BytesOut", "流出流量"),
|
||||
LAG("Lag", "消费组Lag");
|
||||
|
||||
private String name;
|
||||
|
||||
private String message;
|
||||
|
||||
MonitorMetricsType(String name, String message) {
|
||||
this.name = name;
|
||||
this.message = message;
|
||||
}
|
||||
|
||||
public static boolean legal(String name) {
|
||||
for (MonitorMetricsType elem: MonitorMetricsType.values()) {
|
||||
if (elem.name.equals(name)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "MetricType{" +
|
||||
"name='" + name + '\'' +
|
||||
", message='" + message + '\'' +
|
||||
'}';
|
||||
}
|
||||
|
||||
public static List<AbstractMap.SimpleEntry<String, String>> toList() {
|
||||
List<AbstractMap.SimpleEntry<String, String>> metricTypeList = new ArrayList<>();
|
||||
for (MonitorMetricsType elem: MonitorMetricsType.values()) {
|
||||
metricTypeList.add(new AbstractMap.SimpleEntry<>(elem.name, elem.message));
|
||||
}
|
||||
return metricTypeList;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public String getMessage() {
|
||||
return message;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,56 +0,0 @@
|
||||
package com.xiaojukeji.kafka.manager.common.constant.monitor;
|
||||
|
||||
import java.util.AbstractMap;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 通知类型
|
||||
* @author huangyiminghappy@163.com
|
||||
* @date 2019-05-06
|
||||
*/
|
||||
public enum MonitorNotifyType {
|
||||
KAFKA_MESSAGE("KAFKA", "告警发送到KAFKA");
|
||||
|
||||
String name;
|
||||
|
||||
String message;
|
||||
|
||||
MonitorNotifyType(String name, String message){
|
||||
this.name = name;
|
||||
this.message = message;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public String getMessage() {
|
||||
return message;
|
||||
}
|
||||
|
||||
public static boolean legal(String name) {
|
||||
for (MonitorNotifyType elem: MonitorNotifyType.values()) {
|
||||
if (elem.name.equals(name)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "NotifyType{" +
|
||||
"name='" + name + '\'' +
|
||||
", message='" + message + '\'' +
|
||||
'}';
|
||||
}
|
||||
|
||||
public static List<AbstractMap.SimpleEntry<String, String>> toList() {
|
||||
List<AbstractMap.SimpleEntry<String, String>> notifyTypeList = new ArrayList<>();
|
||||
for (MonitorNotifyType elem: MonitorNotifyType.values()) {
|
||||
notifyTypeList.add(new AbstractMap.SimpleEntry<>(elem.name, elem.message));
|
||||
}
|
||||
return notifyTypeList;
|
||||
}
|
||||
}
|
||||
@@ -1,69 +0,0 @@
|
||||
package com.xiaojukeji.kafka.manager.common.entity;
|
||||
|
||||
/**
|
||||
* ConsumerMetrics
|
||||
* @author tukun
|
||||
* @date 2015/11/12
|
||||
*/
|
||||
public class ConsumerMetrics {
|
||||
private Long clusterId;
|
||||
|
||||
private String topicName;
|
||||
|
||||
private String consumerGroup;
|
||||
|
||||
private String location;
|
||||
|
||||
private Long sumLag;
|
||||
|
||||
public Long getClusterId() {
|
||||
return clusterId;
|
||||
}
|
||||
|
||||
public void setClusterId(Long clusterId) {
|
||||
this.clusterId = clusterId;
|
||||
}
|
||||
|
||||
public String getTopicName() {
|
||||
return topicName;
|
||||
}
|
||||
|
||||
public void setTopicName(String topicName) {
|
||||
this.topicName = topicName;
|
||||
}
|
||||
|
||||
public String getConsumerGroup() {
|
||||
return consumerGroup;
|
||||
}
|
||||
|
||||
public void setConsumerGroup(String consumerGroup) {
|
||||
this.consumerGroup = consumerGroup;
|
||||
}
|
||||
|
||||
public String getLocation() {
|
||||
return location;
|
||||
}
|
||||
|
||||
public void setLocation(String location) {
|
||||
this.location = location;
|
||||
}
|
||||
|
||||
public Long getSumLag() {
|
||||
return sumLag;
|
||||
}
|
||||
|
||||
public void setSumLag(Long sumLag) {
|
||||
this.sumLag = sumLag;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "ConsumerMetrics{" +
|
||||
"clusterId=" + clusterId +
|
||||
", topicName='" + topicName + '\'' +
|
||||
", consumerGroup='" + consumerGroup + '\'' +
|
||||
", location='" + location + '\'' +
|
||||
", sumLag=" + sumLag +
|
||||
'}';
|
||||
}
|
||||
}
|
||||
@@ -1,76 +0,0 @@
|
||||
package com.xiaojukeji.kafka.manager.common.entity;
|
||||
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import com.xiaojukeji.kafka.manager.common.constant.StatusCode;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
* @author huangyiminghappy@163.com
|
||||
* @date 2019-07-08
|
||||
*/
|
||||
public class Result<T> implements Serializable {
|
||||
private static final long serialVersionUID = -2772975319944108658L;
|
||||
|
||||
private T data;
|
||||
private String message;
|
||||
private Integer code;
|
||||
|
||||
public Result(T data) {
|
||||
this.data = data;
|
||||
this.code = StatusCode.SUCCESS;
|
||||
this.message = "成功";
|
||||
}
|
||||
|
||||
public Result() {
|
||||
this(null);
|
||||
}
|
||||
|
||||
public Result(Integer code, String message) {
|
||||
this.message = message;
|
||||
this.code = code;
|
||||
}
|
||||
|
||||
public Result(Integer code, T data, String message) {
|
||||
this.data = data;
|
||||
this.message = message;
|
||||
this.code = code;
|
||||
}
|
||||
|
||||
|
||||
public T getData()
|
||||
{
|
||||
return (T)this.data;
|
||||
}
|
||||
|
||||
public void setData(T data)
|
||||
{
|
||||
this.data = data;
|
||||
}
|
||||
|
||||
public String getMessage()
|
||||
{
|
||||
return this.message;
|
||||
}
|
||||
|
||||
public void setMessage(String message)
|
||||
{
|
||||
this.message = message;
|
||||
}
|
||||
|
||||
public Integer getCode()
|
||||
{
|
||||
return this.code;
|
||||
}
|
||||
|
||||
public void setCode(Integer code)
|
||||
{
|
||||
this.code = code;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString()
|
||||
{
|
||||
return JSON.toJSONString(this);
|
||||
}
|
||||
}
|
||||
@@ -1,24 +0,0 @@
|
||||
package com.xiaojukeji.kafka.manager.common.entity.annotations;
|
||||
|
||||
import java.lang.annotation.Documented;
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
import static java.lang.annotation.RetentionPolicy.RUNTIME;
|
||||
|
||||
/**
|
||||
* FieldSelector
|
||||
* @author huangyiminghappy@163.com
|
||||
* @date 2019-06-19
|
||||
*/
|
||||
@Target(ElementType.FIELD)
|
||||
@Retention(RUNTIME)
|
||||
@Documented
|
||||
public @interface FieldSelector {
|
||||
//注解的属性
|
||||
String name() default "";
|
||||
|
||||
int[] types() default {};
|
||||
|
||||
}
|
||||
@@ -1,35 +0,0 @@
|
||||
package com.xiaojukeji.kafka.manager.common.entity.bizenum;
|
||||
|
||||
/**
|
||||
* 用户角色
|
||||
* @author zengqiao_cn@163.com
|
||||
* @date 19/4/15
|
||||
*/
|
||||
public enum AccountRoleEnum {
|
||||
UNKNOWN(-1),
|
||||
|
||||
NORMAL(0),
|
||||
|
||||
SRE(1),
|
||||
|
||||
ADMIN(2);
|
||||
|
||||
private Integer role;
|
||||
|
||||
AccountRoleEnum(Integer role) {
|
||||
this.role = role;
|
||||
}
|
||||
|
||||
public Integer getRole() {
|
||||
return role;
|
||||
}
|
||||
|
||||
public static AccountRoleEnum getUserRoleEnum(Integer role) {
|
||||
for (AccountRoleEnum elem: AccountRoleEnum.values()) {
|
||||
if (elem.getRole().equals(role)) {
|
||||
return elem;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -1,38 +0,0 @@
|
||||
package com.xiaojukeji.kafka.manager.common.entity.bizenum;
|
||||
|
||||
/**
|
||||
* 操作Topic的状态
|
||||
* @author zengqiao
|
||||
* @date 19/11/26
|
||||
*/
|
||||
public enum AdminTopicStatusEnum {
|
||||
SUCCESS(0, "成功"),
|
||||
REPLACE_DB_FAILED(1, "更新DB失败"),
|
||||
PARAM_NULL_POINTER(2, "参数错误"),
|
||||
PARTITION_NUM_ILLEGAL(3, "分区数错误"),
|
||||
BROKER_NUM_NOT_ENOUGH(4, "Broker数不足错误"),
|
||||
TOPIC_NAME_ILLEGAL(5, "Topic名称非法"),
|
||||
TOPIC_EXISTED(6, "Topic已存在"),
|
||||
UNKNOWN_TOPIC_PARTITION(7, "Topic未知"),
|
||||
TOPIC_CONFIG_ILLEGAL(8, "Topic配置错误"),
|
||||
TOPIC_IN_DELETING(9, "Topic正在删除"),
|
||||
UNKNOWN_ERROR(10, "未知错误");
|
||||
|
||||
private Integer code;
|
||||
|
||||
private String message;
|
||||
|
||||
AdminTopicStatusEnum(Integer code, String message) {
|
||||
this.code = code;
|
||||
this.message = message;
|
||||
}
|
||||
|
||||
public Integer getCode() {
|
||||
return code;
|
||||
}
|
||||
|
||||
public String getMessage() {
|
||||
return message;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,42 +0,0 @@
|
||||
package com.xiaojukeji.kafka.manager.common.entity.bizenum;
|
||||
|
||||
/**
|
||||
* DBStatus状态含义
|
||||
* @author zengqiao_cn@163.com
|
||||
* @date 19/4/15
|
||||
*/
|
||||
public enum DBStatusEnum {
|
||||
/**
|
||||
* 逻辑删除
|
||||
*/
|
||||
DELETED(-1),
|
||||
|
||||
/**
|
||||
* 普通
|
||||
*/
|
||||
NORMAL(0),
|
||||
|
||||
/**
|
||||
* 已完成并通过
|
||||
*/
|
||||
PASSED(1);
|
||||
|
||||
private Integer status;
|
||||
|
||||
DBStatusEnum(Integer status) {
|
||||
this.status = status;
|
||||
}
|
||||
|
||||
public Integer getStatus() {
|
||||
return status;
|
||||
}
|
||||
|
||||
public static DBStatusEnum getDBStatusEnum(Integer status) {
|
||||
for (DBStatusEnum elem: DBStatusEnum.values()) {
|
||||
if (elem.getStatus().equals(status)) {
|
||||
return elem;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -1,19 +0,0 @@
|
||||
package com.xiaojukeji.kafka.manager.common.entity.bizenum;
|
||||
|
||||
/**
|
||||
* 操作类型
|
||||
* @author zengqiao
|
||||
* @date 19/11/21
|
||||
*/
|
||||
public enum OperationEnum {
|
||||
CREATE_TOPIC("create_topic"),
|
||||
DELETE_TOPIC("delete_topic"),
|
||||
MODIFY_TOPIC_CONFIG("modify_topic_config"),
|
||||
EXPAND_TOPIC_PARTITION("expand_topic_partition");
|
||||
|
||||
public String message;
|
||||
|
||||
OperationEnum(String message) {
|
||||
this.message = message;
|
||||
}
|
||||
}
|
||||
@@ -1,33 +0,0 @@
|
||||
package com.xiaojukeji.kafka.manager.common.entity.bizenum;
|
||||
|
||||
/**
|
||||
* 工单类型
|
||||
* @author zengqiao
|
||||
* @date 19/6/23
|
||||
*/
|
||||
public enum OrderTypeEnum {
|
||||
UNKNOWN(-1),
|
||||
|
||||
APPLY_TOPIC(0),
|
||||
|
||||
APPLY_PARTITION(1);
|
||||
|
||||
private Integer code;
|
||||
|
||||
OrderTypeEnum(Integer code) {
|
||||
this.code = code;
|
||||
}
|
||||
|
||||
public Integer getCode() {
|
||||
return code;
|
||||
}
|
||||
|
||||
public static OrderTypeEnum getOrderTypeEnum(Integer code) {
|
||||
for (OrderTypeEnum elem: OrderTypeEnum.values()) {
|
||||
if (elem.getCode().equals(code)) {
|
||||
return elem;
|
||||
}
|
||||
}
|
||||
return OrderTypeEnum.UNKNOWN;
|
||||
}
|
||||
}
|
||||
@@ -1,31 +0,0 @@
|
||||
package com.xiaojukeji.kafka.manager.common.entity.bizenum;
|
||||
|
||||
/**
|
||||
* 优先副本选举状态
|
||||
* @author zengqiao
|
||||
* @date 2017/6/29.
|
||||
*/
|
||||
public enum PreferredReplicaElectEnum {
|
||||
SUCCESS(0, "成功[创建成功|执行成功]"),
|
||||
RUNNING(1, "正在执行"),
|
||||
ALREADY_EXIST(2, "任务已存在"),
|
||||
PARAM_ILLEGAL(3, "参数错误"),
|
||||
UNKNOWN(4, "进度未知");
|
||||
|
||||
private Integer code;
|
||||
|
||||
private String message;
|
||||
|
||||
PreferredReplicaElectEnum(Integer code, String message) {
|
||||
this.code = code;
|
||||
this.message = message;
|
||||
}
|
||||
|
||||
public Integer getCode() {
|
||||
return code;
|
||||
}
|
||||
|
||||
public String getMessage() {
|
||||
return message;
|
||||
}
|
||||
}
|
||||
@@ -1,45 +0,0 @@
|
||||
package com.xiaojukeji.kafka.manager.common.entity.bizenum;
|
||||
|
||||
/**
|
||||
* 迁移状态
|
||||
* @author zengqiao
|
||||
* @date 19/12/29
|
||||
*/
|
||||
public enum ReassignmentStatusEnum {
|
||||
WAITING(0, "等待执行"),
|
||||
RUNNING(1, "正在执行"),
|
||||
SUCCESS(2, "迁移成功"),
|
||||
FAILED(3, "迁移失败"),
|
||||
CANCELED(4, "取消任务");
|
||||
|
||||
private Integer code;
|
||||
|
||||
private String message;
|
||||
|
||||
ReassignmentStatusEnum(Integer code, String message) {
|
||||
this.code = code;
|
||||
this.message = message;
|
||||
}
|
||||
|
||||
public Integer getCode() {
|
||||
return code;
|
||||
}
|
||||
|
||||
public String getMessage() {
|
||||
return message;
|
||||
}
|
||||
|
||||
public static boolean triggerTask(Integer status) {
|
||||
if (WAITING.code.equals(status) || RUNNING.code.equals(status)) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public static boolean cancelTask(Integer status) {
|
||||
if (WAITING.code.equals(status)) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -1,132 +0,0 @@
|
||||
package com.xiaojukeji.kafka.manager.common.entity.dto;
|
||||
|
||||
import com.xiaojukeji.kafka.manager.common.entity.metrics.BrokerMetrics;
|
||||
import com.xiaojukeji.kafka.manager.common.entity.zookeeper.BrokerMetadata;
|
||||
|
||||
/**
|
||||
* @author zengqiao
|
||||
* @date 19/4/21
|
||||
*/
|
||||
public class BrokerOverallDTO {
|
||||
private Integer brokerId;
|
||||
|
||||
private String host;
|
||||
|
||||
private Integer port;
|
||||
|
||||
private Integer jmxPort;
|
||||
|
||||
private Long startTime;
|
||||
|
||||
private Integer partitionCount;
|
||||
|
||||
private Integer underReplicatedPartitions;
|
||||
|
||||
private Integer leaderCount;
|
||||
|
||||
private Double bytesInPerSec;
|
||||
|
||||
public Integer getBrokerId() {
|
||||
return brokerId;
|
||||
}
|
||||
|
||||
public void setBrokerId(Integer brokerId) {
|
||||
this.brokerId = brokerId;
|
||||
}
|
||||
|
||||
public String getHost() {
|
||||
return host;
|
||||
}
|
||||
|
||||
public void setHost(String host) {
|
||||
this.host = host;
|
||||
}
|
||||
|
||||
public Integer getPort() {
|
||||
return port;
|
||||
}
|
||||
|
||||
public void setPort(Integer port) {
|
||||
this.port = port;
|
||||
}
|
||||
|
||||
public Integer getJmxPort() {
|
||||
return jmxPort;
|
||||
}
|
||||
|
||||
public void setJmxPort(Integer jmxPort) {
|
||||
this.jmxPort = jmxPort;
|
||||
}
|
||||
|
||||
public Long getStartTime() {
|
||||
return startTime;
|
||||
}
|
||||
|
||||
public void setStartTime(Long startTime) {
|
||||
this.startTime = startTime;
|
||||
}
|
||||
|
||||
public Integer getPartitionCount() {
|
||||
return partitionCount;
|
||||
}
|
||||
|
||||
public void setPartitionCount(Integer partitionCount) {
|
||||
this.partitionCount = partitionCount;
|
||||
}
|
||||
|
||||
public Integer getUnderReplicatedPartitions() {
|
||||
return underReplicatedPartitions;
|
||||
}
|
||||
|
||||
public void setUnderReplicatedPartitions(Integer underReplicatedPartitions) {
|
||||
this.underReplicatedPartitions = underReplicatedPartitions;
|
||||
}
|
||||
|
||||
public Integer getLeaderCount() {
|
||||
return leaderCount;
|
||||
}
|
||||
|
||||
public void setLeaderCount(Integer leaderCount) {
|
||||
this.leaderCount = leaderCount;
|
||||
}
|
||||
|
||||
public Double getBytesInPerSec() {
|
||||
return bytesInPerSec;
|
||||
}
|
||||
|
||||
public void setBytesInPerSec(Double bytesInPerSec) {
|
||||
this.bytesInPerSec = bytesInPerSec;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "BrokerOverallDTO{" +
|
||||
"brokerId=" + brokerId +
|
||||
", host='" + host + '\'' +
|
||||
", port=" + port +
|
||||
", jmxPort=" + jmxPort +
|
||||
", startTime=" + startTime +
|
||||
", partitionCount=" + partitionCount +
|
||||
", underReplicatedPartitions=" + underReplicatedPartitions +
|
||||
", leaderCount=" + leaderCount +
|
||||
", bytesInPerSec=" + bytesInPerSec +
|
||||
'}';
|
||||
}
|
||||
|
||||
public static BrokerOverallDTO newInstance(BrokerMetadata brokerMetadata, BrokerMetrics brokerMetrics) {
|
||||
BrokerOverallDTO brokerOverallDTO = new BrokerOverallDTO();
|
||||
brokerOverallDTO.setBrokerId(brokerMetadata.getBrokerId());
|
||||
brokerOverallDTO.setHost(brokerMetadata.getHost());
|
||||
brokerOverallDTO.setPort(brokerMetadata.getPort());
|
||||
brokerOverallDTO.setJmxPort(brokerMetadata.getJmxPort());
|
||||
brokerOverallDTO.setStartTime(brokerMetadata.getTimestamp());
|
||||
if (brokerMetrics == null) {
|
||||
return brokerOverallDTO;
|
||||
}
|
||||
brokerOverallDTO.setPartitionCount(brokerMetrics.getPartitionCount());
|
||||
brokerOverallDTO.setLeaderCount(brokerMetrics.getLeaderCount());
|
||||
brokerOverallDTO.setBytesInPerSec(brokerMetrics.getBytesInPerSec());
|
||||
brokerOverallDTO.setUnderReplicatedPartitions(brokerMetrics.getUnderReplicatedPartitions());
|
||||
return brokerOverallDTO;
|
||||
}
|
||||
}
|
||||
@@ -1,121 +0,0 @@
|
||||
package com.xiaojukeji.kafka.manager.common.entity.dto;
|
||||
|
||||
import com.xiaojukeji.kafka.manager.common.entity.metrics.BrokerMetrics;
|
||||
import com.xiaojukeji.kafka.manager.common.entity.zookeeper.BrokerMetadata;
|
||||
import com.xiaojukeji.kafka.manager.common.entity.bizenum.DBStatusEnum;
|
||||
|
||||
/**
|
||||
* @author zengqiao_cn@163.com
|
||||
* @date 19/4/21
|
||||
*/
|
||||
public class BrokerOverviewDTO {
|
||||
private Integer brokerId;
|
||||
|
||||
private String host;
|
||||
|
||||
private Integer port;
|
||||
|
||||
private Integer jmxPort;
|
||||
|
||||
private Long startTime;
|
||||
|
||||
private Double byteIn;
|
||||
|
||||
private Double byteOut;
|
||||
|
||||
private Integer status;
|
||||
|
||||
public Integer getBrokerId() {
|
||||
return brokerId;
|
||||
}
|
||||
|
||||
public void setBrokerId(Integer brokerId) {
|
||||
this.brokerId = brokerId;
|
||||
}
|
||||
|
||||
public String getHost() {
|
||||
return host;
|
||||
}
|
||||
|
||||
public void setHost(String host) {
|
||||
this.host = host;
|
||||
}
|
||||
|
||||
public Integer getPort() {
|
||||
return port;
|
||||
}
|
||||
|
||||
public void setPort(Integer port) {
|
||||
this.port = port;
|
||||
}
|
||||
|
||||
public Integer getJmxPort() {
|
||||
return jmxPort;
|
||||
}
|
||||
|
||||
public void setJmxPort(Integer jmxPort) {
|
||||
this.jmxPort = jmxPort;
|
||||
}
|
||||
|
||||
public Long getStartTime() {
|
||||
return startTime;
|
||||
}
|
||||
|
||||
public void setStartTime(Long startTime) {
|
||||
this.startTime = startTime;
|
||||
}
|
||||
|
||||
public Double getByteIn() {
|
||||
return byteIn;
|
||||
}
|
||||
|
||||
public void setByteIn(Double byteIn) {
|
||||
this.byteIn = byteIn;
|
||||
}
|
||||
|
||||
public Double getByteOut() {
|
||||
return byteOut;
|
||||
}
|
||||
|
||||
public void setByteOut(Double byteOut) {
|
||||
this.byteOut = byteOut;
|
||||
}
|
||||
|
||||
public Integer getStatus() {
|
||||
return status;
|
||||
}
|
||||
|
||||
public void setStatus(Integer status) {
|
||||
this.status = status;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "BrokerInfoDTO{" +
|
||||
"brokerId=" + brokerId +
|
||||
", host='" + host + '\'' +
|
||||
", port=" + port +
|
||||
", jmxPort=" + jmxPort +
|
||||
", startTime=" + startTime +
|
||||
", byteIn=" + byteIn +
|
||||
", byteOut=" + byteOut +
|
||||
", status=" + status +
|
||||
'}';
|
||||
}
|
||||
|
||||
public static BrokerOverviewDTO newInstance(BrokerMetadata brokerMetadata, BrokerMetrics brokerMetrics) {
|
||||
BrokerOverviewDTO brokerOverviewDTO = new BrokerOverviewDTO();
|
||||
brokerOverviewDTO.setBrokerId(brokerMetadata.getBrokerId());
|
||||
brokerOverviewDTO.setHost(brokerMetadata.getHost());
|
||||
brokerOverviewDTO.setPort(brokerMetadata.getPort());
|
||||
brokerOverviewDTO.setJmxPort(brokerMetadata.getJmxPort());
|
||||
brokerOverviewDTO.setStartTime(brokerMetadata.getTimestamp());
|
||||
brokerOverviewDTO.setStatus(DBStatusEnum.NORMAL.getStatus());
|
||||
if (brokerMetrics == null) {
|
||||
return brokerOverviewDTO;
|
||||
}
|
||||
brokerOverviewDTO.setByteIn(brokerMetrics.getBytesInPerSec());
|
||||
brokerOverviewDTO.setByteOut(brokerMetrics.getBytesOutPerSec());
|
||||
return brokerOverviewDTO;
|
||||
}
|
||||
}
|
||||
@@ -1,70 +0,0 @@
|
||||
package com.xiaojukeji.kafka.manager.common.entity.dto;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* @author zengqiao
|
||||
* @date 19/4/22
|
||||
*/
|
||||
public class ControllerDTO {
|
||||
private String clusterName;
|
||||
|
||||
private Integer brokerId;
|
||||
|
||||
private String host;
|
||||
|
||||
private Integer controllerVersion;
|
||||
|
||||
private Date controllerTimestamp;
|
||||
|
||||
public String getClusterName() {
|
||||
return clusterName;
|
||||
}
|
||||
|
||||
public void setClusterName(String clusterName) {
|
||||
this.clusterName = clusterName;
|
||||
}
|
||||
|
||||
public Integer getBrokerId() {
|
||||
return brokerId;
|
||||
}
|
||||
|
||||
public void setBrokerId(Integer brokerId) {
|
||||
this.brokerId = brokerId;
|
||||
}
|
||||
|
||||
public String getHost() {
|
||||
return host;
|
||||
}
|
||||
|
||||
public void setHost(String host) {
|
||||
this.host = host;
|
||||
}
|
||||
|
||||
public Integer getControllerVersion() {
|
||||
return controllerVersion;
|
||||
}
|
||||
|
||||
public void setControllerVersion(Integer controllerVersion) {
|
||||
this.controllerVersion = controllerVersion;
|
||||
}
|
||||
|
||||
public Date getControllerTimestamp() {
|
||||
return controllerTimestamp;
|
||||
}
|
||||
|
||||
public void setControllerTimestamp(Date controllerTimestamp) {
|
||||
this.controllerTimestamp = controllerTimestamp;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "ControllerInfoDTO{" +
|
||||
"clusterName='" + clusterName + '\'' +
|
||||
", brokerId=" + brokerId +
|
||||
", host='" + host + '\'' +
|
||||
", controllerVersion=" + controllerVersion +
|
||||
", controllerTimestamp=" + controllerTimestamp +
|
||||
'}';
|
||||
}
|
||||
}
|
||||
@@ -1,123 +0,0 @@
|
||||
package com.xiaojukeji.kafka.manager.common.entity.dto;
|
||||
|
||||
/**
|
||||
* @author arthur
|
||||
* @date 2018/09/03
|
||||
*/
|
||||
public class TopicBasicDTO {
|
||||
private String topicName;
|
||||
|
||||
private Integer partitionNum;
|
||||
|
||||
private Integer replicaNum;
|
||||
|
||||
private Integer brokerNum;
|
||||
|
||||
private String remark;
|
||||
|
||||
private Long modifyTime;
|
||||
|
||||
private Long createTime;
|
||||
|
||||
private String region;
|
||||
|
||||
private Long retentionTime;
|
||||
|
||||
private String principal;
|
||||
|
||||
public String getTopicName() {
|
||||
return topicName;
|
||||
}
|
||||
|
||||
public void setTopicName(String topicName) {
|
||||
this.topicName = topicName;
|
||||
}
|
||||
|
||||
public Integer getPartitionNum() {
|
||||
return partitionNum;
|
||||
}
|
||||
|
||||
public void setPartitionNum(Integer partitionNum) {
|
||||
this.partitionNum = partitionNum;
|
||||
}
|
||||
|
||||
public Integer getReplicaNum() {
|
||||
return replicaNum;
|
||||
}
|
||||
|
||||
public void setReplicaNum(Integer replicaNum) {
|
||||
this.replicaNum = replicaNum;
|
||||
}
|
||||
|
||||
public Integer getBrokerNum() {
|
||||
return brokerNum;
|
||||
}
|
||||
|
||||
public void setBrokerNum(Integer brokerNum) {
|
||||
this.brokerNum = brokerNum;
|
||||
}
|
||||
|
||||
public String getRemark() {
|
||||
return remark;
|
||||
}
|
||||
|
||||
public void setRemark(String remark) {
|
||||
this.remark = remark;
|
||||
}
|
||||
|
||||
public String getRegion() {
|
||||
return region;
|
||||
}
|
||||
|
||||
public void setRegion(String region) {
|
||||
this.region = region;
|
||||
}
|
||||
|
||||
public Long getRetentionTime() {
|
||||
return retentionTime;
|
||||
}
|
||||
|
||||
public void setRetentionTime(Long retentionTime) {
|
||||
this.retentionTime = retentionTime;
|
||||
}
|
||||
|
||||
public Long getModifyTime() {
|
||||
return modifyTime;
|
||||
}
|
||||
|
||||
public void setModifyTime(Long modifyTime) {
|
||||
this.modifyTime = modifyTime;
|
||||
}
|
||||
|
||||
public Long getCreateTime() {
|
||||
return createTime;
|
||||
}
|
||||
|
||||
public void setCreateTime(Long createTime) {
|
||||
this.createTime = createTime;
|
||||
}
|
||||
|
||||
public String getPrincipal() {
|
||||
return principal;
|
||||
}
|
||||
|
||||
public void setPrincipal(String principal) {
|
||||
this.principal = principal;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "TopicBasicInfoDTO{" +
|
||||
"topicName='" + topicName + '\'' +
|
||||
", partitionNum=" + partitionNum +
|
||||
", replicaNum=" + replicaNum +
|
||||
", brokerNum=" + brokerNum +
|
||||
", remark='" + remark + '\'' +
|
||||
", modifyTime=" + modifyTime +
|
||||
", createTime=" + createTime +
|
||||
", region='" + region + '\'' +
|
||||
", retentionTime=" + retentionTime +
|
||||
", principal='" + principal + '\'' +
|
||||
'}';
|
||||
}
|
||||
}
|
||||
@@ -1,86 +0,0 @@
|
||||
package com.xiaojukeji.kafka.manager.common.entity.dto;
|
||||
|
||||
public class TopicOverviewDTO {
|
||||
private Long clusterId;
|
||||
|
||||
private String topicName;
|
||||
|
||||
private Integer replicaNum;
|
||||
|
||||
private Integer partitionNum;
|
||||
|
||||
private Double bytesInPerSec;
|
||||
|
||||
private Double produceRequestPerSec;
|
||||
|
||||
private Long updateTime;
|
||||
|
||||
public Long getClusterId() {
|
||||
return clusterId;
|
||||
}
|
||||
|
||||
public void setClusterId(Long clusterId) {
|
||||
this.clusterId = clusterId;
|
||||
}
|
||||
|
||||
public String getTopicName() {
|
||||
return topicName;
|
||||
}
|
||||
|
||||
public void setTopicName(String topicName) {
|
||||
this.topicName = topicName;
|
||||
}
|
||||
|
||||
public Integer getReplicaNum() {
|
||||
return replicaNum;
|
||||
}
|
||||
|
||||
public void setReplicaNum(Integer replicaNum) {
|
||||
this.replicaNum = replicaNum;
|
||||
}
|
||||
|
||||
public Integer getPartitionNum() {
|
||||
return partitionNum;
|
||||
}
|
||||
|
||||
public void setPartitionNum(Integer partitionNum) {
|
||||
this.partitionNum = partitionNum;
|
||||
}
|
||||
|
||||
public Double getBytesInPerSec() {
|
||||
return bytesInPerSec;
|
||||
}
|
||||
|
||||
public void setBytesInPerSec(Double bytesInPerSec) {
|
||||
this.bytesInPerSec = bytesInPerSec;
|
||||
}
|
||||
|
||||
public Double getProduceRequestPerSec() {
|
||||
return produceRequestPerSec;
|
||||
}
|
||||
|
||||
public void setProduceRequestPerSec(Double produceRequestPerSec) {
|
||||
this.produceRequestPerSec = produceRequestPerSec;
|
||||
}
|
||||
|
||||
public Long getUpdateTime() {
|
||||
return updateTime;
|
||||
}
|
||||
|
||||
public void setUpdateTime(Long updateTime) {
|
||||
this.updateTime = updateTime;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "TopicOverviewDTO{" +
|
||||
"clusterId=" + clusterId +
|
||||
", topicName='" + topicName + '\'' +
|
||||
", replicaNum=" + replicaNum +
|
||||
", partitionNum=" + partitionNum +
|
||||
", bytesInPerSec=" + bytesInPerSec +
|
||||
", produceRequestPerSec=" + produceRequestPerSec +
|
||||
", updateTime=" + updateTime +
|
||||
'}';
|
||||
}
|
||||
}
|
||||
@@ -1,105 +0,0 @@
|
||||
package com.xiaojukeji.kafka.manager.common.entity.dto;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author arthur
|
||||
* @date 2017/6/6.
|
||||
*/
|
||||
public class TopicPartitionDTO implements Serializable {
|
||||
|
||||
private Integer partitionId;
|
||||
|
||||
private Long offset;
|
||||
|
||||
private Integer leaderBrokerId;
|
||||
|
||||
private Integer preferredBrokerId;
|
||||
|
||||
private Integer leaderEpoch;
|
||||
|
||||
private List<Integer> replicasBroker;
|
||||
|
||||
private List<Integer> isr;
|
||||
|
||||
private Boolean underReplicated;
|
||||
|
||||
public Integer getPartitionId() {
|
||||
return partitionId;
|
||||
}
|
||||
|
||||
public void setPartitionId(Integer partitionId) {
|
||||
this.partitionId = partitionId;
|
||||
}
|
||||
|
||||
public Long getOffset() {
|
||||
return offset;
|
||||
}
|
||||
|
||||
public void setOffset(Long offset) {
|
||||
this.offset = offset;
|
||||
}
|
||||
|
||||
public Integer getLeaderBrokerId() {
|
||||
return leaderBrokerId;
|
||||
}
|
||||
|
||||
public void setLeaderBrokerId(Integer leaderBrokerId) {
|
||||
this.leaderBrokerId = leaderBrokerId;
|
||||
}
|
||||
|
||||
public Integer getPreferredBrokerId() {
|
||||
return preferredBrokerId;
|
||||
}
|
||||
|
||||
public void setPreferredBrokerId(Integer preferredBrokerId) {
|
||||
this.preferredBrokerId = preferredBrokerId;
|
||||
}
|
||||
|
||||
public Integer getLeaderEpoch() {
|
||||
return leaderEpoch;
|
||||
}
|
||||
|
||||
public void setLeaderEpoch(Integer leaderEpoch) {
|
||||
this.leaderEpoch = leaderEpoch;
|
||||
}
|
||||
|
||||
public List<Integer> getReplicasBroker() {
|
||||
return replicasBroker;
|
||||
}
|
||||
|
||||
public void setReplicasBroker(List<Integer> replicasBroker) {
|
||||
this.replicasBroker = replicasBroker;
|
||||
}
|
||||
|
||||
public List<Integer> getIsr() {
|
||||
return isr;
|
||||
}
|
||||
|
||||
public void setIsr(List<Integer> isr) {
|
||||
this.isr = isr;
|
||||
}
|
||||
|
||||
public boolean isUnderReplicated() {
|
||||
return underReplicated;
|
||||
}
|
||||
|
||||
public void setUnderReplicated(boolean underReplicated) {
|
||||
this.underReplicated = underReplicated;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "TopicPartitionDTO{" +
|
||||
"partitionId=" + partitionId +
|
||||
", offset=" + offset +
|
||||
", leaderBrokerId=" + leaderBrokerId +
|
||||
", preferredBrokerId=" + preferredBrokerId +
|
||||
", leaderEpoch=" + leaderEpoch +
|
||||
", replicasBroker=" + replicasBroker +
|
||||
", isr=" + isr +
|
||||
", underReplicated=" + underReplicated +
|
||||
'}';
|
||||
}
|
||||
}
|
||||
@@ -1,47 +0,0 @@
|
||||
package com.xiaojukeji.kafka.manager.common.entity.dto.alarm;
|
||||
|
||||
/**
|
||||
* 告警通知
|
||||
* @author zengqiao
|
||||
* @date 2020-02-14
|
||||
*/
|
||||
public class AlarmNotifyDTO {
|
||||
private Long alarmRuleId;
|
||||
|
||||
private String actionTag;
|
||||
|
||||
private String message;
|
||||
|
||||
public Long getAlarmRuleId() {
|
||||
return alarmRuleId;
|
||||
}
|
||||
|
||||
public void setAlarmRuleId(Long alarmRuleId) {
|
||||
this.alarmRuleId = alarmRuleId;
|
||||
}
|
||||
|
||||
public String getActionTag() {
|
||||
return actionTag;
|
||||
}
|
||||
|
||||
public void setActionTag(String actionTag) {
|
||||
this.actionTag = actionTag;
|
||||
}
|
||||
|
||||
public String getMessage() {
|
||||
return message;
|
||||
}
|
||||
|
||||
public void setMessage(String message) {
|
||||
this.message = message;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "AlarmNotifyDTO{" +
|
||||
"alarmRuleId=" + alarmRuleId +
|
||||
", actionTag='" + actionTag + '\'' +
|
||||
", message='" + message + '\'' +
|
||||
'}';
|
||||
}
|
||||
}
|
||||
@@ -1,127 +0,0 @@
|
||||
package com.xiaojukeji.kafka.manager.common.entity.dto.alarm;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* @author zengqiao
|
||||
* @date 19/12/16
|
||||
*/
|
||||
public class AlarmRuleDTO {
|
||||
/**
|
||||
* 告警ID
|
||||
*/
|
||||
private Long id;
|
||||
|
||||
/**
|
||||
* 告警名称
|
||||
*/
|
||||
private String name;
|
||||
|
||||
/**
|
||||
* 已持续次数
|
||||
*/
|
||||
private Integer duration;
|
||||
|
||||
/**
|
||||
* 集群ID, 过滤条件中必有的, 单独拿出来
|
||||
*/
|
||||
private Long clusterId;
|
||||
|
||||
/**
|
||||
* 告警策略表达式
|
||||
*/
|
||||
private AlarmStrategyExpressionDTO strategyExpression;
|
||||
|
||||
/**
|
||||
* 告警策略过滤条件
|
||||
*/
|
||||
private Map<String, String> strategyFilterMap;
|
||||
|
||||
/**
|
||||
* 告警策略Action方式
|
||||
*/
|
||||
private Map<String, AlarmStrategyActionDTO> strategyActionMap;
|
||||
|
||||
/**
|
||||
* 修改时间
|
||||
*/
|
||||
private Long gmtModify;
|
||||
|
||||
public Long getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(Long id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public Integer getDuration() {
|
||||
return duration;
|
||||
}
|
||||
|
||||
public void setDuration(Integer duration) {
|
||||
this.duration = duration;
|
||||
}
|
||||
|
||||
public Long getClusterId() {
|
||||
return clusterId;
|
||||
}
|
||||
|
||||
public void setClusterId(Long clusterId) {
|
||||
this.clusterId = clusterId;
|
||||
}
|
||||
|
||||
public AlarmStrategyExpressionDTO getStrategyExpression() {
|
||||
return strategyExpression;
|
||||
}
|
||||
|
||||
public void setStrategyExpression(AlarmStrategyExpressionDTO strategyExpression) {
|
||||
this.strategyExpression = strategyExpression;
|
||||
}
|
||||
|
||||
public Map<String, String> getStrategyFilterMap() {
|
||||
return strategyFilterMap;
|
||||
}
|
||||
|
||||
public void setStrategyFilterMap(Map<String, String> strategyFilterMap) {
|
||||
this.strategyFilterMap = strategyFilterMap;
|
||||
}
|
||||
|
||||
public Map<String, AlarmStrategyActionDTO> getStrategyActionMap() {
|
||||
return strategyActionMap;
|
||||
}
|
||||
|
||||
public void setStrategyActionMap(Map<String, AlarmStrategyActionDTO> strategyActionMap) {
|
||||
this.strategyActionMap = strategyActionMap;
|
||||
}
|
||||
|
||||
public Long getGmtModify() {
|
||||
return gmtModify;
|
||||
}
|
||||
|
||||
public void setGmtModify(Long gmtModify) {
|
||||
this.gmtModify = gmtModify;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "AlarmRuleDTO{" +
|
||||
"id=" + id +
|
||||
", name='" + name + '\'' +
|
||||
", duration=" + duration +
|
||||
", clusterId=" + clusterId +
|
||||
", strategyExpression=" + strategyExpression +
|
||||
", strategyFilterMap=" + strategyFilterMap +
|
||||
", strategyActionMap=" + strategyActionMap +
|
||||
", gmtModify=" + gmtModify +
|
||||
'}';
|
||||
}
|
||||
}
|
||||
@@ -1,43 +0,0 @@
|
||||
package com.xiaojukeji.kafka.manager.common.entity.dto.alarm;
|
||||
|
||||
/**
|
||||
* @author zengqiao
|
||||
* @date 19/12/16
|
||||
*/
|
||||
public class AlarmStrategyActionDTO {
|
||||
private String actionWay; // 告知方式: kafka
|
||||
|
||||
private String actionTag;
|
||||
|
||||
public String getActionWay() {
|
||||
return actionWay;
|
||||
}
|
||||
|
||||
public void setActionWay(String actionWay) {
|
||||
this.actionWay = actionWay;
|
||||
}
|
||||
|
||||
public String getActionTag() {
|
||||
return actionTag;
|
||||
}
|
||||
|
||||
public void setActionTag(String actionTag) {
|
||||
this.actionTag = actionTag;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "AlarmStrategyActionDTO{" +
|
||||
"actionWay='" + actionWay + '\'' +
|
||||
", actionTag='" + actionTag + '\'' +
|
||||
'}';
|
||||
}
|
||||
|
||||
public boolean legal() {
|
||||
if (actionWay == null
|
||||
|| actionTag == null) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -1,68 +0,0 @@
|
||||
package com.xiaojukeji.kafka.manager.common.entity.dto.alarm;
|
||||
|
||||
/**
|
||||
* 策略表达式
|
||||
* @author zengqiao
|
||||
* @date 19/12/16
|
||||
*/
|
||||
public class AlarmStrategyExpressionDTO {
|
||||
private String metric;
|
||||
|
||||
private String opt;
|
||||
|
||||
private Long threshold;
|
||||
|
||||
private Integer duration;
|
||||
|
||||
public String getMetric() {
|
||||
return metric;
|
||||
}
|
||||
|
||||
public void setMetric(String metric) {
|
||||
this.metric = metric;
|
||||
}
|
||||
|
||||
public String getOpt() {
|
||||
return opt;
|
||||
}
|
||||
|
||||
public void setOpt(String opt) {
|
||||
this.opt = opt;
|
||||
}
|
||||
|
||||
public Long getThreshold() {
|
||||
return threshold;
|
||||
}
|
||||
|
||||
public void setThreshold(Long threshold) {
|
||||
this.threshold = threshold;
|
||||
}
|
||||
|
||||
public Integer getDuration() {
|
||||
return duration;
|
||||
}
|
||||
|
||||
public void setDuration(Integer duration) {
|
||||
this.duration = duration;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "AlarmStrategyExpressionModel{" +
|
||||
"metric='" + metric + '\'' +
|
||||
", opt='" + opt + '\'' +
|
||||
", threshold=" + threshold +
|
||||
", duration=" + duration +
|
||||
'}';
|
||||
}
|
||||
|
||||
public boolean legal() {
|
||||
if (metric == null
|
||||
|| opt == null
|
||||
|| threshold == null
|
||||
|| duration == null || duration <= 0) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -1,44 +0,0 @@
|
||||
package com.xiaojukeji.kafka.manager.common.entity.dto.alarm;
|
||||
|
||||
/**
|
||||
* 告警过滤条件
|
||||
* @author zengqiao
|
||||
* @date 19/12/16
|
||||
*/
|
||||
public class AlarmStrategyFilterDTO {
|
||||
private String key;
|
||||
|
||||
private String value;
|
||||
|
||||
public String getKey() {
|
||||
return key;
|
||||
}
|
||||
|
||||
public void setKey(String key) {
|
||||
this.key = key;
|
||||
}
|
||||
|
||||
public String getValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
public void setValue(String value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "AlarmStrategyFilterModel{" +
|
||||
"key='" + key + '\'' +
|
||||
", value='" + value + '\'' +
|
||||
'}';
|
||||
}
|
||||
|
||||
public boolean legal() {
|
||||
if (key == null
|
||||
|| value == null) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -1,394 +0,0 @@
|
||||
package com.xiaojukeji.kafka.manager.common.entity.metrics;
|
||||
|
||||
import com.xiaojukeji.kafka.manager.common.constant.MetricsType;
|
||||
import com.xiaojukeji.kafka.manager.common.entity.annotations.FieldSelector;
|
||||
import com.xiaojukeji.kafka.manager.common.entity.po.BaseEntryDO;
|
||||
|
||||
/**
|
||||
* @author zengqiao
|
||||
* @date 19/11/25
|
||||
*/
|
||||
public class BaseMetrics extends BaseEntryDO {
|
||||
/**
|
||||
* 每秒流入的近一分钟的均值、平均字节数、近五分钟均值、近十五分钟均值
|
||||
*/
|
||||
@FieldSelector(types = {
|
||||
MetricsType.BROKER_FLOW_DETAIL,
|
||||
MetricsType.BROKER_TO_DB_METRICS,
|
||||
MetricsType.BROKER_REAL_TIME_METRICS,
|
||||
MetricsType.BROKER_OVER_VIEW_METRICS,
|
||||
MetricsType.BROKER_ANALYSIS_METRICS,
|
||||
MetricsType.BROKER_TOPIC_ANALYSIS_METRICS,
|
||||
MetricsType.TOPIC_FLOW_DETAIL,
|
||||
MetricsType.TOPIC_FLOW_OVERVIEW,
|
||||
MetricsType.TOPIC_METRICS_TO_DB
|
||||
})
|
||||
protected Double bytesInPerSec = 0.0;
|
||||
protected Double bytesInPerSecMeanRate = 0.0;
|
||||
protected Double bytesInPerSecFiveMinuteRate = 0.0;
|
||||
protected Double bytesInPerSecFifteenMinuteRate = 0.0;
|
||||
|
||||
/**
|
||||
* 每秒流出的近一分钟的均值、平均字节数、近五分钟均值、近十五分钟均值
|
||||
*/
|
||||
@FieldSelector(types = {
|
||||
MetricsType.BROKER_FLOW_DETAIL,
|
||||
MetricsType.BROKER_TO_DB_METRICS,
|
||||
MetricsType.BROKER_REAL_TIME_METRICS,
|
||||
MetricsType.BROKER_OVER_VIEW_METRICS,
|
||||
MetricsType.BROKER_ANALYSIS_METRICS,
|
||||
MetricsType.BROKER_TOPIC_ANALYSIS_METRICS,
|
||||
MetricsType.TOPIC_FLOW_DETAIL,
|
||||
MetricsType.TOPIC_METRICS_TO_DB
|
||||
})
|
||||
protected Double bytesOutPerSec = 0.0;
|
||||
protected Double bytesOutPerSecMeanRate = 0.0;
|
||||
protected Double bytesOutPerSecFiveMinuteRate = 0.0;
|
||||
protected Double bytesOutPerSecFifteenMinuteRate = 0.0;
|
||||
|
||||
/**
|
||||
* 每秒流入的近一分钟的均值、平均字节数、近五分钟均值、近十五分钟均值
|
||||
*/
|
||||
@FieldSelector(types = {
|
||||
MetricsType.BROKER_FLOW_DETAIL,
|
||||
MetricsType.BROKER_TO_DB_METRICS,
|
||||
MetricsType.BROKER_REAL_TIME_METRICS,
|
||||
MetricsType.BROKER_ANALYSIS_METRICS,
|
||||
MetricsType.BROKER_TOPIC_ANALYSIS_METRICS,
|
||||
MetricsType.TOPIC_FLOW_DETAIL,
|
||||
MetricsType.TOPIC_METRICS_TO_DB
|
||||
})
|
||||
protected Double messagesInPerSec = 0.0;
|
||||
protected Double messagesInPerSecMeanRate = 0.0;
|
||||
protected Double messagesInPerSecFiveMinuteRate = 0.0;
|
||||
protected Double messagesInPerSecFifteenMinuteRate = 0.0;
|
||||
|
||||
/**
|
||||
* 每秒拒绝的近一分钟的均值、平均字节数、近五分钟均值、近十五分钟均值
|
||||
*/
|
||||
@FieldSelector(types = {
|
||||
MetricsType.BROKER_FLOW_DETAIL,
|
||||
MetricsType.BROKER_TO_DB_METRICS,
|
||||
MetricsType.BROKER_REAL_TIME_METRICS,
|
||||
MetricsType.TOPIC_FLOW_DETAIL,
|
||||
MetricsType.TOPIC_METRICS_TO_DB
|
||||
})
|
||||
protected Double bytesRejectedPerSec = 0.0;
|
||||
protected Double bytesRejectedPerSecMeanRate = 0.0;
|
||||
protected Double bytesRejectedPerSecFiveMinuteRate = 0.0;
|
||||
protected Double bytesRejectedPerSecFifteenMinuteRate = 0.0;
|
||||
|
||||
/**
|
||||
* 每秒失败的Produce请求数的近一分钟的均值、平均字节数、近五分钟均值、近十五分钟均值
|
||||
*/
|
||||
@FieldSelector(types = {
|
||||
MetricsType.BROKER_FLOW_DETAIL,
|
||||
MetricsType.BROKER_TO_DB_METRICS,
|
||||
MetricsType.BROKER_REAL_TIME_METRICS,
|
||||
MetricsType.TOPIC_FLOW_DETAIL
|
||||
})
|
||||
protected Double failProduceRequestPerSec = 0.0;
|
||||
protected Double failProduceRequestPerSecMeanRate = 0.0;
|
||||
protected Double failProduceRequestPerSecFiveMinuteRate = 0.0;
|
||||
protected Double failProduceRequestPerSecFifteenMinuteRate = 0.0;
|
||||
|
||||
/**
|
||||
* 每秒失败的Fetch请求数的近一分钟的均值、平均字节数、近五分钟均值、近十五分钟均值
|
||||
*/
|
||||
@FieldSelector(types = {
|
||||
MetricsType.BROKER_FLOW_DETAIL,
|
||||
MetricsType.BROKER_TO_DB_METRICS,
|
||||
MetricsType.BROKER_REAL_TIME_METRICS,
|
||||
MetricsType.TOPIC_FLOW_DETAIL
|
||||
})
|
||||
protected Double failFetchRequestPerSec = 0.0;
|
||||
protected Double failFetchRequestPerSecMeanRate = 0.0;
|
||||
protected Double failFetchRequestPerSecFiveMinuteRate = 0.0;
|
||||
protected Double failFetchRequestPerSecFifteenMinuteRate = 0.0;
|
||||
|
||||
/**
|
||||
* 每秒总Produce请求数的近一分钟的均值、平均字节数、近五分钟均值、近十五分钟均值
|
||||
*/
|
||||
@FieldSelector(types = {
|
||||
MetricsType.BROKER_FLOW_DETAIL,
|
||||
MetricsType.BROKER_ANALYSIS_METRICS,
|
||||
MetricsType.BROKER_TOPIC_ANALYSIS_METRICS,
|
||||
MetricsType.TOPIC_FLOW_DETAIL,
|
||||
MetricsType.TOPIC_METRICS_TO_DB,
|
||||
MetricsType.TOPIC_FLOW_OVERVIEW
|
||||
})
|
||||
protected Double totalProduceRequestsPerSec = 0.0;
|
||||
protected Double totalProduceRequestsPerSecMeanRate = 0.0;
|
||||
protected Double totalProduceRequestsPerSecFiveMinuteRate = 0.0;
|
||||
protected Double totalProduceRequestsPerSecFifteenMinuteRate = 0.0;
|
||||
|
||||
/**
|
||||
* 每秒总Fetch请求数的近一分钟的均值、平均字节数、近五分钟均值、近十五分钟均值
|
||||
*/
|
||||
@FieldSelector(types = {
|
||||
MetricsType.BROKER_FLOW_DETAIL,
|
||||
MetricsType.BROKER_ANALYSIS_METRICS,
|
||||
MetricsType.BROKER_TOPIC_ANALYSIS_METRICS,
|
||||
MetricsType.TOPIC_FLOW_DETAIL
|
||||
})
|
||||
protected Double totalFetchRequestsPerSec = 0.0;
|
||||
protected Double totalFetchRequestsPerSecMeanRate = 0.0;
|
||||
protected Double totalFetchRequestsPerSecFiveMinuteRate = 0.0;
|
||||
protected Double totalFetchRequestsPerSecFifteenMinuteRate = 0.0;
|
||||
|
||||
public Double getBytesInPerSec() {
|
||||
return bytesInPerSec;
|
||||
}
|
||||
|
||||
public void setBytesInPerSec(Double bytesInPerSec) {
|
||||
this.bytesInPerSec = bytesInPerSec;
|
||||
}
|
||||
|
||||
public Double getBytesInPerSecMeanRate() {
|
||||
return bytesInPerSecMeanRate;
|
||||
}
|
||||
|
||||
public void setBytesInPerSecMeanRate(Double bytesInPerSecMeanRate) {
|
||||
this.bytesInPerSecMeanRate = bytesInPerSecMeanRate;
|
||||
}
|
||||
|
||||
public Double getBytesInPerSecFiveMinuteRate() {
|
||||
return bytesInPerSecFiveMinuteRate;
|
||||
}
|
||||
|
||||
public void setBytesInPerSecFiveMinuteRate(Double bytesInPerSecFiveMinuteRate) {
|
||||
this.bytesInPerSecFiveMinuteRate = bytesInPerSecFiveMinuteRate;
|
||||
}
|
||||
|
||||
public Double getBytesInPerSecFifteenMinuteRate() {
|
||||
return bytesInPerSecFifteenMinuteRate;
|
||||
}
|
||||
|
||||
public void setBytesInPerSecFifteenMinuteRate(Double bytesInPerSecFifteenMinuteRate) {
|
||||
this.bytesInPerSecFifteenMinuteRate = bytesInPerSecFifteenMinuteRate;
|
||||
}
|
||||
|
||||
public Double getBytesOutPerSec() {
|
||||
return bytesOutPerSec;
|
||||
}
|
||||
|
||||
public void setBytesOutPerSec(Double bytesOutPerSec) {
|
||||
this.bytesOutPerSec = bytesOutPerSec;
|
||||
}
|
||||
|
||||
public Double getBytesOutPerSecMeanRate() {
|
||||
return bytesOutPerSecMeanRate;
|
||||
}
|
||||
|
||||
public void setBytesOutPerSecMeanRate(Double bytesOutPerSecMeanRate) {
|
||||
this.bytesOutPerSecMeanRate = bytesOutPerSecMeanRate;
|
||||
}
|
||||
|
||||
public Double getBytesOutPerSecFiveMinuteRate() {
|
||||
return bytesOutPerSecFiveMinuteRate;
|
||||
}
|
||||
|
||||
public void setBytesOutPerSecFiveMinuteRate(Double bytesOutPerSecFiveMinuteRate) {
|
||||
this.bytesOutPerSecFiveMinuteRate = bytesOutPerSecFiveMinuteRate;
|
||||
}
|
||||
|
||||
public Double getBytesOutPerSecFifteenMinuteRate() {
|
||||
return bytesOutPerSecFifteenMinuteRate;
|
||||
}
|
||||
|
||||
public void setBytesOutPerSecFifteenMinuteRate(Double bytesOutPerSecFifteenMinuteRate) {
|
||||
this.bytesOutPerSecFifteenMinuteRate = bytesOutPerSecFifteenMinuteRate;
|
||||
}
|
||||
|
||||
public Double getMessagesInPerSec() {
|
||||
return messagesInPerSec;
|
||||
}
|
||||
|
||||
public void setMessagesInPerSec(Double messagesInPerSec) {
|
||||
this.messagesInPerSec = messagesInPerSec;
|
||||
}
|
||||
|
||||
public Double getMessagesInPerSecMeanRate() {
|
||||
return messagesInPerSecMeanRate;
|
||||
}
|
||||
|
||||
public void setMessagesInPerSecMeanRate(Double messagesInPerSecMeanRate) {
|
||||
this.messagesInPerSecMeanRate = messagesInPerSecMeanRate;
|
||||
}
|
||||
|
||||
public Double getMessagesInPerSecFiveMinuteRate() {
|
||||
return messagesInPerSecFiveMinuteRate;
|
||||
}
|
||||
|
||||
public void setMessagesInPerSecFiveMinuteRate(Double messagesInPerSecFiveMinuteRate) {
|
||||
this.messagesInPerSecFiveMinuteRate = messagesInPerSecFiveMinuteRate;
|
||||
}
|
||||
|
||||
public Double getMessagesInPerSecFifteenMinuteRate() {
|
||||
return messagesInPerSecFifteenMinuteRate;
|
||||
}
|
||||
|
||||
public void setMessagesInPerSecFifteenMinuteRate(Double messagesInPerSecFifteenMinuteRate) {
|
||||
this.messagesInPerSecFifteenMinuteRate = messagesInPerSecFifteenMinuteRate;
|
||||
}
|
||||
|
||||
public Double getBytesRejectedPerSec() {
|
||||
return bytesRejectedPerSec;
|
||||
}
|
||||
|
||||
public void setBytesRejectedPerSec(Double bytesRejectedPerSec) {
|
||||
this.bytesRejectedPerSec = bytesRejectedPerSec;
|
||||
}
|
||||
|
||||
public Double getBytesRejectedPerSecMeanRate() {
|
||||
return bytesRejectedPerSecMeanRate;
|
||||
}
|
||||
|
||||
public void setBytesRejectedPerSecMeanRate(Double bytesRejectedPerSecMeanRate) {
|
||||
this.bytesRejectedPerSecMeanRate = bytesRejectedPerSecMeanRate;
|
||||
}
|
||||
|
||||
public Double getBytesRejectedPerSecFiveMinuteRate() {
|
||||
return bytesRejectedPerSecFiveMinuteRate;
|
||||
}
|
||||
|
||||
public void setBytesRejectedPerSecFiveMinuteRate(Double bytesRejectedPerSecFiveMinuteRate) {
|
||||
this.bytesRejectedPerSecFiveMinuteRate = bytesRejectedPerSecFiveMinuteRate;
|
||||
}
|
||||
|
||||
public Double getBytesRejectedPerSecFifteenMinuteRate() {
|
||||
return bytesRejectedPerSecFifteenMinuteRate;
|
||||
}
|
||||
|
||||
public void setBytesRejectedPerSecFifteenMinuteRate(Double bytesRejectedPerSecFifteenMinuteRate) {
|
||||
this.bytesRejectedPerSecFifteenMinuteRate = bytesRejectedPerSecFifteenMinuteRate;
|
||||
}
|
||||
|
||||
public Double getFailProduceRequestPerSec() {
|
||||
return failProduceRequestPerSec;
|
||||
}
|
||||
|
||||
public void setFailProduceRequestPerSec(Double failProduceRequestPerSec) {
|
||||
this.failProduceRequestPerSec = failProduceRequestPerSec;
|
||||
}
|
||||
|
||||
public Double getFailProduceRequestPerSecMeanRate() {
|
||||
return failProduceRequestPerSecMeanRate;
|
||||
}
|
||||
|
||||
public void setFailProduceRequestPerSecMeanRate(Double failProduceRequestPerSecMeanRate) {
|
||||
this.failProduceRequestPerSecMeanRate = failProduceRequestPerSecMeanRate;
|
||||
}
|
||||
|
||||
public Double getFailProduceRequestPerSecFiveMinuteRate() {
|
||||
return failProduceRequestPerSecFiveMinuteRate;
|
||||
}
|
||||
|
||||
public void setFailProduceRequestPerSecFiveMinuteRate(Double failProduceRequestPerSecFiveMinuteRate) {
|
||||
this.failProduceRequestPerSecFiveMinuteRate = failProduceRequestPerSecFiveMinuteRate;
|
||||
}
|
||||
|
||||
public Double getFailProduceRequestPerSecFifteenMinuteRate() {
|
||||
return failProduceRequestPerSecFifteenMinuteRate;
|
||||
}
|
||||
|
||||
public void setFailProduceRequestPerSecFifteenMinuteRate(Double failProduceRequestPerSecFifteenMinuteRate) {
|
||||
this.failProduceRequestPerSecFifteenMinuteRate = failProduceRequestPerSecFifteenMinuteRate;
|
||||
}
|
||||
|
||||
public Double getFailFetchRequestPerSec() {
|
||||
return failFetchRequestPerSec;
|
||||
}
|
||||
|
||||
public void setFailFetchRequestPerSec(Double failFetchRequestPerSec) {
|
||||
this.failFetchRequestPerSec = failFetchRequestPerSec;
|
||||
}
|
||||
|
||||
public Double getFailFetchRequestPerSecMeanRate() {
|
||||
return failFetchRequestPerSecMeanRate;
|
||||
}
|
||||
|
||||
public void setFailFetchRequestPerSecMeanRate(Double failFetchRequestPerSecMeanRate) {
|
||||
this.failFetchRequestPerSecMeanRate = failFetchRequestPerSecMeanRate;
|
||||
}
|
||||
|
||||
public Double getFailFetchRequestPerSecFiveMinuteRate() {
|
||||
return failFetchRequestPerSecFiveMinuteRate;
|
||||
}
|
||||
|
||||
public void setFailFetchRequestPerSecFiveMinuteRate(Double failFetchRequestPerSecFiveMinuteRate) {
|
||||
this.failFetchRequestPerSecFiveMinuteRate = failFetchRequestPerSecFiveMinuteRate;
|
||||
}
|
||||
|
||||
public Double getFailFetchRequestPerSecFifteenMinuteRate() {
|
||||
return failFetchRequestPerSecFifteenMinuteRate;
|
||||
}
|
||||
|
||||
public void setFailFetchRequestPerSecFifteenMinuteRate(Double failFetchRequestPerSecFifteenMinuteRate) {
|
||||
this.failFetchRequestPerSecFifteenMinuteRate = failFetchRequestPerSecFifteenMinuteRate;
|
||||
}
|
||||
|
||||
public Double getTotalProduceRequestsPerSec() {
|
||||
return totalProduceRequestsPerSec;
|
||||
}
|
||||
|
||||
public void setTotalProduceRequestsPerSec(Double totalProduceRequestsPerSec) {
|
||||
this.totalProduceRequestsPerSec = totalProduceRequestsPerSec;
|
||||
}
|
||||
|
||||
public Double getTotalProduceRequestsPerSecMeanRate() {
|
||||
return totalProduceRequestsPerSecMeanRate;
|
||||
}
|
||||
|
||||
public void setTotalProduceRequestsPerSecMeanRate(Double totalProduceRequestsPerSecMeanRate) {
|
||||
this.totalProduceRequestsPerSecMeanRate = totalProduceRequestsPerSecMeanRate;
|
||||
}
|
||||
|
||||
public Double getTotalProduceRequestsPerSecFiveMinuteRate() {
|
||||
return totalProduceRequestsPerSecFiveMinuteRate;
|
||||
}
|
||||
|
||||
public void setTotalProduceRequestsPerSecFiveMinuteRate(Double totalProduceRequestsPerSecFiveMinuteRate) {
|
||||
this.totalProduceRequestsPerSecFiveMinuteRate = totalProduceRequestsPerSecFiveMinuteRate;
|
||||
}
|
||||
|
||||
public Double getTotalProduceRequestsPerSecFifteenMinuteRate() {
|
||||
return totalProduceRequestsPerSecFifteenMinuteRate;
|
||||
}
|
||||
|
||||
public void setTotalProduceRequestsPerSecFifteenMinuteRate(Double totalProduceRequestsPerSecFifteenMinuteRate) {
|
||||
this.totalProduceRequestsPerSecFifteenMinuteRate = totalProduceRequestsPerSecFifteenMinuteRate;
|
||||
}
|
||||
|
||||
public Double getTotalFetchRequestsPerSec() {
|
||||
return totalFetchRequestsPerSec;
|
||||
}
|
||||
|
||||
public void setTotalFetchRequestsPerSec(Double totalFetchRequestsPerSec) {
|
||||
this.totalFetchRequestsPerSec = totalFetchRequestsPerSec;
|
||||
}
|
||||
|
||||
public Double getTotalFetchRequestsPerSecMeanRate() {
|
||||
return totalFetchRequestsPerSecMeanRate;
|
||||
}
|
||||
|
||||
public void setTotalFetchRequestsPerSecMeanRate(Double totalFetchRequestsPerSecMeanRate) {
|
||||
this.totalFetchRequestsPerSecMeanRate = totalFetchRequestsPerSecMeanRate;
|
||||
}
|
||||
|
||||
public Double getTotalFetchRequestsPerSecFiveMinuteRate() {
|
||||
return totalFetchRequestsPerSecFiveMinuteRate;
|
||||
}
|
||||
|
||||
public void setTotalFetchRequestsPerSecFiveMinuteRate(Double totalFetchRequestsPerSecFiveMinuteRate) {
|
||||
this.totalFetchRequestsPerSecFiveMinuteRate = totalFetchRequestsPerSecFiveMinuteRate;
|
||||
}
|
||||
|
||||
public Double getTotalFetchRequestsPerSecFifteenMinuteRate() {
|
||||
return totalFetchRequestsPerSecFifteenMinuteRate;
|
||||
}
|
||||
|
||||
public void setTotalFetchRequestsPerSecFifteenMinuteRate(Double totalFetchRequestsPerSecFifteenMinuteRate) {
|
||||
this.totalFetchRequestsPerSecFifteenMinuteRate = totalFetchRequestsPerSecFifteenMinuteRate;
|
||||
}
|
||||
}
|
||||
@@ -1,331 +0,0 @@
|
||||
package com.xiaojukeji.kafka.manager.common.entity.metrics;
|
||||
|
||||
import com.xiaojukeji.kafka.manager.common.constant.Constant;
|
||||
import com.xiaojukeji.kafka.manager.common.constant.MetricsType;
|
||||
import com.xiaojukeji.kafka.manager.common.entity.annotations.FieldSelector;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 需要定时拉取的broker数据
|
||||
* @author tukun
|
||||
* @date 2015/11/6.
|
||||
*/
|
||||
public class BrokerMetrics extends BaseMetrics {
|
||||
/**
|
||||
* 集群ID
|
||||
*/
|
||||
private Long clusterId;
|
||||
|
||||
/**
|
||||
* Topic名称
|
||||
*/
|
||||
private Integer brokerId;
|
||||
|
||||
/**
|
||||
* 每秒Produce请求数的近一分钟的均值、平均字节数、近五分钟均值、近十五分钟均值
|
||||
*/
|
||||
@FieldSelector(types = {
|
||||
MetricsType.BROKER_FLOW_DETAIL,
|
||||
MetricsType.BROKER_TO_DB_METRICS,
|
||||
MetricsType.BROKER_REAL_TIME_METRICS
|
||||
})
|
||||
private Double produceRequestPerSec = 0.0;
|
||||
private Double produceRequestPerSecMeanRate = 0.0;
|
||||
private Double produceRequestPerSecFiveMinuteRate = 0.0;
|
||||
private Double produceRequestPerSecFifteenMinuteRate = 0.0;
|
||||
|
||||
/**
|
||||
* 每秒Fetch请求数的近一分钟的均值、平均字节数、近五分钟均值、近十五分钟均值
|
||||
*/
|
||||
@FieldSelector(types = {
|
||||
MetricsType.BROKER_FLOW_DETAIL,
|
||||
MetricsType.BROKER_TO_DB_METRICS,
|
||||
MetricsType.BROKER_REAL_TIME_METRICS
|
||||
})
|
||||
private Double fetchConsumerRequestPerSec = 0.0;
|
||||
private Double fetchConsumerRequestPerSecMeanRate = 0.0;
|
||||
private Double fetchConsumerRequestPerSecFiveMinuteRate = 0.0;
|
||||
private Double fetchConsumerRequestPerSecFifteenMinuteRate = 0.0;
|
||||
|
||||
/**
|
||||
* Broker分区数量
|
||||
*/
|
||||
@FieldSelector(types = {MetricsType.BROKER_OVER_ALL_METRICS, 5})
|
||||
private int partitionCount;
|
||||
|
||||
/**
|
||||
* Broker已同步分区数量
|
||||
*/
|
||||
@FieldSelector(types = {MetricsType.BROKER_OVER_ALL_METRICS})
|
||||
private int underReplicatedPartitions;
|
||||
|
||||
/**
|
||||
* Broker Leader的数量
|
||||
*/
|
||||
@FieldSelector(types = {MetricsType.BROKER_OVER_ALL_METRICS, 5})
|
||||
private int leaderCount;
|
||||
|
||||
/**
|
||||
* Broker请求处理器空闲百分比
|
||||
*/
|
||||
@FieldSelector(types = {MetricsType.BROKER_TO_DB_METRICS})
|
||||
private Double requestHandlerAvgIdlePercent = 0.0;
|
||||
|
||||
/**
|
||||
* 网络处理器空闲百分比
|
||||
*/
|
||||
@FieldSelector(types = {MetricsType.BROKER_TO_DB_METRICS})
|
||||
private Double networkProcessorAvgIdlePercent = 0.0;
|
||||
|
||||
/**
|
||||
* 请求列表大小
|
||||
*/
|
||||
@FieldSelector(types = {MetricsType.BROKER_TO_DB_METRICS})
|
||||
private Integer requestQueueSize = 0;
|
||||
|
||||
/**
|
||||
* 响应列表大小
|
||||
*/
|
||||
@FieldSelector(types = {MetricsType.BROKER_TO_DB_METRICS})
|
||||
private Integer responseQueueSize = 0;
|
||||
|
||||
/**
|
||||
* 刷日志时间
|
||||
*/
|
||||
@FieldSelector(types = {MetricsType.BROKER_TO_DB_METRICS})
|
||||
private Double logFlushRateAndTimeMs = 0.0;
|
||||
|
||||
/**
|
||||
* produce请求总时间-平均值
|
||||
*/
|
||||
@FieldSelector(types = {MetricsType.BROKER_TO_DB_METRICS})
|
||||
private Double totalTimeProduceMean = 0.0;
|
||||
|
||||
/**
|
||||
* produce请求总时间-99th
|
||||
*/
|
||||
@FieldSelector(types = {MetricsType.BROKER_TO_DB_METRICS})
|
||||
private Double totalTimeProduce99Th = 0.0;
|
||||
|
||||
/**
|
||||
* fetch consumer请求总时间-平均值
|
||||
*/
|
||||
@FieldSelector(types = {MetricsType.BROKER_TO_DB_METRICS})
|
||||
private Double totalTimeFetchConsumerMean = 0.0;
|
||||
|
||||
/**
|
||||
* fetch consumer请求总时间-99th
|
||||
*/
|
||||
@FieldSelector(types = {MetricsType.BROKER_TO_DB_METRICS})
|
||||
private Double totalTimeFetchConsumer99Th = 0.0;
|
||||
|
||||
public Long getClusterId() {
|
||||
return clusterId;
|
||||
}
|
||||
|
||||
public void setClusterId(Long clusterId) {
|
||||
this.clusterId = clusterId;
|
||||
}
|
||||
|
||||
public Integer getBrokerId() {
|
||||
return brokerId;
|
||||
}
|
||||
|
||||
public void setBrokerId(Integer brokerId) {
|
||||
this.brokerId = brokerId;
|
||||
}
|
||||
|
||||
public Double getProduceRequestPerSec() {
|
||||
return produceRequestPerSec;
|
||||
}
|
||||
|
||||
public void setProduceRequestPerSec(Double produceRequestPerSec) {
|
||||
this.produceRequestPerSec = produceRequestPerSec;
|
||||
}
|
||||
|
||||
public Double getProduceRequestPerSecMeanRate() {
|
||||
return produceRequestPerSecMeanRate;
|
||||
}
|
||||
|
||||
public void setProduceRequestPerSecMeanRate(Double produceRequestPerSecMeanRate) {
|
||||
this.produceRequestPerSecMeanRate = produceRequestPerSecMeanRate;
|
||||
}
|
||||
|
||||
public Double getProduceRequestPerSecFiveMinuteRate() {
|
||||
return produceRequestPerSecFiveMinuteRate;
|
||||
}
|
||||
|
||||
public void setProduceRequestPerSecFiveMinuteRate(Double produceRequestPerSecFiveMinuteRate) {
|
||||
this.produceRequestPerSecFiveMinuteRate = produceRequestPerSecFiveMinuteRate;
|
||||
}
|
||||
|
||||
public Double getProduceRequestPerSecFifteenMinuteRate() {
|
||||
return produceRequestPerSecFifteenMinuteRate;
|
||||
}
|
||||
|
||||
public void setProduceRequestPerSecFifteenMinuteRate(Double produceRequestPerSecFifteenMinuteRate) {
|
||||
this.produceRequestPerSecFifteenMinuteRate = produceRequestPerSecFifteenMinuteRate;
|
||||
}
|
||||
|
||||
public Double getFetchConsumerRequestPerSec() {
|
||||
return fetchConsumerRequestPerSec;
|
||||
}
|
||||
|
||||
public void setFetchConsumerRequestPerSec(Double fetchConsumerRequestPerSec) {
|
||||
this.fetchConsumerRequestPerSec = fetchConsumerRequestPerSec;
|
||||
}
|
||||
|
||||
public Double getFetchConsumerRequestPerSecMeanRate() {
|
||||
return fetchConsumerRequestPerSecMeanRate;
|
||||
}
|
||||
|
||||
public void setFetchConsumerRequestPerSecMeanRate(Double fetchConsumerRequestPerSecMeanRate) {
|
||||
this.fetchConsumerRequestPerSecMeanRate = fetchConsumerRequestPerSecMeanRate;
|
||||
}
|
||||
|
||||
public Double getFetchConsumerRequestPerSecFiveMinuteRate() {
|
||||
return fetchConsumerRequestPerSecFiveMinuteRate;
|
||||
}
|
||||
|
||||
public void setFetchConsumerRequestPerSecFiveMinuteRate(Double fetchConsumerRequestPerSecFiveMinuteRate) {
|
||||
this.fetchConsumerRequestPerSecFiveMinuteRate = fetchConsumerRequestPerSecFiveMinuteRate;
|
||||
}
|
||||
|
||||
public Double getFetchConsumerRequestPerSecFifteenMinuteRate() {
|
||||
return fetchConsumerRequestPerSecFifteenMinuteRate;
|
||||
}
|
||||
|
||||
public void setFetchConsumerRequestPerSecFifteenMinuteRate(Double fetchConsumerRequestPerSecFifteenMinuteRate) {
|
||||
this.fetchConsumerRequestPerSecFifteenMinuteRate = fetchConsumerRequestPerSecFifteenMinuteRate;
|
||||
}
|
||||
|
||||
public int getPartitionCount() {
|
||||
return partitionCount;
|
||||
}
|
||||
|
||||
public void setPartitionCount(int partitionCount) {
|
||||
this.partitionCount = partitionCount;
|
||||
}
|
||||
|
||||
public int getUnderReplicatedPartitions() {
|
||||
return underReplicatedPartitions;
|
||||
}
|
||||
|
||||
public void setUnderReplicatedPartitions(int underReplicatedPartitions) {
|
||||
this.underReplicatedPartitions = underReplicatedPartitions;
|
||||
}
|
||||
|
||||
public int getLeaderCount() {
|
||||
return leaderCount;
|
||||
}
|
||||
|
||||
public void setLeaderCount(int leaderCount) {
|
||||
this.leaderCount = leaderCount;
|
||||
}
|
||||
|
||||
public Double getRequestHandlerAvgIdlePercent() {
|
||||
return requestHandlerAvgIdlePercent;
|
||||
}
|
||||
|
||||
public void setRequestHandlerAvgIdlePercent(Double requestHandlerAvgIdlePercent) {
|
||||
this.requestHandlerAvgIdlePercent = requestHandlerAvgIdlePercent;
|
||||
}
|
||||
|
||||
public Double getNetworkProcessorAvgIdlePercent() {
|
||||
return networkProcessorAvgIdlePercent;
|
||||
}
|
||||
|
||||
public void setNetworkProcessorAvgIdlePercent(Double networkProcessorAvgIdlePercent) {
|
||||
this.networkProcessorAvgIdlePercent = networkProcessorAvgIdlePercent;
|
||||
}
|
||||
|
||||
public Integer getRequestQueueSize() {
|
||||
return requestQueueSize;
|
||||
}
|
||||
|
||||
public void setRequestQueueSize(Integer requestQueueSize) {
|
||||
this.requestQueueSize = requestQueueSize;
|
||||
}
|
||||
|
||||
public Integer getResponseQueueSize() {
|
||||
return responseQueueSize;
|
||||
}
|
||||
|
||||
public void setResponseQueueSize(Integer responseQueueSize) {
|
||||
this.responseQueueSize = responseQueueSize;
|
||||
}
|
||||
|
||||
public Double getLogFlushRateAndTimeMs() {
|
||||
return logFlushRateAndTimeMs;
|
||||
}
|
||||
|
||||
public void setLogFlushRateAndTimeMs(Double logFlushRateAndTimeMs) {
|
||||
this.logFlushRateAndTimeMs = logFlushRateAndTimeMs;
|
||||
}
|
||||
|
||||
public Double getTotalTimeProduceMean() {
|
||||
return totalTimeProduceMean;
|
||||
}
|
||||
|
||||
public void setTotalTimeProduceMean(Double totalTimeProduceMean) {
|
||||
this.totalTimeProduceMean = totalTimeProduceMean;
|
||||
}
|
||||
|
||||
public Double getTotalTimeProduce99Th() {
|
||||
return totalTimeProduce99Th;
|
||||
}
|
||||
|
||||
public void setTotalTimeProduce99Th(Double totalTimeProduce99Th) {
|
||||
this.totalTimeProduce99Th = totalTimeProduce99Th;
|
||||
}
|
||||
|
||||
public Double getTotalTimeFetchConsumerMean() {
|
||||
return totalTimeFetchConsumerMean;
|
||||
}
|
||||
|
||||
public void setTotalTimeFetchConsumerMean(Double totalTimeFetchConsumerMean) {
|
||||
this.totalTimeFetchConsumerMean = totalTimeFetchConsumerMean;
|
||||
}
|
||||
|
||||
public Double getTotalTimeFetchConsumer99Th() {
|
||||
return totalTimeFetchConsumer99Th;
|
||||
}
|
||||
|
||||
public void setTotalTimeFetchConsumer99Th(Double totalTimeFetchConsumer99Th) {
|
||||
this.totalTimeFetchConsumer99Th = totalTimeFetchConsumer99Th;
|
||||
}
|
||||
|
||||
private static void initialization(Field[] fields){
|
||||
for(Field field : fields){
|
||||
FieldSelector annotation = field.getAnnotation(FieldSelector.class);
|
||||
if(annotation ==null){
|
||||
continue;
|
||||
}
|
||||
|
||||
String fieldName;
|
||||
if("".equals(annotation.name())) {
|
||||
fieldName = field.getName().substring(0,1).toUpperCase() + field.getName().substring(1);
|
||||
} else{
|
||||
fieldName = annotation.name();
|
||||
}
|
||||
for(int type: annotation.types()){
|
||||
List<String> list = Constant.BROKER_METRICS_TYPE_MBEAN_NAME_MAP.getOrDefault(type, new ArrayList<>());
|
||||
list.add(fieldName);
|
||||
Constant.BROKER_METRICS_TYPE_MBEAN_NAME_MAP.put(type, list);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static List<String> getFieldNameList(int metricsType){
|
||||
synchronized (BrokerMetrics.class) {
|
||||
if (Constant.BROKER_METRICS_TYPE_MBEAN_NAME_MAP.isEmpty()) {
|
||||
initialization(BrokerMetrics.class.getDeclaredFields());
|
||||
initialization(BaseMetrics.class.getDeclaredFields());
|
||||
}
|
||||
}
|
||||
return Constant.BROKER_METRICS_TYPE_MBEAN_NAME_MAP.getOrDefault(metricsType, new ArrayList<>());
|
||||
}
|
||||
}
|
||||
@@ -1,68 +0,0 @@
|
||||
package com.xiaojukeji.kafka.manager.common.entity.metrics;
|
||||
|
||||
import com.xiaojukeji.kafka.manager.common.constant.Constant;
|
||||
import com.xiaojukeji.kafka.manager.common.entity.annotations.FieldSelector;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class TopicMetrics extends BaseMetrics {
|
||||
/**
|
||||
* 集群ID
|
||||
*/
|
||||
private Long clusterId;
|
||||
|
||||
/**
|
||||
* Topic名称
|
||||
*/
|
||||
private String topicName;
|
||||
|
||||
public Long getClusterId() {
|
||||
return clusterId;
|
||||
}
|
||||
|
||||
public void setClusterId(Long clusterId) {
|
||||
this.clusterId = clusterId;
|
||||
}
|
||||
|
||||
public String getTopicName() {
|
||||
return topicName;
|
||||
}
|
||||
|
||||
public void setTopicName(String topicName) {
|
||||
this.topicName = topicName;
|
||||
}
|
||||
|
||||
private static void initialization(Field[] fields){
|
||||
for(Field field : fields){
|
||||
FieldSelector annotation = field.getAnnotation(FieldSelector.class);
|
||||
if(annotation ==null){
|
||||
continue;
|
||||
}
|
||||
String fieldName;
|
||||
if("".equals(annotation.name())){
|
||||
String name = field.getName();
|
||||
fieldName = name.substring(0,1).toUpperCase()+name.substring(1);
|
||||
}else{
|
||||
fieldName = annotation.name();
|
||||
}
|
||||
for(int type: annotation.types()){
|
||||
List<String> list = Constant.TOPIC_METRICS_TYPE_MBEAN_NAME_MAP.getOrDefault(type, new ArrayList<>());
|
||||
list.add(fieldName);
|
||||
Constant.TOPIC_METRICS_TYPE_MBEAN_NAME_MAP.put(type, list);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static List<String> getFieldNameList(int type){
|
||||
synchronized (TopicMetrics.class) {
|
||||
if (Constant.TOPIC_METRICS_TYPE_MBEAN_NAME_MAP.isEmpty()) {
|
||||
initialization(TopicMetrics.class.getDeclaredFields());
|
||||
initialization(BaseMetrics.class.getDeclaredFields());
|
||||
}
|
||||
}
|
||||
return Constant.TOPIC_METRICS_TYPE_MBEAN_NAME_MAP.get(type);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,68 +0,0 @@
|
||||
package com.xiaojukeji.kafka.manager.common.entity.po;
|
||||
|
||||
public class AlarmRuleDO extends BaseDO {
|
||||
private String alarmName;
|
||||
|
||||
private String strategyExpressions;
|
||||
|
||||
private String strategyFilters;
|
||||
|
||||
private String strategyActions;
|
||||
|
||||
private String principals;
|
||||
|
||||
public String getAlarmName() {
|
||||
return alarmName;
|
||||
}
|
||||
|
||||
public void setAlarmName(String alarmName) {
|
||||
this.alarmName = alarmName;
|
||||
}
|
||||
|
||||
public String getStrategyExpressions() {
|
||||
return strategyExpressions;
|
||||
}
|
||||
|
||||
public void setStrategyExpressions(String strategyExpressions) {
|
||||
this.strategyExpressions = strategyExpressions;
|
||||
}
|
||||
|
||||
public String getStrategyFilters() {
|
||||
return strategyFilters;
|
||||
}
|
||||
|
||||
public void setStrategyFilters(String strategyFilters) {
|
||||
this.strategyFilters = strategyFilters;
|
||||
}
|
||||
|
||||
public String getStrategyActions() {
|
||||
return strategyActions;
|
||||
}
|
||||
|
||||
public void setStrategyActions(String strategyActions) {
|
||||
this.strategyActions = strategyActions;
|
||||
}
|
||||
|
||||
public String getPrincipals() {
|
||||
return principals;
|
||||
}
|
||||
|
||||
public void setPrincipals(String principals) {
|
||||
this.principals = principals;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "AlarmRuleDO{" +
|
||||
"alarmName='" + alarmName + '\'' +
|
||||
", strategyExpressions='" + strategyExpressions + '\'' +
|
||||
", strategyFilters='" + strategyFilters + '\'' +
|
||||
", strategyActions='" + strategyActions + '\'' +
|
||||
", principals='" + principals + '\'' +
|
||||
", id=" + id +
|
||||
", status=" + status +
|
||||
", gmtCreate=" + gmtCreate +
|
||||
", gmtModify=" + gmtModify +
|
||||
'}';
|
||||
}
|
||||
}
|
||||
@@ -1,59 +0,0 @@
|
||||
package com.xiaojukeji.kafka.manager.common.entity.po;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* @author arthur
|
||||
* @date 2017/7/25.
|
||||
*/
|
||||
public class BaseDO {
|
||||
protected Long id;
|
||||
|
||||
protected Integer status;
|
||||
|
||||
protected Date gmtCreate;
|
||||
|
||||
protected Date gmtModify;
|
||||
|
||||
public Long getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(Long id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public Integer getStatus() {
|
||||
return status;
|
||||
}
|
||||
|
||||
public void setStatus(Integer status) {
|
||||
this.status = status;
|
||||
}
|
||||
|
||||
public Date getGmtCreate() {
|
||||
return gmtCreate;
|
||||
}
|
||||
|
||||
public void setGmtCreate(Date gmtCreate) {
|
||||
this.gmtCreate = gmtCreate;
|
||||
}
|
||||
|
||||
public Date getGmtModify() {
|
||||
return gmtModify;
|
||||
}
|
||||
|
||||
public void setGmtModify(Date gmtModify) {
|
||||
this.gmtModify = gmtModify;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "BaseDO{" +
|
||||
"id=" + id +
|
||||
", status=" + status +
|
||||
", gmtCreate=" + gmtCreate +
|
||||
", gmtModify=" + gmtModify +
|
||||
'}';
|
||||
}
|
||||
}
|
||||
@@ -1,37 +0,0 @@
|
||||
package com.xiaojukeji.kafka.manager.common.entity.po;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* @author zengqiao
|
||||
* @date 19/11/25
|
||||
*/
|
||||
public abstract class BaseEntryDO {
|
||||
protected Long id;
|
||||
|
||||
protected Date gmtCreate;
|
||||
|
||||
public Long getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(Long id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public Date getGmtCreate() {
|
||||
return gmtCreate;
|
||||
}
|
||||
|
||||
public void setGmtCreate(Date gmtCreate) {
|
||||
this.gmtCreate = gmtCreate;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "BaseEntryDO{" +
|
||||
"id=" + id +
|
||||
", gmtCreate=" + gmtCreate +
|
||||
'}';
|
||||
}
|
||||
}
|
||||
@@ -1,127 +0,0 @@
|
||||
package com.xiaojukeji.kafka.manager.common.entity.po;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
public class ClusterDO extends BaseDO{
|
||||
private String clusterName;
|
||||
|
||||
private String zookeeper;
|
||||
|
||||
private String bootstrapServers;
|
||||
|
||||
private String kafkaVersion;
|
||||
|
||||
private Integer alarmFlag;
|
||||
|
||||
private String securityProtocol;
|
||||
|
||||
private String saslMechanism;
|
||||
|
||||
private String saslJaasConfig;
|
||||
|
||||
public String getClusterName() {
|
||||
return clusterName;
|
||||
}
|
||||
|
||||
public void setClusterName(String clusterName) {
|
||||
this.clusterName = clusterName;
|
||||
}
|
||||
|
||||
public String getZookeeper() {
|
||||
return zookeeper;
|
||||
}
|
||||
|
||||
public void setZookeeper(String zookeeper) {
|
||||
this.zookeeper = zookeeper;
|
||||
}
|
||||
|
||||
public String getBootstrapServers() {
|
||||
return bootstrapServers;
|
||||
}
|
||||
|
||||
public void setBootstrapServers(String bootstrapServers) {
|
||||
this.bootstrapServers = bootstrapServers;
|
||||
}
|
||||
|
||||
public String getKafkaVersion() {
|
||||
return kafkaVersion;
|
||||
}
|
||||
|
||||
public void setKafkaVersion(String kafkaVersion) {
|
||||
this.kafkaVersion = kafkaVersion;
|
||||
}
|
||||
|
||||
public Integer getAlarmFlag() {
|
||||
return alarmFlag;
|
||||
}
|
||||
|
||||
public void setAlarmFlag(Integer alarmFlag) {
|
||||
this.alarmFlag = alarmFlag;
|
||||
}
|
||||
|
||||
public String getSecurityProtocol() {
|
||||
return securityProtocol;
|
||||
}
|
||||
|
||||
public void setSecurityProtocol(String securityProtocol) {
|
||||
this.securityProtocol = securityProtocol;
|
||||
}
|
||||
|
||||
public String getSaslMechanism() {
|
||||
return saslMechanism;
|
||||
}
|
||||
|
||||
public void setSaslMechanism(String saslMechanism) {
|
||||
this.saslMechanism = saslMechanism;
|
||||
}
|
||||
|
||||
public String getSaslJaasConfig() {
|
||||
return saslJaasConfig;
|
||||
}
|
||||
|
||||
public void setSaslJaasConfig(String saslJaasConfig) {
|
||||
this.saslJaasConfig = saslJaasConfig;
|
||||
}
|
||||
|
||||
public Integer getStatus() {
|
||||
return status;
|
||||
}
|
||||
|
||||
public void setStatus(Integer status) {
|
||||
this.status = status;
|
||||
}
|
||||
|
||||
public Date getGmtCreate() {
|
||||
return gmtCreate;
|
||||
}
|
||||
|
||||
public void setGmtCreate(Date gmtCreate) {
|
||||
this.gmtCreate = gmtCreate;
|
||||
}
|
||||
|
||||
public Date getGmtModify() {
|
||||
return gmtModify;
|
||||
}
|
||||
|
||||
public void setGmtModify(Date gmtModify) {
|
||||
this.gmtModify = gmtModify;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "ClusterDO{" +
|
||||
"clusterName='" + clusterName + '\'' +
|
||||
", zookeeper='" + zookeeper + '\'' +
|
||||
", bootstrapServers='" + bootstrapServers + '\'' +
|
||||
", kafkaVersion='" + kafkaVersion + '\'' +
|
||||
", alarmFlag=" + alarmFlag +
|
||||
", securityProtocol='" + securityProtocol + '\'' +
|
||||
", saslMechanism='" + saslMechanism + '\'' +
|
||||
", saslJaasConfig='" + saslJaasConfig + '\'' +
|
||||
", id=" + id +
|
||||
", status=" + status +
|
||||
", gmtCreate=" + gmtCreate +
|
||||
", gmtModify=" + gmtModify +
|
||||
'}';
|
||||
}
|
||||
}
|
||||
@@ -1,110 +0,0 @@
|
||||
package com.xiaojukeji.kafka.manager.common.entity.po;
|
||||
|
||||
import com.xiaojukeji.kafka.manager.common.entity.metrics.BrokerMetrics;
|
||||
|
||||
public class ClusterMetricsDO extends BaseEntryDO {
|
||||
private Long clusterId;
|
||||
|
||||
private Integer topicNum = 0;
|
||||
|
||||
private Integer partitionNum = 0;
|
||||
|
||||
private Integer brokerNum = 0;
|
||||
|
||||
private Double bytesInPerSec = 0.0;
|
||||
|
||||
private Double bytesOutPerSec = 0.0;
|
||||
|
||||
private Double bytesRejectedPerSec = 0.0;
|
||||
|
||||
private Double messagesInPerSec = 0.0;
|
||||
|
||||
public Long getClusterId() {
|
||||
return clusterId;
|
||||
}
|
||||
|
||||
public void setClusterId(Long clusterId) {
|
||||
this.clusterId = clusterId;
|
||||
}
|
||||
|
||||
public Integer getTopicNum() {
|
||||
return topicNum;
|
||||
}
|
||||
|
||||
public void setTopicNum(Integer topicNum) {
|
||||
this.topicNum = topicNum;
|
||||
}
|
||||
|
||||
public Integer getPartitionNum() {
|
||||
return partitionNum;
|
||||
}
|
||||
|
||||
public void setPartitionNum(Integer partitionNum) {
|
||||
this.partitionNum = partitionNum;
|
||||
}
|
||||
|
||||
public Integer getBrokerNum() {
|
||||
return brokerNum;
|
||||
}
|
||||
|
||||
public void setBrokerNum(Integer brokerNum) {
|
||||
this.brokerNum = brokerNum;
|
||||
}
|
||||
|
||||
public Double getBytesInPerSec() {
|
||||
return bytesInPerSec;
|
||||
}
|
||||
|
||||
public void setBytesInPerSec(Double bytesInPerSec) {
|
||||
this.bytesInPerSec = bytesInPerSec;
|
||||
}
|
||||
|
||||
public Double getBytesOutPerSec() {
|
||||
return bytesOutPerSec;
|
||||
}
|
||||
|
||||
public void setBytesOutPerSec(Double bytesOutPerSec) {
|
||||
this.bytesOutPerSec = bytesOutPerSec;
|
||||
}
|
||||
|
||||
public Double getBytesRejectedPerSec() {
|
||||
return bytesRejectedPerSec;
|
||||
}
|
||||
|
||||
public void setBytesRejectedPerSec(Double bytesRejectedPerSec) {
|
||||
this.bytesRejectedPerSec = bytesRejectedPerSec;
|
||||
}
|
||||
|
||||
public Double getMessagesInPerSec() {
|
||||
return messagesInPerSec;
|
||||
}
|
||||
|
||||
public void setMessagesInPerSec(Double messagesInPerSec) {
|
||||
this.messagesInPerSec = messagesInPerSec;
|
||||
}
|
||||
|
||||
public void addBrokerMetrics(BrokerMetrics brokerMetrics) {
|
||||
this.clusterId = brokerMetrics.getClusterId();
|
||||
this.brokerNum += 1;
|
||||
this.bytesInPerSec += brokerMetrics.getBytesInPerSec();
|
||||
this.bytesOutPerSec += brokerMetrics.getBytesOutPerSec();
|
||||
this.bytesRejectedPerSec += brokerMetrics.getBytesRejectedPerSec();
|
||||
this.messagesInPerSec += brokerMetrics.getMessagesInPerSec();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "ClusterMetricsDO{" +
|
||||
"clusterId=" + clusterId +
|
||||
", topicNum=" + topicNum +
|
||||
", partitionNum=" + partitionNum +
|
||||
", brokerNum=" + brokerNum +
|
||||
", bytesInPerSec=" + bytesInPerSec +
|
||||
", bytesOutPerSec=" + bytesOutPerSec +
|
||||
", bytesRejectedPerSec=" + bytesRejectedPerSec +
|
||||
", messagesInPerSec=" + messagesInPerSec +
|
||||
", id=" + id +
|
||||
", gmtCreate=" + gmtCreate +
|
||||
'}';
|
||||
}
|
||||
}
|
||||
@@ -1,96 +0,0 @@
|
||||
package com.xiaojukeji.kafka.manager.common.entity.po;
|
||||
|
||||
/**
|
||||
* migrate topic task do
|
||||
* @author zengqiao
|
||||
* @date 19/4/16
|
||||
*/
|
||||
public class MigrationTaskDO extends BaseDO {
|
||||
private Long clusterId;
|
||||
|
||||
private String topicName;
|
||||
|
||||
private String reassignmentJson;
|
||||
|
||||
private Long throttle;
|
||||
|
||||
private String operator;
|
||||
|
||||
private String description;
|
||||
|
||||
public String getDescription() {
|
||||
return description;
|
||||
}
|
||||
|
||||
public void setDescription(String description) {
|
||||
this.description = description;
|
||||
}
|
||||
|
||||
public String getOperator() {
|
||||
return operator;
|
||||
}
|
||||
|
||||
public void setOperator(String operator) {
|
||||
this.operator = operator;
|
||||
}
|
||||
|
||||
public Long getClusterId() {
|
||||
return clusterId;
|
||||
}
|
||||
|
||||
public void setClusterId(Long clusterId) {
|
||||
this.clusterId = clusterId;
|
||||
}
|
||||
|
||||
public String getTopicName() {
|
||||
return topicName;
|
||||
}
|
||||
|
||||
public void setTopicName(String topicName) {
|
||||
this.topicName = topicName;
|
||||
}
|
||||
|
||||
public String getReassignmentJson() {
|
||||
return reassignmentJson;
|
||||
}
|
||||
|
||||
public void setReassignmentJson(String reassignmentJson) {
|
||||
this.reassignmentJson = reassignmentJson;
|
||||
}
|
||||
|
||||
public Long getThrottle() {
|
||||
return throttle;
|
||||
}
|
||||
|
||||
public void setThrottle(Long throttle) {
|
||||
this.throttle = throttle;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "MigrationTaskDO{" +
|
||||
"clusterId=" + clusterId +
|
||||
", topicName='" + topicName + '\'' +
|
||||
", reassignmentJson='" + reassignmentJson + '\'' +
|
||||
", throttle=" + throttle +
|
||||
", id=" + id +
|
||||
", status=" + status +
|
||||
", gmtCreate=" + gmtCreate +
|
||||
", gmtModify=" + gmtModify +
|
||||
'}';
|
||||
}
|
||||
|
||||
public static MigrationTaskDO createInstance(Long clusterId,
|
||||
String topicName,
|
||||
String reassignmentJson,
|
||||
Long throttle,
|
||||
String description) {
|
||||
MigrationTaskDO migrationTaskDO = new MigrationTaskDO();
|
||||
migrationTaskDO.setClusterId(clusterId);
|
||||
migrationTaskDO.setTopicName(topicName);
|
||||
migrationTaskDO.setReassignmentJson(reassignmentJson);
|
||||
migrationTaskDO.setThrottle(throttle);
|
||||
migrationTaskDO.setDescription(description);
|
||||
return migrationTaskDO;
|
||||
}
|
||||
}
|
||||
@@ -1,64 +0,0 @@
|
||||
package com.xiaojukeji.kafka.manager.common.entity.po;
|
||||
|
||||
public class OperationHistoryDO extends BaseEntryDO {
|
||||
private Long clusterId;
|
||||
|
||||
private String topicName;
|
||||
|
||||
private String operator;
|
||||
|
||||
private String operation;
|
||||
|
||||
public Long getClusterId() {
|
||||
return clusterId;
|
||||
}
|
||||
|
||||
public void setClusterId(Long clusterId) {
|
||||
this.clusterId = clusterId;
|
||||
}
|
||||
|
||||
public String getTopicName() {
|
||||
return topicName;
|
||||
}
|
||||
|
||||
public void setTopicName(String topicName) {
|
||||
this.topicName = topicName;
|
||||
}
|
||||
|
||||
public String getOperator() {
|
||||
return operator;
|
||||
}
|
||||
|
||||
public void setOperator(String operator) {
|
||||
this.operator = operator;
|
||||
}
|
||||
|
||||
public String getOperation() {
|
||||
return operation;
|
||||
}
|
||||
|
||||
public void setOperation(String operation) {
|
||||
this.operation = operation;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "OperationHistoryDO{" +
|
||||
"clusterId=" + clusterId +
|
||||
", topicName='" + topicName + '\'' +
|
||||
", operator='" + operator + '\'' +
|
||||
", operation='" + operation + '\'' +
|
||||
", id=" + id +
|
||||
", gmtCreate=" + gmtCreate +
|
||||
'}';
|
||||
}
|
||||
|
||||
public static OperationHistoryDO newInstance(Long clusterId, String topicName, String operator, String operation) {
|
||||
OperationHistoryDO operationHistoryDO = new OperationHistoryDO();
|
||||
operationHistoryDO.setClusterId(clusterId);
|
||||
operationHistoryDO.setTopicName(topicName);
|
||||
operationHistoryDO.setOperator(operator);
|
||||
operationHistoryDO.setOperation(operation);
|
||||
return operationHistoryDO;
|
||||
}
|
||||
}
|
||||
@@ -1,134 +0,0 @@
|
||||
package com.xiaojukeji.kafka.manager.common.entity.po;
|
||||
|
||||
public class OrderPartitionDO extends BaseDO{
|
||||
private Long clusterId;
|
||||
|
||||
private String clusterName;
|
||||
|
||||
private String topicName;
|
||||
|
||||
private String applicant;
|
||||
|
||||
private Integer partitionNum;
|
||||
|
||||
private String brokerList;
|
||||
|
||||
private Long peakBytesIn;
|
||||
|
||||
private String description;
|
||||
|
||||
private Integer orderStatus;
|
||||
|
||||
private String approver;
|
||||
|
||||
private String opinion;
|
||||
|
||||
public Long getClusterId() {
|
||||
return clusterId;
|
||||
}
|
||||
|
||||
public void setClusterId(Long clusterId) {
|
||||
this.clusterId = clusterId;
|
||||
}
|
||||
|
||||
public String getClusterName() {
|
||||
return clusterName;
|
||||
}
|
||||
|
||||
public void setClusterName(String clusterName) {
|
||||
this.clusterName = clusterName;
|
||||
}
|
||||
|
||||
public String getTopicName() {
|
||||
return topicName;
|
||||
}
|
||||
|
||||
public void setTopicName(String topicName) {
|
||||
this.topicName = topicName;
|
||||
}
|
||||
|
||||
public String getApplicant() {
|
||||
return applicant;
|
||||
}
|
||||
|
||||
public void setApplicant(String applicant) {
|
||||
this.applicant = applicant;
|
||||
}
|
||||
|
||||
public Integer getPartitionNum() {
|
||||
return partitionNum;
|
||||
}
|
||||
|
||||
public void setPartitionNum(Integer partitionNum) {
|
||||
this.partitionNum = partitionNum;
|
||||
}
|
||||
|
||||
public String getBrokerList() {
|
||||
return brokerList;
|
||||
}
|
||||
|
||||
public void setBrokerList(String brokerList) {
|
||||
this.brokerList = brokerList;
|
||||
}
|
||||
|
||||
public Long getPeakBytesIn() {
|
||||
return peakBytesIn;
|
||||
}
|
||||
|
||||
public void setPeakBytesIn(Long peakBytesIn) {
|
||||
this.peakBytesIn = peakBytesIn;
|
||||
}
|
||||
|
||||
public String getDescription() {
|
||||
return description;
|
||||
}
|
||||
|
||||
public void setDescription(String description) {
|
||||
this.description = description;
|
||||
}
|
||||
|
||||
public Integer getOrderStatus() {
|
||||
return orderStatus;
|
||||
}
|
||||
|
||||
public void setOrderStatus(Integer orderStatus) {
|
||||
this.orderStatus = orderStatus;
|
||||
}
|
||||
|
||||
public String getApprover() {
|
||||
return approver;
|
||||
}
|
||||
|
||||
public void setApprover(String approver) {
|
||||
this.approver = approver;
|
||||
}
|
||||
|
||||
public String getOpinion() {
|
||||
return opinion;
|
||||
}
|
||||
|
||||
public void setOpinion(String opinion) {
|
||||
this.opinion = opinion;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "OrderPartitionDO{" +
|
||||
"clusterId=" + clusterId +
|
||||
", clusterName='" + clusterName + '\'' +
|
||||
", topicName='" + topicName + '\'' +
|
||||
", applicant='" + applicant + '\'' +
|
||||
", partitionNum=" + partitionNum +
|
||||
", brokerList='" + brokerList + '\'' +
|
||||
", peakBytesIn=" + peakBytesIn +
|
||||
", description='" + description + '\'' +
|
||||
", orderStatus=" + orderStatus +
|
||||
", approver='" + approver + '\'' +
|
||||
", opinion='" + opinion + '\'' +
|
||||
", id=" + id +
|
||||
", status=" + status +
|
||||
", gmtCreate=" + gmtCreate +
|
||||
", gmtModify=" + gmtModify +
|
||||
'}';
|
||||
}
|
||||
}
|
||||
@@ -1,178 +0,0 @@
|
||||
package com.xiaojukeji.kafka.manager.common.entity.po;
|
||||
|
||||
public class OrderTopicDO extends BaseDO {
|
||||
private Long clusterId;
|
||||
|
||||
private String clusterName;
|
||||
|
||||
private String topicName;
|
||||
|
||||
private Long retentionTime;
|
||||
|
||||
private Integer partitionNum;
|
||||
|
||||
private Integer replicaNum;
|
||||
|
||||
private String regions;
|
||||
|
||||
private String brokers;
|
||||
|
||||
private Long peakBytesIn;
|
||||
|
||||
private String applicant;
|
||||
|
||||
private String principals;
|
||||
|
||||
private String description;
|
||||
|
||||
private Integer orderStatus;
|
||||
|
||||
private String approver;
|
||||
|
||||
private String opinion;
|
||||
|
||||
public Long getClusterId() {
|
||||
return clusterId;
|
||||
}
|
||||
|
||||
public void setClusterId(Long clusterId) {
|
||||
this.clusterId = clusterId;
|
||||
}
|
||||
|
||||
public String getClusterName() {
|
||||
return clusterName;
|
||||
}
|
||||
|
||||
public void setClusterName(String clusterName) {
|
||||
this.clusterName = clusterName;
|
||||
}
|
||||
|
||||
public String getTopicName() {
|
||||
return topicName;
|
||||
}
|
||||
|
||||
public void setTopicName(String topicName) {
|
||||
this.topicName = topicName;
|
||||
}
|
||||
|
||||
public Long getRetentionTime() {
|
||||
return retentionTime;
|
||||
}
|
||||
|
||||
public void setRetentionTime(Long retentionTime) {
|
||||
this.retentionTime = retentionTime;
|
||||
}
|
||||
|
||||
public Integer getPartitionNum() {
|
||||
return partitionNum;
|
||||
}
|
||||
|
||||
public void setPartitionNum(Integer partitionNum) {
|
||||
this.partitionNum = partitionNum;
|
||||
}
|
||||
|
||||
public Integer getReplicaNum() {
|
||||
return replicaNum;
|
||||
}
|
||||
|
||||
public void setReplicaNum(Integer replicaNum) {
|
||||
this.replicaNum = replicaNum;
|
||||
}
|
||||
|
||||
public String getRegions() {
|
||||
return regions;
|
||||
}
|
||||
|
||||
public void setRegions(String regions) {
|
||||
this.regions = regions;
|
||||
}
|
||||
|
||||
public String getBrokers() {
|
||||
return brokers;
|
||||
}
|
||||
|
||||
public void setBrokers(String brokers) {
|
||||
this.brokers = brokers;
|
||||
}
|
||||
|
||||
public Long getPeakBytesIn() {
|
||||
return peakBytesIn;
|
||||
}
|
||||
|
||||
public void setPeakBytesIn(Long peakBytesIn) {
|
||||
this.peakBytesIn = peakBytesIn;
|
||||
}
|
||||
|
||||
public String getApplicant() {
|
||||
return applicant;
|
||||
}
|
||||
|
||||
public void setApplicant(String applicant) {
|
||||
this.applicant = applicant;
|
||||
}
|
||||
|
||||
public String getPrincipals() {
|
||||
return principals;
|
||||
}
|
||||
|
||||
public void setPrincipals(String principals) {
|
||||
this.principals = principals;
|
||||
}
|
||||
|
||||
public String getDescription() {
|
||||
return description;
|
||||
}
|
||||
|
||||
public void setDescription(String description) {
|
||||
this.description = description;
|
||||
}
|
||||
|
||||
public Integer getOrderStatus() {
|
||||
return orderStatus;
|
||||
}
|
||||
|
||||
public void setOrderStatus(Integer orderStatus) {
|
||||
this.orderStatus = orderStatus;
|
||||
}
|
||||
|
||||
public String getApprover() {
|
||||
return approver;
|
||||
}
|
||||
|
||||
public void setApprover(String approver) {
|
||||
this.approver = approver;
|
||||
}
|
||||
|
||||
public String getOpinion() {
|
||||
return opinion;
|
||||
}
|
||||
|
||||
public void setOpinion(String opinion) {
|
||||
this.opinion = opinion;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "OrderTopicDO{" +
|
||||
"clusterId=" + clusterId +
|
||||
", clusterName='" + clusterName + '\'' +
|
||||
", topicName='" + topicName + '\'' +
|
||||
", retentionTime=" + retentionTime +
|
||||
", partitionNum=" + partitionNum +
|
||||
", replicaNum=" + replicaNum +
|
||||
", regions='" + regions + '\'' +
|
||||
", brokers='" + brokers + '\'' +
|
||||
", peakBytesIn=" + peakBytesIn +
|
||||
", applicant='" + applicant + '\'' +
|
||||
", principals='" + principals + '\'' +
|
||||
", description='" + description + '\'' +
|
||||
", orderStatus=" + orderStatus +
|
||||
", approver='" + approver + '\'' +
|
||||
", opinion='" + opinion + '\'' +
|
||||
", id=" + id +
|
||||
", status=" + status +
|
||||
", gmtCreate=" + gmtCreate +
|
||||
", gmtModify=" + gmtModify +
|
||||
'}';
|
||||
}
|
||||
}
|
||||
@@ -1,63 +0,0 @@
|
||||
package com.xiaojukeji.kafka.manager.common.entity.po;
|
||||
|
||||
public class RegionDO extends BaseDO{
|
||||
private String regionName;
|
||||
|
||||
private Long clusterId;
|
||||
|
||||
private String brokerList;
|
||||
|
||||
private Integer level;
|
||||
|
||||
private String description;
|
||||
|
||||
private String operator;
|
||||
|
||||
public String getRegionName() {
|
||||
return regionName;
|
||||
}
|
||||
|
||||
public void setRegionName(String regionName) {
|
||||
this.regionName = regionName;
|
||||
}
|
||||
|
||||
public Long getClusterId() {
|
||||
return clusterId;
|
||||
}
|
||||
|
||||
public void setClusterId(Long clusterId) {
|
||||
this.clusterId = clusterId;
|
||||
}
|
||||
|
||||
public String getBrokerList() {
|
||||
return brokerList;
|
||||
}
|
||||
|
||||
public void setBrokerList(String brokerList) {
|
||||
this.brokerList = brokerList;
|
||||
}
|
||||
|
||||
public Integer getLevel() {
|
||||
return level;
|
||||
}
|
||||
|
||||
public void setLevel(Integer level) {
|
||||
this.level = level;
|
||||
}
|
||||
|
||||
public String getDescription() {
|
||||
return description;
|
||||
}
|
||||
|
||||
public void setDescription(String description) {
|
||||
this.description = description;
|
||||
}
|
||||
|
||||
public String getOperator() {
|
||||
return operator;
|
||||
}
|
||||
|
||||
public void setOperator(String operator) {
|
||||
this.operator = operator;
|
||||
}
|
||||
}
|
||||
@@ -1,68 +0,0 @@
|
||||
package com.xiaojukeji.kafka.manager.common.entity.po;
|
||||
|
||||
public class TopicDO extends BaseDO{
|
||||
private Long clusterId;
|
||||
|
||||
private String topicName;
|
||||
|
||||
private String applicant;
|
||||
|
||||
private String principals;
|
||||
|
||||
private String description;
|
||||
|
||||
public Long getClusterId() {
|
||||
return clusterId;
|
||||
}
|
||||
|
||||
public void setClusterId(Long clusterId) {
|
||||
this.clusterId = clusterId;
|
||||
}
|
||||
|
||||
public String getTopicName() {
|
||||
return topicName;
|
||||
}
|
||||
|
||||
public void setTopicName(String topicName) {
|
||||
this.topicName = topicName;
|
||||
}
|
||||
|
||||
public String getApplicant() {
|
||||
return applicant;
|
||||
}
|
||||
|
||||
public void setApplicant(String applicant) {
|
||||
this.applicant = applicant;
|
||||
}
|
||||
|
||||
public String getPrincipals() {
|
||||
return principals;
|
||||
}
|
||||
|
||||
public void setPrincipals(String principals) {
|
||||
this.principals = principals;
|
||||
}
|
||||
|
||||
public String getDescription() {
|
||||
return description;
|
||||
}
|
||||
|
||||
public void setDescription(String description) {
|
||||
this.description = description;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "TopicDO{" +
|
||||
"clusterId=" + clusterId +
|
||||
", topicName='" + topicName + '\'' +
|
||||
", applicant='" + applicant + '\'' +
|
||||
", principals='" + principals + '\'' +
|
||||
", description='" + description + '\'' +
|
||||
", id=" + id +
|
||||
", status=" + status +
|
||||
", gmtCreate=" + gmtCreate +
|
||||
", gmtModify=" + gmtModify +
|
||||
'}';
|
||||
}
|
||||
}
|
||||
@@ -1,46 +0,0 @@
|
||||
package com.xiaojukeji.kafka.manager.common.entity.po;
|
||||
|
||||
public class TopicFavoriteDO extends BaseDO{
|
||||
private String username;
|
||||
|
||||
private Long clusterId;
|
||||
|
||||
private String topicName;
|
||||
|
||||
public String getUsername() {
|
||||
return username;
|
||||
}
|
||||
|
||||
public void setUsername(String username) {
|
||||
this.username = username;
|
||||
}
|
||||
|
||||
public Long getClusterId() {
|
||||
return clusterId;
|
||||
}
|
||||
|
||||
public void setClusterId(Long clusterId) {
|
||||
this.clusterId = clusterId;
|
||||
}
|
||||
|
||||
public String getTopicName() {
|
||||
return topicName;
|
||||
}
|
||||
|
||||
public void setTopicName(String topicName) {
|
||||
this.topicName = topicName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "TopicFavoriteDO{" +
|
||||
"username='" + username + '\'' +
|
||||
", clusterId=" + clusterId +
|
||||
", topicName='" + topicName + '\'' +
|
||||
", id=" + id +
|
||||
", status=" + status +
|
||||
", gmtCreate=" + gmtCreate +
|
||||
", gmtModify=" + gmtModify +
|
||||
'}';
|
||||
}
|
||||
}
|
||||
@@ -1,17 +0,0 @@
|
||||
package com.xiaojukeji.kafka.manager.common.entity.po.query;
|
||||
|
||||
/**
|
||||
* @author zengqiao
|
||||
* @date 19/12/2
|
||||
*/
|
||||
public class AlarmRuleQueryOption extends BaseQueryOption {
|
||||
private String alarmName;
|
||||
|
||||
public String getAlarmName() {
|
||||
return alarmName;
|
||||
}
|
||||
|
||||
public void setAlarmName(String alarmName) {
|
||||
this.alarmName = alarmName;
|
||||
}
|
||||
}
|
||||
@@ -1,24 +0,0 @@
|
||||
package com.xiaojukeji.kafka.manager.common.entity.po.query;
|
||||
|
||||
/**
|
||||
* @author zengqiao
|
||||
* @date 19/12/2
|
||||
*/
|
||||
public class BaseQueryOption {
|
||||
protected Long id;
|
||||
|
||||
public Long getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(Long id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "BaseQueryOption{" +
|
||||
"id=" + id +
|
||||
'}';
|
||||
}
|
||||
}
|
||||
@@ -1,17 +0,0 @@
|
||||
package com.xiaojukeji.kafka.manager.common.entity.po.query;
|
||||
|
||||
/**
|
||||
* @author zengqiao
|
||||
* @date 19/12/4
|
||||
*/
|
||||
public class ClusterQueryOption extends BaseQueryOption {
|
||||
private String clusterName;
|
||||
|
||||
public String getClusterName() {
|
||||
return clusterName;
|
||||
}
|
||||
|
||||
public void setClusterName(String clusterName) {
|
||||
this.clusterName = clusterName;
|
||||
}
|
||||
}
|
||||
@@ -1,15 +0,0 @@
|
||||
package com.xiaojukeji.kafka.manager.common.utils;
|
||||
|
||||
import java.util.Calendar;
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* 日期工具
|
||||
* @author huangyiminghappy@163.com
|
||||
* @date 2019-03-20
|
||||
*/
|
||||
public class DateUtils {
|
||||
public static Date long2Date(Long time){
|
||||
return new Date(time);
|
||||
}
|
||||
}
|
||||
@@ -1,72 +0,0 @@
|
||||
package com.xiaojukeji.kafka.manager.common.utils.jmx;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import javax.management.remote.JMXConnector;
|
||||
import javax.management.remote.JMXConnectorFactory;
|
||||
import javax.management.remote.JMXServiceURL;
|
||||
import java.io.IOException;
|
||||
import java.net.MalformedURLException;
|
||||
|
||||
/**
|
||||
* JMXConnector包装类
|
||||
* @author tukun
|
||||
* @date 2015/11/9.
|
||||
*/
|
||||
public class JmxConnectorWrap {
|
||||
private final static Logger logger = LoggerFactory.getLogger(JmxConnectorWrap.class);
|
||||
|
||||
private JMXConnector jmxConnector;
|
||||
|
||||
/**
|
||||
* JMX连接的主机名
|
||||
*/
|
||||
private String host;
|
||||
|
||||
/**
|
||||
* JMX连接端口
|
||||
*/
|
||||
private int port;
|
||||
|
||||
public JmxConnectorWrap(String host, int port) {
|
||||
this.host = host;
|
||||
this.port = port;
|
||||
}
|
||||
|
||||
public JMXConnector getJmxConnector() {
|
||||
// 如果JMX连接断开,则进行重新连接
|
||||
if (jmxConnector == null && port != -1) {
|
||||
createJMXConnector();
|
||||
}
|
||||
return jmxConnector;
|
||||
}
|
||||
|
||||
private synchronized void createJMXConnector() {
|
||||
if (jmxConnector != null) {
|
||||
return;
|
||||
}
|
||||
|
||||
String jmxUrl = String.format("service:jmx:rmi:///jndi/rmi://%s:%d/jmxrmi", host, port);
|
||||
try {
|
||||
JMXServiceURL url = new JMXServiceURL(jmxUrl);
|
||||
jmxConnector = JMXConnectorFactory.connect(url, null);
|
||||
} catch (MalformedURLException e) {
|
||||
logger.error("JMX url exception, host:{} port:{} jmxUrl:{}", host, port, jmxUrl, e);
|
||||
} catch (IOException e) {
|
||||
logger.error("JMX connect exception, host:{} port:{}.", host, port, e);
|
||||
}
|
||||
logger.info("JMX connect success, host:{} port:{}.", host, port);
|
||||
}
|
||||
|
||||
public void close() {
|
||||
if (jmxConnector == null) {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
jmxConnector.close();
|
||||
} catch (IOException e) {
|
||||
logger.warn("close JmxConnector exception, host:{} port:{}.", host, port, e);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,93 +0,0 @@
|
||||
package com.xiaojukeji.kafka.manager.common.utils.jmx;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* kafka集群的mbean的object name集合
|
||||
* @author tukun, zengqiao
|
||||
* @date 2015/11/5.
|
||||
*/
|
||||
public class MbeanNameUtil {
|
||||
|
||||
//broker监控参数
|
||||
private static final String MESSAGE_IN_PER_SEC = "kafka.server:type=BrokerTopicMetrics,name=MessagesInPerSec";
|
||||
private static final String BYTES_IN_PER_SEC = "kafka.server:type=BrokerTopicMetrics,name=BytesInPerSec";
|
||||
private static final String BYTES_OUT_PER_SEC = "kafka.server:type=BrokerTopicMetrics,name=BytesOutPerSec";
|
||||
private static final String BYTES_REJECTED_PER_SEC = "kafka.server:type=BrokerTopicMetrics,name=BytesRejectedPerSec";
|
||||
private static final String FAILED_FETCH_REQUEST_PER_SEC = "kafka.server:type=BrokerTopicMetrics,name=FailedFetchRequestsPerSec";
|
||||
private static final String FAILED_PRODUCE_REQUEST_PER_SEC = "kafka.server:type=BrokerTopicMetrics,name=FailedProduceRequestsPerSec";
|
||||
private static final String PRODUCE_REQUEST_PER_SEC = "kafka.network:type=RequestMetrics,name=RequestsPerSec,request=Produce";
|
||||
private static final String CONSUMER_REQUEST_PER_SEC = "kafka.network:type=RequestMetrics,name=RequestsPerSec,request=FetchConsumer";
|
||||
private static final String TOTAL_PRODUCE_REQUEST_PER_SEC = "kafka.server:type=BrokerTopicMetrics,name=TotalProduceRequestsPerSec";
|
||||
private static final String TOTAL_FETCH_REQUEST_PER_SEC = "kafka.server:type=BrokerTopicMetrics,name=TotalFetchRequestsPerSec";
|
||||
|
||||
private static final String REQUEST_HANDLER_AVG_IDLE_PERCENT = "kafka.server:type=KafkaRequestHandlerPool,name=RequestHandlerAvgIdlePercent";
|
||||
private static final String NETWORK_PROCESSOR_AVG_IDLE_PERCENT = "kafka.network:type=SocketServer,name=NetworkProcessorAvgIdlePercent";
|
||||
private static final String REQUEST_QUEUE_SIZE = "kafka.network:type=RequestChannel,name=RequestQueueSize";
|
||||
private static final String RESPONSE_QUEUE_SIZE = "kafka.network:type=RequestChannel,name=ResponseQueueSize";
|
||||
private static final String LOG_FLUSH_RATE_AND_TIME_MS = "kafka.log:type=LogFlushStats,name=LogFlushRateAndTimeMs";
|
||||
private static final String TOTAL_TIME_PRODUCE = "kafka.network:type=RequestMetrics,name=TotalTimeMs,request=Produce";
|
||||
private static final String TOTAL_TIME_FETCH_CONSUMER = "kafka.network:type=RequestMetrics,name=TotalTimeMs,request=FetchConsumer";
|
||||
|
||||
private static final String PART_COUNT = "kafka.server:type=ReplicaManager,name=PartitionCount";
|
||||
private static final String PARTITION_OFFSET_PULL = "kafka.log:type=Log,name=LogEndOffset,topic=${topic},partition=${partition}";
|
||||
private static final String UNDER_REPLICATED_PARTITIONS = "kafka.server:type=ReplicaManager,name=UnderReplicatedPartitions";
|
||||
private static final String LEADER_COUNT = "kafka.server:type=ReplicaManager,name=LeaderCount";
|
||||
|
||||
|
||||
// private static final String PRODUCE_REQUEST_TIME = "kafka.network:type=TopicRequestMetrics,name=TotalTimeMs,request=Produce";
|
||||
// private static final String FETCH_REQUEST_TIME = "kafka.network:type=TopicRequestMetrics,name=TotalTimeMs,request=FetchConsumer";
|
||||
|
||||
|
||||
//存储监控的参数name到获取的object_name的映射关系图
|
||||
private static Map<String, Mbean> mbeanNameMap = new HashMap<String, Mbean>();
|
||||
static {
|
||||
//监控参数配置,object_name和监控的属性名
|
||||
mbeanNameMap.put("MessagesInPerSec", new Mbean(MESSAGE_IN_PER_SEC,"OneMinuteRate", Double.class));
|
||||
mbeanNameMap.put("BytesInPerSec", new Mbean(BYTES_IN_PER_SEC,"OneMinuteRate", Double.class));
|
||||
mbeanNameMap.put("BytesOutPerSec", new Mbean(BYTES_OUT_PER_SEC,"OneMinuteRate", Double.class));
|
||||
mbeanNameMap.put("BytesRejectedPerSec", new Mbean(BYTES_REJECTED_PER_SEC,"OneMinuteRate", Double.class));
|
||||
mbeanNameMap.put("FailFetchRequestPerSec", new Mbean(FAILED_FETCH_REQUEST_PER_SEC,"OneMinuteRate", Double.class));
|
||||
mbeanNameMap.put("FailProduceRequestPerSec", new Mbean(FAILED_PRODUCE_REQUEST_PER_SEC,"OneMinuteRate", Double.class));
|
||||
mbeanNameMap.put("ProduceRequestPerSec", new Mbean(PRODUCE_REQUEST_PER_SEC,"OneMinuteRate", Double.class));
|
||||
mbeanNameMap.put("FetchConsumerRequestPerSec", new Mbean(CONSUMER_REQUEST_PER_SEC,"OneMinuteRate", Double.class));
|
||||
mbeanNameMap.put("TotalProduceRequestsPerSec", new Mbean(TOTAL_PRODUCE_REQUEST_PER_SEC,"OneMinuteRate", Double.class));
|
||||
mbeanNameMap.put("TotalFetchRequestsPerSec", new Mbean(TOTAL_FETCH_REQUEST_PER_SEC,"OneMinuteRate", Double.class));
|
||||
|
||||
|
||||
mbeanNameMap.put("PartitionOffset", new Mbean(PARTITION_OFFSET_PULL,"Value", int.class));
|
||||
|
||||
mbeanNameMap.put("PartitionCount", new Mbean(PART_COUNT,"Value", int.class));
|
||||
mbeanNameMap.put("UnderReplicatedPartitions", new Mbean(UNDER_REPLICATED_PARTITIONS,"Value", int.class));
|
||||
mbeanNameMap.put("LeaderCount", new Mbean(LEADER_COUNT,"Value", int.class));
|
||||
|
||||
mbeanNameMap.put("RequestHandlerAvgIdlePercent", new Mbean(REQUEST_HANDLER_AVG_IDLE_PERCENT,"OneMinuteRate", Double.class));
|
||||
mbeanNameMap.put("NetworkProcessorAvgIdlePercent", new Mbean(NETWORK_PROCESSOR_AVG_IDLE_PERCENT,"Value", Double.class));
|
||||
mbeanNameMap.put("RequestQueueSize", new Mbean(REQUEST_QUEUE_SIZE,"Value", int.class));
|
||||
mbeanNameMap.put("ResponseQueueSize", new Mbean(RESPONSE_QUEUE_SIZE, "Value", int.class));
|
||||
mbeanNameMap.put("LogFlushRateAndTimeMs", new Mbean(LOG_FLUSH_RATE_AND_TIME_MS,"OneMinuteRate", Double.class));
|
||||
mbeanNameMap.put("TotalTimeProduceMean", new Mbean(TOTAL_TIME_PRODUCE,"Mean", Double.class));
|
||||
mbeanNameMap.put("TotalTimeProduce99Th", new Mbean(TOTAL_TIME_PRODUCE,"99thPercentile", Double.class));
|
||||
mbeanNameMap.put("TotalTimeFetchConsumerMean", new Mbean(TOTAL_TIME_FETCH_CONSUMER,"Mean", Double.class));
|
||||
mbeanNameMap.put("TotalTimeFetchConsumer99Th", new Mbean(TOTAL_TIME_FETCH_CONSUMER,"99thPercentile", Double.class));
|
||||
|
||||
// mbeanNameMap.put("ProduceRequestTime", new Mbean(PRODUCE_REQUEST_TIME,"Value"));
|
||||
// mbeanNameMap.put("FetchRequestTime", new Mbean(FETCH_REQUEST_TIME,"Value"));
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据属性名,kafka版本,topic获取相应的Mbean
|
||||
*/
|
||||
public static Mbean getMbean(String name, String topic) {
|
||||
Mbean mbean = mbeanNameMap.get(name);
|
||||
if (mbean == null) {
|
||||
return null;
|
||||
}
|
||||
if (topic != null && !topic.isEmpty()) {
|
||||
return new Mbean(mbean.getObjectName() + ",topic=" + topic, mbean.getProperty(), mbean.getPropertyClass());
|
||||
}
|
||||
return mbean;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,17 +0,0 @@
|
||||
package com.xiaojukeji.kafka.manager.common.utils.zk;
|
||||
|
||||
/**
|
||||
* Created by limeng on 2017/12/22
|
||||
*/
|
||||
public interface StateChangeListener {
|
||||
|
||||
enum State {
|
||||
CONNECTION_RECONNECT, //
|
||||
CONNECTION_DISCONNECT, NODE_DATA_CHANGED, CHILD_UPDATED, CHILD_ADDED, CHILD_DELETED,
|
||||
//
|
||||
;
|
||||
}
|
||||
|
||||
void onChange(State state, String path);
|
||||
|
||||
}
|
||||
@@ -1,165 +0,0 @@
|
||||
package com.xiaojukeji.kafka.manager.common.utils.zk;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 存储结构:
|
||||
*
|
||||
* <pre>
|
||||
* /consumers
|
||||
* consumer-group
|
||||
* ids
|
||||
* consumerId
|
||||
* offsets
|
||||
* topic-0
|
||||
* 0(partition编号,节点内容表示)
|
||||
* 1
|
||||
* 2
|
||||
* topic-1
|
||||
* owners
|
||||
* /brokers
|
||||
* topics
|
||||
* topic-0 (节点内容是 ("0",[0,1,2]))
|
||||
* partitions
|
||||
* 0
|
||||
* state(节点内容是leader的brokerId,同步副本信息等)
|
||||
* 1
|
||||
* 2
|
||||
* topic-x
|
||||
* ids
|
||||
* 1(临时节点,broker编号,节点信息为broker相关信息,如JMX端口,host和port等)
|
||||
* 2
|
||||
* n
|
||||
* </pre>
|
||||
*
|
||||
* @author tukun @ 2015-11-5
|
||||
* @version 1.0.0
|
||||
*/
|
||||
public class ZkPathUtil {
|
||||
|
||||
public static final String ZOOKEEPER_SEPARATOR = "/";
|
||||
|
||||
public static final String BROKER_ROOT_NODE = ZOOKEEPER_SEPARATOR + "brokers";
|
||||
|
||||
public static final String CONTROLLER_ROOT_NODE = ZOOKEEPER_SEPARATOR + "controller";
|
||||
|
||||
public static final String BROKER_IDS_ROOT = BROKER_ROOT_NODE
|
||||
+ ZOOKEEPER_SEPARATOR + "ids";
|
||||
|
||||
public static final String BROKER_TOPICS_ROOT = BROKER_ROOT_NODE
|
||||
+ ZOOKEEPER_SEPARATOR + "topics";
|
||||
|
||||
public static final String CONSUMER_ROOT_NODE = ZOOKEEPER_SEPARATOR + "consumers";
|
||||
|
||||
public static final String CONFIG_ROOT_NODE = ZOOKEEPER_SEPARATOR + "config";
|
||||
|
||||
public static final String CONFIG_TOPICS_ROOT_NODE = CONFIG_ROOT_NODE + ZOOKEEPER_SEPARATOR + "topics";
|
||||
|
||||
//存储监控的参数name到获取的object_name的映射关系图
|
||||
private static Map<String, String> zkPathMap = new HashMap<String, String>();
|
||||
|
||||
static {
|
||||
zkPathMap.put("ConusmerPartitionOffset", CONSUMER_ROOT_NODE + ZOOKEEPER_SEPARATOR
|
||||
+ "${consumerGroup}" + ZOOKEEPER_SEPARATOR
|
||||
+ "offsets" + ZOOKEEPER_SEPARATOR + "${topic}"
|
||||
+ ZOOKEEPER_SEPARATOR + "${partition}");
|
||||
}
|
||||
|
||||
//for broker目录
|
||||
public static String getBrokerIdNodePath(long brokerId) {
|
||||
return String.format(BROKER_IDS_ROOT + ZOOKEEPER_SEPARATOR + "%d", brokerId);
|
||||
}
|
||||
|
||||
public static String getBrokerTopicRoot(String topic) {
|
||||
return BROKER_TOPICS_ROOT + ZOOKEEPER_SEPARATOR + topic;
|
||||
}
|
||||
|
||||
public static String getBrokerTopicPartitionRoot(String topic) {
|
||||
return BROKER_TOPICS_ROOT + ZOOKEEPER_SEPARATOR + topic + ZOOKEEPER_SEPARATOR
|
||||
+ "partitions";
|
||||
}
|
||||
|
||||
public static String getBrokerTopicPartitionStatePath(String topic, int partitionId) {
|
||||
return String.format(getBrokerTopicPartitionRoot(topic) + ZOOKEEPER_SEPARATOR + "%d"
|
||||
+ ZOOKEEPER_SEPARATOR + "state", partitionId);
|
||||
}
|
||||
|
||||
//for consumer
|
||||
public static String getConsumerTopicPartitionOffsetNodePath(String consumerGroup,
|
||||
String topic, int partitionId) {
|
||||
return String.format(CONSUMER_ROOT_NODE + ZOOKEEPER_SEPARATOR + "%s" + ZOOKEEPER_SEPARATOR
|
||||
+ "offset" + "%s" + "%d", consumerGroup, topic, partitionId);
|
||||
}
|
||||
|
||||
public static String getConsumerGroupRoot(String consumerGroup) {
|
||||
return CONSUMER_ROOT_NODE + ZOOKEEPER_SEPARATOR + consumerGroup;
|
||||
}
|
||||
|
||||
public static String getConsumerGroupIdsRoot(String consumerGroup) {
|
||||
return CONSUMER_ROOT_NODE + ZOOKEEPER_SEPARATOR + consumerGroup + ZOOKEEPER_SEPARATOR
|
||||
+ "ids";
|
||||
}
|
||||
|
||||
public static String getConsumerGroupOffsetRoot(String consumerGroup) {
|
||||
return CONSUMER_ROOT_NODE + ZOOKEEPER_SEPARATOR + consumerGroup + ZOOKEEPER_SEPARATOR
|
||||
+ "offsets";
|
||||
}
|
||||
|
||||
public static String getConsumerGroupOwnersRoot(String consumerGroup) {
|
||||
return CONSUMER_ROOT_NODE + ZOOKEEPER_SEPARATOR + consumerGroup + ZOOKEEPER_SEPARATOR
|
||||
+ "owners";
|
||||
}
|
||||
|
||||
public static String getConsumerGroupConsumerIdsNodePath(String consumerGroup, String consumerId) {
|
||||
return getConsumerGroupIdsRoot(consumerGroup) + ZOOKEEPER_SEPARATOR + consumerId;
|
||||
}
|
||||
|
||||
public static String getConsumerGroupOffsetTopicNode(String consumerGroup, String topic) {
|
||||
return getConsumerGroupOffsetRoot(consumerGroup) + ZOOKEEPER_SEPARATOR + topic;
|
||||
}
|
||||
|
||||
public static String getConsumerGroupOffsetTopicPartitionNode(String consumerGroup,
|
||||
String topic, int partitionId) {
|
||||
return getConsumerGroupOffsetTopicNode(consumerGroup, topic) + ZOOKEEPER_SEPARATOR
|
||||
+ partitionId;
|
||||
}
|
||||
|
||||
public static String getConsumerGroupOwnersTopicNode(String consumerGroup, String topic) {
|
||||
return getConsumerGroupOwnersRoot(consumerGroup) + ZOOKEEPER_SEPARATOR + topic;
|
||||
}
|
||||
|
||||
public static String getConsumerGroupOwnersTopicPartitionNode(String consumerGroup,
|
||||
String topic, int partitionId) {
|
||||
return getConsumerGroupOwnersTopicNode(consumerGroup, topic) + ZOOKEEPER_SEPARATOR
|
||||
+ partitionId;
|
||||
}
|
||||
|
||||
public static String getConfigTopicNode(String topicName) {
|
||||
return CONFIG_TOPICS_ROOT_NODE + ZOOKEEPER_SEPARATOR + topicName;
|
||||
}
|
||||
|
||||
public static String parseLastPartFromZkPath(String zkPath) {
|
||||
return zkPath.substring(zkPath.lastIndexOf("/") + 1);
|
||||
}
|
||||
|
||||
public static Map<String, String> getZkPathMap() {
|
||||
return zkPathMap;
|
||||
}
|
||||
|
||||
public static void setZkPathMap(Map<String, String> zkPathMap) {
|
||||
ZkPathUtil.zkPathMap = zkPathMap;
|
||||
}
|
||||
|
||||
public static String getControllerRootNode() {
|
||||
return CONTROLLER_ROOT_NODE;
|
||||
}
|
||||
|
||||
public static String getEntityConfigPath(String entityType, String entity) {
|
||||
return getEntityConfigRootPath(entityType) + "/" + entity;
|
||||
}
|
||||
|
||||
public static String getEntityConfigRootPath(String entityType) {
|
||||
return CONFIG_ROOT_NODE + "/" + entityType;
|
||||
}
|
||||
}
|
||||
9510
console/package-lock.json
generated
9510
console/package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@@ -1,69 +0,0 @@
|
||||
import * as React from 'react';
|
||||
|
||||
import { PaginationConfig, Table } from 'component/antd';
|
||||
import { observer } from 'mobx-react';
|
||||
import urlQuery from 'store/url-query';
|
||||
import { IConsumeInfo } from 'store/topic';
|
||||
import { consume } from 'store/consume';
|
||||
import { SearchAndFilter } from 'container/cluster-topic';
|
||||
import { modal } from 'store';
|
||||
|
||||
const pagination: PaginationConfig = {
|
||||
position: 'bottom',
|
||||
showQuickJumper: true,
|
||||
pageSize: 10,
|
||||
showTotal: (total) => `共 ${total} 条`,
|
||||
};
|
||||
|
||||
@observer
|
||||
export class AdminConsume extends SearchAndFilter {
|
||||
public state = {
|
||||
searchKey: '',
|
||||
};
|
||||
|
||||
public columns = [{
|
||||
title: '消费组名称',
|
||||
dataIndex: 'consumerGroup',
|
||||
key: 'consumerGroup',
|
||||
width: '70%',
|
||||
sorter: (a: IConsumeInfo, b: IConsumeInfo) => a.consumerGroup.charCodeAt(0) - b.consumerGroup.charCodeAt(0),
|
||||
}, {
|
||||
title: 'location',
|
||||
dataIndex: 'location',
|
||||
key: 'location',
|
||||
width: '20%',
|
||||
render: (t: string) => t.toLowerCase(),
|
||||
}, {
|
||||
title: '操作',
|
||||
key: 'operation',
|
||||
width: '10%',
|
||||
render: (t: string, r: IConsumeInfo) => {
|
||||
return (
|
||||
<a onClick={modal.showConsumerTopic.bind(null, Object.assign({ clusterId: urlQuery.clusterId }, r))}>详情</a>);
|
||||
},
|
||||
},
|
||||
];
|
||||
|
||||
public componentDidMount() {
|
||||
consume.getConsumeInfo(urlQuery.clusterId);
|
||||
}
|
||||
|
||||
public render() {
|
||||
const data = consume.data.filter((d) => d.consumerGroup.includes(this.state.searchKey));
|
||||
return (
|
||||
<>
|
||||
<ul className="table-operation-bar">
|
||||
{this.renderSearch('请输入消费组名称')}
|
||||
</ul>
|
||||
<div style={{ marginTop: '48px' }}>
|
||||
<Table
|
||||
columns={this.columns}
|
||||
dataSource={data}
|
||||
pagination={pagination}
|
||||
rowKey="consumerGroup"
|
||||
/>
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -1,8 +0,0 @@
|
||||
.content-container .table-operation-bar.in-panel {
|
||||
position: static;
|
||||
text-align: right;
|
||||
.new-topic {
|
||||
margin-right: 0;
|
||||
margin-left: 30px;
|
||||
}
|
||||
}
|
||||
@@ -1,69 +0,0 @@
|
||||
import * as React from 'react';
|
||||
|
||||
import { PaginationConfig, Table } from 'component/antd';
|
||||
import { observer } from 'mobx-react';
|
||||
import urlQuery from 'store/url-query';
|
||||
import { IConsumeInfo } from 'store/topic';
|
||||
import { consume } from 'store/consume';
|
||||
import { SearchAndFilter } from 'container/cluster-topic';
|
||||
import { modal } from 'store';
|
||||
|
||||
const pagination: PaginationConfig = {
|
||||
position: 'bottom',
|
||||
showQuickJumper: true,
|
||||
pageSize: 10,
|
||||
showTotal: (total) => `共 ${total} 条`,
|
||||
};
|
||||
|
||||
@observer
|
||||
export class AdminConsume extends SearchAndFilter {
|
||||
public state = {
|
||||
searchKey: '',
|
||||
};
|
||||
|
||||
public columns = [{
|
||||
title: '消费组名称',
|
||||
dataIndex: 'consumerGroup',
|
||||
key: 'consumerGroup',
|
||||
width: '70%',
|
||||
sorter: (a: IConsumeInfo, b: IConsumeInfo) => a.consumerGroup.charCodeAt(0) - b.consumerGroup.charCodeAt(0),
|
||||
}, {
|
||||
title: 'location',
|
||||
dataIndex: 'location',
|
||||
key: 'location',
|
||||
width: '20%',
|
||||
render: (t: string) => t.toLowerCase(),
|
||||
}, {
|
||||
title: '操作',
|
||||
key: 'operation',
|
||||
width: '10%',
|
||||
render: (t: string, r: IConsumeInfo) => {
|
||||
return (
|
||||
<a onClick={modal.showConsumerTopic.bind(null, Object.assign({ clusterId: urlQuery.clusterId }, r))}>详情</a>);
|
||||
},
|
||||
},
|
||||
];
|
||||
|
||||
public componentDidMount() {
|
||||
consume.getConsumeInfo(urlQuery.clusterId);
|
||||
}
|
||||
|
||||
public render() {
|
||||
const data = consume.data.filter((d) => d.consumerGroup.includes(this.state.searchKey));
|
||||
return (
|
||||
<div className="k-row">
|
||||
<ul className="table-operation-bar">
|
||||
{this.renderSearch('请输入消费组名称')}
|
||||
</ul>
|
||||
<div style={{ marginTop: '48px' }}>
|
||||
<Table
|
||||
columns={this.columns}
|
||||
dataSource={data}
|
||||
pagination={pagination}
|
||||
rowKey="consumerGroup"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -1,87 +0,0 @@
|
||||
import * as React from 'react';
|
||||
|
||||
import { Table, Tabs, PaginationConfig } from 'component/antd';
|
||||
import { observer } from 'mobx-react';
|
||||
import urlQuery from 'store/url-query';
|
||||
import { controller } from 'store/controller';
|
||||
import { SearchAndFilter } from 'container/cluster-topic';
|
||||
import moment from 'moment';
|
||||
|
||||
const TabPane = Tabs.TabPane;
|
||||
|
||||
const columns = [
|
||||
{
|
||||
title: 'BrokerId',
|
||||
dataIndex: 'brokerId',
|
||||
key: 'brokerId',
|
||||
sorter: (a: any, b: any) => a.brokerNum - b.brokerNum,
|
||||
},
|
||||
{
|
||||
title: 'host',
|
||||
key: 'host',
|
||||
dataIndex: 'host',
|
||||
render: (r: string, t: any) => {
|
||||
return (
|
||||
<a href={`/admin/broker_detail?clusterId=${urlQuery.clusterId}&brokerId=${t.brokerId}`} target="_blank">{r}
|
||||
</a>
|
||||
); },
|
||||
},
|
||||
{
|
||||
title: '版本',
|
||||
dataIndex: 'controllerVersion',
|
||||
key: 'controllerVersion',
|
||||
},
|
||||
{
|
||||
title: '变更时间',
|
||||
dataIndex: 'controllerTimestamp',
|
||||
key: 'controllerTimestamp',
|
||||
sorter: (a: any, b: any) => a.controllerTimestamp - b.updacontrollerTimestampteTime,
|
||||
render: (t: number) => moment(t).format('YYYY-MM-DD HH:mm:ss'),
|
||||
},
|
||||
];
|
||||
|
||||
const pagination: PaginationConfig = {
|
||||
position: 'bottom',
|
||||
showQuickJumper: true,
|
||||
pageSize: 10,
|
||||
showTotal: (total) => `共 ${total} 条`,
|
||||
};
|
||||
|
||||
@observer
|
||||
export class AdminController extends SearchAndFilter {
|
||||
public state = {
|
||||
searchKey: '',
|
||||
};
|
||||
|
||||
public componentDidMount() {
|
||||
controller.getController(urlQuery.clusterId);
|
||||
}
|
||||
|
||||
public renderController() {
|
||||
if (!controller.data) return null;
|
||||
const data = controller.data.filter((d) => d.host.includes(this.state.searchKey));
|
||||
return (
|
||||
<Table
|
||||
columns={columns}
|
||||
dataSource={data}
|
||||
pagination={pagination}
|
||||
rowKey="controllerTimestamp"
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
public render() {
|
||||
return (
|
||||
<>
|
||||
<ul className="table-operation-bar">
|
||||
{this.renderSearch('请输入关键词')}
|
||||
</ul>
|
||||
<Tabs defaultActiveKey="1" type="card">
|
||||
<TabPane tab="Controller变更历史" key="1">
|
||||
{this.renderController()}
|
||||
</TabPane>
|
||||
</Tabs>
|
||||
</>
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -1,60 +0,0 @@
|
||||
import * as React from 'react';
|
||||
|
||||
import urlQuery from 'store/url-query';
|
||||
import { NetWorkFlow } from 'container/topic-detail/com';
|
||||
import { Tabs } from 'component/antd';
|
||||
import { broker } from 'store/broker';
|
||||
import { BrokerStatus } from 'container/broker-info/base-info';
|
||||
import { BrokerList } from 'container/broker-info/base-info';
|
||||
import { AdminConsume } from 'container/admin-consume';
|
||||
import { AdminRegion } from 'container/admin-region';
|
||||
import { AdminController } from 'container/admin-controller';
|
||||
import AdminTopic from 'container/admin-topic/index';
|
||||
import { handleTabKey } from 'lib/utils';
|
||||
|
||||
export class ClusterDetail extends React.Component {
|
||||
|
||||
public updateStatus = () => {
|
||||
broker.getBrokerNetwork(urlQuery.clusterId);
|
||||
}
|
||||
public componentDidMount() {
|
||||
this.updateStatus();
|
||||
}
|
||||
public render() {
|
||||
return (
|
||||
<>
|
||||
<Tabs type="card" activeKey={location.hash.substr(1) || '0'} onChange={handleTabKey}>
|
||||
<Tabs.TabPane tab="集群流量" key="0">
|
||||
<div className="k-row right-flow">
|
||||
<p className="k-title">历史流量</p>
|
||||
<NetWorkFlow clusterId={urlQuery.clusterId} />
|
||||
</div>
|
||||
<div className="k-row right-flow" style={{ marginTop: '50px' }}>
|
||||
<p className="k-title">实时流量</p>
|
||||
<span className="k-abs" onClick={this.updateStatus}>
|
||||
<i className="k-icon-shuaxin didi-theme" />刷新
|
||||
</span>
|
||||
<BrokerStatus />
|
||||
</div>
|
||||
</Tabs.TabPane>
|
||||
<Tabs.TabPane tab="Topic管理" key="1">
|
||||
<AdminTopic />
|
||||
</Tabs.TabPane>
|
||||
<Tabs.TabPane tab="Broker状态概览" key="2">
|
||||
<BrokerList />
|
||||
</Tabs.TabPane>
|
||||
<Tabs.TabPane tab="ConsumerGroup列表" key="3">
|
||||
<AdminConsume />
|
||||
</Tabs.TabPane>
|
||||
<Tabs.TabPane tab="Region管理" key="4">
|
||||
<AdminRegion />
|
||||
</Tabs.TabPane>
|
||||
<Tabs.TabPane tab="Controller变更历史" key="5">
|
||||
<AdminController />
|
||||
</Tabs.TabPane>
|
||||
</Tabs>
|
||||
|
||||
</>
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -1,9 +0,0 @@
|
||||
.right-flow {
|
||||
.k-abs {
|
||||
right: 24px;
|
||||
cursor: pointer;
|
||||
& > i {
|
||||
margin-right: 5px;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,133 +0,0 @@
|
||||
import * as React from 'react';
|
||||
import './index.less';
|
||||
|
||||
import { Table, Tabs, ColumnProps, PaginationConfig } from 'component/antd';
|
||||
|
||||
import { modal } from 'store';
|
||||
import { cluster } from 'store/cluster';
|
||||
import { observer } from 'mobx-react';
|
||||
import { IClusterData } from 'types/base-type';
|
||||
|
||||
const TabPane = Tabs.TabPane;
|
||||
|
||||
const detailUrl = '/admin/cluster_detail?clusterId=';
|
||||
|
||||
const collectionColumns: Array<ColumnProps<IClusterData>> = [
|
||||
{
|
||||
title: '集群ID',
|
||||
dataIndex: 'clusterId',
|
||||
key: 'clusterId',
|
||||
sorter: (a: IClusterData, b: IClusterData) => a.clusterId - b.clusterId,
|
||||
},
|
||||
{
|
||||
title: '集群名称',
|
||||
key: 'clusterName',
|
||||
sorter: (a: IClusterData, b: IClusterData) => a.clusterName.charCodeAt(0) - b.clusterName.charCodeAt(0),
|
||||
render: (text, record) => {
|
||||
const url = `${detailUrl}${record.clusterId}&clusterName=${record.clusterName}`;
|
||||
return <a href={encodeURI(url)}>{record.clusterName}</a>;
|
||||
},
|
||||
},
|
||||
{
|
||||
title: 'Topic 数',
|
||||
key: 'topicNum',
|
||||
sorter: (a: IClusterData, b: IClusterData) => a.topicNum - b.topicNum,
|
||||
render: (text, record) => {
|
||||
return <a href={`${detailUrl}${record.clusterId}#1`}>{record.topicNum}</a>;
|
||||
},
|
||||
},
|
||||
{
|
||||
title: 'Broker 数量',
|
||||
dataIndex: 'brokerNum',
|
||||
key: 'brokerNum',
|
||||
sorter: (a: IClusterData, b: IClusterData) => a.brokerNum - b.brokerNum,
|
||||
render: (text, record) => {
|
||||
return (
|
||||
<a
|
||||
href={
|
||||
`${detailUrl}${record.clusterId}&clusterName=${btoa(encodeURIComponent(record.clusterName))}#2`}
|
||||
>
|
||||
{record.brokerNum}
|
||||
</a>);
|
||||
},
|
||||
},
|
||||
{
|
||||
title: 'ConsumerGroup 数',
|
||||
key: 'consumerGroupNum',
|
||||
sorter: (a: IClusterData, b: IClusterData) => a.consumerGroupNum - b.consumerGroupNum,
|
||||
render: (text, record) => {
|
||||
return <a href={`${detailUrl}${record.clusterId}#3`}>{record.consumerGroupNum}</a>;
|
||||
},
|
||||
},
|
||||
{
|
||||
title: 'Region 数',
|
||||
key: 'regionNum',
|
||||
sorter: (a: IClusterData, b: IClusterData) => a.regionNum - b.regionNum,
|
||||
render: (text, record) => {
|
||||
return <a href={`${detailUrl}${record.clusterId}`}>{record.regionNum}</a>;
|
||||
},
|
||||
},
|
||||
{
|
||||
title: 'ControllerID',
|
||||
key: 'controllerId',
|
||||
sorter: (a: IClusterData, b: IClusterData) => a.controllerId - b.controllerId,
|
||||
render: (text, record) => {
|
||||
return <a href={`${detailUrl}${record.clusterId}#5`}>{record.controllerId}</a>;
|
||||
},
|
||||
},
|
||||
{
|
||||
title: '操作',
|
||||
dataIndex: 'operation',
|
||||
key: 'operation',
|
||||
render: (text, record) => {
|
||||
return (
|
||||
<span className="table-operation">
|
||||
<a onClick={modal.showModifyCluster.bind(null, record)}>修改</a>
|
||||
</span>
|
||||
);
|
||||
},
|
||||
},
|
||||
];
|
||||
|
||||
const pagination: PaginationConfig = {
|
||||
position: 'bottom',
|
||||
showQuickJumper: true,
|
||||
pageSize: 10,
|
||||
showTotal: (total) => `共 ${total} 条`,
|
||||
};
|
||||
|
||||
@observer
|
||||
export class AdminHome extends React.Component {
|
||||
public renderList() {
|
||||
return (
|
||||
<Table
|
||||
columns={collectionColumns}
|
||||
dataSource={cluster.data.slice(1)}
|
||||
pagination={pagination}
|
||||
rowKey="clusterId"
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
public componentDidMount() {
|
||||
cluster.getClusters();
|
||||
cluster.getKafkaVersions();
|
||||
}
|
||||
|
||||
public render() {
|
||||
return (
|
||||
<>
|
||||
<ul className="table-operation-bar">
|
||||
<li className="new-topic" onClick={modal.showNewCluster}>
|
||||
<i className="k-icon-xinjian didi-theme"/>添加集群
|
||||
</li>
|
||||
</ul>
|
||||
<Tabs defaultActiveKey="1" type="card">
|
||||
<TabPane tab="集群列表" key="1">
|
||||
{this.renderList()}
|
||||
</TabPane>
|
||||
</Tabs>
|
||||
</>
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -1,138 +0,0 @@
|
||||
import * as React from 'react';
|
||||
|
||||
import { Table, Tabs, Modal, notification } from 'component/antd';
|
||||
import { PaginationConfig } from 'antd/es/table/interface';
|
||||
import { modal } from 'store';
|
||||
import { observer } from 'mobx-react';
|
||||
import { operation, ITask, taskMap } from 'store/operation';
|
||||
import { cluster } from 'store/cluster';
|
||||
import moment from 'moment';
|
||||
import { modifyTask } from 'lib/api';
|
||||
import { SearchAndFilter } from 'container/cluster-topic';
|
||||
import { tableFilter } from 'lib/utils';
|
||||
|
||||
const pagination: PaginationConfig = {
|
||||
position: 'bottom',
|
||||
showQuickJumper: true,
|
||||
pageSize: 10,
|
||||
showTotal: (total) => `共 ${total} 条`,
|
||||
};
|
||||
|
||||
@observer
|
||||
export class AdminOperation extends SearchAndFilter {
|
||||
public state = {
|
||||
searchKey: '',
|
||||
filterClusterVisible: false,
|
||||
filterStatusVisible: false,
|
||||
};
|
||||
|
||||
public renderColumns = (data: ITask[]) => {
|
||||
const cluster = Object.assign({
|
||||
title: '集群名称',
|
||||
dataIndex: 'clusterName',
|
||||
key: 'clusterId',
|
||||
filters: tableFilter<ITask>(data, 'clusterName'),
|
||||
onFilter: (value: string, record: ITask) => record.clusterName.indexOf(value) === 0,
|
||||
}, this.renderColumnsFilter('filterClusterVisible'));
|
||||
|
||||
const status = Object.assign({
|
||||
title: '状态',
|
||||
dataIndex: 'status',
|
||||
key: 'status',
|
||||
filters: taskMap.map((ele, index) => ({ text: ele, value: index + '' })),
|
||||
onFilter: (value: string, record: ITask) => record.status === +value,
|
||||
render: (t: number) => <span className={t === 2 || t === 1 ? 'success' : t === 3 ? 'fail' : ''}>{taskMap[t]}</span>,
|
||||
}, this.renderColumnsFilter('filterStatusVisible'));
|
||||
|
||||
return [
|
||||
{
|
||||
title: '任务id',
|
||||
dataIndex: 'taskId',
|
||||
key: 'taskId',
|
||||
sorter: (a: ITask, b: ITask) => a.taskId - b.taskId,
|
||||
},
|
||||
cluster,
|
||||
{
|
||||
title: 'Topic名称',
|
||||
dataIndex: 'topicName',
|
||||
key: 'topicName',
|
||||
sorter: (a: ITask, b: ITask) => a.topicName.charCodeAt(0) - b.topicName.charCodeAt(0),
|
||||
},
|
||||
{
|
||||
title: '创建人',
|
||||
dataIndex: 'operator',
|
||||
key: 'operator',
|
||||
sorter: (a: ITask, b: ITask) => a.operator.charCodeAt(0) - b.operator.charCodeAt(0),
|
||||
},
|
||||
{
|
||||
title: '创建时间',
|
||||
dataIndex: 'gmtCreate',
|
||||
key: 'gmtCreate',
|
||||
sorter: (a: ITask, b: ITask) => a.gmtCreate - b.gmtCreate,
|
||||
render: (t: number) => moment(t).format('YYYY-MM-DD HH:mm:ss'),
|
||||
},
|
||||
status,
|
||||
{
|
||||
title: '操作',
|
||||
dataIndex: 'operation',
|
||||
key: 'operation',
|
||||
width: 200,
|
||||
render: (text: string, record: ITask) => {
|
||||
const status: number = record.status;
|
||||
return (
|
||||
<span className="table-operation">
|
||||
<a onClick={modal.showTask.bind(null, record, 'detail')}>详情</a>
|
||||
{+status === 0 || +status === 1 ? <a onClick={modal.showTask.bind(null, record)}>修改</a> : null}
|
||||
{!status ? <a onClick={this.handleAction.bind(null, record.taskId, 'start')}>执行</a> : null}
|
||||
{!status ? <a onClick={this.handleAction.bind(null, record.taskId, 'cancel')}>撤销</a> : null}
|
||||
</span>
|
||||
);
|
||||
},
|
||||
},
|
||||
];
|
||||
}
|
||||
|
||||
public handleAction(taskId: number, type: string) {
|
||||
Modal.confirm({
|
||||
title: `确认${type === 'start' ? '执行Topic迁移任务' : '撤销任务' + taskId}`,
|
||||
okText: '确定',
|
||||
cancelText: '取消',
|
||||
onOk: () => {
|
||||
modifyTask({ action: type, taskId }).then(() => {
|
||||
notification.success({ message: `${type === 'start' ? '执行' : '撤销'}任务成功` });
|
||||
operation.getTask();
|
||||
});
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
public componentDidMount() {
|
||||
operation.getTask();
|
||||
cluster.getClusters();
|
||||
}
|
||||
|
||||
public render() {
|
||||
const { searchKey } = this.state;
|
||||
const data: ITask[] = operation.tasks && searchKey ? operation.tasks.filter((d) => d.taskId === +searchKey) : operation.tasks;
|
||||
return (
|
||||
<>
|
||||
<ul className="table-operation-bar">
|
||||
<li className="new-topic" onClick={modal.showTask.bind(null, null)}>
|
||||
<i className="k-icon-xinjian didi-theme" />新建迁移任务
|
||||
</li>
|
||||
{this.renderSearch('请输入关键字')}
|
||||
</ul>
|
||||
<Tabs type="card">
|
||||
<Tabs.TabPane tab="迁移任务" key="0">
|
||||
<Table
|
||||
rowKey="taskId"
|
||||
columns={this.renderColumns(data)}
|
||||
dataSource={data}
|
||||
pagination={pagination}
|
||||
/>
|
||||
</Tabs.TabPane>
|
||||
</Tabs>
|
||||
</>
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -1,16 +0,0 @@
|
||||
.num-container {
|
||||
position: relative;
|
||||
.num {
|
||||
position: absolute;
|
||||
width: 15px;
|
||||
height: 15px;
|
||||
line-height: 15px;
|
||||
border-radius: 15px;
|
||||
background-color: #f5222d;
|
||||
color: #fff;
|
||||
display: inline-block;
|
||||
right: -18px;
|
||||
text-align: center;
|
||||
top: -1px;
|
||||
}
|
||||
}
|
||||
@@ -1,171 +0,0 @@
|
||||
import * as React from 'react';
|
||||
|
||||
import { Table, Tabs } from 'component/antd';
|
||||
import { PaginationConfig } from 'antd/es/table/interface';
|
||||
import { modal } from 'store';
|
||||
import { observer } from 'mobx-react';
|
||||
import { order, tableStatusFilter } from 'store/order';
|
||||
import moment from 'moment';
|
||||
import { handleTabKey, tableFilter } from 'lib/utils';
|
||||
import { SearchAndFilter } from 'container/cluster-topic';
|
||||
import { IBaseOrder } from 'types/base-type';
|
||||
|
||||
import './index.less';
|
||||
|
||||
const TabPane = Tabs.TabPane;
|
||||
|
||||
const pagination: PaginationConfig = {
|
||||
position: 'bottom',
|
||||
showQuickJumper: true,
|
||||
pageSize: 10,
|
||||
showTotal: (total) => `共 ${total} 条`,
|
||||
};
|
||||
|
||||
@observer
|
||||
export class AdminOrder extends SearchAndFilter {
|
||||
public state = {
|
||||
searchKey: '',
|
||||
filterClusterVisible: false,
|
||||
filterStatusVisible: false,
|
||||
filterSVisible: false,
|
||||
filterCVisible: false,
|
||||
};
|
||||
|
||||
public componentDidMount() {
|
||||
order.getAdminOrder();
|
||||
}
|
||||
|
||||
public renderColumns = (data: IBaseOrder[], type: boolean) => {
|
||||
const cluster = Object.assign({
|
||||
title: '集群名称',
|
||||
dataIndex: 'clusterName',
|
||||
key: 'clusterName',
|
||||
filters: tableFilter<IBaseOrder>(data, 'clusterName'),
|
||||
onFilter: (value: string, record: IBaseOrder) => record.clusterName.indexOf(value) === 0,
|
||||
}, this.renderColumnsFilter(type ? 'filterClusterVisible' : 'filterCVisible'));
|
||||
|
||||
const status = Object.assign({
|
||||
title: '审批状态',
|
||||
dataIndex: 'statusStr',
|
||||
key: 'statusStr',
|
||||
width: 100,
|
||||
filters: tableStatusFilter,
|
||||
onFilter: (value: string, record: IBaseOrder) => record.statusStr.indexOf(value) === 0,
|
||||
render: (t: string) => <span className={t === '通过' ? 'success' : t === '拒绝' ? 'fail' : ''}>{t}</span>,
|
||||
}, this.renderColumnsFilter(type ? 'filterStatusVisible' : 'filterSVisible'));
|
||||
return [
|
||||
{
|
||||
title: '工单 ID',
|
||||
dataIndex: 'orderId',
|
||||
key: 'orderId',
|
||||
sorter: (a: IBaseOrder, b: IBaseOrder) => a.orderId - b.orderId,
|
||||
},
|
||||
cluster,
|
||||
{
|
||||
title: 'Topic 名称',
|
||||
dataIndex: 'topicName',
|
||||
key: 'topicName',
|
||||
sorter: (a: IBaseOrder, b: IBaseOrder) => a.topicName.charCodeAt(0) - b.topicName.charCodeAt(0),
|
||||
},
|
||||
{
|
||||
title: '申请人',
|
||||
dataIndex: 'applicant',
|
||||
key: 'applicant',
|
||||
sorter: (a: IBaseOrder, b: IBaseOrder) => a.applicant.charCodeAt(0) - b.applicant.charCodeAt(0),
|
||||
},
|
||||
{
|
||||
title: '审批人',
|
||||
dataIndex: 'approver',
|
||||
key: 'approver',
|
||||
},
|
||||
{
|
||||
title: '申请时间',
|
||||
dataIndex: 'gmtCreate',
|
||||
key: 'gmtCreate',
|
||||
sorter: (a: IBaseOrder, b: IBaseOrder) => a.gmtCreate - b.gmtCreate,
|
||||
render: (t: number) => moment(t).format('YYYY-MM-DD HH:mm:ss'),
|
||||
},
|
||||
status,
|
||||
{
|
||||
title: '操作',
|
||||
dataIndex: 'operation',
|
||||
key: 'operation',
|
||||
width: 100,
|
||||
render: (text: string, r: IBaseOrder) => {
|
||||
if (!+location.hash.substr(1)) {
|
||||
return (
|
||||
<span className="table-operation">
|
||||
<a onClick={modal.showOrderApprove.bind(null, r, 'showOrderDetail')}>详情</a>
|
||||
{r.orderStatus === 0 ? <a onClick={modal.showOrderApprove.bind(null, r, 'showOrderApprove')}>审批</a> : null}
|
||||
</span>
|
||||
);
|
||||
} else {
|
||||
return (
|
||||
<span className="table-operation">
|
||||
<a onClick={modal.showPartition.bind(null, r, 'showPartitionDetail')}>详情</a>
|
||||
{r.orderStatus === 0 ? <a onClick={modal.showPartition.bind(null, r, 'showPartition')}>审批</a> : null}
|
||||
</span>
|
||||
);
|
||||
}
|
||||
},
|
||||
},
|
||||
];
|
||||
}
|
||||
|
||||
public renderTopic() {
|
||||
const data = order.adminTopicOrder.filter((d) => d.topicName.includes(this.state.searchKey));
|
||||
return (
|
||||
<Table
|
||||
columns={this.renderColumns(data, true)}
|
||||
dataSource={data}
|
||||
pagination={pagination}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
public renderPartition() {
|
||||
const data = order.adminPartitionOrder.filter((d) => d.topicName.includes(this.state.searchKey));
|
||||
return (
|
||||
<Table
|
||||
columns={this.renderColumns(data, false)}
|
||||
dataSource={data}
|
||||
pagination={pagination}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
public render() {
|
||||
const defaultKey = location.hash.substr(1) || '0';
|
||||
return (
|
||||
<>
|
||||
<ul className="table-operation-bar">
|
||||
{this.renderSearch('请输入topic名称')}
|
||||
</ul>
|
||||
<Tabs activeKey={defaultKey} type="card" onChange={handleTabKey}>
|
||||
<TabPane
|
||||
key="0"
|
||||
tab={
|
||||
<div className="num-container">
|
||||
{order.pendingTopic ? <span className="num">{order.pendingTopic}</span> : null}
|
||||
Topic 申请
|
||||
</div>
|
||||
}
|
||||
>
|
||||
{this.renderTopic()}
|
||||
</TabPane>
|
||||
<TabPane
|
||||
tab={
|
||||
<div className="num-container">
|
||||
{order.pendingOrder ? <span className="num">{order.pendingOrder}</span> : null}
|
||||
扩容申请
|
||||
</div>
|
||||
}
|
||||
key="1"
|
||||
>
|
||||
{this.renderPartition()}
|
||||
</TabPane>
|
||||
</Tabs>
|
||||
</>
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -1,138 +0,0 @@
|
||||
import * as React from 'react';
|
||||
|
||||
import { Table, Tabs, Modal, PaginationConfig, notification } from 'component/antd';
|
||||
import { modal } from 'store';
|
||||
import { observer } from 'mobx-react';
|
||||
import { IRegionData, region, statusMap, levelMap } from 'store/region';
|
||||
import urlQuery from 'store/url-query';
|
||||
import { SearchAndFilter } from 'container/cluster-topic';
|
||||
|
||||
const TabPane = Tabs.TabPane;
|
||||
|
||||
const handleDeleteRegion = (record: IRegionData) => {
|
||||
Modal.confirm({
|
||||
title: `确认删除 ${record.regionName} ?`,
|
||||
okText: '确定',
|
||||
cancelText: '取消',
|
||||
onOk: () => {
|
||||
region.delRegion(record.regionId).then(() => {
|
||||
notification.success({ message: '删除成功' });
|
||||
region.getRegions(urlQuery.clusterId);
|
||||
});
|
||||
},
|
||||
});
|
||||
};
|
||||
|
||||
const pagination: PaginationConfig = {
|
||||
position: 'bottom',
|
||||
showQuickJumper: true,
|
||||
pageSize: 10,
|
||||
showTotal: (total) => `共 ${total} 条`,
|
||||
};
|
||||
|
||||
@observer
|
||||
export class AdminRegion extends SearchAndFilter {
|
||||
public state = {
|
||||
searchKey: '',
|
||||
filterStatus: false,
|
||||
filterLevel: false,
|
||||
};
|
||||
|
||||
public renderColumns = () => {
|
||||
const status = Object.assign({
|
||||
title: '状态',
|
||||
dataIndex: 'status',
|
||||
key: 'status',
|
||||
filters: statusMap.map((ele, index) => ({ text: ele, value: index + '' })),
|
||||
render: (t: number) => <span className={!(t + 1) ? 'fail' : t === 1 ? '' : 'success'}>{statusMap[t + 1]}</span>,
|
||||
onFilter: (value: string, record: IRegionData) => record.status + 1 === +value,
|
||||
}, this.renderColumnsFilter('filterStatus'));
|
||||
|
||||
const level = Object.assign({
|
||||
title: '重要程度',
|
||||
dataIndex: 'level',
|
||||
key: 'level',
|
||||
filters: levelMap.map((ele, index) => ({ text: ele, value: index + '' })),
|
||||
render: (t: number) => {
|
||||
return levelMap[t];
|
||||
},
|
||||
onFilter: (value: string, record: IRegionData) => record.level === +value,
|
||||
}, this.renderColumnsFilter('filterLevel'));
|
||||
|
||||
return [
|
||||
{
|
||||
title: 'Region名称',
|
||||
dataIndex: 'regionName',
|
||||
key: 'regionName',
|
||||
},
|
||||
{
|
||||
title: 'BrokerList',
|
||||
key: 'brokerIdList',
|
||||
render: (text: string, record: IRegionData) => {
|
||||
return <span>{record.brokerIdList.join(', ')}</span>;
|
||||
},
|
||||
},
|
||||
{
|
||||
title: '操作者',
|
||||
dataIndex: 'operator',
|
||||
key: 'operator',
|
||||
},
|
||||
status,
|
||||
level,
|
||||
{
|
||||
title: '备注',
|
||||
dataIndex: 'description',
|
||||
key: 'description',
|
||||
},
|
||||
{
|
||||
title: '操作',
|
||||
dataIndex: 'operation',
|
||||
key: 'operation',
|
||||
width: 200,
|
||||
render: (text: string, record: IRegionData) => {
|
||||
return (
|
||||
<span className="table-operation">
|
||||
<a onClick={modal.showRegion.bind(null, record)}>编辑</a>
|
||||
<a onClick={handleDeleteRegion.bind(null, record)}>删除</a>
|
||||
</span>
|
||||
);
|
||||
},
|
||||
},
|
||||
];
|
||||
}
|
||||
|
||||
public componentDidMount() {
|
||||
region.getRegions(urlQuery.clusterId);
|
||||
}
|
||||
|
||||
public renderRegion() {
|
||||
if (!region.data) return null;
|
||||
const data = region.data.filter((d) => d.regionName.includes(this.state.searchKey));
|
||||
return (
|
||||
<Table
|
||||
columns={this.renderColumns()}
|
||||
dataSource={data}
|
||||
pagination={pagination}
|
||||
rowKey="regionId"
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
public render() {
|
||||
return (
|
||||
<>
|
||||
<ul className="table-operation-bar">
|
||||
<li className="new-topic" onClick={modal.showRegion.bind(null, null)}>
|
||||
<i className="k-icon-xinjian didi-theme" />新增Region
|
||||
</li>
|
||||
{this.renderSearch('请输入关键词')}
|
||||
</ul>
|
||||
<Tabs defaultActiveKey="1" type="card">
|
||||
<TabPane tab="Region管理" key="1">
|
||||
{this.renderRegion()}
|
||||
</TabPane>
|
||||
</Tabs>
|
||||
</>
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -1,148 +0,0 @@
|
||||
import * as React from 'react';
|
||||
|
||||
import { Table, Tabs, Form, notification, Modal, Tooltip } from 'component/antd';
|
||||
import { PaginationConfig } from 'antd/es/table/interface';
|
||||
import { UserHome } from 'container/user-home';
|
||||
import { topic } from 'store/topic';
|
||||
import urlQuery from 'store/url-query';
|
||||
import { modal } from 'store';
|
||||
import { observer } from 'mobx-react';
|
||||
import { deleteTopic } from 'lib/api';
|
||||
import { cluster } from 'store/cluster';
|
||||
import { ITopic } from 'types/base-type';
|
||||
|
||||
const pagination: PaginationConfig = {
|
||||
position: 'bottom',
|
||||
showQuickJumper: true,
|
||||
pageSize: 10,
|
||||
showTotal: (total) => `共 ${total} 条`,
|
||||
};
|
||||
|
||||
@observer
|
||||
class AdminTopic extends UserHome {
|
||||
|
||||
public cols = [
|
||||
{
|
||||
title: 'Topic名称',
|
||||
dataIndex: 'topicName',
|
||||
key: 'topicName',
|
||||
width: 350,
|
||||
onCell: () => ({
|
||||
style: {
|
||||
maxWidth: 250,
|
||||
overflow: 'hidden',
|
||||
whiteSpace: 'nowrap',
|
||||
textOverflow: 'ellipsis',
|
||||
cursor: 'pointer',
|
||||
},
|
||||
}),
|
||||
sorter: (a: ITopic, b: ITopic) => a.topicName.charCodeAt(0) - b.topicName.charCodeAt(0),
|
||||
render: (t: string, r: ITopic) => {
|
||||
return <a href={`/user/topic_detail?clusterId=${r.clusterId}&topic=${r.topicName}`}>{t}</a>;
|
||||
},
|
||||
},
|
||||
{
|
||||
title: '分区数',
|
||||
dataIndex: 'partitionNum',
|
||||
key: 'partitionNum',
|
||||
sorter: (a: ITopic, b: ITopic) => b.partitionNum - a.partitionNum,
|
||||
},
|
||||
{
|
||||
title: '副本数',
|
||||
dataIndex: 'replicaNum',
|
||||
key: 'replicaNum',
|
||||
sorter: (a: ITopic, b: ITopic) => b.replicaNum - a.replicaNum,
|
||||
},
|
||||
{
|
||||
title: '流入 (KB/s)',
|
||||
dataIndex: 'byteIn',
|
||||
key: 'byteIn',
|
||||
sorter: (a: ITopic, b: ITopic) => b.byteIn - a.byteIn,
|
||||
render: (t: number) => (t / 1024).toFixed(2),
|
||||
},
|
||||
{
|
||||
title: '流入(QPS)',
|
||||
dataIndex: 'produceRequest',
|
||||
key: 'produceRequest',
|
||||
width: 150,
|
||||
sorter: (a: ITopic, b: ITopic) => b.produceRequest - a.produceRequest,
|
||||
render: (t: number) => t.toFixed(2),
|
||||
},
|
||||
{
|
||||
title: '负责人',
|
||||
dataIndex: 'principals',
|
||||
key: 'principals',
|
||||
width: 120,
|
||||
onCell: () => ({
|
||||
style: {
|
||||
maxWidth: 100,
|
||||
overflow: 'hidden',
|
||||
whiteSpace: 'nowrap',
|
||||
textOverflow: 'ellipsis',
|
||||
cursor: 'pointer',
|
||||
},
|
||||
}),
|
||||
render: (t: string) => <Tooltip placement="top" title={t} >{t}</Tooltip>,
|
||||
sorter: (a: ITopic, b: ITopic) =>
|
||||
a.principals && b.principals ? a.principals.charCodeAt(0) - b.principals.charCodeAt(0) : (-1),
|
||||
},
|
||||
{
|
||||
title: '操作',
|
||||
dataIndex: 'operation',
|
||||
key: 'operation',
|
||||
width: 200,
|
||||
render: (text: string, r: ITopic) => {
|
||||
return (
|
||||
<span className="table-operation">
|
||||
<a onClick={modal.showExpandAdmin.bind(null, r)}>扩分区</a>
|
||||
<a onClick={modal.showAdimTopic.bind(null, r)}>编辑</a>
|
||||
<a onClick={this.handleDelete.bind(null, r)}>删除</a>
|
||||
</span>
|
||||
);
|
||||
},
|
||||
},
|
||||
];
|
||||
|
||||
public handleDelete = ({ clusterId, topicName }: ITopic) => {
|
||||
const topicNameList = [topicName];
|
||||
Modal.confirm({
|
||||
title: `确认删除${topicName}?`,
|
||||
okText: '确定',
|
||||
cancelText: '取消',
|
||||
onOk: () => {
|
||||
deleteTopic({ clusterId, topicNameList }).then(() => {
|
||||
notification.success({ message: '删除成功' });
|
||||
topic.getAdminTopics(urlQuery.clusterId);
|
||||
});
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
public renderTable() {
|
||||
|
||||
return (
|
||||
<>
|
||||
<Tabs type="card">
|
||||
<Tabs.TabPane tab="Topic管理" key="0">
|
||||
<Table pagination={pagination} columns={this.cols} dataSource={this.getData(topic.data)} rowKey="topicName" />
|
||||
</Tabs.TabPane>
|
||||
</Tabs>
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
public componentDidMount() {
|
||||
cluster.getClusters();
|
||||
topic.getAdminTopics(urlQuery.clusterId);
|
||||
}
|
||||
|
||||
public renderClusterTopic() {
|
||||
return (
|
||||
<>
|
||||
{this.renderSearch('请输入Topic名称或者负责人')}
|
||||
</>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default Form.create({ name: 'aminTopic' })(AdminTopic);
|
||||
@@ -1,12 +0,0 @@
|
||||
.u-container {
|
||||
width: 100%;
|
||||
height: 48px;
|
||||
background: rgba(0,0,0,0.02);
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
vertical-align: middle;
|
||||
line-height: 48px;
|
||||
padding: 0 12px;
|
||||
margin-top: 20px;
|
||||
position: relative;
|
||||
}
|
||||
@@ -1,97 +0,0 @@
|
||||
import * as React from 'react';
|
||||
|
||||
import { Table, notification, PaginationConfig, Modal } from 'component/antd';
|
||||
import { observer } from 'mobx-react';
|
||||
import { users } from 'store/users';
|
||||
import { deleteUser } from 'lib/api';
|
||||
import { modal } from 'store';
|
||||
import { SearchAndFilter } from 'container/cluster-topic';
|
||||
import './index.less';
|
||||
|
||||
const pagination: PaginationConfig = {
|
||||
position: 'bottom',
|
||||
showQuickJumper: true,
|
||||
pageSize: 10,
|
||||
showTotal: (total) => `共 ${total} 条`,
|
||||
};
|
||||
|
||||
const handleForbidden = (record: any) => {
|
||||
Modal.confirm({
|
||||
title: `确认删除 ${record.username} ?`,
|
||||
okText: '确定',
|
||||
cancelText: '取消',
|
||||
onOk: () => {
|
||||
deleteUser(record.username).then(() => {
|
||||
notification.success({ message: '删除成功' });
|
||||
users.getUsers();
|
||||
});
|
||||
},
|
||||
});
|
||||
};
|
||||
|
||||
@observer
|
||||
export class UserManage extends SearchAndFilter {
|
||||
public state = {
|
||||
searchKey: '',
|
||||
filterVisible: false,
|
||||
};
|
||||
|
||||
public renderColumns = () => {
|
||||
const role = Object.assign({
|
||||
title: '角色',
|
||||
key: 'roleName',
|
||||
dataIndex: 'roleName',
|
||||
filters: users.filterRole,
|
||||
onFilter: (value: string, record: any) => record.roleName.indexOf(value) === 0,
|
||||
}, this.renderColumnsFilter('filterVisible'));
|
||||
|
||||
return [
|
||||
{
|
||||
title: '用户名',
|
||||
dataIndex: 'username',
|
||||
key: 'username',
|
||||
},
|
||||
role,
|
||||
{
|
||||
title: '操作',
|
||||
dataIndex: 'operation',
|
||||
key: 'operation',
|
||||
render: (t: any, r: any) => {
|
||||
return (
|
||||
<span className="table-operation">
|
||||
<a onClick={modal.showNewUser.bind(null, r)}>修改</a>
|
||||
<a onClick={handleForbidden.bind(null, r)}>删除</a>
|
||||
</span>
|
||||
);
|
||||
},
|
||||
},
|
||||
];
|
||||
}
|
||||
|
||||
public componentDidMount() {
|
||||
users.getUsers();
|
||||
}
|
||||
|
||||
public render() {
|
||||
const data = users.userData.filter((d) => d.username.includes(this.state.searchKey));
|
||||
return (
|
||||
<>
|
||||
<div className="u-container">
|
||||
<span>管理员授权</span>
|
||||
<ul className="table-operation-bar">
|
||||
<li className="new-topic" onClick={modal.showNewUser.bind(null, null)}>
|
||||
<i className="k-icon-xinjian didi-theme" />新建用户
|
||||
</li>
|
||||
{this.renderSearch('用户名称')}
|
||||
</ul>
|
||||
</div>
|
||||
<Table
|
||||
columns={this.renderColumns()}
|
||||
dataSource={data}
|
||||
pagination={pagination}
|
||||
rowKey="username"
|
||||
/>
|
||||
</>
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -1,135 +0,0 @@
|
||||
import * as React from 'react';
|
||||
|
||||
import { Table, Tabs, Select, Input, notification, Modal } from 'component/antd';
|
||||
import { PaginationConfig } from 'antd/es/table/interface';
|
||||
import { modal } from 'store';
|
||||
import { observer } from 'mobx-react';
|
||||
import { alarm, IAlarm } from 'store/alarm';
|
||||
import { deleteAlarm } from 'lib/api';
|
||||
import { SearchAndFilter } from 'container/cluster-topic';
|
||||
import { getCookie } from 'lib/utils';
|
||||
import moment = require('moment');
|
||||
|
||||
const TabPane = Tabs.TabPane;
|
||||
const Search = Input.Search;
|
||||
|
||||
const handleDeleteAlarm = (record: IAlarm) => {
|
||||
Modal.confirm({
|
||||
title: `确认删除 ${record.alarmName} ?`,
|
||||
okText: '确定',
|
||||
cancelText: '取消',
|
||||
onOk: () => {
|
||||
deleteAlarm(record.id).then(() => {
|
||||
notification.success({ message: '删除成功' });
|
||||
alarm.getAlarm();
|
||||
});
|
||||
},
|
||||
});
|
||||
};
|
||||
|
||||
const pagination: PaginationConfig = {
|
||||
position: 'bottom',
|
||||
showQuickJumper: true,
|
||||
pageSize: 10,
|
||||
showTotal: (total) => `共 ${total} 条`,
|
||||
};
|
||||
|
||||
@observer
|
||||
export class Alarm extends SearchAndFilter {
|
||||
public state = {
|
||||
searchKey: '',
|
||||
filterVisible: false,
|
||||
};
|
||||
|
||||
public componentDidMount() {
|
||||
alarm.getAlarm();
|
||||
alarm.getAlarmConstant();
|
||||
}
|
||||
|
||||
public renderColumns = () => {
|
||||
const status = Object.assign({
|
||||
title: '状态',
|
||||
dataIndex: 'status',
|
||||
key: 'status',
|
||||
filters: [{ text: '已启用', value: '1' }, { text: '暂停', value: '0' }],
|
||||
onFilter: (value: string, record: IAlarm) => record.status === +value,
|
||||
render: (t: string) => <span className={t ? 'success' : ''}>{t ? '已启用' : '暂停'}</span>,
|
||||
}, this.renderColumnsFilter('filterVisible'));
|
||||
|
||||
return [
|
||||
{
|
||||
title: '配置名称',
|
||||
dataIndex: 'alarmName',
|
||||
key: 'alarmName',
|
||||
sorter: (a: IAlarm, b: IAlarm) => a.alarmName.charCodeAt(0) - b.alarmName.charCodeAt(0),
|
||||
},
|
||||
{
|
||||
title: '负责人',
|
||||
dataIndex: 'principalList',
|
||||
key: 'principalList',
|
||||
render: (t: string[]) => t.join(','),
|
||||
},
|
||||
{
|
||||
title: '创建时间',
|
||||
dataIndex: 'gmtCreate',
|
||||
key: 'gmtCreate',
|
||||
sorter: (a: IAlarm, b: IAlarm) => a.gmtCreate - b.gmtCreate,
|
||||
render: (t: number) => moment(t).format('YYYY-MM-DD HH:mm:ss'),
|
||||
},
|
||||
status,
|
||||
{
|
||||
title: '操作',
|
||||
dataIndex: 'operation',
|
||||
key: 'operation',
|
||||
width: 200,
|
||||
render: (text: string, record: IAlarm) => {
|
||||
return (
|
||||
<span className="table-operation">
|
||||
<a onClick={this.handleModify.bind(null, record)}>修改</a>
|
||||
<a onClick={handleDeleteAlarm.bind(null, record)}>删除</a>
|
||||
</span>
|
||||
);
|
||||
},
|
||||
},
|
||||
];
|
||||
}
|
||||
|
||||
public renderAlarm() {
|
||||
const data = alarm.data.filter((d) => {
|
||||
return d.alarmName.includes(this.state.searchKey) || d.principalList.includes(this.state.searchKey);
|
||||
});
|
||||
return (
|
||||
<Table
|
||||
columns={this.renderColumns()}
|
||||
dataSource={data}
|
||||
pagination={pagination}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
public handleModify = (record: IAlarm) => {
|
||||
if (!getCookie('username') && !record.principalList.includes(getCookie('username'))) {
|
||||
notification.success({ message: '抱歉,没有修改权限' });
|
||||
return false;
|
||||
}
|
||||
modal.showAlarmModify(record);
|
||||
}
|
||||
|
||||
public render() {
|
||||
return (
|
||||
<>
|
||||
<ul className="table-operation-bar">
|
||||
<li className="new-topic" onClick={modal.showAlarm.bind(null, null)}>
|
||||
<i className="k-icon-xinjian didi-theme" />添加告警配置
|
||||
</li>
|
||||
{this.renderSearch('请输入关键字')}
|
||||
</ul>
|
||||
<Tabs defaultActiveKey="1" type="card">
|
||||
<TabPane tab="告警列表" key="1">
|
||||
{this.renderAlarm()}
|
||||
</TabPane>
|
||||
</Tabs>
|
||||
</>
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -1,82 +0,0 @@
|
||||
import * as React from 'react';
|
||||
import { TopicDetail } from 'container/topic-detail';
|
||||
import './index.less';
|
||||
import { broker, IBrokerNetworkInfo } from 'store/broker';
|
||||
import { observer } from 'mobx-react';
|
||||
import { StatusGraghCom } from 'component/flow-table';
|
||||
import urlQuery from 'store/url-query';
|
||||
import { NetWorkFlow } from 'container/topic-detail/com';
|
||||
|
||||
@observer
|
||||
export class OneBrokerStatus extends StatusGraghCom<IBrokerNetworkInfo> {
|
||||
public getData() {
|
||||
return broker.oneNetwork;
|
||||
}
|
||||
}
|
||||
|
||||
export class BrokerBaseDetail extends TopicDetail {
|
||||
public componentDidMount() {
|
||||
broker.getOneBrokerNetwork(urlQuery.clusterId, urlQuery.brokerId);
|
||||
broker.getBrokerTopicAnalyzer(urlQuery.clusterId, urlQuery.brokerId);
|
||||
}
|
||||
|
||||
public render() {
|
||||
return (
|
||||
<>
|
||||
<div className="k-row right-flow mb-24">
|
||||
<p className="k-title">基本信息</p>
|
||||
<Summary />
|
||||
</div>
|
||||
<div className="k-row right-flow mb-24">
|
||||
<p className="k-title">历史流量</p>
|
||||
<NetWorkFlow clusterId={urlQuery.clusterId} brokerId={urlQuery.brokerId} />
|
||||
</div>
|
||||
<div className="k-row right-flow">
|
||||
<p className="k-title">实时流量</p>
|
||||
<span className="k-abs"><i className="k-icon-shuaxin didi-theme" />刷新</span>
|
||||
<OneBrokerStatus />
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@observer
|
||||
class Summary extends React.Component {
|
||||
public componentDidMount() {
|
||||
broker.getBrokerBaseInfo(urlQuery.clusterId, urlQuery.brokerId);
|
||||
}
|
||||
|
||||
public render() {
|
||||
return (
|
||||
<div className="k-summary">
|
||||
<div className="k-row-1">
|
||||
<div>主机:{broker.brokerBaseInfo.host}</div>
|
||||
<div>启动时间:{broker.brokerBaseInfo.startTime}</div>
|
||||
</div>
|
||||
<div className="k-row-3">
|
||||
<div>
|
||||
<span>Topic数</span>
|
||||
<p>{broker.brokerBaseInfo.topicNum}</p>
|
||||
</div>
|
||||
<div>
|
||||
<span>分区数</span>
|
||||
<p>{broker.brokerBaseInfo.partitionCount}</p>
|
||||
</div>
|
||||
<div>
|
||||
<span>分区Leader</span>
|
||||
<p>{broker.brokerBaseInfo.leaderCount}</p>
|
||||
</div>
|
||||
<div>
|
||||
<span>Port</span>
|
||||
<p>{broker.brokerBaseInfo.port}</p>
|
||||
</div>
|
||||
<div>
|
||||
<span>JMX Port</span>
|
||||
<p>{broker.brokerBaseInfo.jmxPort}</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -1,90 +0,0 @@
|
||||
import React from 'react';
|
||||
import { observer } from 'mobx-react';
|
||||
import { broker } from 'store/broker';
|
||||
import urlQuery from 'store/url-query';
|
||||
import echarts from 'echarts/lib/echarts';
|
||||
import { getBrokerMetricOption } from 'lib/charts-config';
|
||||
import { MetricChartList as list } from './constant';
|
||||
import { Spin, DatePicker, notification, Button } from 'component/antd';
|
||||
import './index.less';
|
||||
|
||||
// 引入柱状图
|
||||
import 'echarts/lib/chart/line';
|
||||
// 引入提示框和标题组件
|
||||
import 'echarts/lib/component/tooltip';
|
||||
import 'echarts/lib/component/title';
|
||||
import 'echarts/lib/component/legend';
|
||||
import moment from 'moment';
|
||||
|
||||
@observer
|
||||
export class BrokerMetrics extends React.Component {
|
||||
public chartId: HTMLDivElement[] = [];
|
||||
public charts: echarts.ECharts[] = [];
|
||||
|
||||
public state = {
|
||||
loading: true,
|
||||
};
|
||||
|
||||
public renderCharts(startTime: moment.Moment, endTime: moment.Moment) {
|
||||
broker.getBrokerKeyMetrics(urlQuery.clusterId, urlQuery.brokerId,
|
||||
startTime.format('x'),
|
||||
endTime.format('x')).then(data => {
|
||||
getBrokerMetricOption(list, data).forEach((ele: object, index) => {
|
||||
if (ele) {
|
||||
this.charts[index] = echarts.init(this.chartId[index]);
|
||||
this.charts[index].setOption(ele);
|
||||
this.setState({ loading: false });
|
||||
}
|
||||
this.charts[index] = null;
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
public componentDidMount() {
|
||||
this.renderCharts(broker.startTime, broker.endTime);
|
||||
}
|
||||
|
||||
public handleSearch = () => {
|
||||
const { startTime, endTime } = broker;
|
||||
if (startTime >= endTime) {
|
||||
notification.error({ message: '开始时间不能大于或等于结束时间' });
|
||||
return false;
|
||||
}
|
||||
this.setState({ loading: true });
|
||||
this.renderCharts(startTime, endTime);
|
||||
}
|
||||
|
||||
public render() {
|
||||
const charts = list.map((item, index) => {
|
||||
if (!item.value) return <div className="emptyChart" key={index} ref={(id) => this.chartId.push(id)} />;
|
||||
return (
|
||||
<div key={index}>
|
||||
<p>{item.label}</p>
|
||||
<Spin spinning={this.state.loading}>
|
||||
<div style={{ height: 300, padding: '0px 10px' }} ref={(id) => this.chartId.push(id)} />
|
||||
</Spin>
|
||||
</div>
|
||||
);
|
||||
});
|
||||
return (
|
||||
<>
|
||||
<div className="status-graph">
|
||||
<ul className="k-toolbar topic-line-tool">
|
||||
<li>
|
||||
<span className="label">开始时间</span>
|
||||
<DatePicker showTime={true} value={broker.startTime} onChange={broker.changeStartTime} />
|
||||
</li>
|
||||
<li>
|
||||
<span className="label" >结束时间</span>
|
||||
<DatePicker showTime={true} value={broker.endTime} onChange={broker.changeEndTime} />
|
||||
</li>
|
||||
<li><Button type="primary" size="small" onClick={this.handleSearch}>查询</Button></li>
|
||||
</ul>
|
||||
</div>
|
||||
<div className="charts-container" >
|
||||
{charts}
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -1,109 +0,0 @@
|
||||
import React from 'react';
|
||||
import { Table, PaginationConfig } from 'component/antd';
|
||||
import { observer } from 'mobx-react';
|
||||
import { broker, IPartitions } from 'store/broker';
|
||||
import { columsDefault } from './constant';
|
||||
import urlQuery from 'store/url-query';
|
||||
import './index.less';
|
||||
|
||||
const columns = [{
|
||||
title: 'Topic',
|
||||
dataIndex: 'topicName',
|
||||
key: 'topicName',
|
||||
}, {
|
||||
title: 'Leader',
|
||||
dataIndex: 'leaderPartitionList',
|
||||
onCell: () => ({
|
||||
style: {
|
||||
maxWidth: 250,
|
||||
overflow: 'hidden',
|
||||
whiteSpace: 'nowrap',
|
||||
textOverflow: 'ellipsis',
|
||||
cursor: 'pointer',
|
||||
},
|
||||
}),
|
||||
render: (value: number[]) => {
|
||||
return value.map(i => <span key={i} className="p-params">{i}</span>);
|
||||
},
|
||||
}, {
|
||||
title: '副本',
|
||||
dataIndex: 'followerPartitionIdList',
|
||||
onCell: () => ({
|
||||
style: {
|
||||
maxWidth: 250,
|
||||
overflow: 'hidden',
|
||||
whiteSpace: 'nowrap',
|
||||
textOverflow: 'ellipsis',
|
||||
cursor: 'pointer',
|
||||
},
|
||||
}),
|
||||
render: (value: number[]) => {
|
||||
return value.map(i => <span key={i} className="p-params">{i}</span>);
|
||||
},
|
||||
}, {
|
||||
title: '未同步副本',
|
||||
dataIndex: 'notUnderReplicatedPartitionIdList',
|
||||
render: (value: number[]) => {
|
||||
return value.map(i => <span key={i} className="p-params-unFinished">{i}</span>);
|
||||
},
|
||||
}, {
|
||||
title: '状态',
|
||||
dataIndex: 'underReplicated',
|
||||
render: (value: boolean) => {
|
||||
return value ? '已同步' : '未同步';
|
||||
},
|
||||
}, {
|
||||
title: '操作',
|
||||
render: (record: IPartitions) => {
|
||||
return (<a onClick={broker.handleOpen.bind(broker, record.topicName)}>查看详情</a>);
|
||||
},
|
||||
},
|
||||
];
|
||||
|
||||
const pagination: PaginationConfig = {
|
||||
position: 'bottom',
|
||||
showQuickJumper: true,
|
||||
pageSize: 10,
|
||||
showTotal: (total) => `共 ${total} 条`,
|
||||
};
|
||||
|
||||
@observer
|
||||
export class BrokerPartition extends React.Component {
|
||||
|
||||
public componentDidMount() {
|
||||
broker.getPartitions(urlQuery.clusterId, urlQuery.brokerId);
|
||||
}
|
||||
|
||||
public getDescription = (value: any, record: IPartitions) => {
|
||||
return Object.keys(value).map((key: keyof IPartitions) => {
|
||||
return (
|
||||
<p key={key}><span>{value[key]}</span>{(record[key] as []).join(',')}
|
||||
(共{(record[key] as []).length}个)</p>);
|
||||
});
|
||||
}
|
||||
|
||||
public getMoreDetail = (record: IPartitions) => {
|
||||
return (
|
||||
<div className="p-description">
|
||||
<p><span>Topic: </span>{record.topicName}</p>
|
||||
<p><span>isUnderReplicated:</span>{record.underReplicated ? '已同步' : '未同步'}</p>
|
||||
{this.getDescription(columsDefault, record)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
public render() {
|
||||
return (
|
||||
<Table
|
||||
columns={columns}
|
||||
expandIconAsCell={false}
|
||||
expandIconColumnIndex={-1}
|
||||
expandedRowRender={this.getMoreDetail}
|
||||
dataSource={broker.topicPartitionsInfo}
|
||||
expandedRowKeys={broker.openKeys}
|
||||
rowKey="topicName"
|
||||
pagination={pagination}
|
||||
/>
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -1,64 +0,0 @@
|
||||
export const MetricChartList = [
|
||||
{
|
||||
value: 'requestHandlerIdlPercent',
|
||||
label: '请求处理器空闲百分比(%)',
|
||||
},
|
||||
{
|
||||
value: 'networkProcessorIdlPercent',
|
||||
label: '网络处理器空闲百分比(%)',
|
||||
},
|
||||
{
|
||||
value: 'requestQueueSize',
|
||||
label: '请求列表大小(个)',
|
||||
},
|
||||
{
|
||||
value: 'responseQueueSize',
|
||||
label: '响应列表大小(个)',
|
||||
},
|
||||
{
|
||||
value: 'logFlushTime',
|
||||
label: '刷日志时间(ms)',
|
||||
},
|
||||
{
|
||||
value: '',
|
||||
label: '',
|
||||
},
|
||||
{
|
||||
value: 'totalTimeProduceMean',
|
||||
label: 'produce请求时间-平均值(ms)',
|
||||
},
|
||||
{
|
||||
value: 'totalTimeFetchConsumerMean',
|
||||
label: 'fetch请求处理时间-平均值(ms)',
|
||||
},
|
||||
{
|
||||
value: 'totalTimeProduce99Th',
|
||||
label: 'produce请求时间-99分位(ms)',
|
||||
},
|
||||
{
|
||||
value: 'totalTimeFetchConsumer99Th',
|
||||
label: 'fetch请求处理时间-99分位(ms)',
|
||||
},
|
||||
{
|
||||
value: 'failProduceRequest',
|
||||
label: '每秒生产失败数(条/秒)',
|
||||
},
|
||||
{
|
||||
value: 'failFetchRequest',
|
||||
label: '每秒消费失败数(条/秒)',
|
||||
},
|
||||
];
|
||||
|
||||
export const columsDefault = {
|
||||
leaderPartitionList: 'leaderPartitions:',
|
||||
followerPartitionIdList: 'followerPartitions:',
|
||||
notUnderReplicatedPartitionIdList: 'notUnderReplicatedPartitions:',
|
||||
};
|
||||
|
||||
export const brokerMetrics = {
|
||||
bytesIn: 'Bytes In(MB/ 秒)',
|
||||
bytesOut: 'Bytes Out(MB/ 秒)',
|
||||
messagesIn: 'Messages In(条)',
|
||||
totalFetchRequests: 'Total Fetch Requests(QPS)',
|
||||
totalProduceRequests: 'Total Produce Requests(QPS)',
|
||||
};
|
||||
@@ -1,37 +0,0 @@
|
||||
import * as React from 'react';
|
||||
import { Tabs } from 'component/antd';
|
||||
import { BrokerBaseDetail } from './base-detail';
|
||||
import { TopicAnalysis } from './topic-analysis';
|
||||
import { BrokerTopicInfo } from './topic-info';
|
||||
import { BrokerPartition } from './broker-partition';
|
||||
import { BrokerMetrics } from './broker-index';
|
||||
import { handleTabKey } from 'lib/utils';
|
||||
|
||||
const TabPane = Tabs.TabPane;
|
||||
|
||||
export class BrokerDetail extends React.Component {
|
||||
public render() {
|
||||
return (
|
||||
<Tabs activeKey={location.hash.substr(1) || '1'} type="card" onChange={handleTabKey}>
|
||||
<TabPane tab="状态信息" key="1">
|
||||
<BrokerBaseDetail />
|
||||
</TabPane>
|
||||
<TabPane tab="Topic信息" key="2">
|
||||
<BrokerTopicInfo />
|
||||
</TabPane>
|
||||
<TabPane tab="Partition信息" key="3">
|
||||
<BrokerPartition />
|
||||
</TabPane>
|
||||
{/* <TabPane tab="状态图" key="4">
|
||||
<NetWorkFlow clusterId={urlQuery.clusterId} />
|
||||
</TabPane> */}
|
||||
<TabPane tab="Topic分析" key="5">
|
||||
<TopicAnalysis />
|
||||
</TabPane>
|
||||
<TabPane tab="Broker关键指标" key="6">
|
||||
<BrokerMetrics />
|
||||
</TabPane>
|
||||
</Tabs>
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -1,94 +0,0 @@
|
||||
import * as React from 'react';
|
||||
import { Table } from 'component/antd';
|
||||
import urlQuery from 'store/url-query';
|
||||
import { broker, IBrokerMetrics } from 'store/broker';
|
||||
import { brokerMetrics } from './constant';
|
||||
import { observer } from 'mobx-react';
|
||||
|
||||
const columns = [{
|
||||
title: 'Topic名称',
|
||||
dataIndex: 'topicName',
|
||||
key: 'topicName',
|
||||
},
|
||||
{
|
||||
title: 'Bytes In(MB/s)',
|
||||
dataIndex: 'bytesInRate',
|
||||
key: 'bytesInRate',
|
||||
render: (t: number, record: any) => `${record && record.bytesIn} (${+Math.ceil((t * 100))}%)`,
|
||||
},
|
||||
{
|
||||
title: 'Bytes Out(MB/s)',
|
||||
dataIndex: 'bytesOutRate',
|
||||
key: 'bytesOutRate',
|
||||
render: (t: number, record: any) => `${record && record.bytesOut} (${+Math.ceil((t * 100))}%)`,
|
||||
},
|
||||
{
|
||||
title: 'Message In(秒)',
|
||||
dataIndex: 'messagesInRate',
|
||||
key: 'messagesInRate',
|
||||
render: (t: number, record: any) => `${record && record.messagesIn} (${+Math.ceil((t * 100))}%)`,
|
||||
},
|
||||
{
|
||||
title: 'Total Fetch Requests(秒)',
|
||||
dataIndex: 'totalFetchRequestsRate',
|
||||
key: 'totalFetchRequestsRate',
|
||||
render: (t: number, record: any) => `${record && record.totalFetchRequests} (${+Math.ceil((t * 100))}%)`,
|
||||
},
|
||||
{
|
||||
title: 'Total Produce Requests(秒)',
|
||||
dataIndex: 'totalProduceRequestsRate',
|
||||
key: 'totalProduceRequestsRate',
|
||||
render: (t: number, record: any) => `${record && record.totalProduceRequests} (${+Math.ceil((t * 100))}%)`,
|
||||
}];
|
||||
@observer
|
||||
export class TopicAnalysis extends React.Component {
|
||||
public componentDidMount() {
|
||||
broker.getOneBrokerNetwork(urlQuery.clusterId, urlQuery.brokerId);
|
||||
broker.getBrokerTopicAnalyzer(urlQuery.clusterId, urlQuery.brokerId);
|
||||
}
|
||||
|
||||
public render() {
|
||||
return (
|
||||
<>
|
||||
<div className="k-row right-flow mb-24">
|
||||
<p className="k-title">Broker 状态</p>
|
||||
<BrokerStatus />
|
||||
</div>
|
||||
<div className="k-row right-flow">
|
||||
<p className="k-title">Topic 状态</p>
|
||||
<span className="k-abs didi-theme" style={{ fontSize: '14px' }}>说明:数值后的百分比表示“占Broker总量的百分比”</span>
|
||||
<Table
|
||||
rowKey="name"
|
||||
columns={columns}
|
||||
dataSource={broker.analyzerData.topicAnalysisVOList}
|
||||
pagination={false}
|
||||
/>;
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
}
|
||||
}
|
||||
@observer
|
||||
class BrokerStatus extends React.Component {
|
||||
public render() {
|
||||
return (
|
||||
<div className="k-summary">
|
||||
<div className="k-row-3">
|
||||
<div>
|
||||
<span>Broker ID</span>
|
||||
<p>{urlQuery.brokerId}</p>
|
||||
</div>
|
||||
{broker.analyzerData ?
|
||||
Object.keys(brokerMetrics).map((i: keyof IBrokerMetrics) => {
|
||||
return (
|
||||
<div key={i}>
|
||||
<span className={brokerMetrics[i] && brokerMetrics[i].length > 25 ? 'long-text' : ''}>{brokerMetrics[i]}</span>
|
||||
<p>{broker.analyzerData[i] && broker.analyzerData[i].toFixed(2)}</p>
|
||||
</div>
|
||||
);
|
||||
}) : ''}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -1,102 +0,0 @@
|
||||
import React from 'react';
|
||||
import { Table, PaginationConfig } from 'component/antd';
|
||||
import { observer } from 'mobx-react';
|
||||
import { broker } from 'store/broker';
|
||||
import urlQuery from 'store/url-query';
|
||||
import moment from 'moment';
|
||||
import { ITopic } from 'types/base-type';
|
||||
import { SearchAndFilter } from 'container/cluster-topic';
|
||||
|
||||
const cloumns = [{
|
||||
title: 'Topic名称',
|
||||
key: 'topicName',
|
||||
width: 350,
|
||||
onCell: () => ({
|
||||
style: {
|
||||
maxWidth: 250,
|
||||
overflow: 'hidden',
|
||||
whiteSpace: 'nowrap',
|
||||
textOverflow: 'ellipsis',
|
||||
cursor: 'pointer',
|
||||
},
|
||||
}),
|
||||
sorter: (a: ITopic, b: ITopic) => a.topicName.charCodeAt(0) - b.topicName.charCodeAt(0),
|
||||
render: (t: string, r: ITopic) => {
|
||||
return (
|
||||
<a
|
||||
href={`/admin/topic_detail?clusterId=${urlQuery.clusterId}&topic=${r.topicName}`}
|
||||
target="_blank"
|
||||
>
|
||||
{r.topicName}
|
||||
</a>
|
||||
);
|
||||
},
|
||||
}, {
|
||||
title: '分区数',
|
||||
dataIndex: 'partitionNum',
|
||||
key: 'partitionNum',
|
||||
sorter: (a: ITopic, b: ITopic) => b.partitionNum - a.partitionNum,
|
||||
}, {
|
||||
title: '副本数',
|
||||
dataIndex: 'replicaNum',
|
||||
key: 'replicaNum',
|
||||
sorter: (a: ITopic, b: ITopic) => b.replicaNum - a.replicaNum,
|
||||
}, {
|
||||
title: '流入(KB/s)',
|
||||
dataIndex: 'byteIn',
|
||||
key: 'byteIn',
|
||||
sorter: (a: ITopic, b: ITopic) => b.byteIn - a.byteIn,
|
||||
render: (t: number) => (t / 1024).toFixed(2),
|
||||
}, {
|
||||
title: '流入(QPS)',
|
||||
dataIndex: 'produceRequest',
|
||||
key: 'produceRequest',
|
||||
sorter: (a: ITopic, b: ITopic) => b.produceRequest - a.produceRequest,
|
||||
render: (t: number) => t.toFixed(2),
|
||||
}, {
|
||||
title: '负责人',
|
||||
dataIndex: 'principals',
|
||||
key: 'principals',
|
||||
}, {
|
||||
title: '修改时间',
|
||||
dataIndex: 'updateTime',
|
||||
key: 'updateTime',
|
||||
sorter: (a: ITopic, b: ITopic) => a.updateTime - b.updateTime,
|
||||
render: (t: number) => moment(t).format('YYYY-MM-DD HH:mm:ss'),
|
||||
}, {
|
||||
}];
|
||||
|
||||
const pagination: PaginationConfig = {
|
||||
position: 'bottom',
|
||||
showQuickJumper: true,
|
||||
pageSize: 10,
|
||||
showTotal: (total) => `共 ${total} 条`,
|
||||
};
|
||||
|
||||
@observer
|
||||
export class BrokerTopicInfo extends SearchAndFilter {
|
||||
public state = {
|
||||
searchKey: '',
|
||||
filterClusterVisible: false,
|
||||
filterStatusVisible: false,
|
||||
};
|
||||
|
||||
public componentDidMount() {
|
||||
broker.getBrokerTopic(urlQuery.clusterId, urlQuery.brokerId);
|
||||
}
|
||||
public render() {
|
||||
const { searchKey } = this.state;
|
||||
const data: ITopic[] = broker.topics.filter((d) => d.topicName.includes(searchKey) ||
|
||||
(d.principals && d.principals.includes(searchKey)));
|
||||
return (
|
||||
<>
|
||||
<div style={{ height: 45 }}>
|
||||
<ul className="table-operation-bar">
|
||||
{this.renderSearch('请输入Topic名称或者负责人')}
|
||||
</ul>
|
||||
</div>
|
||||
<Table columns={cloumns} dataSource={data} rowKey="topicName" pagination={pagination} />
|
||||
</>
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -1,255 +0,0 @@
|
||||
import * as React from 'react';
|
||||
import './index.less';
|
||||
import { Table, Modal, notification, PaginationConfig, Button, Spin } from 'component/antd';
|
||||
import { broker, IBroker, IBrokerNetworkInfo, IBrokerPartition } from 'store/broker';
|
||||
import { observer } from 'mobx-react';
|
||||
import { StatusGraghCom } from 'component/flow-table';
|
||||
import urlQuery from 'store/url-query';
|
||||
import moment from 'moment';
|
||||
import { deleteBroker } from 'lib/api';
|
||||
import { SearchAndFilter } from 'container/cluster-topic';
|
||||
|
||||
import './index.less';
|
||||
import { modal } from 'store';
|
||||
import { tableFilter } from 'lib/utils';
|
||||
|
||||
const pagination: PaginationConfig = {
|
||||
position: 'bottom',
|
||||
showQuickJumper: true,
|
||||
pageSize: 5,
|
||||
showTotal: (total) => `共 ${total} 条`,
|
||||
};
|
||||
|
||||
@observer
|
||||
export class BrokerStatus extends StatusGraghCom<IBrokerNetworkInfo> {
|
||||
public getData() {
|
||||
return broker.network;
|
||||
}
|
||||
}
|
||||
|
||||
@observer
|
||||
export class BrokerList extends SearchAndFilter {
|
||||
public state = {
|
||||
searchKey: '',
|
||||
searchId: '',
|
||||
filterRegionVisible: false,
|
||||
filterStatusVisible: false,
|
||||
filterVisible: false,
|
||||
filterRVisible: false,
|
||||
};
|
||||
|
||||
public colPartition = (list: IBroker[]) => {
|
||||
const region = Object.assign({
|
||||
title: 'Region',
|
||||
dataIndex: 'regionName',
|
||||
key: 'regionName',
|
||||
filters: tableFilter<IBroker>(list, 'regionName'),
|
||||
onFilter: (value: string, record: IBroker) => record.regionName === value,
|
||||
}, this.renderColumnsFilter('filterRVisible'));
|
||||
|
||||
const status = Object.assign({
|
||||
title: '已同步',
|
||||
dataIndex: 'underReplicatedPartitionCount',
|
||||
key: 'underReplicatedPartitionCount',
|
||||
filters: [{ text: '是', value: '1' }, { text: '否', value: '0' }],
|
||||
onFilter: (value: string, record: IBrokerPartition) => {
|
||||
// underReplicatedPartitionCount > 0 表示未同步完成
|
||||
const syncStatus = record.underReplicatedPartitionCount ? '0' : '1';
|
||||
return syncStatus === value;
|
||||
},
|
||||
render: (text: number) => (
|
||||
<>
|
||||
<span style={{ marginRight: 8 }}>{text ? '否' : '是'}</span>
|
||||
</>
|
||||
),
|
||||
}, this.renderColumnsFilter('filterVisible'));
|
||||
|
||||
return [{
|
||||
title: 'BrokerID',
|
||||
dataIndex: 'brokerId',
|
||||
key: 'brokerId',
|
||||
sorter: (a: IBrokerPartition, b: IBrokerPartition) => a.brokerId - b.brokerId,
|
||||
}, {
|
||||
title: '峰值(MB/s)',
|
||||
dataIndex: 'bytesInPerSec',
|
||||
key: 'bytesInPerSec',
|
||||
sorter: (a: IBrokerPartition, b: IBrokerPartition) => a.bytesInPerSec - b.bytesInPerSec,
|
||||
render: (t: number) => (t / (1024 * 1024)).toFixed(2),
|
||||
}, {
|
||||
title: '分区数量',
|
||||
dataIndex: 'partitionCount',
|
||||
key: 'partitionCount',
|
||||
sorter: (a: IBrokerPartition, b: IBrokerPartition) => a.partitionCount - b.partitionCount,
|
||||
}, {
|
||||
title: 'Leader数量',
|
||||
dataIndex: 'leaderCount',
|
||||
key: 'leaderCount',
|
||||
sorter: (a: IBrokerPartition, b: IBrokerPartition) => a.leaderCount - b.leaderCount,
|
||||
}, {
|
||||
title: '未同步副本数量',
|
||||
dataIndex: 'notUnderReplicatedPartitionCount',
|
||||
key: 'notUnderReplicatedPartitionCount',
|
||||
sorter: (a: IBrokerPartition, b: IBrokerPartition) =>
|
||||
a.notUnderReplicatedPartitionCount - b.notUnderReplicatedPartitionCount,
|
||||
},
|
||||
status,
|
||||
region,
|
||||
];
|
||||
}
|
||||
|
||||
public colList = (list: IBroker[]) => {
|
||||
const region = Object.assign({
|
||||
title: 'Region',
|
||||
dataIndex: 'regionName',
|
||||
key: 'regionName',
|
||||
filters: tableFilter<IBroker>(list, 'regionName'),
|
||||
onFilter: (value: string, record: IBroker) => record.regionName === value,
|
||||
}, this.renderColumnsFilter('filterRegionVisible'));
|
||||
|
||||
const status = Object.assign({
|
||||
title: '状态',
|
||||
dataIndex: 'status',
|
||||
key: 'status',
|
||||
filters: [{ text: '未使用', value: '未使用' }, { text: '使用中', value: '使用中' }],
|
||||
onFilter: (value: string, record: IBroker) => record.status === value,
|
||||
render: (t: number) => t ? '未使用' : '使用中',
|
||||
}, this.renderColumnsFilter('filterStatusVisible'));
|
||||
|
||||
return [{
|
||||
title: 'BrokerID',
|
||||
dataIndex: 'brokerId',
|
||||
key: 'brokerId',
|
||||
sorter: (a: IBroker, b: IBroker) => a.brokerId - b.brokerId,
|
||||
render: (t: string, record: IBroker) => {
|
||||
return (
|
||||
<a
|
||||
href={`/admin/broker_detail?clusterId=${urlQuery.clusterId}&brokerId=${record.brokerId}`}
|
||||
target="_blank"
|
||||
>
|
||||
{t}
|
||||
</a>
|
||||
);
|
||||
},
|
||||
}, {
|
||||
title: '主机',
|
||||
dataIndex: 'host',
|
||||
key: 'host',
|
||||
sorter: (a: IBroker, b: IBroker) => a.host.charCodeAt(0) - b.host.charCodeAt(0),
|
||||
}, {
|
||||
title: 'Port',
|
||||
dataIndex: 'port',
|
||||
key: 'port',
|
||||
sorter: (a: IBroker, b: IBroker) => a.port - b.port,
|
||||
}, {
|
||||
title: 'JMX Port',
|
||||
dataIndex: 'jmxPort',
|
||||
key: 'jmxPort',
|
||||
sorter: (a: IBroker, b: IBroker) => a.jmxPort - b.jmxPort,
|
||||
}, {
|
||||
title: '启动时间',
|
||||
dataIndex: 'startTime',
|
||||
key: 'startTime',
|
||||
sorter: (a: IBroker, b: IBroker) => a.startTime - b.startTime,
|
||||
render: (t: number) => moment(t).format('YYYY-MM-DD HH:mm:ss'),
|
||||
}, {
|
||||
title: '流入(KB/s)',
|
||||
dataIndex: 'byteIn',
|
||||
key: 'byteIn',
|
||||
sorter: (a: IBroker, b: IBroker) => b.byteIn - a.byteIn,
|
||||
render: (t: number) => (t / 1024).toFixed(2),
|
||||
}, {
|
||||
title: '流出(KB/s)',
|
||||
dataIndex: 'byteOut',
|
||||
key: 'byteOut',
|
||||
sorter: (a: IBroker, b: IBroker) => b.byteOut - a.byteOut,
|
||||
render: (t: number) => (t / 1024).toFixed(2),
|
||||
},
|
||||
region,
|
||||
status,
|
||||
{
|
||||
title: '操作',
|
||||
render: (text: string, record: IBroker) => {
|
||||
return (
|
||||
<>
|
||||
<span className="table-operation">
|
||||
<a
|
||||
href={`/admin/broker_detail?clusterId=${urlQuery.clusterId}&brokerId=${record.brokerId}`}
|
||||
target="_blank"
|
||||
>详情
|
||||
</a>
|
||||
<a
|
||||
onClick={!record.status ? () => { } : this.deleteBroker.bind(null, record)}
|
||||
style={!record.status ? { cursor: 'not-allowed', color: '#999' } : {}}
|
||||
>删除
|
||||
</a>
|
||||
</span>
|
||||
</>
|
||||
);
|
||||
},
|
||||
}];
|
||||
}
|
||||
|
||||
public deleteBroker = ({ brokerId }: IBroker) => {
|
||||
Modal.confirm({
|
||||
title: `确认删除${brokerId}?`,
|
||||
okText: '确定',
|
||||
cancelText: '取消',
|
||||
onOk: () => {
|
||||
deleteBroker(urlQuery.clusterId, brokerId).then(() => {
|
||||
notification.success({ message: '删除成功' });
|
||||
broker.getBrokerList(urlQuery.clusterId);
|
||||
});
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
public componentDidMount() {
|
||||
broker.getBrokerList(urlQuery.clusterId);
|
||||
broker.getBrokerPartition(urlQuery.clusterId);
|
||||
}
|
||||
|
||||
public render() {
|
||||
const dataList = this.state.searchKey !== '' ?
|
||||
broker.list.filter((d) => d.host.includes(this.state.searchKey) || d.brokerId === +this.state.searchKey)
|
||||
: broker.list;
|
||||
const dataPartitions = this.state.searchId !== '' ?
|
||||
broker.partitions.filter((d) => d.brokerId === +this.state.searchId) : broker.partitions;
|
||||
return (
|
||||
<Spin spinning={broker.loading}>
|
||||
<div className="k-row">
|
||||
<ul className="k-tab">
|
||||
<li>Broker概览</li>
|
||||
<li className="k-tab-button">
|
||||
<Button type="primary" onClick={modal.showLeaderRebalance}>Leader Rebalance</Button>
|
||||
</li>
|
||||
{this.renderSearch('请输入主机或BrokerId')}
|
||||
</ul>
|
||||
<div style={this.state.searchKey ? { minHeight: 370 } : null}>
|
||||
<Table
|
||||
columns={this.colList(dataList)}
|
||||
dataSource={dataList}
|
||||
rowKey="brokerId"
|
||||
pagination={pagination}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="k-row" style={{ height: 400 }}>
|
||||
<ul className="k-tab">
|
||||
<li>Broker分区概览</li>
|
||||
<li className="k-tab-button">
|
||||
<Button type="primary" onClick={modal.showLeaderRebalance}>Leader Rebalance</Button>
|
||||
</li>
|
||||
{this.renderSearch('请输入BrokerId', 'searchId')}
|
||||
</ul>
|
||||
<Table
|
||||
columns={this.colPartition(dataPartitions)}
|
||||
dataSource={dataPartitions}
|
||||
rowKey="brokerId"
|
||||
pagination={pagination}
|
||||
/>
|
||||
</div>
|
||||
</Spin>
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -1,79 +0,0 @@
|
||||
import * as React from 'react';
|
||||
import { Select, Button, Tooltip } from 'component/antd';
|
||||
import { observer } from 'mobx-react';
|
||||
import urlQuery from 'store/url-query';
|
||||
import './index.less';
|
||||
import moment = require('moment');
|
||||
import { modal } from 'store';
|
||||
import { selecOptions } from './constant';
|
||||
import { broker, IBrokerPartition, IOverviewKey } from 'store/broker';
|
||||
|
||||
@observer
|
||||
export class BrokerOverview extends React.Component {
|
||||
public renderSquare = (type: IOverviewKey) => {
|
||||
return broker.realPartitions.map((item: IBrokerPartition) => {
|
||||
const brokerDetail = (
|
||||
<div>
|
||||
<p><span>ID:</span>{item.brokerId}</p>
|
||||
<p><span>{selecOptions[type]}</span>{item[type]}</p>
|
||||
<p><span>主机: </span>{item.host}</p>
|
||||
<p><span>端口:</span>{item.port}</p>
|
||||
<p><span>jmx端口:</span>{item.jmxPort}</p>
|
||||
<p><span>启动时间:</span>{moment(item.startTime).format('YYYY-MM-DD HH:mm:ss')}</p>
|
||||
</div>
|
||||
);
|
||||
return (
|
||||
<Tooltip key={item.brokerId} placement="right" title={brokerDetail}>
|
||||
<a
|
||||
className={type === 'notUnderReplicatedPartitionCount' && item[type] ? 'finished' : ''}
|
||||
href={`/admin/broker_detail?clusterId=${urlQuery.clusterId}&brokerId=${item.brokerId}`}
|
||||
target="_blank"
|
||||
>{item[type]}
|
||||
</a>
|
||||
</Tooltip>
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
public render() {
|
||||
return (
|
||||
<>
|
||||
<ul className="topic-line-tool">
|
||||
<li>
|
||||
<span className="label">Region</span>
|
||||
<Select defaultValue="all" style={{ width: '260px' }} onChange={broker.filterSquare}>
|
||||
<Select.Option value="all">全部</Select.Option>
|
||||
{broker.regionOption.map((i: any) => <Select.Option
|
||||
key={i.brokerId}
|
||||
value={i.regionName}
|
||||
>{i.regionName}
|
||||
</Select.Option>)}
|
||||
</Select>
|
||||
</li>
|
||||
<li>
|
||||
<span className="label">维度</span>
|
||||
<Select defaultValue={broker.viewType} style={{ width: '160px' }} onChange={broker.handleOverview}>
|
||||
{Object.keys(selecOptions)
|
||||
.map((i: IOverviewKey) => <Select.Option value={i} key={i}>{selecOptions[i]}</Select.Option>)}
|
||||
</Select>
|
||||
</li>
|
||||
<li>
|
||||
<Button type="primary" onClick={modal.showLeaderRebalance}>Leader Rebalance</Button>
|
||||
</li>
|
||||
{
|
||||
broker.viewType === 'notUnderReplicatedPartitionCount' ?
|
||||
<li className="introduce">
|
||||
<span className="common common-green" />
|
||||
<span className="label">同步</span>
|
||||
<span className="common common-red" />
|
||||
<span className="label">未同步</span>
|
||||
</li> : ''
|
||||
}
|
||||
</ul>
|
||||
<div className="square-container">
|
||||
{this.renderSquare(broker.viewType)}
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -1,5 +0,0 @@
|
||||
export const selecOptions = {
|
||||
partitionCount: '分区数量',
|
||||
leaderCount: 'leader数量',
|
||||
notUnderReplicatedPartitionCount: '副本状态',
|
||||
};
|
||||
@@ -1,84 +0,0 @@
|
||||
.square-container {
|
||||
width: 100%;
|
||||
background-color: #fff;
|
||||
padding: 17px 20px;
|
||||
a {
|
||||
display: inline-block;
|
||||
width: 35px;
|
||||
height: 22px;
|
||||
background: rgba(255, 241, 240, 1);
|
||||
border-radius: 4px;
|
||||
line-height: 22px;
|
||||
margin-right: 20px;
|
||||
text-align: center;
|
||||
color: #f5222d;
|
||||
&.finished {
|
||||
background: rgba(47, 194, 91, 0.2);
|
||||
color: #2fc25b;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.topic-line-tool {
|
||||
height: 48px;
|
||||
font-size: 14px;
|
||||
font-family: PingFangSC-Regular;
|
||||
font-weight: 400;
|
||||
color: rgba(0, 0, 0, 0.85);
|
||||
background: rgba(250, 250, 250);
|
||||
li {
|
||||
display: inline-block;
|
||||
vertical-align: middle;
|
||||
margin-left: 24px;
|
||||
line-height: 48px;
|
||||
span.label {
|
||||
padding-right: 10px;
|
||||
}
|
||||
&.introduce {
|
||||
float: right;
|
||||
span.common {
|
||||
display: inline-block;
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
border-radius: 8px;
|
||||
vertical-align: middle;
|
||||
margin-right: 10px;
|
||||
&-green {
|
||||
background: rgba(47, 194, 91, 1);
|
||||
}
|
||||
&-red {
|
||||
background: rgba(245, 34, 45, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.k-tab {
|
||||
width: 100%;
|
||||
height: 48px;
|
||||
line-height: 48px;
|
||||
background: rgba(0, 0, 0, 0.02);
|
||||
padding: 0px 24px;
|
||||
font-size: 14px;
|
||||
font-family: PingFangSC-Medium;
|
||||
font-weight: 500;
|
||||
color: rgba(0, 0, 0, 0.85);
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
position: relative;
|
||||
margin: 0;
|
||||
.k-tab-button {
|
||||
position: absolute;
|
||||
right: 213px;
|
||||
}
|
||||
}
|
||||
|
||||
.deleteButton {
|
||||
&.ant-btn {
|
||||
color: #f38031;
|
||||
text-decoration: none;
|
||||
border: none;
|
||||
background-color: transparent;
|
||||
}
|
||||
}
|
||||
@@ -1,21 +0,0 @@
|
||||
import * as React from 'react';
|
||||
import { Tabs } from 'component/antd';
|
||||
import { BrokerList } from './base-info';
|
||||
import { BrokerOverview } from './broker-overview';
|
||||
|
||||
const TabPane = Tabs.TabPane;
|
||||
|
||||
export class BrokerInfo extends React.Component {
|
||||
public render() {
|
||||
return (
|
||||
<Tabs defaultActiveKey="1" type="card">
|
||||
<TabPane tab="Broker状态概览" key="1">
|
||||
<BrokerList />
|
||||
</TabPane>
|
||||
{/* <TabPane tab="Broker状态总览" key="2">
|
||||
<BrokerOverview />
|
||||
</TabPane> */}
|
||||
</Tabs>
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -1,98 +0,0 @@
|
||||
import * as React from 'react';
|
||||
import { Select, Input, Checkbox, Icon } from 'component/antd';
|
||||
import { cluster } from 'store/cluster';
|
||||
import { IFiler } from 'types/base-type';
|
||||
|
||||
const Option = Select.Option;
|
||||
const Search = Input.Search;
|
||||
|
||||
interface IParams {
|
||||
filters: IFiler[];
|
||||
setSelectedKeys: (selectedKeys: string[]) => void;
|
||||
confirm?: () => void;
|
||||
}
|
||||
|
||||
interface IState {
|
||||
[filter: string]: boolean | string;
|
||||
}
|
||||
|
||||
export class SearchAndFilter extends React.Component<any, IState> {
|
||||
public timer: number;
|
||||
|
||||
public renderCluster() {
|
||||
return (
|
||||
<li>
|
||||
<Select value={cluster.active} onChange={cluster.changeCluster}>
|
||||
{cluster.data.map((d) => <Option value={d.clusterId} key={d.clusterId}>{d.clusterName}</Option>)}
|
||||
</Select>
|
||||
</li>
|
||||
);
|
||||
}
|
||||
|
||||
public renderSearch(placeholder?: string, keyName: string = 'searchKey') {
|
||||
return (
|
||||
<li><Search placeholder={placeholder || '请输入Topic名称'} onChange={this.onSearchChange.bind(null, keyName)} /></li>
|
||||
);
|
||||
}
|
||||
|
||||
public onSearchChange = (keyName: string, e: React.ChangeEvent<HTMLInputElement>) => {
|
||||
const searchKey = e.target.value.trim();
|
||||
this.setState({
|
||||
[keyName]: searchKey,
|
||||
});
|
||||
}
|
||||
|
||||
public handleChange(params: IParams, e: []) {
|
||||
const { setSelectedKeys, confirm } = params;
|
||||
setSelectedKeys(e);
|
||||
confirm();
|
||||
}
|
||||
|
||||
public handleVisble = (type: string) => {
|
||||
if (this.timer) window.clearTimeout(this.timer);
|
||||
window.setTimeout(() => {
|
||||
this.setState({ [type]: true });
|
||||
});
|
||||
}
|
||||
|
||||
public handleUnVisble = (type: string) => {
|
||||
this.timer = window.setTimeout(() => {
|
||||
this.setState({ [type]: false });
|
||||
}, 100);
|
||||
}
|
||||
|
||||
public renderFilter = (type: string, params: IParams) => {
|
||||
const { filters } = params;
|
||||
return filters !== undefined ? (
|
||||
<ul
|
||||
onMouseOver={this.handleVisble.bind(null, type)}
|
||||
onMouseLeave={this.handleUnVisble.bind(null, type)}
|
||||
className="ant-dropdown-menu ant-dropdown-menu-vertical"
|
||||
>
|
||||
<Checkbox.Group onChange={this.handleChange.bind(null, params)}>
|
||||
{filters.map(i => <li key={i.value} className="ant-dropdown-menu-item">
|
||||
<Checkbox value={i.value} >{i.text}</Checkbox>
|
||||
</li>)}
|
||||
</Checkbox.Group>
|
||||
</ul>
|
||||
) : <div />;
|
||||
}
|
||||
|
||||
public renderFilterIcon = (type: string) => {
|
||||
return (
|
||||
<span
|
||||
onMouseOver={this.handleVisble.bind(null, type)}
|
||||
onMouseLeave={this.handleUnVisble.bind(null, type)}
|
||||
><Icon type="filter" theme="filled" />
|
||||
</span>
|
||||
);
|
||||
}
|
||||
|
||||
public renderColumnsFilter = (type: string) => {
|
||||
return {
|
||||
filterIcon: this.renderFilterIcon.bind(null, type),
|
||||
filterDropdownVisible: this.state[type],
|
||||
filterDropdown: this.renderFilter.bind(null, type),
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -1,34 +0,0 @@
|
||||
.ant-table-title {
|
||||
padding: 0px 0px 16px 0px;
|
||||
}
|
||||
|
||||
.consumer-container {
|
||||
.ant-table-title {
|
||||
position: absolute;
|
||||
top: -38px;
|
||||
}
|
||||
}
|
||||
|
||||
.group-title {
|
||||
display: inline-block;
|
||||
font-size: 14px;
|
||||
font-weight: 700;
|
||||
color: rgb(105, 105, 105);
|
||||
> div {
|
||||
display: inline-block;
|
||||
border: 0.5px dashed rgba(0, 0, 0, 0.3);
|
||||
padding: 5px 8px;
|
||||
margin-right: 10px;
|
||||
span {
|
||||
color: #f38031;
|
||||
font-weight: 700;
|
||||
}
|
||||
&.group-select {
|
||||
width: 250px;
|
||||
border: none;
|
||||
.ant-select {
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,111 +0,0 @@
|
||||
import * as React from 'react';
|
||||
|
||||
import { Table, Tabs, PaginationConfig, Select } from 'component/antd';
|
||||
import Url from 'lib/url-parser';
|
||||
import { topic, IGroupInfo } from 'store/topic';
|
||||
import { observer } from 'mobx-react';
|
||||
import { TopicDetail } from 'container/topic-detail';
|
||||
|
||||
import './index.less';
|
||||
|
||||
const TabPane = Tabs.TabPane;
|
||||
|
||||
const parColumns = [
|
||||
{
|
||||
title: 'Partition ID',
|
||||
dataIndex: 'partitionId',
|
||||
key: 'partitionId',
|
||||
sorter: (a: IGroupInfo, b: IGroupInfo) => a.partitionId - b.partitionId,
|
||||
},
|
||||
{
|
||||
title: 'Consume ID',
|
||||
dataIndex: 'clientId',
|
||||
key: 'clientId',
|
||||
sorter: (a: IGroupInfo, b: IGroupInfo) => +a.clientId - +b.clientId,
|
||||
},
|
||||
{
|
||||
title: 'Consumer Offset',
|
||||
dataIndex: 'consumeOffset',
|
||||
key: 'consumeOffset',
|
||||
sorter: (a: IGroupInfo, b: IGroupInfo) => a.consumeOffset - b.consumeOffset,
|
||||
},
|
||||
{
|
||||
title: 'Partition Offset',
|
||||
dataIndex: 'partitionOffset',
|
||||
key: 'partitionOffset',
|
||||
sorter: (a: IGroupInfo, b: IGroupInfo) => a.partitionOffset - b.partitionOffset,
|
||||
},
|
||||
{
|
||||
title: 'Lag',
|
||||
dataIndex: 'lag',
|
||||
key: 'lag',
|
||||
sorter: (a: IGroupInfo, b: IGroupInfo) => a.lag - b.lag,
|
||||
},
|
||||
];
|
||||
|
||||
const pagination: PaginationConfig = {
|
||||
position: 'bottom',
|
||||
showQuickJumper: true,
|
||||
pageSize: 10,
|
||||
showTotal: (total) => `共 ${total} 条`,
|
||||
};
|
||||
|
||||
@observer
|
||||
export class Consumer extends TopicDetail {
|
||||
public clusterId: number;
|
||||
public topicName: string;
|
||||
public group: string;
|
||||
public location: string;
|
||||
|
||||
constructor(props: any) {
|
||||
super(props);
|
||||
const url = Url();
|
||||
this.clusterId = Number(url.search.clusterId);
|
||||
this.topicName = url.search.topic;
|
||||
this.location = url.search.location;
|
||||
this.group = url.search.group;
|
||||
this.handleGroupChange(this.group + ',' + this.location);
|
||||
}
|
||||
|
||||
public handleGroupChange = (value: string) => {
|
||||
const { topicName, clusterId } = this;
|
||||
topic.getGroupInfo(topicName, clusterId, value.split(',')[0], value.split(',')[1]);
|
||||
}
|
||||
|
||||
public renderHeader = () => {
|
||||
return (
|
||||
<div className="group-title">
|
||||
consumerGroup:
|
||||
<div className="group-select">
|
||||
<Select defaultValue={this.group} onChange={this.handleGroupChange}>
|
||||
{topic.consumeInfo.map((d) => <Select.Option value={d.consumerGroup + ',' + d.location} key={d.consumerGroup}>
|
||||
{d.consumerGroup}</Select.Option>)}
|
||||
</Select>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
public renderConsumer() {
|
||||
const data = this.state.searchKey ?
|
||||
topic.groupInfo.filter((g) => g.partitionId === Number(this.state.searchKey)) : topic.groupInfo;
|
||||
return (
|
||||
<Table
|
||||
rowKey="partitionId"
|
||||
columns={parColumns}
|
||||
dataSource={data}
|
||||
pagination={pagination}
|
||||
title={this.renderHeader}
|
||||
className={location.pathname.includes('admin') ? 'consumer-container' : ''}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
public renderTab() {
|
||||
return (
|
||||
<TabPane tab="消费详情" key="2">
|
||||
{this.renderConsumer()}
|
||||
</TabPane>
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -1,31 +0,0 @@
|
||||
.o-container {
|
||||
width: 100%;
|
||||
padding: 40px 0 0 10px;
|
||||
.b-list {
|
||||
button {
|
||||
margin: 0 5px 0 10px;
|
||||
}
|
||||
}
|
||||
.headLine {
|
||||
padding-top: 30px;
|
||||
margin-top: 30px;
|
||||
color: #f38031;
|
||||
border-top: 1px solid rgb(216, 216, 216);
|
||||
}
|
||||
.timeButton {
|
||||
position: relative;
|
||||
left: 260px;
|
||||
top: 40px;
|
||||
}
|
||||
.partionButton {
|
||||
float: right;
|
||||
margin: 20px 15px 0 0;
|
||||
}
|
||||
.b-item {
|
||||
margin-top: 20px;
|
||||
padding-left: 222px;
|
||||
button {
|
||||
margin-right: 10px;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,19 +0,0 @@
|
||||
import * as React from 'react';
|
||||
import { observer } from 'mobx-react';
|
||||
import { drawer } from 'store/drawer';
|
||||
|
||||
import ResetOffset from './reset-offset';
|
||||
import TopicSample from './topic-sample';
|
||||
|
||||
@observer
|
||||
export default class AllDrawerInOne extends React.Component {
|
||||
public render() {
|
||||
if (!drawer.id) return null;
|
||||
return (
|
||||
<>
|
||||
{drawer.id === 'showResetOffset' ? <ResetOffset /> : null}
|
||||
{drawer.id === 'showTopicSample' ? <TopicSample /> : null}
|
||||
</>
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -1,118 +0,0 @@
|
||||
import * as React from 'react';
|
||||
import { Drawer, Form, Row, Button, Input, DatePicker, Col, Select, message, Alert } from 'component/antd';
|
||||
import { drawer } from 'store/drawer';
|
||||
import { topic } from 'store/topic';
|
||||
import { consume } from 'store/consume';
|
||||
import { observer } from 'mobx-react';
|
||||
|
||||
import './index.less';
|
||||
import moment = require('moment');
|
||||
|
||||
@observer
|
||||
class ResetOffset extends React.Component<any> {
|
||||
|
||||
public handleSubmit = (e: React.MouseEvent<any, MouseEvent>) => {
|
||||
e.preventDefault();
|
||||
this.props.form.validateFields((err: Error, values: any) => {
|
||||
if (err) return;
|
||||
const { timestamp } = values;
|
||||
consume.offsetPartition(Object.assign({ timestamp: +moment(timestamp).format('x') }, topic.currentGroup))
|
||||
.then(() => {
|
||||
message.success('重置时间成功');
|
||||
window.setTimeout(() => {
|
||||
location.reload();
|
||||
}, 200);
|
||||
});
|
||||
});
|
||||
}
|
||||
public submitPartiton = () => {
|
||||
consume.offsetPartition(topic.currentGroup, 1).then(() => {
|
||||
message.success('重置分区成功');
|
||||
window.setTimeout(() => {
|
||||
location.reload();
|
||||
}, 200);
|
||||
});
|
||||
}
|
||||
|
||||
public render() {
|
||||
const { getFieldDecorator } = this.props.form;
|
||||
return (
|
||||
<Drawer
|
||||
title="重置消费偏移"
|
||||
width={520}
|
||||
closable={false}
|
||||
onClose={drawer.close}
|
||||
visible={true}
|
||||
destroyOnClose={true}
|
||||
>
|
||||
<Alert message="重置之前一定要停止消费任务!!!" type="warning" showIcon={true} />
|
||||
<div className="o-container">
|
||||
<Form labelAlign="left" onSubmit={this.handleSubmit} >
|
||||
<Row>
|
||||
<p style={{ fontSize: '14px', color: '#f38031' }}>重置到指定时间</p>
|
||||
</Row>
|
||||
<Row gutter={16}>
|
||||
<Col span={6}>
|
||||
<Form.Item label="请选择时间" >
|
||||
{getFieldDecorator('timestamp', {
|
||||
rules: [{ required: true, message: '请选择时间' }],
|
||||
initialValue: moment(),
|
||||
})(
|
||||
<DatePicker showTime={true} style={{ width: '50%' }} />,
|
||||
)}
|
||||
</Form.Item>
|
||||
</Col>
|
||||
<Col span={6}>
|
||||
<Form.Item className="timeButton">
|
||||
<Button type="primary" htmlType="submit">
|
||||
重置
|
||||
</Button>
|
||||
</Form.Item>
|
||||
</Col>
|
||||
</Row>
|
||||
<Row className="headLine">
|
||||
<p style={{ fontSize: '14px' }}>重置到指定分区</p>
|
||||
</Row>
|
||||
<Row>
|
||||
<Form.Item>
|
||||
<Row>
|
||||
<Col span={8}>partitionId</Col>
|
||||
<Col span={16}>partitionOffset</Col>
|
||||
</Row>
|
||||
{consume.offsetList.map((ele, index) => {
|
||||
return (
|
||||
<Row key={index} gutter={16}>
|
||||
<Col span={8}>
|
||||
<Select placeholder="请选择" onChange={consume.selectChange.bind(consume, index)}>
|
||||
{topic.groupInfo.map((r, k) => {
|
||||
return <Select.Option key={k} value={r.partitionId}>{r.partitionId}</Select.Option>;
|
||||
})}
|
||||
</Select></Col>
|
||||
<Col span={10}>
|
||||
<Input placeholder="请输入partition offset" onChange={consume.inputChange.bind(consume, index)} />
|
||||
</Col>
|
||||
<Col span={6} className="b-list">
|
||||
<Button type="dashed" icon="plus" onClick={consume.handleList.bind(null, null)} />
|
||||
<Button
|
||||
type="dashed"
|
||||
icon="minus"
|
||||
disabled={index === 0}
|
||||
onClick={consume.handleList.bind(null, index)}
|
||||
/>
|
||||
</Col>
|
||||
</Row>
|
||||
);
|
||||
})}
|
||||
<Row className="partionButton">
|
||||
<Button type="primary" onClick={this.submitPartiton}>重置</Button>
|
||||
</Row>
|
||||
</Form.Item>
|
||||
</Row>
|
||||
</Form>
|
||||
</div>
|
||||
</Drawer>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default Form.create({ name: 'topicSample' })(ResetOffset);
|
||||
@@ -1,103 +0,0 @@
|
||||
import * as React from 'react';
|
||||
import { Drawer, Form, Row, Button, Input, InputNumber, notification } from 'component/antd';
|
||||
import { drawer } from 'store/drawer';
|
||||
|
||||
import './index.less';
|
||||
import { topic } from 'store/topic';
|
||||
|
||||
const topicFormItemLayout = {
|
||||
labelCol: {
|
||||
span: 5,
|
||||
},
|
||||
wrapperCol: {
|
||||
span: 14,
|
||||
},
|
||||
};
|
||||
|
||||
class TopicSample extends React.Component<any> {
|
||||
public state = {
|
||||
loading: false,
|
||||
};
|
||||
|
||||
public handleSubmit = (e: React.MouseEvent<any, MouseEvent>) => {
|
||||
e.preventDefault();
|
||||
this.props.form.validateFields((err: Error, values: any) => {
|
||||
if (err) return;
|
||||
const { offset, partitionId } = values;
|
||||
const bothExist = [offset, partitionId].filter(item => item === undefined || item === null).length;
|
||||
if (bothExist === 1) {
|
||||
notification.error({ message: '分区号和偏移量必须同时存在' });
|
||||
return false;
|
||||
}
|
||||
this.setState({ loading: true });
|
||||
topic.addSample(Object.assign(drawer.topicData, values)).then(() => this.setState({ loading: false }));
|
||||
});
|
||||
}
|
||||
|
||||
public cleanData = () => {
|
||||
topic.sampleData = null;
|
||||
drawer.close();
|
||||
}
|
||||
public render() {
|
||||
const { getFieldDecorator } = this.props.form;
|
||||
return (
|
||||
<Drawer
|
||||
title="Topic 采样"
|
||||
width={620}
|
||||
closable={false}
|
||||
onClose={this.cleanData}
|
||||
visible={true}
|
||||
destroyOnClose={true}
|
||||
>
|
||||
<div className="o-container">
|
||||
<Form {...topicFormItemLayout} labelAlign="right" onSubmit={this.handleSubmit} >
|
||||
<Row>
|
||||
<Form.Item label="最大采样条数" >
|
||||
{getFieldDecorator('maxMsgNum', {
|
||||
rules: [{ required: true, message: '请输入最大采样条数' }],
|
||||
initialValue: 1,
|
||||
})(<Input />)}
|
||||
</Form.Item>
|
||||
</Row>
|
||||
<Row>
|
||||
<Form.Item label="最大采样时间">
|
||||
{getFieldDecorator('timeout', {
|
||||
rules: [{ required: true, message: '请输入最大采样时间' }],
|
||||
initialValue: 3000,
|
||||
})(<Input />)}
|
||||
</Form.Item>
|
||||
</Row>
|
||||
<Row>
|
||||
<Form.Item label="分区号">
|
||||
{getFieldDecorator('partitionId')(<InputNumber min={0} />)}
|
||||
</Form.Item>
|
||||
</Row>
|
||||
<Row>
|
||||
<Form.Item label="偏移量">
|
||||
{getFieldDecorator('offset')(<InputNumber min={0} />)}
|
||||
</Form.Item>
|
||||
</Row>
|
||||
<Row>
|
||||
<Form.Item className="b-item">
|
||||
<Button type="primary" htmlType="submit" loading={this.state.loading}>确认</Button>
|
||||
<Button type="primary" onClick={this.cleanData}>取消</Button>
|
||||
</Form.Item>
|
||||
</Row>
|
||||
</Form>
|
||||
{
|
||||
topic.sampleData ?
|
||||
topic.sampleData.map((i: any, index: number) => {
|
||||
return <Input.TextArea
|
||||
value={i.value}
|
||||
style={{ height: 120, width: 500, marginTop: 10 }}
|
||||
key={index}
|
||||
/>;
|
||||
}) : null
|
||||
}
|
||||
</div>
|
||||
</Drawer>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default Form.create({ name: 'topicSample' })(TopicSample);
|
||||
@@ -1,103 +0,0 @@
|
||||
.kafka-header-container {
|
||||
height: 64px;
|
||||
background-color: #fff;
|
||||
box-shadow: 0px 2px 4px 0px rgba(0, 0, 0, .1);
|
||||
position: relative;
|
||||
z-index: 100;
|
||||
display: flex;
|
||||
flex-flow: row nowrap;
|
||||
.left-content {
|
||||
width: 220px;
|
||||
margin-left: 16px;
|
||||
}
|
||||
.mid-content {
|
||||
flex: 1;
|
||||
padding-left: 100px;
|
||||
a {
|
||||
color: #4A4A4A;
|
||||
&:hover {
|
||||
color: #f38031;
|
||||
}
|
||||
}
|
||||
span {
|
||||
display: inline-block;
|
||||
vertical-align: middle;
|
||||
position: relative;
|
||||
line-height: 64px;
|
||||
width: 120px;
|
||||
text-align: center;
|
||||
&.k-active {
|
||||
a {
|
||||
color: #f38031;
|
||||
}
|
||||
&:after {
|
||||
width: 100%;
|
||||
content: '';
|
||||
height: 4px;
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
background: #f38031;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.right-content {
|
||||
margin-right: 24px;
|
||||
position: relative;
|
||||
.kafka-avatar-icon {
|
||||
font-size: 24px;
|
||||
position: absolute;
|
||||
top: 15px;
|
||||
left: -30px;
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
}
|
||||
.kafka-header-text {
|
||||
font-size: 14px;
|
||||
}
|
||||
}
|
||||
.left-content,
|
||||
.right-content {
|
||||
font-size: 0;
|
||||
& > span {
|
||||
display: inline-block;
|
||||
line-height: 64px;
|
||||
vertical-align: middle;
|
||||
}
|
||||
}
|
||||
|
||||
.kafka-header-icon {
|
||||
height: 45px;
|
||||
width: 45px;
|
||||
img {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
}
|
||||
.kafka-header-text {
|
||||
margin-left: 16px;
|
||||
font-size: 18px;
|
||||
font-weight: 500;
|
||||
font-family: PingFangSC-Medium;
|
||||
color: rgba(25,24,24,1);
|
||||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
.kafka-header-menu {
|
||||
width: 88px;
|
||||
background-color: #fff;
|
||||
position: absolute;
|
||||
top: -20px;
|
||||
box-shadow: 0px 0px 4px 0px rgba(217,217,217);
|
||||
border-radius: 4px;
|
||||
li {
|
||||
text-align: center;
|
||||
height: 32px;
|
||||
line-height: 32px;
|
||||
cursor: pointer;
|
||||
&:hover {
|
||||
background: rgba(236,111,38,0.1);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,56 +0,0 @@
|
||||
import * as React from 'react';
|
||||
|
||||
import './index.less';
|
||||
import { getCookie, deleteCookie } from 'lib/utils';
|
||||
import { userLogoff } from 'lib/api';
|
||||
import { notification, Dropdown } from 'component/antd';
|
||||
import { users } from 'store/users';
|
||||
import logoUrl from '../../assets/image/kafka-logo.png';
|
||||
import devIcon from '../../assets/image/devops.png';
|
||||
import adminIcon from '../../assets/image/admin.png';
|
||||
import userIcon from '../../assets/image/normal.png';
|
||||
|
||||
interface IHeader {
|
||||
active: string;
|
||||
}
|
||||
|
||||
export const Header = (props: IHeader) => {
|
||||
const { active } = props;
|
||||
const username = getCookie('username');
|
||||
const role = Number(getCookie('role'));
|
||||
|
||||
const logoff = () => {
|
||||
userLogoff(username).then(() => {
|
||||
notification.success({ message: '退出成功' });
|
||||
deleteCookie(['username', 'role']);
|
||||
location.reload();
|
||||
});
|
||||
};
|
||||
|
||||
const menu = (
|
||||
<ul className="kafka-header-menu">
|
||||
{role ? <li> <a href="/admin/user_manage">管理</a></li> : ''}
|
||||
<li onClick={logoff}>退出</li>
|
||||
</ul>
|
||||
);
|
||||
|
||||
return (
|
||||
<div className="kafka-header-container">
|
||||
<div className="left-content">
|
||||
<img className="kafka-header-icon" src={logoUrl} alt="" />
|
||||
<span className="kafka-header-text">Kafka Manager</span>
|
||||
</div>
|
||||
<div className="mid-content">
|
||||
<span className={active === 'user' ? 'k-active' : ''}><a href="/">集群监控</a></span>
|
||||
{role ? <span className={active === 'admin' ? 'k-active' : ''}><a href="/admin">集群管控</a></span> : ''}
|
||||
</div>
|
||||
<div className="right-content">
|
||||
<img className="kafka-avatar-icon" src={role === 2? adminIcon : role === 1 ? devIcon: userIcon } alt="" />
|
||||
<Dropdown overlay={menu}>
|
||||
<span className="kafka-header-text">
|
||||
{users.mapRole(role)} : {username}</span>
|
||||
</Dropdown>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
@@ -1,79 +0,0 @@
|
||||
export const userMenu = [{
|
||||
href: '/',
|
||||
i: 'k-icon-iconfontzhizuobiaozhun023110',
|
||||
title: 'Topic列表',
|
||||
}, {
|
||||
href: '/user/my_order',
|
||||
i: 'k-icon-order1',
|
||||
title: '工单列表',
|
||||
}, {
|
||||
href: '/user/alarm',
|
||||
i: 'k-icon-gaojing',
|
||||
title: '告警配置',
|
||||
}, {
|
||||
href: '/user/modify_user',
|
||||
i: 'k-icon-yonghuguanli',
|
||||
title: '密码修改',
|
||||
}];
|
||||
|
||||
export const adminMenu = [{
|
||||
href: '/admin',
|
||||
i: 'k-icon-jiqun',
|
||||
title: '集群列表',
|
||||
}, {
|
||||
href: '/admin/order',
|
||||
i: 'k-icon-order1',
|
||||
title: '资源审批',
|
||||
},
|
||||
// }, {
|
||||
// href: '/admin/task',
|
||||
// i: 'k-icon-renwuliebiao',
|
||||
// title: '任务列表',
|
||||
// }, {
|
||||
// {
|
||||
// href: '/admin/alarm',
|
||||
// i: 'k-icon-gaojing',
|
||||
// title: '告警配置',
|
||||
// }, {
|
||||
{
|
||||
href: '/admin/user_manage',
|
||||
i: 'k-icon-yonghuguanli',
|
||||
title: '用户管理',
|
||||
},
|
||||
// }, {
|
||||
// href: '/admin/auto_approval',
|
||||
// i: 'k-icon-shenpi1',
|
||||
// title: '自动审批管理',
|
||||
// }, {
|
||||
{
|
||||
href: '/admin/operation',
|
||||
i: 'k-icon-xiaofeikecheng',
|
||||
title: '任务管理',
|
||||
// }, {
|
||||
// href: '/admin/modify_user',
|
||||
// i: 'k-icon-jiaoseshouquan',
|
||||
// title: '密码修改',
|
||||
}];
|
||||
|
||||
export interface IMenuItem {
|
||||
href: string;
|
||||
i: string;
|
||||
title: string;
|
||||
}
|
||||
|
||||
export const userMap = new Map<string, IMenuItem>();
|
||||
userMenu.forEach(m => {
|
||||
userMap.set(m.href, m);
|
||||
});
|
||||
|
||||
export const adminMap = new Map<string, IMenuItem>();
|
||||
adminMenu.forEach(m => {
|
||||
adminMap.set(m.href, m);
|
||||
});
|
||||
|
||||
export const getActiveMenu = (mode: 'admin' | 'user', href: string) => {
|
||||
const map = mode === 'admin' ? adminMap : userMap;
|
||||
const defaultMenu = mode === 'admin' ? '/admin' : '/';
|
||||
const menuItem = map.get(href);
|
||||
return menuItem && menuItem.href || defaultMenu;
|
||||
};
|
||||
@@ -1,57 +0,0 @@
|
||||
import * as React from 'react';
|
||||
|
||||
import './index.less';
|
||||
import { Tooltip, Icon } from 'component/antd';
|
||||
import { adminMenu, userMenu } from './constant';
|
||||
import { BrowserRouter as Router, NavLink } from 'react-router-dom';
|
||||
|
||||
interface ILeftMenuProps {
|
||||
page: string;
|
||||
mode?: 'admin' | 'user';
|
||||
}
|
||||
|
||||
export class LeftMenu extends React.Component<ILeftMenuProps> {
|
||||
public state = {
|
||||
status: 'k-open',
|
||||
};
|
||||
|
||||
public open = () => {
|
||||
const { status } = this.state;
|
||||
const newStatus = !status ? 'k-open' : '';
|
||||
this.setState({
|
||||
status: newStatus,
|
||||
});
|
||||
}
|
||||
|
||||
public render() {
|
||||
const { status } = this.state;
|
||||
const { page, mode } = this.props;
|
||||
const menu = mode === 'admin' ? adminMenu : userMenu;
|
||||
return (
|
||||
<div className={`left-menu ${status}`}>
|
||||
<ul>
|
||||
{
|
||||
menu.map((m, i) => {
|
||||
const cnt = (
|
||||
<li key={m.i}>
|
||||
<NavLink exact={true} to={m.href} activeClassName="active">
|
||||
<i className={m.i} />
|
||||
{status ? <span>{m.title}</span> : null}
|
||||
</NavLink>
|
||||
</li>
|
||||
);
|
||||
|
||||
if (!status) {
|
||||
return <Tooltip placement="right" title={m.title} key={m.i} >{cnt}</Tooltip>;
|
||||
}
|
||||
return cnt;
|
||||
})
|
||||
}
|
||||
</ul>
|
||||
<div className="k-float-op" onClick={this.open}>
|
||||
<Icon type={status ? 'double-left' : 'double-right'} />
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -1,141 +0,0 @@
|
||||
import * as React from 'react';
|
||||
import { Modal, Form, Row, Input, Select, notification } from 'component/antd';
|
||||
import { modal } from 'store/modal';
|
||||
import { cluster } from 'store/cluster';
|
||||
import { operation } from 'store/operation';
|
||||
import { topic, IAdminExpand } from 'store/topic';
|
||||
import { observer } from 'mobx-react';
|
||||
import { broker } from 'store/broker';
|
||||
import { topicDilatation } from 'lib/api';
|
||||
import urlQuery from 'store/url-query';
|
||||
import { IValueLabel } from 'types/base-type';
|
||||
|
||||
const topicFormItemLayout = {
|
||||
labelCol: {
|
||||
span: 7,
|
||||
},
|
||||
wrapperCol: {
|
||||
span: 11,
|
||||
},
|
||||
};
|
||||
@observer
|
||||
class Topic extends React.Component<any> {
|
||||
|
||||
public handleSubmit = () => {
|
||||
this.props.form.validateFields((err: Error, values: any) => {
|
||||
if (err) return;
|
||||
values.partitionNum = +values.partitionNum;
|
||||
topicDilatation(values).then(() => {
|
||||
topic.getAdminTopics(urlQuery.clusterId);
|
||||
notification.success({ message: '扩容成功' });
|
||||
modal.close();
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
public componentDidMount() {
|
||||
const { clusterId, topicName } = modal.topicDetail;
|
||||
operation.initRegionOptions(clusterId);
|
||||
broker.initBrokerOptions(clusterId);
|
||||
cluster.getClusters();
|
||||
topic.getTopicMetaData(clusterId, topicName);
|
||||
}
|
||||
|
||||
public render() {
|
||||
const { getFieldDecorator } = this.props.form;
|
||||
const initialData = topic.topicDetail || {} as IAdminExpand;
|
||||
return (
|
||||
<Modal
|
||||
title="扩分区"
|
||||
style={{ top: 70 }}
|
||||
visible={true}
|
||||
onCancel={modal.close}
|
||||
maskClosable={false}
|
||||
width="680px"
|
||||
destroyOnClose={true}
|
||||
okText="确定"
|
||||
cancelText="取消"
|
||||
onOk={this.handleSubmit}
|
||||
>
|
||||
<Form {...topicFormItemLayout}>
|
||||
<Row>
|
||||
<Form.Item label="集群名称">
|
||||
{getFieldDecorator('clusterId', {
|
||||
rules: [{ required: true, message: '请选择集群' }],
|
||||
initialValue: +initialData.clusterId || +cluster.data[1].clusterId,
|
||||
})(
|
||||
<Select disabled={true}>
|
||||
{
|
||||
cluster.data.slice(1).map(c => {
|
||||
return <Select.Option value={c.clusterId} key={c.clusterId}>{c.clusterName}</Select.Option>;
|
||||
})
|
||||
}
|
||||
</Select>,
|
||||
)}
|
||||
</Form.Item>
|
||||
</Row>
|
||||
<Row>
|
||||
<Form.Item label="Topic名称">
|
||||
{getFieldDecorator('topicName', {
|
||||
rules: [{ required: true, message: '请选择Topic' }],
|
||||
initialValue: initialData.topicName,
|
||||
})(
|
||||
<Input disabled={true} />,
|
||||
)}
|
||||
</Form.Item>
|
||||
</Row>
|
||||
<Form.Item label="所处Broker列表">
|
||||
<Input value={initialData.brokerIdList && initialData.brokerIdList.join(',')} disabled={true} />
|
||||
</Form.Item>
|
||||
<Form.Item
|
||||
label="已有分区数"
|
||||
>
|
||||
<Input value={initialData.partitionNum} disabled={true} />
|
||||
</Form.Item>
|
||||
<Form.Item
|
||||
label="副本数"
|
||||
>
|
||||
<Input value={initialData.replicaNum} disabled={true} />
|
||||
</Form.Item>
|
||||
<Form.Item
|
||||
label="新扩Broker列表"
|
||||
>
|
||||
{getFieldDecorator('brokerIdList', {
|
||||
initialValue: initialData.brokerIdList || [],
|
||||
rules: [{
|
||||
required: true,
|
||||
validator: (_: any, value: string, callback: (wrong?: string) => void) => {
|
||||
if (initialData.replicaNum > value.length) {
|
||||
callback('Broker数需要大于或等于副本数');
|
||||
}
|
||||
callback();
|
||||
},
|
||||
}],
|
||||
})(
|
||||
<Select mode="multiple" optionLabelProp="title" placeholder="请选择broker">
|
||||
{
|
||||
broker.BrokerOptions.map((t: IValueLabel) => {
|
||||
return <Select.Option value={t.value} title={t.value + ''} key={t.value} >
|
||||
<span aria-label={t.value}> {t.label} </span>
|
||||
</Select.Option>;
|
||||
})
|
||||
}
|
||||
</Select>,
|
||||
)}
|
||||
</Form.Item>
|
||||
<Form.Item
|
||||
label="新增分区数"
|
||||
>
|
||||
{getFieldDecorator('partitionNum', {
|
||||
rules: [{ required: true, message: '请输入新增分区数' }],
|
||||
})(
|
||||
<Input placeholder="请输入新增分区数" />,
|
||||
)}
|
||||
</Form.Item>
|
||||
</Form>
|
||||
</Modal>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default Form.create({ name: 'topic' })(Topic);
|
||||
@@ -1,303 +0,0 @@
|
||||
import * as React from 'react';
|
||||
import { Modal, Form, Row, Input, Select, notification, Col, Radio } from 'component/antd';
|
||||
import { modal } from 'store/modal';
|
||||
import { alarm } from 'store/alarm';
|
||||
import { observer } from 'mobx-react';
|
||||
import { cluster } from 'store/cluster';
|
||||
import { addAlarm, modifyAlarm } from 'lib/api';
|
||||
import { topic } from 'store/topic';
|
||||
import { broker } from 'store/broker';
|
||||
import { getRandomPassword, getCookie } from 'lib/utils';
|
||||
import { IAlarmBase } from 'types/base-type';
|
||||
|
||||
const Option = Select.Option;
|
||||
|
||||
const topicFormItemLayout = {
|
||||
labelCol: {
|
||||
span: 6,
|
||||
},
|
||||
wrapperCol: {
|
||||
span: 14,
|
||||
},
|
||||
};
|
||||
|
||||
@observer
|
||||
class Alarm extends React.Component<any> {
|
||||
public data: any = null;
|
||||
public state = {
|
||||
loading: false,
|
||||
type: 'Lag',
|
||||
};
|
||||
|
||||
public handleSubmit = () => {
|
||||
this.props.form.validateFields((err: Error, values: any) => {
|
||||
if (err) return;
|
||||
this.setState({ loading: true });
|
||||
const { metric, opt, threshold, duration, alarmName, principalList: principal, actionTag, status } = values;
|
||||
const principalList = typeof (principal) === 'object' ? principal : principal.split(',');
|
||||
const strategyActionList = [{ actionTag, actionWay: 'KAFKA' }];
|
||||
const strategyFilterList = Array.from(['topicName', 'consumerGroup', 'brokerId', 'clusterId'], (item) => {
|
||||
if ((this.state.type === 'Lag' || !+getCookie('role')) && item === 'brokerId') return;
|
||||
if (this.state.type !== 'Lag' && item === 'consumerGroup' || JSON.stringify(values[item]) === '[]') return;
|
||||
return {
|
||||
key: item,
|
||||
value: values[item],
|
||||
};
|
||||
}).filter(i => i);
|
||||
const params: IAlarmBase = {
|
||||
status, strategyActionList, strategyFilterList, alarmName, principalList,
|
||||
strategyExpressionList: [{ metric, opt, threshold: +threshold, duration: +duration }],
|
||||
};
|
||||
const notiMessage = alarm.curData ? { message: '修改成功' } : { message: '添加告警成功' };
|
||||
const fn = alarm.curData ? modifyAlarm : addAlarm;
|
||||
fn(alarm.curData ? Object.assign({ id: alarm.curData.id }, params) : params).then(() => {
|
||||
notification.success(notiMessage);
|
||||
alarm.getAlarm();
|
||||
modal.close();
|
||||
}, (err) => {
|
||||
this.setState({ loading: false });
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
public initSelection = (value: number) => {
|
||||
topic.getTopicList(value);
|
||||
broker.initBrokerOptions(value);
|
||||
}
|
||||
|
||||
public componentDidMount = () => {
|
||||
cluster.getClusters();
|
||||
if (this.isModify()) {
|
||||
this.setState({ type: alarm.curData.strategyExpressionList[0].metric }, () => {
|
||||
this.data = this.getFilterList();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
public onChange = (type: any) => {
|
||||
this.setState({ type });
|
||||
}
|
||||
|
||||
public filterSelection = (input: string, option: any) => {
|
||||
return option.props.children.toLowerCase().indexOf(input.toLowerCase()) >= 0;
|
||||
}
|
||||
|
||||
public getFilterList = () => {
|
||||
const filterList = new Map();
|
||||
alarm.curData.strategyFilterList.forEach(item => {
|
||||
filterList.set(item.key, item.value);
|
||||
});
|
||||
this.initSelection(+filterList.get('clusterId'));
|
||||
return filterList;
|
||||
}
|
||||
|
||||
public getActionTag = () => {
|
||||
this.props.form.setFieldsValue({
|
||||
actionTag: 'KAFKA_' + getRandomPassword(),
|
||||
});
|
||||
}
|
||||
|
||||
public isModify = () => !!alarm.curData;
|
||||
|
||||
public render() {
|
||||
const { getFieldDecorator } = this.props.form;
|
||||
const { loading, type } = this.state;
|
||||
const isModify = this.isModify();
|
||||
const initialData = alarm.curData;
|
||||
const { data } = this;
|
||||
const role = +getCookie('role');
|
||||
return (
|
||||
<Modal
|
||||
title="告警配置"
|
||||
style={{ top: 30 }}
|
||||
visible={true}
|
||||
onCancel={modal.close}
|
||||
maskClosable={false}
|
||||
width={700}
|
||||
destroyOnClose={true}
|
||||
okText="确定"
|
||||
cancelText="取消"
|
||||
onOk={this.handleSubmit}
|
||||
confirmLoading={loading}
|
||||
>
|
||||
<Form {...topicFormItemLayout} >
|
||||
<Form.Item label="告警名称">
|
||||
{getFieldDecorator('alarmName', {
|
||||
rules: [{ required: true, message: '告警规则名称' }],
|
||||
initialValue: isModify ? initialData.alarmName : '',
|
||||
})(
|
||||
<Input placeholder="请输入告警配置名称" />,
|
||||
)}
|
||||
</Form.Item>
|
||||
<Form.Item label="负责人">
|
||||
{getFieldDecorator('principalList', {
|
||||
rules: [{ required: true, message: '请输入负责人' }],
|
||||
initialValue: isModify ? initialData.principalList : getCookie('username'),
|
||||
})(
|
||||
<Input placeholder="多个负责人请用逗号隔开" />,
|
||||
)}
|
||||
</Form.Item>
|
||||
<Row>
|
||||
<Col span={6}>
|
||||
<p style={{ textAlign: 'right', color: 'rgba(0,0,0,.85)', paddingTop: '8px' }}>告警规则: </p>
|
||||
</Col>
|
||||
<Col span={14} className="ruleArea">
|
||||
<Row>
|
||||
<Col span={12}>
|
||||
<Form.Item wrapperCol={{ span: 22 }}>
|
||||
{getFieldDecorator('metric', {
|
||||
rules: [{ required: true, message: '请选择 Metric' }],
|
||||
initialValue: isModify ? initialData.strategyExpressionList[0].metric : '',
|
||||
})(
|
||||
<Select placeholder="请选择 Metric" onChange={this.onChange}>
|
||||
{
|
||||
alarm.alarmConstant.metricTypeList.map((ele, index) => {
|
||||
return <Option key={index} value={Object.keys(ele)[0]}> {Object.keys(ele)[0]}</Option>;
|
||||
})
|
||||
}
|
||||
</Select>,
|
||||
)}
|
||||
</Form.Item>
|
||||
</Col>
|
||||
<Col span={12}>
|
||||
<Form.Item wrapperCol={{ span: 22 }}>
|
||||
{getFieldDecorator('opt', {
|
||||
rules: [{ required: true, message: '请选择 Condition' }],
|
||||
initialValue: isModify ? initialData.strategyExpressionList[0].opt : '',
|
||||
})(
|
||||
<Select placeholder="请选择 Condition">
|
||||
{
|
||||
alarm.alarmConstant.conditionTypeList.map((ele, index) => {
|
||||
return <Option key={index} value={Object.keys(ele)[0]}> {Object.keys(ele)[0]} </Option>;
|
||||
})
|
||||
}
|
||||
</Select>,
|
||||
)}
|
||||
</Form.Item>
|
||||
</Col>
|
||||
</Row>
|
||||
<Row>
|
||||
<Col span={12}>
|
||||
<Form.Item wrapperCol={{ span: 22 }}>
|
||||
{getFieldDecorator('threshold', {
|
||||
rules: [{ required: true, message: '请输入 value' }],
|
||||
initialValue: isModify ? initialData.strategyExpressionList[0].threshold : '',
|
||||
})(
|
||||
<Input addonBefore="metricValue" />,
|
||||
)}
|
||||
</Form.Item>
|
||||
</Col>
|
||||
<Col span={12}>
|
||||
<Form.Item wrapperCol={{ span: 22 }}>
|
||||
{getFieldDecorator('duration', {
|
||||
rules: [{ required: true, message: '请输入持续时间' }],
|
||||
initialValue: isModify ? initialData.strategyExpressionList[0].duration : '',
|
||||
})(
|
||||
<Input addonBefore="duration" />,
|
||||
)}
|
||||
</Form.Item>
|
||||
</Col>
|
||||
</Row>
|
||||
</Col>
|
||||
</Row>
|
||||
<Row>
|
||||
<Col span={6}>
|
||||
<p style={{ textAlign: 'right', color: 'rgba(0,0,0,.85)', paddingTop: '8px' }}>过滤规则: </p>
|
||||
</Col>
|
||||
<Col span={14} className="ruleArea">
|
||||
<span className="label">集群名称</span>
|
||||
<Form.Item wrapperCol={{ span: 25 }} className="t-input">
|
||||
{getFieldDecorator('clusterId', {
|
||||
rules: [{ required: true, message: '请选择集群' }],
|
||||
initialValue: data && +data.get('clusterId') || '',
|
||||
})(
|
||||
<Select onChange={this.initSelection} placeholder="请选择集群" >
|
||||
{
|
||||
cluster.data.slice(1).map(c => {
|
||||
return <Select.Option value={c.clusterId} key={c.clusterId}>{c.clusterName}</Select.Option>;
|
||||
})
|
||||
}
|
||||
</Select>,
|
||||
)}
|
||||
</Form.Item>
|
||||
<Row>
|
||||
<span className="label">Topic名称</span>
|
||||
<Form.Item wrapperCol={{ span: 25 }} className="t-input">
|
||||
{getFieldDecorator('topicName', {
|
||||
rules: [{ required: type === 'Lag' || !role, message: '请选择Topic' }],
|
||||
initialValue: data && data.get('topicName') || '',
|
||||
})(
|
||||
<Select
|
||||
placeholder="请选择Topic"
|
||||
allowClear={true}
|
||||
filterOption={this.filterSelection}
|
||||
showSearch={true}
|
||||
>
|
||||
{
|
||||
topic.topicNameList.map(t => {
|
||||
return <Select.Option value={t} key={t}>{t}</Select.Option>;
|
||||
})
|
||||
}
|
||||
</Select>,
|
||||
)}
|
||||
</Form.Item>
|
||||
</Row>
|
||||
{type !== 'Lag' ? role ? (
|
||||
<Row>
|
||||
<span className="label">BrokeId</span>
|
||||
<Form.Item wrapperCol={{ span: 25 }} className="t-input">
|
||||
{getFieldDecorator('brokerId', {
|
||||
initialValue: data && data.get('brokerId') || [],
|
||||
})(
|
||||
<Select optionLabelProp="title" placeholder="请选择Broker" allowClear={true}>
|
||||
{
|
||||
broker.BrokerOptions.map(t => {
|
||||
return <Select.Option value={t.value} title={t.value + ''} key={t.value} >
|
||||
<span aria-label={t.value}> {t.label} </span>
|
||||
</Select.Option>;
|
||||
})
|
||||
}
|
||||
</Select>,
|
||||
)}
|
||||
</Form.Item>
|
||||
</Row>
|
||||
) : null : (
|
||||
<>
|
||||
<span className="label">消费组</span>
|
||||
<Form.Item wrapperCol={{ span: 25 }} className="t-input">
|
||||
{getFieldDecorator('consumerGroup', {
|
||||
rules: [{ required: type === 'Lag', message: '请输入消费组' }],
|
||||
initialValue: data && data.get('consumerGroup') || '',
|
||||
})(
|
||||
<Input placeholder="请输入消费组" />,
|
||||
)}
|
||||
</Form.Item>
|
||||
</>
|
||||
)}
|
||||
</Col>
|
||||
</Row>
|
||||
<Form.Item label="TagName">
|
||||
{getFieldDecorator('actionTag', {
|
||||
rules: [{ required: true, message: '请输入tag' }],
|
||||
initialValue: isModify ? initialData.strategyActionList[0].actionTag : '',
|
||||
})(
|
||||
<Input placeholder="请输入tag" addonAfter={<span style={{ cursor: 'pointer' }} onClick={this.getActionTag}>自动生成</span>} />,
|
||||
)}
|
||||
</Form.Item>
|
||||
<Form.Item label="开启告警">
|
||||
{getFieldDecorator('status', {
|
||||
initialValue: isModify ? initialData.status : 1,
|
||||
})(
|
||||
<Radio.Group>
|
||||
<Radio value={1}>是</Radio>
|
||||
<Radio value={0}>否</Radio>
|
||||
</Radio.Group>,
|
||||
)}
|
||||
</Form.Item>
|
||||
</Form>
|
||||
</Modal >
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default Form.create({ name: 'alarm' })(Alarm);
|
||||
@@ -1,24 +0,0 @@
|
||||
import * as React from 'react';
|
||||
import { Modal } from 'component/antd';
|
||||
import { modal } from 'store/modal';
|
||||
import { NetWorkFlow } from 'container/topic-detail/com';
|
||||
|
||||
export class ClusterDetail extends React.Component<any> {
|
||||
public render() {
|
||||
return (
|
||||
<Modal
|
||||
title="集群流量"
|
||||
style={{ top: 70 }}
|
||||
visible={true}
|
||||
onCancel={modal.close}
|
||||
maskClosable={false}
|
||||
width={1000}
|
||||
destroyOnClose={true}
|
||||
>
|
||||
<div className="k-row">
|
||||
<NetWorkFlow clusterId={modal.currentCluster.clusterId} />
|
||||
</div>
|
||||
</Modal>
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -1,173 +0,0 @@
|
||||
import * as React from 'react';
|
||||
import { Modal, Form, Row, Input, Select, Radio, message } from 'component/antd';
|
||||
import { modal } from 'store/modal';
|
||||
import { cluster } from 'store/cluster';
|
||||
import { INewCluster } from 'types/base-type';
|
||||
import { newCluster, modifyCluster } from 'lib/api';
|
||||
|
||||
const Option = Select.Option;
|
||||
|
||||
const topicFormItemLayout = {
|
||||
labelCol: {
|
||||
span: 8,
|
||||
},
|
||||
wrapperCol: {
|
||||
span: 12,
|
||||
},
|
||||
};
|
||||
|
||||
class Cluster extends React.Component<any> {
|
||||
public handleSubmit = (e: React.MouseEvent<any, MouseEvent>) => {
|
||||
e.preventDefault();
|
||||
const { clusterId } = modal.currentCluster;
|
||||
this.props.form.validateFieldsAndScroll((err: any, values: INewCluster) => {
|
||||
if (err) return;
|
||||
const commonFn = (fn: any) => {
|
||||
fn.then(() => {
|
||||
message.success(this.getTips());
|
||||
modal.close();
|
||||
cluster.getClusters();
|
||||
});
|
||||
};
|
||||
clusterId ?
|
||||
commonFn(modifyCluster(Object.assign(values, {clusterId}))) : commonFn(newCluster(values));
|
||||
});
|
||||
}
|
||||
|
||||
public getTips() {
|
||||
if (modal.currentCluster.clusterId) return '修改成功';
|
||||
return '添加成功';
|
||||
}
|
||||
|
||||
public getTitle() {
|
||||
if (modal.currentCluster.clusterId) return '修改集群';
|
||||
return '添加集群';
|
||||
}
|
||||
|
||||
public render() {
|
||||
const { getFieldDecorator } = this.props.form;
|
||||
return (
|
||||
<Modal
|
||||
title={this.getTitle()}
|
||||
style={{ top: 70 }}
|
||||
visible={true}
|
||||
onCancel={modal.close}
|
||||
maskClosable={false}
|
||||
width={700}
|
||||
destroyOnClose={true}
|
||||
okText="确定"
|
||||
cancelText="取消"
|
||||
onOk={this.handleSubmit}
|
||||
>
|
||||
<Form {...topicFormItemLayout} >
|
||||
<Row>
|
||||
<Form.Item
|
||||
label="集群名称"
|
||||
>
|
||||
{getFieldDecorator('clusterName', {
|
||||
rules: [{ required: true, message: '请输入集群名称' }],
|
||||
initialValue: modal.currentCluster.clusterName,
|
||||
})(
|
||||
<Input
|
||||
placeholder="请输入集群名称"
|
||||
/>,
|
||||
)}
|
||||
</Form.Item>
|
||||
</Row>
|
||||
<Row>
|
||||
<Form.Item
|
||||
label="zookeeper地址"
|
||||
>
|
||||
{getFieldDecorator('zookeeper', {
|
||||
rules: [{ required: true, message: '请输入 zookeeper 地址' }],
|
||||
initialValue: modal.currentCluster.zookeeper,
|
||||
})(
|
||||
<Input.TextArea
|
||||
placeholder="请输入 zookeeper 地址"
|
||||
/>,
|
||||
)}
|
||||
</Form.Item>
|
||||
</Row>
|
||||
<Row>
|
||||
<Form.Item
|
||||
label="kafka版本"
|
||||
>
|
||||
{getFieldDecorator('kafkaVersion', {
|
||||
rules: [{ required: true, message: '请选择 kafka 版本' }],
|
||||
initialValue: modal.currentCluster.kafkaVersion,
|
||||
})(
|
||||
<Select placeholder="请选择 kafka 版本">
|
||||
{cluster.kafkaVersions.map((v) => {
|
||||
return <Option key={v} value={v}>{v}</Option>;
|
||||
})}
|
||||
</Select>,
|
||||
)}
|
||||
</Form.Item>
|
||||
</Row>
|
||||
<Row>
|
||||
<Form.Item
|
||||
label="集群访问地址"
|
||||
>
|
||||
{getFieldDecorator('bootstrapServers', {
|
||||
rules: [{ required: true, message: '请输入集群访问地址' }],
|
||||
initialValue: modal.currentCluster.bootstrapServers,
|
||||
})(
|
||||
<Input.TextArea placeholder="请输入集群访问地址" />,
|
||||
)}
|
||||
</Form.Item>
|
||||
</Row>
|
||||
<Row>
|
||||
<Form.Item
|
||||
label="SASL JAAS配置"
|
||||
>
|
||||
{getFieldDecorator('saslJaasConfig', {
|
||||
initialValue: modal.currentCluster.saslJaasConfig,
|
||||
})(
|
||||
<Input placeholder="请输入SASL JAAS配置" />,
|
||||
)}
|
||||
</Form.Item>
|
||||
</Row>
|
||||
<Row>
|
||||
<Form.Item
|
||||
label="SASL机制"
|
||||
>
|
||||
{getFieldDecorator('saslMechanism', {
|
||||
initialValue: modal.currentCluster.saslMechanism,
|
||||
})(
|
||||
<Input placeholder="请输入SASL机制" />,
|
||||
)}
|
||||
</Form.Item>
|
||||
</Row>
|
||||
<Row>
|
||||
<Form.Item
|
||||
label="安全协议"
|
||||
>
|
||||
{getFieldDecorator('securityProtocol', {
|
||||
initialValue: modal.currentCluster.securityProtocol,
|
||||
})(
|
||||
<Input placeholder="请输入安全协议" />,
|
||||
)}
|
||||
</Form.Item>
|
||||
</Row>
|
||||
<Row>
|
||||
<Form.Item
|
||||
label="是否开启告警"
|
||||
>
|
||||
{getFieldDecorator('alarmFlag', {
|
||||
rules: [{ required: true, message: '请选择是否开启告警' }],
|
||||
initialValue: modal.currentCluster.alarmFlag === undefined ? 1 : modal.currentCluster.alarmFlag,
|
||||
})(
|
||||
<Radio.Group>
|
||||
<Radio value={1}>是</Radio>
|
||||
<Radio value={0}>否</Radio>
|
||||
</Radio.Group>,
|
||||
)}
|
||||
</Form.Item>
|
||||
</Row>
|
||||
</Form>
|
||||
</Modal>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default Form.create({ name: 'cluster' })(Cluster);
|
||||
@@ -1,42 +0,0 @@
|
||||
import * as React from 'react';
|
||||
import { modal } from 'store/modal';
|
||||
import { consume } from 'store/consume';
|
||||
import Modal from 'antd/es/modal';
|
||||
import { observer } from 'mobx-react';
|
||||
import Table from 'antd/es/table';
|
||||
|
||||
const columns = [
|
||||
{
|
||||
title: 'Topic 列表',
|
||||
dataIndex: 'topicName',
|
||||
key: 'topicName',
|
||||
},
|
||||
];
|
||||
|
||||
@observer
|
||||
export default class ConsumerTopic extends React.Component {
|
||||
public componentDidMount() {
|
||||
const { clusterId, consumerGroup, location } = modal.consumberGroup;
|
||||
consume.getConsumerTopic(clusterId, consumerGroup, location.toLowerCase());
|
||||
}
|
||||
public render() {
|
||||
return (
|
||||
<Modal
|
||||
title="消费的Topic列表"
|
||||
style={{ top: 200 }}
|
||||
visible={true}
|
||||
onCancel={modal.close}
|
||||
maskClosable={false}
|
||||
width={500}
|
||||
footer={null}
|
||||
>
|
||||
<Table
|
||||
rowKey="topicName"
|
||||
columns={columns}
|
||||
pagination={false}
|
||||
dataSource={consume.consumerTopic}
|
||||
/>
|
||||
</Modal>
|
||||
);
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user