Compare commits

...

547 Commits

Author SHA1 Message Date
EricZeng
67ad5cacb7 Merge pull request #453 from didi/dev
1.设置版本为2.6.0; 2.补充v2.6.0的release notes
2022-01-24 13:32:13 +08:00
zengqiao
b4a739476a 补充v2.6.0的release notes 2022-01-24 13:30:48 +08:00
zengqiao
a7bf2085db 设置版本为2.6.0 2022-01-24 13:30:05 +08:00
zengqiao
c3802cf48b 去除@project.version@说明 2022-01-24 13:27:10 +08:00
EricZeng
54711c4491 Merge pull request #452 from didi/dev
允许配置文件中不进行配置
2022-01-24 13:22:48 +08:00
zengqiao
fcb52a69c0 允许配置文件中不进行配置 2022-01-24 13:16:30 +08:00
zengqiao
1b632f9754 调整文章顺序 2022-01-22 13:24:07 +08:00
EricZeng
73d7a0ecdc Merge pull request #450 from didi/dev
调整Task模块日志及Api请求统计日志的输出
2022-01-21 19:25:01 +08:00
EricZeng
08943593b3 Merge pull request #449 from kingdomrushing/dev_v2.6.0
增加对定时任务的说明
2022-01-21 15:27:17 +08:00
xuguang
c949a88f20 周期任务说明文档内容补充 2022-01-21 13:59:46 +08:00
xuguang
a49c11f655 统一定时任务cron格式 2022-01-21 13:14:31 +08:00
xuguang
a66aed4a88 增加对定时任务的注释和说明文档 2022-01-21 13:12:58 +08:00
xuguang
0045c953a0 Merge branch 'dev' of github.com:kingdomrushing/LogiKM into dev_v2.6.0 2022-01-21 10:59:38 +08:00
xuguang
fdce41b451 增加对定时任务的说明 2022-01-21 10:50:29 +08:00
EricZeng
053d4dcb18 Merge pull request #447 from didi/dev
补充KCM使用文档
2022-01-20 14:29:18 +08:00
zengqiao
e1b2c442aa 调整Task模块日志及Api请求统计日志的输出 2022-01-20 14:28:39 +08:00
zengqiao
0ed8ba8ca4 补充KCM使用文档 2022-01-20 11:47:55 +08:00
EricZeng
7d9ec05062 Merge pull request #445 from didi/dev
优化corn表达式解析失败后退出无任何日志提示问题
2022-01-20 10:22:16 +08:00
zengqiao
4f3c1ad9b6 优化corn表达式解析失败后退出无任何日志提示问题 2022-01-19 20:23:18 +08:00
EricZeng
6d45ed586c Merge pull request #444 from didi/dev
1. 完善搜索用户时可以显示用户的其他元信息(完善chineseName和department); 2. 升级至v2.6.0说明
2022-01-19 15:25:11 +08:00
zengqiao
3b0c208eff 补充v2.6.0升级说明及修复新增account提示mysql错误问题 2022-01-18 15:48:05 +08:00
EricZeng
05022f8db4 Merge pull request #442 from Huyueeer/devLookUserName
LDAP忽略大小写 & 认证携带必要元信息(姓名、部门、邮箱)
2022-01-18 15:26:32 +08:00
EricZeng
3336de457a Merge pull request #441 from didi/dev
bump springboot version to 2.1.18 and ignore springframework version …
2022-01-18 14:42:18 +08:00
EricZeng
10a27bc29c Merge pull request #443 from lucasun/master
V2.6.0 FE
2022-01-18 14:24:17 +08:00
Hu.Yue
542e5d3c2d Merge branch 'didi-dev' into devLookUserName 2022-01-18 14:09:05 +08:00
lucasun
7372617b14 Merge branch 'didi:master' into master 2022-01-18 14:07:44 +08:00
Hu.Yue
89735a130b Merge branch 'dev' of https://github.com/didi/LogiKM into didi-dev 2022-01-18 14:07:34 +08:00
孙超
859cf74bd6 2.6.0问题修复 2022-01-18 14:05:32 +08:00
zengqiao
e2744ab399 bump version to 2.6.0 2022-01-18 14:00:20 +08:00
Hu.Yue
16bd065098 Merge branch 'dev' of https://github.com/didi/LogiKM into didi-dev 2022-01-18 13:58:16 +08:00
zengqiao
71c52e6dd7 bump springboot version to 2.1.18 and ignore springframework version config 2022-01-17 21:18:06 +08:00
EricZeng
a7f8c3ced3 Merge pull request #440 from didi/dev
1.安装部署脚本LogiKM可配置; 2.增加网关接口及第三方接口可直接调用的开关;
2022-01-17 21:08:55 +08:00
zengqiao
f3f0432c65 1.安装部署脚本LogiKM可配置; 2.增加网关接口及第三方接口可直接调用的开关; 2022-01-17 20:41:53 +08:00
EricZeng
426ba2d150 Merge pull request #439 from didi/dev
1、修复swagger抛出的NumberFormatException问题; 2、Swagger提示版本和POM中版本通过配置保持一致; 3、梳理Task模块任务-BrokerMetrics任务梳理;
2022-01-17 20:39:10 +08:00
zengqiao
2790099efa 梳理Task模块任务-BrokerMetrics任务梳理 2022-01-17 15:28:36 +08:00
zengqiao
f6ba8bc95e Swagger提示版本和POM中版本通过配置保持一致 2022-01-17 13:17:07 +08:00
zengqiao
d6181522c0 修复swagger抛出的NumberFormatException问题 2022-01-17 11:42:30 +08:00
EricZeng
04cf071ca6 Merge pull request #437 from didi/dev
增加简单回退工具类,增加Jmx连接失败回退功能机制,优化Jmx连接失败日志
2022-01-15 13:56:44 +08:00
zengqiao
e4371b5d02 修正注释 2022-01-14 14:28:45 +08:00
zengqiao
52c52b2a0d 增加简单回退工具类,增加Jmx连接失败回退功能机制,优化Jmx连接失败日志 2022-01-14 14:24:04 +08:00
EricZeng
8f40f10575 Merge pull request #436 from didi/dev
1. 增加对BrokerMetadata中endpoints为internal|External方式的解析; 2. 增加线程池、客户端池可配置; 3. fix config incorrectly comment
2022-01-13 16:28:34 +08:00
zengqiao
fe0f6fcd0b fix config incorrectly comment 2022-01-13 16:02:33 +08:00
EricZeng
31b1ad8bb4 Merge pull request #435 from kingdomrushing/dev_v2.6.0
增加线程池、客户端池可配置 & 增加对BrokerMetadata中endpoints为internal|External方式的解析
2022-01-13 15:51:54 +08:00
xuguang
373680d854 线程池 & BrokerMetadata 问题修复 2022-01-13 15:39:39 +08:00
xuguang
9e3bc80495 线程池 & BrokerMetadata 问题修复 2022-01-13 15:35:11 +08:00
xuguang
52ccaeffd5 解决依赖冲突 2022-01-13 11:48:43 +08:00
kingdomrushing
18136c12fd Merge branch 'didi:master' into dev_v2.6.0 2022-01-13 11:41:20 +08:00
EricZeng
dec3f9e75e Merge pull request #429 from didi/dev
ldap config add default value
2022-01-13 11:40:46 +08:00
EricZeng
ccc0ee4d18 Merge pull request #432 from didi/master
merge master to dev
2022-01-13 11:40:17 +08:00
kingdomrushing
69e9708080 Merge branch 'dev' into dev_v2.6.0 2022-01-13 11:39:50 +08:00
lucasun
5944ba099a Merge pull request #431 from lucasun/hotfix/2.5.0_fe
修复图片名称大小写问题
2022-01-13 11:17:25 +08:00
孙超
ada2718b5e 修复图片名称大小写问题 2022-01-13 11:13:26 +08:00
lucasun
1f87bd63e7 Merge pull request #416 from potaaaaaato/master
update echarts from v4 to v5
2022-01-13 10:55:34 +08:00
xuguang
c0f3259cf6 增加线程池、客户端池可配置 2022-01-12 19:56:37 +08:00
EricZeng
e1d5749a40 Merge pull request #428 from didi/dev
Dockerfile mv application.yml to fix start failed problem
2022-01-12 18:14:20 +08:00
zengqiao
a8d7eb27d9 ldap config add default value 2022-01-12 18:03:16 +08:00
zengqiao
1eecdf3829 Dockerfile mv application.yml to fix start failed problem 2022-01-12 17:45:40 +08:00
EricZeng
be8b345889 Merge pull request #427 from didi/dev
del unused jmx_prometheus_javaagent-0.14.0.jar
2022-01-12 17:40:48 +08:00
zengqiao
074da389b3 del unused jmx_prometheus_javaagent-0.14.0.jar 2022-01-12 17:32:13 +08:00
xuguang
4df2dc09fe 增加对BrokerMetadata中endpoints为internal|External方式的解析 2022-01-12 16:15:46 +08:00
EricZeng
e8d42ba074 Merge pull request #425 from didi/dev
1. optimize reeassign task-name; 2. ignore read kafka-controller data when znode not exist; 3.add region created event and handle it to cal region capacity immediately;
2022-01-12 11:44:22 +08:00
zengqiao
c036483680 add region created event and handle it to cal region capacity immediately 2022-01-11 17:49:17 +08:00
zengqiao
2818584db6 ignore read kafka-controller data when znode not exist 2022-01-11 17:19:14 +08:00
zengqiao
37585f760d optimize reeassign task-name 2022-01-11 16:57:24 +08:00
EricZeng
f5477a03a1 Merge pull request #364 from Huyueeer/devConfig
平台配置EXPIRED_TOPIC_CONFIG新增正则过滤Topic
2022-01-11 16:33:21 +08:00
EricZeng
50388425b2 Merge pull request #424 from didi/dev
1.add lombok; 2.support change delete metrics rate;
2022-01-11 16:29:43 +08:00
zengqiao
725c59eab0 support change delete metrics rate 2022-01-11 16:03:22 +08:00
zengqiao
7bf1de29a4 add lombok 2022-01-11 14:04:48 +08:00
EricZeng
d90c3fc7dd Merge pull request #423 from didi/dev
1. bump swagger version; 2. fix NPE when flush logical cluster and physical cluster not in cache or not exist; 3. JmxConnectorWrap's log add cluster and broker info;
2022-01-11 13:16:46 +08:00
zengqiao
80785ce072 JmxConnectorWrap's log add cluster and broker info 2022-01-11 11:45:28 +08:00
zengqiao
44ea896de8 fix NPE when flush logical cluster and physical cluster not in cache or not exist 2022-01-11 11:37:23 +08:00
zengqiao
d30cb8a0f0 bump swagger version 2022-01-11 11:24:43 +08:00
EricZeng
6c7b333b34 Merge pull request #422 from didi/dev
网关增加配置及修改配置时,version不变化问题修复
2022-01-10 10:26:49 +08:00
石臻臻的杂货铺
6d34a00e77 Update README.md 2022-01-08 15:02:07 +08:00
zengqiao
4e10f8d1c5 网关增加配置及修改配置时,version不变化问题修复 2022-01-07 15:35:14 +08:00
EricZeng
a22cd853fc Merge pull request #421 from didi/dev
修复批量往DB写入空指标数组时报SQL语法异常的问题
2022-01-07 14:16:07 +08:00
zengqiao
354e0d6a87 修复批量往DB写入空指标数组时报SQL语法异常的问题 2022-01-07 13:55:42 +08:00
EricZeng
dfabe28645 Merge pull request #420 from didi/master
合并主分支
2022-01-07 13:38:10 +08:00
EricZeng
fce230da48 Merge pull request #414 from didi/dev
设置Log4j 2的版本为2.16.0
2022-01-07 13:36:50 +08:00
EricZeng
6835e1e680 Merge pull request #419 from ZHAOYINRUI/patch-6
更新视频教程地址
2022-01-04 11:07:52 +08:00
ZHAOYINRUI
d8f89b8f67 更新视频教程地址 2022-01-04 11:06:51 +08:00
eilenexuzhe
ec28eba781 feat: move webpack-dev-server to scripts 2021-12-27 17:12:51 +08:00
eilenexuzhe
5ef8fff5bc feat: update echarts v4 to v5 2021-12-27 17:12:02 +08:00
Peng
10b0a3dabb Update README.md 2021-12-24 11:54:52 +08:00
zengqiao
a23907e009 开启前端包 2021-12-17 15:45:45 +08:00
zengqiao
dbeae4ca68 设置log4j2版本为2.16.0以修复相关漏洞 2021-12-17 11:44:50 +08:00
zengqiao
0fb0e94848 Merge branch 'master' into dev 2021-12-16 22:29:45 +08:00
石臻臻的杂货铺
95d2a82d35 Merge pull request #412 from didi/v2.5.0
升级到2.5版本
2021-12-16 18:34:30 +08:00
shirenchuang
5bc6eb6774 升级到2.5版本 2021-12-16 18:28:51 +08:00
石臻臻的杂货铺
3ba81e9aaa Merge pull request #411 from didi/v2.5.0
升级到2.5版本
2021-12-16 15:28:34 +08:00
shirenchuang
329a9b59c1 升级到2.5版本 2021-12-16 15:08:54 +08:00
EricZeng
22c26e24b1 Merge pull request #410 from lucasun/hotfix/2.5.0_fe
修复顶导V2.5.0版本
2021-12-11 14:30:22 +08:00
孙超
396045177c 修复顶导V2.5.0版本 2021-12-11 14:25:43 +08:00
EricZeng
820571d993 Merge pull request #408 from didi/master
merge master
2021-12-02 19:39:41 +08:00
EricZeng
e311d3767c Merge pull request #407 from didi/dev_v2.5.0
merge dev_v2.5.0 to master
2021-12-01 19:42:03 +08:00
EricZeng
24d7b80244 Merge pull request #406 from kingdomrushing/dev_v2.5.0
我的申请-审批中-审批时间置为空
2021-12-01 13:31:08 +08:00
xuguang
61f99e4d2e 我的申请-审批中-审批时间置为空 2021-12-01 12:54:02 +08:00
EricZeng
d5348bcf49 Merge pull request #405 from lucasun/dev_v2.5.0_fe
我的申请-审批列表列-申请时间、审批时间增加无数据判断
2021-12-01 11:27:58 +08:00
孙超
5d31d66365 我的申请-审批列表列-申请时间、审批时间增加无数据判断 2021-12-01 11:17:12 +08:00
EricZeng
29778a0154 Merge pull request #400 from lucasun/dev_v2.5.0_fe
Dev v2.5.0 fe
2021-11-30 15:01:49 +08:00
Peng
165c0a5866 Update README.md 2021-11-29 19:32:54 +08:00
EricZeng
588323961e Merge pull request #401 from didi/master
合并主分支到2.5开发分支
2021-11-23 18:50:27 +08:00
孙超
fd1c0b71c5 V2.5.0前端 更换二维码&前端bugfix 2021-11-23 17:48:10 +08:00
lucasun
54fbdcadf9 Merge branch 'didi:master' into master 2021-11-23 17:35:27 +08:00
石臻臻的杂货铺
69a30d0cf0 Merge pull request #399 from kingdomrushing/dev_v2.5.0
修复"新添加集群的时候,报watch的空指针异常"问题 & 修复"删除废弃Topic之后,Topic资源治理没有同步删除"问题
2021-11-22 17:35:36 +08:00
xuguang
b8f9b44f38 修复获取topic流量指标未按时间排序问题 2021-11-20 13:30:34 +08:00
xuguang
cbf17d4eb5 修复"新添加集群的时候,报watch的空指针异常"问题 & 修复"删除废弃Topic之后,Topic资源治理没有同步删除"问题 2021-11-19 19:27:19 +08:00
石臻臻的杂货铺
327e025262 Merge pull request #397 from kingdomrushing/dev_v2.5.0
Dev v2.5.0
2021-11-19 14:20:20 +08:00
xuguang
6b1e944bba 修复topic管理中topic编辑备注没有数据回显问题 2021-11-19 13:23:52 +08:00
EricZeng
668ed4d61b Merge pull request #396 from didi/dev_inc_monitor_indicators
补充新增上报监控系统指标说明文档
2021-11-16 22:32:20 +08:00
zengqiao
312c0584ed 补充新增上报监控系统指标说明文档 2021-11-16 22:20:35 +08:00
zengqiao
110d3acb58 补充新增上报监控系统指标说明文档 2021-11-16 22:16:35 +08:00
xuguang
ddbc60283b 将tomcat版本升级为8.5.72 & "我的审批"列表增加"通过时间"列,并支持按该列排序 & JMX连接关闭问题修复 2021-11-16 17:15:58 +08:00
shirenchuang
471bcecfd6 Merge branch 'v2.4.3' into dev_v2.5.0 2021-11-15 12:45:01 +08:00
shirenchuang
0245791b13 Merge remote-tracking branch 'origin/master' into dev_v2.5.0 2021-11-15 11:45:22 +08:00
shirenchuang
4794396ce8 Merge remote-tracking branch 'origin/master' into v2.4.3 2021-11-15 10:49:22 +08:00
EricZeng
c7088779d6 Merge pull request #395 from ZHAOYINRUI/patch-5
Update README.md
2021-11-11 15:21:11 +08:00
ZHAOYINRUI
672905da12 Update README.md 2021-11-11 15:19:29 +08:00
EricZeng
47172b13be Merge pull request #394 from ZHAOYINRUI/patch-4
Update README.md
2021-11-09 14:18:34 +08:00
ZHAOYINRUI
3668a10af6 Update README.md 2021-11-09 12:43:09 +08:00
EricZeng
a4e294c03f Merge pull request #393 from ZHAOYINRUI/patch-3
增加【Kafka中文社区】知识星球二维码
2021-11-08 17:44:15 +08:00
ZHAOYINRUI
3fd6f4003f 增加【Kafka中文社区】知识星球二维码 2021-11-08 17:39:08 +08:00
EricZeng
3eaf5cd530 Merge pull request #378 from didi/dev
白名单接口中仅保留登录接口
2021-09-21 11:09:36 +08:00
zengqiao
c344fd8ca4 白名单接口中仅保留登录接口 2021-09-21 11:00:33 +08:00
EricZeng
09639ca294 Merge pull request #377 from didi/dev
修复Sonar扫描问题
2021-09-21 10:58:36 +08:00
EricZeng
a81b6dca83 Merge pull request #376 from didi/master
merge master
2021-09-21 10:47:55 +08:00
mike.zhangliang
b74aefb08f Update README.md 2021-08-15 15:14:25 +08:00
huyueeer
fffc0c3add 完善搜索用户时可以显示用户的其他元信息(完善chineseName和department) 2021-08-12 15:28:23 +08:00
mike.zhangliang
757f90aa7a Update README.md 2021-08-11 09:08:33 +08:00
huyueeer
022f9eb551 更新EXPIRED_TOPIC_CONFIG文档描述 2021-08-06 16:00:16 +08:00
huyueeer
6e7b82cfcb 平台配置EXPIRED_TOPIC_CONFIG新增正则过滤Topic 2021-08-06 14:52:22 +08:00
huyueeer
b5fb24b360 本地认证或LDAP认证支持携带‘姓名’、‘部门’、‘邮箱’等用户元信息 2021-08-06 11:40:24 +08:00
huyueeer
b77345222c LDAP认证忽略大小写,修正判断顺序,相同LDAP用户反复REPLACE 2021-08-05 11:17:38 +08:00
huyueeer
793e81406e LDAP认证忽略大小写,修正从LDAP服务器返回值设置Username 2021-08-04 16:23:57 +08:00
huyueeer
cef1ec95d2 LDAP验证忽略账户大小写 2021-08-04 14:14:53 +08:00
EricZeng
7e1b3c552b Merge pull request #360 from ZHAOYINRUI/patch-1
Update 开源版与商业版特性对比.md
2021-08-03 10:02:02 +08:00
ZHAOYINRUI
69736a63b6 Update 开源版与商业版特性对比.md
补充优化
2021-08-02 22:10:15 +08:00
EricZeng
fb4a9f9056 删除多余的‘在’
删除多余的‘在’
2021-07-26 09:28:16 +08:00
zengqiao
387d89d3af optimize code format by sonar-lint 2021-07-13 10:39:28 +08:00
EricZeng
65d9ca9d39 Merge pull request #336 from fengxsong/master
feat: update dockerfile and helm chart
2021-07-10 10:47:57 +08:00
Peng
8c842af4ba Update README.md
更新小尺寸logo
2021-07-09 12:46:18 +08:00
shirenchuang
4faf9262c9 配置文件漏了 加上 2021-07-09 11:55:14 +08:00
shirenchuang
be7724c67d 2021-07-09 11:21:20 +08:00
Peng
48d26347f7 Update README.md
替换logo
2021-07-09 11:01:18 +08:00
shirenchuang
bdb01ec8b5 2021-07-07 13:28:55 +08:00
mike.zhangliang
9047815799 Update README.md 2021-07-06 17:36:23 +08:00
EricZeng
05bd94a2cc Merge pull request #344 from didi/dev
删除钉钉群二维码
2021-07-05 12:15:52 +08:00
zengqiao
c9f7da84d0 删除钉钉群二维码 2021-07-05 12:14:37 +08:00
EricZeng
bcc124e86a Merge pull request #343 from Hongten/master
修复Converts#convert2OrderDO() 出现重复赋值
2021-07-04 21:35:34 +08:00
Hongten
48d2733403 Merge pull request #2 from didi/master
sync code
2021-07-04 18:04:55 +08:00
hongtenzone@foxmail.com
31fc6e4e56 remove duplicate operation 2021-07-04 17:59:36 +08:00
hongtenzone@foxmail.com
fcdeef0146 remove duplicate operation 2021-07-04 17:55:54 +08:00
EricZeng
1cd524c0cc Merge pull request #341 from didi/dev
Topic基本信息中增加retention.bytes信息
2021-07-02 18:34:56 +08:00
zengqiao
0f746917a7 Topic基本信息中增加retention.bytes信息 2021-07-02 16:41:57 +08:00
EricZeng
a2228d0169 Merge pull request #335 from didi/dev
bump jackson-databind version to 2.9.10.8
2021-06-24 18:04:57 +08:00
shirenchuang
e8a679d34b Merge branch 'master' into v2.4.3 2021-06-24 17:18:50 +08:00
fengxusong
1912a42091 fix: default config 2021-06-24 14:00:29 +08:00
fengxusong
ca81f96635 feat: update dockerfile and charts 2021-06-24 12:13:29 +08:00
zengqiao
eb3b8c4b31 bump jackson-databind version to 2.9.10.8 2021-06-23 21:31:43 +08:00
EricZeng
6740d6d60b Merge pull request #332 from didi/dev
修复poll异常时, 超时时间不生效问题
2021-06-23 20:24:50 +08:00
zengqiao
c46c35b248 修复poll异常时, 超时时间不生效问题 2021-06-23 10:11:38 +08:00
EricZeng
0b2dcec4bc Merge pull request #323 from didi/dev
fix jmx credentials
2021-06-03 10:22:12 +08:00
shirenchuang
f8e2a4aff4 修改km的打包方式
增加启动/关闭脚本
2021-06-02 18:13:58 +08:00
zengqiao
7256db8c4e fix jmx credentials 2021-06-02 13:59:18 +08:00
shirenchuang
b14d5d9bee 修改km的打包方式
增加启动/关闭脚本
2021-06-01 20:20:40 +08:00
shirenchuang
12e15c3e4b Merge branch 'shirc_dev' into dev_v2.5.0 2021-06-01 20:19:53 +08:00
shirenchuang
51911bf272 add distribution 2021-06-01 20:17:54 +08:00
shirenchuang
6dc8061401 add distribution 2021-06-01 16:32:16 +08:00
EricZeng
b8fa4f8797 Merge pull request #319 from didi/dev
optimize n9e's default port
2021-05-31 19:44:38 +08:00
zengqiao
cc0bea7f45 optimize n9e's default port 2021-05-31 19:43:03 +08:00
EricZeng
4e9124b244 Merge pull request #316 from didi/dev
Topic账单配置说明
2021-05-29 13:46:18 +08:00
zengqiao
f0eabef7b0 Topic账单配置说明 2021-05-28 17:36:36 +08:00
EricZeng
23e5557958 Merge pull request #315 from didi/master
kafka-gateway相关功能说明
2021-05-28 17:13:29 +08:00
EricZeng
b1d02afa85 Merge pull request #312 from lucasun/master
修复clipbord 2.0.6 打包问题
2021-05-28 11:34:01 +08:00
孙超
2edc380f47 修改package.json增加内存修复和clipbord版本 2021-05-28 11:30:33 +08:00
孙超
cea8295c09 clipbord升级版本 2021-05-28 11:21:12 +08:00
EricZeng
244bfc993a Merge pull request #310 from ZHAOYINRUI/master
补充FAQ开源版和商业版特性对比
2021-05-27 14:50:52 +08:00
ZHAOYINRUI
3a272a4493 Update faq.md 2021-05-27 14:45:51 +08:00
ZHAOYINRUI
a3300db770 Update faq.md 2021-05-27 14:22:59 +08:00
ZHAOYINRUI
b0394ce261 Delete Logi-KafkaManager开源版和商业版特性对比总结.pdf 2021-05-27 14:22:03 +08:00
ZHAOYINRUI
3123089790 Create 开源版与商业版特性对比.md 2021-05-27 14:21:48 +08:00
ZHAOYINRUI
f13cf66676 Delete 开源版与商业版特性对比.md 2021-05-27 12:08:15 +08:00
ZHAOYINRUI
0c8c4d87fb Delete 开源版与商业版特性对比.md 2021-05-27 12:08:01 +08:00
ZHAOYINRUI
066088fdeb Update faq.md 2021-05-27 12:06:51 +08:00
ZHAOYINRUI
cf641e41c7 Update faq.md 2021-05-27 12:05:41 +08:00
ZHAOYINRUI
5b48322e1b Update faq.md 2021-05-27 12:04:58 +08:00
ZHAOYINRUI
9d3f680d58 Update faq.md 2021-05-27 12:04:04 +08:00
ZHAOYINRUI
bed28d57e6 Update 开源版与商业版特性对比.md 2021-05-27 12:02:09 +08:00
ZHAOYINRUI
2538525103 Update 开源版与商业版特性对比.md 2021-05-27 12:01:51 +08:00
ZHAOYINRUI
6ed798db8c Create 开源版与商业版特性对比.md 2021-05-27 12:01:15 +08:00
ZHAOYINRUI
8e9d966829 Update 开源版与商业版特性对比.md 2021-05-27 12:00:26 +08:00
ZHAOYINRUI
be16640f92 Update 开源版与商业版特性对比.md 2021-05-27 11:59:41 +08:00
ZHAOYINRUI
0e1376dd2e Create 开源版与商业版特性对比.md 2021-05-27 11:57:56 +08:00
ZHAOYINRUI
0494575aa7 Update faq.md 2021-05-27 11:32:08 +08:00
ZHAOYINRUI
bed57534e0 Add files via upload 2021-05-27 11:22:47 +08:00
EricZeng
1862d631d1 Merge pull request #305 from didi/dev
heartbeat表的数据更新时间从MySQL自动生成调整为Logi-KM的时间
2021-05-25 13:44:04 +08:00
zengqiao
c977ce5690 heartbeat表的数据更新时间从MySQL自动生成调整为Logi-KM的时间 2021-05-25 10:27:27 +08:00
zengqiao
84df377516 bump version to v2.4.2 and add release notes 2021-05-21 10:45:10 +08:00
EricZeng
4d9a284f6e Merge pull request #303 from didi/dev
bump tomcat version to 8.5.66
2021-05-21 10:21:16 +08:00
zengqiao
da7ad8b44a bump tomcat version to 8.5.66 2021-05-21 10:20:09 +08:00
EricZeng
4164046323 Merge pull request #301 from didi/dev
fix title version
2021-05-20 20:36:14 +08:00
zengqiao
72e743dfd1 fix title version 2021-05-20 20:35:23 +08:00
EricZeng
7eb7edaf0a Merge pull request #300 from didi/dev
bump tomcat version to 8.5.56
2021-05-20 20:33:59 +08:00
zengqiao
49368aaf76 bump tomcat version to 8.5.56 2021-05-20 18:17:30 +08:00
zengqiao
b8c07a966f bump version to v2.4.1 2021-05-18 21:00:20 +08:00
EricZeng
c6bcc0e3aa Merge pull request #297 from didi/dev
split op util controller to topic controller and leader controller, and add authority controller, quota controller
2021-05-18 20:21:18 +08:00
zengqiao
7719339f23 split op util controller to topic controller and leader controller, and add authority controller, quota controller 2021-05-18 20:18:08 +08:00
EricZeng
8ad64722ed Merge pull request #296 from tcf1207239873/dev
迭代优化2.4.1-配额调整
2021-05-18 19:37:58 +08:00
tangcongfa_v@didichuxing.com
611f8b8865 调整配额与权限 2021-05-18 18:25:03 +08:00
tangcongfa_v@didichuxing.com
38bdc173e8 Merge remote-tracking branch 'origin/dev' into dev 2021-05-18 16:07:40 +08:00
tangcongfa_v@didichuxing.com
52244325d9 权限调整 2021-05-18 16:03:24 +08:00
tcf1207239873
3fd3d99b8c Merge pull request #4 from didi/dev
Dev-0518-2
2021-05-18 15:45:55 +08:00
tangcongfa_v@didichuxing.com
d4ee5e91a2 配额调整 2021-05-18 14:49:00 +08:00
EricZeng
c2ad2d7238 Merge pull request #295 from didi/dev
简化sd配置枚举类的长度
2021-05-18 14:36:29 +08:00
zengqiao
892e195f0e code format 2021-05-18 14:33:02 +08:00
zengqiao
c5b1bed7dc 简化sd配置枚举类的长度 2021-05-18 14:13:23 +08:00
EricZeng
0e388d7aa7 Merge pull request #294 from didi/dev
增加登录绕过的接口调用方式
2021-05-18 11:48:55 +08:00
zengqiao
c3a0dbbe48 增加登录绕过的接口调用方式 2021-05-18 11:45:15 +08:00
tangcongfa_v@didichuxing.com
8b95b3ffc7 配额调整 2021-05-18 11:25:41 +08:00
tcf1207239873
42b78461cd Merge pull request #3 from didi/dev
Dev-0518
2021-05-18 10:30:57 +08:00
EricZeng
9190a41ca5 Merge pull request #293 from didi/dev
增加监控指标说明
2021-05-17 18:57:58 +08:00
zengqiao
28a7251319 增加监控指标说明 2021-05-17 15:31:08 +08:00
EricZeng
20565866ef Merge pull request #292 from didi/master
merge master
2021-05-17 15:20:50 +08:00
EricZeng
246f10aee5 Merge pull request #258 from Huyueeer/patch-2
更新Topic资源治理部分
2021-05-17 09:58:09 +08:00
EricZeng
960017280d 增加Topic资源治理的配置说明
增加Topic资源治理的配置说明
2021-05-17 09:57:56 +08:00
tangcongfa_v@didichuxing.com
7218aaf52e 权限调整 2021-05-13 17:49:42 +08:00
zengqiao
62050cc7b6 Merge branch 'master' of https://github.com/didi/Logi-KafkaManager 2021-05-13 16:22:16 +08:00
zengqiao
f88a14ac0a 补充说明为什么删除Topic成功之后, 又立马出现的原因 2021-05-13 16:22:05 +08:00
EricZeng
9286761c30 更新体验地址
更新体验地址
2021-05-13 10:26:07 +08:00
zengqiao
07c3273247 增加v2.4.0更新内容 2021-05-12 20:16:47 +08:00
tangcongfa_v@didichuxing.com
eb8fe77582 配额调整 2021-05-12 11:31:41 +08:00
tangcongfa_v@didichuxing.com
b68ba0bff6 配额调整 2021-05-11 16:58:44 +08:00
tangcongfa_v@didichuxing.com
696657c09e 处理冲突 2021-05-11 10:40:58 +08:00
tcf1207239873
12bea9b60a Merge pull request #1 from didi/dev
Dev
2021-05-11 10:28:02 +08:00
tangcongfa_v@didichuxing.com
9334e9552f 处理冲突 2021-05-11 10:25:25 +08:00
tangcongfa_v@didichuxing.com
a43b04a98b 处理冲突 2021-05-11 10:23:25 +08:00
zengqiao
f359ff995d faq中增加应用下线失败的说明 2021-05-11 08:41:37 +08:00
tangcongfa_v@didichuxing.com
9185d2646b 权限申请 2021-05-10 16:22:58 +08:00
EricZeng
33e61c762c Merge pull request #285 from didi/dev
bump commons-beanutils version to 1.9.4 & faq补充app的使用说明
2021-05-08 13:51:26 +08:00
zengqiao
e342e646ff 优化因DB时区不对导致周期任务不能被触发的日志 2021-05-08 13:50:04 +08:00
zengqiao
ed163a80e0 bump commons-beanutils version to 1.9.4 2021-05-08 11:45:27 +08:00
zengqiao
b390df08b5 faq补充app的使用说明 2021-05-08 11:28:52 +08:00
tangcongfa_v@didichuxing.com
f0b3b9f7f4 扩分区 2021-05-08 11:23:06 +08:00
EricZeng
a67d732507 Merge pull request #284 from didi/dev
faq中补充说明heartbeat表的作用及集群删除是否影响物理集群的说明
2021-05-08 11:20:51 +08:00
zengqiao
ca0ebe0d75 faq中补充说明heartbeat表的作用及集群删除是否影响物理集群的说明 2021-05-08 11:15:25 +08:00
EricZeng
94d113cbe0 Merge pull request #283 from didi/master
merge master
2021-05-08 11:07:53 +08:00
Hongten
25c3aeaa5f Merge pull request #1 from Hongten/optimize/migration_task_name
optimize the migration task name
2021-05-07 19:26:54 +08:00
Xiang Hong Wei
736d5a00b7 optimize the migration task name 2021-05-07 19:06:47 +08:00
zengqiao
f1627b214c FAQ:新建告警组说明优化 2021-05-07 14:03:09 +08:00
EricZeng
d9265ec7ea Merge pull request #280 from didi/dev
连接信息写DB优化为批量写入
2021-05-07 13:52:43 +08:00
zengqiao
663e871bed 连接信息写DB优化为批量写入 2021-05-07 13:51:34 +08:00
shirenchuang
5c5eaddef7 readme add 社区km文章 2021-05-07 11:34:32 +08:00
shirenchuang
edaec4f1ae readme add 社区km文章 2021-05-07 11:34:18 +08:00
EricZeng
6d19acaa6c 更新FAQ,增加磁盘信息没有数据的说明
更新FAQ,增加磁盘信息没有数据的说明
2021-05-06 18:39:30 +08:00
EricZeng
d29a619fbf 优化页面无数据的FAQ
优化页面无数据的FAQ
2021-05-06 17:54:46 +08:00
EricZeng
b17808dd91 Merge pull request #275 from Huyueeer/master
修改maxMetricsSaveDays字段为Long类型
2021-04-30 18:48:54 +08:00
HuYueeer
c5321a3667 修改maxMetricsSaveDays字段为Long类型 2021-04-30 13:47:49 +08:00
EricZeng
8836691510 Merge pull request #273 from didi/dev
bump jetty-util version to 9.4.39.v20210325
2021-04-29 17:26:40 +08:00
zengqiao
6568f6525d bump jetty-util version to 9.4.39.v20210325 2021-04-29 17:25:08 +08:00
tangcongfa_v@didichuxing.com
473fc27b49 创建topic 2021-04-28 18:05:58 +08:00
EricZeng
74aeb55acb Merge pull request #266 from Liu-XinYuan/responsecode-fix
In case of authentication failure, add a clear response code
2021-04-28 17:25:55 +08:00
Liu-XinYuan
8efcf0529f In case of authentication failure, add a clear response code 2021-04-28 17:14:03 +08:00
EricZeng
06071c2f9c Merge pull request #264 from didi/dev_2.4.0
修复Topic工单选择Broker方式进行审批时展示的还是Region的问题
2021-04-28 14:19:26 +08:00
EricZeng
5eb4eca487 Merge pull request #263 from lucasun/master
修复Topic工单审批时,切换到Broker时展示还是Region的问题
2021-04-28 14:17:11 +08:00
孙超
33f6153e12 V2.4 bugfix 2021-04-28 14:09:54 +08:00
tangcongfa_v@didichuxing.com
df3283f526 删除topic 2021-04-28 11:22:53 +08:00
tangcongfa_v@didichuxing.com
b5901a2819 创建topic 2021-04-28 11:08:01 +08:00
EricZeng
6d5f1402fe Merge pull request #262 from didi/dev
增加App与Topic自动化审批开关
2021-04-28 10:51:12 +08:00
zengqiao
65e3782b2e 增加App与Topic自动化审批开关 2021-04-28 10:48:17 +08:00
EricZeng
135981dd30 Merge pull request #261 from didi/dev
开放接口集群ID开始调整, op对应的是物理集群ID, normal对应的是逻辑集群ID, 第一步, util接口调整
2021-04-28 10:15:42 +08:00
zengqiao
fe5cf2d922 开放接口集群ID开始调整, op对应的是物理集群ID, normal对应的是逻辑集群ID, 第一步, util接口调整 2021-04-28 10:10:16 +08:00
EricZeng
e15425cc2e 修复错别字
修复错别字
2021-04-27 17:36:44 +08:00
EricZeng
c3cb0a4e33 优化FAQ中告警组创建的说明
优化FAQ中告警组创建的说明
2021-04-27 17:30:18 +08:00
lucasun
cc32976bdd Merge pull request #259 from JokerQueue/master
用户管理页面,前端限制用户删除自己
2021-04-27 14:08:31 +08:00
Joker
bc08318716 用户管理页面,前端限制用户删除自己 2021-04-26 21:15:27 +08:00
tangcongfa_v@didichuxing.com
ee1ab30c2c 创建topic 2021-04-26 17:48:32 +08:00
HuYueeer
7fa1a66f7e 更新Topic资源治理部分 2021-04-26 14:51:12 +08:00
EricZeng
946bf37406 Merge pull request #257 from Huyueeer/patch-1
更新提问:heartbeat表相关
2021-04-26 14:27:10 +08:00
HuYueeer
8706f6931a Update faq.md
更新提问:heartbeat表相关
2021-04-26 14:15:32 +08:00
tangcongfa_v@didichuxing.com
f551674860 创建topic 2021-04-26 11:16:53 +08:00
EricZeng
d90fe0ef07 Merge pull request #253 from didi/master
merge master
2021-04-26 10:01:19 +08:00
EricZeng
bf979fa3b3 Merge pull request #252 from didi/dev_2.4.0
Dev 2.4.0
2021-04-26 09:55:30 +08:00
EricZeng
b3b88891e9 Merge pull request #251 from lucasun/master
v2.4.0
2021-04-25 21:01:33 +08:00
lucasun
01c5de60dc Merge branch 'master' into master 2021-04-25 20:54:10 +08:00
孙超
47b8fe5022 V2.4.1 FE 2021-04-25 20:43:20 +08:00
zengqiao
324b37b875 v2.4.0 be code 2021-04-25 18:11:52 +08:00
zengqiao
76e7e192d8 bump version to 2.4.0 2021-04-25 17:40:47 +08:00
EricZeng
f9f3c4d923 Merge pull request #240 from yangvipguang/docker-dev
Docker容器镜像优化
2021-04-25 17:23:36 +08:00
杨光
a476476bd1 Update Dockerfile
添加进程管理器tini 防止僵尸应用
升级基础镜像到Java 16 alpine 
默认使用官方jar 包
默认开启JMX 监控
2021-04-23 14:10:40 +08:00
杨光
82a60a884a Add files via upload 2021-04-23 14:06:55 +08:00
杨光
f17727de18 Merge pull request #1 from didi/master
同步提交
2021-04-23 11:31:35 +08:00
shirenchuang
f1f33c79f4 Merge branch 'shirc_dev' into dev 2021-04-23 10:26:43 +08:00
shirenchuang
d52eaafdbb 修正一下 用户手册中的 共享集群和独享集群的概念 2021-04-23 10:25:36 +08:00
shirenchuang
e7a3e50ed1 Merge branch 'shirc_dev' into dev 2021-04-23 10:20:01 +08:00
shirenchuang
2e09a87baa Merge remote-tracking branch 'origin/master' into shirc_dev 2021-04-23 10:18:30 +08:00
shirenchuang
b92ae7e47e 修正一个注释 2021-04-23 10:18:18 +08:00
EricZeng
f98446e139 Merge pull request #239 from Liu-XinYuan/i238
fix  create topic failed when not specify peak_byte_in
2021-04-22 19:02:48 +08:00
Liu-XinYuan
57a48dadaa modify from obj ==null to ValidateUtils.isNull 2021-04-22 18:44:34 +08:00
Liu-XinYuan
c65ec68e46 fix create topic failed when not specify peak_byte_in 2021-04-22 18:30:23 +08:00
zengqiao
d6559be3fc 部分后台任务获取Topic列表时不走缓存 2021-04-22 16:06:37 +08:00
shirenchuang
6fbf67f9a9 Merge branch 'dev' into shirc_dev 2021-04-22 14:13:32 +08:00
zengqiao
59df5b24fe broker元信息中增加Rack信息 2021-04-20 19:28:36 +08:00
zengqiao
3e1544294b 删除无效代码 2021-04-20 17:22:26 +08:00
EricZeng
a12c398816 Merge pull request #232 from didi/dev
应用下线功能权限列表获取优化
2021-04-20 13:54:49 +08:00
EricZeng
0bd3e28348 Merge pull request #228 from PengShuaixin/dev
应用下线审批功能优化
2021-04-20 13:51:32 +08:00
PengShuaixin
ad4e39c088 应用下线功能权限列表获取优化 2021-04-20 11:22:11 +08:00
PengShuaixin
2668d96e6a Merge remote-tracking branch 'origin/dev' into dev
# Conflicts:
#	kafka-manager-extends/kafka-manager-bpm/src/main/java/com/xiaojukeji/kafka/manager/bpm/order/impl/DeleteAppOrder.java
2021-04-20 11:19:49 +08:00
shirenchuang
357c496aad 下线应用的时候 判断先下线topic 2021-04-20 11:18:07 +08:00
shirenchuang
22a513ba22 升级mysql驱动;支持Mysql 8.0+ 2021-04-20 11:18:07 +08:00
zengqiao
e6dd1119be 通过获取类的RequestMapping注解来判断当前请求是否需要登录 2021-04-20 11:18:07 +08:00
EricZeng
2dbe454e04 Merge pull request #231 from didi/master
merge master
2021-04-20 10:46:03 +08:00
zengqiao
e3a59b76eb 修复数据删空之后, 缓存不能被更新的BUG 2021-04-19 20:31:40 +08:00
shirenchuang
01008acfcd 本地sql配置 2021-04-19 15:35:48 +08:00
zengqiao
b67a162d3f bump version to v2.3.1 2021-04-19 14:13:48 +08:00
shirenchuang
8bfde9fbaf Merge branch 'shirc_dev' into dev 2021-04-19 10:19:11 +08:00
shirenchuang
1fdecf8def 下线应用的时候 判断先下线topic 2021-04-19 10:17:29 +08:00
zengqiao
1141d4b833 通过获取类的RequestMapping注解来判断当前请求是否有权限 2021-04-15 18:12:21 +08:00
EricZeng
cdac92ca7b Merge pull request #229 from didi/dev
通过获取类的RequestMapping注解来判断当前请求是否需要登录
2021-04-14 19:47:43 +08:00
zengqiao
2a57c260cc 通过获取类的RequestMapping注解来判断当前请求是否需要登录 2021-04-14 19:40:19 +08:00
PengShuaixin
f41e29ab3a 应用下线功能优化 2021-04-14 12:29:59 +08:00
zengqiao
8f10624073 add jmx prometheus jar 2021-04-12 17:58:24 +08:00
EricZeng
eb1f8be11e Merge pull request #224 from didi/master
merge master
2021-04-12 13:51:14 +08:00
EricZeng
3333501ab9 Merge pull request #222 from zwOvO/master
删除无用import、删除无用代码
2021-04-09 19:28:04 +08:00
zwOvO
0f40820315 删除无用import、删除无用代码 2021-04-09 11:41:06 +08:00
shirenchuang
5f1a839620 升级mysql驱动;支持Mysql 8.0+ 2021-04-06 12:09:52 +08:00
zengqiao
b9bb1c775d change uri filter rule 2021-04-06 10:26:21 +08:00
zengqiao
1059b7376b forbiden request when uri contain .. 2021-04-06 10:01:29 +08:00
EricZeng
f38ab4a9ce Merge pull request #217 from didi/dev
拒绝包含./或/连续过多的接口请求
2021-03-31 20:00:52 +08:00
zengqiao
9e7450c012 拒绝包含./或/连续过多的接口请求 2021-03-31 19:45:18 +08:00
EricZeng
99a3e360fe Merge pull request #216 from didi/dev
接口过滤策略由接口黑名单转成接口白名单
2021-03-30 12:56:19 +08:00
lucasun
d45f8f78d6 Merge pull request #215 from zhangfenhua/master
增加nginx配置:前后端分离&配置多个静态资源
2021-03-30 11:11:58 +08:00
zengqiao
648af61116 接口过滤策略由接口黑名单转成接口白名单 2021-03-29 21:21:23 +08:00
zhangfenhua
eebf1b89b1 nginx配置手册 2021-03-29 11:53:50 +08:00
EricZeng
f8094bb624 Merge pull request #211 from didi/dev
add expert config desc
2021-03-23 15:23:10 +08:00
zengqiao
ed13e0d2c2 add expert config desc 2021-03-23 15:21:48 +08:00
EricZeng
aa830589b4 Merge pull request #210 from didi/dev
fix monitor enable time illegal bug
2021-03-22 17:22:44 +08:00
zengqiao
999a2bd929 fix monitor enable time illegal bug 2021-03-22 17:21:12 +08:00
EricZeng
d69ee98450 Merge pull request #209 from didi/dev
add faq, kafka version supported & apply logical cluster and how to handle it
2021-03-22 13:43:14 +08:00
zengqiao
f6712c24ad merge master 2021-03-22 13:42:09 +08:00
zengqiao
89d2772194 add faq, kafka version supported & apply logical cluster and how to handle it 2021-03-22 13:38:23 +08:00
mike.zhangliang
03352142b6 Update README.md
微信加群方式补充
2021-03-16 14:46:38 +08:00
lucasun
73a51e0c00 Merge pull request #205 from ZQKC/master
add qa
2021-03-10 19:27:01 +08:00
zengqiao
2e26f8caa6 add qa 2021-03-10 19:23:29 +08:00
EricZeng
f9bcce9e43 Merge pull request #3 from didi/master
merge didi Logi-KM
2021-03-10 19:20:39 +08:00
EricZeng
2ecc877ba8 fix add_cluster.md path
fix add_cluster.md path
2021-03-10 15:45:48 +08:00
EricZeng
3f8a3c69e3 Merge pull request #201 from ZQKC/master
optimize ldap
2021-03-10 14:12:35 +08:00
zengqiao
67c37a0984 optimize ldap 2021-03-10 13:52:09 +08:00
EricZeng
a58a55d00d Merge pull request #203 from lucasun/hotfix/v2.3.1
clipbord版本锁定在2.0.6,升级2.0.7会引起ts打包报错
2021-03-09 18:11:02 +08:00
孙超
06d51dd0b8 clipbord版本锁定在2.0.6,升级2.0.7会引起ts打包报错 2021-03-09 18:07:42 +08:00
zengqiao
d5db028f57 optimize ldap 2021-03-09 15:13:55 +08:00
EricZeng
fcb85ff4be Merge pull request #2 from didi/master
merge didi logi-km
2021-03-09 11:07:17 +08:00
EricZeng
3695b4363d Merge pull request #200 from didi/dev
del ResultStatus which in vo
2021-03-09 11:02:46 +08:00
zengqiao
cb11e6437c del ResultStatus in vo 2021-03-09 11:01:21 +08:00
EricZeng
5127bd11ce Merge pull request #198 from didi/master
merge master
2021-03-09 10:42:28 +08:00
EricZeng
91f90aefa1 Merge pull request #195 from fanghanyun/v2.3.0_ldap
support AD LDAP
2021-03-09 10:40:42 +08:00
fanghanyun
0a067bce36 Support AD LDAP 2021-03-09 10:19:08 +08:00
fanghanyun
f0aba433bf Support AD LDAP 2021-03-08 20:31:15 +08:00
EricZeng
f06467a0e3 Merge pull request #197 from didi/dev
delete without used code
2021-03-05 16:12:27 +08:00
zengqiao
68bcd3c710 delete without used code 2021-03-05 16:05:58 +08:00
EricZeng
a645733cc5 Merge pull request #196 from didi/dev
add gateway config docs
2021-03-05 15:31:53 +08:00
zengqiao
49fe5baf94 add gateway config docs 2021-03-05 14:59:40 +08:00
fanghanyun
411ee55653 support AD LDAP 2021-03-05 14:45:54 +08:00
EricZeng
e351ce7411 Merge pull request #194 from didi/dev
reject req when uri contains ..
2021-03-04 17:52:56 +08:00
zengqiao
f33e585a71 reject req when uri contains .. 2021-03-04 17:51:35 +08:00
EricZeng
77f3096e0d Merge pull request #191 from didi/dev
Dev
2021-02-28 22:04:34 +08:00
EricZeng
9a5b18c4e6 Merge pull request #190 from JokerQueue/dev
bug fix:correct way to judge a user does not exist
2021-02-28 14:36:28 +08:00
Joker
0c7112869a bug fix:correct way to judge a user does not exist 2021-02-27 22:35:35 +08:00
EricZeng
f66a4d71ea Merge pull request #188 from JokerQueue/dev
bug fix: unexpected stop of the topic sync task
2021-02-26 22:46:54 +08:00
Joker
9b0ab878df bug fix: unexpected stop of the topic sync task 2021-02-26 19:47:03 +08:00
EricZeng
d30b90dfd0 Merge pull request #186 from ZHAOYINRUI/master
新增releases_notes、更新FAQ
2021-02-26 09:59:18 +08:00
ZHAOYINRUI
efd28f8c27 Update faq.md 2021-02-26 00:03:25 +08:00
ZHAOYINRUI
e05e722387 Add files via upload 2021-02-26 00:01:09 +08:00
EricZeng
748e81956d Update faq.md 2021-02-24 14:10:41 +08:00
EricZeng
c9a41febce Merge pull request #184 from didi/dev
reject illegal zk address
2021-02-23 17:32:20 +08:00
zengqiao
18e244b756 reject illegal zk address 2021-02-23 17:18:49 +08:00
mrazkong
47676139a3 Merge pull request #183 from didi/dev
support dynamic change cluster auth
2021-02-23 16:56:26 +08:00
zengqiao
1ed933b7ad support dynamic change auth 2021-02-23 16:34:21 +08:00
EricZeng
f6a343ccd6 Merge pull request #182 from didi/master
merge master
2021-02-23 15:47:28 +08:00
EricZeng
dd6cdc22e5 Merge pull request #178 from Observe-secretly/v2.2.1_ldap
新功能:增加了对LDAP登录的支持
2021-02-10 12:35:07 +08:00
李民
f70f4348b3 Merge branch 'master' into v2.2.1_ldap 2021-02-10 10:00:32 +08:00
EricZeng
ec7f801929 Merge pull request #180 from didi/dev_2.3.0
Dev 2.3.0
2021-02-09 22:06:51 +08:00
zengqiao
0f8aca382e bump version to 2.3.0 2021-02-09 21:47:56 +08:00
zengqiao
0270f77eaa add upgrade doc 2021-02-09 21:46:55 +08:00
EricZeng
dcba71ada4 Merge pull request #179 from lucasun/dev_2.3.0_fe
迭代V2.5, 修复broker监控问题,增加JMX认证支持等...
2021-02-09 18:48:42 +08:00
孙超
6080f76a9c 迭代V2.5, 修复broker监控问题,增加JMX认证支持等... 2021-02-09 15:26:47 +08:00
李民
e7349161f3 BUG FIX:修改LDAP登录重复注册用户的BUG 2021-02-09 15:22:26 +08:00
李民
2e2907ea09 修改LDAP获取UserDN的时候可能出错的问题 2021-02-09 14:33:53 +08:00
李民
25e84b2a6c 新功能:增加对LDAP的登录的支持 2021-02-09 11:33:54 +08:00
zengqiao
5efd424172 version 2.3.0 2021-02-09 11:20:56 +08:00
EricZeng
2672502c07 Merge pull request #174 from 17hao/issue-153-authority
Tracking delete account
2021-02-07 16:10:56 +08:00
EricZeng
83440cc3d9 Merge pull request #173 from 17hao/issue-153
Tracking changes applied to app
2021-02-07 16:10:01 +08:00
17hao
8e5f93be1c Tracking delete account 2021-02-07 15:54:41 +08:00
17hao
c1afc07955 Tracking changes applied to app 2021-02-07 15:16:26 +08:00
EricZeng
4a83e14878 Merge pull request #172 from 17hao/issue-153
Tracking changes applied to Kafka cluster
2021-02-07 14:38:38 +08:00
17hao
832320abc6 Improve code's cohesion && save jmx properties 2021-02-07 14:20:57 +08:00
17hao
70c237da72 Tracking changes applied to Kafka cluster 2021-02-07 13:23:22 +08:00
EricZeng
edfcc5c023 Merge pull request #169 from 17hao/issue-153
Record topic operation
2021-02-06 22:30:32 +08:00
17hao
0668debec6 Update pom.xml 2021-02-06 18:46:47 +08:00
17hao
02d6463faa Using JsonUtils instead of fastjson 2021-02-06 18:43:36 +08:00
17hao
1fdb85234c Record editting topic 2021-02-05 12:18:50 +08:00
EricZeng
44b7dd1808 Merge pull request #167 from ZHAOYINRUI/master
更新readme、集群接入手册
2021-02-04 19:21:59 +08:00
ZHAOYINRUI
e983ee3101 Update README.md 2021-02-04 19:10:11 +08:00
ZHAOYINRUI
75e7e81c05 Add files via upload 2021-02-04 19:09:02 +08:00
ZHAOYINRUI
31ce3b9c08 Update add_cluster.md 2021-02-04 19:08:28 +08:00
EricZeng
ed93c50fef modify without logical cluster desc 2021-02-04 16:54:42 +08:00
EricZeng
4845660eb5 Merge pull request #163 from 17hao/issue-160
Issue#160: Remove __consumer_offsets from topic list
2021-02-04 16:42:41 +08:00
17hao
c7919210a2 Fix topic list filter condition 2021-02-04 16:32:31 +08:00
17hao
9491418f3b Update if statements 2021-02-04 12:33:32 +08:00
17hao
e8de403286 Hide __transaction_state in topic list && fix logic error 2021-02-04 12:14:44 +08:00
17hao
dfb625377b Using existing topic name constant 2021-02-03 22:30:38 +08:00
EricZeng
2c0f2a8be6 Merge pull request #166 from ZHAOYINRUI/master
更新集群接入文章、资源申请文章
2021-02-03 21:02:38 +08:00
ZHAOYINRUI
787d3cb3e9 Update resource_apply.md 2021-02-03 20:52:44 +08:00
ZHAOYINRUI
96ca17d26c Add files via upload 2021-02-03 19:43:03 +08:00
ZHAOYINRUI
3dd0f7f2c3 Update add_cluster.md 2021-02-03 19:41:33 +08:00
ZHAOYINRUI
10ba0cf976 Update resource_apply.md 2021-02-03 18:18:02 +08:00
ZHAOYINRUI
276c15cc23 Delete docs/user_guide/resource_apply directory 2021-02-03 18:08:15 +08:00
ZHAOYINRUI
2584b848ad Update resource_apply.md 2021-02-03 18:07:34 +08:00
ZHAOYINRUI
6471efed5f Add files via upload 2021-02-03 18:04:40 +08:00
ZHAOYINRUI
5b7d7ad65d Create resource_apply.md 2021-02-03 18:01:42 +08:00
17hao
712851a8a5 Add braces 2021-02-03 16:06:16 +08:00
17hao
63d291cb47 Remove __consumer_offsets from topic list 2021-02-03 15:50:33 +08:00
EricZeng
f825c92111 Merge pull request #159 from didi/dev_2.2.1
storage support s3
2021-02-03 13:49:52 +08:00
EricZeng
419eb2ea41 Merge pull request #158 from didi/dev
change dockerfile and heml location
2021-02-03 10:09:43 +08:00
zengqiao
89b58dd64e storage support s3 2021-02-02 16:42:20 +08:00
zengqiao
6bc5f81440 change dockerfile and heml location 2021-02-02 15:58:46 +08:00
EricZeng
424f4b7b5e Merge pull request #157 from didi/master
merge master
2021-02-02 15:33:51 +08:00
mrazkong
9271a1caac Merge pull request #118 from yangvipguang/helm-dev
增加Dockerfile 和 简单Helm
2021-02-01 10:50:05 +08:00
杨光
0ee4df03f9 Update Dockerfile 2021-01-31 15:34:15 +08:00
杨光
8ac713ce32 Update Dockerfile 2021-01-31 15:30:18 +08:00
杨光
76b2489fe9 Delete docker-depends/agent/config directory 2021-01-31 15:29:50 +08:00
杨光
6786095154 Delete sources.list 2021-01-31 15:29:31 +08:00
杨光
2c5793ef37 Delete settings 2021-01-31 15:29:19 +08:00
杨光
d483f25b96 Add files via upload
add  jmx prometheus
2021-01-31 15:28:59 +08:00
EricZeng
7118368979 Merge pull request #136 from ZHAOYINRUI/patch-10
Create resource_apply.md
2021-01-29 10:54:11 +08:00
EricZeng
59256c2e80 modify jdbc url
modify jdbc url, add useSSL=false
2021-01-29 10:53:35 +08:00
EricZeng
1fb8a0db1e Merge pull request #146 from ZHAOYINRUI/patch-12
Update README.md
2021-01-29 10:03:48 +08:00
ZHAOYINRUI
07d0c8e8fa Update README.md 2021-01-28 22:02:49 +08:00
EricZeng
98452ead17 Merge pull request #145 from didi/dev
faq add how to resolve topic biz data not exist error desc
2021-01-28 16:20:42 +08:00
zengqiao
d8c9f40377 faq add how to resolve topic biz data not exist error desc 2021-01-28 15:50:31 +08:00
EricZeng
8148d5eec6 Merge pull request #144 from didi/dev
optimize result code
2021-01-28 14:11:00 +08:00
zengqiao
4c429ad604 optimize result code 2021-01-28 12:06:06 +08:00
EricZeng
a9c52de8d5 Merge pull request #143 from ZhaoXinlong/patch-1
correcting some typo
2021-01-27 20:28:32 +08:00
ZhaoXinlong
f648aa1f91 correcting some typo
修改文字错误
2021-01-27 16:31:42 +08:00
EricZeng
eaba388bdd Merge pull request #142 from didi/dev
add connect jmx failed desc
2021-01-27 16:06:39 +08:00
zengqiao
73e6afcbc6 add connect jmx failed desc 2021-01-27 16:01:18 +08:00
EricZeng
8c3b72adf2 Merge pull request #139 from didi/dev
optimize message when login failed
2021-01-26 19:57:50 +08:00
zengqiao
ae18ff4262 optimize login failed message 2021-01-26 16:15:08 +08:00
ZHAOYINRUI
1adc8af543 Create resource_apply.md 2021-01-25 19:27:31 +08:00
EricZeng
7413df6f1e Merge pull request #131 from ZHAOYINRUI/patch-9
Update alarm_rules.md
2021-01-25 18:36:06 +08:00
EricZeng
bda8559190 Merge pull request #135 from didi/master
merge master
2021-01-25 18:34:56 +08:00
EricZeng
b74612fa41 Merge pull request #134 from didi/dev_2.2.0
merge dev 2.2.0
2021-01-25 17:30:26 +08:00
EricZeng
22e0c20dcd Merge pull request #133 from lucasun/dev_2.2.0_fe
fix txt
2021-01-25 17:21:42 +08:00
孙超
08f92e1100 fix txt 2021-01-25 17:02:07 +08:00
zengqiao
bb12ece46e modify zk example 2021-01-25 17:01:54 +08:00
EricZeng
0065438305 Merge pull request #132 from lucasun/dev_2.2.0_fe
add fe page
2021-01-25 16:47:02 +08:00
孙超
7f115c1b3e add fe page 2021-01-25 15:34:07 +08:00
ZHAOYINRUI
4e0114ab0d Update alarm_rules.md 2021-01-25 13:24:01 +08:00
EricZeng
0ef64fa4bd Merge pull request #126 from ZHAOYINRUI/patch-8
Create alarm_rules.md
2021-01-25 11:09:21 +08:00
ZHAOYINRUI
84dbc17c22 Update alarm_rules.md 2021-01-25 11:04:30 +08:00
EricZeng
16e16e356d Merge pull request #130 from xuehaipeng/patch-1
Update faq.md
2021-01-25 10:35:12 +08:00
xuehaipeng
978ee885c4 Update faq.md 2021-01-24 20:06:29 +08:00
zengqiao
850d43df63 add v2.2.0 feature & fix 2021-01-23 13:19:29 +08:00
zengqiao
fc109fd1b1 bump version to 2.2.0 2021-01-23 12:41:38 +08:00
EricZeng
9aefc55534 Merge pull request #1 from didi/dev
merge didi dev
2021-01-23 11:16:35 +08:00
EricZeng
2829947b93 Merge pull request #129 from didi/master
merge master
2021-01-23 11:09:52 +08:00
EricZeng
0c2af89a1c Merge pull request #125 from ZHAOYINRUI/patch-7
create kafka_metrics_desc.md
2021-01-23 11:03:14 +08:00
EricZeng
14c2dc9624 update kafka_metrics.md 2021-01-23 11:01:44 +08:00
EricZeng
4f35d710a6 Update and rename metric.md to kafka_metrics_desc.md 2021-01-23 10:58:11 +08:00
EricZeng
fdb5e018e5 Merge pull request #122 from ZHAOYINRUI/patch-4
Update README.md
2021-01-23 10:51:26 +08:00
EricZeng
6001fde25c Update dynamic_config_manager.md 2021-01-23 10:21:47 +08:00
EricZeng
ae63c0adaf Merge pull request #128 from didi/dev
add sync topic to db doc
2021-01-23 10:20:27 +08:00
zengqiao
ad1539c8f6 add sync topic to db doc 2021-01-23 10:17:59 +08:00
EricZeng
634a0c8cd0 Update faq.md 2021-01-22 20:42:13 +08:00
ZHAOYINRUI
773f9a0c63 Create alarm_rules.md 2021-01-22 18:16:51 +08:00
ZHAOYINRUI
e4e320e9e3 Create metric.md 2021-01-22 18:06:35 +08:00
ZHAOYINRUI
3b4b400e6b Update README.md 2021-01-22 15:56:53 +08:00
杨光
a950be2d95 change password 2021-01-20 17:57:14 +08:00
杨光
ba6f5ab984 add helm and dockerfile 2021-01-20 17:49:56 +08:00
mike.zhangliang
f3a5e3f5ed Update README.md 2021-01-18 19:06:43 +08:00
mike.zhangliang
e685e621f3 Update README.md 2021-01-18 19:05:44 +08:00
EricZeng
2cd2be9b67 Merge pull request #112 from didi/dev
监控告警系统对接说明文档
2021-01-17 18:21:16 +08:00
zengqiao
e73d9e8a03 add monitor_system_integrate_with_self file 2021-01-17 18:18:07 +08:00
zengqiao
476f74a604 rename file 2021-01-17 16:49:02 +08:00
EricZeng
ab0d1d99e6 Merge pull request #111 from didi/dev
Dev
2021-01-17 16:11:08 +08:00
zengqiao
d5680ffd5d 增加Topic同步任务&Bug修复 2021-01-16 16:26:38 +08:00
EricZeng
3c091a88d4 Merge pull request #110 from didi/master
合并master分支上的改动
2021-01-16 13:37:31 +08:00
EricZeng
49b70b33de Merge pull request #108 from didi/dev
增加application.yml文件说明 & 修改版本
2021-01-16 13:34:07 +08:00
zengqiao
c5ff2716fb 优化build.sh & yaml 2021-01-16 12:39:56 +08:00
ZQKC
400fdf0896 修复图片地址错误问题
修复图片地址错误问题
2021-01-16 12:04:20 +08:00
ZQKC
cbb8c7323c Merge pull request #109 from ZHAOYINRUI/master
架构图更新、钉钉群ID更新
2021-01-16 09:33:19 +08:00
ZHAOYINRUI
60e79f8f77 Update README.md 2021-01-16 00:25:06 +08:00
ZHAOYINRUI
0e829d739a Add files via upload 2021-01-16 00:22:31 +08:00
ZQKC
62abb274e0 增加application.yml文件说明
增加application.yml文件说明
2021-01-15 19:14:48 +08:00
ZQKC
e4028785de Update README.md
change km address
2021-01-09 15:30:30 +08:00
mrazkong
2bb44bcb76 Update Intergration_n9e_monitor.md 2021-01-07 17:09:15 +08:00
mike.zhangliang
684599f81b Update README.md 2021-01-07 15:44:17 +08:00
mike.zhangliang
b56d28f5df Update README.md 2021-01-07 15:43:07 +08:00
ZHAOYINRUI
02b9ac04c8 Update user_guide_cn.md 2020-12-30 22:44:23 +08:00
zengqiao
2fc283990a bump version to 2.1.0 2020-12-19 01:53:46 +08:00
ZQKC
abb652ebd5 Merge pull request #104 from didi/dev
v2.1版本合并
2020-12-19 01:14:26 +08:00
zengqiao
55786cb7f7 修改node版本要求 2020-12-19 00:45:58 +08:00
zengqiao
447a575f4f v2.1 fe 2020-12-19 00:40:52 +08:00
zengqiao
49280a8617 v2.1版本更新 2020-12-19 00:27:16 +08:00
ZQKC
ff78a9cc35 Merge pull request #101 from didi/dev
use mysql 8
2020-12-11 11:49:06 +08:00
zengqiao
3fea5c9c8c use mysql 8 2020-12-11 10:48:03 +08:00
ZQKC
aea63cad52 Merge pull request #94 from didi/dev
增加FAQ
2020-11-22 21:49:48 +08:00
zengqiao
800abe9920 增加FAQ 2020-11-22 21:43:52 +08:00
ZQKC
dd6069e41a Merge pull request #93 from didi/dev
夜莺Mon集成配置说明
2020-11-22 20:09:34 +08:00
zengqiao
90d31aeff0 夜莺Mon集成配置说明 2020-11-22 20:07:14 +08:00
ZQKC
4d9a327b1f Merge pull request #92 from didi/dev
FIX N9e Mon
2020-11-22 18:15:49 +08:00
zengqiao
06a97ef076 FIX N9e Mon 2020-11-22 18:13:36 +08:00
ZQKC
76c2477387 Merge pull request #91 from didi/dev
修复上报夜莺功能
2020-11-22 17:00:39 +08:00
zengqiao
bc4dac9cad 删除无效代码 2020-11-22 16:58:43 +08:00
zengqiao
36e3d6c18a 修复上报夜莺功能 2020-11-22 16:56:22 +08:00
ZQKC
edfd84a8e3 Merge pull request #88 from didi/dev
增加build.sh
2020-11-15 17:02:26 +08:00
zengqiao
fb20cf6069 增加build.sh 2020-11-15 16:58:28 +08:00
ZQKC
abbe47f6b9 Merge pull request #87 from didi/dev
初始化SQL优化&KCM修复&连接信息修复
2020-11-15 16:55:42 +08:00
zengqiao
f84d250134 kcm修复&连接信息接口修复 2020-11-15 16:50:59 +08:00
zengqiao
3ffb4b8990 初始化SQL优化 2020-11-15 16:31:10 +08:00
ZQKC
f70cfabede Merge pull request #84 from didi/dev
fix 前端资源加载问题
2020-11-14 16:56:16 +08:00
potaaato
3a81783d77 Merge pull request #83 from Candieslove/master
fix: remove track.js && add font.css
2020-11-13 14:04:41 +08:00
eilenexuzhe
237a4a90ff fix: remove track.js && add font.css 2020-11-13 11:58:46 +08:00
ZQKC
99c7dfc98d Merge pull request #81 from didi/dev
修复Topic详情中服务地址不展示问题
2020-11-08 20:13:03 +08:00
zengqiao
48aba34370 修复Topic详情中服务地址不展示问题 2020-11-08 20:07:45 +08:00
ZQKC
29cca36f2c Merge pull request #80 from didi/dev
增加上报监控指标开关
2020-11-08 17:14:50 +08:00
zengqiao
0f5819f5c2 增加上报监控指标开关 2020-11-08 17:13:04 +08:00
ZQKC
373772de2d Merge pull request #79 from didi/dev
文案优化|服务发现接口修复
2020-11-08 16:11:10 +08:00
zengqiao
7f5bbe8b5f 优化 2020-11-08 16:00:15 +08:00
zengqiao
daee57167b 服务发现接口修复 2020-11-08 15:59:50 +08:00
zengqiao
03467196b9 POM文件优化 2020-11-08 15:59:27 +08:00
zengqiao
d3f3531cdb 文案优化 2020-11-08 15:43:42 +08:00
ZQKC
883b694592 Merge pull request #78 from didi/dev
文档更新
2020-11-07 22:21:52 +08:00
zengqiao
6c89d66af9 文档更新 2020-11-07 22:09:22 +08:00
ZQKC
fb0a76b418 Merge pull request #77 from didi/master
master合并到dev
2020-11-07 22:02:24 +08:00
ZQKC
64f77fca5b Merge pull request #71 from didi/dev_2.x
开放接口
2020-10-26 22:53:53 +08:00
zengqiao
b1fca2c5be 删除无效代码 2020-10-26 11:23:28 +08:00
zengqiao
108d705f09 删除无效代码 2020-10-26 11:20:34 +08:00
zengqiao
a77242e66c 开放接口&近期BUG修复 2020-10-26 11:17:45 +08:00
ZQKC
8b153113ff Merge pull request #70 from didi/master
merge master
2020-10-26 10:45:56 +08:00
zengqiao
6d0ec37135 增加格式PDF文档防止图裂 2020-10-22 09:32:58 +08:00
ZQKC
603dadff35 Merge pull request #62 from didi/dev
统一依赖包版本
2020-09-29 17:32:32 +08:00
zengqiao
1a4ef3d9c1 统一pom包版本 2020-09-29 17:25:04 +08:00
ZQKC
788468054a Merge pull request #61 from didi/master
合并master分支
2020-09-29 17:16:52 +08:00
ZQKC
bdb44c6dce Merge pull request #59 from didi/dev_2.x
Dev 2.x
2020-09-29 10:47:16 +08:00
zengqiao
251086f9e9 问题修复: 修复账号搜索仅返回一个的问题 2020-09-28 21:52:50 +08:00
zengqiao
b22aa62046 修改console包版本 2020-09-28 17:31:08 +08:00
zengqiao
c6e4b60424 kafka-manager 2.0 2020-09-28 15:46:34 +08:00
1503 changed files with 97458 additions and 38297 deletions

16
.gitignore vendored
View File

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

View File

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

176
README.md
View File

@@ -1,135 +1,117 @@
---
![kafka-manager-logo](doc/assets/images/common/logo_name.png)
![logikm_logo](https://user-images.githubusercontent.com/71620349/125024570-9e07a100-e0b3-11eb-8ebc-22e73e056771.png)
**一站式`Apache Kafka`集群指标监控与运维管控平台**
---
`LogiKM开源至今备受关注考虑到开源项目应该更贴合Apache Kafka未来发展方向经项目组慎重考虑预计22年5月份将其品牌升级成Know Streaming届时项目名称和Logo也将统一更新感谢大家一如既往的支持敬请期待`
## 主要功能特性
阅读本README文档您可以了解到滴滴Logi-KafkaManager的用户群体、产品定位等信息并通过体验地址快速体验Kafka集群指标监控与运维管控的全流程。
### 集群监控维度
## 1 产品简介
滴滴Logi-KafkaManager脱胎于滴滴内部多年的Kafka运营实践经验是面向Kafka用户、Kafka运维人员打造的共享多租户Kafka云平台。专注于Kafka运维管控、监控告警、资源治理等核心场景经历过大规模集群、海量大数据的考验。内部满意度高达90%的同时,还与多家知名企业达成商业化合作。
- 多版本集群管控,支持从`0.10.2``2.4`版本;
- 集群Topic、Broker等多维度历史与实时关键指标查看
### 1.1 快速体验地址
- 体验地址 http://117.51.150.133:8080 账号密码 admin/admin
### 1.2 体验地图
相比较于同类产品的用户视角单一大多为管理员视角滴滴Logi-KafkaManager建立了基于分角色、多场景视角的体验地图。分别是**用户体验地图、运维体验地图、运营体验地图**
#### 1.2.1 用户体验地图
- 平台租户申请  申请应用App作为Kafka中的用户名并用 AppID+password作为身份验证
- 集群资源申请  :按需申请、按需使用。可使用平台提供的共享集群,也可为应用申请独立的集群
- Topic        可根据应用App创建Topic或者申请其他topic的读写权限
- Topic        Topic数据采样、调整配额、申请分区等操作
-          基于Topic生产消费各环节耗时统计监控不同分位数性能指标
-     :支持将消费偏移重置至指定时间或指定位置
#### 1.2.2 运维体验地图
- 多版本集群管控  :支持从`0.10.2``2.x`版本
-             集群Topic、Broker等多维度历史与实时关键指标查看建立健康分体系
-             划分部分Broker作为Region使用Region定义资源划分单位并按照业务、保障能力区分逻辑集群
- Broker          :包括优先副本选举等操作
- Topic            :包括创建、查询、扩容、修改属性、迁移、下线等
### 集群管控维度
#### 1.2.3 运营体验地图
-        沉淀资源治理方法。针对Topic分区热点、分区不足等高频常见问题沉淀资源治理方法实现资源治理专家化
-        工单体系。Topic创建、调整配额、申请分区等操作由专业运维人员审批规范资源使用保障平台平稳运行
-        成本控制。Topic资源、集群资源按需申请、按需使用。根据流量核算费用帮助企业建设大数据成本核算体系
- 集群运维包括逻辑Region方式管理集群
- Broker运维包括优先副本选举
- Topic运维包括创建、查询、扩容、修改属性、数据采样及迁移等
- 消费组运维,包括指定时间或指定偏移两种方式进行重置消费偏移;
### 1.3 核心优势
-         :监控多项核心指标,统计不同分位数据,提供种类丰富的指标监控报表,帮助用户、运维人员快速高效定位问题
- 便        按照Region定义集群资源划分单位将逻辑集群根据保障等级划分。在方便资源隔离、提高扩展能力的同时实现对服务端的强管控
-         基于滴滴内部多年运营实践沉淀资源治理方法建立健康分体系。针对Topic分区热点、分区不足等高频常见问题实现资源治理专家化
-        :与滴滴夜莺监控告警系统打通,集成监控告警、集群部署、集群升级等能力。形成运维生态,凝练专家服务,使运维更高效
### 1.4 滴滴Logi-KafkaManager架构图
![kafka-manager-arch](https://img-ys011.didistatic.com/static/dicloudpub/do1_xgDHNDLj2ChKxctSuf72)
### 用户使用维度
## 2 相关文档
- 管理员用户与普通用户视角区分;
- 管理员用户与普通用户权限区分;
### 2.1 产品文档
- [滴滴LogiKM 安装手册](docs/install_guide/install_guide_cn.md)
- [滴滴LogiKM 接入集群](docs/user_guide/add_cluster/add_cluster.md)
- [滴滴LogiKM 用户使用手册](docs/user_guide/user_guide_cn.md)
- [滴滴LogiKM FAQ](docs/user_guide/faq.md)
---
## kafka-manager架构图
![kafka-manager-arch](doc/assets/images/common/arch.png)
### 2.2 社区文章
- [滴滴云官网产品介绍](https://www.didiyun.com/production/logi-KafkaManager.html)
- [7年沉淀之作--滴滴Logi日志服务套件](https://mp.weixin.qq.com/s/-KQp-Qo3WKEOc9wIR2iFnw)
- [滴滴LogiKM 一站式Kafka监控与管控平台](https://mp.weixin.qq.com/s/9qSZIkqCnU6u9nLMvOOjIQ)
- [滴滴LogiKM 开源之路](https://xie.infoq.cn/article/0223091a99e697412073c0d64)
- [滴滴LogiKM 系列视频教程](https://space.bilibili.com/442531657/channel/seriesdetail?sid=571649)
- [kafka最强最全知识图谱](https://www.szzdzhp.com/kafka/)
- [滴滴LogiKM新用户入门系列文章专栏 --石臻臻](https://www.szzdzhp.com/categories/LogIKM/)
- [kafka实践十五滴滴开源Kafka管控平台 LogiKM研究--A叶子叶来](https://blog.csdn.net/yezonggang/article/details/113106244)
---
## 3 滴滴Logi开源用户交流群
## 安装手册
![image](https://user-images.githubusercontent.com/5287750/111266722-e531d800-8665-11eb-9242-3484da5a3099.png)
### 环境依赖
想跟各个大佬交流Kafka Es 等中间件/大数据相关技术请 加微信进群。
- `Maven 3.5.0+`(后端打包依赖)
- `node v8.12.0+`(前端打包依赖)
- `Java 8+`(运行环境需要)
- `MySQL``PostgreSQL`(数据存储)
微信加群:添加<font color=red>mike_zhangliang</font><font color=red>danke-xie</font>的微信号备注Logi加群或关注公众号 云原生可观测性 回复 "Logi加群"
---
## 4 知识星球
### 环境初始化
<img width="447" alt="image" src="https://user-images.githubusercontent.com/71620349/147314042-843a371a-48c0-4d9a-a65e-ca40236f3300.png">
**MySQL**
<br>
<center>
✅我们正在组建国内最大最权威的
</center>
<br>
<center>
<font color=red size=5><b>【Kafka中文社区】</b></font>
</center>
在这里你可以结交各大互联网Kafka大佬以及近2000+Kafka爱好者一起实现知识共享实时掌控最新行业资讯期待您的加入中https://z.didi.cn/5gSF9
执行[create_mysql_table.sql](doc/create_mysql_table.sql)中的SQL命令从而创建所需的MySQL库及表默认创建的库名是`kafka_manager`
<font color=red size=5>有问必答~ </font>
```
############# 示例:
mysql -uXXXX -pXXX -h XXX.XXX.XXX.XXX -PXXXX < ./create_mysql_table.sql
```
<font color=red size=5>互动有礼~ </font>
**PostgreSQL**
PS:提问请尽量把问题一次性描述清楚,并告知环境信息情况哦~!如使用版本、操作步骤、报错/警告信息等方便大V们快速解答
执行[create_postgresql_table.sql](doc/create_postgresql_table.sql)中的SQL命令从而创建所需的PostgreSQL表。
## 5 项目成员
```
############# 示例:
psql -h XXX.XXX.XXX.XXX -U XXXX -d kafka_manager -f ./create_postgresql_table.sql
```
### 5.1 内部核心人员
*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` 配置文件。***
---
`iceyuhui``liuyaguang``limengmonty``zhangliangmike``xiepeng``nullhuangyiming``zengqiao``eilenexuzhe``huangjiaweihjw``zhaoyinrui``marzkonglingxu``joysunchao``石臻臻`
### 打包
执行`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)
## 钉钉交流群
搜索群号:`32821440` 或者扫码可入群交流. 备注:在钉钉搜索框搜索`32821440`,然后搜索结果中点击 "网络查找手机/邮箱/钉钉号" 即可看到我们的钉钉群滴滴KafkaManager开源用户群。
![dingding_group](doc/assets/images/common/dingding_group.jpg)
## 项目成员
### 内部核心人员
`iceyuhui``liuyaguang``limengmonty``zhangliangmike``nullhuangyiming``zengqiao``eilenexuzhe``huangjiaweihjw`
### 外部贡献者
### 5.2 外部贡献者
`fangjunyu``zhoutaiyang`
## 协议
## 6 协议
`kafka-manager`基于`Apache-2.0`协议进行分发和使用,更多信息参见[协议文件](./LICENSE)
`LogiKM`基于`Apache-2.0`协议进行分发和使用,更多信息参见[协议文件](./LICENSE)

174
Releases_Notes.md Normal file
View File

@@ -0,0 +1,174 @@
---
![kafka-manager-logo](./docs/assets/images/common/logo_name.png)
**一站式`Apache Kafka`集群指标监控与运维管控平台**
---
## v2.6.0
版本上线时间2022-01-24
### 能力提升
- 增加简单回退工具类
### 体验优化
- 补充周期任务说明文档
- 补充集群安装部署使用说明文档
- 升级Swagger、SpringFramework、SpringBoot、EChats版本
- 优化Task模块的日志输出
- 优化corn表达式解析失败后退出无任何日志提示问题
- Ldap用户接入时增加部门及邮箱信息等
- 对Jmx模块增加连接失败后的回退机制及错误日志优化
- 增加线程池、客户端池可配置
- 删除无用的jmx_prometheus_javaagent-0.14.0.jar
- 优化迁移任务名称
- 优化创建Region时Region容量信息不能立即被更新问题
- 引入lombok
- 更新视频教程
- 优化kcm_script.sh脚本中的LogiKM地址为可通过程序传入
- 第三方接口及网关接口,增加是否跳过登录的开关
- extends模块相关配置调整为非必须在application.yml中配置
### bug修复
- 修复批量往DB写入空指标数组时报SQL语法异常的问题
- 修复网关增加配置及修改配置时version不变化问题
- 修复集群列表页,提示框遮挡问题
- 修复对高版本Broker元信息协议解析失败的问题
- 修复Dockerfile执行时提示缺少application.yml文件的问题
- 修复逻辑集群更新时,会报空指针的问题
## v2.4.1+
版本上线时间2021-05-21
### 能力提升
- 增加直接增加权限和配额的接口(v2.4.1)
- 增加接口调用可绕过登录的功能(v2.4.1)
### 体验优化
- tomcat 版本提升至8.5.66(v2.4.2)
- op接口优化拆分util接口为topic、leader两类接口(v2.4.1)
- 简化Gateway配置的Key长度(v2.4.1)
### bug修复
- 修复页面展示版本错误问题(v2.4.2)
## v2.4.0
版本上线时间2021-05-18
### 能力提升
- 增加App与Topic自动化审批开关
- Broker元信息中增加Rack信息
- 升级MySQL 驱动支持MySQL 8+
- 增加操作记录查询界面
### 体验优化
- FAQ告警组说明优化
- 用户手册共享及 独享集群概念优化
- 用户管理界面,前端限制用户删除自己
### bug修复
- 修复op-util类中创建Topic失败的接口
- 周期同步Topic到DB的任务修复将Topic列表查询从缓存调整为直接查DB
- 应用下线审批失败的功能修复将权限为0(无权限)的数据进行过滤
- 修复登录及权限绕过的漏洞
- 修复研发角色展示接入集群、暂停监控等按钮的问题
## v2.3.0
版本上线时间2021-02-08
### 能力提升
- 新增支持docker化部署
- 可指定Broker作为候选controller
- 可新增并管理网关配置
- 可获取消费组状态
- 增加集群的JMX认证
### 体验优化
- 优化编辑用户角色、修改密码的流程
- 新增consumerID的搜索功能
- 优化“Topic连接信息”、“消费组重置消费偏移”、“修改Topic保存时间”的文案提示
- 在相应位置增加《资源申请文档》链接
### bug修复
- 修复Broker监控图表时间轴展示错误的问题
- 修复创建夜莺监控告警规则时,使用的告警周期的单位不正确的问题
## v2.2.0
版本上线时间2021-01-25
### 能力提升
- 优化工单批量操作流程
- 增加获取Topic75分位/99分位的实时耗时数据
- 增加定时任务可将无主未落DB的Topic定期写入DB
### 体验优化
- 在相应位置增加《集群接入文档》链接
- 优化物理集群、逻辑集群含义
- 在Topic详情页、Topic扩分区操作弹窗增加展示Topic所属Region的信息
- 优化Topic审批时Topic数据保存时间的配置流程
- 优化Topic/应用申请、审批时的错误提示文案
- 优化Topic数据采样的操作项文案
- 优化运维人员删除Topic时的提示文案
- 优化运维人员删除Region的删除逻辑与提示文案
- 优化运维人员删除逻辑集群的提示文案
- 优化上传集群配置文件时的文件类型限制条件
### bug修复
- 修复填写应用名称时校验特殊字符出错的问题
- 修复普通用户越权访问应用详情的问题
- 修复由于Kafka版本升级导致的数据压缩格式无法获取的问题
- 修复删除逻辑集群或Topic之后界面依旧展示的问题
- 修复进行Leader rebalance操作时执行结果重复提示的问题
## v2.1.0
版本上线时间2020-12-19
### 体验优化
- 优化页面加载时的背景样式
- 优化普通用户申请Topic权限的流程
- 优化Topic申请配额、申请分区的权限限制
- 优化取消Topic权限的文案提示
- 优化申请配额表单的表单项名称
- 优化重置消费偏移的操作流程
- 优化创建Topic迁移任务的表单内容
- 优化Topic扩分区操作的弹窗界面样式
- 优化集群Broker监控可视化图表样式
- 优化创建逻辑集群的表单内容
- 优化集群安全协议的提示文案
### bug修复
- 修复偶发性重置消费偏移失败的问题

View File

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

View File

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

View File

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

View File

@@ -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; //操作部分成功
}

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -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 + '\'' +
'}';
}
}

View File

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

View File

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

View File

@@ -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 + '\'' +
'}';
}
}

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -1,132 +0,0 @@
package com.xiaojukeji.kafka.manager.common.entity.zookeeper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.List;
/**
* @author zengqiao
* @date 19/4/3
*
* 存储Broker的元信息, 元信息对应的ZK节点是/brokers/ids/{brokerId}
* 节点结构:
* {
* "listener_security_protocol_map":{"SASL_PLAINTEXT":"SASL_PLAINTEXT"},
* "endpoints":["SASL_PLAINTEXT://10.179.162.202:9093"],
* "jmx_port":9999,
* "host":null,
* "timestamp":"1546632983233",
* "port":-1,
* "version":4
* }
*/
public class BrokerMetadata implements Cloneable {
private final static Logger LOGGER = LoggerFactory.getLogger(TopicMetadata.class);
private long clusterId;
private int brokerId;
private List<String> endpoints;
private String host;
private int port;
//zk上字段对应
private int jmx_port;
private String version;
private long timestamp;
public long getClusterId() {
return clusterId;
}
public void setClusterId(long clusterId) {
this.clusterId = clusterId;
}
public int getBrokerId() {
return brokerId;
}
public void setBrokerId(int brokerId) {
this.brokerId = brokerId;
}
public List<String> getEndpoints() {
return endpoints;
}
public void setEndpoints(List<String> endpoints) {
this.endpoints = endpoints;
}
public String getHost() {
return host;
}
public void setHost(String host) {
this.host = host;
}
public int getPort() {
return port;
}
public void setPort(int port) {
this.port = port;
}
public int getJmxPort() {
return jmx_port;
}
public void setJmxPort(int jmxPort) {
this.jmx_port = jmxPort;
}
public String getVersion() {
return version;
}
public void setVersion(String version) {
this.version = version;
}
public long getTimestamp() {
return timestamp;
}
public void setTimestamp(long timestamp) {
this.timestamp = timestamp;
}
@Override
public Object clone() {
try {
return super.clone();
} catch (CloneNotSupportedException var3) {
LOGGER.error("clone BrokerMetadata failed.", var3);
}
return null;
}
@Override
public String toString() {
return "BrokerMetadata{" +
"clusterId=" + clusterId +
", brokerId=" + brokerId +
", endpoints=" + endpoints +
", host='" + host + '\'' +
", port=" + port +
", jmxPort=" + jmx_port +
", version='" + version + '\'' +
", timestamp=" + timestamp +
'}';
}
}

View File

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

View File

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

View File

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

View File

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

View File

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

File diff suppressed because it is too large Load Diff

View File

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

View File

@@ -1,8 +0,0 @@
.content-container .table-operation-bar.in-panel {
position: static;
text-align: right;
.new-topic {
margin-right: 0;
margin-left: 30px;
}
}

View File

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

View File

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

View File

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

View File

@@ -1,9 +0,0 @@
.right-flow {
.k-abs {
right: 24px;
cursor: pointer;
& > i {
margin-right: 5px;
}
}
}

View File

@@ -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}&#4`}>{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>
</>
);
}
}

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -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 InMB/ 秒)',
bytesOut: 'Bytes OutMB/ 秒)',
messagesIn: 'Messages In条)',
totalFetchRequests: 'Total Fetch RequestsQPS)',
totalProduceRequests: 'Total Produce RequestsQPS)',
};

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -1,5 +0,0 @@
export const selecOptions = {
partitionCount: '分区数量',
leaderCount: 'leader数量',
notUnderReplicatedPartitionCount: '副本状态',
};

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

Some files were not shown because too many files have changed in this diff Show More