From cef1ec95d295ea3bf1b89c5d8821e155d909fa6b Mon Sep 17 00:00:00 2001 From: huyueeer Date: Wed, 4 Aug 2021 14:14:53 +0800 Subject: [PATCH 01/19] =?UTF-8?q?LDAP=E9=AA=8C=E8=AF=81=E5=BF=BD=E7=95=A5?= =?UTF-8?q?=E8=B4=A6=E6=88=B7=E5=A4=A7=E5=B0=8F=E5=86=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../kafka/manager/account/component/sso/BaseSessionSignOn.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/kafka-manager-extends/kafka-manager-account/src/main/java/com/xiaojukeji/kafka/manager/account/component/sso/BaseSessionSignOn.java b/kafka-manager-extends/kafka-manager-account/src/main/java/com/xiaojukeji/kafka/manager/account/component/sso/BaseSessionSignOn.java index 1ff36964..bf2d29dc 100644 --- a/kafka-manager-extends/kafka-manager-account/src/main/java/com/xiaojukeji/kafka/manager/account/component/sso/BaseSessionSignOn.java +++ b/kafka-manager-extends/kafka-manager-account/src/main/java/com/xiaojukeji/kafka/manager/account/component/sso/BaseSessionSignOn.java @@ -52,6 +52,8 @@ public class BaseSessionSignOn extends AbstractSingleSignOn { //判断是否激活了LDAP验证, 若激活则也可使用ldap进行认证 if(!ValidateUtils.isNull(accountLdapEnabled) && accountLdapEnabled){ + //基于LDAP的登陆用户忽略大小写账户,统一做大写处理 + dto.setUsername(dto.getUsername().toUpperCase()); //去LDAP验证账密 if(!ldapAuthentication.authenticate(dto.getUsername(),dto.getPassword())){ return Result.buildFrom(ResultStatus.LDAP_AUTHENTICATION_FAILED); From 793e81406ec8a36a28376b45f9a5c010d0ea1597 Mon Sep 17 00:00:00 2001 From: huyueeer Date: Wed, 4 Aug 2021 16:23:57 +0800 Subject: [PATCH 02/19] =?UTF-8?q?LDAP=E8=AE=A4=E8=AF=81=E5=BF=BD=E7=95=A5?= =?UTF-8?q?=E5=A4=A7=E5=B0=8F=E5=86=99=EF=BC=8C=E4=BF=AE=E6=AD=A3=E4=BB=8E?= =?UTF-8?q?LDAP=E6=9C=8D=E5=8A=A1=E5=99=A8=E8=BF=94=E5=9B=9E=E5=80=BC?= =?UTF-8?q?=E8=AE=BE=E7=BD=AEUsername?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../manager/common/utils/SplitUtils.java | 14 +++++++ .../component/ldap/LdapAuthentication.java | 40 ++++++++++++++----- .../component/sso/BaseSessionSignOn.java | 9 +++-- 3 files changed, 49 insertions(+), 14 deletions(-) create mode 100644 kafka-manager-common/src/main/java/com/xiaojukeji/kafka/manager/common/utils/SplitUtils.java diff --git a/kafka-manager-common/src/main/java/com/xiaojukeji/kafka/manager/common/utils/SplitUtils.java b/kafka-manager-common/src/main/java/com/xiaojukeji/kafka/manager/common/utils/SplitUtils.java new file mode 100644 index 00000000..d3692d96 --- /dev/null +++ b/kafka-manager-common/src/main/java/com/xiaojukeji/kafka/manager/common/utils/SplitUtils.java @@ -0,0 +1,14 @@ +package com.xiaojukeji.kafka.manager.common.utils; + +/** + * @className: SplitUtils + * @description: Split string of type keyValue + * @author: Hu.Yue + * @date: 2021/8/4 + **/ +public class SplitUtils { + + public static String keyValueSplit(String keyValue){ + return keyValue.split(":\\s+")[1]; + } +} diff --git a/kafka-manager-extends/kafka-manager-account/src/main/java/com/xiaojukeji/kafka/manager/account/component/ldap/LdapAuthentication.java b/kafka-manager-extends/kafka-manager-account/src/main/java/com/xiaojukeji/kafka/manager/account/component/ldap/LdapAuthentication.java index f456c916..4dde4083 100644 --- a/kafka-manager-extends/kafka-manager-account/src/main/java/com/xiaojukeji/kafka/manager/account/component/ldap/LdapAuthentication.java +++ b/kafka-manager-extends/kafka-manager-account/src/main/java/com/xiaojukeji/kafka/manager/account/component/ldap/LdapAuthentication.java @@ -1,5 +1,6 @@ package com.xiaojukeji.kafka.manager.account.component.ldap; +import com.xiaojukeji.kafka.manager.common.utils.SplitUtils; import com.xiaojukeji.kafka.manager.common.utils.ValidateUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -14,7 +15,9 @@ import javax.naming.directory.SearchControls; import javax.naming.directory.SearchResult; import javax.naming.ldap.InitialLdapContext; import javax.naming.ldap.LdapContext; +import java.util.HashMap; import java.util.Hashtable; +import java.util.Map; @Component public class LdapAuthentication { @@ -60,8 +63,11 @@ public class LdapAuthentication { return null; } - private String getUserDN(String account, LdapContext ctx) { + private Map getLdapAttrsInfo(String account, LdapContext ctx) { + //存储更多的LDAP元信息 + Map ldapAttrsInfo = new HashMap<>(); String userDN = ""; + ldapAttrsInfo.clear(); try { SearchControls constraints = new SearchControls(); constraints.setSearchScope(SearchControls.SUBTREE_SCOPE); @@ -69,7 +75,7 @@ public class LdapAuthentication { NamingEnumeration en = ctx.search("", filter, constraints); if (en == null || !en.hasMoreElements()) { - return ""; + return null; } // maybe more than one element while (en.hasMoreElements()) { @@ -78,13 +84,25 @@ public class LdapAuthentication { SearchResult si = (SearchResult) obj; userDN += si.getName(); userDN += "," + ldapBasedn; + //携带LDAP更多元信息以填充用户元信息 + ldapAttrsInfo.put("userDN", userDN); + ldapAttrsInfo.put("sAMAccountName", + SplitUtils.keyValueSplit(si.getAttributes().get("samaccountname").toString())); + ldapAttrsInfo.put("department", + SplitUtils.keyValueSplit(si.getAttributes().get("department").toString())); + ldapAttrsInfo.put("company", + SplitUtils.keyValueSplit(si.getAttributes().get("company").toString())); + ldapAttrsInfo.put("displayName", + SplitUtils.keyValueSplit(si.getAttributes().get("displayname").toString())); + ldapAttrsInfo.put("mail", + SplitUtils.keyValueSplit(si.getAttributes().get("mail").toString())); break; } } } catch (Exception e) { LOGGER.error("class=LdapAuthentication||method=getUserDN||account={}||errMsg={}", account, e); } - return userDN; + return ldapAttrsInfo; } /** @@ -93,23 +111,23 @@ public class LdapAuthentication { * @param password * @return */ - public boolean authenticate(String account, String password) { + public Map authenticate(String account, String password) { LdapContext ctx = getLdapContext(); if (ValidateUtils.isNull(ctx)) { - return false; + return null; } try { - String userDN = getUserDN(account, ctx); - if(ValidateUtils.isBlank(userDN)){ - return false; + Map ldapAttrsInfo = getLdapAttrsInfo(account, ctx); + if(ValidateUtils.isNull(ldapAttrsInfo)){ + return null; } - ctx.addToEnvironment(Context.SECURITY_PRINCIPAL, userDN); + ctx.addToEnvironment(Context.SECURITY_PRINCIPAL, ldapAttrsInfo.get("userDN").toString()); ctx.addToEnvironment(Context.SECURITY_CREDENTIALS, password); ctx.reconnect(null); - return true; + return ldapAttrsInfo; } catch (AuthenticationException e) { LOGGER.warn("class=LdapAuthentication||method=authenticate||account={}||errMsg={}", account, e); } catch (NamingException e) { @@ -125,6 +143,6 @@ public class LdapAuthentication { } } } - return false; + return null; } } diff --git a/kafka-manager-extends/kafka-manager-account/src/main/java/com/xiaojukeji/kafka/manager/account/component/sso/BaseSessionSignOn.java b/kafka-manager-extends/kafka-manager-account/src/main/java/com/xiaojukeji/kafka/manager/account/component/sso/BaseSessionSignOn.java index bf2d29dc..bb5f415c 100644 --- a/kafka-manager-extends/kafka-manager-account/src/main/java/com/xiaojukeji/kafka/manager/account/component/sso/BaseSessionSignOn.java +++ b/kafka-manager-extends/kafka-manager-account/src/main/java/com/xiaojukeji/kafka/manager/account/component/sso/BaseSessionSignOn.java @@ -17,6 +17,7 @@ import org.springframework.stereotype.Service; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; +import java.util.Map; /** * @author zengqiao @@ -52,15 +53,17 @@ public class BaseSessionSignOn extends AbstractSingleSignOn { //判断是否激活了LDAP验证, 若激活则也可使用ldap进行认证 if(!ValidateUtils.isNull(accountLdapEnabled) && accountLdapEnabled){ - //基于LDAP的登陆用户忽略大小写账户,统一做大写处理 - dto.setUsername(dto.getUsername().toUpperCase()); //去LDAP验证账密 - if(!ldapAuthentication.authenticate(dto.getUsername(),dto.getPassword())){ + Map ldapAttrsInfo; + ldapAttrsInfo = ldapAuthentication.authenticate(dto.getUsername(),dto.getPassword()); + if(ValidateUtils.isNull(ldapAttrsInfo)){ return Result.buildFrom(ResultStatus.LDAP_AUTHENTICATION_FAILED); } if((ValidateUtils.isNull(accountResult) || ValidateUtils.isNull(accountResult.getData())) && authUserRegistration){ //自动注册 + //使用Ldap:sAMAccountName替换用户输入的值 + dto.setUsername(ldapAttrsInfo.get("sAMAccountName").toString()); AccountDO accountDO = new AccountDO(); accountDO.setUsername(dto.getUsername()); accountDO.setRole(AccountRoleEnum.getUserRoleEnum(authUserRegistrationRole).getRole()); From b77345222c34be19a6c8a39e636ce1a2119cd956 Mon Sep 17 00:00:00 2001 From: huyueeer Date: Thu, 5 Aug 2021 11:17:38 +0800 Subject: [PATCH 03/19] =?UTF-8?q?LDAP=E8=AE=A4=E8=AF=81=E5=BF=BD=E7=95=A5?= =?UTF-8?q?=E5=A4=A7=E5=B0=8F=E5=86=99=EF=BC=8C=E4=BF=AE=E6=AD=A3=E5=88=A4?= =?UTF-8?q?=E6=96=AD=E9=A1=BA=E5=BA=8F=EF=BC=8C=E7=9B=B8=E5=90=8CLDAP?= =?UTF-8?q?=E7=94=A8=E6=88=B7=E5=8F=8D=E5=A4=8DREPLACE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../account/component/sso/BaseSessionSignOn.java | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/kafka-manager-extends/kafka-manager-account/src/main/java/com/xiaojukeji/kafka/manager/account/component/sso/BaseSessionSignOn.java b/kafka-manager-extends/kafka-manager-account/src/main/java/com/xiaojukeji/kafka/manager/account/component/sso/BaseSessionSignOn.java index bb5f415c..c64a1717 100644 --- a/kafka-manager-extends/kafka-manager-account/src/main/java/com/xiaojukeji/kafka/manager/account/component/sso/BaseSessionSignOn.java +++ b/kafka-manager-extends/kafka-manager-account/src/main/java/com/xiaojukeji/kafka/manager/account/component/sso/BaseSessionSignOn.java @@ -48,22 +48,22 @@ public class BaseSessionSignOn extends AbstractSingleSignOn { if (ValidateUtils.isBlank(dto.getUsername()) || ValidateUtils.isNull(dto.getPassword())) { return Result.buildFailure("Missing parameters"); } - - Result accountResult = accountService.getAccountDO(dto.getUsername()); + //先创建空对象,看是在LDAP去做填充,还是直接查表填充 + Result accountResult; //判断是否激活了LDAP验证, 若激活则也可使用ldap进行认证 if(!ValidateUtils.isNull(accountLdapEnabled) && accountLdapEnabled){ //去LDAP验证账密 - Map ldapAttrsInfo; - ldapAttrsInfo = ldapAuthentication.authenticate(dto.getUsername(),dto.getPassword()); + Map ldapAttrsInfo = ldapAuthentication.authenticate(dto.getUsername(),dto.getPassword());; if(ValidateUtils.isNull(ldapAttrsInfo)){ return Result.buildFrom(ResultStatus.LDAP_AUTHENTICATION_FAILED); } + //LDAP验证通过,拿LDAP的sAMAccountName替换dto对象的值,便于第一次自动注册采用LDAP值,并且第二次也避免REPLACE + dto.setUsername(ldapAttrsInfo.get("sAMAccountName").toString()); + accountResult = accountService.getAccountDO(dto.getUsername()); if((ValidateUtils.isNull(accountResult) || ValidateUtils.isNull(accountResult.getData())) && authUserRegistration){ //自动注册 - //使用Ldap:sAMAccountName替换用户输入的值 - dto.setUsername(ldapAttrsInfo.get("sAMAccountName").toString()); AccountDO accountDO = new AccountDO(); accountDO.setUsername(dto.getUsername()); accountDO.setRole(AccountRoleEnum.getUserRoleEnum(authUserRegistrationRole).getRole()); @@ -73,6 +73,8 @@ public class BaseSessionSignOn extends AbstractSingleSignOn { return Result.buildSuc(dto.getUsername()); } + //不走LDAP认证直接查表填充 + accountResult = accountService.getAccountDO(dto.getUsername()); if (ValidateUtils.isNull(accountResult) || accountResult.failed()) { return new Result<>(accountResult.getCode(), accountResult.getMessage()); From b5fb24b36032c4e3c57b076102895d97a819a8a5 Mon Sep 17 00:00:00 2001 From: huyueeer Date: Fri, 6 Aug 2021 11:40:24 +0800 Subject: [PATCH 04/19] =?UTF-8?q?=E6=9C=AC=E5=9C=B0=E8=AE=A4=E8=AF=81?= =?UTF-8?q?=E6=88=96LDAP=E8=AE=A4=E8=AF=81=E6=94=AF=E6=8C=81=E6=90=BA?= =?UTF-8?q?=E5=B8=A6=E2=80=98=E5=A7=93=E5=90=8D=E2=80=99=E3=80=81=E2=80=98?= =?UTF-8?q?=E9=83=A8=E9=97=A8=E2=80=99=E3=80=81=E2=80=98=E9=82=AE=E7=AE=B1?= =?UTF-8?q?=E2=80=99=E7=AD=89=E7=94=A8=E6=88=B7=E5=85=83=E4=BF=A1=E6=81=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/install_guide/create_mysql_table.sql | 3 ++ .../common/entity/dto/rd/AccountDTO.java | 36 ++++++++++++++++ .../manager/common/entity/pojo/AccountDO.java | 41 +++++++++++++++++-- .../src/main/resources/mapper/AccountDao.xml | 7 +++- .../component/sso/BaseSessionSignOn.java | 3 ++ .../web/converters/AccountConverter.java | 3 ++ 6 files changed, 87 insertions(+), 6 deletions(-) diff --git a/docs/install_guide/create_mysql_table.sql b/docs/install_guide/create_mysql_table.sql index 12910ae1..05a99278 100644 --- a/docs/install_guide/create_mysql_table.sql +++ b/docs/install_guide/create_mysql_table.sql @@ -16,6 +16,9 @@ CREATE TABLE `account` ( `status` int(16) NOT NULL DEFAULT '0' COMMENT '0标识使用中,-1标识已废弃', `gmt_create` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', `gmt_modify` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '修改时间', + `department` varchar(128) DEFAULT '' COMMENT '部门名', + `display_name` varchar(128) DEFAULT '' COMMENT '用户姓名', + `mail` varchar(128) DEFAULT '' COMMENT '邮箱', PRIMARY KEY (`id`), UNIQUE KEY `uniq_username` (`username`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='账号表'; diff --git a/kafka-manager-common/src/main/java/com/xiaojukeji/kafka/manager/common/entity/dto/rd/AccountDTO.java b/kafka-manager-common/src/main/java/com/xiaojukeji/kafka/manager/common/entity/dto/rd/AccountDTO.java index db2b0aff..ab1147a3 100644 --- a/kafka-manager-common/src/main/java/com/xiaojukeji/kafka/manager/common/entity/dto/rd/AccountDTO.java +++ b/kafka-manager-common/src/main/java/com/xiaojukeji/kafka/manager/common/entity/dto/rd/AccountDTO.java @@ -21,6 +21,15 @@ public class AccountDTO { @ApiModelProperty(value = "角色") private Integer role; + @ApiModelProperty(value = "用户姓名") + private String displayName; + + @ApiModelProperty(value = "部门") + private String department; + + @ApiModelProperty(value = "邮箱") + private String mail; + public String getUsername() { return username; } @@ -45,12 +54,39 @@ public class AccountDTO { this.role = role; } + public String getDisplayName() { + return displayName; + } + + public void setDisplayName(String displayName) { + this.displayName = displayName; + } + + public String getDepartment() { + return department; + } + + public void setDepartment(String department) { + this.department = department; + } + + public String getMail() { + return mail; + } + + public void setMail(String mail) { + this.mail = mail; + } + @Override public String toString() { return "AccountDTO{" + "username='" + username + '\'' + ", password='" + password + '\'' + ", role=" + role + + ", displayName='" + displayName + '\'' + + ", department='" + department + '\'' + + ", mail='" + mail + '\'' + '}'; } diff --git a/kafka-manager-common/src/main/java/com/xiaojukeji/kafka/manager/common/entity/pojo/AccountDO.java b/kafka-manager-common/src/main/java/com/xiaojukeji/kafka/manager/common/entity/pojo/AccountDO.java index 13623941..1fa25528 100644 --- a/kafka-manager-common/src/main/java/com/xiaojukeji/kafka/manager/common/entity/pojo/AccountDO.java +++ b/kafka-manager-common/src/main/java/com/xiaojukeji/kafka/manager/common/entity/pojo/AccountDO.java @@ -21,6 +21,12 @@ public class AccountDO { private Integer role; + private String displayName; + + private String department; + + private String mail; + public String getUsername() { return username; } @@ -45,16 +51,43 @@ public class AccountDO { this.role = role; } + public String getDisplayName() { + return displayName; + } + + public void setDisplayName(String displayName) { + this.displayName = displayName; + } + + public String getDepartment() { + return department; + } + + public void setDepartment(String department) { + this.department = department; + } + + public String getMail() { + return mail; + } + + public void setMail(String mail) { + this.mail = mail; + } + @Override public String toString() { return "AccountDO{" + - "username='" + username + '\'' + - ", password='" + password + '\'' + - ", role=" + role + - ", id=" + id + + "id=" + id + ", status=" + status + ", gmtCreate=" + gmtCreate + ", gmtModify=" + gmtModify + + ", username='" + username + '\'' + + ", password='" + password + '\'' + + ", role=" + role + + ", displayName='" + displayName + '\'' + + ", department='" + department + '\'' + + ", mail='" + mail + '\'' + '}'; } } \ No newline at end of file diff --git a/kafka-manager-dao/src/main/resources/mapper/AccountDao.xml b/kafka-manager-dao/src/main/resources/mapper/AccountDao.xml index ac920416..3401ae75 100644 --- a/kafka-manager-dao/src/main/resources/mapper/AccountDao.xml +++ b/kafka-manager-dao/src/main/resources/mapper/AccountDao.xml @@ -10,14 +10,17 @@ + + + diff --git a/kafka-manager-extends/kafka-manager-account/src/main/java/com/xiaojukeji/kafka/manager/account/component/sso/BaseSessionSignOn.java b/kafka-manager-extends/kafka-manager-account/src/main/java/com/xiaojukeji/kafka/manager/account/component/sso/BaseSessionSignOn.java index c64a1717..3ccbd17c 100644 --- a/kafka-manager-extends/kafka-manager-account/src/main/java/com/xiaojukeji/kafka/manager/account/component/sso/BaseSessionSignOn.java +++ b/kafka-manager-extends/kafka-manager-account/src/main/java/com/xiaojukeji/kafka/manager/account/component/sso/BaseSessionSignOn.java @@ -68,6 +68,9 @@ public class BaseSessionSignOn extends AbstractSingleSignOn { accountDO.setUsername(dto.getUsername()); accountDO.setRole(AccountRoleEnum.getUserRoleEnum(authUserRegistrationRole).getRole()); accountDO.setPassword(dto.getPassword()); + accountDO.setDisplayName(ldapAttrsInfo.get("displayName").toString()); + accountDO.setDepartment(ldapAttrsInfo.get("department").toString()); + accountDO.setMail(ldapAttrsInfo.get("mail").toString()); accountService.createAccount(accountDO); } diff --git a/kafka-manager-web/src/main/java/com/xiaojukeji/kafka/manager/web/converters/AccountConverter.java b/kafka-manager-web/src/main/java/com/xiaojukeji/kafka/manager/web/converters/AccountConverter.java index a7eebff4..b774a718 100644 --- a/kafka-manager-web/src/main/java/com/xiaojukeji/kafka/manager/web/converters/AccountConverter.java +++ b/kafka-manager-web/src/main/java/com/xiaojukeji/kafka/manager/web/converters/AccountConverter.java @@ -18,6 +18,9 @@ public class AccountConverter { accountDO.setUsername(dto.getUsername()); accountDO.setPassword(dto.getPassword()); accountDO.setRole(dto.getRole()); + accountDO.setDepartment(dto.getDepartment()); + accountDO.setMail(dto.getMail()); + accountDO.setDisplayName(dto.getDisplayName()); return accountDO; } From fffc0c3add5627639c1a405770564f6c6280b0ab Mon Sep 17 00:00:00 2001 From: huyueeer Date: Thu, 12 Aug 2021 15:28:23 +0800 Subject: [PATCH 05/19] =?UTF-8?q?=E5=AE=8C=E5=96=84=E6=90=9C=E7=B4=A2?= =?UTF-8?q?=E7=94=A8=E6=88=B7=E6=97=B6=E5=8F=AF=E4=BB=A5=E6=98=BE=E7=A4=BA?= =?UTF-8?q?=E7=94=A8=E6=88=B7=E7=9A=84=E5=85=B6=E4=BB=96=E5=85=83=E4=BF=A1?= =?UTF-8?q?=E6=81=AF=EF=BC=88=E5=AE=8C=E5=96=84chineseName=E5=92=8Cdepartm?= =?UTF-8?q?ent=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../account/component/account/BaseEnterpriseStaffService.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/kafka-manager-extends/kafka-manager-account/src/main/java/com/xiaojukeji/kafka/manager/account/component/account/BaseEnterpriseStaffService.java b/kafka-manager-extends/kafka-manager-account/src/main/java/com/xiaojukeji/kafka/manager/account/component/account/BaseEnterpriseStaffService.java index 2eef7774..52e7347e 100644 --- a/kafka-manager-extends/kafka-manager-account/src/main/java/com/xiaojukeji/kafka/manager/account/component/account/BaseEnterpriseStaffService.java +++ b/kafka-manager-extends/kafka-manager-account/src/main/java/com/xiaojukeji/kafka/manager/account/component/account/BaseEnterpriseStaffService.java @@ -54,7 +54,8 @@ public class BaseEnterpriseStaffService extends AbstractEnterpriseStaffService { } List staffList = new ArrayList<>(); for (AccountDO accountDO: doList) { - staffList.add(new EnterpriseStaff(accountDO.getUsername(), accountDO.getUsername(), "")); + //这里对chineseName填充共识的displayName,Department则获取Department信息 + staffList.add(new EnterpriseStaff(accountDO.getUsername(), accountDO.getDisplayName(), accountDO.getDepartment())); } return staffList; } catch (Exception e) { From fe0f6fcd0b3f15aff72fa0524f93e26fe45a401b Mon Sep 17 00:00:00 2001 From: zengqiao Date: Thu, 13 Jan 2022 16:02:33 +0800 Subject: [PATCH 06/19] fix config incorrectly comment --- distribution/conf/application.yml.example | 2 +- kafka-manager-web/src/main/resources/application.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/distribution/conf/application.yml.example b/distribution/conf/application.yml.example index d4d57777..1278e3d2 100644 --- a/distribution/conf/application.yml.example +++ b/distribution/conf/application.yml.example @@ -136,4 +136,4 @@ client-pool: min-idle-client-num: 24 # 最小空闲客户端数 max-idle-client-num: 24 # 最大空闲客户端数 max-total-client-num: 24 # 最大客户端数 - borrow-timeout-unit-ms: 3000 # 租借超时时间,单位秒 \ No newline at end of file + borrow-timeout-unit-ms: 3000 # 租借超时时间,单位毫秒 \ No newline at end of file diff --git a/kafka-manager-web/src/main/resources/application.yml b/kafka-manager-web/src/main/resources/application.yml index 0bfa8972..19ba8593 100644 --- a/kafka-manager-web/src/main/resources/application.yml +++ b/kafka-manager-web/src/main/resources/application.yml @@ -116,4 +116,4 @@ client-pool: min-idle-client-num: 24 # 最小空闲客户端数 max-idle-client-num: 24 # 最大空闲客户端数 max-total-client-num: 24 # 最大客户端数 - borrow-timeout-unit-ms: 3000 # 租借超时时间,单位秒 + borrow-timeout-unit-ms: 3000 # 租借超时时间,单位毫秒 From 52c52b2a0df956541c2797c72f36e06bd2ceed20 Mon Sep 17 00:00:00 2001 From: zengqiao Date: Fri, 14 Jan 2022 14:24:04 +0800 Subject: [PATCH 07/19] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E7=AE=80=E5=8D=95?= =?UTF-8?q?=E5=9B=9E=E9=80=80=E5=B7=A5=E5=85=B7=E7=B1=BB=EF=BC=8C=E5=A2=9E?= =?UTF-8?q?=E5=8A=A0Jmx=E8=BF=9E=E6=8E=A5=E5=A4=B1=E8=B4=A5=E5=9B=9E?= =?UTF-8?q?=E9=80=80=E5=8A=9F=E8=83=BD=E6=9C=BA=E5=88=B6=EF=BC=8C=E4=BC=98?= =?UTF-8?q?=E5=8C=96Jmx=E8=BF=9E=E6=8E=A5=E5=A4=B1=E8=B4=A5=E6=97=A5?= =?UTF-8?q?=E5=BF=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../manager/common/utils/BackoffUtils.java | 55 +++++++++++++ .../manager/common/utils/jmx/JmxConfig.java | 50 +++--------- .../common/utils/jmx/JmxConnectorWrap.java | 80 ++++++++++++++++--- 3 files changed, 135 insertions(+), 50 deletions(-) diff --git a/kafka-manager-common/src/main/java/com/xiaojukeji/kafka/manager/common/utils/BackoffUtils.java b/kafka-manager-common/src/main/java/com/xiaojukeji/kafka/manager/common/utils/BackoffUtils.java index f4218020..084ea5a6 100644 --- a/kafka-manager-common/src/main/java/com/xiaojukeji/kafka/manager/common/utils/BackoffUtils.java +++ b/kafka-manager-common/src/main/java/com/xiaojukeji/kafka/manager/common/utils/BackoffUtils.java @@ -1,9 +1,18 @@ package com.xiaojukeji.kafka.manager.common.utils; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; + public class BackoffUtils { private BackoffUtils() { } + /** + * 需要进行延迟的事件 + * <事件名,延迟结束事件> + */ + private static final Map NEED_BACK_OFF_EVENT_MAP = new ConcurrentHashMap<>(); + public static void backoff(long timeUnitMs) { if (timeUnitMs <= 0) { return; @@ -17,4 +26,50 @@ public class BackoffUtils { // ignore } } + + /** + * 记录延迟设置 + * @param backoffEventKey 回退事件key + * @param backoffTimeUnitMs 回退时间(ms) + */ + public static void putNeedBackoffEvent(String backoffEventKey, Long backoffTimeUnitMs) { + if (backoffEventKey == null || backoffTimeUnitMs == null || backoffTimeUnitMs <= 0) { + return; + } + + NEED_BACK_OFF_EVENT_MAP.put(backoffEventKey, backoffTimeUnitMs + System.currentTimeMillis()); + } + + /** + * 移除回退设置 + * @param backoffEventKey 回退事件key + */ + public static void removeNeedBackoffEvent(String backoffEventKey) { + NEED_BACK_OFF_EVENT_MAP.remove(backoffEventKey); + } + + /** + * 检查是否需要回退 + * @param backoffEventKey 回退事件key + * @return + */ + public static boolean isNeedBackoff(String backoffEventKey) { + Long backoffEventEndTimeUnitMs = NEED_BACK_OFF_EVENT_MAP.get(backoffEventKey); + if (backoffEventEndTimeUnitMs == null) { + return false; + } + + if (backoffEventEndTimeUnitMs > System.currentTimeMillis()) { + return true; + } + + // 移除 + try { + NEED_BACK_OFF_EVENT_MAP.remove(backoffEventKey, backoffEventEndTimeUnitMs); + } catch (Exception e) { + // 如果key不存在,这里可能出现NPE,不过不管什么异常都可以忽略 + } + + return false; + } } diff --git a/kafka-manager-common/src/main/java/com/xiaojukeji/kafka/manager/common/utils/jmx/JmxConfig.java b/kafka-manager-common/src/main/java/com/xiaojukeji/kafka/manager/common/utils/jmx/JmxConfig.java index bbc913c4..f5c380c2 100644 --- a/kafka-manager-common/src/main/java/com/xiaojukeji/kafka/manager/common/utils/jmx/JmxConfig.java +++ b/kafka-manager-common/src/main/java/com/xiaojukeji/kafka/manager/common/utils/jmx/JmxConfig.java @@ -1,5 +1,10 @@ package com.xiaojukeji.kafka.manager.common.utils.jmx; +import lombok.Data; +import lombok.ToString; + +@Data +@ToString public class JmxConfig { /** * 单台最大连接数 @@ -21,45 +26,8 @@ public class JmxConfig { */ private Boolean openSSL; - public Integer getMaxConn() { - return maxConn; - } - - public void setMaxConn(Integer maxConn) { - this.maxConn = maxConn; - } - - public String getUsername() { - return username; - } - - public void setUsername(String username) { - this.username = username; - } - - public String getPassword() { - return password; - } - - public void setPassword(String password) { - this.password = password; - } - - public Boolean isOpenSSL() { - return openSSL; - } - - public void setOpenSSL(Boolean openSSL) { - this.openSSL = openSSL; - } - - @Override - public String toString() { - return "JmxConfig{" + - "maxConn=" + maxConn + - ", username='" + username + '\'' + - ", password='" + password + '\'' + - ", openSSL=" + openSSL + - '}'; - } + /** + * 连接重试回退事件 + */ + private Long retryConnectBackoffTimeUnitMs; } diff --git a/kafka-manager-common/src/main/java/com/xiaojukeji/kafka/manager/common/utils/jmx/JmxConnectorWrap.java b/kafka-manager-common/src/main/java/com/xiaojukeji/kafka/manager/common/utils/jmx/JmxConnectorWrap.java index db1e2341..c66c7bc6 100644 --- a/kafka-manager-common/src/main/java/com/xiaojukeji/kafka/manager/common/utils/jmx/JmxConnectorWrap.java +++ b/kafka-manager-common/src/main/java/com/xiaojukeji/kafka/manager/common/utils/jmx/JmxConnectorWrap.java @@ -18,6 +18,7 @@ import java.util.HashMap; import java.util.Map; import java.util.Set; import java.util.concurrent.atomic.AtomicInteger; +import java.util.concurrent.locks.ReentrantLock; /** * JMXConnector包装类 @@ -41,6 +42,8 @@ public class JmxConnectorWrap { private JmxConfig jmxConfig; + private final ReentrantLock modifyJMXConnectorLock = new ReentrantLock(); + public JmxConnectorWrap(Long physicalClusterId, Integer brokerId, String host, int port, JmxConfig jmxConfig) { this.physicalClusterId = physicalClusterId; this.brokerId = brokerId; @@ -51,7 +54,12 @@ public class JmxConnectorWrap { this.jmxConfig = new JmxConfig(); } if (ValidateUtils.isNullOrLessThanZero(this.jmxConfig.getMaxConn())) { - this.jmxConfig.setMaxConn(1); + // 默认设置20 + this.jmxConfig.setMaxConn(20); + } + if (ValidateUtils.isNullOrLessThanZero(this.jmxConfig.getRetryConnectBackoffTimeUnitMs())) { + // 默认回退10分钟 + this.jmxConfig.setRetryConnectBackoffTimeUnitMs(10 * 60 * 1000L); } this.atomicInteger = new AtomicInteger(this.jmxConfig.getMaxConn()); } @@ -63,17 +71,40 @@ public class JmxConnectorWrap { if (port == -1) { return false; } - return createJmxConnector(); + return safeCreateJmxConnector(); } - public synchronized void close() { + public void close() { + this.closeJmxConnect(); + } + + public void closeJmxConnect() { if (jmxConnector == null) { return; } + try { + modifyJMXConnectorLock.lock(); + + // 移除设置的backoff事件 + BackoffUtils.removeNeedBackoffEvent(buildConnectJmxFailedBackoffEventKey(physicalClusterId, brokerId)); + jmxConnector.close(); - } catch (IOException e) { - LOGGER.warn("close JmxConnector exception, physicalClusterId:{} brokerId:{} host:{} port:{}.", physicalClusterId, brokerId, host, port, e); + } catch (Exception e) { + LOGGER.error("close JmxConnector exception, physicalClusterId:{} brokerId:{} host:{} port:{}.", physicalClusterId, brokerId, host, port, e); + } finally { + jmxConnector = null; + + modifyJMXConnectorLock.unlock(); + } + } + + private boolean safeCreateJmxConnector() { + try { + modifyJMXConnectorLock.lock(); + return createJmxConnector(); + } finally { + modifyJMXConnectorLock.unlock(); } } @@ -81,6 +112,12 @@ public class JmxConnectorWrap { if (jmxConnector != null) { return true; } + + if (BackoffUtils.isNeedBackoff(buildConnectJmxFailedBackoffEventKey(physicalClusterId, brokerId))) { + // 被设置了需要进行回退,则本次不进行创建 + return false; + } + String jmxUrl = String.format("service:jmx:rmi:///jndi/rmi://%s:%d/jmxrmi", host, port); try { Map environment = new HashMap(); @@ -88,7 +125,9 @@ public class JmxConnectorWrap { // fixed by riyuetianmu environment.put(JMXConnector.CREDENTIALS, new String[]{this.jmxConfig.getUsername(), this.jmxConfig.getPassword()}); } - if (jmxConfig.isOpenSSL() != null && this.jmxConfig.isOpenSSL()) { + + if (jmxConfig.getOpenSSL() != null && this.jmxConfig.getOpenSSL()) { + // 开启ssl environment.put(Context.SECURITY_PROTOCOL, "ssl"); SslRMIClientSocketFactory clientSocketFactory = new SslRMIClientSocketFactory(); environment.put(RMIConnectorServer.RMI_CLIENT_SOCKET_FACTORY_ATTRIBUTE, clientSocketFactory); @@ -96,13 +135,17 @@ public class JmxConnectorWrap { } jmxConnector = JMXConnectorFactory.connect(new JMXServiceURL(jmxUrl), environment); - LOGGER.info("JMX connect success, physicalClusterId:{} brokerId:{} host:{} port:{}.", physicalClusterId, brokerId, host, port); + LOGGER.info("connect JMX success, physicalClusterId:{} brokerId:{} host:{} port:{}.", physicalClusterId, brokerId, host, port); return true; } catch (MalformedURLException e) { - LOGGER.error("JMX url exception, physicalClusterId:{} brokerId:{} host:{} port:{} jmxUrl:{}", physicalClusterId, brokerId, host, port, jmxUrl, e); + LOGGER.error("connect JMX failed, JMX url exception, physicalClusterId:{} brokerId:{} host:{} port:{} jmxUrl:{}.", physicalClusterId, brokerId, host, port, jmxUrl, e); } catch (Exception e) { - LOGGER.error("JMX connect exception, physicalClusterId:{} brokerId:{} host:{} port:{}.", physicalClusterId, brokerId, host, port, e); + LOGGER.error("connect JMX failed, physicalClusterId:{} brokerId:{} host:{} port:{}.", physicalClusterId, brokerId, host, port, e); } + + // 设置连接backoff + BackoffUtils.putNeedBackoffEvent(buildConnectJmxFailedBackoffEventKey(physicalClusterId, brokerId), this.jmxConfig.getRetryConnectBackoffTimeUnitMs()); + return false; } @@ -116,6 +159,11 @@ public class JmxConnectorWrap { acquire(); MBeanServerConnection mBeanServerConnection = jmxConnector.getMBeanServerConnection(); return mBeanServerConnection.getAttribute(name, attribute); + } catch (IOException ioe) { + // io错误,则重置连接 + this.closeJmxConnect(); + + throw ioe; } finally { atomicInteger.incrementAndGet(); } @@ -131,6 +179,11 @@ public class JmxConnectorWrap { acquire(); MBeanServerConnection mBeanServerConnection = jmxConnector.getMBeanServerConnection(); return mBeanServerConnection.getAttributes(name, attributes); + } catch (IOException ioe) { + // io错误,则重置连接 + this.closeJmxConnect(); + + throw ioe; } finally { atomicInteger.incrementAndGet(); } @@ -143,6 +196,11 @@ public class JmxConnectorWrap { acquire(); MBeanServerConnection mBeanServerConnection = jmxConnector.getMBeanServerConnection(); return mBeanServerConnection.queryNames(name, query); + } catch (IOException ioe) { + // io错误,则重置连接 + this.closeJmxConnect(); + + throw ioe; } finally { atomicInteger.incrementAndGet(); } @@ -165,4 +223,8 @@ public class JmxConnectorWrap { } } } + + private static String buildConnectJmxFailedBackoffEventKey(Long physicalClusterId, Integer brokerId) { + return "CONNECT_JMX_FAILED_BACK_OFF_EVENT_PHY_" + physicalClusterId + "_BROKER_" + brokerId; + } } From e4371b5d029fbefef0be874c1905b464c817011a Mon Sep 17 00:00:00 2001 From: zengqiao Date: Fri, 14 Jan 2022 14:28:45 +0800 Subject: [PATCH 08/19] =?UTF-8?q?=E4=BF=AE=E6=AD=A3=E6=B3=A8=E9=87=8A?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../xiaojukeji/kafka/manager/common/utils/BackoffUtils.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/kafka-manager-common/src/main/java/com/xiaojukeji/kafka/manager/common/utils/BackoffUtils.java b/kafka-manager-common/src/main/java/com/xiaojukeji/kafka/manager/common/utils/BackoffUtils.java index 084ea5a6..afbf8fc4 100644 --- a/kafka-manager-common/src/main/java/com/xiaojukeji/kafka/manager/common/utils/BackoffUtils.java +++ b/kafka-manager-common/src/main/java/com/xiaojukeji/kafka/manager/common/utils/BackoffUtils.java @@ -8,8 +8,8 @@ public class BackoffUtils { } /** - * 需要进行延迟的事件 - * <事件名,延迟结束事件> + * 需要进行回退的事件信息 + * <回退事件名,回退结束时间> */ private static final Map NEED_BACK_OFF_EVENT_MAP = new ConcurrentHashMap<>(); @@ -28,7 +28,7 @@ public class BackoffUtils { } /** - * 记录延迟设置 + * 记录回退设置 * @param backoffEventKey 回退事件key * @param backoffTimeUnitMs 回退时间(ms) */ From d6181522c0042c0b441305be8d0285f9d6efee74 Mon Sep 17 00:00:00 2001 From: zengqiao Date: Mon, 17 Jan 2022 11:42:30 +0800 Subject: [PATCH 09/19] =?UTF-8?q?=E4=BF=AE=E5=A4=8Dswagger=E6=8A=9B?= =?UTF-8?q?=E5=87=BA=E7=9A=84NumberFormatException=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pom.xml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/pom.xml b/pom.xml index 9d226f87..e790bfd3 100644 --- a/pom.xml +++ b/pom.xml @@ -65,6 +65,11 @@ swagger-annotations ${swagger.version} + + io.swagger + swagger-models + ${swagger.version} + From f6ba8bc95e9baadc4cfa57aa4aa1dd82110dddc0 Mon Sep 17 00:00:00 2001 From: zengqiao Date: Mon, 17 Jan 2022 13:17:07 +0800 Subject: [PATCH 10/19] =?UTF-8?q?Swagger=E6=8F=90=E7=A4=BA=E7=89=88?= =?UTF-8?q?=E6=9C=AC=E5=92=8CPOM=E4=B8=AD=E7=89=88=E6=9C=AC=E9=80=9A?= =?UTF-8?q?=E8=BF=87=E9=85=8D=E7=BD=AE=E4=BF=9D=E6=8C=81=E4=B8=80=E8=87=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- distribution/conf/application.yml | 1 + distribution/conf/application.yml.example | 1 + .../kafka/manager/service/utils/ConfigUtils.java | 5 ++++- .../xiaojukeji/kafka/manager/web/config/SwaggerConfig.java | 7 ++++++- kafka-manager-web/src/main/resources/application.yml | 1 + 5 files changed, 13 insertions(+), 2 deletions(-) diff --git a/distribution/conf/application.yml b/distribution/conf/application.yml index 6b78c104..a11cb737 100644 --- a/distribution/conf/application.yml +++ b/distribution/conf/application.yml @@ -15,6 +15,7 @@ server: spring: application: name: kafkamanager + version: @project.version@ profiles: active: dev datasource: diff --git a/distribution/conf/application.yml.example b/distribution/conf/application.yml.example index 1278e3d2..3894a570 100644 --- a/distribution/conf/application.yml.example +++ b/distribution/conf/application.yml.example @@ -15,6 +15,7 @@ server: spring: application: name: kafkamanager + version: @project.version@ profiles: active: dev datasource: diff --git a/kafka-manager-core/src/main/java/com/xiaojukeji/kafka/manager/service/utils/ConfigUtils.java b/kafka-manager-core/src/main/java/com/xiaojukeji/kafka/manager/service/utils/ConfigUtils.java index 751e08c2..40b73868 100644 --- a/kafka-manager-core/src/main/java/com/xiaojukeji/kafka/manager/service/utils/ConfigUtils.java +++ b/kafka-manager-core/src/main/java/com/xiaojukeji/kafka/manager/service/utils/ConfigUtils.java @@ -18,6 +18,9 @@ public class ConfigUtils { @Value(value = "${custom.idc:cn}") private String idc; - @Value(value = "${spring.profiles.active}") + @Value(value = "${spring.profiles.active:dev}") private String kafkaManagerEnv; + + @Value(value = "${spring.application.version:unknown}") + private String applicationVersion; } diff --git a/kafka-manager-web/src/main/java/com/xiaojukeji/kafka/manager/web/config/SwaggerConfig.java b/kafka-manager-web/src/main/java/com/xiaojukeji/kafka/manager/web/config/SwaggerConfig.java index f4ae13a4..f8406cfe 100644 --- a/kafka-manager-web/src/main/java/com/xiaojukeji/kafka/manager/web/config/SwaggerConfig.java +++ b/kafka-manager-web/src/main/java/com/xiaojukeji/kafka/manager/web/config/SwaggerConfig.java @@ -1,5 +1,7 @@ package com.xiaojukeji.kafka.manager.web.config; +import com.xiaojukeji.kafka.manager.service.utils.ConfigUtils; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.web.servlet.config.annotation.*; @@ -20,6 +22,9 @@ import springfox.documentation.swagger2.annotations.EnableSwagger2; @EnableWebMvc @EnableSwagger2 public class SwaggerConfig implements WebMvcConfigurer { + @Autowired + private ConfigUtils configUtils; + @Override public void addResourceHandlers(ResourceHandlerRegistry registry) { registry.addResourceHandler("swagger-ui.html").addResourceLocations("classpath:/META-INF/resources/"); @@ -41,7 +46,7 @@ public class SwaggerConfig implements WebMvcConfigurer { return new ApiInfoBuilder() .title("LogiKM接口文档") .description("欢迎使用滴滴LogiKM") - .version("2.5.0") + .version(configUtils.getApplicationVersion()) .build(); } diff --git a/kafka-manager-web/src/main/resources/application.yml b/kafka-manager-web/src/main/resources/application.yml index 19ba8593..3cce7463 100644 --- a/kafka-manager-web/src/main/resources/application.yml +++ b/kafka-manager-web/src/main/resources/application.yml @@ -9,6 +9,7 @@ server: spring: application: name: kafkamanager + version: @project.version@ profiles: active: dev datasource: From 2790099efa55c84dc76cbda92d009fc1bb6dba2f Mon Sep 17 00:00:00 2001 From: zengqiao Date: Mon, 17 Jan 2022 15:28:36 +0800 Subject: [PATCH 11/19] =?UTF-8?q?=E6=A2=B3=E7=90=86Task=E6=A8=A1=E5=9D=97?= =?UTF-8?q?=E4=BB=BB=E5=8A=A1-BrokerMetrics=E4=BB=BB=E5=8A=A1=E6=A2=B3?= =?UTF-8?q?=E7=90=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- distribution/conf/application.yml.example | 144 ++++++++--------- .../metrics/BaseMetricsCollectedEvent.java | 33 ++++ .../BatchBrokerMetricsCollectedEvent.java | 22 +++ .../task/component/AbstractScheduledTask.java | 3 +- .../manager/task/component/BaseBizTask.java | 8 +- .../CollectAndPublishBrokerMetrics.java | 93 +++++++++++ .../metrics/delete/DeleteMetrics.java | 14 +- .../metrics/store/StoreBrokerMetrics.java | 146 ------------------ .../sink/db/SinkBrokerMetrics2DB.java | 55 +++++++ .../sink/db/SinkClusterMetrics2DB.java | 80 ++++++++++ .../db}/StoreCommunityTopicMetrics2DB.java | 2 +- .../db}/StoreTopicThrottledMetrics2DB.java | 2 +- .../SinkCommunityTopicMetrics2Kafka.java | 2 +- .../kafka}/SinkConsumerMetrics2Kafka.java | 2 +- .../SinkCommunityTopicMetrics2Monitor.java | 2 +- .../monitor}/SinkConsumerMetrics2Monitor.java | 2 +- .../SinkTopicThrottledMetrics2Monitor.java | 2 +- .../src/main/resources/application.yml | 50 +++--- 18 files changed, 398 insertions(+), 264 deletions(-) create mode 100644 kafka-manager-common/src/main/java/com/xiaojukeji/kafka/manager/common/events/metrics/BaseMetricsCollectedEvent.java create mode 100644 kafka-manager-common/src/main/java/com/xiaojukeji/kafka/manager/common/events/metrics/BatchBrokerMetricsCollectedEvent.java create mode 100644 kafka-manager-task/src/main/java/com/xiaojukeji/kafka/manager/task/dispatch/metrics/collect/CollectAndPublishBrokerMetrics.java delete mode 100644 kafka-manager-task/src/main/java/com/xiaojukeji/kafka/manager/task/dispatch/metrics/store/StoreBrokerMetrics.java create mode 100644 kafka-manager-task/src/main/java/com/xiaojukeji/kafka/manager/task/listener/sink/db/SinkBrokerMetrics2DB.java create mode 100644 kafka-manager-task/src/main/java/com/xiaojukeji/kafka/manager/task/listener/sink/db/SinkClusterMetrics2DB.java rename kafka-manager-task/src/main/java/com/xiaojukeji/kafka/manager/task/listener/{ => sink/db}/StoreCommunityTopicMetrics2DB.java (97%) rename kafka-manager-task/src/main/java/com/xiaojukeji/kafka/manager/task/listener/{ => sink/db}/StoreTopicThrottledMetrics2DB.java (98%) rename kafka-manager-task/src/main/java/com/xiaojukeji/kafka/manager/task/listener/{ => sink/kafka}/SinkCommunityTopicMetrics2Kafka.java (98%) rename kafka-manager-task/src/main/java/com/xiaojukeji/kafka/manager/task/listener/{ => sink/kafka}/SinkConsumerMetrics2Kafka.java (98%) rename kafka-manager-task/src/main/java/com/xiaojukeji/kafka/manager/task/listener/{ => sink/monitor}/SinkCommunityTopicMetrics2Monitor.java (98%) rename kafka-manager-task/src/main/java/com/xiaojukeji/kafka/manager/task/listener/{ => sink/monitor}/SinkConsumerMetrics2Monitor.java (99%) rename kafka-manager-task/src/main/java/com/xiaojukeji/kafka/manager/task/listener/{ => sink/monitor}/SinkTopicThrottledMetrics2Monitor.java (98%) diff --git a/distribution/conf/application.yml.example b/distribution/conf/application.yml.example index 3894a570..ee0290d8 100644 --- a/distribution/conf/application.yml.example +++ b/distribution/conf/application.yml.example @@ -27,7 +27,6 @@ spring: main: allow-bean-definition-overriding: true - servlet: multipart: max-file-size: 100MB @@ -37,28 +36,32 @@ logging: config: classpath:logback-spring.xml custom: - idc: cn # 部署的数据中心, 忽略该配置, 后续会进行删除 - jmx: - max-conn: 10 # 2.3版本配置不在这个地方生效 + idc: cn store-metrics-task: community: - broker-metrics-enabled: true # 社区部分broker metrics信息收集开关, 关闭之后metrics信息将不会进行收集及写DB - topic-metrics-enabled: true # 社区部分topic的metrics信息收集开关, 关闭之后metrics信息将不会进行收集及写DB - didi: - app-topic-metrics-enabled: false # 滴滴埋入的指标, 社区AK不存在该指标,因此默认关闭 - topic-request-time-metrics-enabled: false # 滴滴埋入的指标, 社区AK不存在该指标,因此默认关闭 - topic-throttled-metrics-enabled: false # 滴滴埋入的指标, 社区AK不存在该指标,因此默认关闭 + topic-metrics-enabled: true + didi: # 滴滴Kafka特有的指标 + app-topic-metrics-enabled: false + topic-request-time-metrics-enabled: false + topic-throttled-metrics-enabled: false -# 任务相关的开关 +# 任务相关的配置 task: op: - sync-topic-enabled: false # 未落盘的Topic定期同步到DB中 - order-auto-exec: # 工单自动化审批线程的开关 - topic-enabled: false # Topic工单自动化审批开关, false:关闭自动化审批, true:开启 - app-enabled: false # App工单自动化审批开关, false:关闭自动化审批, true:开启 + sync-topic-enabled: false # 未落盘的Topic定期同步到DB中 + order-auto-exec: # 工单自动化审批线程的开关 + topic-enabled: false # Topic工单自动化审批开关, false:关闭自动化审批, true:开启 + app-enabled: false # App工单自动化审批开关, false:关闭自动化审批, true:开启 metrics: - delete-metrics: - delete-limit-size: 1000 + collect: # 收集指标 + broker-metrics-enabled: true # 收集Broker指标 + sink: # 上报指标 + cluster-metrics: # 上报cluster指标 + sink-db-enabled: true # 上报到db + broker-metrics: # 上报broker指标 + sink-db-enabled: true # 上报到db + delete: # 删除指标 + delete-limit-size: 1000 # 单次删除的批大小 cluster-metrics-save-days: 14 # 集群指标保存天数 broker-metrics-save-days: 14 # Broker指标保存天数 topic-metrics-save-days: 7 # Topic指标保存天数 @@ -66,64 +69,6 @@ task: topic-throttled-metrics-save-days: 7 # Topic限流指标保存天数 app-topic-metrics-save-days: 7 # App+Topic指标保存天数 -# ldap相关的配置 -account: - ldap: - enabled: false - url: ldap://127.0.0.1:389/ - basedn: dc=tsign,dc=cn - factory: com.sun.jndi.ldap.LdapCtxFactory - filter: sAMAccountName - security: - authentication: simple - principal: cn=admin,dc=tsign,dc=cn - credentials: admin - auth-user-registration: true - auth-user-registration-role: normal - -# 集群升级部署相关的功能,需要配合夜莺及S3进行使用 -kcm: - enabled: false - s3: - endpoint: s3.didiyunapi.com - access-key: 1234567890 - secret-key: 0987654321 - bucket: logi-kafka - n9e: - base-url: http://127.0.0.1:8004 - user-token: 12345678 - timeout: 300 - account: root - script-file: kcm_script.sh - -# 监控告警相关的功能,需要配合夜莺进行使用 -# enabled: 表示是否开启监控告警的功能, true: 开启, false: 不开启 -# n9e.nid: 夜莺的节点ID -# n9e.user-token: 用户的密钥,在夜莺的个人设置中 -# n9e.mon.base-url: 监控地址 -# n9e.sink.base-url: 数据上报地址 -# n9e.rdb.base-url: 用户资源中心地址 - -monitor: - enabled: false - n9e: - nid: 2 - user-token: 1234567890 - mon: - base-url: http://127.0.0.1:8000 # 夜莺v4版本,默认端口统一调整为了8000 - sink: - base-url: http://127.0.0.1:8000 # 夜莺v4版本,默认端口统一调整为了8000 - rdb: - base-url: http://127.0.0.1:8000 # 夜莺v4版本,默认端口统一调整为了8000 - - -notify: # 通知的功能 - kafka: # 默认通知发送到kafka的指定Topic中 - cluster-id: 95 # Topic的集群ID - topic-name: didi-kafka-notify # Topic名称 - order: # 部署的KM的地址 - detail-url: http://127.0.0.1 - thread-pool: collect-metrics: thread-num: 256 # 收集指标线程池大小 @@ -137,4 +82,51 @@ client-pool: min-idle-client-num: 24 # 最小空闲客户端数 max-idle-client-num: 24 # 最大空闲客户端数 max-total-client-num: 24 # 最大客户端数 - borrow-timeout-unit-ms: 3000 # 租借超时时间,单位毫秒 \ No newline at end of file + borrow-timeout-unit-ms: 3000 # 租借超时时间,单位毫秒 + +account: + ldap: + enabled: false + url: ldap://127.0.0.1:389/ + basedn: dc=tsign,dc=cn + factory: com.sun.jndi.ldap.LdapCtxFactory + filter: sAMAccountName + security: + authentication: simple + principal: cn=admin,dc=tsign,dc=cn + credentials: admin + auth-user-registration: true + auth-user-registration-role: normal + +kcm: + enabled: false + s3: + endpoint: s3.didiyunapi.com + access-key: 1234567890 + secret-key: 0987654321 + bucket: logi-kafka + n9e: + base-url: http://127.0.0.1:8004 + user-token: 12345678 + timeout: 300 + account: root + script-file: kcm_script.sh + +monitor: + enabled: false + n9e: + nid: 2 + user-token: 1234567890 + mon: + base-url: http://127.0.0.1:8000 # 夜莺v4版本,默认端口统一调整为了8000 + sink: + base-url: http://127.0.0.1:8000 # 夜莺v4版本,默认端口统一调整为了8000 + rdb: + base-url: http://127.0.0.1:8000 # 夜莺v4版本,默认端口统一调整为了8000 + +notify: + kafka: + cluster-id: 95 + topic-name: didi-kafka-notify + order: + detail-url: http://127.0.0.1 diff --git a/kafka-manager-common/src/main/java/com/xiaojukeji/kafka/manager/common/events/metrics/BaseMetricsCollectedEvent.java b/kafka-manager-common/src/main/java/com/xiaojukeji/kafka/manager/common/events/metrics/BaseMetricsCollectedEvent.java new file mode 100644 index 00000000..730e14c9 --- /dev/null +++ b/kafka-manager-common/src/main/java/com/xiaojukeji/kafka/manager/common/events/metrics/BaseMetricsCollectedEvent.java @@ -0,0 +1,33 @@ +package com.xiaojukeji.kafka.manager.common.events.metrics; + +import org.springframework.context.ApplicationEvent; + +/** + * @author zengqiao + * @date 22/01/17 + */ +public class BaseMetricsCollectedEvent extends ApplicationEvent { + /** + * 物理集群ID + */ + protected final Long physicalClusterId; + + /** + * 收集时间,依据业务需要来设置,可以设置任务开始时间,也可以设置任务结束时间 + */ + protected final Long collectTime; + + public BaseMetricsCollectedEvent(Object source, Long physicalClusterId, Long collectTime) { + super(source); + this.physicalClusterId = physicalClusterId; + this.collectTime = collectTime; + } + + public Long getPhysicalClusterId() { + return physicalClusterId; + } + + public Long getCollectTime() { + return collectTime; + } +} diff --git a/kafka-manager-common/src/main/java/com/xiaojukeji/kafka/manager/common/events/metrics/BatchBrokerMetricsCollectedEvent.java b/kafka-manager-common/src/main/java/com/xiaojukeji/kafka/manager/common/events/metrics/BatchBrokerMetricsCollectedEvent.java new file mode 100644 index 00000000..629a44ea --- /dev/null +++ b/kafka-manager-common/src/main/java/com/xiaojukeji/kafka/manager/common/events/metrics/BatchBrokerMetricsCollectedEvent.java @@ -0,0 +1,22 @@ +package com.xiaojukeji.kafka.manager.common.events.metrics; + +import com.xiaojukeji.kafka.manager.common.entity.metrics.BrokerMetrics; + +import java.util.List; + +/** + * @author zengqiao + * @date 20/8/31 + */ +public class BatchBrokerMetricsCollectedEvent extends BaseMetricsCollectedEvent { + private final List metricsList; + + public BatchBrokerMetricsCollectedEvent(Object source, Long physicalClusterId, Long collectTime, List metricsList) { + super(source, physicalClusterId, collectTime); + this.metricsList = metricsList; + } + + public List getMetricsList() { + return metricsList; + } +} \ No newline at end of file diff --git a/kafka-manager-task/src/main/java/com/xiaojukeji/kafka/manager/task/component/AbstractScheduledTask.java b/kafka-manager-task/src/main/java/com/xiaojukeji/kafka/manager/task/component/AbstractScheduledTask.java index 7eddb926..564094d5 100644 --- a/kafka-manager-task/src/main/java/com/xiaojukeji/kafka/manager/task/component/AbstractScheduledTask.java +++ b/kafka-manager-task/src/main/java/com/xiaojukeji/kafka/manager/task/component/AbstractScheduledTask.java @@ -1,7 +1,6 @@ package com.xiaojukeji.kafka.manager.task.component; import com.google.common.collect.Lists; -import com.xiaojukeji.kafka.manager.common.constant.LogConstant; import com.xiaojukeji.kafka.manager.common.utils.factory.DefaultThreadFactory; import com.xiaojukeji.kafka.manager.common.utils.JsonUtils; import com.xiaojukeji.kafka.manager.common.utils.NetUtils; @@ -29,7 +28,7 @@ import java.util.concurrent.*; * @date 20/8/10 */ public abstract class AbstractScheduledTask implements SchedulingConfigurer { - private final static Logger LOGGER = LoggerFactory.getLogger(LogConstant.SCHEDULED_TASK_LOGGER); + private static final Logger LOGGER = LoggerFactory.getLogger(AbstractScheduledTask.class); @Autowired private HeartbeatDao heartbeatDao; diff --git a/kafka-manager-task/src/main/java/com/xiaojukeji/kafka/manager/task/component/BaseBizTask.java b/kafka-manager-task/src/main/java/com/xiaojukeji/kafka/manager/task/component/BaseBizTask.java index 37a36238..b4cfdd47 100644 --- a/kafka-manager-task/src/main/java/com/xiaojukeji/kafka/manager/task/component/BaseBizTask.java +++ b/kafka-manager-task/src/main/java/com/xiaojukeji/kafka/manager/task/component/BaseBizTask.java @@ -1,6 +1,5 @@ package com.xiaojukeji.kafka.manager.task.component; -import com.xiaojukeji.kafka.manager.common.constant.LogConstant; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -9,11 +8,11 @@ import org.slf4j.LoggerFactory; * @date 20/8/10 */ public class BaseBizTask implements Runnable { - private final static Logger LOGGER = LoggerFactory.getLogger(LogConstant.SCHEDULED_TASK_LOGGER); + private static final Logger LOGGER = LoggerFactory.getLogger(AbstractScheduledTask.class); - private E task; + private final E task; - private AbstractScheduledTask scheduledTask; + private final AbstractScheduledTask scheduledTask; public BaseBizTask(E task, AbstractScheduledTask scheduledTask) { this.task = task; @@ -30,6 +29,7 @@ public class BaseBizTask implements Runnable { } catch (Throwable t) { LOGGER.error("scheduled task scheduleName:{} execute failed, task:{}", scheduledTask.getScheduledName(), task, t); } + LOGGER.info("scheduled task scheduleName:{} finished, cost-time:{}ms.", scheduledTask.getScheduledName(), System.currentTimeMillis() - startTime); } } \ No newline at end of file diff --git a/kafka-manager-task/src/main/java/com/xiaojukeji/kafka/manager/task/dispatch/metrics/collect/CollectAndPublishBrokerMetrics.java b/kafka-manager-task/src/main/java/com/xiaojukeji/kafka/manager/task/dispatch/metrics/collect/CollectAndPublishBrokerMetrics.java new file mode 100644 index 00000000..47aa60d4 --- /dev/null +++ b/kafka-manager-task/src/main/java/com/xiaojukeji/kafka/manager/task/dispatch/metrics/collect/CollectAndPublishBrokerMetrics.java @@ -0,0 +1,93 @@ +package com.xiaojukeji.kafka.manager.task.dispatch.metrics.collect; + +import com.xiaojukeji.kafka.manager.common.constant.KafkaMetricsCollections; +import com.xiaojukeji.kafka.manager.common.entity.metrics.BrokerMetrics; +import com.xiaojukeji.kafka.manager.common.events.metrics.BatchBrokerMetricsCollectedEvent; +import com.xiaojukeji.kafka.manager.common.utils.SpringTool; +import com.xiaojukeji.kafka.manager.common.utils.ValidateUtils; +import com.xiaojukeji.kafka.manager.common.utils.jmx.JmxConstant; +import com.xiaojukeji.kafka.manager.common.entity.pojo.ClusterDO; +import com.xiaojukeji.kafka.manager.service.cache.PhysicalClusterMetadataManager; +import com.xiaojukeji.kafka.manager.service.service.ClusterService; +import com.xiaojukeji.kafka.manager.service.service.JmxService; +import com.xiaojukeji.kafka.manager.service.strategy.AbstractHealthScoreStrategy; +import com.xiaojukeji.kafka.manager.task.component.AbstractScheduledTask; +import com.xiaojukeji.kafka.manager.task.component.CustomScheduled; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; + +import java.util.ArrayList; +import java.util.List; + +/** + * Broker指标信息收集 + * @author zengqiao + * @date 20/5/7 + */ +@CustomScheduled(name = "collectAndPublishBrokerMetrics", cron = "21 0/1 * * * ?", threadNum = 2) +@ConditionalOnProperty(prefix = "task.metrics.collect", name = "broker-metrics-enabled", havingValue = "true", matchIfMissing = true) +public class CollectAndPublishBrokerMetrics extends AbstractScheduledTask { + private static final Logger LOGGER = LoggerFactory.getLogger(CollectAndPublishBrokerMetrics.class); + + @Autowired + private JmxService jmxService; + + @Autowired + private ClusterService clusterService; + + @Autowired + private AbstractHealthScoreStrategy healthScoreStrategy; + + @Override + protected List listAllTasks() { + return clusterService.list(); + } + + @Override + public void processTask(ClusterDO clusterDO) { + long startTime = System.currentTimeMillis(); + + try { + SpringTool.publish(new BatchBrokerMetricsCollectedEvent( + this, + clusterDO.getId(), + startTime, + this.getBrokerMetrics(clusterDO.getId())) + ); + } catch (Exception e) { + LOGGER.error("collect broker-metrics failed, physicalClusterId:{}.", clusterDO.getId(), e); + } + + LOGGER.info("collect broker-metrics finished, physicalClusterId:{} costTime:{}", clusterDO.getId(), System.currentTimeMillis() - startTime); + } + + private List getBrokerMetrics(Long clusterId) { + List metricsList = new ArrayList<>(); + for (Integer brokerId: PhysicalClusterMetadataManager.getBrokerIdList(clusterId)) { + BrokerMetrics metrics = jmxService.getBrokerMetrics( + clusterId, + brokerId, + KafkaMetricsCollections.BROKER_TO_DB_METRICS + ); + + if (ValidateUtils.isNull(metrics)) { + continue; + } + + metrics.getMetricsMap().put( + JmxConstant.HEALTH_SCORE, + healthScoreStrategy.calBrokerHealthScore(clusterId, brokerId, metrics) + ); + + metricsList.add(metrics); + } + + if (ValidateUtils.isEmptyList(metricsList)) { + return new ArrayList<>(); + } + + return metricsList; + } +} \ No newline at end of file diff --git a/kafka-manager-task/src/main/java/com/xiaojukeji/kafka/manager/task/dispatch/metrics/delete/DeleteMetrics.java b/kafka-manager-task/src/main/java/com/xiaojukeji/kafka/manager/task/dispatch/metrics/delete/DeleteMetrics.java index 16c2a012..89d7e516 100644 --- a/kafka-manager-task/src/main/java/com/xiaojukeji/kafka/manager/task/dispatch/metrics/delete/DeleteMetrics.java +++ b/kafka-manager-task/src/main/java/com/xiaojukeji/kafka/manager/task/dispatch/metrics/delete/DeleteMetrics.java @@ -42,25 +42,25 @@ public class DeleteMetrics extends AbstractScheduledTask { @Autowired private TopicThrottledMetricsDao topicThrottledMetricsDao; - @Value(value = "${task.metrics.delete-metrics.delete-limit-size:1000}") + @Value(value = "${task.metrics.delete.delete-limit-size:1000}") private Integer deleteLimitSize; - @Value(value = "${task.metrics.delete-metrics.cluster-metrics-save-days:14}") + @Value(value = "${task.metrics.delete.cluster-metrics-save-days:14}") private Integer clusterMetricsSaveDays; - @Value(value = "${task.metrics.delete-metrics.broker-metrics-save-days:14}") + @Value(value = "${task.metrics.delete.broker-metrics-save-days:14}") private Integer brokerMetricsSaveDays; - @Value(value = "${task.metrics.delete-metrics.topic-metrics-save-days:7}") + @Value(value = "${task.metrics.delete.topic-metrics-save-days:7}") private Integer topicMetricsSaveDays; - @Value(value = "${task.metrics.delete-metrics.topic-request-time-metrics-save-days:7}") + @Value(value = "${task.metrics.delete.topic-request-time-metrics-save-days:7}") private Integer topicRequestTimeMetricsSaveDays; - @Value(value = "${task.metrics.delete-metrics.topic-throttled-metrics-save-days:7}") + @Value(value = "${task.metrics.delete.topic-throttled-metrics-save-days:7}") private Integer topicThrottledMetricsSaveDays; - @Value(value = "${task.metrics.delete-metrics.app-topic-metrics-save-days:7}") + @Value(value = "${task.metrics.delete.app-topic-metrics-save-days:7}") private Integer appTopicMetricsSaveDays; @Override diff --git a/kafka-manager-task/src/main/java/com/xiaojukeji/kafka/manager/task/dispatch/metrics/store/StoreBrokerMetrics.java b/kafka-manager-task/src/main/java/com/xiaojukeji/kafka/manager/task/dispatch/metrics/store/StoreBrokerMetrics.java deleted file mode 100644 index 22aeaf2a..00000000 --- a/kafka-manager-task/src/main/java/com/xiaojukeji/kafka/manager/task/dispatch/metrics/store/StoreBrokerMetrics.java +++ /dev/null @@ -1,146 +0,0 @@ -package com.xiaojukeji.kafka.manager.task.dispatch.metrics.store; - -import com.xiaojukeji.kafka.manager.common.constant.Constant; -import com.xiaojukeji.kafka.manager.common.constant.KafkaMetricsCollections; -import com.xiaojukeji.kafka.manager.common.constant.LogConstant; -import com.xiaojukeji.kafka.manager.common.entity.metrics.BaseMetrics; -import com.xiaojukeji.kafka.manager.common.entity.metrics.BrokerMetrics; -import com.xiaojukeji.kafka.manager.common.entity.metrics.ClusterMetrics; -import com.xiaojukeji.kafka.manager.common.utils.ValidateUtils; -import com.xiaojukeji.kafka.manager.common.utils.jmx.JmxConstant; -import com.xiaojukeji.kafka.manager.common.zookeeper.znode.brokers.TopicMetadata; -import com.xiaojukeji.kafka.manager.dao.BrokerMetricsDao; -import com.xiaojukeji.kafka.manager.dao.ClusterMetricsDao; -import com.xiaojukeji.kafka.manager.common.entity.pojo.BrokerMetricsDO; -import com.xiaojukeji.kafka.manager.common.entity.pojo.ClusterDO; -import com.xiaojukeji.kafka.manager.common.entity.pojo.ClusterMetricsDO; -import com.xiaojukeji.kafka.manager.service.cache.PhysicalClusterMetadataManager; -import com.xiaojukeji.kafka.manager.service.service.ClusterService; -import com.xiaojukeji.kafka.manager.service.service.JmxService; -import com.xiaojukeji.kafka.manager.service.strategy.AbstractHealthScoreStrategy; -import com.xiaojukeji.kafka.manager.service.utils.MetricsConvertUtils; -import com.xiaojukeji.kafka.manager.task.component.AbstractScheduledTask; -import com.xiaojukeji.kafka.manager.task.component.CustomScheduled; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; - -import java.util.ArrayList; -import java.util.List; -import java.util.Map; - -/** - * Broker指标信息存DB, Broker流量, 集群流量 - * @author zengqiao - * @date 20/5/7 - */ -@CustomScheduled(name = "storeBrokerMetrics", cron = "21 0/1 * * * ?", threadNum = 2) -@ConditionalOnProperty(prefix = "custom.store-metrics-task.community", name = "broker-metrics-enabled", havingValue = "true", matchIfMissing = true) -public class StoreBrokerMetrics extends AbstractScheduledTask { - private static final Logger LOGGER = LoggerFactory.getLogger(LogConstant.SCHEDULED_TASK_LOGGER); - - @Autowired - private JmxService jmxService; - - @Autowired - private ClusterService clusterService; - - @Autowired - private BrokerMetricsDao brokerMetricsDao; - - @Autowired - private ClusterMetricsDao clusterMetricsDao; - - @Autowired - private AbstractHealthScoreStrategy healthScoreStrategy; - - @Override - protected List listAllTasks() { - return clusterService.list(); - } - - @Override - public void processTask(ClusterDO clusterDO) { - long startTime = System.currentTimeMillis(); - List clusterMetricsList = new ArrayList<>(); - - try { - List brokerMetricsList = getAndBatchAddMetrics(startTime, clusterDO.getId()); - clusterMetricsList.add(supplyAndConvert2ClusterMetrics( - clusterDO.getId(), - MetricsConvertUtils.merge2BaseMetricsByAdd(brokerMetricsList)) - ); - } catch (Exception t) { - LOGGER.error("collect failed, clusterId:{}.", clusterDO.getId(), t); - } - long endTime = System.currentTimeMillis(); - LOGGER.info("collect finish, clusterId:{} costTime:{}", clusterDO.getId(), endTime - startTime); - - List doList = MetricsConvertUtils.convertAndUpdateCreateTime2ClusterMetricsDOList( - startTime, - clusterMetricsList - ); - - if (ValidateUtils.isEmptyList(doList)) { - return; - } - - clusterMetricsDao.batchAdd(doList); - } - - private List getAndBatchAddMetrics(Long startTime, Long clusterId) { - List metricsList = new ArrayList<>(); - for (Integer brokerId: PhysicalClusterMetadataManager.getBrokerIdList(clusterId)) { - BrokerMetrics metrics = jmxService.getBrokerMetrics( - clusterId, - brokerId, - KafkaMetricsCollections.BROKER_TO_DB_METRICS - ); - if (ValidateUtils.isNull(metrics)) { - continue; - } - metrics.getMetricsMap().put( - JmxConstant.HEALTH_SCORE, - healthScoreStrategy.calBrokerHealthScore(clusterId, brokerId, metrics) - ); - metricsList.add(metrics); - } - if (ValidateUtils.isEmptyList(metricsList)) { - return new ArrayList<>(); - } - - List doList = - MetricsConvertUtils.convertAndUpdateCreateTime2BrokerMetricsDOList(startTime, metricsList); - int i = 0; - do { - List subDOList = doList.subList(i, Math.min(i + Constant.BATCH_INSERT_SIZE, doList.size())); - if (ValidateUtils.isEmptyList(subDOList)) { - break; - } - - brokerMetricsDao.batchAdd(subDOList); - i += Constant.BATCH_INSERT_SIZE; - } while (i < doList.size()); - - return metricsList; - } - - private ClusterMetrics supplyAndConvert2ClusterMetrics(Long clusterId, BaseMetrics baseMetrics) { - ClusterMetrics metrics = new ClusterMetrics(clusterId); - Map metricsMap = metrics.getMetricsMap(); - metricsMap.putAll(baseMetrics.getMetricsMap()); - metricsMap.put(JmxConstant.TOPIC_NUM, PhysicalClusterMetadataManager.getTopicNameList(clusterId).size()); - metricsMap.put(JmxConstant.BROKER_NUM, PhysicalClusterMetadataManager.getBrokerIdList(clusterId).size()); - Integer partitionNum = 0; - for (String topicName : PhysicalClusterMetadataManager.getTopicNameList(clusterId)) { - TopicMetadata topicMetaData = PhysicalClusterMetadataManager.getTopicMetadata(clusterId, topicName); - if (ValidateUtils.isNull(topicMetaData)) { - continue; - } - partitionNum += topicMetaData.getPartitionNum(); - } - metricsMap.put(JmxConstant.PARTITION_NUM, partitionNum); - return metrics; - } -} \ No newline at end of file diff --git a/kafka-manager-task/src/main/java/com/xiaojukeji/kafka/manager/task/listener/sink/db/SinkBrokerMetrics2DB.java b/kafka-manager-task/src/main/java/com/xiaojukeji/kafka/manager/task/listener/sink/db/SinkBrokerMetrics2DB.java new file mode 100644 index 00000000..923d26b6 --- /dev/null +++ b/kafka-manager-task/src/main/java/com/xiaojukeji/kafka/manager/task/listener/sink/db/SinkBrokerMetrics2DB.java @@ -0,0 +1,55 @@ +package com.xiaojukeji.kafka.manager.task.listener.sink.db; + +import com.xiaojukeji.kafka.manager.common.constant.Constant; +import com.xiaojukeji.kafka.manager.common.entity.metrics.BrokerMetrics; +import com.xiaojukeji.kafka.manager.common.entity.pojo.BrokerMetricsDO; +import com.xiaojukeji.kafka.manager.common.events.metrics.BatchBrokerMetricsCollectedEvent; +import com.xiaojukeji.kafka.manager.common.utils.ValidateUtils; +import com.xiaojukeji.kafka.manager.dao.BrokerMetricsDao; +import com.xiaojukeji.kafka.manager.service.utils.MetricsConvertUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; +import org.springframework.context.ApplicationListener; +import org.springframework.stereotype.Component; + +import java.util.List; + +/** + * @author zengqiao + * @date 22/01/17 + */ +@Component +@ConditionalOnProperty(prefix = "task.metrics.sink.broker-metrics", name = "sink-db-enabled", havingValue = "true", matchIfMissing = true) +public class SinkBrokerMetrics2DB implements ApplicationListener { + private static final Logger logger = LoggerFactory.getLogger(SinkBrokerMetrics2DB.class); + + @Autowired + private BrokerMetricsDao metricsDao; + + @Override + public void onApplicationEvent(BatchBrokerMetricsCollectedEvent event) { + logger.debug("sink broker-metrics to db start, event:{}.", event); + + List metricsList = event.getMetricsList(); + if (ValidateUtils.isEmptyList(metricsList)) { + logger.warn("sink broker-metrics to db finished, without need sink, event:{}.", event); + return; + } + + List doList = MetricsConvertUtils.convertAndUpdateCreateTime2BrokerMetricsDOList(event.getCollectTime(), metricsList); + int i = 0; + while (i < doList.size()) { + List subDOList = doList.subList(i, Math.min(i + Constant.BATCH_INSERT_SIZE, doList.size())); + if (ValidateUtils.isEmptyList(subDOList)) { + break; + } + + metricsDao.batchAdd(subDOList); + i += Constant.BATCH_INSERT_SIZE; + } + + logger.debug("sink broker-metrics to db finished, event:{}.", event); + } +} \ No newline at end of file diff --git a/kafka-manager-task/src/main/java/com/xiaojukeji/kafka/manager/task/listener/sink/db/SinkClusterMetrics2DB.java b/kafka-manager-task/src/main/java/com/xiaojukeji/kafka/manager/task/listener/sink/db/SinkClusterMetrics2DB.java new file mode 100644 index 00000000..a1aab09c --- /dev/null +++ b/kafka-manager-task/src/main/java/com/xiaojukeji/kafka/manager/task/listener/sink/db/SinkClusterMetrics2DB.java @@ -0,0 +1,80 @@ +package com.xiaojukeji.kafka.manager.task.listener.sink.db; + +import com.xiaojukeji.kafka.manager.common.entity.metrics.BaseMetrics; +import com.xiaojukeji.kafka.manager.common.entity.metrics.BrokerMetrics; +import com.xiaojukeji.kafka.manager.common.entity.metrics.ClusterMetrics; +import com.xiaojukeji.kafka.manager.common.entity.pojo.ClusterMetricsDO; +import com.xiaojukeji.kafka.manager.common.events.metrics.BatchBrokerMetricsCollectedEvent; +import com.xiaojukeji.kafka.manager.common.utils.ValidateUtils; +import com.xiaojukeji.kafka.manager.common.utils.jmx.JmxConstant; +import com.xiaojukeji.kafka.manager.common.zookeeper.znode.brokers.TopicMetadata; +import com.xiaojukeji.kafka.manager.dao.ClusterMetricsDao; +import com.xiaojukeji.kafka.manager.service.cache.PhysicalClusterMetadataManager; +import com.xiaojukeji.kafka.manager.service.utils.MetricsConvertUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; +import org.springframework.context.ApplicationListener; +import org.springframework.stereotype.Component; + +import java.util.Arrays; +import java.util.List; +import java.util.Map; + +/** + * @author zengqiao + * @date 22/01/17 + */ +@Component +@ConditionalOnProperty(prefix = "task.metrics.sink.cluster-metrics", name = "sink-db-enabled", havingValue = "true", matchIfMissing = true) +public class SinkClusterMetrics2DB implements ApplicationListener { + private static final Logger logger = LoggerFactory.getLogger(SinkClusterMetrics2DB.class); + + @Autowired + private ClusterMetricsDao clusterMetricsDao; + + @Override + public void onApplicationEvent(BatchBrokerMetricsCollectedEvent event) { + logger.debug("sink cluster-metrics to db start, event:{}.", event); + + List metricsList = event.getMetricsList(); + if (ValidateUtils.isEmptyList(metricsList)) { + logger.warn("sink cluster-metrics to db finished, without need sink, event:{}.", event); + return; + } + + List doList = MetricsConvertUtils.convertAndUpdateCreateTime2ClusterMetricsDOList( + event.getCollectTime(), + // 合并broker-metrics为cluster-metrics + Arrays.asList(supplyAndConvert2ClusterMetrics(event.getPhysicalClusterId(), MetricsConvertUtils.merge2BaseMetricsByAdd(event.getMetricsList()))) + ); + + if (ValidateUtils.isEmptyList(doList)) { + logger.warn("sink cluster-metrics to db finished, without need sink, event:{}.", event); + return; + } + + clusterMetricsDao.batchAdd(doList); + + logger.debug("sink cluster-metrics to db finished, event:{}.", event); + } + + private ClusterMetrics supplyAndConvert2ClusterMetrics(Long clusterId, BaseMetrics baseMetrics) { + ClusterMetrics metrics = new ClusterMetrics(clusterId); + Map metricsMap = metrics.getMetricsMap(); + metricsMap.putAll(baseMetrics.getMetricsMap()); + metricsMap.put(JmxConstant.TOPIC_NUM, PhysicalClusterMetadataManager.getTopicNameList(clusterId).size()); + metricsMap.put(JmxConstant.BROKER_NUM, PhysicalClusterMetadataManager.getBrokerIdList(clusterId).size()); + Integer partitionNum = 0; + for (String topicName : PhysicalClusterMetadataManager.getTopicNameList(clusterId)) { + TopicMetadata topicMetaData = PhysicalClusterMetadataManager.getTopicMetadata(clusterId, topicName); + if (ValidateUtils.isNull(topicMetaData)) { + continue; + } + partitionNum += topicMetaData.getPartitionNum(); + } + metricsMap.put(JmxConstant.PARTITION_NUM, partitionNum); + return metrics; + } +} \ No newline at end of file diff --git a/kafka-manager-task/src/main/java/com/xiaojukeji/kafka/manager/task/listener/StoreCommunityTopicMetrics2DB.java b/kafka-manager-task/src/main/java/com/xiaojukeji/kafka/manager/task/listener/sink/db/StoreCommunityTopicMetrics2DB.java similarity index 97% rename from kafka-manager-task/src/main/java/com/xiaojukeji/kafka/manager/task/listener/StoreCommunityTopicMetrics2DB.java rename to kafka-manager-task/src/main/java/com/xiaojukeji/kafka/manager/task/listener/sink/db/StoreCommunityTopicMetrics2DB.java index f75368d2..267e32b7 100644 --- a/kafka-manager-task/src/main/java/com/xiaojukeji/kafka/manager/task/listener/StoreCommunityTopicMetrics2DB.java +++ b/kafka-manager-task/src/main/java/com/xiaojukeji/kafka/manager/task/listener/sink/db/StoreCommunityTopicMetrics2DB.java @@ -1,4 +1,4 @@ -package com.xiaojukeji.kafka.manager.task.listener; +package com.xiaojukeji.kafka.manager.task.listener.sink.db; import com.xiaojukeji.kafka.manager.common.constant.Constant; import com.xiaojukeji.kafka.manager.common.constant.LogConstant; diff --git a/kafka-manager-task/src/main/java/com/xiaojukeji/kafka/manager/task/listener/StoreTopicThrottledMetrics2DB.java b/kafka-manager-task/src/main/java/com/xiaojukeji/kafka/manager/task/listener/sink/db/StoreTopicThrottledMetrics2DB.java similarity index 98% rename from kafka-manager-task/src/main/java/com/xiaojukeji/kafka/manager/task/listener/StoreTopicThrottledMetrics2DB.java rename to kafka-manager-task/src/main/java/com/xiaojukeji/kafka/manager/task/listener/sink/db/StoreTopicThrottledMetrics2DB.java index e94a2793..c2d74df3 100644 --- a/kafka-manager-task/src/main/java/com/xiaojukeji/kafka/manager/task/listener/StoreTopicThrottledMetrics2DB.java +++ b/kafka-manager-task/src/main/java/com/xiaojukeji/kafka/manager/task/listener/sink/db/StoreTopicThrottledMetrics2DB.java @@ -1,4 +1,4 @@ -package com.xiaojukeji.kafka.manager.task.listener; +package com.xiaojukeji.kafka.manager.task.listener.sink.db; import com.xiaojukeji.kafka.manager.common.bizenum.KafkaClientEnum; import com.xiaojukeji.kafka.manager.common.constant.Constant; diff --git a/kafka-manager-task/src/main/java/com/xiaojukeji/kafka/manager/task/listener/SinkCommunityTopicMetrics2Kafka.java b/kafka-manager-task/src/main/java/com/xiaojukeji/kafka/manager/task/listener/sink/kafka/SinkCommunityTopicMetrics2Kafka.java similarity index 98% rename from kafka-manager-task/src/main/java/com/xiaojukeji/kafka/manager/task/listener/SinkCommunityTopicMetrics2Kafka.java rename to kafka-manager-task/src/main/java/com/xiaojukeji/kafka/manager/task/listener/sink/kafka/SinkCommunityTopicMetrics2Kafka.java index ad80ceb2..5f3a0e5c 100644 --- a/kafka-manager-task/src/main/java/com/xiaojukeji/kafka/manager/task/listener/SinkCommunityTopicMetrics2Kafka.java +++ b/kafka-manager-task/src/main/java/com/xiaojukeji/kafka/manager/task/listener/sink/kafka/SinkCommunityTopicMetrics2Kafka.java @@ -1,4 +1,4 @@ -package com.xiaojukeji.kafka.manager.task.listener; +package com.xiaojukeji.kafka.manager.task.listener.sink.kafka; import com.xiaojukeji.kafka.manager.common.constant.ConfigConstant; import com.xiaojukeji.kafka.manager.common.constant.LogConstant; diff --git a/kafka-manager-task/src/main/java/com/xiaojukeji/kafka/manager/task/listener/SinkConsumerMetrics2Kafka.java b/kafka-manager-task/src/main/java/com/xiaojukeji/kafka/manager/task/listener/sink/kafka/SinkConsumerMetrics2Kafka.java similarity index 98% rename from kafka-manager-task/src/main/java/com/xiaojukeji/kafka/manager/task/listener/SinkConsumerMetrics2Kafka.java rename to kafka-manager-task/src/main/java/com/xiaojukeji/kafka/manager/task/listener/sink/kafka/SinkConsumerMetrics2Kafka.java index 7070dae1..eb6c2d37 100644 --- a/kafka-manager-task/src/main/java/com/xiaojukeji/kafka/manager/task/listener/SinkConsumerMetrics2Kafka.java +++ b/kafka-manager-task/src/main/java/com/xiaojukeji/kafka/manager/task/listener/sink/kafka/SinkConsumerMetrics2Kafka.java @@ -1,4 +1,4 @@ -package com.xiaojukeji.kafka.manager.task.listener; +package com.xiaojukeji.kafka.manager.task.listener.sink.kafka; import com.xiaojukeji.kafka.manager.common.constant.ConfigConstant; import com.xiaojukeji.kafka.manager.common.constant.LogConstant; diff --git a/kafka-manager-task/src/main/java/com/xiaojukeji/kafka/manager/task/listener/SinkCommunityTopicMetrics2Monitor.java b/kafka-manager-task/src/main/java/com/xiaojukeji/kafka/manager/task/listener/sink/monitor/SinkCommunityTopicMetrics2Monitor.java similarity index 98% rename from kafka-manager-task/src/main/java/com/xiaojukeji/kafka/manager/task/listener/SinkCommunityTopicMetrics2Monitor.java rename to kafka-manager-task/src/main/java/com/xiaojukeji/kafka/manager/task/listener/sink/monitor/SinkCommunityTopicMetrics2Monitor.java index e2ac74a9..80b3eccd 100644 --- a/kafka-manager-task/src/main/java/com/xiaojukeji/kafka/manager/task/listener/SinkCommunityTopicMetrics2Monitor.java +++ b/kafka-manager-task/src/main/java/com/xiaojukeji/kafka/manager/task/listener/sink/monitor/SinkCommunityTopicMetrics2Monitor.java @@ -1,4 +1,4 @@ -package com.xiaojukeji.kafka.manager.task.listener; +package com.xiaojukeji.kafka.manager.task.listener.sink.monitor; import com.xiaojukeji.kafka.manager.monitor.common.entry.bizenum.MonitorMetricNameEnum; import com.xiaojukeji.kafka.manager.common.constant.LogConstant; diff --git a/kafka-manager-task/src/main/java/com/xiaojukeji/kafka/manager/task/listener/SinkConsumerMetrics2Monitor.java b/kafka-manager-task/src/main/java/com/xiaojukeji/kafka/manager/task/listener/sink/monitor/SinkConsumerMetrics2Monitor.java similarity index 99% rename from kafka-manager-task/src/main/java/com/xiaojukeji/kafka/manager/task/listener/SinkConsumerMetrics2Monitor.java rename to kafka-manager-task/src/main/java/com/xiaojukeji/kafka/manager/task/listener/sink/monitor/SinkConsumerMetrics2Monitor.java index 4ca276f9..a5c2e008 100644 --- a/kafka-manager-task/src/main/java/com/xiaojukeji/kafka/manager/task/listener/SinkConsumerMetrics2Monitor.java +++ b/kafka-manager-task/src/main/java/com/xiaojukeji/kafka/manager/task/listener/sink/monitor/SinkConsumerMetrics2Monitor.java @@ -1,4 +1,4 @@ -package com.xiaojukeji.kafka.manager.task.listener; +package com.xiaojukeji.kafka.manager.task.listener.sink.monitor; import com.xiaojukeji.kafka.manager.monitor.common.entry.bizenum.MonitorMetricNameEnum; import com.xiaojukeji.kafka.manager.common.constant.LogConstant; diff --git a/kafka-manager-task/src/main/java/com/xiaojukeji/kafka/manager/task/listener/SinkTopicThrottledMetrics2Monitor.java b/kafka-manager-task/src/main/java/com/xiaojukeji/kafka/manager/task/listener/sink/monitor/SinkTopicThrottledMetrics2Monitor.java similarity index 98% rename from kafka-manager-task/src/main/java/com/xiaojukeji/kafka/manager/task/listener/SinkTopicThrottledMetrics2Monitor.java rename to kafka-manager-task/src/main/java/com/xiaojukeji/kafka/manager/task/listener/sink/monitor/SinkTopicThrottledMetrics2Monitor.java index fb95947c..ff1cb823 100644 --- a/kafka-manager-task/src/main/java/com/xiaojukeji/kafka/manager/task/listener/SinkTopicThrottledMetrics2Monitor.java +++ b/kafka-manager-task/src/main/java/com/xiaojukeji/kafka/manager/task/listener/sink/monitor/SinkTopicThrottledMetrics2Monitor.java @@ -1,4 +1,4 @@ -package com.xiaojukeji.kafka.manager.task.listener; +package com.xiaojukeji.kafka.manager.task.listener.sink.monitor; import com.xiaojukeji.kafka.manager.common.bizenum.KafkaClientEnum; import com.xiaojukeji.kafka.manager.monitor.common.MonitorSinkConstant; diff --git a/kafka-manager-web/src/main/resources/application.yml b/kafka-manager-web/src/main/resources/application.yml index 3cce7463..4f83afb5 100644 --- a/kafka-manager-web/src/main/resources/application.yml +++ b/kafka-manager-web/src/main/resources/application.yml @@ -33,7 +33,6 @@ custom: idc: cn store-metrics-task: community: - broker-metrics-enabled: true topic-metrics-enabled: true didi: # 滴滴Kafka特有的指标 app-topic-metrics-enabled: false @@ -43,13 +42,20 @@ custom: # 任务相关的配置 task: op: - sync-topic-enabled: false # 未落盘的Topic定期同步到DB中 - order-auto-exec: # 工单自动化审批线程的开关 - topic-enabled: false # Topic工单自动化审批开关, false:关闭自动化审批, true:开启 - app-enabled: false # App工单自动化审批开关, false:关闭自动化审批, true:开启 + sync-topic-enabled: false # 未落盘的Topic定期同步到DB中 + order-auto-exec: # 工单自动化审批线程的开关 + topic-enabled: false # Topic工单自动化审批开关, false:关闭自动化审批, true:开启 + app-enabled: false # App工单自动化审批开关, false:关闭自动化审批, true:开启 metrics: - delete-metrics: - delete-limit-size: 1000 + collect: # 收集指标 + broker-metrics-enabled: true # 收集Broker指标 + sink: # 上报指标 + cluster-metrics: # 上报cluster指标 + sink-db-enabled: true # 上报到db + broker-metrics: # 上报broker指标 + sink-db-enabled: true # 上报到db + delete: # 删除指标 + delete-limit-size: 1000 # 单次删除的批大小 cluster-metrics-save-days: 14 # 集群指标保存天数 broker-metrics-save-days: 14 # Broker指标保存天数 topic-metrics-save-days: 7 # Topic指标保存天数 @@ -57,6 +63,21 @@ task: topic-throttled-metrics-save-days: 7 # Topic限流指标保存天数 app-topic-metrics-save-days: 7 # App+Topic指标保存天数 +thread-pool: + collect-metrics: + thread-num: 256 # 收集指标线程池大小 + queue-size: 5000 # 收集指标线程池的queue大小 + api-call: + thread-num: 16 # api服务线程池大小 + queue-size: 5000 # api服务线程池的queue大小 + +client-pool: + kafka-consumer: + min-idle-client-num: 24 # 最小空闲客户端数 + max-idle-client-num: 24 # 最大空闲客户端数 + max-total-client-num: 24 # 最大客户端数 + borrow-timeout-unit-ms: 3000 # 租借超时时间,单位毫秒 + account: ldap: enabled: false @@ -103,18 +124,3 @@ notify: topic-name: didi-kafka-notify order: detail-url: http://127.0.0.1 - -thread-pool: - collect-metrics: - thread-num: 256 # 收集指标线程池大小 - queue-size: 5000 # 收集指标线程池的queue大小 - api-call: - thread-num: 16 # api服务线程池大小 - queue-size: 5000 # api服务线程池的queue大小 - -client-pool: - kafka-consumer: - min-idle-client-num: 24 # 最小空闲客户端数 - max-idle-client-num: 24 # 最大空闲客户端数 - max-total-client-num: 24 # 最大客户端数 - borrow-timeout-unit-ms: 3000 # 租借超时时间,单位毫秒 From f3f0432c65ed4e5cb68aa2c4f09ffed95fcab8c5 Mon Sep 17 00:00:00 2001 From: zengqiao Date: Mon, 17 Jan 2022 20:41:53 +0800 Subject: [PATCH 12/19] =?UTF-8?q?1.=E5=AE=89=E8=A3=85=E9=83=A8=E7=BD=B2?= =?UTF-8?q?=E8=84=9A=E6=9C=ACLogiKM=E5=8F=AF=E9=85=8D=E7=BD=AE;=202.?= =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E7=BD=91=E5=85=B3=E6=8E=A5=E5=8F=A3=E5=8F=8A?= =?UTF-8?q?=E7=AC=AC=E4=B8=89=E6=96=B9=E6=8E=A5=E5=8F=A3=E5=8F=AF=E7=9B=B4?= =?UTF-8?q?=E6=8E=A5=E8=B0=83=E7=94=A8=E7=9A=84=E5=BC=80=E5=85=B3;?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- distribution/conf/application.yml.example | 22 +++++++++++-------- .../manager/common/constant/ApiPrefix.java | 6 ----- .../account/impl/LoginServiceImpl.java | 15 ++++++++++--- .../manager/kcm/component/agent/n9e/N9e.java | 16 +++++++++----- .../src/main/resources/kcm_script.sh | 12 +++++----- .../thirdpart/ThirdPartBrokerController.java | 6 ++--- .../src/main/resources/application.yml | 22 +++++++++++-------- 7 files changed, 58 insertions(+), 41 deletions(-) diff --git a/distribution/conf/application.yml.example b/distribution/conf/application.yml.example index ee0290d8..f777ce31 100644 --- a/distribution/conf/application.yml.example +++ b/distribution/conf/application.yml.example @@ -85,6 +85,9 @@ client-pool: borrow-timeout-unit-ms: 3000 # 租借超时时间,单位毫秒 account: + jump-login: + gateway-api: false # 网关接口 + third-part-api: false # 第三方接口 ldap: enabled: false url: ldap://127.0.0.1:389/ @@ -98,19 +101,20 @@ account: auth-user-registration: true auth-user-registration-role: normal -kcm: - enabled: false - s3: +kcm: # 集群安装部署,仅安装broker + enabled: false # 是否开启 + s3: # s3 存储服务 endpoint: s3.didiyunapi.com access-key: 1234567890 secret-key: 0987654321 bucket: logi-kafka - n9e: - base-url: http://127.0.0.1:8004 - user-token: 12345678 - timeout: 300 - account: root - script-file: kcm_script.sh + n9e: # 夜莺 + base-url: http://127.0.0.1:8004 # 夜莺job服务地址 + user-token: 12345678 # 用户的token + timeout: 300 # 当台操作的超时时间 + account: root # 操作时使用的账号 + script-file: kcm_script.sh # 脚本,已内置好,在源码的kcm模块内,此处配置无需修改 + logikm-url: http://127.0.0.1:8080 # logikm部署地址,部署时kcm_script.sh会调用logikm检查部署中的一些状态 monitor: enabled: false diff --git a/kafka-manager-common/src/main/java/com/xiaojukeji/kafka/manager/common/constant/ApiPrefix.java b/kafka-manager-common/src/main/java/com/xiaojukeji/kafka/manager/common/constant/ApiPrefix.java index b0f84405..5422076c 100644 --- a/kafka-manager-common/src/main/java/com/xiaojukeji/kafka/manager/common/constant/ApiPrefix.java +++ b/kafka-manager-common/src/main/java/com/xiaojukeji/kafka/manager/common/constant/ApiPrefix.java @@ -20,12 +20,6 @@ public class ApiPrefix { // open public static final String API_V1_THIRD_PART_PREFIX = API_V1_PREFIX + "third-part/"; - // 开放给OP的接口, 后续对 应的接口的集群都需要是物理集群 - public static final String API_V1_THIRD_PART_OP_PREFIX = API_V1_THIRD_PART_PREFIX + "op/"; - - // 开放给Normal的接口, 后续对应的接口的集群,都需要是逻辑集群 - public static final String API_V1_THIRD_PART_NORMAL_PREFIX = API_V1_THIRD_PART_PREFIX + "normal/"; - // gateway public static final String GATEWAY_API_V1_PREFIX = "/gateway" + API_V1_PREFIX; diff --git a/kafka-manager-extends/kafka-manager-account/src/main/java/com/xiaojukeji/kafka/manager/account/impl/LoginServiceImpl.java b/kafka-manager-extends/kafka-manager-account/src/main/java/com/xiaojukeji/kafka/manager/account/impl/LoginServiceImpl.java index f49f7dca..f0299d87 100644 --- a/kafka-manager-extends/kafka-manager-account/src/main/java/com/xiaojukeji/kafka/manager/account/impl/LoginServiceImpl.java +++ b/kafka-manager-extends/kafka-manager-account/src/main/java/com/xiaojukeji/kafka/manager/account/impl/LoginServiceImpl.java @@ -14,6 +14,7 @@ import com.xiaojukeji.kafka.manager.common.utils.ValidateUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Service; import javax.servlet.http.Cookie; @@ -27,7 +28,13 @@ import javax.servlet.http.HttpSession; */ @Service("loginService") public class LoginServiceImpl implements LoginService { - private final static Logger LOGGER = LoggerFactory.getLogger(LoginServiceImpl.class); + private static final Logger LOGGER = LoggerFactory.getLogger(LoginServiceImpl.class); + + @Value(value = "${account.jump-login.gateway-api:false}") + private Boolean jumpLoginGatewayApi; + + @Value(value = "${account.jump-login.third-part-api:false}") + private Boolean jumpLoginThirdPartApi; @Autowired private AccountService accountService; @@ -75,8 +82,10 @@ public class LoginServiceImpl implements LoginService { return false; } - if (classRequestMappingValue.equals(ApiPrefix.API_V1_SSO_PREFIX)) { - // 白名单接口直接true + if (classRequestMappingValue.equals(ApiPrefix.API_V1_SSO_PREFIX) || + (jumpLoginGatewayApi != null && jumpLoginGatewayApi && classRequestMappingValue.equals(ApiPrefix.GATEWAY_API_V1_PREFIX)) || + (jumpLoginThirdPartApi != null && jumpLoginThirdPartApi && classRequestMappingValue.equals(ApiPrefix.API_V1_THIRD_PART_PREFIX))) { + // 登录接口 or 允许跳过且是跳过类型的接口,则直接跳过登录 return true; } diff --git a/kafka-manager-extends/kafka-manager-kcm/src/main/java/com/xiaojukeji/kafka/manager/kcm/component/agent/n9e/N9e.java b/kafka-manager-extends/kafka-manager-kcm/src/main/java/com/xiaojukeji/kafka/manager/kcm/component/agent/n9e/N9e.java index 6e3fa677..d0a2503b 100644 --- a/kafka-manager-extends/kafka-manager-kcm/src/main/java/com/xiaojukeji/kafka/manager/kcm/component/agent/n9e/N9e.java +++ b/kafka-manager-extends/kafka-manager-kcm/src/main/java/com/xiaojukeji/kafka/manager/kcm/component/agent/n9e/N9e.java @@ -37,21 +37,24 @@ import java.util.Map; public class N9e extends AbstractAgent { private static final Logger LOGGER = LoggerFactory.getLogger(N9e.class); - @Value("${kcm.n9e.base-url}") + @Value("${kcm.n9e.base-url:}") private String baseUrl; - @Value("${kcm.n9e.user-token}") + @Value("${kcm.n9e.user-token:12345678}") private String userToken; - @Value("${kcm.n9e.account}") + @Value("${kcm.n9e.account:root}") private String account; - @Value("${kcm.n9e.timeout}") + @Value("${kcm.n9e.timeout:300}") private Integer timeout; - @Value("${kcm.n9e.script-file}") + @Value("${kcm.n9e.script-file:kcm_script.sh}") private String scriptFile; + @Value("${kcm.n9e.logikm-url:}") + private String logiKMUrl; + private String script; private static final String CREATE_TASK_URI = "/api/job-ce/tasks"; @@ -219,7 +222,8 @@ public class N9e extends AbstractAgent { sb.append(creationTaskData.getKafkaPackageUrl()).append(",,"); sb.append(creationTaskData.getServerPropertiesName().replace(KafkaFileEnum.SERVER_CONFIG.getSuffix(), "")).append(",,"); sb.append(creationTaskData.getServerPropertiesMd5()).append(",,"); - sb.append(creationTaskData.getServerPropertiesUrl()); + sb.append(creationTaskData.getServerPropertiesUrl()).append(",,"); + sb.append(this.logiKMUrl); N9eCreationTask n9eCreationTask = new N9eCreationTask(); n9eCreationTask.setTitle(Constant.TASK_TITLE_PREFIX + "-集群ID:" + creationTaskData.getClusterId()); diff --git a/kafka-manager-extends/kafka-manager-kcm/src/main/resources/kcm_script.sh b/kafka-manager-extends/kafka-manager-kcm/src/main/resources/kcm_script.sh index ffd54a20..16ffb80c 100644 --- a/kafka-manager-extends/kafka-manager-kcm/src/main/resources/kcm_script.sh +++ b/kafka-manager-extends/kafka-manager-kcm/src/main/resources/kcm_script.sh @@ -18,12 +18,13 @@ p_kafka_server_properties_name=${7} #server配置名 p_kafka_server_properties_md5=${8} #server配置MD5 p_kafka_server_properties_url=${9} #server配置文件下载地址 +p_kafka_manager_url=${10} #LogiKM地址 + #----------------------------------------配置信息------------------------------------------------------# g_base_dir='/home' g_cluster_task_dir=${g_base_dir}"/kafka_cluster_task/task_${p_task_id}" #部署升级路径 g_rollback_version=${g_cluster_task_dir}"/rollback_version" #回滚版本 g_new_kafka_package_name='' #最终的包名 -g_kafka_manager_addr='' #kafka-manager地址 g_local_ip=`ifconfig -a|grep inet|grep -v 127.0.0.1|grep -v inet6|awk '{print $2}'|tr -d "addr:"` g_hostname=${g_local_ip} @@ -47,7 +48,7 @@ function dchat_alarm() { # 检查并初始化环境 function check_and_init_env() { - if [ -z "${p_task_id}" -o -z "${p_cluster_task_type}" -o -z "${p_kafka_package_url}" -o -z "${p_cluster_id}" -o -z "${p_kafka_package_name}" -o -z "${p_kafka_package_md5}" -o -z "${p_kafka_server_properties_name}" -o -z "${p_kafka_server_properties_md5}" ]; then + if [ -z "${p_task_id}" -o -z "${p_cluster_task_type}" -o -z "${p_kafka_package_url}" -o -z "${p_cluster_id}" -o -z "${p_kafka_package_name}" -o -z "${p_kafka_package_md5}" -o -z "${p_kafka_server_properties_name}" -o -z "${p_kafka_server_properties_md5}" -o -z "${p_kafka_manager_url}" ]; then ECHO_LOG "存在为空的参数不合法, 退出集群任务" dchat_alarm "存在为空的参数不合法, 退出集群任务" exit 1 @@ -72,11 +73,11 @@ function check_and_init_env() { # 检查并等待集群所有的副本处于同步的状态 function check_and_wait_broker_stabled() { - under_replication_count=`curl -s -G -d "hostname="${g_hostname} ${g_kafka_manager_addr}/api/v1/third-part/${p_cluster_id}/broker-stabled | python -m json.tool | grep true |wc -l` + under_replication_count=`curl -s -G -d "hostname="${g_hostname} ${p_kafka_manager_url}/api/v1/third-part/${p_cluster_id}/broker-stabled | python -m json.tool | grep true |wc -l` while [ "$under_replication_count" -ne 1 ]; do ECHO_LOG "存在${under_replication_count}个副本未同步, sleep 10s" sleep 10 - under_replication_count=`curl -s -G -d "hostname="${g_hostname} ${g_kafka_manager_addr}/api/v1/third-part/${p_cluster_id}/broker-stabled | python -m json.tool | grep true |wc -l` + under_replication_count=`curl -s -G -d "hostname="${g_hostname} ${p_kafka_manager_url}/api/v1/third-part/${p_cluster_id}/broker-stabled | python -m json.tool | grep true |wc -l` done ECHO_LOG "集群副本都已经处于同步的状态, 可以进行集群升级" } @@ -324,6 +325,7 @@ ECHO_LOG " p_kafka_package_name=${p_kafka_package_name}" ECHO_LOG " p_kafka_package_md5=${p_kafka_package_md5}" ECHO_LOG " p_kafka_server_properties_name=${p_kafka_server_properties_name}" ECHO_LOG " p_kafka_server_properties_md5=${p_kafka_server_properties_md5}" +ECHO_LOG " p_kafka_manager_url=${p_kafka_manager_url}" @@ -342,7 +344,7 @@ fi ECHO_LOG "停kafka服务" stop_kafka_server -ECHO_LOG "停5秒, 确保" +ECHO_LOG "再停5秒, 确保端口已释放" sleep 5 if [ "${p_cluster_task_type}" == "0" ];then diff --git a/kafka-manager-web/src/main/java/com/xiaojukeji/kafka/manager/web/api/versionone/thirdpart/ThirdPartBrokerController.java b/kafka-manager-web/src/main/java/com/xiaojukeji/kafka/manager/web/api/versionone/thirdpart/ThirdPartBrokerController.java index 790b85be..8469afec 100644 --- a/kafka-manager-web/src/main/java/com/xiaojukeji/kafka/manager/web/api/versionone/thirdpart/ThirdPartBrokerController.java +++ b/kafka-manager-web/src/main/java/com/xiaojukeji/kafka/manager/web/api/versionone/thirdpart/ThirdPartBrokerController.java @@ -32,7 +32,7 @@ import java.util.stream.Collectors; */ @Api(tags = "开放接口-Broker相关接口(REST)") @RestController -@RequestMapping(ApiPrefix.API_V1_THIRD_PART_OP_PREFIX) +@RequestMapping(ApiPrefix.API_V1_THIRD_PART_PREFIX) public class ThirdPartBrokerController { @Autowired private BrokerService brokerService; @@ -44,7 +44,7 @@ public class ThirdPartBrokerController { private ClusterService clusterService; @ApiOperation(value = "Broker信息概览", notes = "") - @RequestMapping(value = "{clusterId}/brokers/{brokerId}/overview", method = RequestMethod.GET) + @GetMapping(value = "{clusterId}/brokers/{brokerId}/overview") @ResponseBody public Result getBrokerOverview(@PathVariable Long clusterId, @PathVariable Integer brokerId) { @@ -70,7 +70,7 @@ public class ThirdPartBrokerController { } @ApiOperation(value = "BrokerRegion信息", notes = "所有集群的") - @RequestMapping(value = "broker-regions", method = RequestMethod.GET) + @GetMapping(value = "broker-regions") @ResponseBody public Result> getBrokerRegions() { List clusterDOList = clusterService.list(); diff --git a/kafka-manager-web/src/main/resources/application.yml b/kafka-manager-web/src/main/resources/application.yml index 4f83afb5..9cd51d46 100644 --- a/kafka-manager-web/src/main/resources/application.yml +++ b/kafka-manager-web/src/main/resources/application.yml @@ -79,6 +79,9 @@ client-pool: borrow-timeout-unit-ms: 3000 # 租借超时时间,单位毫秒 account: + jump-login: + gateway-api: false # 网关接口 + third-part-api: false # 第三方接口 ldap: enabled: false url: ldap://127.0.0.1:389/ @@ -92,19 +95,20 @@ account: auth-user-registration: true auth-user-registration-role: normal -kcm: - enabled: false - s3: +kcm: # 集群安装部署,仅安装broker + enabled: false # 是否开启 + s3: # s3 存储服务 endpoint: s3.didiyunapi.com access-key: 1234567890 secret-key: 0987654321 bucket: logi-kafka - n9e: - base-url: http://127.0.0.1:8004 - user-token: 12345678 - timeout: 300 - account: root - script-file: kcm_script.sh + n9e: # 夜莺 + base-url: http://127.0.0.1:8004 # 夜莺job服务地址 + user-token: 12345678 # 用户的token + timeout: 300 # 当台操作的超时时间 + account: root # 操作时使用的账号 + script-file: kcm_script.sh # 脚本,已内置好,在源码的kcm模块内,此处配置无需修改 + logikm-url: http://127.0.0.1:8080 # logikm部署地址,部署时kcm_script.sh会调用logikm检查部署中的一些状态 monitor: enabled: false From 71c52e6dd7e10a14c80972adce8bded997b181b9 Mon Sep 17 00:00:00 2001 From: zengqiao Date: Mon, 17 Jan 2022 21:18:06 +0800 Subject: [PATCH 13/19] bump springboot version to 2.1.18 and ignore springframework version config --- kafka-manager-common/pom.xml | 3 --- kafka-manager-core/pom.xml | 3 --- kafka-manager-extends/kafka-manager-kcm/pom.xml | 4 ---- kafka-manager-extends/kafka-manager-monitor/pom.xml | 3 --- kafka-manager-extends/kafka-manager-notify/pom.xml | 2 -- kafka-manager-extends/kafka-manager-openapi/pom.xml | 2 -- kafka-manager-task/pom.xml | 2 -- kafka-manager-web/pom.xml | 4 ++-- pom.xml | 2 +- 9 files changed, 3 insertions(+), 22 deletions(-) diff --git a/kafka-manager-common/pom.xml b/kafka-manager-common/pom.xml index f6c33def..f784bf8d 100644 --- a/kafka-manager-common/pom.xml +++ b/kafka-manager-common/pom.xml @@ -21,15 +21,12 @@ 1.8 UTF-8 UTF-8 - - 5.1.3.RELEASE org.springframework spring-web - ${spring-version} diff --git a/kafka-manager-core/pom.xml b/kafka-manager-core/pom.xml index 81675a43..e00663ed 100644 --- a/kafka-manager-core/pom.xml +++ b/kafka-manager-core/pom.xml @@ -24,7 +24,6 @@ 1.8 UTF-8 UTF-8 - 5.1.3.RELEASE @@ -38,12 +37,10 @@ org.springframework spring-web - ${spring-version} org.springframework spring-test - ${spring-version} diff --git a/kafka-manager-extends/kafka-manager-kcm/pom.xml b/kafka-manager-extends/kafka-manager-kcm/pom.xml index 7ffd00e3..12a942d5 100644 --- a/kafka-manager-extends/kafka-manager-kcm/pom.xml +++ b/kafka-manager-extends/kafka-manager-kcm/pom.xml @@ -28,7 +28,6 @@ 1.8 UTF-8 UTF-8 - 5.1.3.RELEASE @@ -56,17 +55,14 @@ org.springframework spring-beans - ${spring-version} org.springframework spring-context - ${spring-version} org.springframework spring-test - ${spring-version} diff --git a/kafka-manager-extends/kafka-manager-monitor/pom.xml b/kafka-manager-extends/kafka-manager-monitor/pom.xml index 0948a190..9f04b7c9 100644 --- a/kafka-manager-extends/kafka-manager-monitor/pom.xml +++ b/kafka-manager-extends/kafka-manager-monitor/pom.xml @@ -25,7 +25,6 @@ 1.8 UTF-8 UTF-8 - 5.1.3.RELEASE @@ -63,12 +62,10 @@ org.springframework spring-beans - ${spring-version} org.springframework spring-context - ${spring-version} \ No newline at end of file diff --git a/kafka-manager-extends/kafka-manager-notify/pom.xml b/kafka-manager-extends/kafka-manager-notify/pom.xml index a2fd2c4b..348164eb 100644 --- a/kafka-manager-extends/kafka-manager-notify/pom.xml +++ b/kafka-manager-extends/kafka-manager-notify/pom.xml @@ -25,7 +25,6 @@ 1.8 UTF-8 UTF-8 - 5.1.3.RELEASE @@ -48,7 +47,6 @@ org.springframework spring-context - ${spring-version} \ No newline at end of file diff --git a/kafka-manager-extends/kafka-manager-openapi/pom.xml b/kafka-manager-extends/kafka-manager-openapi/pom.xml index caaa1242..cc6f3316 100644 --- a/kafka-manager-extends/kafka-manager-openapi/pom.xml +++ b/kafka-manager-extends/kafka-manager-openapi/pom.xml @@ -24,7 +24,6 @@ 1.8 UTF-8 UTF-8 - 5.1.3.RELEASE @@ -46,7 +45,6 @@ org.springframework spring-context - ${spring-version} \ No newline at end of file diff --git a/kafka-manager-task/pom.xml b/kafka-manager-task/pom.xml index 8927ef8e..dce8d3c8 100644 --- a/kafka-manager-task/pom.xml +++ b/kafka-manager-task/pom.xml @@ -24,7 +24,6 @@ 1.8 UTF-8 UTF-8 - 5.1.3.RELEASE @@ -52,7 +51,6 @@ org.springframework spring-context - ${spring-version} \ No newline at end of file diff --git a/kafka-manager-web/pom.xml b/kafka-manager-web/pom.xml index 91b09fc5..2308c6f8 100644 --- a/kafka-manager-web/pom.xml +++ b/kafka-manager-web/pom.xml @@ -16,8 +16,8 @@ 1.8 1.8 - 2.1.1.RELEASE - 5.1.3.RELEASE + 2.1.18.RELEASE + 5.1.19.RELEASE false 8.5.72 2.16.0 diff --git a/pom.xml b/pom.xml index e790bfd3..7c0831b9 100644 --- a/pom.xml +++ b/pom.xml @@ -11,7 +11,7 @@ org.springframework.boot spring-boot-starter-parent - 2.1.1.RELEASE + 2.1.18.RELEASE From e2744ab3990225fe8ec998b484ddf5a9c8ac2b09 Mon Sep 17 00:00:00 2001 From: zengqiao Date: Tue, 18 Jan 2022 14:00:20 +0800 Subject: [PATCH 14/19] bump version to 2.6.0 --- kafka-manager-web/pom.xml | 15 ++++++--------- pom.xml | 3 ++- 2 files changed, 8 insertions(+), 10 deletions(-) diff --git a/kafka-manager-web/pom.xml b/kafka-manager-web/pom.xml index 2308c6f8..80ccdfe1 100644 --- a/kafka-manager-web/pom.xml +++ b/kafka-manager-web/pom.xml @@ -16,8 +16,6 @@ 1.8 1.8 - 2.1.18.RELEASE - 5.1.19.RELEASE false 8.5.72 2.16.0 @@ -73,22 +71,22 @@ org.springframework.boot spring-boot-starter-web - ${springframework.boot.version} + ${spring.boot.version} org.springframework.boot spring-boot-starter-aop - ${springframework.boot.version} + ${spring.boot.version} org.springframework.boot spring-boot-starter-logging - ${springframework.boot.version} + ${spring.boot.version} org.springframework.boot spring-boot-starter-thymeleaf - ${springframework.boot.version} + ${spring.boot.version} junit @@ -105,18 +103,17 @@ org.springframework spring-context-support - ${spring-version} kafka-manager - + org.springframework.boot spring-boot-maven-plugin - ${springframework.boot.version} + ${spring.boot.version} diff --git a/pom.xml b/pom.xml index 7c0831b9..8b8db3a2 100644 --- a/pom.xml +++ b/pom.xml @@ -16,7 +16,8 @@ - 2.5 + 2.6.0 + 2.1.18.RELEASE 2.9.2 1.5.21 From 859cf74bd646e39693277d9b6990c320d6662987 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=AD=99=E8=B6=85?= Date: Tue, 18 Jan 2022 14:05:32 +0800 Subject: [PATCH 15/19] =?UTF-8?q?2.6.0=E9=97=AE=E9=A2=98=E4=BF=AE=E5=A4=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/container/admin/cluster-list/index.tsx | 2 +- kafka-manager-console/src/container/header/index.tsx | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/kafka-manager-console/src/container/admin/cluster-list/index.tsx b/kafka-manager-console/src/container/admin/cluster-list/index.tsx index be6956d6..cdd197fa 100644 --- a/kafka-manager-console/src/container/admin/cluster-list/index.tsx +++ b/kafka-manager-console/src/container/admin/cluster-list/index.tsx @@ -295,7 +295,7 @@ export class ClusterList extends SearchAndFilterContainer { cancelText="取消" okText="确认" > - + diff --git a/kafka-manager-console/src/container/header/index.tsx b/kafka-manager-console/src/container/header/index.tsx index d0b8febe..8d90e3f0 100644 --- a/kafka-manager-console/src/container/header/index.tsx +++ b/kafka-manager-console/src/container/header/index.tsx @@ -145,7 +145,7 @@ export const Header = observer((props: IHeader) => {
LogiKM - v2.5.0 + v2.6.0 {/* 添加版本超链接 */}
From 3b0c208eff8c7cbaaf883d04d77748fbc9ec2565 Mon Sep 17 00:00:00 2001 From: zengqiao Date: Tue, 18 Jan 2022 15:48:05 +0800 Subject: [PATCH 16/19] =?UTF-8?q?=E8=A1=A5=E5=85=85v2.6.0=E5=8D=87?= =?UTF-8?q?=E7=BA=A7=E8=AF=B4=E6=98=8E=E5=8F=8A=E4=BF=AE=E5=A4=8D=E6=96=B0?= =?UTF-8?q?=E5=A2=9Eaccount=E6=8F=90=E7=A4=BAmysql=E9=94=99=E8=AF=AF?= =?UTF-8?q?=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- distribution/conf/create_mysql_table.sql | 6 ++--- distribution/upgrade_config.md | 10 +++++++ .../upgrade_manual/logi-km-v2.2.0.md | 27 ------------------- .../upgrade_manual/logi-km-v2.3.0.md | 17 ------------ .../src/main/resources/mapper/AccountDao.xml | 6 ++--- .../component/sso/BaseSessionSignOn.java | 7 ++--- .../web/converters/AccountConverter.java | 11 +++++--- 7 files changed, 28 insertions(+), 56 deletions(-) delete mode 100644 docs/dev_guide/upgrade_manual/logi-km-v2.2.0.md delete mode 100644 docs/dev_guide/upgrade_manual/logi-km-v2.3.0.md diff --git a/distribution/conf/create_mysql_table.sql b/distribution/conf/create_mysql_table.sql index 05a99278..f859d752 100644 --- a/distribution/conf/create_mysql_table.sql +++ b/distribution/conf/create_mysql_table.sql @@ -13,12 +13,12 @@ CREATE TABLE `account` ( `username` varchar(128) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL DEFAULT '' COMMENT '用户名', `password` varchar(128) NOT NULL DEFAULT '' COMMENT '密码', `role` tinyint(8) NOT NULL DEFAULT '0' COMMENT '角色类型, 0:普通用户 1:研发 2:运维', + `department` varchar(256) DEFAULT '' COMMENT '部门名', + `display_name` varchar(256) DEFAULT '' COMMENT '用户姓名', + `mail` varchar(256) DEFAULT '' COMMENT '邮箱', `status` int(16) NOT NULL DEFAULT '0' COMMENT '0标识使用中,-1标识已废弃', `gmt_create` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', `gmt_modify` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '修改时间', - `department` varchar(128) DEFAULT '' COMMENT '部门名', - `display_name` varchar(128) DEFAULT '' COMMENT '用户姓名', - `mail` varchar(128) DEFAULT '' COMMENT '邮箱', PRIMARY KEY (`id`), UNIQUE KEY `uniq_username` (`username`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='账号表'; diff --git a/distribution/upgrade_config.md b/distribution/upgrade_config.md index 5f976042..06eb01b1 100644 --- a/distribution/upgrade_config.md +++ b/distribution/upgrade_config.md @@ -39,4 +39,14 @@ ALTER TABLE `gateway_config` ADD COLUMN `description` TEXT NULL COMMENT '描述信息' AFTER `version`; ``` +### 升级至`2.6.0`版本 +#### 1.mysql变更 +`2.6.0`版本在`account`表增加用户姓名,部门名,邮箱三个字段,因此需要执行下面的sql进行字段的增加。 + +```sql +ALTER TABLE `account` +ADD COLUMN `display_name` VARCHAR(256) NOT NULL DEFAULT '' COMMENT '用户名' AFTER `role`, +ADD COLUMN `department` VARCHAR(256) NOT NULL DEFAULT '' COMMENT '部门名' AFTER `display_name`, +ADD COLUMN `mail` VARCHAR(256) NOT NULL DEFAULT '' COMMENT '邮箱' AFTER `department`; +``` diff --git a/docs/dev_guide/upgrade_manual/logi-km-v2.2.0.md b/docs/dev_guide/upgrade_manual/logi-km-v2.2.0.md deleted file mode 100644 index 96622080..00000000 --- a/docs/dev_guide/upgrade_manual/logi-km-v2.2.0.md +++ /dev/null @@ -1,27 +0,0 @@ - ---- - -![kafka-manager-logo](../../assets/images/common/logo_name.png) - -**一站式`Apache Kafka`集群指标监控与运维管控平台** - ---- - -# 升级至`2.2.0`版本 - -`2.2.0`版本在`cluster`表及`logical_cluster`各增加了一个字段,因此需要执行下面的sql进行字段的增加。 - -```sql -# 往cluster表中增加jmx_properties字段, 这个字段会用于存储jmx相关的认证以及配置信息 -ALTER TABLE `cluster` ADD COLUMN `jmx_properties` TEXT NULL COMMENT 'JMX配置' AFTER `security_properties`; - -# 往logical_cluster中增加identification字段, 同时数据和原先name数据相同, 最后增加一个唯一键. -# 此后, name字段还是表示集群名称, 而identification字段表示的是集群标识, 只能是字母数字及下划线组成, -# 数据上报到监控系统时, 集群这个标识采用的字段就是identification字段, 之前使用的是name字段. -ALTER TABLE `logical_cluster` ADD COLUMN `identification` VARCHAR(192) NOT NULL DEFAULT '' COMMENT '逻辑集群标识' AFTER `name`; - -UPDATE `logical_cluster` SET `identification`=`name` WHERE id>=0; - -ALTER TABLE `logical_cluster` ADD INDEX `uniq_identification` (`identification` ASC); -``` - diff --git a/docs/dev_guide/upgrade_manual/logi-km-v2.3.0.md b/docs/dev_guide/upgrade_manual/logi-km-v2.3.0.md deleted file mode 100644 index 3a4196f8..00000000 --- a/docs/dev_guide/upgrade_manual/logi-km-v2.3.0.md +++ /dev/null @@ -1,17 +0,0 @@ - ---- - -![kafka-manager-logo](../../assets/images/common/logo_name.png) - -**一站式`Apache Kafka`集群指标监控与运维管控平台** - ---- - -# 升级至`2.3.0`版本 - -`2.3.0`版本在`gateway_config`表增加了一个描述说明的字段,因此需要执行下面的sql进行字段的增加。 - -```sql -ALTER TABLE `gateway_config` -ADD COLUMN `description` TEXT NULL COMMENT '描述信息' AFTER `version`; -``` diff --git a/kafka-manager-dao/src/main/resources/mapper/AccountDao.xml b/kafka-manager-dao/src/main/resources/mapper/AccountDao.xml index 3401ae75..299d120b 100644 --- a/kafka-manager-dao/src/main/resources/mapper/AccountDao.xml +++ b/kafka-manager-dao/src/main/resources/mapper/AccountDao.xml @@ -8,11 +8,11 @@ + + + - - - diff --git a/kafka-manager-extends/kafka-manager-account/src/main/java/com/xiaojukeji/kafka/manager/account/component/sso/BaseSessionSignOn.java b/kafka-manager-extends/kafka-manager-account/src/main/java/com/xiaojukeji/kafka/manager/account/component/sso/BaseSessionSignOn.java index 3683b193..a0309cb6 100644 --- a/kafka-manager-extends/kafka-manager-account/src/main/java/com/xiaojukeji/kafka/manager/account/component/sso/BaseSessionSignOn.java +++ b/kafka-manager-extends/kafka-manager-account/src/main/java/com/xiaojukeji/kafka/manager/account/component/sso/BaseSessionSignOn.java @@ -58,6 +58,7 @@ public class BaseSessionSignOn extends AbstractSingleSignOn { if(ValidateUtils.isNull(ldapAttrsInfo)){ return Result.buildFrom(ResultStatus.LDAP_AUTHENTICATION_FAILED); } + //LDAP验证通过,拿LDAP的sAMAccountName替换dto对象的值,便于第一次自动注册采用LDAP值,并且第二次也避免REPLACE dto.setUsername(ldapAttrsInfo.get("sAMAccountName").toString()); accountResult = accountService.getAccountDO(dto.getUsername()); @@ -68,9 +69,9 @@ public class BaseSessionSignOn extends AbstractSingleSignOn { accountDO.setUsername(dto.getUsername()); accountDO.setRole(AccountRoleEnum.getUserRoleEnum(authUserRegistrationRole).getRole()); accountDO.setPassword(dto.getPassword()); - accountDO.setDisplayName(ldapAttrsInfo.get("displayName").toString()); - accountDO.setDepartment(ldapAttrsInfo.get("department").toString()); - accountDO.setMail(ldapAttrsInfo.get("mail").toString()); + accountDO.setDisplayName(ldapAttrsInfo.getOrDefault("displayName", "").toString()); + accountDO.setDepartment(ldapAttrsInfo.getOrDefault("department", "").toString()); + accountDO.setMail(ldapAttrsInfo.getOrDefault("mail", "").toString()); accountService.createAccount(accountDO); } diff --git a/kafka-manager-web/src/main/java/com/xiaojukeji/kafka/manager/web/converters/AccountConverter.java b/kafka-manager-web/src/main/java/com/xiaojukeji/kafka/manager/web/converters/AccountConverter.java index b774a718..d1ce32c2 100644 --- a/kafka-manager-web/src/main/java/com/xiaojukeji/kafka/manager/web/converters/AccountConverter.java +++ b/kafka-manager-web/src/main/java/com/xiaojukeji/kafka/manager/web/converters/AccountConverter.java @@ -13,14 +13,19 @@ import java.util.List; * @date 19/5/3 */ public class AccountConverter { + private AccountConverter() { + } + public static AccountDO convert2AccountDO(AccountDTO dto) { AccountDO accountDO = new AccountDO(); accountDO.setUsername(dto.getUsername()); accountDO.setPassword(dto.getPassword()); accountDO.setRole(dto.getRole()); - accountDO.setDepartment(dto.getDepartment()); - accountDO.setMail(dto.getMail()); - accountDO.setDisplayName(dto.getDisplayName()); + + // 兼容前端未传这些信息的情况 + accountDO.setDepartment(dto.getDepartment() == null? "": dto.getDepartment()); + accountDO.setMail(dto.getMail() == null? "": dto.getMail()); + accountDO.setDisplayName(dto.getDisplayName() == null? "": dto.getDisplayName()); return accountDO; } From 4f3c1ad9b6d921c19f4d8732193e1bf1284eee1a Mon Sep 17 00:00:00 2001 From: zengqiao Date: Wed, 19 Jan 2022 20:23:18 +0800 Subject: [PATCH 17/19] =?UTF-8?q?=E4=BC=98=E5=8C=96corn=E8=A1=A8=E8=BE=BE?= =?UTF-8?q?=E5=BC=8F=E8=A7=A3=E6=9E=90=E5=A4=B1=E8=B4=A5=E5=90=8E=E9=80=80?= =?UTF-8?q?=E5=87=BA=E6=97=A0=E4=BB=BB=E4=BD=95=E6=97=A5=E5=BF=97=E6=8F=90?= =?UTF-8?q?=E7=A4=BA=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../kafka/manager/task/component/AbstractScheduledTask.java | 5 ++--- .../com/xiaojukeji/kafka/manager/web/MainApplication.java | 5 ++--- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/kafka-manager-task/src/main/java/com/xiaojukeji/kafka/manager/task/component/AbstractScheduledTask.java b/kafka-manager-task/src/main/java/com/xiaojukeji/kafka/manager/task/component/AbstractScheduledTask.java index 564094d5..28c0e97d 100644 --- a/kafka-manager-task/src/main/java/com/xiaojukeji/kafka/manager/task/component/AbstractScheduledTask.java +++ b/kafka-manager-task/src/main/java/com/xiaojukeji/kafka/manager/task/component/AbstractScheduledTask.java @@ -80,10 +80,9 @@ public abstract class AbstractScheduledTask implements Sch return true; } - LOGGER.error("modify scheduledCron failed, format invalid, scheduledName:{} scheduledCron:{}." - , scheduledName, scheduledCron); + LOGGER.error("modify scheduledCron failed, format invalid, scheduledName:{} scheduledCron:{}.", scheduledName, scheduledCron); if (existIfIllegal) { - System.exit(0); + throw new UnsupportedOperationException(String.format("scheduledName:%s scheduledCron:%s format invalid", scheduledName, scheduledCron)); } return false; } diff --git a/kafka-manager-web/src/main/java/com/xiaojukeji/kafka/manager/web/MainApplication.java b/kafka-manager-web/src/main/java/com/xiaojukeji/kafka/manager/web/MainApplication.java index 106d15f5..c5522a4f 100644 --- a/kafka-manager-web/src/main/java/com/xiaojukeji/kafka/manager/web/MainApplication.java +++ b/kafka-manager-web/src/main/java/com/xiaojukeji/kafka/manager/web/MainApplication.java @@ -3,7 +3,6 @@ package com.xiaojukeji.kafka.manager.web; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.boot.SpringApplication; -import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.web.servlet.ServletComponentScan; import org.springframework.scheduling.annotation.EnableAsync; @@ -17,7 +16,6 @@ import org.springframework.scheduling.annotation.EnableScheduling; @EnableAsync @EnableScheduling @ServletComponentScan -@EnableAutoConfiguration @SpringBootApplication(scanBasePackages = {"com.xiaojukeji.kafka.manager"}) public class MainApplication { private static final Logger LOGGER = LoggerFactory.getLogger(MainApplication.class); @@ -28,7 +26,8 @@ public class MainApplication { sa.run(args); LOGGER.info("MainApplication started"); } catch (Exception e) { - e.printStackTrace(); + LOGGER.error("start failed and application exit", e); + System.exit(1); } } } From 0ed8ba8ca43dea0fa4e6ebec20085353fa920827 Mon Sep 17 00:00:00 2001 From: zengqiao Date: Thu, 20 Jan 2022 11:47:55 +0800 Subject: [PATCH 18/19] =?UTF-8?q?=E8=A1=A5=E5=85=85KCM=E4=BD=BF=E7=94=A8?= =?UTF-8?q?=E6=96=87=E6=A1=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/dev_guide/assets/kcm/kcm_principle.png | Bin 0 -> 71084 bytes docs/dev_guide/drawio/KCM实现原理.drawio | 89 ++++++++++++++++++++ docs/dev_guide/如何使用集群安装部署功能.md | 89 ++++++++++++++++++++ 3 files changed, 178 insertions(+) create mode 100644 docs/dev_guide/assets/kcm/kcm_principle.png create mode 100644 docs/dev_guide/drawio/KCM实现原理.drawio create mode 100644 docs/dev_guide/如何使用集群安装部署功能.md diff --git a/docs/dev_guide/assets/kcm/kcm_principle.png b/docs/dev_guide/assets/kcm/kcm_principle.png new file mode 100644 index 0000000000000000000000000000000000000000..d206f57c63ab6aaaeea0b76fcfc5e2ed8468f489 GIT binary patch literal 71084 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 literal 0 HcmV?d00001 diff --git a/docs/dev_guide/drawio/KCM实现原理.drawio b/docs/dev_guide/drawio/KCM实现原理.drawio new file mode 100644 index 00000000..d2742a80 --- /dev/null +++ b/docs/dev_guide/drawio/KCM实现原理.drawio @@ -0,0 +1,89 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/docs/dev_guide/如何使用集群安装部署功能.md b/docs/dev_guide/如何使用集群安装部署功能.md new file mode 100644 index 00000000..5e5f0101 --- /dev/null +++ b/docs/dev_guide/如何使用集群安装部署功能.md @@ -0,0 +1,89 @@ + +--- + +![kafka-manager-logo](../assets/images/common/logo_name.png) + +**一站式`Apache Kafka`集群指标监控与运维管控平台** + +--- + +# 如何使用集群安装部署功能? + +[TOC] + +## 1、实现原理 + +![KCM实现原理](./assets/kcm/kcm_principle.png) + +- LogiKM上传安装包到S3服务; +- LogiKM调用夜莺-Job服务接口,创建执行[kcm_script.sh](https://github.com/didi/LogiKM/blob/master/kafka-manager-extends/kafka-manager-kcm/src/main/resources/kcm_script.sh)脚本的任务,kcm_script.sh脚本是安装部署Kafka集群的脚本; +- 夜莺将任务脚本下发到具体的机器上,通过夜莺Agent执行该脚本; +- kcm_script.sh脚本会进行Kafka-Broker的安装部署; + + +--- + +## 2、使用方式 + +### 2.1、第一步:修改配置 + +**配置application.yml文件** +```yaml +# +kcm: + enabled: false # 是否开启,将其修改为true + s3: # s3 存储服务 + endpoint: s3.didiyunapi.com + access-key: 1234567890 + secret-key: 0987654321 + bucket: logi-kafka + n9e: # 夜莺 + base-url: http://127.0.0.1:8004 # 夜莺job服务地址 + user-token: 12345678 # 用户的token + timeout: 300 # 单台操作的超时时间 + account: root # 操作时使用的账号 + script-file: kcm_script.sh # 脚本,已内置好,在源码的kcm模块内,此处配置无需修改 + logikm-url: http://127.0.0.1:8080 # logikm部署地址,部署时kcm_script.sh会调用logikm检查部署中的一些状态,这里只需要填写 http://IP:PORT 就可以了 + + +account: + jump-login: + gateway-api: false # 网关接口 + third-part-api: false # 第三方接口,将其修改为true,即允许未登录情况下调用开放的第三方接口 +``` + +### 2.2、第二步:检查服务 + +**检查s3服务** +- 测试 "运维管控-》集群运维-》版本管理" 页面的上传,查看等功能是否都正常。如果存在不正常,则需要查看s3的配置是否正确; +- 如果都没有问题,则上传Kafka的以.tgz结尾的安装包以及server.properties文件; + +**检查夜莺Job服务** +- 创建一个job任务,机器选择需要安装Kafka集群的机器,然后执行的命令是echo "Hello LogiKM",看能否被成功执行。如果不行,则需要检查夜莺的安装; +- 如果没有问题则表示夜莺和所需部署的机器之间的交互是没有问题的; + +### 2.3、第三步:接入集群 + +在LogiKM的 “运维管控-》集群列表” 中接入需要安装部署的集群,**PS:此时是允许接入一个没有任何Broker的空的Kafka集群**,其中对的bootstrapServers配置搭建完成后的Kafka集群地址就可以了,而ZK地址必须和集群的server.properties中的ZK地址保持一致; + +### 2.4、第四步:部署集群 + +- 打开LogiKM的 “运维管控-》集群运维-》集群任务” 页面,点击 “新建集群任务” 按钮; +- 选择集群、任务类型、包版本、server配置及填写主机列表,然后点击确认,即可在夜莺的Job服务中心中创建一个任务出来。**PS:如果创建失败,可以看一下日志我为什么创建失败**; +- 随后可以点击详情及状态对任务进行操作; + +### 2.5、可能问题 + +#### 2.5.1、问题一:任务执行超时、失败等 + +进入夜莺Job服务中心,查看对应的任务的相关日志; + +- 提示安装包下载失败,则需要查看对应的s3服务是否可以直接wget下载安装包,如果不可以则需要对kcm_script.sh脚本进行修改; +- 提示调用LogiKM失败,则可以使用postman手动测试一下kcm_script.sh脚本调用LogiKM的那个接口是否有问题,如果存在问题则进行相应的修改;PS:具体接口见kcm_script.sh脚本 + + +## 3、备注说明 + +- 集群安装部署,仅安装部署Kafka-Broker,不安装Kafka的ZK服务; +- 安装部署中,有任何定制化的需求,例如修改安装的目录等,可以通过修改kcm_script.sh脚本实现; +- kcm_script.sh脚本位置:[kcm_script.sh](https://github.com/didi/LogiKM/blob/master/kafka-manager-extends/kafka-manager-kcm/src/main/resources/kcm_script.sh); From e1b2c442aacf7154f8b03edb0faa698fa2783485 Mon Sep 17 00:00:00 2001 From: zengqiao Date: Thu, 20 Jan 2022 14:28:39 +0800 Subject: [PATCH 19/19] =?UTF-8?q?=E8=B0=83=E6=95=B4Task=E6=A8=A1=E5=9D=97?= =?UTF-8?q?=E6=97=A5=E5=BF=97=E5=8F=8AApi=E8=AF=B7=E6=B1=82=E7=BB=9F?= =?UTF-8?q?=E8=AE=A1=E6=97=A5=E5=BF=97=E7=9A=84=E8=BE=93=E5=87=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../manager/common/constant/LogConstant.java | 16 ------ .../task/component/AbstractScheduledTask.java | 10 ++-- .../manager/task/component/Heartbeat.java | 3 +- .../task/dispatch/biz/CalKafkaTopicBill.java | 4 +- .../task/dispatch/biz/CalTopicStatistics.java | 3 +- .../task/dispatch/biz/FlushBrokerTable.java | 3 +- .../task/dispatch/biz/FlushExpiredTopic.java | 3 +- .../dispatch/biz/SyncClusterTaskState.java | 3 +- .../collect/CollectAndPublishCGData.java | 3 +- .../metrics/delete/DeleteMetrics.java | 3 +- .../store/StoreDiDiAppTopicMetrics.java | 3 +- .../StoreDiDiTopicRequestTimeMetrics.java | 3 +- .../dispatch/op/AutoHandleTopicOrder.java | 3 +- .../dispatch/op/AutomatedHandleOrder.java | 3 +- .../task/dispatch/op/FlushReassignment.java | 3 +- .../task/dispatch/op/SyncTopic2DB.java | 3 +- .../db/StoreCommunityTopicMetrics2DB.java | 3 +- .../db/StoreTopicThrottledMetrics2DB.java | 3 +- .../SinkCommunityTopicMetrics2Kafka.java | 3 +- .../sink/kafka/SinkConsumerMetrics2Kafka.java | 3 +- .../SinkCommunityTopicMetrics2Monitor.java | 3 +- .../monitor/SinkConsumerMetrics2Monitor.java | 3 +- .../task/schedule/FlushTopicMetrics.java | 3 +- .../FlushBKConsumerGroupMetadata.java | 3 +- .../metadata/FlushTopicProperties.java | 3 +- .../FlushZKConsumerGroupMetadata.java | 3 +- .../manager/web/metrics/MetricsRegistry.java | 3 +- .../src/main/resources/logback-spring.xml | 53 +++++-------------- 28 files changed, 42 insertions(+), 113 deletions(-) delete mode 100644 kafka-manager-common/src/main/java/com/xiaojukeji/kafka/manager/common/constant/LogConstant.java diff --git a/kafka-manager-common/src/main/java/com/xiaojukeji/kafka/manager/common/constant/LogConstant.java b/kafka-manager-common/src/main/java/com/xiaojukeji/kafka/manager/common/constant/LogConstant.java deleted file mode 100644 index bba7670c..00000000 --- a/kafka-manager-common/src/main/java/com/xiaojukeji/kafka/manager/common/constant/LogConstant.java +++ /dev/null @@ -1,16 +0,0 @@ -package com.xiaojukeji.kafka.manager.common.constant; - -/** - * @author zengqiao - * @date 20/8/10 - */ -public class LogConstant { - public static final String COLLECTOR_METRICS_LOGGER = "COLLECTOR_METRICS_LOGGER"; - - public static final String API_METRICS_LOGGER = "API_METRICS_LOGGER"; - - public static final String SCHEDULED_TASK_LOGGER = "SCHEDULED_TASK_LOGGER"; - - private LogConstant() { - } -} \ No newline at end of file diff --git a/kafka-manager-task/src/main/java/com/xiaojukeji/kafka/manager/task/component/AbstractScheduledTask.java b/kafka-manager-task/src/main/java/com/xiaojukeji/kafka/manager/task/component/AbstractScheduledTask.java index 28c0e97d..bfd6da5d 100644 --- a/kafka-manager-task/src/main/java/com/xiaojukeji/kafka/manager/task/component/AbstractScheduledTask.java +++ b/kafka-manager-task/src/main/java/com/xiaojukeji/kafka/manager/task/component/AbstractScheduledTask.java @@ -72,16 +72,15 @@ public abstract class AbstractScheduledTask implements Sch LOGGER.info("init custom scheduled finished, scheduledName:{} scheduledCron:{}.", scheduledName, scheduledCron); } - private boolean checkAndModifyCron(String scheduledName, String scheduledCron, boolean existIfIllegal) { + private boolean checkAndModifyCron(String scheduledName, String scheduledCron, boolean isInit) { if (scheduledCron.matches(ScheduledTaskConstant.CRON_REG_EX)) { this.scheduledCron = scheduledCron; - LOGGER.info("modify scheduledCron success, scheduledName:{} scheduledCron:{}." - , scheduledName, scheduledCron); + LOGGER.info("{} scheduledCron success, scheduledName:{} scheduledCron:{}.", isInit? "init": "modify", scheduledName, scheduledCron); return true; } LOGGER.error("modify scheduledCron failed, format invalid, scheduledName:{} scheduledCron:{}.", scheduledName, scheduledCron); - if (existIfIllegal) { + if (isInit) { throw new UnsupportedOperationException(String.format("scheduledName:%s scheduledCron:%s format invalid", scheduledName, scheduledCron)); } return false; @@ -128,7 +127,8 @@ public abstract class AbstractScheduledTask implements Sch LOGGER.info("customScheduled task finished, empty selected task, scheduledName:{}.", scheduledName); return; } - LOGGER.info("customScheduled task running, selected tasks, IP:{} selectedTasks:{}.", + + LOGGER.debug("customScheduled task running, selected tasks, IP:{} selectedTasks:{}.", NetUtils.localIp(), JsonUtils.toJSONString(selectTasks) ); diff --git a/kafka-manager-task/src/main/java/com/xiaojukeji/kafka/manager/task/component/Heartbeat.java b/kafka-manager-task/src/main/java/com/xiaojukeji/kafka/manager/task/component/Heartbeat.java index d00c0ad0..c6009fcd 100644 --- a/kafka-manager-task/src/main/java/com/xiaojukeji/kafka/manager/task/component/Heartbeat.java +++ b/kafka-manager-task/src/main/java/com/xiaojukeji/kafka/manager/task/component/Heartbeat.java @@ -1,6 +1,5 @@ package com.xiaojukeji.kafka.manager.task.component; -import com.xiaojukeji.kafka.manager.common.constant.LogConstant; import com.xiaojukeji.kafka.manager.common.utils.NetUtils; import com.xiaojukeji.kafka.manager.dao.HeartbeatDao; import com.xiaojukeji.kafka.manager.common.entity.pojo.HeartbeatDO; @@ -18,7 +17,7 @@ import java.util.Date; */ @Component public class Heartbeat { - private final static Logger LOGGER = LoggerFactory.getLogger(LogConstant.SCHEDULED_TASK_LOGGER); + private static final Logger LOGGER = LoggerFactory.getLogger(Heartbeat.class); @Autowired private HeartbeatDao heartbeatDao; diff --git a/kafka-manager-task/src/main/java/com/xiaojukeji/kafka/manager/task/dispatch/biz/CalKafkaTopicBill.java b/kafka-manager-task/src/main/java/com/xiaojukeji/kafka/manager/task/dispatch/biz/CalKafkaTopicBill.java index 93b0a274..ac1486f6 100644 --- a/kafka-manager-task/src/main/java/com/xiaojukeji/kafka/manager/task/dispatch/biz/CalKafkaTopicBill.java +++ b/kafka-manager-task/src/main/java/com/xiaojukeji/kafka/manager/task/dispatch/biz/CalKafkaTopicBill.java @@ -1,8 +1,6 @@ package com.xiaojukeji.kafka.manager.task.dispatch.biz; - import com.xiaojukeji.kafka.manager.common.constant.Constant; -import com.xiaojukeji.kafka.manager.common.constant.LogConstant; import com.xiaojukeji.kafka.manager.task.config.TopicBillConfig; import com.xiaojukeji.kafka.manager.common.entity.pojo.gateway.AppDO; import com.xiaojukeji.kafka.manager.common.utils.DateUtils; @@ -30,7 +28,7 @@ import java.util.*; */ @CustomScheduled(name = "calKafkaBill", cron = "0 0 1 * * *", threadNum = 1) public class CalKafkaTopicBill extends AbstractScheduledTask { - private final static Logger LOGGER = LoggerFactory.getLogger(LogConstant.SCHEDULED_TASK_LOGGER); + private static final Logger LOGGER = LoggerFactory.getLogger(CalKafkaTopicBill.class); @Autowired private AppService appService; diff --git a/kafka-manager-task/src/main/java/com/xiaojukeji/kafka/manager/task/dispatch/biz/CalTopicStatistics.java b/kafka-manager-task/src/main/java/com/xiaojukeji/kafka/manager/task/dispatch/biz/CalTopicStatistics.java index 7d809417..d293a4b0 100644 --- a/kafka-manager-task/src/main/java/com/xiaojukeji/kafka/manager/task/dispatch/biz/CalTopicStatistics.java +++ b/kafka-manager-task/src/main/java/com/xiaojukeji/kafka/manager/task/dispatch/biz/CalTopicStatistics.java @@ -1,7 +1,6 @@ package com.xiaojukeji.kafka.manager.task.dispatch.biz; import com.xiaojukeji.kafka.manager.common.bizenum.OffsetPosEnum; -import com.xiaojukeji.kafka.manager.common.constant.LogConstant; import com.xiaojukeji.kafka.manager.common.entity.pojo.ClusterDO; import com.xiaojukeji.kafka.manager.common.entity.pojo.TopicStatisticsDO; import com.xiaojukeji.kafka.manager.common.utils.DateUtils; @@ -30,7 +29,7 @@ import java.util.Map; */ @CustomScheduled(name = "calTopicStatistics", cron = "0 0 0/4 * * ?", threadNum = 5) public class CalTopicStatistics extends AbstractScheduledTask { - private final static Logger LOGGER = LoggerFactory.getLogger(LogConstant.SCHEDULED_TASK_LOGGER); + private static final Logger LOGGER = LoggerFactory.getLogger(CalTopicStatistics.class); @Autowired private ClusterService clusterService; diff --git a/kafka-manager-task/src/main/java/com/xiaojukeji/kafka/manager/task/dispatch/biz/FlushBrokerTable.java b/kafka-manager-task/src/main/java/com/xiaojukeji/kafka/manager/task/dispatch/biz/FlushBrokerTable.java index 533f321f..a9458d4d 100644 --- a/kafka-manager-task/src/main/java/com/xiaojukeji/kafka/manager/task/dispatch/biz/FlushBrokerTable.java +++ b/kafka-manager-task/src/main/java/com/xiaojukeji/kafka/manager/task/dispatch/biz/FlushBrokerTable.java @@ -1,7 +1,6 @@ package com.xiaojukeji.kafka.manager.task.dispatch.biz; import com.xiaojukeji.kafka.manager.common.bizenum.DBStatusEnum; -import com.xiaojukeji.kafka.manager.common.constant.LogConstant; import com.xiaojukeji.kafka.manager.common.utils.ValidateUtils; import com.xiaojukeji.kafka.manager.common.zookeeper.znode.brokers.BrokerMetadata; import com.xiaojukeji.kafka.manager.common.entity.pojo.BrokerDO; @@ -27,7 +26,7 @@ import java.util.*; */ @CustomScheduled(name = "flushBrokerTable", cron = "0 0 0/1 * * ?", threadNum = 1) public class FlushBrokerTable extends AbstractScheduledTask { - private final static Logger LOGGER = LoggerFactory.getLogger(LogConstant.SCHEDULED_TASK_LOGGER); + private static final Logger LOGGER = LoggerFactory.getLogger(FlushBrokerTable.class); @Autowired private BrokerService brokerService; diff --git a/kafka-manager-task/src/main/java/com/xiaojukeji/kafka/manager/task/dispatch/biz/FlushExpiredTopic.java b/kafka-manager-task/src/main/java/com/xiaojukeji/kafka/manager/task/dispatch/biz/FlushExpiredTopic.java index 1759ea0e..a42584f7 100644 --- a/kafka-manager-task/src/main/java/com/xiaojukeji/kafka/manager/task/dispatch/biz/FlushExpiredTopic.java +++ b/kafka-manager-task/src/main/java/com/xiaojukeji/kafka/manager/task/dispatch/biz/FlushExpiredTopic.java @@ -1,7 +1,6 @@ package com.xiaojukeji.kafka.manager.task.dispatch.biz; import com.xiaojukeji.kafka.manager.common.constant.Constant; -import com.xiaojukeji.kafka.manager.common.constant.LogConstant; import com.xiaojukeji.kafka.manager.common.entity.metrics.TopicMetrics; import com.xiaojukeji.kafka.manager.common.entity.pojo.ClusterDO; import com.xiaojukeji.kafka.manager.common.entity.pojo.TopicExpiredDO; @@ -32,7 +31,7 @@ import java.util.Map; */ @CustomScheduled(name = "flushExpiredTopic", cron = "0 0 0/5 * * ?", threadNum = 1) public class FlushExpiredTopic extends AbstractScheduledTask { - private final static Logger LOGGER = LoggerFactory.getLogger(LogConstant.SCHEDULED_TASK_LOGGER); + private static final Logger LOGGER = LoggerFactory.getLogger(FlushExpiredTopic.class); @Autowired private TopicExpiredDao topicExpiredDao; diff --git a/kafka-manager-task/src/main/java/com/xiaojukeji/kafka/manager/task/dispatch/biz/SyncClusterTaskState.java b/kafka-manager-task/src/main/java/com/xiaojukeji/kafka/manager/task/dispatch/biz/SyncClusterTaskState.java index 9edddb28..49b5b09e 100644 --- a/kafka-manager-task/src/main/java/com/xiaojukeji/kafka/manager/task/dispatch/biz/SyncClusterTaskState.java +++ b/kafka-manager-task/src/main/java/com/xiaojukeji/kafka/manager/task/dispatch/biz/SyncClusterTaskState.java @@ -1,6 +1,5 @@ package com.xiaojukeji.kafka.manager.task.dispatch.biz; -import com.xiaojukeji.kafka.manager.common.constant.LogConstant; import com.xiaojukeji.kafka.manager.common.entity.pojo.ClusterTaskDO; import com.xiaojukeji.kafka.manager.common.utils.ValidateUtils; import com.xiaojukeji.kafka.manager.kcm.ClusterTaskService; @@ -23,7 +22,7 @@ import java.util.List; @CustomScheduled(name = "syncClusterTaskState", cron = "0 0/1 * * * ?", threadNum = 1) @ConditionalOnProperty(prefix = "kcm", name = "enabled", havingValue = "true", matchIfMissing = true) public class SyncClusterTaskState extends AbstractScheduledTask { - private final static Logger LOGGER = LoggerFactory.getLogger(LogConstant.SCHEDULED_TASK_LOGGER); + private static final Logger LOGGER = LoggerFactory.getLogger(SyncClusterTaskState.class); @Autowired private ClusterTaskService clusterTaskService; diff --git a/kafka-manager-task/src/main/java/com/xiaojukeji/kafka/manager/task/dispatch/metrics/collect/CollectAndPublishCGData.java b/kafka-manager-task/src/main/java/com/xiaojukeji/kafka/manager/task/dispatch/metrics/collect/CollectAndPublishCGData.java index 28bb1612..5d796cc9 100644 --- a/kafka-manager-task/src/main/java/com/xiaojukeji/kafka/manager/task/dispatch/metrics/collect/CollectAndPublishCGData.java +++ b/kafka-manager-task/src/main/java/com/xiaojukeji/kafka/manager/task/dispatch/metrics/collect/CollectAndPublishCGData.java @@ -1,7 +1,6 @@ package com.xiaojukeji.kafka.manager.task.dispatch.metrics.collect; import com.xiaojukeji.kafka.manager.common.bizenum.OffsetPosEnum; -import com.xiaojukeji.kafka.manager.common.constant.LogConstant; import com.xiaojukeji.kafka.manager.common.entity.ao.consumer.ConsumerGroup; import com.xiaojukeji.kafka.manager.common.entity.metrics.ConsumerMetrics; import com.xiaojukeji.kafka.manager.common.entity.pojo.ClusterDO; @@ -33,7 +32,7 @@ import java.util.concurrent.FutureTask; */ @CustomScheduled(name = "newCollectAndPublishCGData", cron = "30 0/1 * * * *", threadNum = 10) public class CollectAndPublishCGData extends AbstractScheduledTask { - private final static Logger LOGGER = LoggerFactory.getLogger(LogConstant.SCHEDULED_TASK_LOGGER); + private static final Logger LOGGER = LoggerFactory.getLogger(CollectAndPublishCGData.class); @Autowired private TopicService topicService; diff --git a/kafka-manager-task/src/main/java/com/xiaojukeji/kafka/manager/task/dispatch/metrics/delete/DeleteMetrics.java b/kafka-manager-task/src/main/java/com/xiaojukeji/kafka/manager/task/dispatch/metrics/delete/DeleteMetrics.java index 89d7e516..9f34db7c 100644 --- a/kafka-manager-task/src/main/java/com/xiaojukeji/kafka/manager/task/dispatch/metrics/delete/DeleteMetrics.java +++ b/kafka-manager-task/src/main/java/com/xiaojukeji/kafka/manager/task/dispatch/metrics/delete/DeleteMetrics.java @@ -1,6 +1,5 @@ package com.xiaojukeji.kafka.manager.task.dispatch.metrics.delete; -import com.xiaojukeji.kafka.manager.common.constant.LogConstant; import com.xiaojukeji.kafka.manager.common.utils.BackoffUtils; import com.xiaojukeji.kafka.manager.dao.*; import com.xiaojukeji.kafka.manager.task.component.AbstractScheduledTask; @@ -22,7 +21,7 @@ import java.util.List; */ @CustomScheduled(name = "deleteMetrics", cron = "0 0/2 * * * ?", threadNum = 1) public class DeleteMetrics extends AbstractScheduledTask { - private static final Logger LOGGER = LoggerFactory.getLogger(LogConstant.SCHEDULED_TASK_LOGGER); + private static final Logger LOGGER = LoggerFactory.getLogger(DeleteMetrics.class); @Autowired private TopicMetricsDao topicMetricsDao; diff --git a/kafka-manager-task/src/main/java/com/xiaojukeji/kafka/manager/task/dispatch/metrics/store/StoreDiDiAppTopicMetrics.java b/kafka-manager-task/src/main/java/com/xiaojukeji/kafka/manager/task/dispatch/metrics/store/StoreDiDiAppTopicMetrics.java index 6543f6fa..88f89c43 100644 --- a/kafka-manager-task/src/main/java/com/xiaojukeji/kafka/manager/task/dispatch/metrics/store/StoreDiDiAppTopicMetrics.java +++ b/kafka-manager-task/src/main/java/com/xiaojukeji/kafka/manager/task/dispatch/metrics/store/StoreDiDiAppTopicMetrics.java @@ -2,7 +2,6 @@ package com.xiaojukeji.kafka.manager.task.dispatch.metrics.store; import com.xiaojukeji.kafka.manager.common.constant.Constant; import com.xiaojukeji.kafka.manager.common.constant.KafkaMetricsCollections; -import com.xiaojukeji.kafka.manager.common.constant.LogConstant; import com.xiaojukeji.kafka.manager.common.entity.metrics.TopicMetrics; import com.xiaojukeji.kafka.manager.common.utils.ValidateUtils; import com.xiaojukeji.kafka.manager.dao.TopicAppMetricsDao; @@ -27,7 +26,7 @@ import java.util.*; @CustomScheduled(name = "storeDiDiAppTopicMetrics", cron = "41 0/1 * * * ?", threadNum = 5) @ConditionalOnProperty(prefix = "custom.store-metrics-task.didi", name = "app-topic-metrics-enabled", havingValue = "true", matchIfMissing = true) public class StoreDiDiAppTopicMetrics extends AbstractScheduledTask { - private static final Logger LOGGER = LoggerFactory.getLogger(LogConstant.SCHEDULED_TASK_LOGGER); + private static final Logger LOGGER = LoggerFactory.getLogger(StoreDiDiAppTopicMetrics.class); @Autowired private JmxService jmxService; diff --git a/kafka-manager-task/src/main/java/com/xiaojukeji/kafka/manager/task/dispatch/metrics/store/StoreDiDiTopicRequestTimeMetrics.java b/kafka-manager-task/src/main/java/com/xiaojukeji/kafka/manager/task/dispatch/metrics/store/StoreDiDiTopicRequestTimeMetrics.java index 040612f2..d664ea80 100644 --- a/kafka-manager-task/src/main/java/com/xiaojukeji/kafka/manager/task/dispatch/metrics/store/StoreDiDiTopicRequestTimeMetrics.java +++ b/kafka-manager-task/src/main/java/com/xiaojukeji/kafka/manager/task/dispatch/metrics/store/StoreDiDiTopicRequestTimeMetrics.java @@ -2,7 +2,6 @@ package com.xiaojukeji.kafka.manager.task.dispatch.metrics.store; import com.xiaojukeji.kafka.manager.common.constant.Constant; import com.xiaojukeji.kafka.manager.common.constant.KafkaMetricsCollections; -import com.xiaojukeji.kafka.manager.common.constant.LogConstant; import com.xiaojukeji.kafka.manager.common.entity.metrics.TopicMetrics; import com.xiaojukeji.kafka.manager.common.utils.ValidateUtils; import com.xiaojukeji.kafka.manager.dao.TopicRequestMetricsDao; @@ -27,7 +26,7 @@ import java.util.*; @CustomScheduled(name = "storeDiDiTopicRequestTimeMetrics", cron = "51 0/1 * * * ?", threadNum = 5) @ConditionalOnProperty(prefix = "custom.store-metrics-task.didi", name = "topic-request-time-metrics-enabled", havingValue = "true", matchIfMissing = true) public class StoreDiDiTopicRequestTimeMetrics extends AbstractScheduledTask { - private static final Logger LOGGER = LoggerFactory.getLogger(LogConstant.SCHEDULED_TASK_LOGGER); + private static final Logger LOGGER = LoggerFactory.getLogger(StoreDiDiTopicRequestTimeMetrics.class); @Autowired private JmxService jmxService; diff --git a/kafka-manager-task/src/main/java/com/xiaojukeji/kafka/manager/task/dispatch/op/AutoHandleTopicOrder.java b/kafka-manager-task/src/main/java/com/xiaojukeji/kafka/manager/task/dispatch/op/AutoHandleTopicOrder.java index 46158b60..535bd93e 100644 --- a/kafka-manager-task/src/main/java/com/xiaojukeji/kafka/manager/task/dispatch/op/AutoHandleTopicOrder.java +++ b/kafka-manager-task/src/main/java/com/xiaojukeji/kafka/manager/task/dispatch/op/AutoHandleTopicOrder.java @@ -4,7 +4,6 @@ import com.xiaojukeji.kafka.manager.bpm.OrderService; import com.xiaojukeji.kafka.manager.bpm.common.OrderStatusEnum; import com.xiaojukeji.kafka.manager.bpm.common.OrderTypeEnum; import com.xiaojukeji.kafka.manager.common.constant.Constant; -import com.xiaojukeji.kafka.manager.common.constant.LogConstant; import com.xiaojukeji.kafka.manager.common.constant.SystemCodeConstant; import com.xiaojukeji.kafka.manager.common.constant.TopicCreationConstant; import com.xiaojukeji.kafka.manager.common.entity.ResultStatus; @@ -38,7 +37,7 @@ import java.util.Properties; @CustomScheduled(name = "autoHandleTopicOrder", cron = "0 0/1 * * * ?", threadNum = 1) @ConditionalOnProperty(prefix = "task.op.order-auto-exec", name = "topic-enabled", havingValue = "true", matchIfMissing = false) public class AutoHandleTopicOrder extends AbstractScheduledTask { - private static final Logger LOGGER = LoggerFactory.getLogger(LogConstant.SCHEDULED_TASK_LOGGER); + private static final Logger LOGGER = LoggerFactory.getLogger(AutoHandleTopicOrder.class); @Autowired private ConfigService configService; diff --git a/kafka-manager-task/src/main/java/com/xiaojukeji/kafka/manager/task/dispatch/op/AutomatedHandleOrder.java b/kafka-manager-task/src/main/java/com/xiaojukeji/kafka/manager/task/dispatch/op/AutomatedHandleOrder.java index e9cb1cb1..10743330 100644 --- a/kafka-manager-task/src/main/java/com/xiaojukeji/kafka/manager/task/dispatch/op/AutomatedHandleOrder.java +++ b/kafka-manager-task/src/main/java/com/xiaojukeji/kafka/manager/task/dispatch/op/AutomatedHandleOrder.java @@ -4,7 +4,6 @@ import com.xiaojukeji.kafka.manager.bpm.OrderService; import com.xiaojukeji.kafka.manager.bpm.common.OrderStatusEnum; import com.xiaojukeji.kafka.manager.bpm.common.OrderTypeEnum; import com.xiaojukeji.kafka.manager.common.constant.Constant; -import com.xiaojukeji.kafka.manager.common.constant.LogConstant; import com.xiaojukeji.kafka.manager.common.entity.ResultStatus; import com.xiaojukeji.kafka.manager.bpm.common.handle.OrderHandleBaseDTO; import com.xiaojukeji.kafka.manager.common.utils.DateUtils; @@ -34,7 +33,7 @@ import java.util.*; @CustomScheduled(name = "automatedHandleOrder", cron = "0 0/1 * * * ?", threadNum = 1) @ConditionalOnProperty(prefix = "task.op.order-auto-exec", name = "app-enabled", havingValue = "true", matchIfMissing = false) public class AutomatedHandleOrder extends AbstractScheduledTask { - private static final Logger LOGGER = LoggerFactory.getLogger(LogConstant.SCHEDULED_TASK_LOGGER); + private static final Logger LOGGER = LoggerFactory.getLogger(AutomatedHandleOrder.class); @Autowired private OrderService orderService; diff --git a/kafka-manager-task/src/main/java/com/xiaojukeji/kafka/manager/task/dispatch/op/FlushReassignment.java b/kafka-manager-task/src/main/java/com/xiaojukeji/kafka/manager/task/dispatch/op/FlushReassignment.java index cfd11bfa..49a80572 100644 --- a/kafka-manager-task/src/main/java/com/xiaojukeji/kafka/manager/task/dispatch/op/FlushReassignment.java +++ b/kafka-manager-task/src/main/java/com/xiaojukeji/kafka/manager/task/dispatch/op/FlushReassignment.java @@ -3,7 +3,6 @@ package com.xiaojukeji.kafka.manager.task.dispatch.op; import com.xiaojukeji.kafka.manager.common.bizenum.TaskStatusEnum; import com.xiaojukeji.kafka.manager.common.bizenum.TaskStatusReassignEnum; import com.xiaojukeji.kafka.manager.common.constant.Constant; -import com.xiaojukeji.kafka.manager.common.constant.LogConstant; import com.xiaojukeji.kafka.manager.common.constant.TopicCreationConstant; import com.xiaojukeji.kafka.manager.common.entity.ResultStatus; import com.xiaojukeji.kafka.manager.common.utils.ValidateUtils; @@ -36,7 +35,7 @@ import java.util.*; @Component @CustomScheduled(name = "flushReassignment", cron = "0 0/1 * * * ?", threadNum = 1) public class FlushReassignment extends AbstractScheduledTask { - private final static Logger LOGGER = LoggerFactory.getLogger(LogConstant.SCHEDULED_TASK_LOGGER); + private static final Logger LOGGER = LoggerFactory.getLogger(FlushReassignment.class); @Autowired private ClusterService clusterService; diff --git a/kafka-manager-task/src/main/java/com/xiaojukeji/kafka/manager/task/dispatch/op/SyncTopic2DB.java b/kafka-manager-task/src/main/java/com/xiaojukeji/kafka/manager/task/dispatch/op/SyncTopic2DB.java index bb069aa8..c23225b7 100644 --- a/kafka-manager-task/src/main/java/com/xiaojukeji/kafka/manager/task/dispatch/op/SyncTopic2DB.java +++ b/kafka-manager-task/src/main/java/com/xiaojukeji/kafka/manager/task/dispatch/op/SyncTopic2DB.java @@ -2,7 +2,6 @@ package com.xiaojukeji.kafka.manager.task.dispatch.op; import com.xiaojukeji.kafka.manager.common.bizenum.TopicAuthorityEnum; import com.xiaojukeji.kafka.manager.common.constant.KafkaConstant; -import com.xiaojukeji.kafka.manager.common.constant.LogConstant; import com.xiaojukeji.kafka.manager.common.constant.TopicCreationConstant; import com.xiaojukeji.kafka.manager.common.entity.pojo.ClusterDO; import com.xiaojukeji.kafka.manager.common.entity.pojo.TopicDO; @@ -39,7 +38,7 @@ import java.util.stream.Collectors; @CustomScheduled(name = "syncTopic2DB", cron = "0 0/2 * * * ?", threadNum = 1) @ConditionalOnProperty(prefix = "task.op", name = "sync-topic-enabled", havingValue = "true", matchIfMissing = false) public class SyncTopic2DB extends AbstractScheduledTask { - private static final Logger LOGGER = LoggerFactory.getLogger(LogConstant.SCHEDULED_TASK_LOGGER); + private static final Logger LOGGER = LoggerFactory.getLogger(SyncTopic2DB.class); private static final String SYNC_TOPIC_2_DB_CONFIG_KEY = "SYNC_TOPIC_2_DB_CONFIG_KEY"; diff --git a/kafka-manager-task/src/main/java/com/xiaojukeji/kafka/manager/task/listener/sink/db/StoreCommunityTopicMetrics2DB.java b/kafka-manager-task/src/main/java/com/xiaojukeji/kafka/manager/task/listener/sink/db/StoreCommunityTopicMetrics2DB.java index 267e32b7..46966d5e 100644 --- a/kafka-manager-task/src/main/java/com/xiaojukeji/kafka/manager/task/listener/sink/db/StoreCommunityTopicMetrics2DB.java +++ b/kafka-manager-task/src/main/java/com/xiaojukeji/kafka/manager/task/listener/sink/db/StoreCommunityTopicMetrics2DB.java @@ -1,7 +1,6 @@ package com.xiaojukeji.kafka.manager.task.listener.sink.db; import com.xiaojukeji.kafka.manager.common.constant.Constant; -import com.xiaojukeji.kafka.manager.common.constant.LogConstant; import com.xiaojukeji.kafka.manager.common.entity.metrics.TopicMetrics; import com.xiaojukeji.kafka.manager.common.entity.pojo.TopicMetricsDO; import com.xiaojukeji.kafka.manager.common.events.TopicMetricsCollectedEvent; @@ -25,7 +24,7 @@ import java.util.List; @Component("storeCommunityTopicMetrics2DB") @ConditionalOnProperty(prefix = "custom.store-metrics-task.community", name = "topic-metrics-enabled", havingValue = "true", matchIfMissing = true) public class StoreCommunityTopicMetrics2DB implements ApplicationListener { - private static final Logger LOGGER = LoggerFactory.getLogger(LogConstant.SCHEDULED_TASK_LOGGER); + private static final Logger LOGGER = LoggerFactory.getLogger(StoreCommunityTopicMetrics2DB.class); @Autowired private TopicMetricsDao topicMetricsDao; diff --git a/kafka-manager-task/src/main/java/com/xiaojukeji/kafka/manager/task/listener/sink/db/StoreTopicThrottledMetrics2DB.java b/kafka-manager-task/src/main/java/com/xiaojukeji/kafka/manager/task/listener/sink/db/StoreTopicThrottledMetrics2DB.java index c2d74df3..fd0f6517 100644 --- a/kafka-manager-task/src/main/java/com/xiaojukeji/kafka/manager/task/listener/sink/db/StoreTopicThrottledMetrics2DB.java +++ b/kafka-manager-task/src/main/java/com/xiaojukeji/kafka/manager/task/listener/sink/db/StoreTopicThrottledMetrics2DB.java @@ -2,7 +2,6 @@ package com.xiaojukeji.kafka.manager.task.listener.sink.db; import com.xiaojukeji.kafka.manager.common.bizenum.KafkaClientEnum; import com.xiaojukeji.kafka.manager.common.constant.Constant; -import com.xiaojukeji.kafka.manager.common.constant.LogConstant; import com.xiaojukeji.kafka.manager.common.entity.metrics.TopicThrottledMetrics; import com.xiaojukeji.kafka.manager.common.entity.pojo.TopicThrottledMetricsDO; import com.xiaojukeji.kafka.manager.common.utils.ValidateUtils; @@ -24,7 +23,7 @@ import java.util.*; @Component("storeTopicThrottledMetrics2DB") @ConditionalOnProperty(prefix = "custom.store-metrics-task.didi", name = "topic-throttled-metrics-enabled", havingValue = "true", matchIfMissing = true) public class StoreTopicThrottledMetrics2DB implements ApplicationListener { - private final static Logger LOGGER = LoggerFactory.getLogger(LogConstant.SCHEDULED_TASK_LOGGER); + private static final Logger LOGGER = LoggerFactory.getLogger(StoreTopicThrottledMetrics2DB.class); @Autowired private ThrottleService throttleService; diff --git a/kafka-manager-task/src/main/java/com/xiaojukeji/kafka/manager/task/listener/sink/kafka/SinkCommunityTopicMetrics2Kafka.java b/kafka-manager-task/src/main/java/com/xiaojukeji/kafka/manager/task/listener/sink/kafka/SinkCommunityTopicMetrics2Kafka.java index 5f3a0e5c..3b8e6413 100644 --- a/kafka-manager-task/src/main/java/com/xiaojukeji/kafka/manager/task/listener/sink/kafka/SinkCommunityTopicMetrics2Kafka.java +++ b/kafka-manager-task/src/main/java/com/xiaojukeji/kafka/manager/task/listener/sink/kafka/SinkCommunityTopicMetrics2Kafka.java @@ -1,7 +1,6 @@ package com.xiaojukeji.kafka.manager.task.listener.sink.kafka; import com.xiaojukeji.kafka.manager.common.constant.ConfigConstant; -import com.xiaojukeji.kafka.manager.common.constant.LogConstant; import com.xiaojukeji.kafka.manager.common.entity.ao.config.TopicNameConfig; import com.xiaojukeji.kafka.manager.common.entity.ao.remote.KafkaTopicMetrics; import com.xiaojukeji.kafka.manager.common.entity.metrics.TopicMetrics; @@ -27,7 +26,7 @@ import java.util.List; */ @Component("sinkCommunityTopicMetrics2Kafka") public class SinkCommunityTopicMetrics2Kafka implements ApplicationListener { - private final static Logger LOGGER = LoggerFactory.getLogger(LogConstant.SCHEDULED_TASK_LOGGER); + private static final Logger LOGGER = LoggerFactory.getLogger(SinkCommunityTopicMetrics2Kafka.class); @Autowired private ConfigService configService; diff --git a/kafka-manager-task/src/main/java/com/xiaojukeji/kafka/manager/task/listener/sink/kafka/SinkConsumerMetrics2Kafka.java b/kafka-manager-task/src/main/java/com/xiaojukeji/kafka/manager/task/listener/sink/kafka/SinkConsumerMetrics2Kafka.java index eb6c2d37..c2d69dbe 100644 --- a/kafka-manager-task/src/main/java/com/xiaojukeji/kafka/manager/task/listener/sink/kafka/SinkConsumerMetrics2Kafka.java +++ b/kafka-manager-task/src/main/java/com/xiaojukeji/kafka/manager/task/listener/sink/kafka/SinkConsumerMetrics2Kafka.java @@ -1,7 +1,6 @@ package com.xiaojukeji.kafka.manager.task.listener.sink.kafka; import com.xiaojukeji.kafka.manager.common.constant.ConfigConstant; -import com.xiaojukeji.kafka.manager.common.constant.LogConstant; import com.xiaojukeji.kafka.manager.common.entity.ao.config.TopicNameConfig; import com.xiaojukeji.kafka.manager.common.entity.ao.remote.KafkaConsumerMetrics; import com.xiaojukeji.kafka.manager.common.entity.ao.remote.KafkaConsumerMetricsElem; @@ -27,7 +26,7 @@ import java.util.Map; */ @Component("produceConsumerMetrics") public class SinkConsumerMetrics2Kafka implements ApplicationListener { - private final static Logger LOGGER = LoggerFactory.getLogger(LogConstant.SCHEDULED_TASK_LOGGER); + private static final Logger LOGGER = LoggerFactory.getLogger(SinkConsumerMetrics2Kafka.class); @Autowired private ConfigService configService; diff --git a/kafka-manager-task/src/main/java/com/xiaojukeji/kafka/manager/task/listener/sink/monitor/SinkCommunityTopicMetrics2Monitor.java b/kafka-manager-task/src/main/java/com/xiaojukeji/kafka/manager/task/listener/sink/monitor/SinkCommunityTopicMetrics2Monitor.java index 80b3eccd..c2804592 100644 --- a/kafka-manager-task/src/main/java/com/xiaojukeji/kafka/manager/task/listener/sink/monitor/SinkCommunityTopicMetrics2Monitor.java +++ b/kafka-manager-task/src/main/java/com/xiaojukeji/kafka/manager/task/listener/sink/monitor/SinkCommunityTopicMetrics2Monitor.java @@ -1,7 +1,6 @@ package com.xiaojukeji.kafka.manager.task.listener.sink.monitor; import com.xiaojukeji.kafka.manager.monitor.common.entry.bizenum.MonitorMetricNameEnum; -import com.xiaojukeji.kafka.manager.common.constant.LogConstant; import com.xiaojukeji.kafka.manager.monitor.common.MonitorSinkConstant; import com.xiaojukeji.kafka.manager.common.entity.metrics.TopicMetrics; import com.xiaojukeji.kafka.manager.monitor.common.entry.sink.MonitorTopicSinkTag; @@ -32,7 +31,7 @@ import java.util.List; @ConditionalOnProperty(prefix = "monitor", name = "enabled", havingValue = "true", matchIfMissing = true) @CustomScheduled(name = "sinkCommunityTopicMetrics2Monitor", cron = "1 0/1 * * * ?", threadNum = 5) public class SinkCommunityTopicMetrics2Monitor extends AbstractScheduledTask { - private final static Logger LOGGER = LoggerFactory.getLogger(LogConstant.SCHEDULED_TASK_LOGGER); + private static final Logger LOGGER = LoggerFactory.getLogger(SinkCommunityTopicMetrics2Monitor.class); @Autowired private AbstractMonitorService abstractMonitor; diff --git a/kafka-manager-task/src/main/java/com/xiaojukeji/kafka/manager/task/listener/sink/monitor/SinkConsumerMetrics2Monitor.java b/kafka-manager-task/src/main/java/com/xiaojukeji/kafka/manager/task/listener/sink/monitor/SinkConsumerMetrics2Monitor.java index a5c2e008..d12b0dfb 100644 --- a/kafka-manager-task/src/main/java/com/xiaojukeji/kafka/manager/task/listener/sink/monitor/SinkConsumerMetrics2Monitor.java +++ b/kafka-manager-task/src/main/java/com/xiaojukeji/kafka/manager/task/listener/sink/monitor/SinkConsumerMetrics2Monitor.java @@ -1,7 +1,6 @@ package com.xiaojukeji.kafka.manager.task.listener.sink.monitor; import com.xiaojukeji.kafka.manager.monitor.common.entry.bizenum.MonitorMetricNameEnum; -import com.xiaojukeji.kafka.manager.common.constant.LogConstant; import com.xiaojukeji.kafka.manager.monitor.common.MonitorSinkConstant; import com.xiaojukeji.kafka.manager.common.entity.metrics.ConsumerMetrics; import com.xiaojukeji.kafka.manager.common.entity.metrics.TopicMetrics; @@ -32,7 +31,7 @@ import java.util.*; @Component("sinkConsumerMetrics2Monitor") @ConditionalOnProperty(prefix = "monitor", name = "enabled", havingValue = "true", matchIfMissing = true) public class SinkConsumerMetrics2Monitor implements ApplicationListener { - private final static Logger LOGGER = LoggerFactory.getLogger(LogConstant.SCHEDULED_TASK_LOGGER); + private static final Logger LOGGER = LoggerFactory.getLogger(SinkConsumerMetrics2Monitor.class); @Autowired private LogicalClusterMetadataManager logicalClusterMetadataManager; diff --git a/kafka-manager-task/src/main/java/com/xiaojukeji/kafka/manager/task/schedule/FlushTopicMetrics.java b/kafka-manager-task/src/main/java/com/xiaojukeji/kafka/manager/task/schedule/FlushTopicMetrics.java index affb03e4..ef428a35 100644 --- a/kafka-manager-task/src/main/java/com/xiaojukeji/kafka/manager/task/schedule/FlushTopicMetrics.java +++ b/kafka-manager-task/src/main/java/com/xiaojukeji/kafka/manager/task/schedule/FlushTopicMetrics.java @@ -1,7 +1,6 @@ package com.xiaojukeji.kafka.manager.task.schedule; import com.xiaojukeji.kafka.manager.common.constant.KafkaMetricsCollections; -import com.xiaojukeji.kafka.manager.common.constant.LogConstant; import com.xiaojukeji.kafka.manager.common.entity.metrics.TopicMetrics; import com.xiaojukeji.kafka.manager.common.utils.ValidateUtils; import com.xiaojukeji.kafka.manager.common.entity.pojo.ClusterDO; @@ -22,7 +21,7 @@ import java.util.*; */ @Component public class FlushTopicMetrics { - private final static Logger LOGGER = LoggerFactory.getLogger(LogConstant.SCHEDULED_TASK_LOGGER); + private static final Logger LOGGER = LoggerFactory.getLogger(FlushTopicMetrics.class); @Autowired private JmxService jmxService; diff --git a/kafka-manager-task/src/main/java/com/xiaojukeji/kafka/manager/task/schedule/metadata/FlushBKConsumerGroupMetadata.java b/kafka-manager-task/src/main/java/com/xiaojukeji/kafka/manager/task/schedule/metadata/FlushBKConsumerGroupMetadata.java index 239c3ed0..8c3de582 100644 --- a/kafka-manager-task/src/main/java/com/xiaojukeji/kafka/manager/task/schedule/metadata/FlushBKConsumerGroupMetadata.java +++ b/kafka-manager-task/src/main/java/com/xiaojukeji/kafka/manager/task/schedule/metadata/FlushBKConsumerGroupMetadata.java @@ -1,6 +1,5 @@ package com.xiaojukeji.kafka.manager.task.schedule.metadata; -import com.xiaojukeji.kafka.manager.common.constant.LogConstant; import com.xiaojukeji.kafka.manager.common.entity.ConsumerMetadata; import com.xiaojukeji.kafka.manager.common.utils.ValidateUtils; import com.xiaojukeji.kafka.manager.common.entity.pojo.ClusterDO; @@ -25,7 +24,7 @@ import java.util.*; */ @Component public class FlushBKConsumerGroupMetadata { - private final static Logger LOGGER = LoggerFactory.getLogger(LogConstant.SCHEDULED_TASK_LOGGER); + private static final Logger LOGGER = LoggerFactory.getLogger(FlushBKConsumerGroupMetadata.class); @Autowired private ClusterService clusterService; diff --git a/kafka-manager-task/src/main/java/com/xiaojukeji/kafka/manager/task/schedule/metadata/FlushTopicProperties.java b/kafka-manager-task/src/main/java/com/xiaojukeji/kafka/manager/task/schedule/metadata/FlushTopicProperties.java index 41a8bde4..74394c9b 100644 --- a/kafka-manager-task/src/main/java/com/xiaojukeji/kafka/manager/task/schedule/metadata/FlushTopicProperties.java +++ b/kafka-manager-task/src/main/java/com/xiaojukeji/kafka/manager/task/schedule/metadata/FlushTopicProperties.java @@ -1,6 +1,5 @@ package com.xiaojukeji.kafka.manager.task.schedule.metadata; -import com.xiaojukeji.kafka.manager.common.constant.LogConstant; import com.xiaojukeji.kafka.manager.common.utils.ValidateUtils; import com.xiaojukeji.kafka.manager.common.zookeeper.ZkConfigImpl; import com.xiaojukeji.kafka.manager.service.utils.KafkaZookeeperUtils; @@ -22,7 +21,7 @@ import java.util.Properties; */ @Component public class FlushTopicProperties { - private final static Logger LOGGER = LoggerFactory.getLogger(LogConstant.SCHEDULED_TASK_LOGGER); + private static final Logger LOGGER = LoggerFactory.getLogger(FlushTopicProperties.class); @Autowired private ClusterService clusterService; diff --git a/kafka-manager-task/src/main/java/com/xiaojukeji/kafka/manager/task/schedule/metadata/FlushZKConsumerGroupMetadata.java b/kafka-manager-task/src/main/java/com/xiaojukeji/kafka/manager/task/schedule/metadata/FlushZKConsumerGroupMetadata.java index 54321240..f661b890 100644 --- a/kafka-manager-task/src/main/java/com/xiaojukeji/kafka/manager/task/schedule/metadata/FlushZKConsumerGroupMetadata.java +++ b/kafka-manager-task/src/main/java/com/xiaojukeji/kafka/manager/task/schedule/metadata/FlushZKConsumerGroupMetadata.java @@ -1,6 +1,5 @@ package com.xiaojukeji.kafka.manager.task.schedule.metadata; -import com.xiaojukeji.kafka.manager.common.constant.LogConstant; import com.xiaojukeji.kafka.manager.common.entity.ConsumerMetadata; import com.xiaojukeji.kafka.manager.common.utils.ValidateUtils; import com.xiaojukeji.kafka.manager.common.zookeeper.ZkConfigImpl; @@ -27,7 +26,7 @@ import java.util.stream.Collectors; */ @Component public class FlushZKConsumerGroupMetadata { - private final static Logger LOGGER = LoggerFactory.getLogger(LogConstant.SCHEDULED_TASK_LOGGER); + private static final Logger LOGGER = LoggerFactory.getLogger(FlushZKConsumerGroupMetadata.class); @Autowired private ClusterService clusterService; diff --git a/kafka-manager-web/src/main/java/com/xiaojukeji/kafka/manager/web/metrics/MetricsRegistry.java b/kafka-manager-web/src/main/java/com/xiaojukeji/kafka/manager/web/metrics/MetricsRegistry.java index 0847df6b..ccda754f 100644 --- a/kafka-manager-web/src/main/java/com/xiaojukeji/kafka/manager/web/metrics/MetricsRegistry.java +++ b/kafka-manager-web/src/main/java/com/xiaojukeji/kafka/manager/web/metrics/MetricsRegistry.java @@ -1,7 +1,6 @@ package com.xiaojukeji.kafka.manager.web.metrics; import com.codahale.metrics.*; -import com.xiaojukeji.kafka.manager.common.constant.LogConstant; import com.xiaojukeji.kafka.manager.common.utils.factory.DefaultThreadFactory; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -21,7 +20,7 @@ import java.util.concurrent.TimeUnit; */ @Component public class MetricsRegistry { - private static final Logger LOGGER = LoggerFactory.getLogger(LogConstant.API_METRICS_LOGGER); + private static final Logger LOGGER = LoggerFactory.getLogger(MetricsRegistry.class); private static final DecimalFormat DECIMAL_FORMAT = new DecimalFormat("#"); diff --git a/kafka-manager-web/src/main/resources/logback-spring.xml b/kafka-manager-web/src/main/resources/logback-spring.xml index c1c16136..83273633 100644 --- a/kafka-manager-web/src/main/resources/logback-spring.xml +++ b/kafka-manager-web/src/main/resources/logback-spring.xml @@ -131,15 +131,15 @@ - - - ${log.path}/metrics/collector_metrics.log + + + ${log.path}/log_task.log %d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n UTF-8 - ${log.path}/metrics/collector_metrics_%d{yyyy-MM-dd}.%i.log + ${log.path}/log_task_%d{yyyy-MM-dd}.%i.log 100MB @@ -147,15 +147,15 @@ - + - ${log.path}/metrics/api_metrics.log + ${log.path}/api_metrics.log %d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n UTF-8 - ${log.path}/metrics/api_metrics_%d{yyyy-MM-dd}.%i.log + ${log.path}/api_metrics_%d{yyyy-MM-dd}.%i.log 100MB @@ -163,31 +163,13 @@ - - - ${log.path}/metrics/scheduled_tasks.log - - %d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n - UTF-8 - - - ${log.path}/metrics/scheduled_tasks_%d{yyyy-MM-dd}.%i.log - - 100MB - - 5 - - + + + - - - - + - - - @@ -199,17 +181,6 @@ - + - - - - - - - - - - - \ No newline at end of file