Compare commits

...
Author SHA1 Message Date
tomsun28andDevin 17bd9f7e73 ci(doc-deploy): fix pnpm cache setup and upgrade Node to 22
The doc-deploy workflow failed with "Unable to locate executable file:
pnpm" because actions/setup-node (with cache: pnpm) ran before pnpm was
installed. Reorder the steps so pnpm/action-setup runs first, matching
the order already used in doc-build-test.yml. Also pin pnpm to v10 and
upgrade Node.js from 20 (deprecated on GitHub Actions runners) to 22
in both doc workflows to clear the deprecation warning.

Generated with [Devin](https://devin.ai)

Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-07-25 21:09:27 +08:00
Tomsun28 c805d633b6 docs: add new contributors and update notice year (#4245) 2026-07-25 20:22:02 +08:00
NekoPunchandTomsun28 c12372d82d fix(web-app): replace removed stylelint --syntax flag (#4241)
Co-authored-by: Tomsun28 <tomsun28@outlook.com>
2026-07-25 14:28:14 +08:00
NekoPunchandTomsun28 63cc017bba fix(web-app): point threshold user guide link to correct docs (#4239)
Co-authored-by: Tomsun28 <tomsun28@outlook.com>
2026-07-25 14:19:44 +08:00
NekoPunchandTomsun28 9531a2fcd3 fix(web-app): add missing Korean observability menu translations (#4240)
Co-authored-by: Tomsun28 <tomsun28@outlook.com>
2026-07-25 14:13:10 +08:00
Yang Chen 717521369c fix: update GreptimeDB Docker Compose to v1.1.3 (#4244) 2026-07-25 14:08:51 +08:00
Yang Chen c8f2da472e fix: add SSE authentication and correct GreptimeDB SQL (#4243) 2026-07-25 13:09:13 +08:00
Logic 6152c07320 refactor: evolve common-core payload compatibility (#4237) 2026-07-24 15:07:35 +08:00
Duansg b832d7ace4 [fix] fix horizontal scroll not working in periodic threshold preview table (#4238) 2026-07-24 10:39:36 +08:00
DuansgandTomsun28 3ab68b5814 [improve] degrade observability consoles gracefully when storage lacks log/trace/metric support (#4233)
Co-authored-by: Tomsun28 <tomsun28@outlook.com>
2026-07-24 00:54:05 +08:00
shown 1d9edb244c feat: use spring ai MethodToolCallbackProvider replace custom reflect… (#4234)
Signed-off-by: yuluo-yx <yuluo08290126@gmail.com>
2026-07-23 20:41:28 +08:00
Duansg 1429115282 [improve] pre-create hertzbeat_logs table during greptime signal initialization (#4231) 2026-07-23 11:34:35 +08:00
4b217e7097 feat(status-page): add configurable time range for component history (#4222)
Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
Co-authored-by: Duansg <siguoduan@gmail.com>
Co-authored-by: Tomsun28 <tomsun28@outlook.com>
2026-07-23 00:23:37 +08:00
shown 032a4852f7 fix(ai): propagate security context to tool callbacks (#4230)
Signed-off-by: yuluo-yx <yuluo08290126@gmail.com>
2026-07-22 23:46:33 +08:00
Duansg 6b78b784a2 [improve] remove unused log management translations (#4229) 2026-07-22 14:33:17 +08:00
Duansg 11cd5bb0c7 [improve] reject masked receiver edit when the stored receiver does not exist (#4225) 2026-07-22 01:32:24 +08:00
hengyussandTomsun28 a9eb231989 fix:prometheus timeout monitor key mismatch (#4215)
Co-authored-by: Tomsun28 <tomsun28@outlook.com>
2026-07-21 23:59:29 +08:00
shownandTomsun28 9b31baec8a fix(ai): improve SOP execution and provider config handling (#4224)
Signed-off-by: yuluo-yx <yuluo08290126@gmail.com>
Co-authored-by: Tomsun28 <tomsun28@outlook.com>
2026-07-21 23:34:06 +08:00
DuansgandTomsun28 0a38a73756 [improve] form-urlencode SQL request body in GreptimeSqlQueryExecutor (#4223)
Co-authored-by: Tomsun28 <tomsun28@outlook.com>
2026-07-21 23:19:43 +08:00
Duansg c9e3338c9f [improve] mask secret fields of notice receiver in rest api response (#4220) 2026-07-21 23:11:30 +08:00
shown 107f7d02ff fix(log): send initial SSE event and periodic heartbeat (#4221)
Signed-off-by: yuluo-yx <yuluo08290126@gmail.com>
2026-07-20 22:42:25 +08:00
shown e3acbbd6db chore(ci): Add workflow_dispatch trigger to nightly build (#4213) 2026-07-18 01:45:13 +08:00
31bc7d8a51 [feature] Add Korean i18n (#4197)
Co-authored-by: Claude Sonnet 5 <noreply@anthropic.com>
Co-authored-by: Duansg <siguoduan@gmail.com>
Co-authored-by: Tomsun28 <tomsun28@outlook.com>
2026-07-17 21:51:27 +08:00
Duansg 79427099a2 [improve] bump grpc-java from 1.56.1 to 1.76.3 (#4211) 2026-07-17 10:40:17 +08:00
Duansg 0edc363bcc fix: remove duplicated ASF license headers left by license-eye auto-fix (#4210) 2026-07-16 22:58:42 +08:00
47538dbc1a feat(observability): add Angular three-signal transition (#4195)
Signed-off-by: Duansg <siguoduan@gmail.com>
Signed-off-by: Tomsun28 <tomsun28@outlook.com>
Co-authored-by: Duansg <siguoduan@gmail.com>
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: Tomsun28 <tomsun28@outlook.com>
Co-authored-by: aias00 <liuhongyu@apache.org>
2026-07-16 20:39:17 +08:00
shown aee4fcc19b fix(ai): correct conversation message handling (#4208)
Signed-off-by: yuluo-yx <yuluo08290126@gmail.com>
2026-07-15 22:03:36 +08:00
Logic 34940db118 refactor: remove obsolete template marketplace (#4207) 2026-07-14 21:39:54 +08:00
NekoPunchandaias00 0d3f142849 fix: collector boot fails when jar manifest lacks Class-Path (#4190)
Co-authored-by: aias00 <liuhongyu@apache.org>
2026-07-14 00:36:09 -07:00
37623cbc37 fix: pin collector docker image root path across versions (#4189)
Co-authored-by: Duansg <siguoduan@gmail.com>
Co-authored-by: aias00 <liuhongyu@apache.org>
2026-07-13 08:27:22 -07:00
shown 1980d9a611 feat: replace deprecated Spring AI Tool API (#4206)
Signed-off-by: yuluo-yx <yuluo08290126@gmail.com>
2026-07-13 22:39:23 +08:00
DuansgandClaude Fable 5 cc8206062f [fix] Fixed matching issues caused by date components and outdated time zone offsets (#4192)
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
2026-07-13 07:23:02 -07:00
Duansg 8b6d0d0056 [fix] carry job labels/annotations/metadata in timeout metrics data (#4205) 2026-07-13 04:00:00 -07:00
NekoPunchandDuansg 7d14ed80ba [fix] expose prestodb auth parameters and wire authorization into all metrics (#4188)
Co-authored-by: Duansg <siguoduan@gmail.com>
2026-07-12 23:46:00 -07:00
NekoPunch f69c0f7b10 docs: fix dead taosKeeper doc links (#4202) 2026-07-13 14:11:39 +08:00
Duansg 4cf968a3f4 [fix] Fix notice rule label matching against grouped alerts (#4191) 2026-07-12 08:34:45 -07:00
Duansg 9bd2796119 [fix] cancel the overwritten timeout in cyclicJob to fix HashedWheelTimeout memory leak (#4201) 2026-07-12 08:05:40 -07:00
shown 0734013a2a fix: avoid LLM generates sql has sql injection error (#4200)
Signed-off-by: yuluo-yx <yuluo08290126@gmail.com>
2026-07-12 22:45:19 +08:00
shown 6ec4958997 [fix] Prevent NPE when VictoriaMetrics compression is unset (#4199) 2026-07-12 17:25:02 +08:00
shown e57c728364 feat: fix ssh connection bug (#4198) 2026-07-12 16:56:05 +08:00
Duansg 265c3f1872 [fix] Fix startup_failure: pin third-party actions to ASF-allowlisted SHAs (#4193) 2026-07-11 17:03:45 +08:00
90f4c28b86 [collector]bugfix: close jdbc connection on statement creation failure (#4184)
Co-authored-by: hutiefang <hutiefang@qq.com>
Co-authored-by: Duansg <siguoduan@gmail.com>
Signed-off-by: hutiefang <hutiefang@qq.com>
2026-07-11 16:08:34 +08:00
LiuHanZhiandTomsun28 577ab10c5f docs: fix 13 typos in documentation and comments (#4187)
Co-authored-by: Tomsun28 <tomsun28@outlook.com>
2026-07-08 22:31:26 +08:00
ef2672b06c [doc] fix typos and stale setup instructions across docs (#4186)
Co-authored-by: Duansg <siguoduan@gmail.com>
Co-authored-by: Tomsun28 <tomsun28@outlook.com>
2026-07-08 22:05:27 +08:00
NekoPunchandDuansg c2c3095505 [monitoring-template] fix: correct malformed html tags in help text (#4185)
Co-authored-by: Duansg <siguoduan@gmail.com>
2026-07-08 21:54:47 +08:00
liutianyouandTomsun28 09a8bd809a [fix] upgrade the version of spring-ai. (#4176)
Co-authored-by: Tomsun28 <tomsun28@outlook.com>
2026-07-04 18:43:16 +08:00
3c87b977ed [bugfix] Fix duplicate collector job timeouts (#4169)
Co-authored-by: hutiefang <hutiefang@qq.com>
Co-authored-by: Tomsun28 <tomsun28@outlook.com>
2026-07-04 16:52:52 +08:00
hutiefang76andTomsun28 375ee5494e [collector]bugfix: honor XML response charset (#4167)
Co-authored-by: Tomsun28 <tomsun28@outlook.com>
2026-07-04 14:27:37 +08:00
wilmerdooleyandTomsun28 a4dbf0b9bc [fix] persist custom monitor labels when writing to GreptimeDB (#4151)
Signed-off-by: wilmerdooley <wilmerdooley1@gmail.com>
Co-authored-by: Tomsun28 <tomsun28@outlook.com>
2026-07-03 20:51:56 +08:00
2fd363dfdd [feat] add ntfy as a new alert notification channel (#4132)
Co-authored-by: lynx009 <2030509072@qq.com>
Co-authored-by: Tomsun28 <tomsun28@outlook.com>
2026-07-03 00:30:57 +08:00
2389db7b3b [feat]:add db account monitoring metrics for postgresql. (#4131)
Co-authored-by: Duansg <siguoduan@gmail.com>
Co-authored-by: Tomsun28 <tomsun28@outlook.com>
2026-07-02 23:44:56 +08:00
liutianyou 1b7f7f9733 [fix] fixed the issue of plugin upload failure. (#4179) 2026-06-29 11:13:42 +08:00
Duansgandaias00 ec5564b54f [fix] pre-validate monitor import batch to avoid orphan tasks and empty list (#4180)
Co-authored-by: aias00 <liuhongyu@apache.org>
2026-06-29 09:54:43 +08:00
Duansgandaias00 87062df97d [fix] fix monitor import/export losing annotations and cron schedule … (#4166)
Co-authored-by: aias00 <liuhongyu@apache.org>
2026-06-28 07:36:55 +08:00
Duansgandaias00 a54be93ff5 [fix] keep monitor selection across pages in monitor list (#4170)
Co-authored-by: aias00 <liuhongyu@apache.org>
2026-06-28 00:02:18 +08:00
Duansg 660bda3d0f [doc] update bulletin help docs for editing and metric-tree selection (#4177) 2026-06-27 23:59:54 +08:00
wilmerdooley 45416c475e fix: avoid blocking modify monitor by redundant detect call (#4154) 2026-06-22 12:47:16 +08:00
Duansg 31aa9b5168 [fix] fix monitor list showing previous page as unavailable when paging (#4161) 2026-06-18 18:37:52 +08:00
Duansg c785f6042d [fix] fixed an issue where cron jobs were not rescheduled (#4159) 2026-06-18 11:38:58 +08:00
Duansg bf6c451c94 [feat] support editing definitions and simplify metric selection (#4158) 2026-06-17 23:41:46 +08:00
d5cf683f4f [bugfix] Fix imported monitor instance being empty due to host/instan… (#4142)
Co-authored-by: Tomsun28 <tomsun28@outlook.com>
Co-authored-by: lynx009 <2030509072@qq.com>
2026-05-29 00:19:38 +08:00
6959441f84 fix(monitor): fix Redis Sentinel helpLink, sentinel metric types, add sentinel_timedout_scripts field (#4122)
Signed-off-by: abhyudayareddy <54602866+abhyudayareddy@users.noreply.github.com>
Co-authored-by: Duansg <siguoduan@gmail.com>
Co-authored-by: Tomsun28 <tomsun28@outlook.com>
2026-05-28 23:48:15 +08:00
Duansg 42f2365e29 [fix] fix the dead link issue in ci (#4148) 2026-05-28 23:23:59 +08:00
Duansg 3496ebf497 [fix] fixed the JMX service URL validation issue (#4146) 2026-05-28 09:39:54 +08:00
70ef12d086 [monitoring-template] feat(sqlserver): add database account expiry metrics (#3737) (#4141)
Co-authored-by: Duansg <siguoduan@gmail.com>
Co-authored-by: Tomsun28 <tomsun28@outlook.com>
2026-05-24 10:31:48 +08:00
Duansg 9d8924f9e4 [fix] fix Dockerfile directory creation error (#4143) 2026-05-22 15:42:06 +08:00
DuansgandTomsun28 ecb238804b [improve] Improve status page settings UI for better UX (#4139)
Co-authored-by: Tomsun28 <tomsun28@outlook.com>
2026-05-22 14:30:34 +08:00
Duansgandzhusaidong 5cb6ee2eb8 [improve] Improve the styling of the monitoring list page (#4138)
Signed-off-by: zhusaidong <zhusaidong@gmail.com>
Co-authored-by: zhusaidong <zhusaidong@gmail.com>
2026-05-20 18:12:26 +08:00
675238b1dd [doc] update metrics storage docs to use duckdb instead of jpa (#4112)
Co-authored-by: shown <yuluo08290126@gmail.com>
Co-authored-by: Duansg <siguoduan@gmail.com>
2026-05-13 21:47:38 +08:00
zhusaidongandDuansg fcb5a9f08f bugfix Update delete dashboard response message to success (#4133)
Signed-off-by: zhusaidong <zhusaidong@gmail.com>
Co-authored-by: Duansg <siguoduan@gmail.com>
2026-05-07 14:22:19 +08:00
Duansg 4a2ddd2506 [improve] Improve LogRealTimeAlertE2eTest group alert flakiness (#4137) 2026-05-07 12:20:45 +08:00
Duansg 35cc62b844 [fix] Fix some issues related to ci (#4135) 2026-05-06 15:11:35 +08:00
Duansg 42eec4d559 [improve] Improvements to NVIDIA's monitoring history charts are not displayed (#4123) 2026-04-21 15:08:13 +08:00
aias00 e57d617db9 ci: reduce repeated setup and nightly rebuild work (#4119) 2026-04-16 18:27:57 +08:00
P_Peaceful 34dad832c3 [doc] add questdb init doc to sidebar and unify label (#4113) 2026-04-11 10:00:00 +08:00
P_PeacefulandTomsun28 50d7548748 [fix] support realtime metric and log edit tooltip (#4110)
Co-authored-by: Tomsun28 <tomsun28@outlook.com>
2026-04-05 23:42:25 +08:00
P_Peaceful 87d55d8ad2 [doc] rename WeChat Public to WeChat Official Account (#4109) 2026-04-05 23:31:38 +08:00
P_Peaceful 4680ae547a [doc]: fix MD001 heading increment issues in home docs (#4106) 2026-04-02 23:57:43 +08:00
P_Peaceful c8209f18ad [doc] update markdownlint config to ignore MD060 (#4105) 2026-04-01 21:27:06 +08:00
shown c8021dc8d7 feat: add common protocol entity check (#4097)
Signed-off-by: yuluo-yx <yuluo08290126@gmail.com>
2026-04-01 08:15:57 +08:00
P_Peaceful e0145f6a4f [feature]: support victoria metrics cluster query executor (#4103) 2026-03-31 15:01:31 +08:00
pentium100andLogic 6d459957fb feat(nacos-sd): add auth and filtering parameters for Nacos service d… (#4099)
Co-authored-by: Logic <zqr10159@dromara.org>
2026-03-29 22:33:33 +08:00
b73f824e3c [Improve] Add common protoctl entity check (#4084)
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: aias00 <liuhongyu@apache.org>
Co-authored-by: Tomsun28 <tomsun28@outlook.com>
2026-03-28 12:10:06 +08:00
2bb4f43494 [improve] optimize the function of creating monitoring using AI (#3922)
Signed-off-by: aias00 <liuhongyu@apache.org>
Co-authored-by: lynx009 <2030509072@qq.com>
Co-authored-by: aias00 <liuhongyu@apache.org>
Co-authored-by: shown <yuluo08290126@gmail.com>
Co-authored-by: Duansg <siguoduan@gmail.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: manshi <lty496227@digital-engine.com>
2026-03-27 23:05:14 +08:00
P_Peaceful 695be421f2 [doc] improve e2e local run guide (#4095) 2026-03-27 16:25:00 +08:00
P_Peacefulandshown 75d6dee367 [ci]: update the dependency versions of GitHub Actions workflows (#4089)
Co-authored-by: shown <yuluo08290126@gmail.com>
2026-03-27 12:45:07 +08:00
Logic a819451011 docs: remove reddit and qq links from readmes (#4092) 2026-03-27 07:51:29 +08:00
P_Peaceful cdb6411b83 [improve] fix e2e test failure caused by api-testing reverse test behavior (#4091)
Signed-off-by: P_Peaceful <wenzhengcheng0223@163.com>
2026-03-25 23:24:07 +08:00
P_Peaceful cdb913c472 [CI] update Docker build-push-action version (#4088)
Signed-off-by: P_Peaceful <wenzhengcheng0223@163.com>
2026-03-24 23:11:47 +08:00
a4d2630320 [fix] fix cyclic silence time matching and cross-midnight handling (#4081)
Co-authored-by: yunfan24 <yunfan24@outlook.com>
Co-authored-by: Tomsun28 <tomsun28@outlook.com>
2026-03-22 22:05:27 +08:00
DuansgandTomsun28 b9e07d81f9 [feat] add monitoring template for the LM Studio platform (#4082)
Co-authored-by: Tomsun28 <tomsun28@outlook.com>
2026-03-22 17:58:02 +08:00
Duansg affccb7fb7 [fix] fixed issue with the token management style (#4083) 2026-03-22 11:23:13 +08:00
DuansgandTomsun28 3e6a7962f6 [feat] add API token management functionality (#4080)
Co-authored-by: Tomsun28 <tomsun28@outlook.com>
2026-03-21 16:20:59 +08:00
922aa311e0 [feat]: add MySQL R2DBC query engine support (#4074)
Signed-off-by: Logic <zqr10159@dromara.org>
Co-authored-by: Duansg <siguoduan@gmail.com>
Co-authored-by: Tomsun28 <tomsun28@outlook.com>
2026-03-21 16:12:17 +08:00
2016b18249 [docs]doc: fix typos and grammar in docs and AccountController (#4072)
Signed-off-by: Duansg <siguoduan@gmail.com>
Co-authored-by: shown <yuluo08290126@gmail.com>
Co-authored-by: Duansg <siguoduan@gmail.com>
2026-03-21 15:39:39 +08:00
zhluandDuansg 0297f0d4f8 [build]fix: remove duplicate version properties in root pom (#4073)
Co-authored-by: Duansg <siguoduan@gmail.com>
2026-03-19 23:46:35 +08:00
5a98b56a5e [docs]doc: unify naming HertzBeat and agentless across docs and assets (#4075)
Co-authored-by: Logic <zqr10159@dromara.org>
Co-authored-by: Duansg <siguoduan@gmail.com>
2026-03-18 22:12:02 +08:00
Duansg bed2e4b3a0 [fix] fix zookeeper configuration not taking effect (#4077) 2026-03-18 21:19:02 +08:00
Duansg d1e28e7621 [improve] improve the hierarchical alignment of token issuance (#4076) 2026-03-18 09:06:07 +08:00
shownandDuansg 61c9b050b5 feat[common]: add core protoctl entity check (#4065)
Signed-off-by: yuluo-yx <yuluo08290126@gmail.com>
Co-authored-by: Duansg <siguoduan@gmail.com>
2026-03-17 20:08:59 +08:00
LogicandTomsun28 f4858d5fcc [feat]: Native collector (#4066)
Co-authored-by: Tomsun28 <tomsun28@outlook.com>
2026-03-17 09:30:08 +08:00
Duansg 07fd5b25c3 [improve] improve plugin upload validation (#4067) 2026-03-17 09:14:38 +08:00
DuansgandTomsun28 d16a95d8d6 [feat]Add monitoring support for Ollama LLM runtime (#4064)
Co-authored-by: Tomsun28 <tomsun28@outlook.com>
2026-03-12 00:52:53 +08:00
shownandTomsun28 39567816e9 feat[common]: add protocol entity check (#4060)
Signed-off-by: yuluo-yx <yuluo08290126@gmail.com>
Co-authored-by: Tomsun28 <tomsun28@outlook.com>
2026-03-12 00:45:21 +08:00
Logic af56746de1 [feat]: migrate blocking executors to virtual threads (#4062) 2026-03-12 00:36:29 +08:00
shown d99e567494 feat: update nacos client to 3.1.1 (#4061)
Signed-off-by: yuluo-yx <yuluo08290126@gmail.com>
2026-03-10 16:47:25 +08:00
Logicandlynx009 9e1a460dc7 refactor: update to Springboot4 and Hibernate 7 (#4057)
Co-authored-by: lynx009 <2030509072@qq.com>
2026-03-09 23:34:15 +08:00
Tomsun28 00b83ff531 chore: remove the sharp package (#4056)
Signed-off-by: tomsun28 <tomsun28@outlook.com>
2026-03-08 20:01:49 +08:00
shown 5c2950d838 feat[common]: add protocl entity check (#4055)
Signed-off-by: yuluo-yx <yuluo08290126@gmail.com>
2026-03-08 19:31:18 +08:00
brettgervasoniandBrett 155667833e [bugfix] correct typo in sureness monitor delete verb definition (#4054)
Co-authored-by: Brett <>
2026-03-08 15:32:35 +08:00
Tomsun28 6b78364596 docs: improve website geo (#4053) 2026-03-07 16:30:44 +08:00
shownandTomsun28 35b79cf649 feat[common]: add hertzbeat common protocol entitiy check (#4052)
Signed-off-by: yuluo-yx <yuluo08290126@gmail.com>
Co-authored-by: Tomsun28 <tomsun28@outlook.com>
2026-03-07 11:56:12 +08:00
fc2efb13eb style: apply primary button style to monitor manage action (#4045)
Co-authored-by: Duansg <siguoduan@gmail.com>
Co-authored-by: Tomsun28 <tomsun28@outlook.com>
2026-03-07 11:54:35 +08:00
DuansgandTomsun28 84361b4d87 [improve] improved interaction styling for the template editor (#4051)
Co-authored-by: Tomsun28 <tomsun28@outlook.com>
2026-03-04 23:34:05 +08:00
DuansgandTomsun28 40c842b0d7 [improve] add group convergence strategy name validation (#4050)
Co-authored-by: Tomsun28 <tomsun28@outlook.com>
2026-03-04 23:30:01 +08:00
shownandDuansg f76581b860 fix[protocol-sd]: add register center params check (#4048)
Signed-off-by: yuluo-yx <yuluo08290126@gmail.com>
Co-authored-by: Duansg <siguoduan@gmail.com>
2026-03-04 23:19:00 +08:00
LunaRain_079 b3dba8b3cf [feat] Support Apache Doris as time-series storage for both metrics and logs (#4031) 2026-03-02 23:02:51 +08:00
layla 8174b68c0d Fix typo: occured to occurred (#4049) 2026-03-01 22:35:50 +08:00
Tomsun28andshown dea7bdc7fe fix: fix home doc deploy action (#4029)
Co-authored-by: shown <yuluo08290126@gmail.com>
2026-03-01 19:37:09 +08:00
Tomsun28andshown c165be6c2a docs: update security model desc (#4047)
Co-authored-by: shown <yuluo08290126@gmail.com>
2026-03-01 19:05:50 +08:00
d99b5dbff5 feat: SOP-driven AI workflows with skills, scheduling, and i18n support (#4016)
Signed-off-by: aias00 <liuhongyu@apache.org>
Signed-off-by: Tomsun28 <tomsun28@outlook.com>
Co-authored-by: lynx009 <2030509072@qq.com>
Co-authored-by: Duansg <siguoduan@gmail.com>
Co-authored-by: aias00 <liuhongyu@apache.org>
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: Tomsun28 <tomsun28@outlook.com>
2026-03-01 15:53:24 +08:00
DuansgandTomsun28 cc50a50a0d [fix] fix alertmanager integration issue (#4022)
Co-authored-by: Tomsun28 <tomsun28@outlook.com>
2026-02-28 00:10:50 +08:00
Duansgandliutianyou dbcd3f3c0d [improve] Improve the login page style (#4044)
Co-authored-by: liutianyou <liutianyou@apache.org>
2026-02-27 23:11:45 +08:00
67c11b9128 fix: Add i18n support for setting-drawer component (#4006)
Co-authored-by: Logic <zqr10159@dromara.org>
Co-authored-by: Tomsun28 <tomsun28@outlook.com>
Co-authored-by: Sherlock Yin <sherlock.yin1994@gmail.com>
Co-authored-by: liutianyou <liutianyou@apache.org>
2026-02-27 22:48:44 +08:00
cd40699293 refactor: Split hertzbeat-common into core and spring modules (#4035)
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: zqr10159 <30048352+zqr10159@users.noreply.github.com>
Co-authored-by: Tomsun28 <tomsun28@outlook.com>
2026-02-25 09:49:52 +08:00
DuansgandLogic 70015568e2 Revert "[Task] Add user account monitoring metrics for MongoDB" (#4038)
Co-authored-by: Logic <zqr10159@dromara.org>
2026-02-24 22:18:43 +08:00
767ce6b073 docs: add H2 database security warning page (#4036)
Signed-off-by: Turan Almammadov <16321061+turanalmammadov@users.noreply.github.com>
Co-authored-by: Turan Almammadov <16321061+turanalmammadov@users.noreply.github.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-24 22:00:29 +08:00
09818174eb [Task] Add user account monitoring metrics for MongoDB (#4033)
Signed-off-by: Turan Almammadov <16321061+turanalmammadov@users.noreply.github.com>
Co-authored-by: Turan Almammadov <16321061+turanalmammadov@users.noreply.github.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-24 17:17:16 +08:00
Duansg ebfd3c73e3 [fix] Fixed template name mismatch issue (#4021) 2026-02-13 23:06:02 +08:00
Tomsun28 cc60f8453b docs: fix the sidebars i18n and version display, add auto deploy action (#4018)
Signed-off-by: tomsun28 <tomsun28@outlook.com>
2026-02-08 22:14:05 +08:00
0cf286a063 [Docs] Release version 1.8.0 documentation (#4017)
Signed-off-by: Tomsun28 <tomsun28@outlook.com>
Co-authored-by: Tomsun28 <tomsun28@outlook.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2026-02-07 10:18:41 +08:00
3da977a96f docs: update download page to v1.8.0 (#4015)
Co-authored-by: a-little-fool <2030509072@qq.com>
Co-authored-by: Duansg <siguoduan@gmail.com>
Co-authored-by: Tomsun28 <tomsun28@outlook.com>
2026-02-07 09:01:49 +08:00
Duansg c10761ec9a [improve] improved version validation documentation content (#4013) 2026-02-06 20:50:59 +08:00
Duansg b0c6324713 [fix] Fixed Prometheus task history charts not working in the Favorites tab (#4014) 2026-02-06 16:39:01 +08:00
DuansgandTomsun28 1b51c19c97 [fix]fixed sql formatting error (#4008)
Co-authored-by: Tomsun28 <tomsun28@outlook.com>
2026-01-30 00:00:31 +08:00
LunaRain_079 a83cb0f50f [docs] Fix HTTP Service Discovery API response format (#4005) 2026-01-29 22:10:15 +08:00
Tomsun28 d6022cb587 docs: update doc add contributors and pnpm lock (#4002)
Signed-off-by: tomsun28 <tomsun28@outlook.com>
2026-01-25 20:34:49 +08:00
LogicandTomsun28 67f525a603 [fix] update table name generation to include application context (#4001)
Co-authored-by: Tomsun28 <tomsun28@outlook.com>
2026-01-24 23:26:08 +08:00
LunaRain_079andDuansg 634006aa7e [refactor] Dynamically concatenate app parameter on the front end to accommodate Prometheus apps (#4000)
Co-authored-by: Duansg <siguoduan@gmail.com>
2026-01-24 23:06:25 +08:00
3eb3f926f5 [fix] Update query parameter encoding and error time parser in VictoriaMetricsClusterDataStorage (#3989)
Co-authored-by: Yang Chen <1597081640@qq.com>
Co-authored-by: aias00 <liuhongyu@apache.org>
Co-authored-by: Duansg <siguoduan@gmail.com>
2026-01-24 20:37:08 +08:00
47caa5bdf8 feat: support otlp http binary protobuf format log data and update doc (#3986)
Signed-off-by: Yang Chen <1597081640@qq.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Logic <zqr10159@dromara.org>
2026-01-23 18:34:36 +08:00
Logic 67c3727362 [Refactor] tighten resource constraints for XML/XPath collector (#3999) 2026-01-22 18:51:01 +08:00
b510d6e5ea [feature] add datasource status retrieval and update alert settings UI (#3985)
Signed-off-by: Logic <zqr10159@126.com>
Signed-off-by: Duansg <siguoduan@gmail.com>
Co-authored-by: aias00 <liuhongyu@apache.org>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Duansg <siguoduan@gmail.com>
2026-01-20 22:43:47 +08:00
1ab27bd556 [doc]: update to Docusaurus v3.9.2 (#3984)
Co-authored-by: Tomsun28 <tomsun28@outlook.com>
Co-authored-by: Duansg <siguoduan@gmail.com>
Co-authored-by: aias00 <liuhongyu@apache.org>
2026-01-20 22:04:27 +08:00
Duansg 9600a5e56f [improve] upgrade script merge (#3987) 2026-01-19 23:47:32 +08:00
6c0d5c0db4 [fix]Fix issues such as index failure (#3953)
Co-authored-by: shown <yuluo08290126@gmail.com>
Co-authored-by: Yang Chen <1597081640@qq.com>
Co-authored-by: Logic <zqr10159@dromara.org>
2026-01-18 23:07:42 +08:00
4b010e6523 [monitoring-template] feat(mysql): add database account expiry metrics (#3969)
Co-authored-by: Logic <zqr10159@dromara.org>
Co-authored-by: Duansg <siguoduan@gmail.com>
2026-01-18 22:29:03 +08:00
8962253dd2 [manager] bugfix: fix incorrect status page date calculation (#3962)
Signed-off-by: Tomsun28 <tomsun28@outlook.com>
Co-authored-by: Duansg <siguoduan@gmail.com>
Co-authored-by: Tomsun28 <tomsun28@outlook.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2026-01-17 20:08:12 +08:00
Logic afd89e4309 Fix htaccess (#3980)
Signed-off-by: Logic <zqr10159@dromara.org>
2026-01-16 22:16:15 +08:00
Logic 43332f49db [fix]: update Content Security Policy in .htaccess to include new domains (#3979) 2026-01-16 20:53:11 +08:00
Duansg cc90de5541 [fix] fixed cache parsing issues (#3977) 2026-01-16 15:47:09 +08:00
Tomsun28 5e1460bf29 docs: update invitation email template (#3975) 2026-01-16 09:10:51 +08:00
LogicandYang Chen 7dbdca849a [doc]: add monitoring documentation for various service discovery methods (#3965)
Co-authored-by: Yang Chen <1597081640@qq.com>
2026-01-15 21:27:42 +08:00
Yang ChenandDuansg df525d2d32 fix: add GreptimeDB docker-compose assembly configuration (#3960)
Co-authored-by: Duansg <siguoduan@gmail.com>
2026-01-14 20:51:24 +08:00
LunaRain_079 dc96f1766b [Fix]: fix TAG type mismatch by introducing schema version for TDengine (#3963) 2026-01-13 21:29:27 +08:00
Tomsun28andDuansg 70da7d5dce docs: update docs link (#3958)
Co-authored-by: Duansg <siguoduan@gmail.com>
2026-01-11 18:46:13 +08:00
Prakash Kumar 0f1169ce36 [Fix] Fixed alignment of header social links on mobile (#3959) 2026-01-11 09:57:39 +08:00
KOYR 1c38d01abb style: widen table column to prevent label truncation (#3957) 2026-01-10 22:10:53 +08:00
f82b5add11 [feature] Update CSP permissions to include Kapa.ai services (#3948)
Signed-off-by: Duansg <siguoduan@gmail.com>
Co-authored-by: Duansg <siguoduan@gmail.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2026-01-08 09:49:48 +08:00
KOYR 8e2c1f3b07 style: adjust grid layout width of form labels (#3950) 2026-01-07 15:06:45 +08:00
Logic 8ef92d70d2 [fix] Update overflow properties and enhance swiper container styles (#3947) 2026-01-07 08:10:37 +08:00
Yang Chen b5ce5c9e9d [fix] refactor system built-in labels validation logic (#3946) 2026-01-06 15:47:25 +08:00
P_Peaceful a19a399acd [bugfix&improve] Fix alert label persistence and improve custom label input (#3933) 2026-01-06 12:01:53 +08:00
529d161478 [improve] Optimize Tooltip display logic and support scrollable content (#3941)
Signed-off-by: Tomsun28 <tomsun28@outlook.com>
Co-authored-by: Tomsun28 <tomsun28@outlook.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2026-01-04 23:24:46 +08:00
168f78ef23 chore: optimzie docker compose docs hertzbeat version (#3929)
Signed-off-by: yuluo-yx <yuluo08290126@gmail.com>
Co-authored-by: aias00 <liuhongyu@apache.org>
Co-authored-by: Duansg <siguoduan@gmail.com>
2026-01-03 19:05:35 +08:00
KOYRandDuansg a159127572 [improve]: Optimize yAxis scale to better reflect data fluctuations (#3939)
Co-authored-by: Duansg <siguoduan@gmail.com>
2026-01-03 01:57:14 +08:00
88933ce0bb [feature] Update UI text and styles for website (#3934)
Signed-off-by: Logic <zqr10159@126.com>
Signed-off-by: Duansg <siguoduan@gmail.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Duansg <siguoduan@gmail.com>
Co-authored-by: aias00 <liuhongyu@apache.org>
2025-12-31 16:00:13 +08:00
Logic 6d703f7eae [feature] add Kapa widget script to docusaurus configuration (#3938) 2025-12-31 10:30:49 +08:00
Duansg f4a0fe3445 [fix] fixed CSP blocking algolia from loading on the page (#3935) 2025-12-30 09:56:58 +08:00
Sahil Shadwal b174c8622c [bugfix]: fix for the collector tab click effect error (#3932) 2025-12-28 18:42:04 +08:00
LathikaBaddam 98e0412ee6 [docs] improve English translation and technical terms for MySQL (#3928) 2025-12-27 20:20:04 +08:00
Logic a138238994 [bugfix] Enhance expiration time parsing to support strict day format (#3924) 2025-12-22 20:44:21 +08:00
Duansgandlynx009 01f5cb1fd6 [feat] Add Grafana to follow the system theme (#3920)
Co-authored-by: lynx009 <2030509072@qq.com>
2025-12-20 19:44:53 +08:00
Tomsun28andYang Chen 472554bc55 [chore] update docker compose hertzbeat version (#3916)
Signed-off-by: tomsun28 <tomsun28@outlook.com>
Co-authored-by: Yang Chen <1597081640@qq.com>
2025-12-19 14:15:28 +08:00
Logic ad9a4ab100 [improve] xugu.md and app-xugu.yml (#3918) 2025-12-17 18:51:58 +08:00
KOYR a806ca1319 [Feature] Enhance draggable UI elements in alert settings (#3915) (#3917) 2025-12-17 09:33:23 +08:00
P_PeacefulandTomsun28 aac5bafe43 [bugfix]: AI conversation message loading issue (#3911)
Co-authored-by: Tomsun28 <tomsun28@outlook.com>
2025-12-16 23:54:38 +08:00
P_PeacefulandLogic 668106d445 [bugfix] AI prompt classpath error (#3912)
Co-authored-by: Logic <zqr10159@dromara.org>
2025-12-16 11:36:23 +08:00
a74671abdd [improve]Improve UI handling for label overflow (#3913)
Co-authored-by: 半半 <kongranyi@cai-inc.com>
Co-authored-by: Logic <zqr10159@dromara.org>
2025-12-16 11:03:15 +08:00
Duansg 120d494c47 [fix]Fixed private collector tasks not taking effect (#3914) 2025-12-16 10:51:39 +08:00
DeleiGuo 5b1d01e0c5 [bugfix] Modify the search predicate from 'host' to 'instance' field (#3910) 2025-12-13 10:25:52 +08:00
Yang ChenandCopilot 950138a340 [feat] Add an SQL editor and prevent SQL injection (#3900)
Signed-off-by: Yang Chen <1597081640@qq.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-12-12 17:52:31 +08:00
zhaoyangplus 93d8f92165 feat(db): Added support for monitoring the Xugu database (#3899) 2025-12-12 11:32:40 +08:00
LogicandCopilot 488df340a1 [Fix]: Use a connection pool to avoid concurrent access to duckdb files. (#3898)
Signed-off-by: Logic <zqr10159@126.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-12-10 15:38:30 +08:00
DuansgandTomsun28 dc51ce7bef [fix]Fixed position offset issue during deserialization of ArrowUtil (#3897)
Co-authored-by: Tomsun28 <tomsun28@outlook.com>
2025-12-09 21:46:36 +08:00
Logicandaias00 862f32e699 [Feature]: enhance logging configuration with asynchronous console appender (#3895)
Co-authored-by: aias00 <liuhongyu@apache.org>
2025-12-09 21:15:42 +08:00
DeleiGuo d0f6a04661 [docs] Add new committer blog (#3894) 2025-12-09 09:46:19 +08:00
shownandTomsun28 cb3fad6a2c feat: optimize hertzbeat ai module (#3891)
Signed-off-by: yuluo-yx <yuluo08290126@gmail.com>
Signed-off-by: shown <yuluo08290126@gmail.com>
Signed-off-by: tomsun28 <tomsun28@outlook.com>
Co-authored-by: Tomsun28 <tomsun28@outlook.com>
2025-12-08 22:55:44 +08:00
Tomsun28andshown c88c232889 feat: support mcp streamable http protocol and upgrade spring ai version (#3890)
Signed-off-by: tomsun28 <tomsun28@outlook.com>
Co-authored-by: shown <yuluo08290126@gmail.com>
2025-12-08 22:12:35 +08:00
6b03e4bb5f chore: add .editorconfig for consistent coding style (#3875)
Co-authored-by: Duansg <siguoduan@gmail.com>
Co-authored-by: aias00 <liuhongyu@apache.org>
2025-12-07 00:02:07 +08:00
7727d63451 [add] Add parameter validators and their corresponding tests (#3888)
Signed-off-by: aias00 <liuhongyu@apache.org>
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Tomsun28 <tomsun28@outlook.com>
2025-12-06 19:34:47 +08:00
Duansg 3e567e5be6 [improve]Improve issues related to tag conflicts (#3889) 2025-12-05 22:02:43 +08:00
Tomsun28andaias00 4ae6ba9a3c feat: update add monitors pop selected menus modal (#3878)
Signed-off-by: tomsun28 <tomsun28@outlook.com>
Co-authored-by: aias00 <liuhongyu@apache.org>
2025-12-04 23:55:10 +08:00
360abcc61d [feature] Using duckdb instead of jpa to store history data (#3883)
Signed-off-by: Logic <zqr10159@126.com>
Co-authored-by: aias00 <liuhongyu@apache.org>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-12-04 23:51:04 +08:00
P_PeacefulandTomsun28 41e57db032 [bugfix] notice policy lost Gotify receiver type (#3886)
Co-authored-by: Tomsun28 <tomsun28@outlook.com>
2025-12-03 22:44:20 +08:00
DuansgandTomsun28 b62137d185 [improve]Improve performance issues caused by too many metrics (#3879)
Co-authored-by: Tomsun28 <tomsun28@outlook.com>
2025-12-03 22:30:26 +08:00
DuansgandTomsun28 2bd635e1d4 [fix]Fix some systemic issues (#3884)
Co-authored-by: Tomsun28 <tomsun28@outlook.com>
2025-12-03 22:25:02 +08:00
Yang Chen 8e8ab80aa0 Revert "[refractor] Using Spring jdbc to query Greptime log" (#3885) 2025-12-03 12:32:45 +08:00
LogicandYang Chen 7f4c2e0487 [refractor] Using Spring jdbc to query Greptime log (#3880)
Signed-off-by: Yang Chen <1597081640@qq.com>
Co-authored-by: Yang Chen <1597081640@qq.com>
2025-12-03 12:11:08 +08:00
e52e715a53 improvement: optimize log stream for high TPS scenarios (#3876)
Signed-off-by: Yang Chen <1597081640@qq.com>
Co-authored-by: factory-droid[bot] <138933559+factory-droid[bot]@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Duansg <siguoduan@gmail.com>
2025-12-03 11:18:49 +08:00
e3e7377d86 [refactor] Refactor Monitor host field to instance and update related logic (#3863)
Signed-off-by: Tomsun28 <tomsun28@outlook.com>
Co-authored-by: Tomsun28 <tomsun28@outlook.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-12-01 21:45:59 +08:00
P_PeacefulandTomsun28 625dbe9624 [bugfix] redis cluster monitor master-slave relationship is inconsistent (#3874)
Co-authored-by: Tomsun28 <tomsun28@outlook.com>
2025-11-30 19:39:40 +08:00
Duansgandaias00 42f0a74edf [fix] adding trusted domain verification (#3866)
Co-authored-by: aias00 <liuhongyu@apache.org>
2025-11-27 20:38:00 +08:00
Tomsun28 cc9f53d71a chore: update sureness yml (#3870) 2025-11-27 20:10:46 +08:00
DeleiGuo 2f122dfb05 [docs] fix the missing documents references in the sidebar (#3867) 2025-11-26 16:52:43 +08:00
f7b0010180 fix: Remove redundant metrics data send in KafkaCommonDataQueue (#3854)
Co-authored-by: Calvin <zhengqiwei@apache.org>
Co-authored-by: Duansg <siguoduan@gmail.com>
2025-11-24 22:11:49 +08:00
2c0fecaa62 [improve] Added simple exponential backoff strategy (#3860)
Signed-off-by: Duansg <siguoduan@gmail.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Yang Chen <1597081640@qq.com>
2025-11-21 16:28:21 +08:00
548966906c [bugfix] align tooltip position for mute icon with other icons (#3862)
Co-authored-by: Duansg <siguoduan@gmail.com>
Co-authored-by: Tomsun28 <tomsun28@outlook.com>
2025-11-20 22:22:56 +08:00
6473546f56 [feat] Add DB2 database monitoring support (#3857)
Co-authored-by: Tomsun28 <tomsun28@outlook.com>
Co-authored-by: Calvin <zhengqiwei@apache.org>
Co-authored-by: Duansg <siguoduan@gmail.com>
2025-11-20 22:16:52 +08:00
035d63c880 [feature] Support FeiShu/Lark App Alert Notification (#3856)
Co-authored-by: Tomsun28 <tomsun28@outlook.com>
Co-authored-by: Calvin <zhengqiwei@apache.org>
2025-11-20 00:14:57 +08:00
Yang ChenandCalvin d56176dfa5 feat: add new docker-compose deployment solution (#3859)
Co-authored-by: Calvin <zhengqiwei@apache.org>
2025-11-19 23:49:13 +08:00
Yang ChenandCalvin c1815f5107 fix: allow access to /log/** path to resolve unauthorized error on refresh (#3858)
Co-authored-by: Calvin <zhengqiwei@apache.org>
2025-11-18 01:33:29 +08:00
7ac175e726 [Improve]Unify UI border-radius to 6px for a more professional look (#3853)
Co-authored-by: Duansg <siguoduan@gmail.com>
Co-authored-by: Tomsun28 <tomsun28@outlook.com>
2025-11-17 23:02:21 +08:00
eb5e843251 [feat] Add webhook authentication support for alert notifications (#3797)
Co-authored-by: Sherlock Yin <sherlock.yin1994@gmail.com>
Co-authored-by: yunfan24 <yunfan24@outlook.com>
Co-authored-by: aias00 <liuhongyu@apache.org>
Co-authored-by: Calvin <zhengqiwei@apache.org>
Co-authored-by: kangli <likang@apache.org>
Co-authored-by: 刘俊辉 <liu.junhui3@iwhalecloud.com>
2025-11-17 22:59:35 +08:00
starryCoderandDuansg bc098aa4d2 [bugfix]manager: Avoid NPE when metrics data queue is empty (#3848)
Co-authored-by: Duansg <siguoduan@gmail.com>
2025-11-14 16:09:49 +08:00
Tomsun28 bcd394b47f [docs] update doc fix wrong manager (#3850)
Signed-off-by: tomsun28 <tomsun28@outlook.com>
2025-11-08 20:33:42 +08:00
Duansg fd2202fcaf [doc] add new committer blog (#3847) 2025-11-06 21:37:17 +08:00
a7629e317a Modify the issue of incorrect signature in Alibaba's SMS sending (#3788)
Co-authored-by: Logic <zqr10159@dromara.org>
Co-authored-by: Tomsun28 <tomsun28@outlook.com>
Co-authored-by: shown <yuluo08290126@gmail.com>
Co-authored-by: yunfan24 <yunfan24@outlook.com>
Co-authored-by: Calvin <zhengqiwei@apache.org>
Co-authored-by: aias00 <liuhongyu@apache.org>
Co-authored-by: Duansg <siguoduan@gmail.com>
2025-11-06 10:38:48 +08:00
DeleiGuoandshown 3a378f8710 [feature] support the security settings for robot signatures in DingTalk (#3841)
Co-authored-by: shown <yuluo08290126@gmail.com>
2025-11-03 11:43:08 +08:00
Tomsun28 cf59907fcd fix the labels limit error (#3842)
Signed-off-by: tomsun28 <tomsun28@outlook.com>
2025-11-02 20:56:21 +08:00
Tomsun28 624ba8dc8d docs: update readme and doc (#3840) 2025-11-02 12:14:20 +08:00
Tomsun28andaias00 fb4b665c85 refactor ai agent and fix bug, update doc (#3836)
Signed-off-by: tomsun28 <tomsun28@outlook.com>
Co-authored-by: aias00 <liuhongyu@apache.org>
2025-11-01 21:22:42 +08:00
Calvin 5a9f371e9d [doc] add pmc blog of Calvin, add Duansg as committer and Calvin as PMC (#3838) 2025-11-01 09:38:45 +08:00
Duansg 5c3d1a04de [improve] SLS integrated access supports merged alarm resolution (#3835) 2025-10-31 21:00:34 +08:00
Cyantyandaias00 024b44f477 [ci] replace outdated link addresses in dead link check (#3834)
Co-authored-by: aias00 <liuhongyu@apache.org>
2025-10-31 10:16:10 +08:00
Cyanty 35046f8a06 [ci] fix markdown lint ci (#3833) 2025-10-31 09:36:28 +08:00
Duansgandaias00 23c2f85e8a [fix] Optimize the issue where missing tags cause alert statuses to become disordered (#3829)
Co-authored-by: aias00 <liuhongyu@apache.org>
2025-10-29 14:24:02 +08:00
Tomsun28 56226c1d52 refactor: split manager to startup module (#3830)
Signed-off-by: tomsun28 <tomsun28@outlook.com>
2025-10-29 13:49:04 +08:00
Tomsun28 9014f117d3 docs: update contributors page (#3827)
Signed-off-by: tomsun28 <tomsun28@outlook.com>
2025-10-25 13:53:35 +08:00
Tomsun28andCalvin e073bfee91 refactor: refactor ai feature (#3823)
Signed-off-by: tomsun28 <tomsun28@outlook.com>
Co-authored-by: Calvin <zhengqiwei@apache.org>
2025-10-25 12:39:53 +08:00
Duansg 897d5d4220 [fix]Fixed issue where refresh did not take effect (#3825) 2025-10-24 21:58:22 +08:00
DuansgandTomsun28 4228605a3d [improve] Jexl validation rule enhancements (#3821)
Co-authored-by: Tomsun28 <tomsun28@outlook.com>
2025-10-19 23:08:19 +08:00
DeleiGuo e7131b1881 [docs] fix the issue of avatar reference on the team page (#3820) 2025-10-18 17:59:16 +08:00
DuansgandTomsun28 8a22797bca [fix] Only POST and PUT methods carry payload (#3814)
Co-authored-by: Tomsun28 <tomsun28@outlook.com>
2025-10-14 21:51:50 +08:00
b9e569a1e0 [fix]: fix bugs in frontend for monitoring (#3806)
Co-authored-by: aias00 <liuhongyu@apache.org>
Co-authored-by: Tomsun28 <tomsun28@outlook.com>
2025-10-13 23:54:11 +08:00
1284b4b46b [feat] Monitoring Center - Added cron expression support for scheduling type (#3777)
Co-authored-by: Calvin <zhengqiwei@apache.org>
Co-authored-by: Sherlock Yin <sherlock.yin1994@gmail.com>
Co-authored-by: Tomsun28 <tomsun28@outlook.com>
2025-10-12 00:12:26 +08:00
175c289e66 modify apt sources from http to https. (#3808)
Co-authored-by: liwei <liwei@itg.com.cn>
Co-authored-by: Logic <zqr10159@dromara.org>
2025-10-11 14:37:06 +08:00
Duansg 899e92882d [refactor]Refactoring prometheus label value utf8 support (#3810) 2025-10-11 11:31:09 +08:00
Yang ChenandTomsun28 d516b3a15d improvement: improve log severity text input (#3805)
Co-authored-by: Tomsun28 <tomsun28@outlook.com>
2025-10-08 00:31:31 +08:00
pentium100andTomsun28 7678c3f139 fix some bug in service discovery: (#3804)
Co-authored-by: Tomsun28 <tomsun28@outlook.com>
2025-10-08 00:29:30 +08:00
Tomsun28 3b49c0cb75 chore: use pnpm instead of yarn (#3802) 2025-10-06 21:33:11 +08:00
zhou yong kangandTomsun28 32d784e57e fix: use UTF-8 to solve Chineses bug (#3792)
Co-authored-by: Tomsun28 <tomsun28@outlook.com>
2025-10-05 09:17:33 +08:00
pentium100andTomsun28 d8f8444275 [feature] dns add record type (#3799)
Co-authored-by: Tomsun28 <tomsun28@outlook.com>
2025-10-05 08:58:34 +08:00
Dedy Kurniawan Santoso 41676c1f13 [improve] nitpicking "Dispatch ALl" on en-US.json (#3800)
Signed-off-by: Dedy Kurniawan Santoso <dedy@xendit.co>
2025-10-04 11:08:13 +08:00
Yang ChenandTomsun28 a3def497b4 [fix] remove v174 and add v180 flway script (#3787)
Co-authored-by: Tomsun28 <tomsun28@outlook.com>
2025-10-01 00:20:55 +08:00
381db85149 [OSPP] Modify Dockerfile to support RISC-V. (#3713)
Co-authored-by: Calvin <zhengqiwei@apache.org>
Co-authored-by: Tom <tomsun28@outlook.com>
2025-09-30 23:22:31 +08:00
会功夫的李白andCalvin d0daa2eec5 [improve] Optimize Gretimedb time-series statistics. (#3776)
Co-authored-by: Calvin <zhengqiwei@apache.org>
2025-09-25 22:56:13 +08:00
9b5f0f7fce [OSPP] Apache HertzBeat Log Monitoring Capability (#3673)
Signed-off-by: Yang Chen <1597081640@qq.com>
Co-authored-by: Calvin <zhengqiwei@apache.org>
Co-authored-by: tomsun28 <tomsun28@outlook.com>
Co-authored-by: Jast <shenghang@apache.org>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-09-25 00:29:00 +08:00
Tom b3ef3d8a6f [docs] update doc and add new contributors (#3783)
Signed-off-by: tomsun28 <tomsun28@outlook.com>
2025-09-24 14:15:49 +08:00
bd1924b016 [bugfix] fix service discovery host field NullPointerException (#3767)
Co-authored-by: kangli <1363539513@qq.com>
Co-authored-by: Calvin <zhengqiwei@apache.org>
Co-authored-by: Sherlock Yin <sherlock.yin1994@gmail.com>
Co-authored-by: aias00 <liuhongyu@apache.org>
2025-09-23 21:23:40 +08:00
1c781d5bc5 [bugfix] webhook url query parameters missing (#3779)
Co-authored-by: Calvin <zhengqiwei@apache.org>
Co-authored-by: aias00 <liuhongyu@apache.org>
2025-09-23 09:31:47 +08:00
586aa53e84 [OSPP] Implement a mcp server to run any scripts or commands securely (#3547)
Signed-off-by: aias00 <liuhongyu@apache.org>
Co-authored-by: Calvin <zhengqiwei@apache.org>
Co-authored-by: aias00 <liuhongyu@apache.org>
Co-authored-by: shown <yuluo08290126@gmail.com>
2025-09-22 19:54:59 +08:00
c5f0389138 [improve] Prometheus streaming parsing optimization enhancements (#3761)
Signed-off-by: Duansg <siguoduan@gmail.com>
Co-authored-by: Sherlock Yin <sherlock.yin1994@gmail.com>
Co-authored-by: Calvin <zhengqiwei@apache.org>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Tom <tomsun28@outlook.com>
2025-09-21 23:34:06 +08:00
b93613c25e [feat] Support jenkins monitoring (#3774)
Co-authored-by: Sherlock Yin <sherlock.yin1994@gmail.com>
Co-authored-by: Calvin <zhengqiwei@apache.org>
2025-09-21 15:38:14 +08:00
a8b0c1024d [Improve] Optimise and use the label-selector component for label selection within pages (#3762)
Co-authored-by: Calvin <zhengqiwei@apache.org>
Co-authored-by: Tom <tomsun28@outlook.com>
2025-09-20 19:16:32 +08:00
Duansg 25a63ccb25 [improve] Improving the operation of threshold rules and the output of expression logs (#3780) 2025-09-20 17:11:19 +08:00
5cdfe545b5 [doc] add japanese i18n in app-idrac.yml (#3766)
Co-authored-by: shown <yuluo08290126@gmail.com>
Co-authored-by: Tom <tomsun28@outlook.com>
2025-09-20 00:48:03 +08:00
+16 9be7295084 [fix]bugfix:Prevent Long.parseLong() error when search param is a float (#3483)
Signed-off-by: Sarthak Arora <f20200060@pilani.bits-pilani.ac.in>
Signed-off-by: Cyanty <153884653+Cyanty@users.noreply.github.com>
Signed-off-by: tomsun28 <tomsun28@outlook.com>
Signed-off-by: Wenqi Luo <495872803@qq.com>
Signed-off-by: yuluo-yx <yuluo08290126@gmail.com>
Signed-off-by: lynx009 <2030509072@qq.com>
Signed-off-by: Tom <tomsun28@outlook.com>
Co-authored-by: aias00 <liuhongyu@apache.org>
Co-authored-by: tomsun28 <tomsun28@outlook.com>
Co-authored-by: Calvin <zhengqiwei@apache.org>
Co-authored-by: 淞筱 <2030509072@qq.com>
Co-authored-by: shown <yuluo08290126@gmail.com>
Co-authored-by: kangli <likang@apache.org>
Co-authored-by: Logic <zqr10159@dromara.org>
Co-authored-by: Sarthak Arora <f20200060@pilani.bits-pilani.ac.in>
Co-authored-by: Jast <shenghang@apache.org>
Co-authored-by: DeleiGuo <deleiguo@163.com>
Co-authored-by: Cyanty <153884653+Cyanty@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Sherlock Yin <sherlock.yin1994@gmail.com>
Co-authored-by: Duansg <siguoduan@gmail.com>
Co-authored-by: liutianyou <tianyou.liu@qq.com>
Co-authored-by: VampireAchao <achao@apache.org>
Co-authored-by: Wenqi Luo <495872803@qq.com>
Co-authored-by: Yang Chen <1597081640@qq.com>
Co-authored-by: tuzuy <95274591+tuzuy@users.noreply.github.com>
Co-authored-by: tuzy <tuzy.cq@chinaccs.cn>
Co-authored-by: Kerwin Bryant <kerwin612@qq.com>
Co-authored-by: liutianyou <liutianyou@apache.org>
Co-authored-by: carl pinto <carlpinto25@gmail.com>
Co-authored-by: TJxiaobao <2922035952@qq.com>
Co-authored-by: cxhello <49056040+cxhello@users.noreply.github.com>
2025-09-20 00:24:51 +08:00
6905bcc986 [feat] Support monitoring center indicator favorites feature (#3735)
Co-authored-by: Calvin <zhengqiwei@apache.org>
Co-authored-by: Tom <tomsun28@outlook.com>
2025-09-19 23:53:26 +08:00
Duansg 1050032a13 [improve] SSE exception handling improvements (#3775) 2025-09-19 00:24:49 +08:00
DeleiGuo 9b223dd217 [doc] replace with the new ASF logo (#3770) 2025-09-17 01:16:25 +08:00
Duansg 0a1b5961e9 [feat] Support apollo configuration center monitoring (#3768) 2025-09-15 08:48:52 +08:00
tuzuyandtuzy a8a70b76d7 [feat] Add configuration file for Dell iDRAC monitoring type (#3763)
Co-authored-by: tuzy <tuzy.cq@chinaccs.cn>
2025-09-13 00:08:46 +08:00
+1 05b63903b5 [GSOC] Added all the necessary tools across services (#3722)
Signed-off-by: Sarthak Arora <f20200060@pilani.bits-pilani.ac.in>
Co-authored-by: Calvin <zhengqiwei@apache.org>
Co-authored-by: Jast <shenghang@apache.org>
Co-authored-by: Duansg <siguoduan@gmail.com>
Co-authored-by: DeleiGuo <deleiguo@163.com>
Co-authored-by: shown <yuluo08290126@gmail.com>
Co-authored-by: tomsun28 <tomsun28@outlook.com>
Co-authored-by: Logic <zqr10159@dromara.org>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Sherlock Yin <sherlock.yin1994@gmail.com>
Co-authored-by: lynx009 <2030509072@qq.com>
2025-09-10 08:31:05 +08:00
Calvin 7d8b55dfb8 [docs] Update contributors (#3759) 2025-09-09 08:10:40 +08:00
DuansgandTom 72a3e59ca6 [improve] Prometheus streaming parsing optimization (#3752)
Co-authored-by: Tom <tomsun28@outlook.com>
2025-09-07 23:20:23 +08:00
3ab94a751b [Improve] optimize the dashboard page and adapt to the new theme (#3730)
Co-authored-by: Calvin <zhengqiwei@apache.org>
Co-authored-by: Tom <tomsun28@outlook.com>
2025-09-07 23:00:12 +08:00
66049f189b [OSPP] Add RISC-V related help document. (#3712)
Signed-off-by: lynx009 <2030509072@qq.com>
Co-authored-by: Calvin <zhengqiwei@apache.org>
Co-authored-by: Tom <tomsun28@outlook.com>
2025-09-07 22:45:21 +08:00
DeleiGuoandTom 69ec3f8751 [bugfix] synchronise AI-related configuration for Docker Compose (#3751)
Co-authored-by: Tom <tomsun28@outlook.com>
2025-09-07 22:42:43 +08:00
feb43c5678 [GSOC] Chat UI, Conversation Management, OpenAI Chat Client Support, More monitoring tools. (#3679)
Signed-off-by: Sarthak Arora <f20200060@pilani.bits-pilani.ac.in>
Co-authored-by: Calvin <zhengqiwei@apache.org>
Co-authored-by: Jast <shenghang@apache.org>
Co-authored-by: Duansg <siguoduan@gmail.com>
Co-authored-by: DeleiGuo <deleiguo@163.com>
Co-authored-by: shown <yuluo08290126@gmail.com>
Co-authored-by: tomsun28 <tomsun28@outlook.com>
Co-authored-by: Logic <zqr10159@dromara.org>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-09-07 22:36:04 +08:00
liutianyou 1fae67282d [doc] update doc for how to release and add release note for 1.7.3 (#3749) 2025-09-06 21:00:04 +08:00
886f0b74f6 chore: optimize pom content (#3732)
Signed-off-by: yuluo-yx <yuluo08290126@gmail.com>
Co-authored-by: Calvin <zhengqiwei@apache.org>
Co-authored-by: Tom <tomsun28@outlook.com>
2025-09-06 09:02:01 +08:00
cxhelloandTom 32e1a43aa5 fix: update CNCF link (#3746)
Co-authored-by: Tom <tomsun28@outlook.com>
2025-09-05 22:28:05 +08:00
liutianyou dcd806802e [doc] update new version download link (#3747) 2025-09-05 21:29:40 +08:00
Duansg 5746cbbbd7 [improve] Prometheus streaming parsing supports CRLF (#3745) 2025-09-05 00:52:33 +08:00
Duansg e23903fd0c [fix] Fixed issue where default path did not match whitelist (#3740) 2025-09-03 21:52:44 +08:00
铁甲小宝andCalvin 780710f226 Integration QuestDB as Time Series Database Storage (#3731)
Co-authored-by: Calvin <zhengqiwei@apache.org>
2025-09-02 14:42:51 +08:00
Duansg 4607ede541 [improve] Improve styling issues (#3734) 2025-09-02 01:25:58 +08:00
tomsun28andTJxiaobao 67ad4b04ef docs: update doc and add graduation blog (#3729)
Signed-off-by: tomsun28 <tomsun28@outlook.com>
Co-authored-by: TJxiaobao <2922035952@qq.com>
2025-08-30 17:34:50 +08:00
DeleiGuoandCalvin 6432d689dd [improve] optimize the incident list on the status page to support paginated queries (#3727)
Co-authored-by: Calvin <zhengqiwei@apache.org>
2025-08-30 11:23:10 +08:00
carl pinto 2eb856fffb [Improve] changed scroll of intervals in New Monitor page (#3726) 2025-08-30 00:02:29 +08:00
liutianyouandtomsun28 56312831ca [release] release new version 1.7.3 (#3724)
Co-authored-by: tomsun28 <tomsun28@outlook.com>
2025-08-29 00:07:49 +08:00
Duansg fe54d42bc0 [improve] Improve Prometheus label PromQL parsing logic (#3725) 2025-08-28 23:56:22 +08:00
DeleiGuoandtomsun28 2ea24c1b3a [feature] add Synology NAS monitoring support (#3721)
Co-authored-by: tomsun28 <tomsun28@outlook.com>
2025-08-28 23:41:47 +08:00
DeleiGuoandCalvin e0040e2ede [feature] add macOS monitoring support (#3715)
Co-authored-by: Calvin <zhengqiwei@apache.org>
2025-08-28 23:26:57 +08:00
Calvinandliutianyou 0ac0fd4a8d [doc] add japanese i18n in app-tdengine.yml (#3717)
Co-authored-by: liutianyou <tianyou.liu@qq.com>
2025-08-27 22:11:51 +08:00
DuansgandCalvin 0ef87bcc08 [improve] Improve performance issues when loading large numbers of metric cards in Monitors (#3719)
Co-authored-by: Calvin <zhengqiwei@apache.org>
2025-08-27 12:41:41 +08:00
Calvinandlynx009 660bda6e14 [doc] add japanese i18n in app-valkey.yml (#3706)
Co-authored-by: lynx009 <2030509072@qq.com>
2025-08-27 11:41:22 +08:00
Calvinandtomsun28 242cf40135 [doc] add japanese i18n in app-ubuntu.yml, app-windows.yml and app-yarn.yml (#3703)
Co-authored-by: tomsun28 <tomsun28@outlook.com>
2025-08-25 23:20:17 +08:00
lynx009 7319c55430 [doc] modify github link. (#3714) 2025-08-25 21:44:56 +08:00
5ea29f610b [improve] Improve the parsing logic of prometheus label (#3662)
Co-authored-by: Calvin <zhengqiwei@apache.org>
Co-authored-by: tomsun28 <tomsun28@outlook.com>
Co-authored-by: Sherlock Yin <sherlock.yin1994@gmail.com>
2025-08-25 19:26:31 +08:00
b74aff0500 refactor: Optimize the monitoring data chart component (#3668)
Co-authored-by: tuzy <tuzy.cq@chinaccs.cn>
Co-authored-by: Calvin <zhengqiwei@apache.org>
Co-authored-by: tomsun28 <tomsun28@outlook.com>
Co-authored-by: Kerwin Bryant <kerwin612@qq.com>
2025-08-24 22:10:27 +08:00
d2e8f2f4aa [bugfix] fixed jexl keyword issue in vastbase monitoring template (#3708)
Co-authored-by: kangli <likang@apache.org>
Co-authored-by: Calvin <zhengqiwei@apache.org>
2025-08-24 20:51:41 +08:00
DeleiGuoandkangli 28681a1f9e [bugfix] fixed jexl keyword issue in greenplum monitoring template (#3707)
Co-authored-by: kangli <likang@apache.org>
2025-08-24 20:49:25 +08:00
DuansgandCalvin 6814c7c357 [feat] Support TDengine monitoring (#3678)
Co-authored-by: Calvin <zhengqiwei@apache.org>
2025-08-24 14:23:23 +08:00
DeleiGuoandCalvin f475540508 [bugfix] fixed jexl keyword issue in kingbase monitoring template (#3705)
Co-authored-by: Calvin <zhengqiwei@apache.org>
2025-08-24 13:04:09 +08:00
Calvin 44660a5042 [doc] add japanese i18n in app-vastbase.yml (#3704) 2025-08-24 12:02:44 +08:00
339386fd2b [bugfix] resolve translation value fetching for uppercase app names (#3690)
Signed-off-by: Wenqi Luo <495872803@qq.com>
Co-authored-by: Calvin <zhengqiwei@apache.org>
Co-authored-by: Yang Chen <1597081640@qq.com>
2025-08-24 00:07:55 +08:00
tomsun28andCalvin faa7cb71db [doc] update website, doc while graduate (#3701)
Signed-off-by: tomsun28 <tomsun28@outlook.com>
Co-authored-by: Calvin <zhengqiwei@apache.org>
2025-08-23 22:11:37 +08:00
014a376c30 [refactor] modify message column to TEXT type (#3698)
Co-authored-by: Calvin <zhengqiwei@apache.org>
Co-authored-by: tomsun28 <tomsun28@outlook.com>
2025-08-23 16:57:04 +08:00
Calvinandtomsun28 377172e44a [doc] add japanese i18n in app-tomcat.yml (#3700)
Co-authored-by: tomsun28 <tomsun28@outlook.com>
2025-08-23 16:52:36 +08:00
Calvinandtomsun28 5b9e19cc30 [doc] add japanese i18n in app-seatunnel.yml (#3691)
Co-authored-by: tomsun28 <tomsun28@outlook.com>
2025-08-23 16:50:24 +08:00
Calvinandtomsun28 0457ec7d16 [doc] add japanese i18n in app-rockylinux.yml (#3688)
Co-authored-by: tomsun28 <tomsun28@outlook.com>
2025-08-23 16:48:08 +08:00
tomsun28andCalvin 2947ee218e chore: update ui theme (#3682)
Signed-off-by: tomsun28 <tomsun28@outlook.com>
Co-authored-by: Calvin <zhengqiwei@apache.org>
2025-08-22 22:37:51 +08:00
DuansgandCalvin 4e841a9fb1 [doc] Fixed menu path errors and MD document format anomalies. (#3695)
Co-authored-by: Calvin <zhengqiwei@apache.org>
2025-08-22 10:08:35 +08:00
tomsun28andCalvin b7ecb9b2ec [doc] update doc while graduate (#3692)
Signed-off-by: tomsun28 <tomsun28@outlook.com>
Co-authored-by: Calvin <zhengqiwei@apache.org>
2025-08-22 01:48:48 +08:00
DeleiGuo 7e1873bc10 [bugfix] fixed jexl keyword issue in spring_gateway monitoring template (#3693) 2025-08-22 01:12:04 +08:00
DeleiGuoandCalvin 8eb60210a3 [bugfix] fixed jexl keyword issue in windows monitoring template (#3687)
Co-authored-by: Calvin <zhengqiwei@apache.org>
2025-08-21 22:38:49 +08:00
DeleiGuoandCalvin d608f732f7 [bugfix] fixed jexl keyword issue in hertzbeat monitoring template (#3686)
Co-authored-by: Calvin <zhengqiwei@apache.org>
2025-08-21 22:36:53 +08:00
DeleiGuoandCalvin 2d9a2955ef [bugfix] fixed jexl keyword issue in postgresql monitoring template (#3685)
Co-authored-by: Calvin <zhengqiwei@apache.org>
2025-08-21 22:19:28 +08:00
cae4423f30 [doc] graduate and remove incubating (#3584)
Co-authored-by: Calvin <zhengqiwei@apache.org>
Co-authored-by: 淞筱 <2030509072@qq.com>
Co-authored-by: aias00 <liuhongyu@apache.org>
Co-authored-by: shown <yuluo08290126@gmail.com>
2025-08-21 21:22:49 +08:00
f0e53a9fb3 [doc] add japanese i18n in app-redis_sentinel.yml (#3681)
Co-authored-by: liutianyou <tianyou.liu@qq.com>
Co-authored-by: tomsun28 <tomsun28@outlook.com>
2025-08-20 00:21:51 +08:00
79da1a198b [improve] optimize status page layout and UI (#3680)
Co-authored-by: Calvin <zhengqiwei@apache.org>
Co-authored-by: tomsun28 <tomsun28@outlook.com>
2025-08-20 00:17:03 +08:00
64cb804147 [doc] add japanese i18n in app-dolphinscheduler.yml (#3677)
Co-authored-by: liutianyou <tianyou.liu@qq.com>
Co-authored-by: tomsun28 <tomsun28@outlook.com>
2025-08-20 00:03:12 +08:00
Calvinandtomsun28 344cb25229 [doc] add japanese i18n in app-redis_cluster.yml (#3672)
Co-authored-by: tomsun28 <tomsun28@outlook.com>
2025-08-19 23:30:11 +08:00
DeleiGuo 74d21a7acd [feature] add user password monitoring metrics in oracle monitor (#3674) 2025-08-19 22:08:05 +08:00
f315bf9607 [fix] Fixed Grafana visualization integration display issue (#3666)
Co-authored-by: Calvin <zhengqiwei@apache.org>
Co-authored-by: tomsun28 <tomsun28@outlook.com>
2025-08-17 14:51:14 +08:00
810d54bef5 [improve] Optimize the scheduling logic for batch flush tasks (#3660)
Signed-off-by: Cyanty <153884653+Cyanty@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Sherlock Yin <sherlock.yin1994@gmail.com>
Co-authored-by: Calvin <zhengqiwei@apache.org>
2025-08-17 14:24:48 +08:00
DeleiGuoandCalvin 48eafa1382 [Feature] add Apache DolphinScheduler monitoring support (#3656)
Co-authored-by: Calvin <zhengqiwei@apache.org>
2025-08-17 10:58:46 +08:00
Calvinandtomsun28 4b6c1e0f08 [doc] add japanese i18n in app-redis.yml (#3669)
Co-authored-by: tomsun28 <tomsun28@outlook.com>
2025-08-17 09:59:11 +08:00
edfd857030 [GSOC] MCP server setup, authorization, and basic tool support (#3610)
Signed-off-by: Sarthak Arora <f20200060@pilani.bits-pilani.ac.in>
Co-authored-by: Calvin <zhengqiwei@apache.org>
Co-authored-by: Jast <shenghang@apache.org>
Co-authored-by: tomsun28 <tomsun28@outlook.com>
2025-08-16 19:08:13 +08:00
tomsun28andLogic 408a06d3eb [doc] update contribution doc (#3667)
Co-authored-by: Logic <zqr10159@dromara.org>
2025-08-16 16:07:41 +08:00
Calvinandtomsun28 fd3a2f0569 [doc] add japanese i18n and remove chinese in script folder (#3665)
Co-authored-by: tomsun28 <tomsun28@outlook.com>
2025-08-16 15:43:24 +08:00
7d8ba72717 [doc] add japanese i18n in app-redhat.yml (#3655)
Co-authored-by: shown <yuluo08290126@gmail.com>
Co-authored-by: tomsun28 <tomsun28@outlook.com>
2025-08-16 15:25:39 +08:00
Calvinandtomsun28 f936b50ce9 [doc] add japanese i18n in app-spring_gateway.yml, app-sqlserver.yml (#3661)
Co-authored-by: tomsun28 <tomsun28@outlook.com>
2025-08-15 20:25:01 +08:00
Calvinandtomsun28 93f5da2d02 [doc] add japanese i18n in app-process.yml (#3654)
Co-authored-by: tomsun28 <tomsun28@outlook.com>
2025-08-15 20:17:14 +08:00
Calvinandshown bc06c268ca [doc] add japanese i18n in app-prestodb.yml, app-spark.yml (#3651)
Co-authored-by: shown <yuluo08290126@gmail.com>
2025-08-15 20:12:07 +08:00
DeleiGuoandCalvin 9e6f2762c0 [doc] improve documentation formatting and readability (#3659)
Co-authored-by: Calvin <zhengqiwei@apache.org>
2025-08-13 00:40:37 +08:00
Duansg 6ac8a42bd3 [doc] add japanese i18n in app-springboot3.yml (#3658) 2025-08-13 00:37:49 +08:00
Calvinandtomsun28 89647d96c7 [doc] add japanese i18n in app-tidb.yml, app-windows_script.yml (#3650)
Co-authored-by: tomsun28 <tomsun28@outlook.com>
2025-08-11 00:57:21 +08:00
tomsun28 0b0fac4a41 [bugfix] fix the collector aes decode with secret error (#3652)
Signed-off-by: tomsun28 <tomsun28@outlook.com>
2025-08-10 22:34:10 +08:00
Duansg f59e15bbbe [fix] Fixed an issue where template configuration was overwritten (#3649) 2025-08-09 23:37:10 +08:00
b7398b1bf9 [feature] Support HertzBeat self monitor (#3641)
Co-authored-by: Calvin <zhengqiwei@apache.org>
Co-authored-by: tomsun28 <tomsun28@outlook.com>
2025-08-09 17:14:17 +08:00
Calvinandtomsun28 0082e724bc [doc] add japanese i18n in app-s7.yml, app-tplink_switch.yml, app-shenyu.yml (#3648)
Co-authored-by: tomsun28 <tomsun28@outlook.com>
2025-08-09 14:25:46 +08:00
57a2daf30d [doc] add japanese i18n in app-prometheus.yml, app-pulsar.yml and app-registry.yml (#3639)
Co-authored-by: aias00 <liuhongyu@apache.org>
Co-authored-by: tomsun28 <tomsun28@outlook.com>
2025-08-09 14:23:39 +08:00
Calvinandtomsun28 db90f29cd0 [doc] add japanese i18n in app-qq_mailbox.yml and app-redfish.yml (#3635)
Co-authored-by: tomsun28 <tomsun28@outlook.com>
2025-08-09 14:21:28 +08:00
DeleiGuoandtomsun28 00fd8fa1da [bugfix] fixed jexl keyword issue in springboot2 monitoring template (#3632)
Co-authored-by: tomsun28 <tomsun28@outlook.com>
2025-08-09 14:18:46 +08:00
60100eb980 [doc] add English version of linux operating system practice usecase (#3631)
Co-authored-by: tomsun28 <tomsun28@outlook.com>
Co-authored-by: aias00 <liuhongyu@apache.org>
2025-08-09 14:16:09 +08:00
DuansgandLogic a6eb6be1ab [feat] Monitoring templates support JSON nested parsing. (#3645)
Co-authored-by: Logic <zqr10159@dromara.org>
2025-08-08 21:54:38 +08:00
DeleiGuoandLogic 5eff094af6 [bugfix] fix potential StringIndexOutOfBoundsException (#3642)
Co-authored-by: Logic <zqr10159@dromara.org>
2025-08-08 21:35:25 +08:00
CalvinandLogic 3b126f53d2 [doc] add japanese i18n in app-smtp.yml, app-ssl_cert.yml, app-storm.yml, app-udp_port.yml, app-uniview.yml, app-website.yml, app-websocket.yml (#3643)
Co-authored-by: Logic <zqr10159@dromara.org>
2025-08-08 21:15:37 +08:00
Calvinandaias00 1a5b722994 [doc] add japanese i18n in app-openai.yml and app-opengauss.yml (#3617)
Co-authored-by: aias00 <liuhongyu@apache.org>
2025-08-08 20:56:45 +08:00
Duansg 5fe20dff05 [fix] remove optional metrics (#3636) 2025-08-07 00:44:35 +08:00
04cfdae1e5 [fix] Fixed issue where jdbc url was replaced (#3625)
Co-authored-by: tomsun28 <tomsun28@outlook.com>
Co-authored-by: 铁甲小宝 <2922035952@qq.com>
2025-08-05 09:57:04 +08:00
8776f98cf5 [Feature] add customized labels to VM metrics (#3622)
Co-authored-by: zhochi <zhochi@cisco.com>
Co-authored-by: Sherlock Yin <sherlock.yin1994@gmail.com>
Co-authored-by: tomsun28 <tomsun28@outlook.com>
Co-authored-by: Logic <zqr10159@dromara.org>
2025-08-05 09:37:12 +08:00
Duansgandtomsun28 da484aef26 [fix] Fixed springboot3 template yaml has the jexl inner conflict keyword(#3629)
Co-authored-by: tomsun28 <tomsun28@outlook.com>
2025-08-04 23:32:02 +08:00
DeleiGuoandtomsun28 e8ebc65053 [doc] add linux operating system practice usecase (#3628)
Co-authored-by: tomsun28 <tomsun28@outlook.com>
2025-08-04 23:12:12 +08:00
Calvinandtomsun28 bd08de41d5 [doc] add japanese i18n in app-postgresql.yml (#3624)
Co-authored-by: tomsun28 <tomsun28@outlook.com>
2025-08-04 23:09:05 +08:00
Calvinandtomsun28 18f8a541f0 [doc] add japanese i18n in app-oracle.yml (#3621)
Co-authored-by: tomsun28 <tomsun28@outlook.com>
2025-08-04 23:06:40 +08:00
Calvinandtomsun28 007ecd2db1 [doc] add japanese i18n in app-opensuse.yml (#3619)
Co-authored-by: tomsun28 <tomsun28@outlook.com>
2025-08-04 23:04:33 +08:00
VampireAchaoandCalvin 89aaad2401 [doc] Optimize the home website navbar layout UI for medium-sized screens (#3616)
Co-authored-by: Calvin <zhengqiwei@apache.org>
2025-08-04 22:47:13 +08:00
17d836752e [feat] Http collect supports jsonpath parsing of numeric type (#3612)
Co-authored-by: tomsun28 <tomsun28@outlook.com>
Co-authored-by: Sherlock Yin <sherlock.yin1994@gmail.com>
2025-08-01 19:05:08 +08:00
VampireAchaoandCalvin 3949b73751 [doc] add japanese i18n in app-oceanbase.yml (#3614)
Signed-off-by: VampireAchao <achao@apache.org>
Co-authored-by: Calvin <zhengqiwei@apache.org>
2025-08-01 00:05:48 +08:00
Calvinandtomsun28 2731504278 [doc] add japanese i18n in app-netease_mailbox.yml and app-ntp.yml (#3607)
Co-authored-by: tomsun28 <tomsun28@outlook.com>
2025-07-30 22:02:09 +08:00
babbfaea68 [bugfix] the tagValue may be null in the determineNewLabels method (#3606)
Co-authored-by: Calvin <zhengqiwei@apache.org>
Co-authored-by: Yang Chen <1597081640@qq.com>
2025-07-30 22:00:19 +08:00
9f7b9994b8 [doc] add japanese i18n in app-nebula_graph_cluster.yml and update japanese of client (#3603)
Co-authored-by: shown <yuluo08290126@gmail.com>
Co-authored-by: tomsun28 <tomsun28@outlook.com>
2025-07-29 09:26:51 +08:00
d156c10aed [doc] update japanese i18n in app-nacos_sd.yml, app-nebula_graph.yml, app-zookeeper.yml (#3602)
Co-authored-by: shown <yuluo08290126@gmail.com>
Co-authored-by: tomsun28 <tomsun28@outlook.com>
2025-07-29 09:22:32 +08:00
Calvinandtomsun28 9f3329c85f [doc] add japanese i18n in app-nvidia.yml, app-ping.yml, app-pop3.yml, app-port.yml and app-push.yml (#3611)
Co-authored-by: tomsun28 <tomsun28@outlook.com>
2025-07-29 09:20:14 +08:00
cto-huhangandCalvin fd1c58f68d [doc] add japanese i18n in app-nacos.yml (#3599)
Co-authored-by: Calvin <zhengqiwei@apache.org>
2025-07-28 12:04:27 +08:00
DeleiGuo 6d1aa503df [doc] fix image reference issues in documents (#3608) 2025-07-28 01:54:05 +08:00
a58ad35c8b [fix] Fix collector offline without sending offline notification (#3601)
Co-authored-by: Calvin <zhengqiwei@apache.org>
Co-authored-by: shown <yuluo08290126@gmail.com>
Co-authored-by: tomsun28 <tomsun28@outlook.com>
2025-07-25 21:53:15 +08:00
Calvinandshown 64cd5f9658 [doc] update japanese i18n in app-mqtt.yml and app-mysql.yml (#3597)
Co-authored-by: shown <yuluo08290126@gmail.com>
2025-07-25 08:19:08 +08:00
Yang Chenandshown a13dd89fd2 [feat] Auto-generate AES key if not configured (#3604)
Co-authored-by: shown <yuluo08290126@gmail.com>
2025-07-24 21:06:45 +08:00
2f5cfa9d5d [improve] VM write request sets up gzip compression and adds saveData unit tests (#3595)
Co-authored-by: Calvin <zhengqiwei@apache.org>
Co-authored-by: Sherlock Yin <sherlock.yin1994@gmail.com>
2025-07-24 19:18:17 +08:00
LunaRain_079andCalvin a9dc7bf7f3 [doc] add japanese i18n in app-rocketmq.yml and app-rabbitmq.yml (#3598)
Co-authored-by: Calvin <zhengqiwei@apache.org>
2025-07-23 10:59:41 +08:00
DuansgandCalvin c1492deaa0 [doc] add japanese i18n in app-nginx.yml (#3600)
Co-authored-by: Calvin <zhengqiwei@apache.org>
2025-07-23 00:18:28 +08:00
CyantyandCalvin 2252b2a769 [doc] add japanese i18n in app-zookeeper.yml and app-zookeeper_sd.yml (#3596)
Co-authored-by: Calvin <zhengqiwei@apache.org>
2025-07-22 00:32:41 +08:00
cto-huhang 73f71503f5 [doc] add japanese i18n in app-mysql.yml (#3594) 2025-07-20 21:17:21 +08:00
Calvinandtomsun28 2e224ce626 [doc] add japanese i18n in app-mongodb_atlas.yml (#3593)
Co-authored-by: tomsun28 <tomsun28@outlook.com>
2025-07-20 09:38:27 +08:00
e5406d57c6 [fix] Fix collector online metadata filling (#3579)
Co-authored-by: Calvin <zhengqiwei@apache.org>
Co-authored-by: tomsun28 <tomsun28@outlook.com>
2025-07-20 09:35:14 +08:00
433a83303f [refactor] Refactor the comparison logic (#3574)
Co-authored-by: Calvin <zhengqiwei@apache.org>
Co-authored-by: aias00 <liuhongyu@apache.org>
Co-authored-by: tomsun28 <tomsun28@outlook.com>
2025-07-20 01:34:03 +08:00
Calvinandtomsun28 f309d5eafd [doc] add japanese i18n in app-mongodb.yml (#3590)
Co-authored-by: tomsun28 <tomsun28@outlook.com>
2025-07-19 18:20:36 +08:00
986103395b [feature] System time zone optimization. (#3588)
Co-authored-by: Sherlock Yin <sherlock.yin1994@gmail.com>
Co-authored-by: tomsun28 <tomsun28@outlook.com>
2025-07-19 18:18:25 +08:00
Calvinandtomsun28 d569721e01 [doc] add japanese i18n in app-modbus.yml (#3580)
Co-authored-by: tomsun28 <tomsun28@outlook.com>
2025-07-19 00:44:03 +08:00
Calvinandtomsun28 08cac3c6cc [doc] add japanese i18n in app-memcached.yml (#3578)
Co-authored-by: tomsun28 <tomsun28@outlook.com>
2025-07-19 00:42:16 +08:00
Calvinandtomsun28 f80d066851 [doc] add japanese i18n in app-mariadb.yml (#3577)
Co-authored-by: tomsun28 <tomsun28@outlook.com>
2025-07-19 00:39:02 +08:00
d6584093f5 [doc] add japanese i18n in app-linux_script.yml (#3575)
Co-authored-by: aias00 <liuhongyu@apache.org>
Co-authored-by: tomsun28 <tomsun28@outlook.com>
2025-07-19 00:37:03 +08:00
DuansgandCalvin fb03a57725 [feature] Support i18n of collector online notification (#3585)
Co-authored-by: Calvin <zhengqiwei@apache.org>
2025-07-18 19:51:08 +08:00
tomsun28 779272d65f [infra] upgrade openjdk image to fix Debian source failed (#3587)
Signed-off-by: tomsun28 <tomsun28@outlook.com>
2025-07-18 15:32:34 +08:00
Logic c21a2952a5 [doc]: add FAQs about task limits (#3581) 2025-07-17 21:52:18 +08:00
Logic b46d049158 [fix]: Fix a problem where the inputstream was closed prematurely when parsing Prometheus (#3567) 2025-07-14 21:21:01 +08:00
Calvin dc52c88d88 [doc] japanese linux (#3571) 2025-07-13 23:45:46 +08:00
Calvin df4e947c8a [doc] japanese kvrocks (#3570) 2025-07-12 14:24:47 +08:00
a4ec6c1f66 [bugfix] Fix MySQL WrongArgumentException (#3564)
Co-authored-by: kangli <1363539513@qq.com>
Co-authored-by: tomsun28 <tomsun28@outlook.com>
Co-authored-by: aias00 <liuhongyu@apache.org>
Co-authored-by: Calvin <zhengqiwei@apache.org>
2025-07-12 00:26:14 +08:00
Yang Chen a8dd57d009 [docs] Add new committer blog (#3569) 2025-07-11 19:33:33 +08:00
af3eabdd1c [mqtt] refact the MQTT based on the Paho SDK and support both unidirectional and bidirectional MQTT over TLS connections. (#3474)
Signed-off-by: yy549159265 <40821310+yy549159265@users.noreply.github.com>
Co-authored-by: aias00 <liuhongyu@apache.org>
Co-authored-by: Logic <zqr10159@dromara.org>
Co-authored-by: Calvin <zhengqiwei@apache.org>
Co-authored-by: tomsun28 <tomsun28@outlook.com>
2025-07-11 13:36:10 +08:00
Calvin d6b300d3df [doc] japanese kubernetes (#3568) 2025-07-11 06:18:35 +08:00
Duansg b5789538e6 [feat] Add QueryExecutor does not support internationalization. (#3565) 2025-07-10 20:04:15 +08:00
Sherlock Yin d6c5b2b8a2 [doc] add new committer (#3563) 2025-07-10 09:23:03 +08:00
Calvin 3a04647c3c [doc] japanese kingbase (#3562) 2025-07-09 00:37:04 +08:00
tomsun28 d2999c1aa6 [doc] add new pmc and committer (#3561) 2025-07-09 00:30:43 +08:00
Duansg b3dbc7092a [doc] Fix documentation error and adjust Chinese semantics (#3559) 2025-07-08 08:17:40 +08:00
Calvinandtomsun28 edb3cb6b6a [doc] japanese kafka promql (#3553)
Co-authored-by: tomsun28 <tomsun28@outlook.com>
2025-07-07 23:25:25 +08:00
淞筱 4dd78b2e98 [doc] V1.7.2 version blog (#3558) 2025-07-07 23:21:43 +08:00
2f91f56b7b [bugfix] fix npe due the victoria insert not config when startup (#3552)
Signed-off-by: tomsun28 <tomsun28@outlook.com>
Co-authored-by: kangli <likang@apache.org>
Co-authored-by: Calvin <zhengqiwei@apache.org>
2025-07-07 09:18:33 +08:00
tomsun28andkangli be3dac488b [improve] make jackson serialize all field visibility (#3551)
Signed-off-by: tomsun28 <tomsun28@outlook.com>
Co-authored-by: kangli <likang@apache.org>
2025-07-07 00:17:39 +08:00
553bdbaf9f [refactor] AlarmCacheManager refactoring processing logic (#3525)
Co-authored-by: Calvin <zhengqiwei@apache.org>
Co-authored-by: 淞筱 <2030509072@qq.com>
Co-authored-by: aias00 <liuhongyu@apache.org>
Co-authored-by: shown <yuluo08290126@gmail.com>
Co-authored-by: Sherlock Yin <sherlock.yin1994@gmail.com>
Co-authored-by: kangli <likang@apache.org>
2025-07-06 22:06:30 +08:00
40d3f1243b feat: Add LogUtil wrapper and optimize logging comments (#3489)
Co-authored-by: aias00 <liuhongyu@apache.org>
Co-authored-by: Calvin <zhengqiwei@apache.org>
Co-authored-by: shown <yuluo08290126@gmail.com>
Co-authored-by: kangli <likang@apache.org>
Co-authored-by: tomsun28 <tomsun28@outlook.com>
2025-07-06 20:57:39 +08:00
740e3f8385 [feature] Support export all allmonitors (#3509)
Co-authored-by: Calvin <zhengqiwei@apache.org>
Co-authored-by: aias00 <liuhongyu@apache.org>
Co-authored-by: Logic <zqr10159@dromara.org>
Co-authored-by: shown <yuluo08290126@gmail.com>
Co-authored-by: kangli <likang@apache.org>
2025-07-06 19:06:19 +08:00
Calvin 47d089dff7 [doc] japanese kafka client (#3550) 2025-07-06 06:51:49 +08:00
Calvin c6f1f07155 [doc] japanese jvm (#3545) 2025-07-05 12:35:45 +08:00
Calvinandtomsun28 0ebd3499b7 [doc] japanese kafka (#3548)
Co-authored-by: tomsun28 <tomsun28@outlook.com>
2025-07-05 12:04:24 +08:00
淞筱 c88d4a7b0e [doc] update download page (#3549) 2025-07-05 11:56:39 +08:00
tomsun28 8bebae9db6 [doc] add hertzbeat maturity and fix doc (#3544) 2025-07-04 19:55:27 +08:00
b6b1a48a5c [doc] recommend newer mysql connector jar (#3541)
Signed-off-by: PJ Fanning <pjfanning@users.noreply.github.com>
Co-authored-by: 淞筱 <2030509072@qq.com>
Co-authored-by: aias00 <liuhongyu@apache.org>
Co-authored-by: tomsun28 <tomsun28@outlook.com>
2025-07-03 23:35:53 +08:00
63ed50ef45 [doc] Fix some issues in the documentation (#3526)
Co-authored-by: Calvin <zhengqiwei@apache.org>
Co-authored-by: 淞筱 <2030509072@qq.com>
Co-authored-by: aias00 <liuhongyu@apache.org>
Co-authored-by: shown <yuluo08290126@gmail.com>
2025-07-03 23:04:31 +08:00
PJ Fanning e63715d1b0 enable GitHub Dependabot to create PRs for security alerts but not for every dependency update (#3543) 2025-07-03 21:27:48 +08:00
Calvin edf3eac6d6 [doc] japanese jetty (#3539) 2025-07-03 11:03:54 +08:00
Calvin 743f285c8d [doc] japanese ipmi (#3537) 2025-07-02 22:55:09 +08:00
Logicandaias00 458433464c [doc]update download page text (#3532)
Co-authored-by: aias00 <liuhongyu@apache.org>
2025-07-02 17:45:28 +08:00
淞筱 64740a4f85 [doc] update outdated links (#3535) 2025-07-02 17:15:19 +08:00
淞筱andaias00 b5a2bce261 download version deal (#3531)
Co-authored-by: aias00 <liuhongyu@apache.org>
2025-07-01 13:11:31 +08:00
Calvin 5e351c854b [doc] japanese iotdb (#3530) 2025-07-01 12:29:54 +08:00
0875bea046 fix: fix something (#3524)
Co-authored-by: Calvin <zhengqiwei@apache.org>
Co-authored-by: 淞筱 <2030509072@qq.com>
2025-06-30 10:56:55 +08:00
Calvin 9ad5f77816 [doc] japanese influxdb promql (#3527) 2025-06-30 09:46:56 +08:00
aias00andCalvin 998f9059bc [feat]parallel ci (#3523)
Co-authored-by: Calvin <zhengqiwei@apache.org>
2025-06-30 00:04:10 +08:00
a1439c3ec2 [fix] fix i18n error and append two metrics about disk infos (#3514)
Signed-off-by: aias00 <liuhongyu@apache.org>
Co-authored-by: aias00 <liuhongyu@apache.org>
Co-authored-by: Calvin <zhengqiwei@apache.org>
2025-06-29 20:20:05 +08:00
742b6f6755 [doc] Add new commiter blog (#3522)
Co-authored-by: yinyijun <yingey2011>
Co-authored-by: 淞筱 <2030509072@qq.com>
2025-06-29 15:15:50 +08:00
5fdb34598c [doc] japanese hikvision (#3499)
Co-authored-by: aias00 <liuhongyu@apache.org>
Co-authored-by: 淞筱 <2030509072@qq.com>
2025-06-29 12:16:17 +08:00
Calvin 4f982d1ab0 [doc] japanese influxdb (#3521) 2025-06-29 11:50:42 +08:00
4a28056d9f [fix] Update the correct replacement of outdated functions and placeholders (#3516)
Co-authored-by: Calvin <zhengqiwei@apache.org>
Co-authored-by: aias00 <liuhongyu@apache.org>
2025-06-28 22:31:18 +08:00
Calvinandaias00 3f2fa71e22 [doc] japanese iceberg (#3519)
Co-authored-by: aias00 <liuhongyu@apache.org>
2025-06-28 22:25:22 +08:00
Jastandaias00 08c81bf62f [Improve] Improve kafka e2e (#3520)
Co-authored-by: aias00 <liuhongyu@apache.org>
2025-06-28 22:23:07 +08:00
e16d6cb4ba [feature] Support for Periodic Threshold preview (#3505)
Co-authored-by: Sherlock Yin <sherlock.yin1994@gmail.com>
Co-authored-by: Calvin <zhengqiwei@apache.org>
2025-06-28 20:38:38 +08:00
Calvin a54d14e803 [doc] japanese hugeGraph (#3518) 2025-06-28 07:24:44 +08:00
Calvinandaias00 01ae281769 [doc] japanese hive (#3506)
Co-authored-by: aias00 <liuhongyu@apache.org>
2025-06-28 00:10:22 +08:00
Calvin 9cb10ff14d [doc] japanese huawei switch (#3515) 2025-06-27 20:55:27 +08:00
Calvin 62f40d3ad1 [doc] japanese hpe switch (#3511) 2025-06-26 00:07:54 +08:00
tomsun28 57601ef989 [release] release new version 1.7.2 (#3510)
Signed-off-by: tomsun28 <tomsun28@outlook.com>
2025-06-25 22:01:18 +08:00
puruidong 0a05edbec5 [bugfix]Fixed an error in the format of the flying book notification (#3508)
Signed-off-by: puruidong <pruidong@gmail.com>
2025-06-25 19:18:21 +08:00
Yang Chenandtomsun28 fcef24fdbf [bugfix] Correctly parse binary comparison expressions (#3504)
Co-authored-by: tomsun28 <tomsun28@outlook.com>
2025-06-25 11:01:12 +08:00
e45c31abfb [bugfix] Fix incorrect expression parsing in alert setting component (#3497)
Co-authored-by: Calvin <zhengqiwei@apache.org>
Co-authored-by: tomsun28 <tomsun28@outlook.com>
2025-06-24 22:56:16 +08:00
198c190ca7 fixed:a minor issue change (#3428)
Signed-off-by: 淞筱 <2030509072@qq.com>
Co-authored-by: kangli <likang@apache.org>
Co-authored-by: Calvin <zhengqiwei@apache.org>
Co-authored-by: aias00 <liuhongyu@apache.org>
Co-authored-by: shown <yuluo08290126@gmail.com>
Co-authored-by: liutianyou <tianyou.liu@qq.com>
Co-authored-by: 淞筱 <2030509072@qq.com>
2025-06-24 22:50:22 +08:00
铁甲小宝anda-little-fool 392a59f9a9 add:a small jdbc modified. (#3500)
Co-authored-by: a-little-fool <2030509072@qq.com>
2025-06-24 22:07:18 +08:00
aias00 c01b7f7bce [feat] update_mvnd_version (#3498) 2025-06-23 21:18:04 +08:00
Calvin 0323b044b8 [doc] japanese hertzbeat token (#3493) 2025-06-23 08:54:47 +08:00
256302fdcf [fix] Fix antlr4 parsing of or and unless logical and set binary operators (#3488)
Co-authored-by: wordofwordof <black.jack.kaiqi@gmail.com>
Co-authored-by: aias00 <liuhongyu@apache.org>
2025-06-22 19:46:34 +08:00
Calvin 3f3330af41 [doc] japanese hertzbeat (#3492) 2025-06-22 19:13:18 +08:00
Calvin 33342baa3f [doc] japanese hdfs namenode (#3490) 2025-06-22 06:43:10 +08:00
Logic 563cbd7943 [ci]: add mvnd support and update backend build (#3491) 2025-06-21 20:07:10 +08:00
Duansgandaias00 ddb1601290 [fix] antlr4 vectors and parse semantic fixes and optimizations (#3482)
Co-authored-by: aias00 <liuhongyu@apache.org>
2025-06-21 07:55:54 +08:00
Calvin 8e9d3c09f3 [doc] japanese hdfs datanode (#3487) 2025-06-21 00:07:53 +08:00
Calvin ade04d2cf2 [doc] japanese hbase region server (#3479) 2025-06-20 09:03:09 +08:00
Calvinandaias00 53555c88c7 [doc] japanese hbase master (#3477)
Co-authored-by: aias00 <liuhongyu@apache.org>
2025-06-19 19:14:43 +08:00
Logic 03bf31269d [docs](webhook): update Chinese documentation for alert integration (#3478) 2025-06-19 19:05:21 +08:00
Calvin 5c329a8a66 [doc] japanese hadoop (#3476) 2025-06-18 23:34:44 +08:00
dda9250243 [feature] Add statusCode metrics data. (#3446)
Co-authored-by: tomsun28 <tomsun28@outlook.com>
Co-authored-by: Logic <zqr10159@dromara.org>
Co-authored-by: aias00 <liuhongyu@apache.org>
Co-authored-by: kangli <likang@apache.org>
Co-authored-by: liutianyou <tianyou.liu@qq.com>
2025-06-17 22:32:31 +08:00
Calvin 65a97aed8f [doc] japanese h3c switch (#3471) 2025-06-17 08:07:17 +08:00
Calvin 56528f4fc0 [doc] japanese greptime (#3469) 2025-06-15 22:12:43 +08:00
Duansgandliutianyou f218ba018a [fix] Fix Monitors paging display. (#3467)
Co-authored-by: liutianyou <tianyou.liu@qq.com>
2025-06-15 11:44:23 +08:00
d6ce0c153a [improvement] change column definitions for commonAnnotations and alertFingerprints to TEXT type (#3463)
Co-authored-by: Jast <shenghang@apache.org>
Co-authored-by: tomsun28 <tomsun28@outlook.com>
Co-authored-by: liutianyou <tianyou.liu@qq.com>
2025-06-14 21:52:27 +08:00
Calvin a1b23cacdc [doc] japanese greenplum (#3468) 2025-06-14 17:40:04 +08:00
ed6214d0c1 [doc] Alert notification template (#3466)
Co-authored-by: yinyijun <yingey2011>
Co-authored-by: tomsun28 <tomsun28@outlook.com>
2025-06-14 13:04:32 +08:00
Duansgandtomsun28 9a3fc5911d [fix] fix jacoco can not generate test reports. (#3455)
Co-authored-by: tomsun28 <tomsun28@outlook.com>
2025-06-14 00:21:07 +08:00
d5d01459e7 [Fix] fix custom monitoring bulletin NullPointerException (#3448)
Co-authored-by: Calvin <zhengqiwei@apache.org>
Co-authored-by: aias00 <liuhongyu@apache.org>
Co-authored-by: kangli <likang@apache.org>
Co-authored-by: liutianyou <tianyou.liu@qq.com>
2025-06-13 08:48:51 +08:00
liutianyouandtomsun28 d077c72211 [doc] add doc for integrate volcengine alerts (#3460)
Co-authored-by: tomsun28 <tomsun28@outlook.com>
2025-06-13 00:32:15 +08:00
Yang Chen 11e3e4cc22 [improvement] disable default OpenTelemetry exporters to prevent connection errors (#3461) 2025-06-12 23:40:28 +08:00
Calvin c24c6ab7aa [doc] japanese freebsd (#3456) 2025-06-12 08:50:13 +08:00
Calvinandaias00 a183176e83 [doc] japanese flink on yarn (#3452)
Co-authored-by: aias00 <liuhongyu@apache.org>
2025-06-11 08:56:10 +08:00
tomsun28 a2e8739fec [doc] add publish version 1.7.1 blog (#3449) 2025-06-11 06:57:02 +08:00
liutianyouandCalvin ebb6e3d4ff [feature] support volcengine alert source (#3451)
Co-authored-by: Calvin <zhengqiwei@apache.org>
2025-06-11 00:48:07 +08:00
tomsun28 fc3f26368d [security] update hertzbeat security model (#3450) 2025-06-11 00:22:26 +08:00
Calvin 7967cfabf0 [doc] japanese flink (#3447) 2025-06-10 07:31:31 +08:00
199466cd59 [feat] add support for OpenRouter AI provider (#3439)
Signed-off-by: Yang Chen <1597081640@qq.com>
Co-authored-by: tomsun28 <tomsun28@outlook.com>
Co-authored-by: aias00 <liuhongyu@apache.org>
Co-authored-by: Jast <shenghang@apache.org>
2025-06-09 23:35:08 +08:00
8065b63057 [docs] Add one-click installation for Rainbond Cloud (#3440)
Signed-off-by: songyg <songyg@goodrain.com>
Co-authored-by: songyg <songyg@goodrain.com>
Co-authored-by: Calvin <zhengqiwei@apache.org>
Co-authored-by: tomsun28 <tomsun28@outlook.com>
Co-authored-by: aias00 <liuhongyu@apache.org>
2025-06-09 23:32:14 +08:00
Calvinandaias00 88655fcf19 [doc] japanese euleros (#3442)
Co-authored-by: aias00 <liuhongyu@apache.org>
2025-06-09 12:03:31 +08:00
Duansgandtomsun28 99b5460dd1 [feature] Support Huawei Cloud Cloud Eye alert source (#3443)
Co-authored-by: tomsun28 <tomsun28@outlook.com>
2025-06-09 00:22:31 +08:00
d681420c11 [feature] add support for darwin (#3431)
Co-authored-by: kangli <likang@apache.org>
Co-authored-by: tomsun28 <tomsun28@outlook.com>
2025-06-09 00:04:02 +08:00
Yang Chen 8618145e44 [feat] add support for ollama and update docs (#3441) 2025-06-07 18:48:41 +08:00
Duansgandkangli dd0045c6a4 [bugfix] Fix the issue where Prometheus RealTime Threshold is not eff… (#3434)
Co-authored-by: kangli <likang@apache.org>
2025-06-06 13:00:55 +08:00
Yang Chen 84e0a604e7 [improvement] disable default OpenTelemetry exporters to prevent connection errors (#3437) 2025-06-06 11:29:51 +08:00
Calvinandtomsun28 ce253f7069 [doc] japanese emqx (#3433)
Co-authored-by: tomsun28 <tomsun28@outlook.com>
2025-06-06 00:52:26 +08:00
Jast 767b70f70b [Improve] add mvnw (#3430) 2025-06-06 00:49:50 +08:00
Duansgandtomsun28 4aad08ca17 [feature]Support Alibaba Cloud 'Simple Log Service(SLS)' alert source (#3422)
Co-authored-by: tomsun28 <tomsun28@outlook.com>
2025-06-04 21:05:57 +08:00
c176bb2988 [doc] japanese elasticsearch (#3423)
Co-authored-by: kangli <likang@apache.org>
Co-authored-by: tomsun28 <tomsun28@outlook.com>
2025-06-04 09:31:22 +08:00
3cb4fc71f9 [doc] japanese dynamic_tp (#3419)
Co-authored-by: kangli <likang@apache.org>
Co-authored-by: tomsun28 <tomsun28@outlook.com>
2025-06-04 09:23:57 +08:00
c3f32132ca [feat] support sql("...") and promql("...") expressions including SQL condition parsing (#3410)
Co-authored-by: Calvin <zhengqiwei@apache.org>
Co-authored-by: shown <yuluo08290126@gmail.com>
2025-06-04 09:07:18 +08:00
e1affb169f [feature]Make GreptimeDB as a grafana data source (#3403)
Signed-off-by: Logic <zqr10159@126.com>
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: Calvin <zhengqiwei@apache.org>
Co-authored-by: tomsun28 <tomsun28@outlook.com>
2025-06-03 23:37:31 +08:00
shown db27159947 [infra]: Update issue tmpl (#3421)
Signed-off-by: shown <yuluo08290126@gmail.com>
2025-06-02 18:52:51 +08:00
63c187488f [doc] japanese doris_fe (#3416)
Co-authored-by: shown <yuluo08290126@gmail.com>
Co-authored-by: tomsun28 <tomsun28@outlook.com>
2025-05-31 09:14:37 +08:00
f3f66ada0d [doc] Update anonymous user auth configuration of the grafana dashboard document (#3407)
Co-authored-by: Calvin <zhengqiwei@apache.org>
Co-authored-by: Logic <zqr10159@dromara.org>
Co-authored-by: kangli <likang@apache.org>
Co-authored-by: shown <yuluo08290126@gmail.com>
2025-05-31 09:12:33 +08:00
tomsun28 d5c934dc01 [doc] update home doc (#3418) 2025-05-30 21:26:14 +08:00
Jast 518eebb6b1 [Doc] Update 1.7.1 (#3411) 2025-05-29 16:12:24 +08:00
Calvin 210454f969 [doc] japanese doris_be (#3409) 2025-05-29 08:03:06 +08:00
Calvin a8db5e31a0 [doc] japanese docker (#3408) 2025-05-28 07:16:33 +08:00
Calvin c01653aff3 [doc] japanese dns sd (#3405) 2025-05-27 21:27:58 +08:00
Calvin 480bd0e449 [doc] japanese dns (#3404) 2025-05-27 08:47:33 +08:00
97faca6753 [docs] update alert threshold doc (#3399)
Co-authored-by: tomsun28 <tomsun28@outlook.com>
Co-authored-by: liutianyou <tianyou.liu@qq.com>
2025-05-26 16:12:50 +08:00
Calvinandtomsun28 e271bd7417 [doc] japanese deepseek & dm (#3400)
Co-authored-by: tomsun28 <tomsun28@outlook.com>
2025-05-26 08:53:40 +08:00
7de4fd1cbf [improve] http sd collector adds authentication (#3388)
Co-authored-by: Calvin <naruse_shinji@163.com>
Co-authored-by: tomsun28 <tomsun28@outlook.com>
Co-authored-by: shown <yuluo08290126@gmail.com>
Co-authored-by: Calvin <zhengqiwei@apache.org>
2025-05-26 08:42:21 +08:00
Calvin c2a7d0db35 [doc] japanese Debian (#3398) 2025-05-25 15:42:54 +08:00
Calvin 93b2630bf3 [doc] japanese dahua (#3396) 2025-05-25 13:09:06 +08:00
Calvinandliutianyou 23749e7fac [doc] japanese coreos (#3393)
Co-authored-by: liutianyou <tianyou.liu@qq.com>
2025-05-24 09:35:46 +08:00
kangli d5eae40754 [doc]add new committer blog (#3395) 2025-05-24 08:23:17 +08:00
Calvin 7ef79de1de [doc] japanese consul sd (#3392) 2025-05-23 13:07:11 +08:00
tomsun28 8496771c8b [doc] new contributor and committer, update doc (#3391)
Signed-off-by: tomsun28 <tomsun28@outlook.com>
2025-05-23 12:15:09 +08:00
Calvin f31c835181 [doc] japanese clickhouse (#3390) 2025-05-23 08:42:33 +08:00
Logicandtomsun28 552554b96d [fix](warehouse): improve GreptimeDB data storage and querying (#3387)
Co-authored-by: tomsun28 <tomsun28@outlook.com>
2025-05-22 23:31:06 +08:00
zhangyaxiandtomsun28 4adcfd2a4e [test] Add unit tests for HttpSdCollectImpl (#3386)
Co-authored-by: tomsun28 <tomsun28@outlook.com>
2025-05-22 23:29:23 +08:00
Calvin e630beecb4 [doc] japanese cisco switch (#3389) 2025-05-22 22:46:53 +08:00
Duansgandtomsun28 6c2b38e180 [doc] modify supplement related documentation (#3383)
Co-authored-by: tomsun28 <tomsun28@outlook.com>
2025-05-21 23:17:50 +08:00
84986dd1bf [feature] support auto nacos service discovery (#3324)
Signed-off-by: tomsun28 <tomsun28@outlook.com>
Signed-off-by: zhangyaxi <yaxi.zhang950408@outlook.com>
Co-authored-by: tomsun28 <tomsun28@outlook.com>
Co-authored-by: Calvin <naruse_shinji@163.com>
Co-authored-by: shown <yuluo08290126@gmail.com>
Co-authored-by: aias00 <liuhongyu@apache.org>
2025-05-21 22:01:09 +08:00
af868e083a [Task] Batch import metrics data in victoria-metrics (#3337)
Co-authored-by: yinyijun <yinyijun6@mgtv.com>
Co-authored-by: Calvin <naruse_shinji@163.com>
Co-authored-by: aias00 <liuhongyu@apache.org>
2025-05-20 23:56:56 +08:00
be3e2f3558 [doc] modify chinese words (#3380)
Co-authored-by: aias00 <liuhongyu@apache.org>
Co-authored-by: tomsun28 <tomsun28@outlook.com>
2025-05-20 21:42:37 +08:00
d32818e8ef [feat] Support Zookeeper Service Discovery (#3377)
Signed-off-by: tomsun28 <tomsun28@outlook.com>
Co-authored-by: Calvin <naruse_shinji@163.com>
Co-authored-by: tomsun28 <tomsun28@outlook.com>
2025-05-20 21:30:48 +08:00
10b283522c [improve] add path validation for pluginservice (#3375)
Signed-off-by: aias00 <liuhongyu@apache.org>
Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com>
Co-authored-by: Calvin <naruse_shinji@163.com>
Co-authored-by: liutianyou <tianyou.liu@qq.com>
2025-05-20 12:32:24 +08:00
31ab2da41e [doc] Add blog (#3379)
Co-authored-by: Calvin <naruse_shinji@163.com>
Co-authored-by: tomsun28 <tomsun28@outlook.com>
2025-05-20 00:16:06 +08:00
LL-LINandtomsun28 a9436049e3 [doc] fix incorrect time template syntax usercase in doc (#3378)
Co-authored-by: tomsun28 <tomsun28@outlook.com>
2025-05-20 00:12:20 +08:00
Calvinandtomsun28 41c010511c [doc] japanese centos (#3376)
Co-authored-by: tomsun28 <tomsun28@outlook.com>
2025-05-20 00:08:39 +08:00
aias00andCalvin b5281c1274 update maven dep (#3359)
Co-authored-by: Calvin <naruse_shinji@163.com>
2025-05-20 00:06:59 +08:00
62cf3d1b2b [improve] improve jndi validation (#3358)
Signed-off-by: tomsun28 <tomsun28@outlook.com>
Co-authored-by: tomsun28 <tomsun28@outlook.com>
Co-authored-by: Calvin <naruse_shinji@163.com>
2025-05-18 17:45:09 +08:00
dc8ae844c1 [improve] improve url validation for serverChan (#3364)
Signed-off-by: aias00 <liuhongyu@apache.org>
Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com>
Co-authored-by: Calvin <naruse_shinji@163.com>
Co-authored-by: tomsun28 <tomsun28@outlook.com>
2025-05-18 16:48:31 +08:00
91a7593b87 [improve] improve url validation for SlackAlertNotifyHandlerImpl (#3363)
Signed-off-by: aias00 <liuhongyu@apache.org>
Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com>
Co-authored-by: Calvin <naruse_shinji@163.com>
Co-authored-by: tomsun28 <tomsun28@outlook.com>
2025-05-18 16:17:31 +08:00
4442a52adf [improve] improve url validation for TelegramBotAlertNotifyHandlerImpl (#3362)
Signed-off-by: aias00 <liuhongyu@apache.org>
Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com>
Co-authored-by: tomsun28 <tomsun28@outlook.com>
2025-05-18 14:09:09 +08:00
60e3437e82 [improve] improve url validation for WeComRobotAlertNotifyHandlerImpl (#3361)
Signed-off-by: aias00 <liuhongyu@apache.org>
Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com>
Co-authored-by: tomsun28 <tomsun28@outlook.com>
2025-05-18 13:31:39 +08:00
21d6ec2f1b [bugfix] Incorrect SD sub-monitor status (#3340)
Signed-off-by: Sherlock Yin <sherlock.yin1994@gmail.com>
Co-authored-by: yinyijun <yinyijun6@mgtv.com>
Co-authored-by: tomsun28 <tomsun28@outlook.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Calvin <naruse_shinji@163.com>
Co-authored-by: aias00 <liuhongyu@apache.org>
2025-05-18 01:00:37 +08:00
tomsun28 3ed50f39cb [doc] new ppmc liutianyou and update qq num (#3357)
Signed-off-by: tomsun28 <tomsun28@outlook.com>
2025-05-17 11:08:39 +08:00
Logic dfba21f224 [doc](start): update greptime-init documentation (#3355) 2025-05-16 20:41:08 +08:00
Sherlock Yinandtomsun28 9fb3f39eb1 [doc] update OS monitor (#3353)
Co-authored-by: tomsun28 <tomsun28@outlook.com>
2025-05-16 07:46:41 +08:00
Calvin 2430448089 [doc] japanese api (#3352) 2025-05-16 00:41:36 +08:00
Yang Chen 993de3d504 [bugfix] Fix incorrect webhook URLs for Uptime Kuma, Zabbix, and Tencent Cloud (#3351) 2025-05-15 20:03:19 +08:00
Jast 955ecd2128 [release] update release version 1.7.1 (#3347) 2025-05-15 15:20:52 +08:00
LL-LIN 96e5402c09 [bugfix] Fix frontend error when all monitor metrics are selected in new bulletin form (#3345) 2025-05-15 14:07:34 +08:00
Jast 0a6e8147e8 [build] Update .gitignore and add Maven wrapper properties (#3346) 2025-05-15 11:31:47 +08:00
7779056983 [feature] Support DNS Service Discovery (#3328)
Signed-off-by: Sherlock Yin <sherlock.yin1994@gmail.com>
Co-authored-by: yinyijun <yinyijun6@mgtv.com>
Co-authored-by: yinyijun <yingey2011>
Co-authored-by: tomsun28 <tomsun28@outlook.com>
2025-05-15 08:25:50 +08:00
Calvinandtomsun28 ca3348adf2 [doc] japanese almalinux (#3343)
Co-authored-by: tomsun28 <tomsun28@outlook.com>
2025-05-15 00:07:06 +08:00
dc822f50e8 [feat] Enhance Label Management for Monitors (#3327)
Co-authored-by: shown <yuluo08290126@gmail.com>
Co-authored-by: aias00 <liuhongyu@apache.org>
Co-authored-by: Calvin <naruse_shinji@163.com>
Co-authored-by: tomsun28 <tomsun28@outlook.com>
2025-05-14 23:31:15 +08:00
896adb76a2 [feature] Support Consul Service Discovery (#3326)
Co-authored-by: aias00 <liuhongyu@apache.org>
Co-authored-by: Calvin <naruse_shinji@163.com>
2025-05-14 23:21:00 +08:00
Calvin 2a49fa5774 [doc] japanese airflow (#3339) 2025-05-14 21:54:54 +08:00
aias00 2259d51cae [feat] add deep wiki badge (#3334) 2025-05-13 14:38:31 +08:00
Calvin e9e49cfbc5 [doc] japanese activemq (#3333) 2025-05-13 08:13:14 +08:00
kangliandtomsun28 3eba906491 [feature] Support Eureka Service Discovery (#3323)
Co-authored-by: tomsun28 <tomsun28@outlook.com>
2025-05-12 20:35:13 +08:00
6645c5d4b2 [Improve] Add i18 for ai bot (#3330)
Co-authored-by: yinyijun <yinyijun6@mgtv.com>
Co-authored-by: tomsun28 <tomsun28@outlook.com>
2025-05-12 20:06:16 +08:00
Calvin 88fb007ef0 [doc] japanese readme (#3329) 2025-05-12 16:03:10 +08:00
LogicandJast 4892ef101f [feature]: integrate OpenTelemetry for GreptimeDB logs and traces- Rename hertzbeat-log to hertzbeat-otel (#3319)
Co-authored-by: Jast <shenghang@apache.org>
2025-05-09 15:03:49 +08:00
tomsun28andshown d0b7e38537 [bugfix] fix the calculator expr exist not work (#3314)
Signed-off-by: tomsun28 <tomsun28@outlook.com>
Co-authored-by: shown <yuluo08290126@gmail.com>
2025-05-09 13:15:46 +08:00
096153b3a4 [license] update the license file, to add the plc4j-driver-s7 license (#3318)
Co-authored-by: cuijianzhong <shangyuancjz@126.com>
Co-authored-by: tomsun28 <tomsun28@outlook.com>
Co-authored-by: aias00 <rokkki@163.com>
Co-authored-by: aias00 <liuhongyu@apache.org>
2025-05-07 22:00:05 +08:00
zhangyaxi b313db36c6 [feature] Support Zabbix alert source (#3317)
Signed-off-by: zhangyaxi <yaxi.zhang950408@outlook.com>
2025-05-07 08:54:23 +08:00
tomsun28andCopilot 47298033dc [refactor] set default encoding charset utf8 (#3315)
Signed-off-by: tomsun28 <tomsun28@outlook.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-05-05 23:30:30 +08:00
tomsun28 f05e91247a [refactor] refactor auto discovery http sd (#3300)
Signed-off-by: tomsun28 <tomsun28@outlook.com>
2025-05-04 00:07:06 +08:00
zhangyaxiandtomsun28 1592c93d25 [feature] Support Uptime Kuma alert source (#3312)
Co-authored-by: tomsun28 <tomsun28@outlook.com>
2025-05-01 14:31:52 +08:00
Yang Chenandtomsun28 46d609a95e [docs] add help documentation for alert integration (#3308)
Co-authored-by: tomsun28 <tomsun28@outlook.com>
2025-04-30 16:05:59 +08:00
Yang Chen f17fb02441 [docs] Correct Markdown formatting and update lint config to enable local checking (#3310) 2025-04-30 11:08:38 +08:00
e6cc71ed56 [Improve] Add unit test for PeriodicAlertCalculator (#3304)
Co-authored-by: yinyijun <yinyijun6@mgtv.com>
Co-authored-by: yinyijun <yingey2011>
Co-authored-by: tomsun28 <tomsun28@outlook.com>
2025-04-28 17:46:14 +08:00
Cyanty e2a9160e59 [refactor] Remove the possible security in action and ignore the 500 code for link check (#3303) 2025-04-28 11:30:14 +08:00
7ebeee2c1f [docs] Add Chinese and English versions of the Hertzbeat upgrade guide (#3294)
Co-authored-by: tomsun28 <tomsun28@outlook.com>
Co-authored-by: shown <yuluo08290126@gmail.com>
Co-authored-by: aias00 <liuhongyu@apache.org>
2025-04-27 00:26:40 +08:00
Cyantyandtomsun28 ccfc8dc8ce [improve] Optimize the way of Dead Link Check (#3302)
Co-authored-by: tomsun28 <tomsun28@outlook.com>
2025-04-26 23:04:49 +08:00
Yang Chenandaias00 ca9db17241 [bugfix] enables support for VictoriaMetrics in cluster mode within HertzBeat (#3297)
Co-authored-by: aias00 <liuhongyu@apache.org>
2025-04-26 22:29:47 +08:00
Cyanty 7a40bdee12 [Doc] Add English doc for springboot auto practice usecase (#3298) 2025-04-26 20:40:16 +08:00
tomsun28 5db20d33f4 [bugfix] fix collector direct oom (#3295) 2025-04-24 20:22:50 +08:00
Cyanty 896869c611 [Doc] Add springboot auto practice usecase (#3293)
Signed-off-by: Cyanty <153884653+Cyanty@users.noreply.github.com>
2025-04-24 12:51:04 +08:00
tomsun28 32ce88b2c0 [webapp] try reduce memory growth and fix crash (#3292)
Signed-off-by: tomsun28 <tomsun28@outlook.com>
2025-04-23 19:47:24 +08:00
2288d8e900 [e2e] add e2e test for k8s monitor (#3280)
Co-authored-by: aias00 <liuhongyu@apache.org>
Co-authored-by: tomsun28 <tomsun28@outlook.com>
Co-authored-by: Jast <shenghang@apache.org>
2025-04-22 23:57:01 +08:00
tomsun28andJast dbb81d44ff [doc] update doc, usecase blog and help doc (#3286)
Co-authored-by: Jast <shenghang@apache.org>
2025-04-22 22:33:47 +08:00
227666dd46 [Task] Set local database as default file server provider (#3282)
Co-authored-by: yinyijun <yingey2011>
Co-authored-by: aias00 <liuhongyu@apache.org>
Co-authored-by: yinyijun <yinyijun6@mgtv.com>
Co-authored-by: tomsun28 <tomsun28@outlook.com>
2025-04-22 22:32:04 +08:00
liutianyouandtomsun28 b14bc6569f [bugfix] page title show "Not page name" when filter monitor list by type (#3289)
Co-authored-by: tomsun28 <tomsun28@outlook.com>
2025-04-22 22:23:54 +08:00
Jastandtomsun28 7c7102da17 [feature] support ai bot (#3285)
Co-authored-by: tomsun28 <tomsun28@outlook.com>
2025-04-22 22:19:17 +08:00
Jay丿167andaias00 489eac8e11 [improve] Add E2E tests for Redis collector (#3283)
Co-authored-by: aias00 <liuhongyu@apache.org>
2025-04-22 20:33:46 +08:00
900655680a [improve] Add jdbc common collect e2e code (#3273) (#3273)
Signed-off-by: Cyanty <153884653+Cyanty@users.noreply.github.com>
Co-authored-by: aias00 <liuhongyu@apache.org>
Co-authored-by: Jast <shenghang@apache.org>
Co-authored-by: shown <yuluo08290126@gmail.com>
2025-04-22 10:19:22 +08:00
tomsun28 e87ed449f2 [doc] update contributors wall (#3281)
Signed-off-by: tomsun28 <tomsun28@outlook.com>
2025-04-22 01:17:41 +08:00
tomsun28 ddf4759b34 [refactor] refact tag to label code (#3278) 2025-04-21 22:16:47 +08:00
Yang ChenandLogic a8ce48b50d [bugfix] support no-whitespace alert expressions in instance filtering (#3276)
Co-authored-by: Logic <zqr10159@dromara.org>
2025-04-21 15:46:16 +08:00
liutianyou a0f3890137 [feature] new alert supports reminding through system notifications (#3275) 2025-04-21 14:47:11 +08:00
liutianyou b02837b362 [bugfix] fix the prometheus metric response data parsing is abnormal (#3274) 2025-04-20 19:47:13 +08:00
9f9cdcf1a9 [Improve] optimize prompt (#3270)
Co-authored-by: Logic <zqr10159@dromara.org>
Co-authored-by: aias00 <liuhongyu@apache.org>
2025-04-20 09:57:06 +08:00
tomsun28 326497939d [webapp] update header logo style (#3272) 2025-04-20 09:49:59 +08:00
Jast d881aff90d [feature] add Maven Wrapper scripts (#3271) 2025-04-19 17:30:57 +08:00
78b0a428ff [feature] support collector alarm and refactor alarm (#2693)
Co-authored-by: Calvin <naruse_shinji@163.com>
Co-authored-by: aias00 <rokkki@163.com>
Co-authored-by: shown <yuluo08290126@gmail.com>
Co-authored-by: aias00 <liuhongyu@apache.org>
Co-authored-by: tomsun28 <tomsun28@outlook.com>
2025-04-19 13:07:41 +08:00
Yang Chenandtomsun28 ba173acc09 [bugfix] correct instance filtering regex in RealTimeAlertCalculator (#3269)
Co-authored-by: tomsun28 <tomsun28@outlook.com>
2025-04-19 10:10:11 +08:00
9d842a241b [bugfix] Wrong webhook alert template (#3265)
Co-authored-by: yinyijun <yinyijun6@mgtv.com>
Co-authored-by: Logic <zqr10159@dromara.org>
2025-04-18 23:48:58 +08:00
Cyanty c480d63833 [PR] [bugfix] Set the prometheus monitoring time and correct historical da… (#3264) 2025-04-18 20:56:50 +08:00
tomsun28 ce479c6ba9 [doc] add new contributor in wall (#3259)
Signed-off-by: tomsun28 <tomsun28@outlook.com>
2025-04-18 10:04:45 +08:00
f683cab857 [bugfix] Resolve incorrect display of detailed information in Prometheus task history monitoring charts under VictoriaMetrics. (#3248)
Co-authored-by: Jast <shenghang@apache.org>
Co-authored-by: aias00 <liuhongyu@apache.org>
2025-04-18 09:52:42 +08:00
9c38bd5309 [refactor] Alert datasource calculate (#3253)
Co-authored-by: yinyijun <yinyijun6@mgtv.com>
Co-authored-by: yinyijun <yingey2011>
Co-authored-by: tomsun28 <tomsun28@outlook.com>
2025-04-18 09:31:47 +08:00
淞筱 e7cd23a85d [bugfix] fix a remote command execution. (#3250) 2025-04-17 23:14:29 +08:00
Jast 81ad7d51b6 [Feature] Add log mcp for java (#3254) 2025-04-17 16:19:15 +08:00
leo 9fa5b17fe4 [bugfix] fix UriComponentsBuilder in PromqlQueryExecutor (#3244) 2025-04-14 20:37:18 +08:00
tomsun28 9700161fdd [doc] add new contributors to wall (#3243)
Signed-off-by: tomsun28 <tomsun28@outlook.com>
2025-04-14 16:40:24 +08:00
f578df1deb [feat] enable label-based filtering and selection for monitoring thresholds (#3223)
Co-authored-by: aias00 <liuhongyu@apache.org>
Co-authored-by: tomsun28 <tomsun28@outlook.com>
2025-04-14 14:26:52 +08:00
eb58bb76f2 [feature] switch to prometheus online parser & add query datasource (#3215)
Signed-off-by: tomsun28 <tomsun28@outlook.com>
Signed-off-by: leo <1552443053@qq.com>
Co-authored-by: Ceilzcx <1758619238@qq.com>
Co-authored-by: tomsun28 <tomsun28@outlook.com>
Co-authored-by: aias00 <liuhongyu@apache.org>
2025-04-14 14:08:11 +08:00
Cyantyandaias00 066d74629a [improve] Adjust Grafana configuration priority hierarchy and optimize API request exception handling (#3241)
Co-authored-by: aias00 <liuhongyu@apache.org>
2025-04-14 09:53:44 +08:00
tomsun28 9619638cff [doc] add new release 1.7.0 blog (#3237) 2025-04-14 09:45:53 +08:00
Yang Chenandtomsun28 b91f849594 [bugfix] Added jobContentCache.remove(jobId) to cancelAsyncCollectJob (#3240)
Co-authored-by: tomsun28 <tomsun28@outlook.com>
2025-04-13 20:28:52 +08:00
Logic e1806f856f [doc]update Grafana dashboard setup instructions (#3238) 2025-04-13 19:40:33 +08:00
淞筱 95654e49c5 [doc] add code-style-check zh-ch. (#3236)
Signed-off-by: 淞筱 <105542329+a-little-fool@users.noreply.github.com>
2025-04-12 13:41:40 +08:00
9ceb6e6400 [bugfix] Fix the issue where pendingTimeouts may be incorrect in the HashedWheelTimer. (#3174)
Co-authored-by: aias00 <rokkki@163.com>
Co-authored-by: aias00 <liuhongyu@apache.org>
Co-authored-by: tomsun28 <tomsun28@outlook.com>
2025-04-12 00:20:10 +08:00
淞筱andtomsun28 64cc15fabb [doc] code style check (#3232)
Co-authored-by: tomsun28 <tomsun28@outlook.com>
2025-04-12 00:14:21 +08:00
27da850ca4 [doc] add alerting silence doc. (#3229)
Co-authored-by: Jast <shenghang@apache.org>
Co-authored-by: tomsun28 <tomsun28@outlook.com>
2025-04-12 00:03:24 +08:00
1ad52321ea [Doc] Add Blog (#3224)
Co-authored-by: Administrator <admin@admin.com>
Co-authored-by: tomsun28 <tomsun28@outlook.com>
2025-04-11 23:50:40 +08:00
Cyanty ff037a6a3a [Doc] Modify the YML configuration parameters for Spring Boot 2.0/3.0 monitoring (#3231) 2025-04-10 20:21:11 +08:00
Logic 433f09a4e3 [feature]A preliminary logging module implementation (#3218) 2025-04-10 15:21:48 +08:00
Jast 706baffd5e [Doc] Fix dead link (#3227) 2025-04-09 23:43:19 +08:00
Logic 0b6fb353f1 [feature]add support for Dahua and Uniview devices (#3214) 2025-04-07 23:05:29 +08:00
0385892674 [feature] add pushgateway to push module (#3204)
Signed-off-by: tomsun28 <tomsun28@outlook.com>
Signed-off-by: leo <1552443053@qq.com>
Co-authored-by: tomsun28 <tomsun28@outlook.com>
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2025-04-05 17:28:11 +08:00
Logic 04e2321175 [test](hertzbeat-collector): add unit test for XML response parsing (#3212) 2025-04-05 09:18:52 +08:00
8373f0a247 [test] add test for controller AlertInhibitController (#3183)
Co-authored-by: yunfan24 <yunfan24@outlook.com>
Co-authored-by: aias00 <rokkki@163.com>
Co-authored-by: aias00 <liuhongyu@apache.org>
Co-authored-by: tomsun28 <tomsun28@outlook.com>
2025-04-03 21:31:06 +08:00
Logic 5ad03687b2 [feature] Implementation of Hikvision camera monitoring and http monitoring xml parsing function (#3211) 2025-04-03 20:07:18 +08:00
tomsun28andaias00 7127159063 [doc] archive version docs (#3207)
Co-authored-by: aias00 <liuhongyu@apache.org>
2025-04-03 14:30:49 +08:00
Nick Guoandtomsun28 51715797ef [improve] optimize DnsCollectTest with status code. (#3209)
Co-authored-by: tomsun28 <tomsun28@outlook.com>
2025-04-03 14:01:10 +08:00
liutianyouandtomsun28 47a1b13781 [doc] add doc for alarm grouping and alarm inhibit (#3206)
Co-authored-by: tomsun28 <tomsun28@outlook.com>
2025-04-03 13:33:15 +08:00
d5fc492b98 [feature] support plc s7 protocol for siemens (#3194)
Co-authored-by: cuijianzhong <shangyuancjz@126.com>
Co-authored-by: tomsun28 <tomsun28@outlook.com>
Co-authored-by: aias00 <rokkki@163.com>
Co-authored-by: aias00 <liuhongyu@apache.org>
2025-04-02 23:09:32 +08:00
bbc30cd3db [improve] i18n Portuguese (#3193)
Co-authored-by: aias00 <rokkki@163.com>
Co-authored-by: aias00 <liuhongyu@apache.org>
Co-authored-by: tomsun28 <tomsun28@outlook.com>
2025-04-02 22:46:33 +08:00
6e50d1f3a7 [improve] support the use of time expressions in HTTP payloads (#3192)
Co-authored-by: aias00 <rokkki@163.com>
Co-authored-by: aias00 <liuhongyu@apache.org>
Co-authored-by: tomsun28 <tomsun28@outlook.com>
2025-04-02 22:32:18 +08:00
b18412254e [improve] optimize kafka collection logic and expand test coverage (#3189)
Co-authored-by: yunfan24 <yunfan24@outlook.com>
Co-authored-by: aias00 <rokkki@163.com>
Co-authored-by: aias00 <liuhongyu@apache.org>
2025-04-02 22:26:37 +08:00
Yang Chenandaias00 fc0ef7773c [bugfix] fix bulletin indicator selection status error (#3201)
Co-authored-by: aias00 <liuhongyu@apache.org>
2025-04-02 15:48:33 +08:00
aias00 adf71441f8 update download info (#3203) 2025-04-02 15:44:42 +08:00
tomsun28 e36842420f [improve] update monitor list ui (#3200)
Signed-off-by: tomsun28 <tomsun28@outlook.com>
2025-03-31 19:27:22 +08:00
tomsun28andaias00 a2c1123b09 [doc] update new hertzbeat ppmc (#3191)
Co-authored-by: aias00 <rokkki@163.com>
2025-03-31 14:52:37 +08:00
tomsun28 b4151a4e73 [improve] update monitor detail ui (#3199)
Signed-off-by: tomsun28 <tomsun28@outlook.com>
2025-03-31 14:33:29 +08:00
jujin 1c1683d9c6 [doc] add blog bout How Does Metrics Collection Work (#3195) 2025-03-30 14:08:15 +08:00
46d4fc2dd9 [bugfix] Modify inconsistent icons (#3190)
Co-authored-by: yinyijun <yingey2011>
Co-authored-by: tomsun28 <tomsun28@outlook.com>
2025-03-29 10:38:07 +08:00
Sarthak Aroraandtomsun28 ffa2487587 [docs] add collector user guide (#3187)
Signed-off-by: tomsun28 <tomsun28@outlook.com>
Co-authored-by: tomsun28 <tomsun28@outlook.com>
2025-03-29 09:13:06 +08:00
30c7b22c4c [doc] add help documentation for Alarms Center (#3181)
Co-authored-by: yunfan24 <yunfan24@outlook.com>
Co-authored-by: aias00 <rokkki@163.com>
2025-03-29 00:06:40 +08:00
彭镜肇andtomsun28 7a3e23ec59 [improve] update import for package import (#3180)
Co-authored-by: tomsun28 <tomsun28@outlook.com>
2025-03-28 00:09:45 +08:00
Jast da6556641a [Doc] Modify the error records in the document (#3178) 2025-03-27 23:45:02 +08:00
Rickandrick b008f16b67 fix: Ai is a typo (#3176)
Co-authored-by: rick <LinuxSuRen@users.noreply.github.com>
2025-03-26 12:59:17 +08:00
tomsun28andaias00 b77222765c [improve] update notice copyright years (#3171)
Signed-off-by: tomsun28 <tomsun28@outlook.com>
Co-authored-by: aias00 <rokkki@163.com>
2025-03-25 10:16:26 +08:00
tomsun28 aeb4188f83 [improve] update git archive export ignore (#3172)
Signed-off-by: tomsun28 <tomsun28@outlook.com>
2025-03-25 09:39:49 +08:00
Yang Chen 311cb131fd [bugfix] fix bind Labels are not updated when the Alarm Severity switches (#3170) 2025-03-24 22:12:06 +08:00
tomsun28andaias00 21558e9b4f [bugfix] fix postgre mount error, use mariadb instead of mysql in compose (#3168)
Signed-off-by: tomsun28 <tomsun28@outlook.com>
Co-authored-by: aias00 <rokkki@163.com>
2025-03-24 15:12:56 +08:00
LL-LINandaias00 8d1f306433 [feature] implement labels-based monitors filtering in bulletin creation flow (#3161)
Co-authored-by: aias00 <rokkki@163.com>
2025-03-24 10:46:52 +08:00
tomsun28 e98af9527e [release] update release version 1.7.0 version and docs (#3165)
Signed-off-by: tomsun28 <tomsun28@outlook.com>
2025-03-23 10:39:00 +08:00
811a07553b [doc] Add alert integration japanese i18 (#3164)
Co-authored-by: yinyijun <yinyijun6@mgtv.com>
Co-authored-by: tomsun28 <tomsun28@outlook.com>
2025-03-22 14:16:28 +08:00
9fd58ced4a [feature] add twilio sms client support (#3159)
Co-authored-by: yunfan24 <yunfan24@outlook.com>
Co-authored-by: tomsun28 <tomsun28@outlook.com>
2025-03-22 14:12:32 +08:00
LL-LINandtomsun28 a331c045ae [bugfix] retain sorting state after monitor list auto-refresh (#3156)
Co-authored-by: tomsun28 <tomsun28@outlook.com>
2025-03-22 11:48:34 +08:00
yunfan24andaias00 63d3d18428 [bugfix] Fix http header being incorrectly encoded. (#3108)
Co-authored-by: aias00 <rokkki@163.com>
2025-03-22 11:44:16 +08:00
Yang Chen cec8d8b396 [bugfix]: fix incomplete class documentation in AppServiceImpl (#3162) 2025-03-21 17:34:43 +08:00
9d68d16a78 [feature] Support TencentCloud alert source (#3149)
Co-authored-by: yunfan24 <yunfan24@outlook.com>
Co-authored-by: tomsun28 <tomsun28@outlook.com>
2025-03-17 20:55:56 +08:00
Kerwin BryantandLogic 290474a715 Abstract Redundant Input Components into ConfigurableFieldComponent for Unified Management (#3152)
Co-authored-by: Logic <zqr10159@dromara.org>
2025-03-17 18:50:00 +08:00
Yang Chenandyunfan24 0dbc7347b4 [feature] Supports sending messages to a specific Telegram group topic.(#3079) (#3143)
Co-authored-by: yunfan24 <yunfan24@outlook.com>
2025-03-17 14:56:02 +08:00
tomsun28 e2a2d5eaec [bugfix] fix nightly docker build github action (#3153) 2025-03-17 10:00:41 +08:00
tomsun28 356cca295d [webapp] fix less style file over max build error (#3151)
Signed-off-by: tomsun28 <tomsun28@outlook.com>
2025-03-16 21:58:45 +08:00
yunfan24 5e09c6d9ae [improve] Merge SMS configuration class. (#3148) 2025-03-16 21:27:07 +08:00
tomsun28andZhang Yuxuan 54caa84fc1 [bugfix] fix collect dispatch error (#3150)
Signed-off-by: tomsun28 <tomsun28@outlook.com>
Co-authored-by: Zhang Yuxuan <1373529784@qq.com>
2025-03-15 21:49:58 +08:00
d2a332f533 [bugfix] Fixed #3112, disappear left menu tree item when restart service (#3116)
Co-authored-by: tomsun28 <tomsun28@outlook.com>
Co-authored-by: yunfan24 <yunfan24@outlook.com>
Co-authored-by: aias00 <rokkki@163.com>
2025-03-15 20:47:53 +08:00
tomsun28andLogic dc2efdf1c2 [improve] support bind metrics label and others into alert (#3146)
Signed-off-by: tomsun28 <tomsun28@outlook.com>
Co-authored-by: Logic <zqr10159@dromara.org>
2025-03-15 19:40:48 +08:00
4defb733bf [feature] support SSH proxy jump connections (#3138)
Co-authored-by: aias00 <rokkki@163.com>
Co-authored-by: Logic <zqr10159@dromara.org>
2025-03-14 20:51:58 +08:00
f8e85ec4f1 [feature] Support skywalking alert source (#3144)
Co-authored-by: yinyijun <yinyijun6@mgtv.com>
Co-authored-by: yinyijun <yingey2011>
Co-authored-by: tomsun28 <tomsun28@outlook.com>
2025-03-14 10:41:35 +08:00
jujinandyunfan24 3468739504 [feature] Add AWS sms client (#3134)
Co-authored-by: yunfan24 <yunfan24@outlook.com>
2025-03-14 01:01:29 +08:00
Kerwin Bryantandtomsun28 5a92161cd9 [webapp] Fix the issue of the empty dropdown menu on the Kanban board page. (#3142)
Co-authored-by: tomsun28 <tomsun28@outlook.com>
2025-03-12 23:58:48 +08:00
Kerwin Bryant 4ce6ffd4ee [improve] Configuring gitpod with java (#3141) 2025-03-12 23:52:36 +08:00
yunfan24andtomsun28 9f34d201ae [doc] Add new committer blog (#3140)
Co-authored-by: tomsun28 <tomsun28@outlook.com>
2025-03-11 00:24:44 +08:00
liutianyou 4b8ccf2fea [improve] improve plugin upload (#3139) 2025-03-11 00:18:57 +08:00
tomsun28 adf27d2544 [bugfix] fix overflow arrow buffer index (#3137) 2025-03-10 15:25:22 +08:00
tomsun28 033b9b0706 [improve] fix potential memory leakage and content length issues. (#3128)
Signed-off-by: tomsun28 <tomsun28@outlook.com>
2025-03-10 00:45:12 +08:00
01be0c7a1d [improve] Optimize the progress display of monitoring imports (#3120)
Signed-off-by: Sherlock Yin <sherlock.yin1994@gmail.com>
Co-authored-by: yinyijun <yinyijun6@mgtv.com>
Co-authored-by: tomsun28 <tomsun28@outlook.com>
Co-authored-by: yinyijun <yingey2011>
2025-03-10 00:25:31 +08:00
0fdd76c0de [feature] add smslocal sms notification (#3135)
Signed-off-by: 淞筱 <105542329+a-little-fool@users.noreply.github.com>
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: yunfan24 <yunfan24@outlook.com>
2025-03-09 21:51:53 +08:00
tomsun28 1a38fcf776 [doc] welcome new committer and contributor (#3132)
Signed-off-by: tomsun28 <tomsun28@outlook.com>
2025-03-07 17:50:13 +08:00
yyahang 268e111024 [bugfix] Fix swagger opening exception that Failed to load API definition. (#3127) (#3129) 2025-03-07 01:03:41 +08:00
tomsun28and淞筱 484dc5f70f [webapp] fix monitor define param wrong placeholder tip (#3118)
Signed-off-by: tomsun28 <tomsun28@outlook.com>
Co-authored-by: 淞筱 <105542329+a-little-fool@users.noreply.github.com>
2025-03-05 21:09:25 +08:00
tomsun28andaias00 b7bd9eb305 [improve] support reuse jdbc connection switch (#3101)
Signed-off-by: tomsun28 <tomsun28@outlook.com>
Co-authored-by: aias00 <rokkki@163.com>
2025-03-05 21:07:06 +08:00
yunfan24and淞筱 a5f874e682 [doc] Add alibaba SMS and unisms documentation. (#3114)
Co-authored-by: 淞筱 <105542329+a-little-fool@users.noreply.github.com>
2025-03-05 10:08:21 +08:00
Jastandtomsun28 fcf52b383a [doc] Add GSOC doc (#3122)
Co-authored-by: tomsun28 <tomsun28@outlook.com>
2025-03-04 21:50:36 +08:00
Jast e93c3a9054 [doc]fix link (#3123) 2025-03-04 00:53:11 +08:00
不关银渐层的事哦andtomsun28 84f222b516 [bugfix] fix #3090 garbled characters (#3113)
Co-authored-by: tomsun28 <tomsun28@outlook.com>
2025-03-03 16:09:12 +08:00
jujin 53bb58da5f [bugfix] Fix exception thrown when searching for CollectRep.Field in the list (#3109) 2025-02-28 23:17:46 +08:00
tomsun28 3688974610 [bugfix] fix alert sse illegal state exception (#3106) 2025-02-25 15:27:53 +08:00
af35043663 [feature] adding-ptBR-translation (#3098)
Co-authored-by: shown <yuluo08290126@gmail.com>
Co-authored-by: tomsun28 <tomsun28@outlook.com>
2025-02-25 09:37:21 +08:00
Jastandshown 84c28229b2 [Feature] Add deepseek Api Monitor (#3096)
Co-authored-by: shown <yuluo08290126@gmail.com>
2025-02-24 15:39:53 +08:00
tomsun28 1a3e614209 [webapp] fix web oom crash when backend api can not access (#3100) 2025-02-23 21:22:37 +08:00
Jast 3df0e56da9 [Improve] Message notification prompt optimization (#3095) 2025-02-23 21:19:10 +08:00
Jast b5b4771e1a [Doc]Improve openai doc (#3097) 2025-02-22 10:30:25 +08:00
b8c5ae4d40 [bugfix] kafka client detect error (#3088)
Co-authored-by: Jast <shenghang@apache.org>
Co-authored-by: tomsun28 <tomsun28@outlook.com>
2025-02-21 22:05:12 +08:00
淞筱 207f2d958c [doc] correct home's new_committer_process (#3094) 2025-02-21 20:59:51 +08:00
Nick Guo 398a40bba4 [improve] optimize kafka collect test (#3093) 2025-02-21 17:47:46 +08:00
yunfan24andtomsun28 bb14681621 [feature] supports alibabacloud sms. (#3084)
Co-authored-by: tomsun28 <tomsun28@outlook.com>
2025-02-21 13:55:30 +08:00
yunfan24 d3a080fbaf [improve] Improve and unify the search. (#3085) 2025-02-20 14:58:56 +08:00
tomsun28 ce6f9feac6 [webapp] update and fix alert ui when theme dark (#3082) 2025-02-16 23:25:04 +08:00
yunfan24 7d18118bbd [feature] SMS notification supports unisms. (#3077) 2025-02-15 22:40:03 +08:00
yunfan24andaias00 d5d2b6bc71 [doc] Update the SMS configuration document. (#3073)
Co-authored-by: aias00 <rokkki@163.com>
2025-02-13 20:32:48 +08:00
Logicandtomsun28 e11a4da2ac [improve](web-app): update monitor chart configuration and springboot GreptimeDB version (#3071)
Co-authored-by: tomsun28 <tomsun28@outlook.com>
2025-02-13 10:19:49 +08:00
58360442ca [Bugfix] fix when the monitor is modified, the status is erroneously changed (#3067)
Co-authored-by: aias00 <rokkki@163.com>
Co-authored-by: tomsun28 <tomsun28@outlook.com>
2025-02-13 00:14:37 +08:00
yunfan24andaias00 4d76c0abf4 [improve] Refactor SMS sending and replace Tencent Cloud SDK with HTTP API. (#3063)
Co-authored-by: aias00 <rokkki@163.com>
2025-02-11 19:40:36 +08:00
Jastandtomsun28 f761e18739 [Feature]Add Chinese check (#3066)
Co-authored-by: tomsun28 <tomsun28@outlook.com>
2025-02-11 10:36:55 +08:00
yunfan24 6ac073a54e [improve] Complete the missing labels in the i18n file. (#3065) 2025-02-11 10:16:36 +08:00
65a8d19c5d [feature] Support SSH Tunnel (#3060)
Co-authored-by: shown <yuluo08290126@gmail.com>
Co-authored-by: aias00 <rokkki@163.com>
2025-02-10 10:20:03 +08:00
tomsun28 060b4d875d [webapp] update ui theme (#3064)
Signed-off-by: tomsun28 <tomsun28@outlook.com>
2025-02-10 10:09:31 +08:00
kangliandLogic 6c88c1ba03 [API DOC] Change Swagger description (#3061)
Co-authored-by: Logic <zqr10159@dromara.org>
2025-02-08 19:29:12 +08:00
tomsun28 8c58a35476 [bugfix] fix singleton not support remove, search id error, audio fetch 401 (#3062)
Signed-off-by: tomsun28 <tomsun28@outlook.com>
2025-02-08 18:36:42 +08:00
2ab05a5669 [feature] Add Japanese i18n (#3013)
Co-authored-by: aias00 <rokkki@163.com>
Co-authored-by: Calvin <naruse_shinji@163.com>
Co-authored-by: tomsun28 <tomsun28@outlook.com>
Co-authored-by: shown <yuluo08290126@gmail.com>
2025-02-08 09:19:13 +08:00
f3bc7f55c5 [feature] Add Sftp config for monitor (#3038)
Co-authored-by: yinyijun <yingey2011>
Co-authored-by: yunfan24 <yunfan24@outlook.com>
Co-authored-by: tomsun28 <tomsun28@outlook.com>
Co-authored-by: yinyijun <yinyijun6@mgtv.com>
2025-02-07 23:57:06 +08:00
7effbc1f0d [Feature]Add zookeeper e2e code (#3030)
Co-authored-by: Calvin <naruse_shinji@163.com>
Co-authored-by: shown <yuluo08290126@gmail.com>
2025-02-07 23:22:10 +08:00
Logicandtomsun28 05e42182d9 [bugfix]style(alert-center): enhance 3D transformation and z-index layers (#3059)
Signed-off-by: tomsun28 <tomsun28@outlook.com>
Signed-off-by: Logic <zqr10159@dromara.org>
Co-authored-by: tomsun28 <tomsun28@outlook.com>
2025-02-07 20:28:15 +08:00
yunfan24andtomsun28 5e69f4dfd0 [bugfix] Fix the issue where the monitoring status is not updated. (#3056)
Co-authored-by: tomsun28 <tomsun28@outlook.com>
2025-02-07 16:12:47 +08:00
tomsun28 aeb0083394 [improve] update theme ui color (#3057)
Signed-off-by: tomsun28 <tomsun28@outlook.com>
2025-02-07 15:47:19 +08:00
Logic 02f635bdd3 [improve](alert-center) enhance alert card animations and interactions (#3055) 2025-02-07 10:18:52 +08:00
7dbcaaeda8 [alert] support multi query expr threshold (#3054)
Signed-off-by: tomsun28 <tomsun28@outlook.com>
Signed-off-by: Logic <zqr10159@126.com>
Co-authored-by: Logic <zqr10159@dromara.org>
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2025-02-06 21:33:56 +08:00
Logicandgithub-actions[bot] 4ddf0a9f3f [alert] support sse for alert center, no need to manually refresh the page, add slide-in animation (#3051)
Signed-off-by: Logic <zqr10159@126.com>
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2025-02-06 16:13:01 +08:00
yunfan24andtomsun28 f1b1e3f7d6 [improve] Search ignores case sensitivity. (#3042)
Co-authored-by: tomsun28 <tomsun28@outlook.com>
2025-02-05 15:56:31 +08:00
yunfan24 921b8e5713 [update] upgrade actions upload-artifact to v4 (#3046) 2025-02-05 11:30:42 +08:00
yunfan24andtomsun28 4009525f81 [improve] Replaced hardcoded text with internationalized string. (#3035)
Co-authored-by: tomsun28 <tomsun28@outlook.com>
2025-01-30 22:01:32 +08:00
yunfan24 e0c7b4e111 [bugfix] Fixed the bug in the threshold rules search box. (#3034) 2025-01-30 21:43:51 +08:00
yunfan24andaias00 5e01482caa [feature] Add pagination and name-based search functionality in notification module (#2948)
Co-authored-by: aias00 <rokkki@163.com>
2025-01-27 14:12:55 +08:00
yunfan24 028e2fbcbe [bugfix] fix and enable some unit tests. (#3031) 2025-01-27 12:58:14 +08:00
tomsun28 d00cc6dcf4 [feature] periodic alert threshold (#3024) 2025-01-26 18:37:57 +08:00
4b7fdd6985 OnlineParserTest doesn't test anything (#3010)
Co-authored-by: aias00 <rokkki@163.com>
Co-authored-by: leo <1552443053@qq.com>
Co-authored-by: tomsun28 <tomsun28@outlook.com>
2025-01-26 16:13:21 +08:00
tomsun28andJast e45ec431aa [doc] update new contributor wall (#3025)
Signed-off-by: tomsun28 <tomsun28@outlook.com>
Co-authored-by: Jast <shenghang@apache.org>
2025-01-26 15:50:05 +08:00
Jastandtomsun28 8fa52fbca1 [Feature] Add API e2e code (#3029)
Co-authored-by: tomsun28 <tomsun28@outlook.com>
2025-01-26 11:23:52 +08:00
Jastandtomsun28 132fd00ab1 [Improve] update english doc (#3028)
Co-authored-by: tomsun28 <tomsun28@outlook.com>
2025-01-26 11:12:43 +08:00
12ba2faa19 [MINOR UPDATE] Use Encode to string when possible (Base64) (#3016)
Co-authored-by: aias00 <rokkki@163.com>
Co-authored-by: tomsun28 <tomsun28@outlook.com>
2025-01-24 18:44:14 +08:00
PJ Fanningandaias00 2f3abfbad4 [issue-2998] remove invalid check in isValidLabelValue (#3015)
Co-authored-by: aias00 <rokkki@163.com>
2025-01-24 18:38:43 +08:00
myangle1120andaias00 95739d9114 [bugfix] Modify mask issue (#3018)
Co-authored-by: aias00 <rokkki@163.com>
2025-01-24 09:27:43 +08:00
Logicandtomsun28 428ae1f7d5 [bugfix]Fix page not found (#3014)
Co-authored-by: tomsun28 <tomsun28@outlook.com>
2025-01-23 19:49:02 +08:00
PJ Fanningandaias00 6509b8bfc6 [MINOR UPDATE] always specify the char encoding in getBytes (#3011)
Co-authored-by: aias00 <rokkki@163.com>
2025-01-23 18:40:59 +08:00
yunfan24andtomsun28 783bd8de89 [improve] Freeze the 'Operate' column on the right side of the list. (#3009)
Co-authored-by: tomsun28 <tomsun28@outlook.com>
2025-01-23 15:52:10 +08:00
Logicandtomsun28 d1115b44d1 [feature](alert) implement drag-and-drop functionality for alert templates (#3005)
Co-authored-by: tomsun28 <tomsun28@outlook.com>
2025-01-22 23:43:50 +08:00
NikhilMurugesanandaias00 68e37d613a [bugfix] fix some unit tests that failed to run (#3007)
Co-authored-by: aias00 <rokkki@163.com>
2025-01-22 23:41:08 +08:00
jonasHanhan 7db0df11ba [feature] Add alerter_zh_TW.properties configuration to adapt to mult… (#3004) 2025-01-21 16:30:48 +08:00
wanhaoandLogic e244bdc5a7 [feature] Complete multiple languages (#3002)
Co-authored-by: Logic <zqr10159@dromara.org>
2025-01-21 09:13:21 +08:00
tomsun28andLogic 0b7aa487f0 [webapp] bugfix edit monitor http query params error (#3001)
Signed-off-by: tomsun28 <tomsun28@outlook.com>
Co-authored-by: Logic <zqr10159@dromara.org>
2025-01-20 13:09:27 +08:00
PJ FanningandLogic 59d8764dfb [MINOR UPDATE] refactor base64 code to simplify the conversions (#2999)
Co-authored-by: Logic <zqr10159@dromara.org>
2025-01-20 10:13:52 +08:00
yunfan24 8a38a34965 [feature] Support monitoring for StarRocks FE and StarRocks BE. (#2997) 2025-01-20 10:03:18 +08:00
tomsun28 fd7e1b0e05 [bugfix] fix wrong http user-agent content (#2996) 2025-01-20 01:16:50 +08:00
PJ Fanning 5441838888 [MINOR UPDATE] fix more instances of unclosed Http Responses (#2995) 2025-01-19 22:45:28 +08:00
PJ FanningandLogic 56b1dcb502 [MINOR UPDATE] close http response in PrometheusAutoCollectImpl (#2994)
Signed-off-by: PJ Fanning <pjfanning@users.noreply.github.com>
Co-authored-by: Logic <zqr10159@dromara.org>
2025-01-19 17:56:16 +08:00
PJ Fanningandtomsun28 efbaf7feac [MINOR UPDATE] close HttpResponse in HttpCollectImpl (#2993)
Signed-off-by: PJ Fanning <pjfanning@users.noreply.github.com>
Co-authored-by: tomsun28 <tomsun28@outlook.com>
2025-01-19 17:48:21 +08:00
Logic 7003b8a150 [Improve]Add Copy token button (#2992) 2025-01-19 14:54:01 +08:00
wanhaoandaias00 aed524a88b [feature] Added multilingual defaults for forms (#2991)
Co-authored-by: aias00 <rokkki@163.com>
2025-01-18 20:54:57 +08:00
aias00 9b20ab8434 [type:fix] remove matomo ip (#2990) 2025-01-17 23:15:44 +08:00
5c39b98eaa [feature] Add privateKey passphrase config for linux monitor (#2982)
Co-authored-by: yinyijun <yinyijun6@mgtv.com>
Co-authored-by: tomsun28 <tomsun28@outlook.com>
Co-authored-by: aias00 <rokkki@163.com>
2025-01-17 22:05:14 +08:00
aias00 43ac859939 [type:improve] fix dependencies vulnerabilites (#2989) 2025-01-17 20:31:57 +08:00
helei1030andtomsun28 b5c2eca819 [docs]added spark Chinese documents and changed the original spar… (#2987)
Co-authored-by: tomsun28 <tomsun28@outlook.com>
2025-01-17 10:41:19 +08:00
PJ Fanning cd57f51892 [MINOR UPDATE] improve xml parsing code (#2988)
Signed-off-by: PJ Fanning <pjfanning@users.noreply.github.com>
2025-01-17 09:17:57 +08:00
tomsun28 a33966de9f [improve] update i18n json stru and update search ui (#2986) 2025-01-16 20:46:32 +08:00
4ff9452926 [bugfix] fix hbase dashboard display anomalies and turn on HTTPS (#2980)
Co-authored-by: zhuoyuchen <>
Co-authored-by: aias00 <rokkki@163.com>
Co-authored-by: Jast <shenghang@apache.org>
2025-01-15 18:20:21 +08:00
Jast 67da9bdbba [Feature] Support copy monitoring (#2981) 2025-01-15 17:03:53 +08:00
tomsun28 8bb4493b43 [bugfix] fix alert integration extern source bug (#2979) 2025-01-14 18:22:21 +08:00
ghyandshown 92edd53f8c [webapp] key-value-input component hover effect fixed (#2972)
Signed-off-by: ghy <ghyghoo8@qq.com>
Co-authored-by: shown <yuluo08290126@gmail.com>
2025-01-13 15:44:14 +08:00
d70ad75dcc [bugfix] Fix NullPointerException (#2849)
Signed-off-by: Ayu <127600988+ayu-v0@users.noreply.github.com>
Signed-off-by: Zhang Yuxuan <1373529784@qq.com>
Co-authored-by: Ayu <14359932+lin-Ayu0v0@user.noreply.gitee.com>
Co-authored-by: shown <yuluo08290126@gmail.com>
Co-authored-by: aias00 <rokkki@163.com>
Co-authored-by: Zhang Yuxuan <1373529784@qq.com>
2025-01-12 22:52:37 +08:00
tomsun28andLogic 2e76c12fe1 [feature] alert integration extern source (#2978)
Signed-off-by: tomsun28 <tomsun28@outlook.com>
Co-authored-by: Logic <zqr10159@dromara.org>
2025-01-12 16:13:52 +08:00
Nick Guoandtomsun28 7e158eb778 [Improve] Add more test cases for Kafka junit tests (#2976)
Co-authored-by: tomsun28 <tomsun28@outlook.com>
2025-01-11 17:05:04 +08:00
Logicandtomsun28 db23c94882 [bugfix](warehouse) add metrics data update logic in memory storage (#2973)
Co-authored-by: tomsun28 <tomsun28@outlook.com>
2025-01-10 20:10:01 +08:00
yunfan24andaias00 e905f36de2 [bugfix] Fix the search functionality issue. (#2970)
Co-authored-by: aias00 <rokkki@163.com>
2025-01-10 19:36:22 +08:00
aias00andshown 037957dbe6 [feature] replace googletagmanager to matomo (#2877)
Co-authored-by: shown <yuluo08290126@gmail.com>
2025-01-09 16:28:17 +08:00
liutianyouandtomsun28 01d18f7935 [Improve] add no popup option after next login (#2969)
Co-authored-by: tomsun28 <tomsun28@outlook.com>
2025-01-08 23:47:47 +08:00
88e350de1c [BUG] "Advanced Settings" is all white in dark mode (#2965)
Co-authored-by: shown <yuluo08290126@gmail.com>
Co-authored-by: tomsun28 <tomsun28@outlook.com>
2025-01-08 23:43:27 +08:00
Nick Guoandtomsun28 07d22a8712 [Improve] Standardize Kafka metric naming (#2961)
Co-authored-by: tomsun28 <tomsun28@outlook.com>
2025-01-08 23:38:29 +08:00
tomsun28 7847fd78b7 [bufix] fix collector job scheduler error (#2966)
Signed-off-by: tomsun28 <tomsun28@outlook.com>
2025-01-08 21:44:42 +08:00
tomsun28 f7676ac8ca [improve] update alarm inhibit rule and alarm ui (#2957) 2025-01-08 10:04:07 +08:00
Jastandtomsun28 dd1cc700d9 [Imporve] Improve Huaweicloud (#2954)
Co-authored-by: tomsun28 <tomsun28@outlook.com>
2025-01-07 23:05:05 +08:00
Nick Guo d8dabe251a [Doc]Add English version of documentation for Kafka Consumer Detail (#2953) 2025-01-07 10:12:47 +08:00
Nick GuoandLogic f2e647d777 【Improve】adjust log level from INFO to WARN. (#2952)
Co-authored-by: Logic <zqr10159@dromara.org>
2025-01-06 13:50:09 +08:00
tomsun28 7bac0245a2 [improve] fix some alarm relate bug, update alarm center ui (#2951)
Signed-off-by: tomsun28 <tomsun28@outlook.com>
2025-01-06 11:25:52 +08:00
Jast d6e5399121 [Improve]Modify Chinese comments (#2950) 2025-01-06 00:36:29 +08:00
doveLinandaias00 00076fc704 [Feature] Support customized JMX monitoring through the Factory Pattern. (#2932)
Co-authored-by: aias00 <rokkki@163.com>
2025-01-05 17:59:42 +08:00
yunfan24andtomsun28 4a3d61bd9e [doc] Add Supported MySQL Versions. (#2949)
Co-authored-by: tomsun28 <tomsun28@outlook.com>
2025-01-05 16:53:50 +08:00
Logic af59b487e4 [bugfix](db): optimize column update. (#2947) 2025-01-05 16:48:56 +08:00
4cd3c3c97f [alarm] refactor new alarm (#2902)
Signed-off-by: tomsun28 <tomsun28@outlook.com>
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: Calvin <naruse_shinji@163.com>
Co-authored-by: a-little-fool <2030509072@qq.com>
Co-authored-by: Logic <zqr10159@dromara.org>
2025-01-04 22:18:27 +08:00
69a21ffaa1 [refactor] refactoring methods replaceCryPlaceholder and replaceSmilingPlace (#2832)
Co-authored-by: Zhang Yuxuan <1373529784@qq.com>
Co-authored-by: aias00 <rokkki@163.com>
Co-authored-by: Calvin <naruse_shinji@163.com>
Co-authored-by: tomsun28 <tomsun28@outlook.com>
2025-01-04 19:54:05 +08:00
Jast 8ab71e672f [Improve]Improve e2e code (#2945) 2025-01-04 15:58:22 +08:00
7625a0b508 [home] updated navbar css #2928 (#2934)
Signed-off-by: Vedant7789 <147625492+Vedant7789@users.noreply.github.com>
Co-authored-by: tomsun28 <tomsun28@outlook.com>
Co-authored-by: shown <yuluo08290126@gmail.com>
Co-authored-by: aias00 <rokkki@163.com>
2025-01-03 17:43:51 +08:00
dc963833e8 [improve] Refactor and Split the Message Notification Component. (#2924)
Co-authored-by: shown <yuluo08290126@gmail.com>
Co-authored-by: aias00 <rokkki@163.com>
2025-01-03 17:15:56 +08:00
Craaaaazy77andshown 87d4379efb [bugfix] Modify the doris_be.md document into an English version (#2936)
Signed-off-by: Craaaaazy77 <417989286@qq.com>
Co-authored-by: shown <yuluo08290126@gmail.com>
2025-01-03 14:40:42 +08:00
Simon Sigréandtomsun28 bffd7c1d4f [bugfix] Corrected case 'DashBoard' is a lower case 'B' (#2935)
Co-authored-by: tomsun28 <tomsun28@outlook.com>
2025-01-02 20:27:24 +08:00
yunfan24 ba21ef5cdb [improve] Improve the synchronization of the mute status. (#2927) 2025-01-02 18:59:44 +08:00
Simon Sigréandtomsun28 3bf237a4eb [feature] Adding CPU Temperature Check Into Default Ubuntu Checks (#2930)
Signed-off-by: Simon Sigré <simon.sigre@gmail.com>
Co-authored-by: tomsun28 <tomsun28@outlook.com>
2025-01-02 00:57:05 +08:00
ponfeeandtomsun28 19e7f128a3 [improve] optimize website navbar css(#2928) (#2929)
Co-authored-by: tomsun28 <tomsun28@outlook.com>
2025-01-01 14:49:57 +08:00
Jastandtomsun28 5c409d7512 [Improve] Optimize the e2e code structure (#2926)
Co-authored-by: tomsun28 <tomsun28@outlook.com>
2025-01-01 14:14:26 +08:00
6bf20ba21a [bugfix] Fixed the 'java.lang.UnsupportedOperationException' exception caused by getCurrentMetricsData (#2923)
Co-authored-by: bcxc <lixiaobaivvv@gmail.com>
Co-authored-by: tomsun28 <tomsun28@outlook.com>
2025-01-01 14:00:32 +08:00
Simon Sigré 8c9b1f3f92 [doc] Update app-windows_script.yml (#2922)
Signed-off-by: Simon Sigré <simon.sigre@gmail.com>
2025-01-01 00:28:34 +08:00
yunfan24 b3eb0083df [bugfix] Bug fix for alarm voice. (#2920) 2024-12-30 23:41:48 +08:00
LogicandJast e51accb3e6 [improve](warehouse): replace empty json object key with empty string (#2919)
Co-authored-by: Jast <shenghang@apache.org>
2024-12-30 20:08:33 +08:00
Logic a9e219811a [bugfix]: fix setColumns method in CollectRep class (#2918) 2024-12-30 19:58:00 +08:00
Jastandtomsun28 51bdb56592 [Feture]Add docker e2e test (#2916)
Co-authored-by: tomsun28 <tomsun28@outlook.com>
2024-12-30 13:05:43 +08:00
yunfan24andtomsun28 3562e870d8 [improve] Add required field indicators and form validation prompts for convergence strategies and silent strategies in the form. (#2913)
Co-authored-by: tomsun28 <tomsun28@outlook.com>
2024-12-30 13:04:03 +08:00
6f9ee2f4e6 [improve] Optimize CacheService and add relevant unit test (#2912)
Co-authored-by: LLWW04 <1713673102@qq.com>
Co-authored-by: tomsun28 <tomsun28@outlook.com>
2024-12-29 23:52:36 +08:00
Jastandtomsun28 917c11f298 [bugfix] Fix docker container name unable to display problem (#2914)
Co-authored-by: tomsun28 <tomsun28@outlook.com>
2024-12-29 11:45:51 +08:00
bf8d5b79bb [bugfix] Fix the bug where canceling an edit on a record still updates the page values. (#2911)
Co-authored-by: aias00 <rokkki@163.com>
Co-authored-by: tomsun28 <tomsun28@outlook.com>
2024-12-29 11:38:57 +08:00
7178c444f2 [feature](web-app)Add Alarm Voice Alerts (#2906)
Signed-off-by: Logic <zqr10159@126.com>
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: aias00 <rokkki@163.com>
2024-12-29 11:25:48 +08:00
Calvinandtomsun28 bc2dc1d567 [improve] fix import of CollectRep (#2910)
Co-authored-by: tomsun28 <tomsun28@outlook.com>
2024-12-28 14:04:11 +08:00
Jastandtomsun28 9714123c98 [Improve] Improve OBS (#2909)
Co-authored-by: tomsun28 <tomsun28@outlook.com>
2024-12-28 12:24:58 +08:00
leo 8ca2f70153 add an online parser for prometheus. (#2851) 2024-12-27 23:18:56 +08:00
doveLin 126268f7ec [feature] Add a new Singleton-pattern-based LRU local cache (#2907) 2024-12-27 14:39:00 +08:00
Logic 12d1f4990d [fix](flink): update calculate metrics definitions (#2905) 2024-12-26 23:45:02 +08:00
Jastandtomsun28 4b21df556c [Imporve] Support Kafka internal topic configuration (#2901)
Co-authored-by: tomsun28 <tomsun28@outlook.com>
2024-12-26 00:06:12 +08:00
Jast 893d91c4f0 [doc] update doc (#2900)
Signed-off-by: Jast <shenghang@apache.org>
2024-12-26 00:00:34 +08:00
4236c438be [feature] integrate with Apache Arrow (#2864)
Signed-off-by: tomsun28 <tomsun28@outlook.com>
Signed-off-by: shown <yuluo08290126@gmail.com>
Co-authored-by: shown <yuluo08290126@gmail.com>
Co-authored-by: tomsun28 <tomsun28@outlook.com>
Co-authored-by: aias00 <rokkki@163.com>
2024-12-24 20:43:14 +08:00
yunfan 6a64752af0 [Improve] add notification when port number changes automatically due to HTTPS toggle.(#2779) (#2896) 2024-12-24 18:22:26 +08:00
东风 c5cce27cb4 [improve]add Plc protocol , Modbus monitor (#2850) 2024-12-23 23:52:40 +08:00
doveLin 364de609bf [collector] fix the issue of reusing the adminClient in the Kafka client. (#2895) 2024-12-23 11:44:45 +08:00
Jast 5d81c32f9d [Improve] Improve Kafka chart display (#2894) 2024-12-23 10:53:53 +08:00
doveLinandtomsun28 6aff6ed053 [collector]add monitoring metrics for consumer groups in Kafka client (#2887)
Co-authored-by: tomsun28 <tomsun28@outlook.com>
2024-12-20 14:20:05 +08:00
Nick Guoandtomsun28 5ba09cf5c1 [doc] add more hints when users are switching data source. (#2880)
Co-authored-by: tomsun28 <tomsun28@outlook.com>
2024-12-20 13:52:46 +08:00
Logic a746e35dcf [Improve]Beautify Charts (#2891) 2024-12-20 12:06:28 +08:00
liutianyou a27777adcb [improve]improve linux process (#2889) 2024-12-20 07:41:17 +08:00
Logic 4b7dfb4c8e [improve] remove stack property from line charts (#2888) 2024-12-19 22:51:42 +08:00
AyuandAyu ceda4a65f9 [chore] delete the redundant else (#2881)
Co-authored-by: Ayu <14359932+lin-Ayu0v0@user.noreply.gitee.com>
2024-12-19 16:07:57 +08:00
d4f6fc1ae8 [Fix] fix clickhouse monitor (#2874)
Co-authored-by: Calvin <naruse_shinji@163.com>
Co-authored-by: aias00 <rokkki@163.com>
2024-12-17 14:20:27 +08:00
铁甲小宝 e999360da8 modified:add a small change. (#2878) 2024-12-16 00:16:29 +08:00
Nick Guo 948fcb739a [improve]Add more helpful messages when adding a Kafka monitor (#2876) 2024-12-14 15:22:27 +08:00
cdf060e9ac [Optimize] Add a reminder about potential collection issues caused by the Docker deployment method of collector. (#2844)
Co-authored-by: Calvin <naruse_shinji@163.com>
Co-authored-by: tomsun28 <tomsun28@outlook.com>
Co-authored-by: shown <yuluo08290126@gmail.com>
Co-authored-by: aias00 <rokkki@163.com>
2024-12-12 20:51:02 +08:00
starryCoder 1280c61af1 [doc] improve windows monitoring doc(#2869) 2024-12-12 15:10:18 +08:00
Nick Guo 86ad10ad7b [doc] Add ',' separator between monitoring types (#2865) 2024-12-10 21:08:55 +08:00
8961cf70a3 [bugfix]A bug fix (#2853)
Co-authored-by: shown <yuluo08290126@gmail.com>
Co-authored-by: aias00 <rokkki@163.com>
2024-12-08 11:48:18 +08:00
tomsun28andaias00 f31909a30d [doc] update security doc and some (#2856)
Signed-off-by: tomsun28 <tomsun28@outlook.com>
Co-authored-by: aias00 <rokkki@163.com>
2024-12-05 08:49:18 +08:00
Jastandtomsun28 2df7e1d269 [improve] improve dependency (#2855)
Co-authored-by: tomsun28 <tomsun28@outlook.com>
2024-12-04 21:24:37 +08:00
tomsun28andCalvin c10ebf0b60 [doc] add security model doc and update contributors (#2846)
Signed-off-by: tomsun28 <tomsun28@outlook.com>
Co-authored-by: Calvin <naruse_shinji@163.com>
2024-12-04 13:58:16 +08:00
1fe70a60cc [bugfix]Fix wrong app name (#2845)
Co-authored-by: Calvin <naruse_shinji@163.com>
Co-authored-by: tomsun28 <tomsun28@outlook.com>
2024-11-30 16:43:09 +08:00
Jastandtomsun28 3ea4c0e7da [Feature] Add ssh e2e code (#2843)
Co-authored-by: tomsun28 <tomsun28@outlook.com>
2024-11-30 16:39:03 +08:00
tomsun28 8228938bd1 [fix] auto generated by protocol buffer (#2842)
Signed-off-by: tomsun28 <tomsun28@outlook.com>
2024-11-30 13:56:05 +08:00
5acaf4844a [feature] support managing tasks by using http_sd (#2830)
Co-authored-by: Zhang Yuxuan <1373529784@qq.com>
Co-authored-by: aias00 <rokkki@163.com>
2024-11-28 00:07:38 +08:00
fc8be06ad5 [improve] update victoriametrics and greptime store (#2836)
Signed-off-by: tomsun28 <tomsun28@outlook.com>
Signed-off-by: Logic <zqr10159@126.com>
Co-authored-by: shown <yuluo08290126@gmail.com>
Co-authored-by: Logic <zqr10159@dromara.org>
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: Zhang Yuxuan <1373529784@qq.com>
2024-11-27 08:58:09 +08:00
tomsun28 509a9c9651 [fix] bugfix flyway location can not auto detect vendor when not h2 (#2835) 2024-11-26 19:28:39 +08:00
Logic 754b18c9ba [doc] update sidebar category label and plugin documentation (#2837) 2024-11-26 14:36:40 +08:00
8cdc92ab56 [chore] Delete redundant Spaces (#2834)
Signed-off-by: ayu-v0 <127600988+ayu-v0@users.noreply.github.com>
Co-authored-by: Ayu <14359932+lin-Ayu0v0@user.noreply.gitee.com>
Co-authored-by: tomsun28 <tomsun28@outlook.com>
2024-11-24 21:01:25 +08:00
tomsun28andLogic f0cb2af031 [improve] update and fix template yml priority (#2829)
Signed-off-by: tomsun28 <tomsun28@outlook.com>
Co-authored-by: Logic <zqr10159@dromara.org>
2024-11-24 15:38:21 +08:00
Jastandtomsun28 bd937bf7b8 [doc] Added custom development collector documentation (#2833)
Co-authored-by: tomsun28 <tomsun28@outlook.com>
2024-11-24 14:10:33 +08:00
starryCoder 8852713e4d [fix]fix windows chinese encoding (#2831) 2024-11-24 11:39:50 +08:00
CalvinandZhang Yuxuan 12f4ecce01 [refactor] change name from http_sd to registry (#2827)
Co-authored-by: Zhang Yuxuan <1373529784@qq.com>
2024-11-22 19:34:42 +08:00
Kerwin Bryant ca9934ec81 Fixed the omissions in #2805 (#2826)
Signed-off-by: Kerwin Bryant <kerwin612@qq.com>
2024-11-22 08:51:00 +08:00
tomsun28andshown eaaf589083 [improve] update grafana auth method and add expose url (#2818)
Signed-off-by: tomsun28 <tomsun28@outlook.com>
Co-authored-by: shown <yuluo08290126@gmail.com>
2024-11-18 23:19:57 +08:00
tomsun28 be84a0abae [improve] update windows metrics yml (#2816)
Signed-off-by: tomsun28 <tomsun28@outlook.com>
2024-11-18 21:57:50 +08:00
Jast 9a00f5a776 [improve] modify e2e test (#2814) 2024-11-14 23:38:43 +08:00
fb4626dd07 [feature] add e2e code (#2811)
Co-authored-by: aias00 <rokkki@163.com>
Co-authored-by: tomsun28 <tomsun28@outlook.com>
2024-11-14 11:24:49 +08:00
Jast f28996255a [Improve] improve kafka monitor (#2813) 2024-11-13 21:35:04 +08:00
Jast 0b79222bd0 [Doc] Add blog (#2812) 2024-11-11 23:19:15 +08:00
liutianyouandZhang Yuxuan 120f3a12fe [fix] fix the Linux process monitoring process exits abnormally without warning (#2810)
Co-authored-by: Zhang Yuxuan <1373529784@qq.com>
2024-11-11 14:09:30 +08:00
b8b1885657 [improve] Fix error links caused by module name changes. (#2807)
Co-authored-by: aias00 <rokkki@163.com>
Co-authored-by: tomsun28 <tomsun28@outlook.com>
2024-11-09 22:17:51 +08:00
caf13c09bd [feature] Support custom refresh intervals for each group of metrics (#2718)
Co-authored-by: tomsun28 <tomsun28@outlook.com>
Co-authored-by: shown <yuluo08290126@gmail.com>
Co-authored-by: aias00 <rokkki@163.com>
Co-authored-by: crossoverJie <crossoverJie@gmail.com>
2024-11-09 13:41:31 +08:00
dca3e351ed [improve] code according to code specifications (#2809)
Co-authored-by: shown <yuluo08290126@gmail.com>
Co-authored-by: aias00 <rokkki@163.com>
2024-11-08 19:16:19 +08:00
Jast 6298e7ae90 [Improve] Improve module name (#2805) 2024-11-08 09:25:28 +08:00
tomsun28 4b2c3756b1 [doc] update new contributors (#2802)
Signed-off-by: tomsun28 <tomsun28@outlook.com>
2024-11-04 11:12:16 +08:00
shinestare d32ec249b4 [fix]Remove the duplicate declaration of commons-net (#2801) 2024-11-03 11:03:01 +08:00
tomsun28andLogic 611ddc22e3 [bugfix] fix collector docker build error (#2799)
Signed-off-by: tomsun28 <tomsun28@outlook.com>
Co-authored-by: Logic <zqr10159@dromara.org>
2024-11-01 17:28:27 +08:00
4373ab23f3 [improve] improve the way Ai is entered and requested (#2762)
Co-authored-by: tomsun28 <tomsun28@outlook.com>
Co-authored-by: shown <yuluo08290126@gmail.com>
Co-authored-by: aias00 <rokkki@163.com>
Co-authored-by: Zhang Yuxuan <1373529784@qq.com>
2024-10-31 22:02:02 +08:00
bff75757db [Task][OSPP] HertzBeat Official Template Marketplace (#2641)
Co-authored-by: Calvin <naruse_shinji@163.com>
Co-authored-by: aias00 <rokkki@163.com>
Co-authored-by: shown <yuluo08290126@gmail.com>
Co-authored-by: tomsun28 <tomsun28@outlook.com>
Co-authored-by: Logic <zqr10159@dromara.org>
2024-10-30 20:07:49 +08:00
tomsun28 50dd262fbf [doc] update deploy doc (#2796) 2024-10-30 15:38:34 +08:00
Jastandtomsun28 dc9743b7a5 [Doc] improve website (#2795)
Co-authored-by: tomsun28 <tomsun28@outlook.com>
2024-10-30 11:02:16 +08:00
Logic 8dc0fdee27 [doc](download): update for v1.6.1 release (#2794) 2024-10-30 10:08:20 +08:00
1267fcae5a [Feature] add seatunnel monitor (#2782)
Co-authored-by: shown <yuluo08290126@gmail.com>
Co-authored-by: aias00 <rokkki@163.com>
Co-authored-by: Zhang Yuxuan <1373529784@qq.com>
2024-10-29 14:28:24 +08:00
afe68ba4f8 [collector]bugfix: close connection when common cache is timeout (#2786)
Co-authored-by: shown <yuluo08290126@gmail.com>
Co-authored-by: aias00 <rokkki@163.com>
2024-10-29 09:10:09 +08:00
4da00d445b [Task] [OSPP] JAVA implements the native ipmi2 communication protocol (#2726)
Signed-off-by: Gao Jian <1209640759@qq.com>
Co-authored-by: aias00 <rokkki@163.com>
Co-authored-by: shown <yuluo08290126@gmail.com>
2024-10-28 20:43:42 +08:00
e3d09ef427 [doc]Correct PostgreSQL image name in documentation (#2789)
Co-authored-by: shown <yuluo08290126@gmail.com>
Co-authored-by: aias00 <rokkki@163.com>
2024-10-27 15:45:21 +08:00
bb0a22c42f [improve] code according to code specifications(#2784) (#2785)
Co-authored-by: shown <yuluo08290126@gmail.com>
Co-authored-by: aias00 <rokkki@163.com>
2024-10-26 17:21:57 +08:00
Jastandshown 291f7cb351 [Improve] Improve log config (#2783)
Co-authored-by: shown <yuluo08290126@gmail.com>
2024-10-26 16:58:06 +08:00
Logic ba4f1e35f8 [bugfix]Update JDBC URL prefix for TDengine connection (#2788) 2024-10-26 16:42:59 +08:00
Logic 32f8cd5188 [improve] fix release script (#2781) 2024-10-23 22:35:45 +08:00
tomsun28 1f22a610ce [improve] update docker-compose license and fix compose config yml (#2778)
Signed-off-by: tomsun28 <tomsun28@outlook.com>
2024-10-22 23:45:39 +08:00
Jast fac3f5b927 [doc] drop dead link (#2777) 2024-10-22 17:21:36 +08:00
tomsun28 efa2dc3969 [improve] email notice template use the common render (#2775)
Signed-off-by: tomsun28 <tomsun28@outlook.com>
2024-10-15 23:48:39 +08:00
tomsun28 a0995d26ec [doc] add baota extern install doc (#2768)
Signed-off-by: tomsun28 <tomsun28@outlook.com>
2024-10-11 23:12:08 +08:00
JastandZhang Yuxuan 4f18c2c930 [Improve] modify kafka log level (#2763)
Co-authored-by: Zhang Yuxuan <1373529784@qq.com>
2024-10-08 21:46:21 +08:00
Jast 739e678dd5 [doc] improve kafka monitor config (#2765) 2024-10-08 21:39:05 +08:00
tomsun28 2856c3fe65 [webapp] fix bulletin with multiple rows of results (#2761)
Signed-off-by: tomsun28 <tomsun28@outlook.com>
2024-10-07 19:45:57 +08:00
Zhang Yuxuan bad49ce17e [doc] fix JDK download mirror link (#2756) 2024-09-29 19:25:53 +08:00
puruidongandtomsun28 64c68a4593 [doc] fix error jdk download link (#2752)
Signed-off-by: puruidong <pruidong@gmail.com>
Signed-off-by: tomsun28 <tomsun28@outlook.com>
Co-authored-by: tomsun28 <tomsun28@outlook.com>
2024-09-28 16:01:15 +08:00
cc47db793f [Improve] Fix cannot upload test report in the PR (#2748)
Co-authored-by: Zhang Yuxuan <1373529784@qq.com>
Co-authored-by: shown <yuluo08290126@gmail.com>
Co-authored-by: aias00 <rokkki@163.com>
2024-09-25 22:25:45 +08:00
108cc4db5a [fix] Threshold Rules search i18n error (#2692) (#2736)
Co-authored-by: keaifa <keaifafafa@gmail.com>
Co-authored-by: shown <yuluo08290126@gmail.com>
Co-authored-by: aias00 <rokkki@163.com>
2024-09-25 09:21:47 +08:00
7e3d009536 [improve] remove side nav user avatar (#2742)
Co-authored-by: Zhang Yuxuan <1373529784@qq.com>
Co-authored-by: shown <yuluo08290126@gmail.com>
2024-09-24 21:33:18 +08:00
aias00andZhang Yuxuan 5dabc7b7fd [improve] support kanban tablename i18n (#2749)
Signed-off-by: aias00 <liuhongyu@apache.org>
Co-authored-by: Zhang Yuxuan <1373529784@qq.com>
2024-09-24 21:22:11 +08:00
aias00andZhang Yuxuan f2eb663e02 [improve] init default theme (#2741)
Co-authored-by: Zhang Yuxuan <1373529784@qq.com>
2024-09-24 17:50:06 +08:00
Jastandtomsun28 ebe7a6f8fe [Improve] Modify Kafka monitoring execution priority (#2743)
Co-authored-by: tomsun28 <tomsun28@outlook.com>
2024-09-24 11:31:59 +08:00
linDong 163a5a05ed [improve]:Improve plugin (#2744) 2024-09-24 09:38:14 +08:00
ec195c1dbf [feature] support kafka admin monitor (#2733)
Co-authored-by: shown <yuluo08290126@gmail.com>
Co-authored-by: tomsun28 <tomsun28@outlook.com>
2024-09-22 23:16:04 +08:00
tomsun28 5fa88ec577 [release] update collector version 1.6.1 (#2739)
Signed-off-by: tomsun28 <tomsun28@outlook.com>
2024-09-22 17:56:16 +08:00
tomsun28 1e4dd6793e [license] update greptime dependency license (#2738)
Signed-off-by: tomsun28 <tomsun28@outlook.com>
2024-09-22 13:36:53 +08:00
tomsun28 a811b9f6cb [license] add ngx query builder license and update (#2737)
Signed-off-by: tomsun28 <tomsun28@outlook.com>
2024-09-22 12:19:32 +08:00
Logicandaias00 a8790c856b [release] release 1.6.1 rc2 and fix crlf encoding (#2724)
Signed-off-by: Logic <zqr10159@dromara.org>
Co-authored-by: aias00 <rokkki@163.com>
2024-09-22 00:02:28 +08:00
Jast b9fdfbd50e [bugfix] fix code describe (#2734) 2024-09-21 12:51:02 +08:00
tomsun28 85b4a4ef0c [improve] revert modify bin shells (#2735) 2024-09-21 11:37:13 +08:00
aias00 febc911639 [improve] modify bin shells (#2723) 2024-09-19 16:07:39 +08:00
Logic 001e76db4b [improve]Add release windows script and update version. (#2722)
Signed-off-by: Logic <zqr10159@dromara.org>
2024-09-19 10:38:13 +08:00
tomsun28andshown ca27605640 [improve] use post request refresh token (#2720)
Signed-off-by: tomsun28 <tomsun28@outlook.com>
Co-authored-by: shown <yuluo08290126@gmail.com>
2024-09-16 16:24:07 +08:00
tomsun28 06ce10ec3a [bugfix] fix tag select component display and select error (#2719)
Signed-off-by: tomsun28 <tomsun28@outlook.com>
2024-09-16 11:07:17 +08:00
aias00 1c17c7cb44 [improve] support notify auto refresh (#2712) 2024-09-15 10:24:29 +08:00
tomsun28 a34ccdd769 [improve] refactor bulletin impl code (#2714)
Signed-off-by: tomsun28 <tomsun28@outlook.com>
2024-09-15 00:41:18 +08:00
f5a8ebeeca [Improve] module code struct (#2707)
Co-authored-by: Logic <zqr10159@dromara.org>
Co-authored-by: shown <yuluo08290126@gmail.com>
Co-authored-by: aias00 <rokkki@163.com>
2024-09-14 11:16:34 +08:00
Logicandaias00 6c36d1d60a [bugfix] template upload (#2710)
Co-authored-by: aias00 <rokkki@163.com>
2024-09-13 21:36:22 +08:00
aias00andshown 90c027d6cc [bugfix] disallow adding tag with same key same value (#2700)
Co-authored-by: shown <yuluo08290126@gmail.com>
2024-09-13 14:30:13 +08:00
liutianyou c30295cf9c [improve] Increase the priority of configuration initialization (#2709) 2024-09-13 08:10:46 +08:00
Zhang Yuxuan bb0e2ea41c [doc] Add new committer blog (#2708) 2024-09-12 20:14:09 +08:00
16f52d1b6e [bugfix] Allow anonymous access for MongoDB Atlas and standalone instances (#2704)
Co-authored-by: shown <yuluo08290126@gmail.com>
Co-authored-by: aias00 <rokkki@163.com>
2024-09-12 15:14:42 +08:00
ff3139e1de test: add unit test case for the util (#2701)
Co-authored-by: rick <LinuxSuRen@users.noreply.github.com>
Co-authored-by: aias00 <rokkki@163.com>
Co-authored-by: shown <yuluo08290126@gmail.com>
2024-09-12 09:14:05 +08:00
Jast 65639da9c4 [doc] Resolve error link (#2706) 2024-09-12 00:11:24 +08:00
aias00 af0dc23b45 [improve] add new committer blog (#2705) 2024-09-11 17:47:20 +08:00
shown 4b81ae4abf [improve]: extract common constant str (#2698) 2024-09-11 07:32:06 +08:00
Zhang Yuxuan d5fdccf1d2 [doc] Add a new committer (#2699) 2024-09-10 13:29:48 +08:00
4d9900b56b [bugfix] fix search value not clear (#2688)
Co-authored-by: shown <yuluo08290126@gmail.com>
Co-authored-by: Calvin <naruse_shinji@163.com>
2024-09-09 23:00:49 +08:00
liutianyouandLogic dab66d4f16 [doc] update doc for feishu notification (#2694)
Co-authored-by: Logic <zqr10159@dromara.org>
2024-09-09 10:30:49 +08:00
shown cd028d8464 [improve] extract some common methods (#2691)
Signed-off-by: yuluo-yx <yuluo08290126@gmail.com>
2024-09-09 09:13:20 +08:00
c4c56c6f85 [doc] remove personal info (#2685)
Co-authored-by: aias00 <rokkki@163.com>
Co-authored-by: shown <yuluo08290126@gmail.com>
Co-authored-by: tomsun28 <tomsun28@outlook.com>
2024-09-08 17:37:59 +08:00
6a852b2b8d fix: fix e2e unstable (#2684)
Co-authored-by: aias00 <rokkki@163.com>
Co-authored-by: shown <yuluo08290126@gmail.com>
2024-09-08 16:54:08 +08:00
aias00 c153433165 [improve] support kanban set auto refresh Interval (#2686) 2024-09-08 16:36:50 +08:00
aias00 27175ef3ef [bugfix] fix status page unknowing status value (#2689) 2024-09-08 16:32:10 +08:00
tomsun28 c507f952de [doc] add new contributor and committer (#2687)
Signed-off-by: tomsun28 <tomsun28@outlook.com>
2024-09-07 23:57:37 +08:00
liutianyou b00a50a469 [improve] beautify lark notification (#2683) 2024-09-07 10:38:44 +08:00
98354f267e [chore] make the controller response be easy (#2679)
Co-authored-by: rick <LinuxSuRen@users.noreply.github.com>
Co-authored-by: shown <yuluo08290126@gmail.com>
Co-authored-by: aias00 <rokkki@163.com>
2024-09-06 11:26:47 +08:00
tomsun28 9080ccd2ba [bugfix] fix load error when edit monitor and can not update (#2682)
Signed-off-by: tomsun28 <tomsun28@outlook.com>
2024-09-06 08:47:58 +08:00
aias00andshown bd3420c4a7 [bugfix] fix kanban failed to add all selections (#2680)
Signed-off-by: aias00 <liuhongyu@apache.org>
Signed-off-by: aias00 <rokkki@163.com>
Co-authored-by: shown <yuluo08290126@gmail.com>
2024-09-05 22:18:25 +08:00
aias00andshown 7506429fc4 [improve] add kanban auto refresh (#2681)
Co-authored-by: shown <yuluo08290126@gmail.com>
2024-09-05 22:10:47 +08:00
Yzzz e9bfee6e7e [optimize] In a minor issue, the values of max and min are reversed (#2678) 2024-09-05 22:02:41 +08:00
aias00 b8a2e865cd [bugfix] fix monitor edit error (#2677) 2024-09-05 09:21:46 +08:00
liutianyou 83c5a3a08a [fix] error image (#2676) 2024-09-05 08:13:41 +08:00
4b7178af02 test: add more unit tests for the collects (#2671)
Co-authored-by: rick <LinuxSuRen@users.noreply.github.com>
Co-authored-by: aias00 <rokkki@163.com>
Co-authored-by: shown <yuluo08290126@gmail.com>
2024-09-04 19:42:22 +08:00
aias00 1841ed59d8 [bugfix] fix custom dashboard show metrics error (#2675) 2024-09-04 18:42:42 +08:00
aias00andLogic 4080f5f068 [bugfix] clear filters when ok\cancel (#2674)
Co-authored-by: Logic <zqr10159@dromara.org>
2024-09-04 16:47:22 +08:00
aias00andLogic 25ee822c5f [bugfix] filter dashboard metrics (#2673)
Co-authored-by: Logic <zqr10159@dromara.org>
2024-09-04 16:44:37 +08:00
aias00andLogic 969c4a95c5 [bugfix] fix bulletin name check (#2669)
Co-authored-by: Logic <zqr10159@dromara.org>
2024-09-04 16:42:01 +08:00
aias00andLogic a15a106a46 [task] customize dashboard jump to monitor detail (#2668)
Co-authored-by: Logic <zqr10159@dromara.org>
2024-09-04 16:39:58 +08:00
aias00 74ed750860 [bugfix] fix monitor detail display error (#2667) 2024-09-04 16:37:08 +08:00
ef377912ef [improve] improve plugin upload check (#2666)
Co-authored-by: shown <yuluo08290126@gmail.com>
Co-authored-by: Logic <zqr10159@dromara.org>
2024-09-03 23:44:11 +08:00
cb11f11ace [feature] add NVIDIA monitor (#2643)
Co-authored-by: aias00 <rokkki@163.com>
Co-authored-by: shown <yuluo08290126@gmail.com>
Co-authored-by: Calvin <naruse_shinji@163.com>
Co-authored-by: tomsun28 <tomsun28@outlook.com>
2024-09-03 23:38:53 +08:00
589b0d915d [feature]Support grafana charts for Prometheus (#1658)
Signed-off-by: Logic <zqr10159@dromara.org>
Signed-off-by: tomsun28 <tomsun28@outlook.com>
Co-authored-by: tomsun28 <tomsun28@outlook.com>
Co-authored-by: liutianyou <tianyou.liu@qq.com>
Co-authored-by: aias00 <rokkki@163.com>
2024-09-03 23:09:14 +08:00
50a18f2813 [improve] improve markdown format for MD045 (#2658)
Co-authored-by: aias00 <rokkki@163.com>
Co-authored-by: Jast <shenghang@apache.org>
Co-authored-by: shown <yuluo08290126@gmail.com>
2024-09-03 23:00:00 +08:00
86ca715a64 test: add more unit tests for some services (#2653)
Co-authored-by: rick <LinuxSuRen@users.noreply.github.com>
Co-authored-by: shown <yuluo08290126@gmail.com>
Co-authored-by: Calvin <naruse_shinji@163.com>
Co-authored-by: aias00 <rokkki@163.com>
2024-09-03 22:40:51 +08:00
7b886fe72d [doc] Add doc for linux_script and windows_script (#2646)
Co-authored-by: shown <yuluo08290126@gmail.com>
Co-authored-by: aias00 <rokkki@163.com>
2024-09-03 22:26:25 +08:00
9024b2aca2 [improve] improve markdown format for MD033 (#2657)
Co-authored-by: aias00 <rokkki@163.com>
Co-authored-by: Jast <shenghang@apache.org>
2024-09-03 22:06:50 +08:00
JastandCalvin 5cd9590907 [improve] Update ElasticSearch monitoring template. Description supports i18n (#2662)
Co-authored-by: Calvin <naruse_shinji@163.com>
2024-09-03 21:35:14 +08:00
sherry-peng2333 8e38b8ba9b fix the mounting issues in script/docker-compose/hertzbeat-postgresql-victoria-metrics/docker-compose.yaml (#2660)
Signed-off-by: sherry-peng2333 <70619577+sherry-peng2333@users.noreply.github.com>
2024-09-03 16:25:23 +08:00
b_mountainand刘进山 47e632a088 [fix] fix byte type npe. (#2659)
Co-authored-by: 刘进山 <liujs@hsmap.com>
2024-09-03 11:32:05 +08:00
4a691777aa [improve] improve plugin params (#2655)
Co-authored-by: shown <yuluo08290126@gmail.com>
Co-authored-by: Calvin <naruse_shinji@163.com>
2024-09-02 23:31:13 +08:00
wyfvsfyandaias00 ec92f4ee97 translation airflow.md to English (#2656)
Co-authored-by: aias00 <rokkki@163.com>
2024-09-02 23:01:14 +08:00
Jast 714f216470 [improve]improve doc 052 (#2654) 2024-09-02 21:55:42 +08:00
Logic 16cb8f681c [doc]Improve install doc (#2650)
Signed-off-by: Logic <zqr10159@dromara.org>
2024-09-02 21:16:11 +08:00
Calvin 3ec150c586 [improve] improve markdown format for MD003 (#2649) 2024-09-02 08:28:07 +08:00
liutianyouandaias00 31fcb0d839 [improve] added a method to obtain plugin parameters (#2644)
Co-authored-by: aias00 <rokkki@163.com>
2024-09-01 20:13:28 +08:00
Logicandliutianyou 3e1d87b59f Grafana doc (#2647)
Co-authored-by: liutianyou <tianyou.liu@qq.com>
2024-09-01 18:38:28 +08:00
liutianyou 2076693a16 [doc] help doc for mqtt (#2645) 2024-09-01 17:37:11 +08:00
7bb049f2df [improve] improve code (#2523)
Signed-off-by: tomsun28 <tomsun28@outlook.com>
Co-authored-by: YuLuo <yuluo08290126@gmail.com>
Co-authored-by: tomsun28 <tomsun28@outlook.com>
Co-authored-by: aias00 <rokkki@163.com>
2024-09-01 00:00:56 +08:00
shown 19955fa59a [improve] add md-lint command and docs (#2640) 2024-08-31 20:01:47 +08:00
049c0937bc [improve] update thread pool nums policy (#2606)
Signed-off-by: tomsun28 <tomsun28@outlook.com>
Co-authored-by: shown <yuluo08290126@gmail.com>
Co-authored-by: Calvin <naruse_shinji@163.com>
2024-08-31 16:07:36 +08:00
liutianyouandLogic 2763ee4dc4 [doc]update doc for custom plugin (#2245)
Signed-off-by: liutianyou <tianyou.liu@qq.com>
Co-authored-by: Logic <zqr10159@dromara.org>
2024-08-31 09:47:12 +08:00
497fc915c3 test: add unit tests for BulletinController (#2642)
Signed-off-by: rick <LinuxSuRen@users.noreply.github.com>
Co-authored-by: rick <LinuxSuRen@users.noreply.github.com>
Co-authored-by: Calvin <naruse_shinji@163.com>
Co-authored-by: shown <yuluo08290126@gmail.com>
2024-08-30 18:35:44 +08:00
Kerwin Bryant e945c42632 Fixed #2632 (#2638) 2024-08-30 17:26:05 +08:00
Logicandshown 59398bd7c6 [doc]Grafana doc (#2636)
Co-authored-by: shown <yuluo08290126@gmail.com>
2024-08-30 10:24:37 +08:00
liutianyou d49cb37c6f [improve] improve plugin (#2637) 2024-08-30 08:54:03 +08:00
89be682a88 [imporve] Adjustment of parameter verification (#2635)
Co-authored-by: 刘进山 <liujs@hsmap.com>
Co-authored-by: Calvin <naruse_shinji@163.com>
Co-authored-by: shown <yuluo08290126@gmail.com>
2024-08-30 00:06:53 +08:00
aias00andshown 0d73ac6fc4 [improve] support master custom java opts (#2634)
Co-authored-by: shown <yuluo08290126@gmail.com>
2024-08-29 23:27:10 +08:00
17636ed582 [improve] add oceanbase help md (#2619)
Co-authored-by: shown <yuluo08290126@gmail.com>
Co-authored-by: Jast <shenghang@apache.org>
2024-08-29 23:22:56 +08:00
aias00andCalvin 9cb50b7190 [Improve] add valkey help md (#2633)
Co-authored-by: Calvin <naruse_shinji@163.com>
2024-08-29 23:03:17 +08:00
0e49e100d8 [feature] Implement custom parameters for plugins (#2616)
Signed-off-by: liutianyou <tianyou.liu@qq.com>
Co-authored-by: shown <yuluo08290126@gmail.com>
Co-authored-by: Kerwin Bryant <kerwin612@qq.com>
Co-authored-by: Logic <zqr10159@dromara.org>
Co-authored-by: liutianyou <tianyou.liu@qq.com>
2024-08-29 20:33:17 +08:00
Logic 24678c2ca0 [doc] Bulletin doc (#2631) 2024-08-29 12:18:35 +08:00
6074c08e1a [feat] support monitor MQTT connections (#2618)
Co-authored-by: shown <yuluo08290126@gmail.com>
Co-authored-by: Logic <zqr10159@dromara.org>
2024-08-29 11:05:54 +08:00
3eb6fb35f4 [improve]Optimize Hbase Master and Regionserver monitoring (#2624)
Co-authored-by: shown <yuluo08290126@gmail.com>
Co-authored-by: Logic <zqr10159@dromara.org>
2024-08-29 10:55:53 +08:00
liutianyouandLogic 466ac37e66 [fix] fix i8n error in bulletin (#2627)
Co-authored-by: Logic <zqr10159@dromara.org>
2024-08-29 10:10:07 +08:00
aias00andshown a5bc6327f9 [Improve] translate redis help md (#2621)
Co-authored-by: shown <yuluo08290126@gmail.com>
2024-08-28 22:59:57 +08:00
aias00andshown 2e9021a12d [improve] translate pop3 help md (#2622)
Co-authored-by: shown <yuluo08290126@gmail.com>
2024-08-28 22:37:43 +08:00
Jast 1dd08b8b19 [improve]Centos network card information monitoring optimization (#2626) 2024-08-28 22:05:37 +08:00
6117396377 [imporve] null judge modify. (#2558)
Co-authored-by: 刘进山 <liujs@hsmap.com>
Co-authored-by: YuLuo <yuluo08290126@gmail.com>
Co-authored-by: Calvin <naruse_shinji@163.com>
Co-authored-by: tomsun28 <tomsun28@outlook.com>
2024-08-27 23:54:50 +08:00
d71b9aa048 simplify the convertUnit (#2595)
Co-authored-by: tomsun28 <tomsun28@outlook.com>
Co-authored-by: Eric <247677858@qq.com>
Co-authored-by: shown <yuluo08290126@gmail.com>
2024-08-27 22:01:44 +08:00
tomsun28andshown 525980f919 [webapp] bugfix monitors pageable not work (#2602)
Signed-off-by: tomsun28 <tomsun28@outlook.com>
Co-authored-by: shown <yuluo08290126@gmail.com>
2024-08-27 11:02:58 +08:00
6e430bcab6 Add push dao unit tests (#2614)
Co-authored-by: I744506 <temirlan.basitov@sap.com>
Co-authored-by: shown <yuluo08290126@gmail.com>
2024-08-27 11:01:16 +08:00
shown 12a53c69da [optimize]: update github action (#2608)
Signed-off-by: yuluo-yx <yuluo08290126@gmail.com>
Signed-off-by: shown <yuluo08290126@gmail.com>
2024-08-27 10:44:04 +08:00
Jastandshown 1799e00ec9 [doc]markdown md046 (#2613)
Co-authored-by: shown <yuluo08290126@gmail.com>
2024-08-27 10:40:05 +08:00
5d416e855b [Feature] Supports Bulletin to view all metrics. (#2584)
Signed-off-by: tomsun28 <tomsun28@outlook.com>
Co-authored-by: YuLuo <yuluo08290126@gmail.com>
Co-authored-by: tomsun28 <tomsun28@outlook.com>
Co-authored-by: kerwin612 <kerwin612@qq.com>
2024-08-27 06:25:38 +08:00
tomsun28andshown 5eef247a5b [improve] enable and fix test src checkstyle (#2610)
Signed-off-by: tomsun28 <tomsun28@outlook.com>
Co-authored-by: shown <yuluo08290126@gmail.com>
2024-08-26 19:13:16 +08:00
Jast 77f725cf42 [fixbug]Fixbug kafka version display (#2609) 2024-08-26 17:03:56 +08:00
shownandJast b7969e78c9 [improve]: enable md040 rules (#2607)
Signed-off-by: yuluo-yx <yuluo08290126@gmail.com>
Co-authored-by: Jast <shenghang@apache.org>
2024-08-26 13:10:13 +08:00
2f4343c453 [Improve] improve markdown format for MD029 (#2604)
Co-authored-by: shown <yuluo08290126@gmail.com>
Co-authored-by: Jast <shenghang@apache.org>
2024-08-26 10:02:21 +08:00
857e4118f0 [improve] Improve markdown md035 (#2592)
Co-authored-by: tomsun28 <tomsun28@outlook.com>
Co-authored-by: shown <yuluo08290126@gmail.com>
2024-08-26 09:27:40 +08:00
Gao Jianandshown c3ffad76ca [fixbug]: Fix Redfish protocol parse bug (#2597)
Co-authored-by: shown <yuluo08290126@gmail.com>
2024-08-25 19:01:40 +08:00
tomsun28andshown 102c72bcc6 [doc] fix markdown lint md013 check (#2599)
Co-authored-by: shown <yuluo08290126@gmail.com>
2024-08-25 18:46:01 +08:00
tomsun28 88aeb9fc21 [bugfix] fix alarm recover not match in converge reduce in some condition (#2603)
Signed-off-by: tomsun28 <tomsun28@outlook.com>
2024-08-25 18:24:10 +08:00
crossoverJie 20f89f3b3b [Improve]Temporarily disable import sort (#2601) 2024-08-25 12:16:18 +08:00
aias00 7facbe827c [improve] improve md format MD025 (#2587) 2024-08-25 09:30:43 +08:00
e3a1b8345f [improve] improve markdown format for MD047 (#2586)
Co-authored-by: YuLuo <yuluo08290126@gmail.com>
Co-authored-by: Jast <admin@hadoop.wiki>
2024-08-24 07:52:56 +08:00
0f0f00c700 [feature] manage dependencies version by parent pom (#2571)
Co-authored-by: Calvin <naruse_shinji@163.com>
Co-authored-by: YuLuo <yuluo08290126@gmail.com>
2024-08-23 23:06:49 +08:00
Kerwin Bryant 51699e34cd [webapp] fix #2244 and update detail ui (#2590) 2024-08-23 17:27:34 +08:00
Jast 343afd517d [Improve] improve markdown format for MD041 (#2588) 2024-08-23 11:33:06 +08:00
tomsun28andJast b602d8ceb6 [Improve] remove 1.4 version doc and improve markdown format for MD001 (#2585)
Co-authored-by: Jast <admin@hadoop.wiki>
2024-08-23 09:26:56 +08:00
bad28bccdb [improve] extra project configuration common filed to constants (#2540)
Signed-off-by: yuluo-yx <yuluo08290126@gmail.com>
Co-authored-by: Calvin <naruse_shinji@163.com>
Co-authored-by: tomsun28 <tomsun28@outlook.com>
2024-08-22 23:49:02 +08:00
aias00 eea68d2a27 [feature] add greenplum help md (#2570)
Signed-off-by: aias00 <rokkki@163.com>
2024-08-22 23:13:19 +08:00
Jastandtomsun28 fff291da82 [Improve] improve markdown format for MD024 (#2580)
Co-authored-by: tomsun28 <tomsun28@outlook.com>
2024-08-22 22:53:48 +08:00
aias00 97aada9956 [feature] add vastbase help md (#2569)
Signed-off-by: aias00 <rokkki@163.com>
2024-08-22 16:48:43 +08:00
Jastandtomsun28 d056ce2aa6 [feature] support dead link check (#2579)
Co-authored-by: tomsun28 <tomsun28@outlook.com>
2024-08-21 23:19:14 +08:00
c2d92eb57d [Improve] improve doc check (#2572)
Co-authored-by: YuLuo <yuluo08290126@gmail.com>
Co-authored-by: tomsun28 <tomsun28@outlook.com>
Co-authored-by: Calvin <naruse_shinji@163.com>
2024-08-21 23:06:39 +08:00
4dceb42dc7 [feature] add iceberg help md (#2573)
Co-authored-by: Calvin <naruse_shinji@163.com>
Co-authored-by: YuLuo <yuluo08290126@gmail.com>
2024-08-21 19:53:26 +08:00
YuLuoandtomsun28 1fac6ab2fa [e2e] add some configuration args to observation atest running status (#2565)
Signed-off-by: yuluo-yx <yuluo08290126@gmail.com>
Co-authored-by: tomsun28 <tomsun28@outlook.com>
2024-08-21 18:52:01 +08:00
235df8bca1 [feature] add kvrocks template (#2564)
Co-authored-by: YuLuo <yuluo08290126@gmail.com>
Co-authored-by: tomsun28 <tomsun28@outlook.com>
2024-08-21 18:29:20 +08:00
YuLuoandtomsun28 603bc3222a chore: rename push service unit test class name (#2562)
Signed-off-by: yuluo-yx <yuluo08290126@gmail.com>
Co-authored-by: tomsun28 <tomsun28@outlook.com>
2024-08-21 17:54:20 +08:00
tomsun28andYuLuo a1d73a292c [webapp] auto resize the monitor detail ui width (#2577)
Signed-off-by: tomsun28 <tomsun28@outlook.com>
Co-authored-by: YuLuo <yuluo08290126@gmail.com>
2024-08-21 13:39:39 +08:00
aias00 bdfffeec4c [bugfix] fix kingbase spotless apply (#2575) 2024-08-21 10:54:54 +08:00
aias00 bc47768bfb [feature] add kingbase help md (#2568) 2024-08-20 23:57:09 +08:00
Jastandtomsun28 98b03b62c7 [doc] update doc style check (#2560)
Co-authored-by: tomsun28 <tomsun28@outlook.com>
2024-08-20 00:31:51 +08:00
Jast ceab3023b1 [improve] linux chart display (#2559) 2024-08-19 22:25:24 +08:00
Jastandtomsun28 a49fa3d91b [fixbug] Fixbug doc format temporary process (#2557)
Co-authored-by: tomsun28 <tomsun28@outlook.com>
2024-08-19 14:24:05 +08:00
5d87275206 [improve] support plugins using other jar (#2553)
Co-authored-by: YuLuo <yuluo08290126@gmail.com>
Co-authored-by: Logic <zqr10159@dromara.org>
2024-08-19 12:36:51 +08:00
a2bd61947b [imporve] move ai package and improve ai code. (#2542)
Co-authored-by: 刘进山 <liujs@hsmap.com>
Co-authored-by: YuLuo <yuluo08290126@gmail.com>
Co-authored-by: linDong <56677297@qq.com>
Co-authored-by: Calvin <naruse_shinji@163.com>
2024-08-19 00:48:34 +08:00
b_mountainandCalvin 7ac21d3171 [improve] Add GeneralConfigTypeEnum. (#2555)
Co-authored-by: Calvin <naruse_shinji@163.com>
2024-08-19 00:41:49 +08:00
YuLuo 4fdc048287 [doc] add new committer docs (#2554)
Signed-off-by: yuluo-yx <yuluo08290126@gmail.com>
2024-08-18 22:53:58 +08:00
tomsun28andYuLuo e10e4b2d8d [improve] fix docker compose package script and update contributor doc (#2552)
Signed-off-by: tomsun28 <tomsun28@outlook.com>
Co-authored-by: YuLuo <yuluo08290126@gmail.com>
2024-08-18 16:45:06 +08:00
aias00andYuLuo 27d66a11c1 [type:feature] add greptimedb template (#2551)
Co-authored-by: YuLuo <yuluo08290126@gmail.com>
2024-08-18 16:36:00 +08:00
YuLuo 19c7d84e53 [infra] remove redundant security bug reporting options (#2550)
Signed-off-by: yuluo-yx <yuluo08290126@gmail.com>
2024-08-18 15:42:35 +08:00
aias00andYuLuo 031e83d701 [bugfix] clear qbdata when cascade change (#2545)
Co-authored-by: YuLuo <yuluo08290126@gmail.com>
2024-08-18 09:30:09 +08:00
aias00andCalvin 5b50307e8c [feature] add valkey template (#2547)
Co-authored-by: Calvin <naruse_shinji@163.com>
2024-08-18 07:33:26 +08:00
Logic 4f7ba7355f Add Contributors' chart (#2548) 2024-08-17 23:04:15 +08:00
aias00andYuLuo 4733ac2eba [bugfix] fix monitor search sync error (#2546)
Co-authored-by: YuLuo <yuluo08290126@gmail.com>
2024-08-17 17:38:21 +08:00
YuLuo e157d82a18 [infra] update actions checkout version to 4 (#2544)
Signed-off-by: yuluo-yx <yuluo08290126@gmail.com>
2024-08-17 15:26:03 +08:00
YuLuo f1a123ee76 [chore] fix typo (#2543)
Signed-off-by: yuluo-yx <yuluo08290126@gmail.com>
2024-08-17 10:14:13 +08:00
584b70a726 [improve] delete deprecate field (#2537)
Co-authored-by: YuLuo <yuluo08290126@gmail.com>
Co-authored-by: tomsun28 <tomsun28@outlook.com>
2024-08-17 00:18:22 +08:00
tomsun28andYuLuo 9d62270131 [improve] auto generate readable random monitor name (#2531)
Signed-off-by: tomsun28 <tomsun28@outlook.com>
Co-authored-by: YuLuo <yuluo08290126@gmail.com>
2024-08-17 00:04:19 +08:00
53a506569a [improve]ElasticSearch historical chart display optimization (#2535)
Co-authored-by: tomsun28 <tomsun28@outlook.com>
Co-authored-by: YuLuo <yuluo08290126@gmail.com>
2024-08-16 23:56:02 +08:00
0ec6a3b6ba [imporve] simplify NoticeConfig Code. (#2530)
Co-authored-by: 刘进山 <liujs@hsmap.com>
Co-authored-by: Calvin <naruse_shinji@163.com>
2024-08-16 22:03:55 +08:00
kangliandtomsun28 c8560e6b16 [bugfix] webhook template json escape (#2532)
Co-authored-by: tomsun28 <tomsun28@outlook.com>
2024-08-16 17:49:57 +08:00
YuLuoandCalvin 361e573d8e [optimize] use okhttpclient connection pool (#2529)
Signed-off-by: yuluo-yx <yuluo08290126@gmail.com>
Co-authored-by: Calvin <naruse_shinji@163.com>
2024-08-16 10:49:43 +08:00
tomsun28 c12b4c0d84 [bugfix] fix github action build docker image error (#2525)
Signed-off-by: tomsun28 <tomsun28@outlook.com>
2024-08-15 21:10:55 +08:00
tomsun28 9b065f7ec0 [infra] support build and push docker image to hub nightly everyday (#2517) 2024-08-14 00:17:35 +08:00
tomsun28 ffa81a68f7 [infra] add sub git module hertzbeat-helm-chart (#2522) 2024-08-14 00:14:30 +08:00
Calvin ed21cc3a94 [improve] fix spotless check failed (#2521) 2024-08-13 22:29:56 +08:00
35616d2763 [improve] add windows i18n (#2513)
Co-authored-by: tomsun28 <tomsun28@outlook.com>
Co-authored-by: Calvin <naruse_shinji@163.com>
2024-08-13 14:19:08 +08:00
Jast fbb74199c9 [feature] add markdown formatter (#2519) 2024-08-13 14:16:41 +08:00
YuLuoandCalvin 3a2350b86d [improve] add MemoryDataStorage unit test (#2515)
Signed-off-by: yuluo-yx <yuluo08290126@gmail.com>
Co-authored-by: Calvin <naruse_shinji@163.com>
2024-08-12 23:34:08 +08:00
YuLuoandtomsun28 b39602f15d [improve] add MetricsDataRedisCodec unit test (#2514)
Signed-off-by: yuluo-yx <yuluo08290126@gmail.com>
Co-authored-by: tomsun28 <tomsun28@outlook.com>
2024-08-12 23:28:22 +08:00
Jastandtomsun28 86c7c2dadf [Improve]add presto monitor metric (#2516)
Co-authored-by: tomsun28 <tomsun28@outlook.com>
2024-08-12 23:26:32 +08:00
aias00andtomsun28 ddfa60e597 [improve] add spring tidb i18n (#2512)
Co-authored-by: tomsun28 <tomsun28@outlook.com>
2024-08-12 23:04:48 +08:00
aias00 e34b64062e [improve] add shenyu\spring gateway i18n (#2511) 2024-08-12 22:56:46 +08:00
aias00andtomsun28 0634e7bb2e [improve] add redis cluster i18n (#2510)
Co-authored-by: tomsun28 <tomsun28@outlook.com>
2024-08-12 22:51:08 +08:00
aias00andtomsun28 0920910738 [improve] add pulsar push rabbitmq i18n (#2509)
Co-authored-by: tomsun28 <tomsun28@outlook.com>
2024-08-12 22:45:40 +08:00
aias00andtomsun28 8ae4d0e2d3 [improve] add oracle i18n (#2508)
Co-authored-by: tomsun28 <tomsun28@outlook.com>
2024-08-12 22:07:31 +08:00
aias00 1c5b3f9c3f [improve] add kafka influxdb jetty i18n (#2507) 2024-08-12 21:14:33 +08:00
YuLuoandtomsun28 a55a098983 [improve] Replacing characters with http constants (#2500)
Signed-off-by: yuluo-yx <yuluo08290126@gmail.com>
Co-authored-by: tomsun28 <tomsun28@outlook.com>
2024-08-12 08:00:17 +08:00
aias00andliutianyou a8c1c48390 [improve] add more yml i18n (#2505)
Co-authored-by: liutianyou <tianyou.liu@qq.com>
2024-08-12 07:46:24 +08:00
aias00andtomsun28 9f7be0292a [improve] add hertzbeat i18n (#2506)
Co-authored-by: tomsun28 <tomsun28@outlook.com>
2024-08-11 22:12:27 +08:00
aias00andtomsun28 3250bc714d [improve] add hive i18n (#2504)
Co-authored-by: tomsun28 <tomsun28@outlook.com>
2024-08-11 22:06:03 +08:00
YuLuoandtomsun28 3d3d881722 [improve] add ObjectStoreConfigServiceImpl unit test (#2502)
Signed-off-by: yuluo-yx <yuluo08290126@gmail.com>
Co-authored-by: tomsun28 <tomsun28@outlook.com>
2024-08-11 16:44:53 +08:00
aias00 3c01298e86 [feature] add iceberg template (#2503) 2024-08-11 16:00:48 +08:00
YuLuo c650972f3d [improve] add AccountServiceImpl unit test (#2501)
Signed-off-by: yuluo-yx <yuluo08290126@gmail.com>
2024-08-11 11:21:15 +08:00
YuLuoandtomsun28 df4272a2f8 [bugfix] fix unit test errors in different languages. (#2498)
Signed-off-by: yuluo-yx <yuluo08290126@gmail.com>
Co-authored-by: tomsun28 <tomsun28@outlook.com>
2024-08-10 09:16:14 +08:00
23d16ae921 [refactor] move code from CollectorController to CollectorService (#2433)
Co-authored-by: ceekay <chandrakant.vankayalapati@github.com>
Co-authored-by: Calvin <naruse_shinji@163.com>
2024-08-09 23:42:12 +08:00
tomsun28andKerwin Bryant aeac1ffed4 [bugfix] fix alarm threshold ava can not modify (#2494)
Signed-off-by: tomsun28 <tomsun28@outlook.com>
Co-authored-by: Kerwin Bryant <kerwin612@qq.com>
2024-08-09 17:09:31 +08:00
YuLuoandtomsun28 bac607f6dd [Improve] add WarehouseServiceImpl unit test (#2497)
Signed-off-by: yuluo-yx <yuluo08290126@gmail.com>
Co-authored-by: tomsun28 <tomsun28@outlook.com>
2024-08-08 23:55:45 +08:00
YuLuoandtomsun28 8faa13e7b4 [Improve] add AvailableAlertDefineIni & SystemSecretServiceImpl unit test (#2496)
Signed-off-by: yuluo-yx <yuluo08290126@gmail.com>
Co-authored-by: tomsun28 <tomsun28@outlook.com>
2024-08-08 23:03:24 +08:00
tomsun28andcrossoverJie 3113487192 [refactor] refactor connect common cache (#2469)
Signed-off-by: tomsun28 <tomsun28@outlook.com>
Co-authored-by: crossoverJie <crossoverJie@gmail.com>
2024-08-08 22:35:51 +08:00
liutianyouandtomsun28 7a7d4792cd [improve] remove demo plugin (#2492)
Co-authored-by: tomsun28 <tomsun28@outlook.com>
2024-08-08 20:41:08 +08:00
YuLuoandtomsun28 ec8cc517d1 [Improve] add SystemGeneralConfigServiceImpl & SmsGeneralConfigServiceImpl unit test (#2490)
Signed-off-by: yuluo-yx <yuluo08290126@gmail.com>
Co-authored-by: tomsun28 <tomsun28@outlook.com>
2024-08-07 23:31:24 +08:00
YuLuoandtomsun28 12fee7fb01 [improve] add StatusPageServiceImpl unit test (#2491)
Signed-off-by: yuluo-yx <yuluo08290126@gmail.com>
Co-authored-by: tomsun28 <tomsun28@outlook.com>
2024-08-07 23:21:03 +08:00
YuLuoandtomsun28 339a33a0bd [Improve] add ObsObjectStoreServiceImpl unit test (#2488)
Signed-off-by: yuluo-yx <yuluo08290126@gmail.com>
Co-authored-by: tomsun28 <tomsun28@outlook.com>
2024-08-07 23:18:24 +08:00
aias00 e3a0fb4537 [improve] add vastbase template (#2487) 2024-08-07 23:16:46 +08:00
YuLuoandtomsun28 9b328ce34c [Improve] add unit test & fix some bugs (#2482)
Signed-off-by: yuluo-yx <yuluo08290126@gmail.com>
Co-authored-by: tomsun28 <tomsun28@outlook.com>
2024-08-07 16:32:38 +08:00
YuLuoandtomsun28 e8dc6482ff [improve] add YamlImExportServiceImpl unit test (#2470)
Signed-off-by: yuluo-yx <yuluo08290126@gmail.com>
Co-authored-by: tomsun28 <tomsun28@outlook.com>
2024-08-07 09:18:36 +08:00
c4fa738d65 [improve] add some code style improve (#2481)
Co-authored-by: Calvin <naruse_shinji@163.com>
Co-authored-by: tomsun28 <tomsun28@outlook.com>
2024-08-07 09:09:16 +08:00
6ac092dcd5 [improve] use file constant & extract file utils (#2474)
Signed-off-by: yuluo-yx <yuluo08290126@gmail.com>
Co-authored-by: Calvin <naruse_shinji@163.com>
Co-authored-by: tomsun28 <tomsun28@outlook.com>
2024-08-06 22:15:26 +08:00
YuLuoandtomsun28 fe403ed880 [improve] add TemplateConfigServiceImpl unit test (#2471)
Signed-off-by: yuluo-yx <yuluo08290126@gmail.com>
Co-authored-by: tomsun28 <tomsun28@outlook.com>
2024-08-06 21:49:31 +08:00
kangliandCalvin d6b19691fb [refactor] move code from MetricsDataController to MetricsService (#2437)
Co-authored-by: Calvin <naruse_shinji@163.com>
2024-08-06 21:07:53 +08:00
aias00 c2c00d44c7 [doc] fix md index order and typo (#2480) 2024-08-06 19:10:23 +08:00
YuLuo e9da2d2925 [Improve] add push module controller unit test (#2451)
Signed-off-by: yuluo-yx <yuluo08290126@gmail.com>
Signed-off-by: YuLuo <yuluo08290126@gmail.com>
2024-08-06 10:57:31 +08:00
tomsun28 58e6e1a2a7 [improve] optimize collect thread prevent cpu idling (#2468)
Signed-off-by: tomsun28 <tomsun28@outlook.com>
2024-08-06 10:17:14 +08:00
YuLuoandCalvin 0c2cc59b55 [chore] add service test tmpl file (#2472)
Signed-off-by: yuluo-yx <yuluo08290126@gmail.com>
Co-authored-by: Calvin <naruse_shinji@163.com>
2024-08-06 00:37:55 +08:00
kangliandCalvin 111f0f6b99 [refactor] move code from AlertSilencesController to AlertSilenceService (#2436)
Co-authored-by: Calvin <naruse_shinji@163.com>
2024-08-06 00:03:43 +08:00
e560502d8e [refactor] move code from AlertsController to AlertService (#2435)
Co-authored-by: tomsun28 <tomsun28@outlook.com>
Co-authored-by: Calvin <naruse_shinji@163.com>
2024-08-05 23:52:40 +08:00
YuLuoandtomsun28 67983c2702 [Improve] add JsonImExportServiceImpl unit test (#2461)
Signed-off-by: yuluo-yx <yuluo08290126@gmail.com>
Co-authored-by: tomsun28 <tomsun28@outlook.com>
2024-08-05 15:42:54 +08:00
YuLuoandtomsun28 033240341b [Improve] add ExcelImExportServiceImpl unit test (#2460)
Signed-off-by: yuluo-yx <yuluo08290126@gmail.com>
Co-authored-by: tomsun28 <tomsun28@outlook.com>
2024-08-05 15:36:33 +08:00
YuLuoandtomsun28 35a8ec4275 [Improve] add AiServiceFactoryImpl unit test (#2459)
Signed-off-by: yuluo-yx <yuluo08290126@gmail.com>
Co-authored-by: tomsun28 <tomsun28@outlook.com>
2024-08-05 15:10:31 +08:00
linDongandtomsun28 9ac45ab343 [improve] use constant (#2458)
Co-authored-by: tomsun28 <tomsun28@outlook.com>
2024-08-05 15:07:38 +08:00
aias00andtomsun28 4b5a97044c [improve] add missed field i18n (#2465)
Co-authored-by: tomsun28 <tomsun28@outlook.com>
2024-08-05 14:37:05 +08:00
lingluojunandtomsun28 477af0959f [refactor] extracting common function for KafkaCommonDataQueue (#2453)
Co-authored-by: tomsun28 <tomsun28@outlook.com>
2024-08-05 12:34:18 +08:00
YuLuoandtomsun28 a5b8f59242 feat fix log upload, when e2e fails it still uploads (#2464)
Signed-off-by: yuluo-yx <yuluo08290126@gmail.com>
Co-authored-by: tomsun28 <tomsun28@outlook.com>
2024-08-05 12:00:27 +08:00
linDongandtomsun28 98b8d95b92 [improve] : Optimize queues to obtain data and prevent cpu idling (#2466)
Co-authored-by: tomsun28 <tomsun28@outlook.com>
2024-08-05 11:42:07 +08:00
kangliandCalvin c0ef4a436e [refactor] move code from AlertConvergesController to AlertConvergeService (#2428)
Co-authored-by: Calvin <naruse_shinji@163.com>
2024-08-04 23:54:43 +08:00
kangliandCalvin 254421bc46 [refactor] move code from AlertReportController to AlertService (#2434)
Co-authored-by: Calvin <naruse_shinji@163.com>
2024-08-04 23:37:52 +08:00
Jast deb827a572 [doc] Add zookeeper doc (#2456)
merge
2024-08-04 19:22:54 +08:00
YuLuoandtomsun28 7eef0c21f1 [Improve] add push module service unit test (#2452)
Signed-off-by: yuluo-yx <yuluo08290126@gmail.com>
Co-authored-by: tomsun28 <tomsun28@outlook.com>
2024-08-04 00:00:49 +08:00
YuLuoandtomsun28 58920978c3 [Improve] add StatusPagesController & StatusPagePublicController unit test (#2446)
Signed-off-by: yuluo-yx <yuluo08290126@gmail.com>
Co-authored-by: tomsun28 <tomsun28@outlook.com>
2024-08-03 23:59:35 +08:00
YuLuoandtomsun28 a4c6a6045f [Improve] add MetricsController unit test (#2445)
Signed-off-by: yuluo-yx <yuluo08290126@gmail.com>
Co-authored-by: tomsun28 <tomsun28@outlook.com>
2024-08-03 23:54:40 +08:00
YuLuoandtomsun28 6e47da758e [Improve] add GeneralConfigController unit test (#2444)
Signed-off-by: yuluo-yx <yuluo08290126@gmail.com>
Co-authored-by: tomsun28 <tomsun28@outlook.com>
2024-08-03 23:53:19 +08:00
YuLuoandtomsun28 ae03111a75 [Improve] add AiController unit test (#2443)
Signed-off-by: yuluo-yx <yuluo08290126@gmail.com>
Co-authored-by: tomsun28 <tomsun28@outlook.com>
2024-08-03 23:47:24 +08:00
lingluojunandtomsun28 69b8db7048 [improve] remove useless invoke method (#2450)
Co-authored-by: tomsun28 <tomsun28@outlook.com>
2024-08-03 23:32:46 +08:00
aias00andtomsun28 de657f9144 [improve] add i18n for postgresql kingbase greenplum (#2448)
Co-authored-by: tomsun28 <tomsun28@outlook.com>
2024-08-03 23:26:36 +08:00
YuLuoandtomsun28 822825b614 [improve] add TimeZoneListener test (#2432)
Signed-off-by: yuluo-yx <yuluo08290126@gmail.com>
Co-authored-by: tomsun28 <tomsun28@outlook.com>
2024-08-03 23:20:24 +08:00
YuLuoandtomsun28 7672502c3d [Improve] add AlertSerializer & AlertDeserializer unit test (#2430)
Signed-off-by: yuluo-yx <yuluo08290126@gmail.com>
Co-authored-by: tomsun28 <tomsun28@outlook.com>
2024-08-03 18:19:30 +08:00
YuLuo 598ed2ea16 [ci] add e2e logs to debug e2e test & delete unnecessary files (#2447)
Signed-off-by: yuluo-yx <yuluo08290126@gmail.com>
2024-08-03 18:10:07 +08:00
kangliandCalvin aee969a18a [refactor] move code from AlertDefinesController to AlertDefineService (#2429)
Co-authored-by: Calvin <naruse_shinji@163.com>
2024-08-02 23:15:45 +08:00
YuLuoandtomsun28 b0438da537 [Improve] add KafkaMetricsDataSerializer & KafkaMetricsDataDeserializer unit test (#2431)
Signed-off-by: yuluo-yx <yuluo08290126@gmail.com>
Co-authored-by: tomsun28 <tomsun28@outlook.com>
2024-08-02 18:01:53 +08:00
aias00 c85e182119 [feature] add greenplum template (#2442) 2024-08-02 17:12:40 +08:00
aias00 7446d3ebbf [feature] add oceanbase template (#2439) 2024-08-02 12:04:18 +08:00
YuLuoandtomsun28 f6e8e64e23 [Improve] add AlertSilenceController unit test (#2425)
Signed-off-by: yuluo-yx <yuluo08290126@gmail.com>
Co-authored-by: tomsun28 <tomsun28@outlook.com>
2024-08-02 10:34:55 +08:00
Jast 2a3f4dfa80 [Improve] script command blacklist (#2438) 2024-08-02 10:05:10 +08:00
YuLuoandtomsun28 3d99835487 [Improve] add AlertConvergesController & AlertConvergeController unit test (#2424)
Signed-off-by: yuluo-yx <yuluo08290126@gmail.com>
Co-authored-by: tomsun28 <tomsun28@outlook.com>
2024-08-01 10:31:18 +08:00
YuLuoandtomsun28 3a7d5829ad [Improve] add AlarmCommonReduce unit test (#2412)
Signed-off-by: yuluo-yx <yuluo08290126@gmail.com>
Signed-off-by: YuLuo <yuluo08290126@gmail.com>
Co-authored-by: tomsun28 <tomsun28@outlook.com>
2024-08-01 10:16:26 +08:00
kangliandtomsun28 51b1a9bdc7 [bugfix] fixed jpa expired data clean error (#2329)
Co-authored-by: tomsun28 <tomsun28@outlook.com>
2024-08-01 10:08:11 +08:00
kangliandCalvin 181ca5aa5e [refactor] move code from MonitorsController to MonitorService (#2415)
Co-authored-by: Calvin <naruse_shinji@163.com>
2024-08-01 00:01:11 +08:00
Limboandtomsun28 a5c444a49a [chore] update web-app readme (#2423)
Co-authored-by: tomsun28 <tomsun28@outlook.com>
2024-07-31 19:32:25 +08:00
Kerwin Bryant 2784c8fa6b Optimize the execution efficiency of Gitpod tasks (#2422) 2024-07-31 19:28:31 +08:00
kangliandCalvin ae4a5b1c63 [refactor] move code from GeneralConfigController to ConfigService (#2414)
Co-authored-by: Calvin <naruse_shinji@163.com>
2024-07-31 00:48:10 +08:00
kangliandCalvin c7f4390638 [refactor] move code from NoticeConfigController to NoticeConfigService (#2416)
Co-authored-by: Calvin <naruse_shinji@163.com>
2024-07-31 00:41:40 +08:00
kangliandCalvin c998d3b850 [refactor] move code from PluginController to PluginService (#2417)
Co-authored-by: Calvin <naruse_shinji@163.com>
2024-07-31 00:36:06 +08:00
kangliandCalvin 861e9d377f [refactor] move code from TagController to TagService (#2418)
Co-authored-by: Calvin <naruse_shinji@163.com>
2024-07-31 00:31:08 +08:00
YuLuoandtomsun28 c1252fbe2b [Improve] add AlarmConvergeReduce unit test (#2410)
Signed-off-by: yuluo-yx <yuluo08290126@gmail.com>
Co-authored-by: tomsun28 <tomsun28@outlook.com>
2024-07-30 23:57:51 +08:00
YuLuoandtomsun28 dce9a4b15e [Improve] add AlarmSilenceReduce unit test (#2409)
Signed-off-by: yuluo-yx <yuluo08290126@gmail.com>
Co-authored-by: tomsun28 <tomsun28@outlook.com>
2024-07-30 23:37:13 +08:00
Kerwin Bryant 15768d8077 [infra] support contribute with Gitpod (#2419) 2024-07-30 21:31:09 +08:00
linDongandtomsun28 2824542037 [doc] Fix profile (#2408)
Co-authored-by: tomsun28 <tomsun28@outlook.com>
2024-07-30 18:26:25 +08:00
aias00andtomsun28 f9bce29523 [feature] add sms config (#2399)
Co-authored-by: tomsun28 <tomsun28@outlook.com>
2024-07-30 18:20:00 +08:00
aias00andtomsun28 6b7dbd53f4 [doc] fix mistake md content (#2406)
Co-authored-by: tomsun28 <tomsun28@outlook.com>
2024-07-29 23:27:50 +08:00
aias00andtomsun28 f5e88db841 [improve] modify ssh client common config (#2403)
Co-authored-by: tomsun28 <tomsun28@outlook.com>
2024-07-29 22:46:08 +08:00
kangliandtomsun28 82219d14df [Improve] add database file server provider (#2371)
Co-authored-by: tomsun28 <tomsun28@outlook.com>
2024-07-29 22:30:47 +08:00
Loongandtomsun28 05bce69b84 [collector] bugfix Fix ssh session not closing properly (#2398)
Co-authored-by: tomsun28 <tomsun28@outlook.com>
2024-07-29 20:44:21 +08:00
YuLuoandCalvin bc49280c3c [Improve] add AlertDefineYamlImExportServiceImpl unit test (#2392)
Signed-off-by: yuluo-yx <yuluo08290126@gmail.com>
Co-authored-by: Calvin <naruse_shinji@163.com>
2024-07-29 17:05:17 +08:00
Kerwin Bryant 90035cac5d [doc] introduction document for the new committer (#2401) 2024-07-29 12:26:57 +08:00
YuLuoandCalvin 3487e4a16b [Improve] add AlertDefineJsonImExportServiceImpl unit test (#2391)
Signed-off-by: yuluo-yx <yuluo08290126@gmail.com>
Signed-off-by: YuLuo <yuluo08290126@gmail.com>
Co-authored-by: Calvin <naruse_shinji@163.com>
2024-07-29 01:24:03 +08:00
YuLuoandCalvin 974b27e878 [Improve] add AlertSilenceServiceImpl unit test (#2393)
Signed-off-by: yuluo-yx <yuluo08290126@gmail.com>
Co-authored-by: Calvin <naruse_shinji@163.com>
2024-07-29 01:10:24 +08:00
aias00andtomsun28 22459c5b6f [improve] add some code style improve (#2376)
Signed-off-by: tomsun28 <tomsun28@outlook.com>
Co-authored-by: tomsun28 <tomsun28@outlook.com>
2024-07-28 19:14:04 +08:00
linDongandtomsun28 64e156be2a [doc] add committer introduction doc (#2394)
Co-authored-by: tomsun28 <tomsun28@outlook.com>
2024-07-28 16:58:24 +08:00
Calvinandtomsun28 a9827bbcef [refactor] move code from AccountController to AccountService (#2373)
Co-authored-by: tomsun28 <tomsun28@outlook.com>
2024-07-28 10:35:01 +08:00
Calvinandtomsun28 0ed1355d76 [docs] add new_committer.md (#2390)
Co-authored-by: tomsun28 <tomsun28@outlook.com>
2024-07-28 09:55:01 +08:00
Calvinandtomsun28 0b81717a9e [docs] update img of new_committer_process.md (#2389)
Co-authored-by: tomsun28 <tomsun28@outlook.com>
2024-07-28 09:43:42 +08:00
Kerwin Bryantandtomsun28 86ca62c67a [bugfix] fixed the issue of missing form validation for the "Rule(Expr)" item in the "Threshold" form (#2387)
Co-authored-by: tomsun28 <tomsun28@outlook.com>
2024-07-28 09:32:15 +08:00
YuLuo 7488dfadc9 [Improve] add SmsAlertNotifyHandlerImpl unit test (#2384)
Signed-off-by: yuluo-yx <yuluo08290126@gmail.com>
2024-07-26 22:03:06 +08:00
YuLuoandtomsun28 50fe51bd95 [Improve] add WebHookAlertNotifyHandlerImpl unit test (#2383)
Signed-off-by: yuluo-yx <yuluo08290126@gmail.com>
Co-authored-by: tomsun28 <tomsun28@outlook.com>
2024-07-26 11:55:19 +08:00
aias00andtomsun28 8233a62aea [type:feature] support alerts click to monitor detail (#2385)
Co-authored-by: tomsun28 <tomsun28@outlook.com>
2024-07-26 11:41:35 +08:00
YuLuoandtomsun28 7367b7315b [Improve] add AlertDefineExcel unit test and fix bugs (#2375)
Signed-off-by: yuluo-yx <yuluo08290126@gmail.com>
Co-authored-by: tomsun28 <tomsun28@outlook.com>
2024-07-26 11:33:15 +08:00
tomsun28andCalvin 9e305f7a59 [bugfix] fix monitors alarms some query filter not work, update link (#2382)
Signed-off-by: tomsun28 <tomsun28@outlook.com>
Co-authored-by: Calvin <naruse_shinji@163.com>
2024-07-26 00:03:47 +08:00
YuLuoandtomsun28 3d9be220e6 [Improve] add ServerChanAlertNotifyHandlerImpl unit test (#2381)
Signed-off-by: yuluo-yx <yuluo08290126@gmail.com>
Co-authored-by: tomsun28 <tomsun28@outlook.com>
2024-07-25 22:29:37 +08:00
YuLuoandtomsun28 659346ddd7 [Improve] add CollectServer unit test (#2379)
Signed-off-by: yuluo-yx <yuluo08290126@gmail.com>
Signed-off-by: YuLuo <yuluo08290126@gmail.com>
Co-authored-by: tomsun28 <tomsun28@outlook.com>
2024-07-25 21:47:15 +08:00
kangliandtomsun28 7f0b340663 [bugfix] fix email send error (#2378)
Co-authored-by: tomsun28 <tomsun28@outlook.com>
2024-07-25 21:39:36 +08:00
YuLuo a427099db7 [Improve] add GotifyAlertNotifyHandlerImpl unit test (#2380)
Signed-off-by: yuluo-yx <yuluo08290126@gmail.com>
2024-07-25 21:17:29 +08:00
YuLuoandtomsun28 d1d28e6763 [Improve] add EmailAlertNotifyHandlerImpl unit test (#2370)
Signed-off-by: yuluo-yx <yuluo08290126@gmail.com>
Co-authored-by: tomsun28 <tomsun28@outlook.com>
2024-07-25 10:13:03 +08:00
YuLuoandtomsun28 ba70b2f269 [Improve] add WeComAppAlertNotifyHandlerImpl send notify test (#2369)
Signed-off-by: yuluo-yx <yuluo08290126@gmail.com>
Co-authored-by: tomsun28 <tomsun28@outlook.com>
2024-07-25 08:33:30 +08:00
YuLuoandtomsun28 2352ceef3d [Improve] add dispatchalarm unit test (#2364)
Signed-off-by: yuluo-yx <yuluo08290126@gmail.com>
Co-authored-by: tomsun28 <tomsun28@outlook.com>
2024-07-25 08:14:34 +08:00
YuLuoandtomsun28 927625a79f [Improve] add timezoneutil unit test (#2362)
Signed-off-by: yuluo-yx <yuluo08290126@gmail.com>
Co-authored-by: tomsun28 <tomsun28@outlook.com>
2024-07-25 00:23:17 +08:00
linDongandtomsun28 16a6620ff6 [fix] fix committer name (#2372)
Co-authored-by: tomsun28 <tomsun28@outlook.com>
2024-07-25 00:17:08 +08:00
YuLuoandtomsun28 a1d016e5d5 [Improve] add strbuffer unit test (#2361)
Signed-off-by: yuluo-yx <yuluo08290126@gmail.com>
Co-authored-by: tomsun28 <tomsun28@outlook.com>
2024-07-24 23:55:27 +08:00
Kerwin Bryantandtomsun28 40aa5a4d73 Fixed the issue of style anomaly caused by incorrect usage of nz-card-tab (#2368)
Co-authored-by: tomsun28 <tomsun28@outlook.com>
2024-07-24 23:48:47 +08:00
YuLuoandtomsun28 aef7ac23c4 [Improve] add prometheusUtil unit test (#2360)
Signed-off-by: yuluo-yx <yuluo08290126@gmail.com>
Co-authored-by: tomsun28 <tomsun28@outlook.com>
2024-07-24 23:45:53 +08:00
Zhang Yuxuanandtomsun28 348b50c4c6 [feature] Optimize script protocol and add Windows-script yml template (#2367)
Signed-off-by: Zhang Yuxuan <1373529784@qq.com>
Co-authored-by: tomsun28 <tomsun28@outlook.com>
2024-07-24 23:38:10 +08:00
liutianyouandtomsun28 88538890b4 [doc] supplement custom plugin doc (#2309)
Co-authored-by: tomsun28 <tomsun28@outlook.com>
2024-07-24 23:28:09 +08:00
kangliandtomsun28 fa4a3fd9e1 [imporve] add template i18n map verify (#2345)
Co-authored-by: tomsun28 <tomsun28@outlook.com>
2024-07-24 23:20:44 +08:00
Kerwin Bryantandtomsun28 3a24edb309 Fixed the issue of a fleeting vertical scrollbar appearing in tab-content (#2363)
Co-authored-by: tomsun28 <tomsun28@outlook.com>
2024-07-24 23:11:39 +08:00
aias00andtomsun28 e142a498e2 [improve] upgrade ssh core dependency version (#2349)
Co-authored-by: tomsun28 <tomsun28@outlook.com>
2024-07-24 23:05:53 +08:00
f4685aa75a [bugfix] Unable to specify collector when creating a monitor (#2311)
Co-authored-by: tomsun28 <tomsun28@outlook.com>
Co-authored-by: Logic <zqr10159@dromara.org>
Co-authored-by: Kerwin Bryant <kerwin612@qq.com>
2024-07-24 11:25:25 +08:00
kangliandtomsun28 f038ec5326 [Improve] add CommonUtil unit test (#2346)
Co-authored-by: tomsun28 <tomsun28@outlook.com>
2024-07-24 10:15:05 +08:00
aias00andtomsun28 06186c5ccc [improve] modify Intervals steps (#2348)
Co-authored-by: tomsun28 <tomsun28@outlook.com>
2024-07-24 09:43:25 +08:00
Calvinandtomsun28 6c931956fa [improve] add redis data storage test case (#2356)
Co-authored-by: tomsun28 <tomsun28@outlook.com>
2024-07-24 09:34:25 +08:00
YuLuoandtomsun28 809f679375 [Improve] add DbAlertStoreHandlerImpl unit test (#2353)
Signed-off-by: yuluo-yx <yuluo08290126@gmail.com>
Co-authored-by: tomsun28 <tomsun28@outlook.com>
2024-07-24 09:29:15 +08:00
Logicandtomsun28 b31d8b1380 [bugfix]: correct setInterval time interval to 2 minutes (#2355)
Co-authored-by: tomsun28 <tomsun28@outlook.com>
2024-07-24 00:11:43 +08:00
Kerwin Bryantandtomsun28 1bba56bfbc Optimize the layout of the "Deploy Collector" modal (#2354)
Co-authored-by: tomsun28 <tomsun28@outlook.com>
2024-07-24 00:08:07 +08:00
YuLuoandtomsun28 357068cc8f [Improve] add CollectDispatcher & NettyDataQueue unit test (#2336)
Signed-off-by: yuluo-yx <yuluo08290126@gmail.com>
Signed-off-by: YuLuo <yuluo08290126@gmail.com>
Co-authored-by: tomsun28 <tomsun28@outlook.com>
2024-07-24 00:04:38 +08:00
YuLuoandtomsun28 8a88607be9 [Improve] add collectJonService unit test (#2351)
Signed-off-by: yuluo-yx <yuluo08290126@gmail.com>
Co-authored-by: tomsun28 <tomsun28@outlook.com>
2024-07-23 23:30:44 +08:00
YuLuoandtomsun28 15e9bd0656 [Improve] add redis data queue unit test (#2330)
Signed-off-by: yuluo-yx <yuluo08290126@gmail.com>
Signed-off-by: YuLuo <yuluo08290126@gmail.com>
Co-authored-by: tomsun28 <tomsun28@outlook.com>
2024-07-23 23:13:03 +08:00
Kerwin Bryantandtomsun28 aa58f0af7f Remove the empty footer of "AppSwitchModal" (#2352)
Co-authored-by: tomsun28 <tomsun28@outlook.com>
2024-07-23 22:59:41 +08:00
Kerwin Bryantandtomsun28 115f7b40c5 [bugfix] Fixed an issue of ssl linkage port on the monitoring editing page (#2350)
Co-authored-by: tomsun28 <tomsun28@outlook.com>
2024-07-23 22:56:03 +08:00
aias00andtomsun28 d2c19cbf95 [type:feat] support KingBase database monitor (#2341)
Co-authored-by: tomsun28 <tomsun28@outlook.com>
2024-07-23 22:31:03 +08:00
aias00 173733784b [type:fix] fix threshold rule modal not clear bug (#2340) 2024-07-23 18:50:14 +08:00
Calvinandtomsun28 df4115a64c [refactor] translate chinese into english in web-app (#2343)
Co-authored-by: tomsun28 <tomsun28@outlook.com>
2024-07-23 08:59:56 +08:00
tomsun28 8d34de4422 [doc] update doc and deploy guide and committer (#2342) 2024-07-23 07:51:08 +08:00
aias00andtomsun28 a482d24770 [bugfix] fix i18n null (#2338)
Co-authored-by: tomsun28 <tomsun28@outlook.com>
2024-07-22 23:01:11 +08:00
YuLuoandtomsun28 aee8481204 [Improve] add some unit test (#2334)
Signed-off-by: yuluo-yx <yuluo08290126@gmail.com>
Co-authored-by: tomsun28 <tomsun28@outlook.com>
2024-07-22 22:55:44 +08:00
Kerwin Bryantandtomsun28 497338e00f [bugfix] Fixed an i18n issue (#2332)
Signed-off-by: Kerwin Bryant <kerwin612@qq.com>
Co-authored-by: tomsun28 <tomsun28@outlook.com>
2024-07-22 22:39:10 +08:00
YuLuo e5236259ff [chore] optimize e2e folder struct (#2316)
Signed-off-by: yuluo-yx <yuluo08290126@gmail.com>
Signed-off-by: YuLuo <yuluo08290126@gmail.com>
2024-07-22 22:32:10 +08:00
Calvinandtomsun28 712c54186e [feature] support redis cluster and sentinel mode in real time data (#2324)
Co-authored-by: tomsun28 <tomsun28@outlook.com>
2024-07-21 21:49:24 +08:00
YuLuoandtomsun28 7aa3be8f7d [Improve] add kafak queue unit test (#2317)
Signed-off-by: yuluo-yx <yuluo08290126@gmail.com>
Signed-off-by: YuLuo <yuluo08290126@gmail.com>
Co-authored-by: tomsun28 <tomsun28@outlook.com>
2024-07-21 21:40:53 +08:00
YuLuo f84e1fc5bf [Improve] add unit test & fix some bugs (#2326)
Signed-off-by: yuluo-yx <yuluo08290126@gmail.com>
2024-07-21 21:03:37 +08:00
YuLuoandtomsun28 a8c1921fa3 [Improve] add commonThreadPoll unit test (#2327)
Signed-off-by: yuluo-yx <yuluo08290126@gmail.com>
Co-authored-by: tomsun28 <tomsun28@outlook.com>
2024-07-21 17:33:02 +08:00
aias00andtomsun28 43afb0bc63 [type:fix] fix empty value not be handled by custom metrics (#2323)
Co-authored-by: tomsun28 <tomsun28@outlook.com>
2024-07-21 17:11:02 +08:00
YuLuoandtomsun28 ee9bdf6773 [Improve] add redis data queue impl (#2319)
Signed-off-by: yuluo-yx <yuluo08290126@gmail.com>
Co-authored-by: tomsun28 <tomsun28@outlook.com>
2024-07-21 17:01:18 +08:00
229b4158cc [bugfix]: fix theme is invalidated after refresh (#2321)
Co-authored-by: Keaifa <keaifafafa@gmail.com>
Co-authored-by: tomsun28 <tomsun28@outlook.com>
2024-07-21 16:29:23 +08:00
liutianyou 3d49b288bb [doc] modify the document that uses PostgreSQL to store metadata (#2322) 2024-07-21 15:53:12 +08:00
Zhang Yuxuanandtomsun28 e0caceda92 [feature] Support collector to run scripts directly as agents to collect metrics. (#2313)
Co-authored-by: tomsun28 <tomsun28@outlook.com>
2024-07-20 15:59:05 +08:00
铁甲小宝andtomsun28 0b73e0900b [bugfix] Notice template fix (#2320)
Co-authored-by: tomsun28 <tomsun28@outlook.com>
2024-07-20 15:26:45 +08:00
Kerwin Bryantandtomsun28 1a09611ad6 [feature] Add the editing mode of "complex rule nesting" to support "threshold rules" (#2315)
Co-authored-by: tomsun28 <tomsun28@outlook.com>
2024-07-20 15:03:10 +08:00
jiangshandtomsun28 be0de49646 [manager] collectorApi unit test case and example (#2306)
Co-authored-by: tomsun28 <tomsun28@outlook.com>
2024-07-20 14:46:16 +08:00
YuLuoandtomsun28 061423d301 [chore] Update readme doc style (#2305)
Signed-off-by: yuluo-yx <yuluo08290126@gmail.com>
Co-authored-by: tomsun28 <tomsun28@outlook.com>
2024-07-20 14:25:48 +08:00
YuLuoandtomsun28 6421fef548 [Improve] Optimize spring auto configuration registry (#2304)
Signed-off-by: yuluo-yx <yuluo08290126@gmail.com>
Co-authored-by: tomsun28 <tomsun28@outlook.com>
2024-07-20 10:24:51 +08:00
kangliandtomsun28 70af0669c6 [bugfix] Only POST and PUT methods carry payload (#2302)
Co-authored-by: tomsun28 <tomsun28@outlook.com>
2024-07-19 16:53:29 +08:00
YuLuoandtomsun28 55b3dd7f0c [Improve] Optimize ResourceBundle & add unit test. (#2297)
Signed-off-by: yuluo-yx <yuluo08290126@gmail.com>
Co-authored-by: tomsun28 <tomsun28@outlook.com>
2024-07-19 16:51:19 +08:00
Calvin 91111e5555 [refactor] remove chinese and change code style in Warehouse (#2312) 2024-07-19 16:28:40 +08:00
铁甲小宝 07913e7d51 A small code specification change. (#2299) 2024-07-18 01:01:29 +08:00
YuLuo 38d466b7f8 [Improve] add common/util/StrUtil unit test (#2301)
Signed-off-by: yuluo-yx <yuluo08290126@gmail.com>
2024-07-17 22:36:42 +08:00
tomsun28andliutianyou 9770c9321e [doc] update committer and contributor (#2295)
Signed-off-by: tomsun28 <tomsun28@outlook.com>
Co-authored-by: liutianyou <tianyou.liu@qq.com>
2024-07-17 16:28:29 +08:00
QBH-insist 7e5283ea0d [doc] fix mysql connections field explanation (#2294) 2024-07-17 10:25:42 +08:00
YuLuoandtomsun28 8f659f0fd1 [Improve] add common memory unit test (#2280)
Co-authored-by: tomsun28 <tomsun28@outlook.com>
2024-07-17 09:51:04 +08:00
liutianyouandtomsun28 7a4ee880c3 [doc]add new committer blog (#2291)
Co-authored-by: tomsun28 <tomsun28@outlook.com>
2024-07-16 23:18:53 +08:00
linDong 3b323e1882 [test] add NoticeConfigControllerTest and MonitorsControllerTest test (#2290) 2024-07-16 22:57:02 +08:00
YuLuoandtomsun28 acc617f9bd [Improve] add springContextHolder unit test (#2287)
Signed-off-by: yuluo-yx <yuluo08290126@gmail.com>
Co-authored-by: tomsun28 <tomsun28@outlook.com>
2024-07-16 21:33:50 +08:00
Logic 5585993503 [bugfix] added basic auth support for VictoriaMetrics status check (#2282) 2024-07-16 16:35:44 +08:00
kangliandtomsun28 fd0e216818 [bugfix] fixed self signed certificate detected bug #1534 (#2221)
Co-authored-by: tomsun28 <tomsun28@outlook.com>
2024-07-15 14:57:21 +08:00
999b37ec4f [bugfix] fixed unable to establish a connection to nginx https port bug #1655 (#2218)
Co-authored-by: Logic <zqr10159@dromara.org>
Co-authored-by: tomsun28 <tomsun28@outlook.com>
2024-07-14 23:15:48 +08:00
linDongandtomsun28 823430bca9 [improve] : Modified loading application.yml (#2256)
Co-authored-by: tomsun28 <tomsun28@outlook.com>
2024-07-14 23:04:35 +08:00
Jastandtomsun28 9a7e0411a1 [fixbug]fix parameter parsing problem (#2251)
Co-authored-by: tomsun28 <tomsun28@outlook.com>
2024-07-14 01:10:35 +08:00
CalvinandLogic 3a2e0b3dd2 [feature] support collect data from header (#2266)
Co-authored-by: Logic <zqr10159@dromara.org>
2024-07-13 09:07:58 +08:00
tomsun28andLogic 25d27880aa [doc] update download link doc (#2264)
Signed-off-by: tomsun28 <tomsun28@outlook.com>
Co-authored-by: Logic <zqr10159@dromara.org>
2024-07-13 09:03:02 +08:00
liutianyouandtomsun28 8a11dacdba [bugfix] fix error when delete plugin (#2265)
Co-authored-by: tomsun28 <tomsun28@outlook.com>
2024-07-11 16:04:37 +08:00
Kerwin Bryant 467c595802 Fixed issue of plugin-upload form (#2267) 2024-07-11 15:58:05 +08:00
Kerwin Bryant c70cc5d9b7 Fixed failure of form validation (#2261) 2024-07-10 23:17:02 +08:00
Kerwin Bryant 8f9143001f Fixed failure of alert form validation (#2259) 2024-07-10 16:21:53 +08:00
Kerwin Bryant 3e50b96322 Fixed failure of monitoring form validation (#2258) 2024-07-10 15:42:10 +08:00
Kerwin Bryantandtomsun28 9cf0e6f4ee Decouple tag selection into an independent basic component. (#2257)
Co-authored-by: tomsun28 <tomsun28@outlook.com>
2024-07-09 23:55:48 +08:00
Logicandtomsun28 d47d3be6b4 [docs] Update guides for HertzBeat 1.6.0 upgrade and MySQL driver url (#2255)
Co-authored-by: tomsun28 <tomsun28@outlook.com>
2024-07-09 23:50:10 +08:00
Kerwin Bryant 6cabe3ca0c Further enhance and refine the optimizations implemented in #2215. (#2249)
Signed-off-by: Kerwin Bryant <kerwin612@qq.com>
2024-07-09 16:19:06 +08:00
Kerwin Bryant 874f7bdab3 Optimize the processing logic for Depend-type fields (#2248) 2024-07-09 10:52:12 +08:00
crossoverJieandtomsun28 f90d1e6242 [doc] Rename the blog file. (#2247)
Co-authored-by: tomsun28 <tomsun28@outlook.com>
2024-07-08 23:19:12 +08:00
Jastandtomsun28 afcb0c19fb [doc] add new committer blog (#2246)
Co-authored-by: tomsun28 <tomsun28@outlook.com>
2024-07-08 23:17:41 +08:00
Jastandtomsun28 0e7323fc04 [improve]update doc and prestodb properties (#2243)
Co-authored-by: tomsun28 <tomsun28@outlook.com>
2024-07-08 22:55:19 +08:00
feb60a7da9 [improve] : Optimize refactoring code, and supplement documentation (#2239)
Co-authored-by: tomsun28 <tomsun28@outlook.com>
Co-authored-by: Logic <zqr10159@dromara.org>
2024-07-08 20:28:24 +08:00
linDongandcrossoverJie 2e7616cd56 [test] : Added the AppControllerTest test case (#2237)
Co-authored-by: crossoverJie <crossoverJie@gmail.com>
2024-07-08 19:38:21 +08:00
liutianyouandLogic 2d53abdaab [feature] add plugin management and support plugin hot reloading (#2238)
Signed-off-by: liutianyou <tianyou.liu@qq.com>
Co-authored-by: Logic <zqr10159@dromara.org>
2024-07-08 18:53:49 +08:00
Kerwin BryantandLogic 9fed2c8a36 Optimize the monitor-edit page (#2242)
Co-authored-by: Logic <zqr10159@dromara.org>
2024-07-08 18:27:12 +08:00
Kerwin BryantandLogic a4db859eee For Spring applications, newly added support basic-auth. (#2241)
Co-authored-by: Logic <zqr10159@dromara.org>
2024-07-08 18:24:39 +08:00
linDongandLogic 9a3a2f0a54 [improve] : Delete Chinese comments, modify word errors, add Operatio… (#2236)
Co-authored-by: Logic <zqr10159@dromara.org>
2024-07-08 17:42:47 +08:00
linDongand铁甲小宝 da05b6a151 [feature] Add presto db monitor (#2234)
Co-authored-by: 铁甲小宝 <2922035952@qq.com>
2024-07-08 14:39:38 +08:00
YuLuoandtomsun28 78621f2f14 [Improve] add TimePeriodUtil & ResourceBundleUtil unit test (#2233)
Signed-off-by: yuluo-yx <yuluo08290126@gmail.com>
Co-authored-by: tomsun28 <tomsun28@outlook.com>
2024-07-07 20:50:09 +08:00
crossoverJieandtomsun28 a618ff00ea [doc] Introduce Committer (#2232)
Co-authored-by: tomsun28 <tomsun28@outlook.com>
2024-07-07 20:44:40 +08:00
Calvin 044c6d4bad [e2e] complete e2e test case (#2231) 2024-07-07 20:33:13 +08:00
Calvinandtomsun28 53787cc215 [bugfix] auto config timezone for Jackson (#2122)
Co-authored-by: tomsun28 <tomsun28@outlook.com>
2024-07-07 14:52:13 +08:00
d884278fed [fix] add springboot3.0 autoconfig (#2230)
Co-authored-by: jiawei.guo <18613599970@163.con>
Co-authored-by: tomsun28 <tomsun28@outlook.com>
2024-07-07 09:45:57 +08:00
YuLuoandtomsun28 21a7788522 [Improve] add ProtoJsonUtil unit test (#2228)
Signed-off-by: yuluo-yx <yuluo08290126@gmail.com>
Co-authored-by: tomsun28 <tomsun28@outlook.com>
2024-07-06 23:23:36 +08:00
YuLuoandtomsun28 c7d192996a [Improve] add MapCap & LruMap unit test (#2227)
Signed-off-by: yuluo-yx <yuluo08290126@gmail.com>
Co-authored-by: tomsun28 <tomsun28@outlook.com>
2024-07-06 22:55:58 +08:00
Calvin 78ce1cdc1f [refactor] remove chinese in application.yml (#2226) 2024-07-06 18:43:33 +08:00
tomsun28andLogic 12230b47ca [doc] update new contributors wall (#2225)
Signed-off-by: tomsun28 <tomsun28@outlook.com>
Co-authored-by: Logic <zqr10159@dromara.org>
2024-07-06 09:15:51 +08:00
Jastandtomsun28 753ea44d2b [improve] optimize code structure and doc modify (#2222)
Co-authored-by: tomsun28 <tomsun28@outlook.com>
2024-07-05 23:54:08 +08:00
Logicandtomsun28 c3faea07c2 [improve] WeCom app supports sending to specific users, departments, tags (#2220)
Co-authored-by: tomsun28 <tomsun28@outlook.com>
2024-07-05 23:37:31 +08:00
mchgood 4149a027a7 [Improve] add @Override (#2224) 2024-07-05 22:52:51 +08:00
Kerwin Bryant 65d69eb191 Fixed style issue of chart in detail-page (#2219) 2024-07-05 17:29:21 +08:00
Kerwin Bryantandtomsun28 5e2e78fe95 Hide the area when there are no advanced settings (#2215)
Co-authored-by: tomsun28 <tomsun28@outlook.com>
2024-07-05 15:51:46 +08:00
Kerwin Bryantandtomsun28 e992da78cd Two new functions are added to the notification center (#2214)
Co-authored-by: tomsun28 <tomsun28@outlook.com>
2024-07-05 15:44:22 +08:00
YuLuo 2fd0090e83 [Chore] translate zh -> en in pom.xml (#2213)
Signed-off-by: yuluo-yx <yuluo08290126@gmail.com>
2024-07-05 15:34:50 +08:00
linDongandLogic a86fc85ffc [feature] : add SparkDesk Ai (#2185)
Co-authored-by: Logic <zqr10159@dromara.org>
2024-07-05 11:23:03 +08:00
f3cecea307 [doc] add redis-cluster help document[New] (#2210)
Co-authored-by: Zhengke Zhou <zhengke.zhou@rightcapital.com>
Co-authored-by: Logic <zqr10159@dromara.org>
2024-07-05 11:12:48 +08:00
Kerwin Bryant cbf6536923 Optimize the user experience of monitoring list pages. (#2211) 2024-07-05 11:07:42 +08:00
Kerwin Bryant 336eaffd27 Optimize the user experience of monitoring list pages. (#2209) 2024-07-05 10:04:58 +08:00
Kerwin BryantandLogic b9f8b7de72 Unified the search interaction of the list page. (#2207)
Co-authored-by: Logic <zqr10159@dromara.org>
2024-07-05 09:58:11 +08:00
YuLuoandLogic 5b44a95298 [Improve] add IpDomainUtil & IntervaiExpressionUtil unit test (#2204)
Signed-off-by: yuluo-yx <yuluo08290126@gmail.com>
Co-authored-by: Logic <zqr10159@dromara.org>
2024-07-05 09:51:50 +08:00
YuLuoandLogic 97e5435296 [chore] update community contribution.md files (#2199)
Signed-off-by: yuluo-yx <yuluo08290126@gmail.com>
Co-authored-by: Logic <zqr10159@dromara.org>
2024-07-05 09:43:44 +08:00
JastandLogic 9b31fe785f [improve]add zookeeper envi monitor (#2202)
Co-authored-by: Logic <zqr10159@dromara.org>
2024-07-05 09:40:35 +08:00
Kerwin BryantandLogic f6fcd52a50 Optimize the tags-selection. (#2198)
Co-authored-by: Logic <zqr10159@dromara.org>
2024-07-05 09:35:41 +08:00
Kerwin Bryantandtomsun28 19a59004de Optimize the detail-page of monitor. (#2196)
Co-authored-by: tomsun28 <tomsun28@outlook.com>
2024-07-05 09:32:12 +08:00
Kerwin Bryantandtomsun28 f9b04ceb0c Add a missing multi-language translation. (#2194)
Co-authored-by: tomsun28 <tomsun28@outlook.com>
2024-07-04 19:44:39 +08:00
kangliandtomsun28 7ee227196d [bugfix] fixed "Alert Threshold Association with Monitors" is invalid bug #2105 (#2191)
Co-authored-by: tomsun28 <tomsun28@outlook.com>
2024-07-04 19:11:17 +08:00
Kerwin Bryantandtomsun28 20f3b01251 Optimize the [Threshold Rule] Form. (#2190)
Co-authored-by: tomsun28 <tomsun28@outlook.com>
2024-07-04 18:56:08 +08:00
Kerwin Bryant 9260bca057 Optimize the dashboard. (#2193) 2024-07-04 18:53:05 +08:00
Kerwin Bryantandtomsun28 6cdffbefac Optimize the visual experience of the monitoring details page. (#2189)
Co-authored-by: tomsun28 <tomsun28@outlook.com>
2024-07-04 10:49:31 +08:00
crossoverJieandtomsun28 0699e89346 [Improve] Refactor the notification sending logic. (#2180)
Co-authored-by: tomsun28 <tomsun28@outlook.com>
2024-07-04 10:21:01 +08:00
linDongandtomsun28 6222c51f41 [doc] add kimiAi doc (#2184)
Co-authored-by: tomsun28 <tomsun28@outlook.com>
2024-07-04 10:11:57 +08:00
Jastandtomsun28 ccbc7c698e [doc] add status page doc (#2186)
Co-authored-by: tomsun28 <tomsun28@outlook.com>
2024-07-04 09:10:49 +08:00
Kerwin BryantandLogic b5c7705f4a [bugfix] fixed issue of status-page (#2182)
Co-authored-by: Logic <zqr10159@dromara.org>
2024-07-04 09:02:16 +08:00
Kerwin Bryant eeba46af9f Fixed issue of acions in list-page. (#2181) 2024-07-04 08:47:25 +08:00
b4d0e77c99 [feature] : support kimi Ai (#2171)
Co-authored-by: Logic <zqr10159@dromara.org>
Co-authored-by: tomsun28 <tomsun28@outlook.com>
2024-07-04 07:52:48 +08:00
Kerwin Bryant 1cb293ac03 [bugfix] fixed issue of monitor-select-menu-modal (#2177) 2024-07-04 07:47:19 +08:00
Kerwin Bryantandtomsun28 2ffdda8f26 [improve] optimize the monitoring editing form. (#2172)
Signed-off-by: Kerwin Bryant <kerwin612@qq.com>
Co-authored-by: tomsun28 <tomsun28@outlook.com>
2024-07-03 14:31:48 +08:00
Logic 4f1c62fa3a [doc]Add new committer crossoverJie. (#2170) 2024-07-02 19:58:30 +08:00
Kerwin BryantandLogic bfe68d8a06 Optimize the style of the header on the monitoring details page. (#2167)
Co-authored-by: Logic <zqr10159@dromara.org>
2024-07-02 15:09:08 +08:00
Kerwin BryantandLogic 215271716d Optimize the content styling of the monitoring details page. (#2168)
Co-authored-by: Logic <zqr10159@dromara.org>
2024-07-02 15:06:59 +08:00
Kerwin Bryant fafc6a8212 Optimize the help-message-show component (#2169) 2024-07-02 14:48:03 +08:00
liutianyouandtomsun28 e860e63f62 [bugfix] modify the prompt information for deleting used tags (#2165)
Signed-off-by: tomsun28 <tomsun28@outlook.com>
Co-authored-by: tomsun28 <tomsun28@outlook.com>
2024-07-02 09:40:05 +08:00
mchgood 702446190d [doc] update contribution.md (#2164)
Signed-off-by: mchgood <38482005+mchgood@users.noreply.github.com>
2024-07-01 23:02:59 +08:00
linDong 7251fb4185 [docs] : Alibaba Ai config doc (#2162) 2024-07-01 21:49:20 +08:00
12bb21cb8d [feature] :support alibaba Ai (#2153)
Co-authored-by: Logic <zqr10159@dromara.org>
Co-authored-by: tomsun28 <tomsun28@outlook.com>
2024-07-01 21:35:29 +08:00
Kerwin Bryant a7f30fc1f6 [bugfix] add missing multi-language translations. (#2163) 2024-07-01 13:57:32 +08:00
liutianyouandtomsun28 2cc779ce1c [fix] remove i18 message in restful api (#2161)
Co-authored-by: tomsun28 <tomsun28@outlook.com>
2024-07-01 09:59:11 +08:00
Kerwin Bryant 27c394d9f7 [bugfix] fixed notify module error (#2160) 2024-06-30 09:24:14 +08:00
b25f1834e8 Modified docker command documentation (#2158)
Co-authored-by: daixianglong <daixianglong@xiaomi.com>
Co-authored-by: Logic <zqr10159@dromara.org>
2024-06-28 16:28:43 +08:00
Kerwin Bryant c878ac8fad [improve] support for formControlName to the multi-func-input component. (#2157) 2024-06-28 16:12:58 +08:00
JastandLogic 0ebcffa408 [improve] optimize delimiters (#2155)
Co-authored-by: Logic <zqr10159@dromara.org>
2024-06-28 10:58:39 +08:00
Kerwin Bryant 5ef96061c9 [improve] add support for search type to the multi-func-input component. (#2154) 2024-06-28 10:28:55 +08:00
liutianyou c06f53c926 [bugfix] fix deleting component error (#2152) 2024-06-28 00:17:54 +08:00
Kerwin Bryant 51765d8f9a Add a basic component for "Monitoring Selection Menu" (#2150) 2024-06-27 19:35:19 +08:00
Kerwin Bryant 1fe37d3789 [feature] add a search to the setting define page. (#2148) 2024-06-27 11:32:25 +08:00
Kerwin BryantandLogic baf2d5f536 Fixed the issue that the [first loading] does not appear (#2144)
Co-authored-by: Logic <zqr10159@dromara.org>
2024-06-26 18:22:43 +08:00
Kerwin BryantandLogic 5757d7427d Add a loading animation to the /setting/define page. (#2145)
Co-authored-by: Logic <zqr10159@dromara.org>
2024-06-26 18:18:55 +08:00
Kerwin BryantandLogic cbb4b8c736 Add a new common toolbar component. (#2143)
Co-authored-by: Logic <zqr10159@dromara.org>
2024-06-26 18:14:16 +08:00
liutianyouandLogic dbac0dfe63 [bugfix] add incident publishing form validation (#2139)
Co-authored-by: Logic <zqr10159@dromara.org>
2024-06-26 18:11:45 +08:00
Kerwin Bryant 8c0b39f69b [improve] continuously supplement and improve the goals set in #2140 (#2142) 2024-06-26 10:24:28 +08:00
a54d8cdd11 [improve] : fix AiService getType method data type,complete information for LICENSE (#2141)
Co-authored-by: Logic <zqr10159@dromara.org>
Co-authored-by: tomsun28 <tomsun28@outlook.com>
2024-06-25 23:42:15 +08:00
Kerwin BryantandLogic ec1c41cf68 Unify the border-radius values of the all components. (#2140)
Co-authored-by: Logic <zqr10159@dromara.org>
2024-06-25 23:30:13 +08:00
tomsun28 93635a0482 [doc] add new committer shenghang (#2137) 2024-06-25 23:20:14 +08:00
Jastandtomsun28 59266ccb8a [doc] doc add committer process (#2136)
Co-authored-by: tomsun28 <tomsun28@outlook.com>
2024-06-25 22:07:19 +08:00
Kerwin Bryant bc4b399a21 [bugfix] fixed the layout styling issue of the left list on the setting/define. (#2134) 2024-06-25 21:43:55 +08:00
Kerwin Bryantandtomsun28 87756f16d9 [improve] support for password type to the app-multi-func-input component. (#2132)
Co-authored-by: tomsun28 <tomsun28@outlook.com>
2024-06-25 15:38:50 +08:00
e1cda5066e [docs] : Add an ai configuration document (#2130)
Co-authored-by: Logic <zqr10159@dromara.org>
Co-authored-by: tomsun28 <tomsun28@outlook.com>
2024-06-25 15:26:31 +08:00
fa0e9ef50a [feature] support ai api with zhipu ai (#2120)
Co-authored-by: Logic <zqr10159@dromara.org>
Co-authored-by: tomsun28 <tomsun28@outlook.com>
2024-06-25 14:34:22 +08:00
Kerwin Bryant a10c2bfbd8 Fixed the issues similar to #2127 on the alert center page. (#2131) 2024-06-25 12:08:11 +08:00
liutianyouandtomsun28 33877615c5 [improve] add configuration for mounting logs (#2128)
Co-authored-by: tomsun28 <tomsun28@outlook.com>
2024-06-25 08:32:09 +08:00
linDongandtomsun28 13411105ed [bug]fix the monitor status is abnormal (#2070)
Co-authored-by: tomsun28 <tomsun28@outlook.com>
2024-06-25 00:04:13 +08:00
e2faa44f18 [fixbug] fix string type data parsing problem (#2066)
Co-authored-by: zhangshenghang <admin@hadoop.wiki>
Co-authored-by: tomsun28 <tomsun28@outlook.com>
2024-06-24 17:45:12 +08:00
Kerwin Bryant 657de4f5b6 Add an input box component with a removal function. (#2127) 2024-06-24 17:19:26 +08:00
Kerwin Bryantandtomsun28 dfa6895a7e [bugfix] fixed the bug of the status filter in the alert center. (#2125)
Co-authored-by: tomsun28 <tomsun28@outlook.com>
2024-06-24 11:18:03 +08:00
Kerwin Bryant a9de486744 [bugfix] fix the status filter in the monitoring center (#2124) 2024-06-24 11:08:25 +08:00
Kerwin Bryant 31d8712299 Fixed the i18n issue similarly to #2117. (#2119) 2024-06-22 13:59:02 +08:00
Kerwin BryantandLogic c4a6e36977 Fixed the i18n issue of the [New Notice Policy] form. (#2117)
Co-authored-by: Logic <zqr10159@dromara.org>
2024-06-21 20:09:11 +08:00
Kerwin BryantandLogic 41c3bf50ee Uniformly use [...] to replace the phrase [More]. (#2115)
Co-authored-by: Logic <zqr10159@dromara.org>
2024-06-21 20:07:01 +08:00
Kerwin BryantandLogic 957cce93d9 Optimize the layout of the [New Threshold Rule] form. (#2116)
Co-authored-by: Logic <zqr10159@dromara.org>
2024-06-21 19:14:30 +08:00
9b7b00e09c Optimize the visual experience of the nz-table template. (#2112)
Co-authored-by: tomsun28 <tomsun28@outlook.com>
Co-authored-by: Logic <zqr10159@dromara.org>
2024-06-21 15:25:33 +08:00
tomsun28andLogic b3976295f5 [improve] update collector info, support env config or auto fetch (#2100)
Signed-off-by: tomsun28 <tomsun28@outlook.com>
Co-authored-by: Logic <zqr10159@dromara.org>
2024-06-21 15:17:57 +08:00
Kerwin Bryantandtomsun28 1be2631af7 optimize the visual experience of the level2Message module. (#2111)
Co-authored-by: tomsun28 <tomsun28@outlook.com>
2024-06-21 11:22:22 +08:00
Kerwin Bryant 5f5f4d0346 [bugfix] the prompt information on the Collector Cluster page (#2114) 2024-06-21 10:55:04 +08:00
Kerwin BryantandLogic 95c30f54cd fixed #2107 (#2108)
Co-authored-by: Logic <zqr10159@dromara.org>
2024-06-20 20:55:03 +08:00
Kerwin BryantandLogic 855abf6ada Fixed a style issue within the dialog on the about-page. (#2109)
Co-authored-by: Logic <zqr10159@dromara.org>
2024-06-20 20:52:04 +08:00
Kerwin Bryant bdf82751a5 Optimize the code by removing unnecessary attribute values (#2110) 2024-06-20 20:45:40 +08:00
f49e20535c [improve] optimization notification code validation (#2102)
Co-authored-by: zhangshenghang <admin@hadoop.wiki>
Co-authored-by: tomsun28 <tomsun28@outlook.com>
2024-06-20 09:14:16 +08:00
dennis zhuang a32757ea7a [feat] supports TTL for greptimedb data storage (#2101) 2024-06-20 08:57:06 +08:00
liutianyou bd52e0527e [bugfix] fix extract double and unit error when unit is Ki (#2099) 2024-06-19 21:46:20 +08:00
dennis zhuang 1bac42b094 fix: greptimedb can't work with version >= 0.5 (#2095) 2024-06-19 18:54:04 +08:00
Rickandrick a71c61a0d8 [fix] the e2e failure without broken the ci (#2093)
Co-authored-by: rick <LinuxSuRen@users.noreply.github.com>
2024-06-19 00:07:35 +08:00
crossoverJieandtomsun28 56db540721 [doc] add codecov badge (#2089)
Signed-off-by: crossoverJie <crossoverJie@gmail.com>
Co-authored-by: tomsun28 <tomsun28@outlook.com>
2024-06-18 10:51:36 +08:00
bc104dfe9f [doc] mysql monitoring help document adds steps for importing drivers (#2091)
Co-authored-by: tomsun28 <tomsun28@outlook.com>
Co-authored-by: Logic <zqr10159@dromara.org>
2024-06-18 08:49:05 +08:00
tomsun28andLogic fc6ea4a2e0 [bugfix] fix some template menus hidden when too long (#2092)
Signed-off-by: tomsun28 <tomsun28@outlook.com>
Co-authored-by: Logic <zqr10159@dromara.org>
2024-06-18 08:34:09 +08:00
Nctllnty 55c48d167c [bugfix] notice rules api access 409 error when upgrade 1.6.0 (#2090) 2024-06-18 07:25:56 +08:00
Rickandtomsun28 393bb95878 [chore] bump api-testing from v0.0.16 to v0.0.17 (#2087)
Signed-off-by: Rick <1450685+LinuxSuRen@users.noreply.github.com>
Co-authored-by: tomsun28 <tomsun28@outlook.com>
2024-06-17 22:49:33 +08:00
Jastandzhangshenghang 915fcbf1d9 [improve] enterprise wechat validate (#2086)
Co-authored-by: zhangshenghang <admin@hadoop.wiki>
2024-06-17 22:43:30 +08:00
Calvinandtomsun28 26b982a59b [license] update license document for jutf7 (#2082)
Co-authored-by: tomsun28 <tomsun28@outlook.com>
2024-06-17 08:00:38 +08:00
crossoverJieandtomsun28 3186aa5eb6 [Improve] support jacoco and codecov (#1985)
Signed-off-by: tomsun28 <tomsun28@outlook.com>
Co-authored-by: tomsun28 <tomsun28@outlook.com>
2024-06-16 22:53:43 +08:00
Zhang Yuxuanandtomsun28 a6ac326581 [feature] after new, edit, resume a monitor, display its status directly and correctly (#2065)
Co-authored-by: tomsun28 <tomsun28@outlook.com>
2024-06-16 16:27:35 +08:00
53b796ff57 [improve]add flink on yarn monitoring (#2078)
Co-authored-by: zhangshenghang <admin@hadoop.wiki>
Co-authored-by: tomsun28 <tomsun28@outlook.com>
2024-06-16 15:35:55 +08:00
Calvinandtomsun28 b7217b5d48 [feature] add column version and public Ip on collector page (#2072)
Co-authored-by: tomsun28 <tomsun28@outlook.com>
2024-06-16 14:48:18 +08:00
tomsun28 b8f2bf30fd [doc] add hertzbeat 1.6.0 release blog (#2083) 2024-06-16 09:08:58 +08:00
Leon Liandtomsun28 bc4ddefc76 [collector] fix the wrong condition for checking the response (#2067)
Co-authored-by: tomsun28 <tomsun28@outlook.com>
2024-06-15 10:26:25 +08:00
Zhang Yuxuanandtomsun28 2fcd100fec [feature] add automatic refresh to the monitoring center (#2064)
Co-authored-by: tomsun28 <tomsun28@outlook.com>
2024-06-14 22:58:24 +08:00
liutianyouandtomsun28 365de4657e [fix] fix unit test passing but outputting exception stack (#2063)
Co-authored-by: tomsun28 <tomsun28@outlook.com>
2024-06-14 22:55:43 +08:00
Zhang Yuxuanandtomsun28 d4e6317a30 [feature] Implement IMAP protocol support (#2059)
Co-authored-by: tomsun28 <tomsun28@outlook.com>
2024-06-14 22:47:40 +08:00
cc19831f7c [feature] support mongodb atlas cluster (#2052)
Co-authored-by: zhangshenghang <admin@hadoop.wiki>
Co-authored-by: tomsun28 <tomsun28@outlook.com>
2024-06-14 21:28:35 +08:00
Gao Jianandtomsun28 f10e5dbd06 [Improve] Fix possible potential thread unsafe issues (#2043)
Co-authored-by: tomsun28 <tomsun28@outlook.com>
2024-06-14 21:18:57 +08:00
af1f59e009 [feature] designated personnel send message (#2038)
Co-authored-by: zhangshenghang <admin@hadoop.wiki>
Co-authored-by: tomsun28 <tomsun28@outlook.com>
2024-06-13 23:28:58 +08:00
aias00andlimbo 009a512ba0 [feature] upgrade webapp angular deps version #1707 (#1987)
Signed-off-by: aias00 <rokkki@163.com>
Co-authored-by: limbo <yykaue@qq.com>
2024-06-12 15:13:56 +08:00
tomsun28 dc381ea338 [improve] update docker compose and k8s helm deploy script (#2076) 2024-06-11 17:52:30 +08:00
Logic 3ed52c54af [doc] hertzbeat 1.6.0 upgrade guide (#2077) 2024-06-11 16:51:26 +08:00
tomsun28and铁甲小宝 c5808a0430 [doc] update release 1.6.0 doc (#2074)
Signed-off-by: tomsun28 <tomsun28@outlook.com>
Co-authored-by: 铁甲小宝 <2922035952@qq.com>
2024-06-11 00:18:14 +08:00
Calvin ed390a50c9 [fixed] required field check for tag settings (#2071) 2024-06-09 22:54:40 +08:00
linDongandtomsun28 cfe93bf19d [doc] add telnet protocol custom doc (#2061)
Co-authored-by: tomsun28 <tomsun28@outlook.com>
2024-06-05 02:45:41 +08:00
5043 changed files with 511468 additions and 171161 deletions
+1058 -30
View File
File diff suppressed because it is too large Load Diff
+9 -6
View File
@@ -16,11 +16,15 @@
#
github:
description: Apache HertzBeat(incubating) is a real-time monitoring system with agentless, performance cluster, prometheus-compatible, custom monitoring and status page building capabilities.
description: An AI-powered next-generation open source real-time observability system.
homepage: https://hertzbeat.apache.org/
labels:
- monitoring
- ai
- agent
- llm
- logs
- monitor
- monitoring
- notifications
- alerting
- self-hosted
@@ -30,15 +34,11 @@ github:
- metrics
- observability
- uptime
- uptime-monitoring
- status
- status-page
- devops
- server
- linux
- database
- mysql
- cloud
enabled_merge_buttons:
squash: true
merge: false
@@ -52,6 +52,9 @@ github:
required_pull_request_reviews:
dismiss_stale_reviews: true
required_approving_review_count: 1
# enable GitHub Dependabot to create PRs for security alerts but not for every dependency update
dependabot_alerts: true
dependabot_updates: false
notifications:
commits: notifications@hertzbeat.apache.org
issues: notifications@hertzbeat.apache.org
+37
View File
@@ -0,0 +1,37 @@
{
"name": "HertzBeat DevContainer",
"image": "mcr.microsoft.com/devcontainers/base:ubuntu",
"features": {
"ghcr.io/devcontainers/features/java:1": {
"version": "17",
"installMaven": "true",
"installGradle": "false"
},
"ghcr.io/devcontainers/features/node:1": {
"version": "20"
},
"ghcr.io/devcontainers/features/git-lfs:1.1.0": {}
},
"customizations": {
"vscode": {
"settings": {},
"extensions": [
"vscjava.vscode-java-pack",
"editorconfig.editorconfig",
"dbaeumer.vscode-eslint",
"stylelint.vscode-stylelint",
"DavidAnson.vscode-markdownlint",
"ms-azuretools.vscode-docker",
"cweijan.vscode-database-client2",
"GitHub.vscode-pull-request-github"
]
}
},
"portsAttributes": {
"4200": {
"label": "HertzBeat Web",
"onAutoForward": "notify"
}
},
"postCreateCommand": "java -version"
}
+55
View File
@@ -0,0 +1,55 @@
# Licensed to the Apache Software Foundation (ASF) under one or more
# contributor license agreements. See the NOTICE file distributed with
# this work for additional information regarding copyright ownership.
# The ASF licenses this file to You under the Apache License, Version 2.0
# (the "License"); you may not use this file except in compliance with
# the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
# EditorConfig is awesome: https://EditorConfig.org
# top-most EditorConfig file
root = true
[*]
charset = utf-8
end_of_line = lf
indent_style = space
# The line max length is 120, match checkstyle rules.
max_line_length = 120
insert_final_newline = true
trim_trailing_whitespace = true
[*.json]
tab_width = 2
indent_size = 2
[*.{yml,yaml}]
tab_width = 2
indent_size = 2
[*.xml]
ij_xml_attribute_wrap = off
ij_xml_text_wrap = off
ij_xml_keep_blank_lines = 1
[pom.xml]
indent_size = 2
[*.java]
indent_size = 4
tab_width = 4
[*.js]
indent_size = 2
[*.ts]
indent_size = 2
+1
View File
@@ -19,5 +19,6 @@
/hip export-ignore
/.github export-ignore
/.idea export-ignore
/.devcontainer export-ignore
.gitattributes export-ignore
.gitignore export-ignore
-3
View File
@@ -20,6 +20,3 @@ contact_links:
- name: Community Support
url: https://github.com/apache/hertzbeat/discussions
about: Please ask and answer questions here.
- name: Security Bug Bounty
url: https://github.com/apache/hertzbeat/issues
about: Please report security vulnerabilities here.
+2 -1
View File
@@ -53,4 +53,5 @@ body:
validations:
required: false
- type: markdown
value: "Please read the [Contribution Guideline](https://hertzbeat.apache.org/docs/others/contributing) before submitting the PR"
attributes:
value: "Please read the [Contribution Guideline](https://hertzbeat.apache.org/docs/community/contribution) before submitting the PR"
+1 -1
View File
@@ -39,4 +39,4 @@ body:
- type: markdown
attributes:
value: |
Please read the [Contribution Guideline](https://hertzbeat.com/docs/others/contributing/) before submitting the PR
Please read the [Contribution Guideline](https://hertzbeat.apache.org/docs/community/contribution) before submitting the PR
+1 -1
View File
@@ -30,5 +30,5 @@ body:
- type: markdown
attributes:
value: |
Please read the [Contribution Guideline](https://hertzbeat.apache.org/docs/others/contributing/) before submitting the PR
Please read the [Contribution Guideline](https://hertzbeat.apache.org/docs/community/contribution) before submitting the PR
+10 -10
View File
@@ -90,24 +90,24 @@ e2e:
backend:
- changed-files:
- any-glob-to-any-file:
- "alerter/**/*"
- "collector/**/*"
- "common/**/*"
- "grafana/**/*"
- "manager/**/*"
- "push/**/*"
- "remoting/**/*"
- "warehouse/**/*"
- "hertzbeat-alerter/**/*"
- "hertzbeat-collector/**/*"
- "hertzbeat-common/**/*"
- "hertzbeat-grafana/**/*"
- "hertzbeat-manager/**/*"
- "hertzbeat-push/**/*"
- "hertzbeat-remoting/**/*"
- "hertzbeat-warehouse/**/*"
collector:
- changed-files:
- any-glob-to-any-file:
- "collector/**/*"
- "hertzbeat-collector/**/*"
monitoring-template:
- changed-files:
- any-glob-to-any-file:
- "manager/src/main/resources/define/**/*"
- "hertzbeat-manager/src/main/resources/define/**/*"
HIP:
- changed-files:
Binary file not shown.

After

Width:  |  Height:  |  Size: 194 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 315 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 282 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 262 KiB

+81 -23
View File
@@ -22,7 +22,7 @@ name: Backend CI
on:
push:
branches: [ master, dev ]
branches: [ master, dev, action* ]
paths-ignore:
- '**.md'
- 'home/**'
@@ -38,30 +38,88 @@ on:
- 'script/**'
- 'material/**'
concurrency:
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
cancel-in-progress: true
jobs:
build:
backend-build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Set up JDK 17
uses: actions/setup-java@v1
with:
java-version: 17
- name: Build with Maven
run: mvn clean -B package -Prelease --file pom.xml
- name: Build Image
env:
IMAGE_PUSH: false
IMAGE_LOAD: true
IMAGE_PLATFORM: linux/amd64
run: |
docker buildx create --use --name myBuilder --driver docker-container
docker buildx use myBuilder
- uses: actions/checkout@v4
- uses: ./script/ci/github-actions/setup-deps
./script/docker/server/build.sh
- name: Run E2E
run: |
sudo curl -L https://github.com/docker/compose/releases/download/v2.23.0/docker-compose-linux-x86_64 -o /usr/local/bin/docker-compose
sudo chmod u+x /usr/local/bin/docker-compose
- name: Build with Maven
run: mvnd clean -B package -pl '!hertzbeat-e2e' -Prelease -Dmaven.test.skip=false --file pom.xml
cd e2e && ./start.sh
- name: Upload coverage reports to Codecov
uses: codecov/codecov-action@v4.0.1
with:
token: ${{ secrets.CODECOV_TOKEN }}
fail_ci_if_error: false
verbose: true
- name: Upload backend distribution
uses: actions/upload-artifact@v4
with:
name: backend-dist-${{ github.run_id }}
path: dist/
retention-days: 1
compression-level: 0
backend-maven-e2e:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: ./script/ci/github-actions/setup-deps
- name: Build backend Maven E2E modules
run: |
mvnd clean -B package \
-pl hertzbeat-e2e/hertzbeat-collector-common-e2e,hertzbeat-e2e/hertzbeat-collector-kafka-e2e,hertzbeat-e2e/hertzbeat-collector-basic-e2e,hertzbeat-e2e/hertzbeat-collector-mysql-r2dbc-e2e,hertzbeat-e2e/hertzbeat-log-e2e \
-am \
-Dmaven.test.skip=false \
--file pom.xml
- name: Upload Maven E2E coverage reports to Codecov
uses: codecov/codecov-action@v4.0.1
with:
token: ${{ secrets.CODECOV_TOKEN }}
fail_ci_if_error: false
verbose: true
backend-image-e2e:
needs: backend-build
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Download backend distribution
uses: actions/download-artifact@v4
with:
name: backend-dist-${{ github.run_id }}
path: dist/
- name: Build Image
uses: docker/build-push-action@53b7df96c91f9c12dcc8a07bcb9ccacbed38856a # v7.3.0
with:
context: ./dist
file: ./script/docker/server/Dockerfile
push: false
tags: apache/hertzbeat:test
- name: Run E2E
run: |
cd e2e
docker compose version
docker compose up --exit-code-from testing --remove-orphans
# upload application logs
- name: Upload logs & API test reports
uses: actions/upload-artifact@v4
if: always()
with:
name: hz-logs-${{ github.run_id }}
path: |
e2e/logs/
e2e/report/
+3 -1
View File
@@ -31,6 +31,8 @@ name: "CodeQL"
on:
schedule:
- cron: '21 13 * * 4'
push:
branches: [ action* ]
jobs:
analyze:
@@ -47,7 +49,7 @@ jobs:
steps:
- name: Checkout repository
uses: actions/checkout@v3
uses: actions/checkout@v4
# Initializes the CodeQL tools for scanning.
- name: Initialize CodeQL
@@ -0,0 +1,89 @@
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership. The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
name: Collector Native Release
run-name: Native collector release build (${{ github.ref_name }})
on:
workflow_dispatch:
jobs:
build-native-collector:
name: Native collector (${{ matrix.platform }})
permissions:
contents: read
timeout-minutes: 120
runs-on: ${{ matrix.runner }}
strategy:
fail-fast: false
matrix:
include:
- platform: linux-amd64
runner: ubuntu-24.04
archive_ext: tar.gz
- platform: linux-arm64
runner: ubuntu-24.04-arm
archive_ext: tar.gz
- platform: macos-amd64
runner: macos-13
archive_ext: tar.gz
- platform: macos-arm64
runner: macos-14
archive_ext: tar.gz
- platform: windows-amd64
runner: windows-latest
archive_ext: zip
steps:
- uses: actions/checkout@v4
- name: Set up GraalVM JDK 25
uses: graalvm/setup-graalvm@186d0493a2df5eb62df5ecc498883d18fd58c303 # v1.6.2
with:
distribution: graalvm-community
java-version: '25'
github-token: ${{ secrets.GITHUB_TOKEN }}
cache: maven
native-image-job-reports: 'true'
- name: Verify toolchain
shell: pwsh
run: |
java -version
native-image --version
mvn -version
- name: Build native collector package
run: mvn -B -pl hertzbeat-collector/hertzbeat-collector-collector -am -Pnative -DskipTests package
- name: Locate native collector package
id: package
shell: pwsh
run: |
$package = Get-ChildItem -Path "dist/apache-hertzbeat-collector-native-*-${{ matrix.platform }}-bin.${{ matrix.archive_ext }}" | Select-Object -First 1
if (-not $package) {
throw "Native collector package not found for ${{ matrix.platform }}"
}
"archive=$($package.FullName)" >> $env:GITHUB_OUTPUT
- name: Upload native collector package
uses: actions/upload-artifact@v4
with:
name: apache-hertzbeat-collector-native-${{ matrix.platform }}
path: ${{ steps.package.outputs.archive }}
retention-days: 14
+44 -82
View File
@@ -19,7 +19,7 @@ name: DOC CI
on:
push:
branches: [ master, dev ]
branches: [ master, dev, action* ]
paths:
- 'home/**'
pull_request:
@@ -27,92 +27,54 @@ on:
paths:
- 'home/**'
concurrency:
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
cancel-in-progress: true
jobs:
build:
docs-build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Check filename in home/blog
- uses: pnpm/action-setup@v4
with:
version: 10
- uses: actions/setup-node@v4
with:
node-version: '22'
cache: pnpm
cache-dependency-path: home/pnpm-lock.yaml
- uses: actions/setup-python@v4
with:
python-version: '3.8'
- name: Check Markdown
uses: DavidAnson/markdownlint-cli2-action@8de2aa07cae85fd17c0b35642db70cf5495f1d25 # v24.0.0
with:
globs: |
./home/README.md
./home/blog/**/*.md
./home/docs/**/*.md
./home/i18n/zh-cn/docusaurus-plugin-content-blog/**/*.md
./home/i18n/zh-cn/docusaurus-plugin-content-docs/current/**/*.md
- name: Check filenames
run: python ./script/ci/docs/check_file_name.py ./script/ci/docs/check_file_name.json
- name: Dead Link Check
run: |
TARGET_DIR="./home/blog"
invalid_files=()
while IFS= read -r -d '' file; do
filename=$(basename "$file")
if [[ ! "$filename" =~ ^[_a-z0-9-]+(\.[_a-z0-9-]+)*$ ]]; then
invalid_files+=("$file")
fi
done < <(find "$TARGET_DIR" -type f -print0)
if [ ${#invalid_files[@]} -ne 0 ]; then
echo "Error: The following files have invalid names:(File name should only contain lowercase letters, numbers, and hyphens.)"
for invalid_file in "${invalid_files[@]}"; do
echo "$invalid_file"
done
exit 1
else
echo "All file names are valid."
fi
- name: Check filename in home/docs
run: |
TARGET_DIR="./home/docs"
invalid_files=()
while IFS= read -r -d '' file; do
filename=$(basename "$file")
if [[ ! "$filename" =~ ^[_a-z0-9-]+(\.[_a-z0-9-]+)*$ ]]; then
invalid_files+=("$file")
fi
done < <(find "$TARGET_DIR" -type f -print0)
if [ ${#invalid_files[@]} -ne 0 ]; then
echo "Error: The following files have invalid names:(File name should only contain lowercase letters, numbers, and hyphens.)"
for invalid_file in "${invalid_files[@]}"; do
echo "$invalid_file"
done
exit 1
else
echo "All file names are valid."
fi
- name: Check filename in /zh-cn/docusaurus-plugin-content-blog
run: |
TARGET_DIR="./home/i18n/zh-cn/docusaurus-plugin-content-blog"
invalid_files=()
while IFS= read -r -d '' file; do
filename=$(basename "$file")
if [[ ! "$filename" =~ ^[_a-z0-9-]+(\.[_a-z0-9-]+)*$ ]]; then
invalid_files+=("$file")
fi
done < <(find "$TARGET_DIR" -type f -print0)
if [ ${#invalid_files[@]} -ne 0 ]; then
echo "Error: The following files have invalid names:(File name should only contain lowercase letters, numbers, and hyphens.)"
for invalid_file in "${invalid_files[@]}"; do
echo "$invalid_file"
done
exit 1
else
echo "All file names are valid."
fi
- name: Check filename in /home/i18n/zh-cn/docusaurus-plugin-content-docs/current
run: |
TARGET_DIR="./home/i18n/zh-cn/docusaurus-plugin-content-docs/current"
invalid_files=()
while IFS= read -r -d '' file; do
filename=$(basename "$file")
if [[ ! "$filename" =~ ^[_a-z0-9-]+(\.[_a-z0-9-]+)*$ ]]; then
invalid_files+=("$file")
fi
done < <(find "$TARGET_DIR" -type f -print0)
if [ ${#invalid_files[@]} -ne 0 ]; then
echo "Error: The following files have invalid names:(File name should only contain lowercase letters, numbers, and hyphens.)"
for invalid_file in "${invalid_files[@]}"; do
echo "$invalid_file"
done
exit 1
else
echo "All file names are valid."
fi
- name: NPM INSTALL
sudo npm install -g markdown-link-check@3.8.7
find ./home/docs ./home/blog ./home/i18n/zh-cn/docusaurus-plugin-content-docs/current ./home/i18n/zh-cn/docusaurus-plugin-content-blog -name "*.md" > all_md_files.txt
printf '%s\n' ./home/README.md >> all_md_files.txt
grep -vFf ./script/ci/exclude_files.txt all_md_files.txt > to_check.txt
xargs -P 8 -a to_check.txt -I{} markdown-link-check -c ./script/ci/link_check.json -q "{}"
- name: PNPM INSTALL
working-directory: home
run: npm install
- name: NPM BUILD
run: pnpm install
- name: PNPM BUILD
working-directory: home
run: npm run build
run: pnpm run build
+94
View File
@@ -0,0 +1,94 @@
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership. The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
name: DOC Deploy
on:
# Trigger on push to master branch when home directory files are changed
push:
branches: [ master ]
paths:
- 'home/**'
# Allow manual workflow trigger
workflow_dispatch:
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
# Set permissions for deployment
permissions:
contents: write
jobs:
deploy:
name: Deploy Documentation to asf-site Branch
runs-on: ubuntu-latest
steps:
# Checkout the repository code
- name: Checkout Repository
uses: actions/checkout@v4
with:
fetch-depth: 0
# Setup pnpm (must run before setup-node so the pnpm cache can be configured)
- name: Setup pnpm
uses: pnpm/action-setup@v4
with:
version: 10
# Setup Node.js environment
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '22'
cache: pnpm
cache-dependency-path: home/pnpm-lock.yaml
# Install dependencies in home directory
- name: Install Dependencies
working-directory: home
run: pnpm install --frozen-lockfile
# Build the documentation site
- name: Build Documentation
working-directory: home
run: pnpm run build
env:
NODE_OPTIONS: --max-old-space-size=4096
# Deploy to asf-site branch using peaceiris/actions-gh-pages
- name: Deploy to asf-site Branch
uses: peaceiris/actions-gh-pages@v3
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
publish_dir: ./home/build
publish_branch: asf-site
force_orphan: true
user_name: 'github-actions[bot]'
user_email: 'github-actions[bot]@users.noreply.github.com'
commit_message: 'Deploy documentation to asf-site branch'
# Output deployment status
- name: Deployment Summary
run: |
echo "Documentation deployed successfully!"
echo "Deployment branch: asf-site"
echo "Source branch: ${{ github.ref_name }}"
echo "Commit SHA: ${{ github.sha }}"
+4 -4
View File
@@ -17,7 +17,8 @@
name: 'HertzBeat Doc Pdf Builder'
on:
page_build
push:
branches: [ page_build* ]
jobs:
build:
@@ -39,7 +40,7 @@ jobs:
run: npx docusaurus-prince-pdf -u https://hertzbeat.apache.org/docs --output docs-en.pdf
- name: Upload results
uses: actions/upload-artifact@v3
uses: actions/upload-artifact@v4
with:
name: docs-cn-pdf
path: docs-cn.pdf
@@ -47,10 +48,9 @@ jobs:
retention-days: 1
- name: Upload results
uses: actions/upload-artifact@v3
uses: actions/upload-artifact@v4
with:
name: docs-en-pdf
path: docs-en.pdf
if-no-files-found: error
retention-days: 1
+17 -5
View File
@@ -22,7 +22,7 @@ name: Frontend CI
on:
push:
branches: [ master, dev ]
branches: [ master, dev, action* ]
paths:
- 'web-app/**'
pull_request:
@@ -30,14 +30,26 @@ on:
paths:
- 'web-app/**'
concurrency:
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
cancel-in-progress: true
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Yarn Install
- uses: actions/checkout@v4
- uses: pnpm/action-setup@v4
with:
version: 10
- uses: actions/setup-node@v4
with:
node-version: '20'
cache: pnpm
cache-dependency-path: web-app/pnpm-lock.yaml
- name: Install
working-directory: web-app
run: yarn
run: pnpm install
- name: EsLint Test
working-directory: web-app
run: yarn lint:ts
run: pnpm lint:ts
+6 -2
View File
@@ -22,17 +22,21 @@ name: License Checker
on:
push:
branches: [ master, dev ]
branches: [ master, dev, action* ]
pull_request:
branches: [ master, dev ]
concurrency:
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
cancel-in-progress: true
jobs:
check-license-header:
name: check-license-header
runs-on: ubuntu-latest
timeout-minutes: 10
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4
with:
submodules: true
- name: Check license header
+97
View File
@@ -0,0 +1,97 @@
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership. The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
name: MCP Bash Server CI
on:
push:
paths:
- 'mcp-servers/mcp-bash-server/**'
- '.github/workflows/mcp-bashserver-test.yml'
pull_request:
paths:
- 'mcp-servers/mcp-bash-server/**'
- '.github/workflows/mcp-bashserver-test.yml'
env:
CARGO_TERM_COLOR: always
RUST_VERSION: 1.88.0
jobs:
test:
name: Test MCP Bash Server
runs-on: ubuntu-latest
strategy:
matrix:
profile: [dev, release]
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Setup Rust toolchain
uses: dtolnay/rust-toolchain@4be7066ada62dd38de10e7b70166bc74ed198c30 # stable
with:
toolchain: ${{ env.RUST_VERSION }}
components: rustfmt, clippy
- name: Cache cargo registry
uses: actions/cache@v4
with:
path: |
~/.cargo/registry/index/
~/.cargo/registry/cache/
~/.cargo/git/db/
key: ${{ runner.os }}-cargo-registry-${{ hashFiles('**/Cargo.lock') }}
restore-keys: |
${{ runner.os }}-cargo-registry-
- name: Cache cargo build
uses: actions/cache@v4
with:
path: target/
key: ${{ runner.os }}-cargo-build-${{ matrix.profile }}-${{ hashFiles('**/Cargo.lock') }}
restore-keys: |
${{ runner.os }}-cargo-build-${{ matrix.profile }}-
${{ runner.os }}-cargo-build-
- name: Check code format
run: cargo fmt --manifest-path ./mcp-servers/mcp-bash-server/Cargo.toml --check
- name: Run cargo check
run: |
if [ "${{ matrix.profile }}" = "release" ]; then
cargo check --release --manifest-path ./mcp-servers/mcp-bash-server/Cargo.toml
else
cargo check --manifest-path ./mcp-servers/mcp-bash-server/Cargo.toml
fi
- name: Run clippy
run: |
if [ "${{ matrix.profile }}" = "release" ]; then
cargo clippy --release --manifest-path ./mcp-servers/mcp-bash-server/Cargo.toml -- -D warnings
else
cargo clippy --manifest-path ./mcp-servers/mcp-bash-server/Cargo.toml -- -D warnings
fi
- name: Run tests
run: |
if [ "${{ matrix.profile }}" = "release" ]; then
cargo test --release --manifest-path ./mcp-servers/mcp-bash-server/Cargo.toml
else
cargo test --manifest-path ./mcp-servers/mcp-bash-server/Cargo.toml
fi
+56
View File
@@ -0,0 +1,56 @@
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership. The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
# This workflow will build a Java project with Maven
# For more information see: https://help.github.com/actions/language-and-framework-guides/building-and-testing-java-with-maven
name: Monitor E2E Test
on:
schedule:
# trigger at 01:00 everyday
- cron: '0 1 * * *'
push:
branches: [ action* ]
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
jobs:
check-license-header:
name: Monitor E2E Test
runs-on: ubuntu-latest
timeout-minutes: 10
steps:
- uses: actions/checkout@v4
- uses: ./script/ci/github-actions/setup-deps
- name: Build with Maven
run: mvnd -B clean package -Prelease -Dmaven.test.skip=true --file pom.xml
- name: Build Image
uses: docker/build-push-action@53b7df96c91f9c12dcc8a07bcb9ccacbed38856a # v7.3.0
with:
context: ./dist
file: ./script/docker/server/Dockerfile
push: false
tags: apache/hertzbeat:test
- name: Run K8s Monitor E2E Test
run: |
cd e2e/k8s
docker compose version
docker compose up --exit-code-from testing --remove-orphans
+82
View File
@@ -0,0 +1,82 @@
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership. The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
name: Nightly CI
on:
schedule:
# trigger at 00:00 everyday
- cron: '0 0 * * *'
push:
branches: [ action* ]
workflow_dispatch:
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
jobs:
build:
runs-on: ubuntu-latest
if: ${{ github.repository == 'apache/hertzbeat' }}
steps:
- uses: actions/checkout@v4
- uses: ./script/ci/github-actions/setup-deps
- uses: pnpm/action-setup@v4
with:
version: 10
- uses: actions/setup-node@v4
with:
node-version: '20'
cache: pnpm
cache-dependency-path: web-app/pnpm-lock.yaml
- name: Build the Frontend
run: |
cd web-app
pnpm install
pnpm package
- name: Build the Backend
run: |
mvnd -B clean package -Prelease,cluster -Dmaven.test.skip=false --file pom.xml
- uses: docker/setup-qemu-action@ce360397dd3f832beb865e1373c09c0e9f86d70a
- uses: docker/setup-buildx-action@4d04d5d9486b7bd6fa91e7baf45bbb4f8b9deedd
- name: Log in to Docker Hub
uses: docker/login-action@af1e73f918a031802d376d3c8bbc3fe56130a9b0 # v4.4.0
with:
username: ${{ secrets.DOCKERHUB_USER }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
- name: Build and Push Server
uses: docker/build-push-action@53b7df96c91f9c12dcc8a07bcb9ccacbed38856a # v7.3.0
with:
context: ./dist
file: ./script/docker/server/Dockerfile
platforms: linux/amd64,linux/arm64
push: true
tags: apache/hertzbeat:nightly
- name: Build and Push Collector
uses: docker/build-push-action@53b7df96c91f9c12dcc8a07bcb9ccacbed38856a # v7.3.0
with:
context: ./dist
file: ./script/docker/collector/Dockerfile
platforms: linux/amd64,linux/arm64
push: true
tags: apache/hertzbeat-collector:nightly
+9 -3
View File
@@ -6,13 +6,13 @@ Thumbs.db
build/
out/
micronaut-cli.yml
.mvn/
mvnw
mvnw.bat
*.log
package-lock.json
*.zip
jdk/
data/
!/e2e/**/data/
### STS ###
.apt_generated
@@ -54,3 +54,9 @@ node_modules
application-dev.yml
application-mysql.yml
application-pg.yml
/package.json
/yarn.lock
# Local Codex workspace files
.codex/
AGENTS.md
+21
View File
@@ -0,0 +1,21 @@
#
# Licensed to the Apache Software Foundation (ASF) under one or more
# contributor license agreements. See the NOTICE file distributed with
# this work for additional information regarding copyright ownership.
# The ASF licenses this file to You under the Apache License, Version 2.0
# (the "License"); you may not use this file except in compliance with
# the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
[submodule "script/helm/hertzbeat-helm-chart"]
path = script/helm/hertzbeat-helm-chart
url = git@github.com:apache/hertzbeat-helm-chart.git
branch = main
+7
View File
@@ -0,0 +1,7 @@
FROM gitpod/workspace-full
USER gitpod
RUN bash -c ". /home/gitpod/.sdkman/bin/sdkman-init.sh && \
sdk install java 21.0.2-tem && \
sdk default java 21.0.2-tem"
+54
View File
@@ -0,0 +1,54 @@
image:
file: .gitpod.Dockerfile
tasks:
- name: Run backend
before: cd hertzbeat-startup
command: |
gp sync-await setup-backend
mvn spring-boot:run
- name: Run frontend
before: cd web-app
command: |
gp sync-await setup-frontend
pnpm start --public-host "`gp url 4200`"
openMode: split-right
- name: Setup backend
init: |
mvn clean install -DskipTests
command: |
gp sync-done setup-backend
exit 0
- name: Setup frontend
init: |
cd web-app && pnpm install
command: |
gp sync-done setup-frontend
exit 0
openMode: split-right
vscode:
extensions:
- vscjava.vscode-java-pack
- editorconfig.editorconfig
- dbaeumer.vscode-eslint
- stylelint.vscode-stylelint
- DavidAnson.vscode-markdownlint
- ms-azuretools.vscode-docker
- cweijan.vscode-database-client2
- GitHub.vscode-pull-request-github
ports:
- port: 4200
name: HertzBeat
onOpen: open-browser
- port: 1157
onOpen: ignore
- port: 1158
onOpen: ignore
+7 -2
View File
@@ -39,6 +39,7 @@ header:
- '**/*.js'
- '**/*.less'
- '**/*.txt'
- '**/*.st'
- '**/target/**'
- '.gitattributes'
- '**/.gitignore'
@@ -62,9 +63,13 @@ header:
- '.stylelintrc'
- '.prettierignore'
- '.prettierrc.js'
- '.gitpod.Dockerfile'
- '.gitpod.yml'
- 'karma.conf.js'
- 'proxy.conf.js'
- 'pnpm-lock.yaml'
- '.helmignore'
- 'script/helm/**'
- 'web-app/src/app/core/**'
- 'web-app/src/app/layout/**'
- 'web-app/src/app/routes/exception/**'
@@ -92,12 +97,12 @@ header:
- 'web-app/src/style.less'
- 'web-app/src/test.ts'
- 'web-app/src/typings.d.ts'
comment: on-failure
dependency:
files:
- pom.xml
- web-app/package.json
+55
View File
@@ -0,0 +1,55 @@
//
// Licensed to the Apache Software Foundation (ASF) under one or more
// contributor license agreements. See the NOTICE file distributed with
// this work for additional information regarding copyright ownership.
// The ASF licenses this file to You under the Apache License, Version 2.0
// (the "License"); you may not use this file except in compliance with
// the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
{
"globs": [
"home/README.md",
"home/blog/**/*.md",
"home/docs/**/*.md",
"home/i18n/zh-cn/docusaurus-plugin-content-blog/**/*.md",
"home/i18n/zh-cn/docusaurus-plugin-content-docs/current/**/*.md"
],
"config": {
"default": true,
"MD001": true,
"MD003": true,
"MD013": {
"line_length": 600,
"code_blocks": false,
"tables": false
},
"MD024": {
"siblings_only": true
},
"MD025": true,
"MD029": true,
"MD033": {
"allowed_elements": ["table", "tr", "td", "a", "img", "sub", "b", "br", "img", "tbody", "mark", "font", "Tabs", "TabItem"]
},
"MD036": false,
"MD040": true,
"MD045": true,
"MD046": true,
"MD047": true,
"MD052": true,
"MD060": false
},
"ignores": [
"**/node_modules/**",
"**/target/**",
"**/dist/**"
]
}
+17
View File
@@ -0,0 +1,17 @@
# Licensed to the Apache Software Foundation (ASF) under one or more
# contributor license agreements. See the NOTICE file distributed with
# this work for additional information regarding copyright ownership.
# The ASF licenses this file to You under the Apache License, Version 2.0
# (the "License"); you may not use this file except in compliance with
# the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
wrapperVersion=3.3.2
distributionType=only-script
distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.9.9/apache-maven-3.9.9-bin.zip
+108 -129
View File
@@ -1,10 +1,10 @@
## Contributor Guide [中文贡献者指南](#贡献者指南)
## Contributor Guide [中文贡献者指南](#贡献者指南)
> We are committed to maintaining a happy community that helps each other, welcome every contributor to join us!
> We are committed to maintaining a happy community that helps each other, welcome every contributor to join us!
### Kinds of Contributions
### Kinds of Contributions
> In the HertzBeat community, there are many ways to contribute:
> In the HertzBeat community, there are many ways to contribute:
- 💻**Code**: Can help the community complete some tasks, write new features or fix some bugs;
@@ -20,88 +20,88 @@
- 💬**Suggestion**: You can also make some suggestions to the project or community to promote the healthy development of the community;
More see [Contribution Types](https://allcontributors.org/docs/en/emoji-key)
More see [Contribution Types](https://allcontributors.org/en/reference/emoji-key/)
Even small corrections to typos are very welcome :)
Even small corrections to typos are very welcome :)
### Getting HertzBeat up and running
### Getting HertzBeat up and running
> To get HertzBeat code running on your development tools, and able to debug with breakpoints.
> This is a front-end and back-end separation project. To start the local code, the back-end [manager](manager) and the front-end [web-app](web-app) must be started separately.
> This is a front-end and back-end separation project. To start the local code, the back-end [startup](hertzbeat-startup) and the front-end [web-app](web-app) must be started separately.
#### Backend start
1. Requires `maven3+`, `java17` and `lombok` environments
1. Requires `maven3+`, `java25` and `lombok` environments
2. (Optional) Modify the configuration file: `manager/src/main/resources/application.yml`
2. (Optional) Modify the configuration file: `hertzbeat-startup/src/main/resources/application.yml`
3. Execute under the project root directory: `mvn clean install -DskipTests`
4. Start `springboot manager` service: `manager/src/main/java/org/apache/hertzbeat/manager/Manager.java`
4. Add VM Options: `--add-opens=java.base/java.nio=org.apache.arrow.memory.core,ALL-UNNAMED`
5. Start `springboot startup` service: `hertzbeat-startup/src/main/java/org/apache/hertzbeat/startup/HertzBeatApplication.java`
#### Frontend start
1. Need `Node Yarn` Environment, Make sure `Node.js >= 18`
1. Need `Node pnpm` Environment, Make sure `Node.js >= 18`
2. Cd to the `web-app` directory: `cd web-app`
3. Install yarn if not existed `npm install -g yarn`
3. Install pnpm if not existed `npm install -g pnpm`
4. Install Dependencies: `yarn install` or `yarn install --registry=https://registry.npmmirror.com` in `web-app`
4. Install Dependencies: `pnpm install` or `pnpm install --registry=https://registry.npmmirror.com` in `web-app`
5. Install angular-cli globally: `yarn global add @angular/cli@15` or `yarn global add @angular/cli@15 --registry=https://registry.npmmirror.com`
5. After the local backend is started, start the local frontend in the web-app directory: `pnpm start`
6. After the local backend is started, start the local frontend in the web-app directory: `ng serve --open`
7. Browser access to localhost:4200 to start, default account/password is *admin/hertzbeat*
6. Browser access to localhost:4200 to start, default account/password is *admin/hertzbeat*
### Find tasks
### Find tasks
Find the issue you are interested in! On our GitHub repo issue list, we often publish some issues with the label good first issue or status: volunteer wanted.
These issues welcome the help of contributors. Among them, good first issues tend to have low thresholds and are suitable for novices.
Find the issue you are interested in! On our GitHub repo issue list, we often publish some issues with the label good first issue or status: volunteer wanted.
These issues welcome the help of contributors. Among them, good first issues tend to have low thresholds and are suitable for novices.
Of course, if you have a good idea, you can also propose it directly on GitHub Discussion or contact with community.
Of course, if you have a good idea, you can also propose it directly on GitHub Discussion or contact with community.
### Submit Pull Request
### Submit Pull Request
1. First you need to fork your target [hertzbeat repository](https://github.com/apache/hertzbeat).
1. First you need to fork your target [hertzbeat repository](https://github.com/apache/hertzbeat).
2. Then download the code locally with git command:
```shell
git clone git@github.com:${YOUR_USERNAME}/hertzbeat.git #Recommended
```
3. After the download is complete, please refer to the getting started guide or README file of the target repository to initialize the project.
```shell
git clone git@github.com:${YOUR_USERNAME}/hertzbeat.git #Recommended
```
3. After the download is complete, please refer to the getting started guide or README file of the target repository to initialize the project.
4. Then, you can refer to the following command to submit the code:
```shell
git checkout -b a-feature-branch #Recommended
```
5. Submit the coed as a commit, the commit message format specification required: [module name or type name]feature or bugfix or doc: custom message.
```shell
git add <modified file/path>
git commit -m '[docs]feature: necessary instructions' #Recommended
```
6. Push to the remote repository
```shell
git push origin a-feature-branch
```
7. Then you can initiate a new PR (Pull Request) on GitHub.
```shell
git checkout -b a-feature-branch #Recommended
```
5. Submit the code as a commit, the commit message format specification required: [module name or type name]feature or bugfix or doc: custom message.
```shell
git add <modified file/path>
git commit -m '[docs]feature: necessary instructions' #Recommended
```
6. Push to the remote repository
```shell
git push origin a-feature-branch
```
7. Then you can initiate a new PR (Pull Request) on GitHub.
Please note that the title of the PR needs to conform to our spec, and write the necessary description in the PR to facilitate code review by Committers and other contributors.
Please note that the title of the PR needs to conform to our spec, and write the necessary description in the PR to facilitate code review by Committers and other contributors.
### Wait for the code to be merged
### Wait for the code to be merged
After submitting the PR, the Committee or the community's friends will review the code you submitted (Code Review), and will propose some modification suggestions or conduct some discussions. Please pay attention to your PR in time.
After submitting the PR, the Committee or the community's friends will review the code you submitted (Code Review), and will propose some modification suggestions or conduct some discussions. Please pay attention to your PR in time.
If subsequent changes are required, there is no need to initiate a new PR. After submitting a commit on the original branch and pushing it to the remote repository, the PR will be automatically updated.
If subsequent changes are required, there is no need to initiate a new PR. After submitting a commit on the original branch and pushing it to the remote repository, the PR will be automatically updated.
In addition, our project has a relatively standardized and strict CI inspection process. After submitting PR, CI will be triggered. Please pay attention to whether it passes the CI inspection.
In addition, our project has a relatively standardized and strict CI inspection process. After submitting PR, CI will be triggered. Please pay attention to whether it passes the CI inspection.
Finally, the Committers can merge the PR into the master branch.
Finally, the Committers can merge the PR into the master branch.
### After the code is merged
### After the code is merged
After the code has been merged, you can delete the development branch on both the local and remote repositories:
After the code has been merged, you can delete the development branch on both the local and remote repositories:
```shell
git branch -d a-dev-branch
@@ -112,51 +112,40 @@ On the master/main branch, you can do the following to sync the upstream reposit
```shell
git remote add upstream https://github.com/apache/hertzbeat.git #Bind the remote warehouse, if it has been executed, it does not need to be executed again
git checkout master
git checkout master
git pull upstream master
```
### HertzBeat Improvement Proposal (HIP)
If you have major new features(e.g., support metrics push gateway, support logs monitoring), you need to write a design document known as a HertzBeat Improvement Proposal (HIP). Before starting to write a HIP, make sure you follow the process [here](https://github.com/apache/hertzbeat/tree/master/hip).
### How to become a Committer?
### How to become a Committer?
With the above steps, you are a contributor to HertzBeat. Repeat the previous steps to stay active in the community, keep at, you can become a Committer!
With the above steps, you are a contributor to HertzBeat. Repeat the previous steps to stay active in the community, keep at, you can become a Committer!
### Join Discussion
### Join Discussion
[Join the Mailing Lists](https://lists.apache.org/list.html?dev@hertzbeat.apache.org) : Mail to `dev-subscribe@hertzbeat.apache.org` to subscribe mailing lists.
Add WeChat account `tan-cloud` to pull you into the WeChat group.
Add WeChat account `ahertzbeat` to pull you into the WeChat group.
## 🥐 Architecture
- **[manager](https://github.com/apache/hertzbeat/tree/master/manager)** Provide monitoring management, system management basic services.
> Provides monitoring management, monitoring configuration management, system user management, etc.
- **[collector](https://github.com/apache/hertzbeat/tree/master/collector)** Provide metrics data collection services.
> Use common protocols to remotely collect and obtain peer-to-peer metrics data.
- **[warehouse](https://github.com/apache/hertzbeat/tree/master/warehouse)** Provide monitoring data warehousing services.
> Metrics data management, data query, calculation and statistics.
- **[alerter](https://github.com/apache/hertzbeat/tree/master/alerter)** Provide alert service.
> Alarm calculation trigger, monitoring status linkage, alarm configuration, and alarm notification.
- **[web-app](https://github.com/apache/hertzbeat/tree/master/web-app)** Provide web ui.
> Angular Web UI.
![hertzBeat](home/static/img/docs/hertzbeat-arch.png)
<br>
<br>
------
<br>
## 贡献者指南
## 贡献者指南
> 非常欢迎参与项目贡献,我们致力于维护一个互相帮助的快乐社区。
> 非常欢迎参与项目贡献,我们致力于维护一个互相帮助的快乐社区。
### 贡献方式
### 贡献方式
> 在 HertzBeat 社区,贡献方式有很多:
> 在 HertzBeat 社区,贡献方式有很多:
- 💻**代码**:可以帮助社区完成一些任务、编写新的feature或者是修复一些bug;
@@ -170,126 +159,116 @@ Add WeChat account `tan-cloud` to pull you into the WeChat group.
- 💡**布道**:可以帮助宣传或推广 HertzBeat 社区,在 meetup 或 summit 中演讲;
- 💬**建议**:也可以对项目或者社区提出一些建议,促进社区的良性发展;
- 💬**建议**:也可以对项目或者社区提出一些建议,促进社区的良性发展;
更多贡献方式参见 [Contribution Types](https://allcontributors.org/docs/en/emoji-key)
更多贡献方式参见 [Contribution Types](https://allcontributors.org/en/reference/emoji-key/)
即便是小到错别字的修正我们也都非常欢迎 :)
即便是小到错别字的修正我们也都非常欢迎 :)
### 让 HertzBeat 运行起来
### 让 HertzBeat 运行起来
> 让 HertzBeat 的代码在您的开发工具上运行起来,并且能够断点调试。
> 此为前后端分离项目,本地代码启动需将后端[manager](manager)和前端[web-app](web-app)分别启动生效。
> 让 HertzBeat 的代码在您的开发工具上运行起来,并且能够断点调试。
> 此为前后端分离项目,本地代码启动需将后端[hertzbeat-startup](hertzbeat-startup)和前端[web-app](web-app)分别启动生效。
#### 后端启动
1. 需要 `maven3+`, `java17``lombok` 环境
1. 需要 `maven3+`, `java25` 和 `lombok` 环境
2. (可选)修改配置文件配置信息-`manager/src/main/resources/application.yml`
2. (可选)修改配置文件配置信息-`hertzbeat-startup/src/main/resources/application.yml`
3. 在项目根目录运行编译: `mvn clean install -DskipTests`
4. 启动`springboot manager`服务 `manager/src/main/java/org/apache/hertzbeat/manager/Manager.java`
4. 在 `jvm` 加入参数 `--add-opens=java.base/java.nio=org.apache.arrow.memory.core,ALL-UNNAMED`
5. 启动`springboot startup`服务 `hertzbeat-startup/src/main/java/org/apache/hertzbeat/startup/HertzBeatApplication.java`
#### 前端启动
1. 需要 `nodejs yarn` 环境, Make sure `Node.js >= 18`
1. 需要 `nodejs pnpm` 环境, Make sure `Node.js >= 18`
2. 进入 `web-app` 目录: `cd web-app`
3. 安装yarn: `npm install -g yarn`
3. 安装pnpm: `npm install -g pnpm`
4. 在前端工程目录 `web-app` 下执行: `yarn install` or `yarn install --registry=https://registry.npmmirror.com` in `web-app`
4. 在前端工程目录 `web-app` 下执行: `pnpm install` or `pnpm install --registry=https://registry.npmmirror.com` in `web-app`
5. 全局安装 `angular-cli`: `yarn global add @angular/cli@15` or `yarn global add @angular/cli@15 --registry=https://registry.npmmirror.com`
5. 待本地后端启动后,在web-app目录下启动本地前端 `pnpm start`
6. 待本地后端启动后,在web-app目录下启动本地前端 `ng serve --open`
6. 浏览器访问 localhost:4200 即可开始,默认账号密码 *admin/hertzbeat*
7. 浏览器访问 localhost:4200 即可开始,默认账号密码 *admin/hertzbeat*
### 寻找任务
### 寻找任务
寻找您感兴趣的Issue!在我们的GitHub仓库和邮件列表中,我们经常会发布一些带有 good first issue 或者 status: volunteer wanted 标签的issue,这些issue都欢迎贡献者的帮助。
其中good first issue往往门槛较低、适合新手。
其中good first issue往往门槛较低、适合新手。
当然,如果您有好的想法,也可以直接在GitHub Discussion 中提出或者联系社区。
当然,如果您有好的想法,也可以直接在GitHub Discussion 中提出或者联系社区。
### 提交 Pull Request
1. 首先您需要 Fork 目标仓库 [hertzbeat repository](https://github.com/apache/hertzbeat).
2. 然后 用git命令 将代码下载到本地:
```shell
git clone git@github.com:${YOUR_USERNAME}/hertzbeat.git #Recommended
```
2. 然后 用git命令 将代码下载到本地:
```shell
git clone git@github.com:${YOUR_USERNAME}/hertzbeat.git #Recommended
```
3. 下载完成后,请参考目标仓库的入门指南或者 README 文件对项目进行初始化。
4. 接着,您可以参考如下命令进行代码的提交, 切换新的分支, 进行开发:
```shell
git checkout -b a-feature-branch #Recommended
```
5. 提交 commit , commit 描述信息需要符合约定格式: [module name or type name]feature or bugfix or doc: custom message.
```shell
git add <modified file/path>
git commit -m '[docs]feature: necessary instructions' #Recommended
```
6. 推送到远程仓库
```shell
git push origin a-feature-branch
```
4. 接着,您可以参考如下命令进行代码的提交, 切换新的分支, 进行开发:
```shell
git checkout -b a-feature-branch #Recommended
```
5. 提交 commit , commit 描述信息需要符合约定格式: [module name or type name]feature or bugfix or doc: custom message.
```shell
git add <modified file/path>
git commit -m '[docs]feature: necessary instructions' #Recommended
```
6. 推送到远程仓库
```shell
git push origin a-feature-branch
```
7. 然后您就可以在 GitHub 上发起新的 PR (Pull Request)。
请注意 PR 的标题需要符合我们的规范,并且在 PR 中写上必要的说明,来方便 Committer 和其他贡献者进行代码审查。
请注意 PR 的标题需要符合我们的规范,并且在 PR 中写上必要的说明,来方便 Committer 和其他贡献者进行代码审查。
### 等待PR代码被合并
### 等待PR代码被合并
在提交了 PR 后,Committer 或者社区的小伙伴们会对您提交的代码进行审查(Code Review),会提出一些修改建议,或者是进行一些讨论,请及时关注您的PR。
在提交了 PR 后,Committer 或者社区的小伙伴们会对您提交的代码进行审查(Code Review),会提出一些修改建议,或者是进行一些讨论,请及时关注您的PR。
若后续需要改动,不需要发起一个新的 PR,在原有的分支上提交 commit 并推送到远程仓库后,PR会自动更新。
另外,我们的项目有比较规范和严格的 CI 检查流程,在提交 PR 之后会触发 CI,请注意是否通过 CI 检查。
最后,Committer 可以将 PR 合并入 master 主分支。
最后,Committer 可以将 PR 合并入 master 主分支。
### 代码被合并后
### 代码被合并后
在代码被合并后,您就可以在本地和远程仓库删除这个开发分支了:
在代码被合并后,您就可以在本地和远程仓库删除这个开发分支了:
```shell
git branch -d a-dev-branch
git push origin --delete a-dev-branch
```
在主分支上,您可以执行以下操作来同步上游仓库:
在主分支上,您可以执行以下操作来同步上游仓库:
```shell
git remote add upstream https://github.com/apache/hertzbeat.git #Bind the remote warehouse, if it has been executed, it does not need to be executed again
git checkout master
git checkout master
git pull upstream master
```
### HertzBeat 改进提案 (HIP)
如果您有重大的新特性(例如,支持指标推送网关,日志监控等),您需要编写一个被称为 HertzBeat 改进提案(HertzBeat Improvement ProposalHIP)的设计文档。在开始编写 HIP 之前,请确保您遵循了[这里](https://github.com/apache/hertzbeat/tree/master/hip)的流程。
### 如何成为Committer
### 如何成为Committer
通过上述步骤,您就是 HertzBeat 的贡献者了。重复前面的步骤,在社区中保持活跃,坚持下去,您就能成为 Committer!
通过上述步骤,您就是 HertzBeat 的贡献者了。重复前面的步骤,在社区中保持活跃,坚持下去,您就能成为 Committer!
### 加入讨论交流
[Join the Mailing Lists](https://lists.apache.org/list.html?dev@hertzbeat.apache.org) : Mail to `dev-subscribe@hertzbeat.apache.org` to subscribe mailing lists.
Add WeChat account `tan-cloud` to pull you into the WeChat group.
Add WeChat account `ahertzbeat` to pull you into the WeChat group.
### 模块
- **[manager](https://github.com/apache/hertzbeat/tree/master/manager)** 提供监控管理,系统管理基础服务
> 提供对监控的管理,监控应用配置的管理,系统用户租户后台管理等。
- **[collector](https://github.com/apache/hertzbeat/tree/master/collector)** 提供监控数据采集服务
> 使用通用协议远程采集获取对端指标数据。
- **[warehouse](https://github.com/apache/hertzbeat/tree/master/warehouse)** 提供监控数据仓储服务
> 采集指标结果数据管理,数据落盘,查询,计算统计。
- **[alerter](https://github.com/apache/hertzbeat/tree/master/alerter)** 提供告警服务
> 告警计算触发,任务状态联动,告警配置,告警通知。
- **[web-app](https://github.com/apache/hertzbeat/tree/master/web-app)** 提供可视化控制台页面
> 监控告警系统可视化控制台前端
![hertzBeat](home/static/img/docs/hertzbeat-arch.png)
![hertzBeat](home/static/img/docs/hertzbeat-arch.png)
-10
View File
@@ -1,10 +0,0 @@
Apache HertzBeat (incubating) is an effort undergoing incubation at the Apache
Software Foundation (ASF), sponsored by the Apache Incubator PMC.
Incubation is required of all newly accepted projects until a further review
indicates that the infrastructure, communications, and decision making process
have stabilized in a manner consistent with other successful ASF projects.
While incubation status is not necessarily a reflection of the completeness
or stability of the code, it does indicate that the project has yet to be
fully endorsed by the ASF.
+2 -2
View File
@@ -1,5 +1,5 @@
Apache HertzBeat (incubating)
Copyright 2024 The Apache Software Foundation
Apache HertzBeat
Copyright 2024-2026 The Apache Software Foundation
This product includes software developed at
The Apache Software Foundation (http://www.apache.org/).
+229 -152
View File
@@ -4,136 +4,91 @@
</a>
</p>
<h4 align="center">
<a href="README.md">English Document</a> | <a href="README_CN.md">中文文档</a>
</h4>
> A real-time monitoring system with agentless, performance cluster, prometheus-compatible, custom monitoring and status page building capabilities.
<p align="center">
<b>Readme</b>:
<b><a href="README.md">English</a></b> | <a href="README_CN.md">中文</a> | <a href="README_JP.md">日本語</a>
</p>
[![Discord](https://img.shields.io/badge/Chat-Discord-7289DA?logo=discord)](https://discord.gg/Fb6M73htGr)
[![Reddit](https://img.shields.io/badge/Reddit-Community-7289DA?logo=reddit)](https://www.reddit.com/r/hertzbeat/)
[![Twitter](https://img.shields.io/twitter/follow/hertzbeat1024?logo=twitter)](https://twitter.com/hertzbeat1024)
[![Twitter](https://img.shields.io/twitter/follow/hertzbeat1024?logo=twitter)](https://x.com/hertzbeat1024)
[![OpenSSF Best Practices](https://www.bestpractices.dev/projects/8139/badge)](https://www.bestpractices.dev/projects/8139)
[![Docker Pulls](https://img.shields.io/docker/pulls/apache/hertzbeat?style=%20for-the-badge&logo=docker&label=DockerHub%20Download)](https://hub.docker.com/repository/docker/apache/hertzbeat/general)
[![codecov](https://codecov.io/gh/apache/HertzBeat/branch/master/graph/badge.svg)](https://app.codecov.io/gh/apache/hertzbeat)
[![Docker Pulls](https://img.shields.io/docker/pulls/apache/hertzbeat?style=%20for-the-badge&logo=docker&label=DockerHub%20Download)](https://hub.docker.com/r/apache/hertzbeat)
[![Artifact Hub](https://img.shields.io/endpoint?url=https://artifacthub.io/badge/repository/hertzbeat)](https://artifacthub.io/packages/search?repo=hertzbeat)
[![YouTube Channel Subscribers](https://img.shields.io/youtube/channel/subscribers/UCri75zfWX0GHqJFPENEbLow?logo=youtube&label=YouTube%20Channel)](https://www.youtube.com/channel/UCri75zfWX0GHqJFPENEbLow)
[![Contribute with Gitpod](https://img.shields.io/badge/Contribute%20with-Gitpod-908a85?logo=gitpod&color=green)](https://gitpod.io/#https://github.com/apache/hertzbeat)
[![Ask DeepWiki](https://deepwiki.com/badge.svg)](https://deepwiki.com/apache/hertzbeat)
[![zread](https://img.shields.io/badge/Ask_Zread-_.svg?style=flat&color=00b0aa&labelColor=000000&logo=data%3Aimage%2Fsvg%2Bxml%3Bbase64%2CPHN2ZyB3aWR0aD0iMTYiIGhlaWdodD0iMTYiIHZpZXdCb3g9IjAgMCAxNiAxNiIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4KPHBhdGggZD0iTTQuOTYxNTYgMS42MDAxSDIuMjQxNTZDMS44ODgxIDEuNjAwMSAxLjYwMTU2IDEuODg2NjQgMS42MDE1NiAyLjI0MDFWNC45NjAxQzEuNjAxNTYgNS4zMTM1NiAxLjg4ODEgNS42MDAxIDIuMjQxNTYgNS42MDAxSDQuOTYxNTZDNS4zMTUwMiA1LjYwMDEgNS42MDE1NiA1LjMxMzU2IDUuNjAxNTYgNC45NjAxVjIuMjQwMUM1LjYwMTU2IDEuODg2NjQgNS4zMTUwMiAxLjYwMDEgNC45NjE1NiAxLjYwMDFaIiBmaWxsPSIjZmZmIi8%2BCjxwYXRoIGQ9Ik00Ljk2MTU2IDEwLjM5OTlIMi4yNDE1NkMxLjg4ODEgMTAuMzk5OSAxLjYwMTU2IDEwLjY4NjQgMS42MDE1NiAxMS4wMzk5VjEzLjc1OTlDMS42MDE1NiAxNC4xMTM0IDEuODg4MSAxNC4zOTk5IDIuMjQxNTYgMTQuMzk5OUg0Ljk2MTU2QzUuMzE1MDIgMTQuMzk5OSA1LjYwMTU2IDE0LjExMzQgNS42MDE1NiAxMy43NTk5VjExLjAzOTlDNS42MDE1NiAxMC42ODY0IDUuMzE1MDIgMTAuMzk5OSA0Ljk2MTU2IDEwLjM5OTlaIiBmaWxsPSIjZmZmIi8%2BCjxwYXRoIGQ9Ik0xMy43NTg0IDEuNjAwMUgxMS4wMzg0QzEwLjY4NSAxLjYwMDEgMTAuMzk4NCAxLjg4NjY0IDEwLjM5ODQgMi4yNDAxVjQuOTYwMUMxMC4zOTg0IDUuMzEzNTYgMTAuNjg1IDUuNjAwMSAxMS4wMzg0IDUuNjAwMUgxMy43NTg0QzE0LjExMTkgNS42MDAxIDE0LjM5ODQgNS4zMTM1NiAxNC4zOTg0IDQuOTYwMVYyLjI0MDFDMTQuMzk4NCAxLjg4NjY0IDE0LjExMTkgMS42MDAxIDEzLjc1ODQgMS42MDAxWiIgZmlsbD0iI2ZmZiIvPgo8cGF0aCBkPSJNNCAxMkwxMiA0TDQgMTJaIiBmaWxsPSIjZmZmIi8%2BCjxwYXRoIGQ9Ik00IDEyTDEyIDQiIHN0cm9rZT0iI2ZmZiIgc3Ryb2tlLXdpZHRoPSIxLjUiIHN0cm9rZS1saW5lY2FwPSJyb3VuZCIvPgo8L3N2Zz4K&logoColor=ffffff)](https://zread.ai/apache/hertzbeat)
**Home: [hertzbeat.apache.org](https://hertzbeat.apache.org)**
**Home: [hertzbeat.apache.org](https://hertzbeat.apache.org)**
**Email: <a href="mailto:dev-subscribe@hertzbeat.apache.org">Mail to `dev-subscribe@hertzbeat.apache.org`</a> to subscribe mailing lists**
## 🎡 <font color="green">Introduction</font>
[Apache HertzBeat](https://github.com/apache/hertzbeat) (incubating) is an easy-to-use, open source, real-time monitoring system with agentless, high performance cluster, prometheus-compatible, offers powerful custom monitoring and status page building capabilities.
[Apache HertzBeat](https://github.com/apache/hertzbeat) is an AI-powered next-generation open source real-time observability system. Unified metrics and logs collection, centralized alerting distribution, intelligent management and analysis. No Agent required, high performance cluster, provides powerful custom monitoring and status page building capabilities.
### Features
* Combines **monitoring, alarm, and notification** features into one platform, and supports monitoring for web service, program, database, cache, os, webserver, middleware, bigdata, cloud-native, network, custom and more.
* Easy to use and agentless, web-based and with one-click monitoring and alerting, zero learning curve.
* Makes protocols such as `Http, Jmx, Ssh, Snmp, Jdbc, Prometheus` configurable, allowing you to collect any metrics by simply configuring the template `YML` file online. Imagine being able to quickly adapt to a new monitoring type like K8s or Docker simply by configuring online with HertzBeat.
* Compatible with the `Prometheus` ecosystem and more, can monitoring what `Prometheus` can monitoring with few clicks on webui.
* High performance, supports horizontal expansion of multi-collector clusters, multi-isolated network monitoring and cloud-edge collaboration.
* Provides flexible alarm threshold rules and timely notifications delivered via `Discord` `Slack` `Telegram` `Email` `Dingtalk` `WeChat` `FeiShu` `Webhook` `SMS` `ServerChan`.
* Provides powerful status page building capabilities, easily communicate the real-time status of your service to users.
- Integrates **collection + analysis + alerting + notification** into one platform, with new AI-powered interactions and features under HertzBeat AI, and built-in MCP Server capabilities.
- Unified metrics platform, agentless, Prometheus-compatible, supports application services, programs, databases, caches, operating systems, big data, middleware, web servers, cloud-native, networks, custom monitoring and more.
- Unified logging platform, seamlessly integrates multiple log sources through OTLP protocol for reporting.
- Unified alerting platform, integrates internal alerts with various external alert sources, unified alert processing and analysis, flexible real-time and periodic threshold rules, grouping convergence, silence, suppression, etc.
- Unified message distribution, alerts processed by the alerting platform are distributed via `Email` `Discord` `Slack` `Telegram` `DingTalk` `WeChat` `FeiShu` `SMS` `Webhook` `ServerChan` and other methods.
- Makes protocols such as `Http, Jmx, Ssh, Snmp, Jdbc, Prometheus` configurable, allowing you to collect any metrics by simply configuring the template `YML` file online. Imagine being able to quickly adapt to a new monitoring type like K8s or Docker simply by configuring online with HertzBeat.
- High performance, supports horizontal expansion of multi-collector clusters, multi-isolated network monitoring and cloud-edge collaboration.
- Provides powerful status page building capabilities, easily communicate the real-time status of your service to users.
> HertzBeat's powerful customization, multi-type support, high performance, easy expansion, and low coupling, aims to help users quickly build their own monitoring system.
> HertzBeat's unified platform, AI intelligence, powerful customization, multi-type support, high performance, and easy expansion, aims to help users quickly and conveniently achieve observability requirements.
----
![hertzbeat](home/static/img/home/1.png)
![hertzbeat](home/static/img/home/status.png)
![hertzbeat](home/static/img/home/9.png)
----
## 🥐 Architecture
## 🥐 Architecture
![hertzBeat](home/static/img/docs/hertzbeat-arch.png)
![HertzBeat](home/static/img/docs/hertzbeat-arch.png)
## ⛄ Supported
> We define all monitoring collection types such as `mysql`, `jvm`, and `k8s` as `YML` monitoring templates, allowing users to import them to support corresponding types of monitoring.
> Welcome everyone to contribute your customized general monitoring type YML template during use.
- [Website](https://raw.githubusercontent.com/apache/hertzbeat/master/manager/src/main/resources/define/app-website.yml), [Port Telnet](https://raw.githubusercontent.com/apache/hertzbeat/master/manager/src/main/resources/define/app-port.yml),
[Http Api](https://raw.githubusercontent.com/apache/hertzbeat/master/manager/src/main/resources/define/app-api.yml), [Ping Connect](https://raw.githubusercontent.com/apache/hertzbeat/master/manager/src/main/resources/define/app-ping.yml),
[Jvm](https://raw.githubusercontent.com/apache/hertzbeat/master/manager/src/main/resources/define/app-jvm.yml), [SiteMap](https://raw.githubusercontent.com/apache/hertzbeat/master/manager/src/main/resources/define/app-fullsite.yml),
[Ssl Certificate](https://raw.githubusercontent.com/apache/hertzbeat/master/manager/src/main/resources/define/app-ssl_cert.yml), [SpringBoot2](https://raw.githubusercontent.com/apache/hertzbeat/master/manager/src/main/resources/define/app-springboot2.yml),
[FTP Server](https://raw.githubusercontent.com/apache/hertzbeat/master/manager/src/main/resources/define/app-ftp.yml), [SpringBoot3](https://raw.githubusercontent.com/apache/hertzbeat/master/manager/src/main/resources/define/app-springboot3.yml),
[Udp Port](https://raw.githubusercontent.com/apache/hertzbeat/master/manager/src/main/resources/define/app-udp.yml), [Dns](https://raw.githubusercontent.com/apache/hertzbeat/master/manager/src/main/resources/define/app-dns.yml),
[Pop3](https://raw.githubusercontent.com/apache/hertzbeat/master/manager/src/main/resources/define/app-pop3.yml), [Ntp](https://raw.githubusercontent.com/apache/hertzbeat/master/manager/src/main/resources/define/app-ntp.yml),
[Api Code](https://raw.githubusercontent.com/apache/hertzbeat/master/manager/src/main/resources/define/app-api_code.yml), [Smtp](https://raw.githubusercontent.com/apache/hertzbeat/master/manager/src/main/resources/define/app-smtp.yml),
[Nginx](https://raw.githubusercontent.com/apache/hertzbeat/master/manager/src/main/resources/define/app-nginx.yml)
- [Mysql](https://raw.githubusercontent.com/apache/hertzbeat/master/manager/src/main/resources/define/app-mysql.yml), [PostgreSQL](https://raw.githubusercontent.com/apache/hertzbeat/master/manager/src/main/resources/define/app-postgresql.yml),
[MariaDB](https://raw.githubusercontent.com/apache/hertzbeat/master/manager/src/main/resources/define/app-mariadb.yml), [Redis](https://raw.githubusercontent.com/apache/hertzbeat/master/manager/src/main/resources/define/app-redis.yml),
[ElasticSearch](https://raw.githubusercontent.com/apache/hertzbeat/master/manager/src/main/resources/define/app-elasticsearch.yml), [SqlServer](https://raw.githubusercontent.com/apache/hertzbeat/master/manager/src/main/resources/define/app-sqlserver.yml),
[Oracle](https://raw.githubusercontent.com/apache/hertzbeat/master/manager/src/main/resources/define/app-oracle.yml), [MongoDB](https://raw.githubusercontent.com/apache/hertzbeat/master/manager/src/main/resources/define/app-mongodb.yml),
[DM](https://raw.githubusercontent.com/apache/hertzbeat/master/manager/src/main/resources/define/app-dm.yml), [OpenGauss](https://raw.githubusercontent.com/apache/hertzbeat/master/manager/src/main/resources/define/app-opengauss.yml),
[ClickHouse](https://raw.githubusercontent.com/apache/hertzbeat/master/manager/src/main/resources/define/app-clickhouse.yml), [IoTDB](https://raw.githubusercontent.com/apache/hertzbeat/master/manager/src/main/resources/define/app-iotdb.yml),
[Redis Cluster](https://raw.githubusercontent.com/apache/hertzbeat/master/manager/src/main/resources/define/app-redis_cluster.yml), [Redis Sentinel](https://raw.githubusercontent.com/apache/hertzbeat/master/manager/src/main/resources/define/app-redis_sentinel.yml)
[Doris BE](https://github.com/apache/hertzbeat/blob/master/manager/src/main/resources/define/app-doris_be.yml), [Doris FE](https://github.com/apache/hertzbeat/blob/master/manager/src/main/resources/define/app-doris_fe.yml),
[Memcached](https://github.com/apache/hertzbeat/blob/master/manager/src/main/resources/define/app-memcached.yml), [NebulaGraph](https://github.com/apache/hertzbeat/blob/master/manager/src/main/resources/define/app-nebulaGraph.yml)
- [Linux](https://raw.githubusercontent.com/apache/hertzbeat/master/manager/src/main/resources/define/app-linux.yml), [Ubuntu](https://raw.githubusercontent.com/apache/hertzbeat/master/manager/src/main/resources/define/app-ubuntu.yml),
[CentOS](https://raw.githubusercontent.com/apache/hertzbeat/master/manager/src/main/resources/define/app-centos.yml), [Windows](https://raw.githubusercontent.com/apache/hertzbeat/master/manager/src/main/resources/define/app-windows.yml),
[EulerOS](https://raw.githubusercontent.com/apache/hertzbeat/master/manager/src/main/resources/define/app-euleros.yml), [Fedora CoreOS](https://raw.githubusercontent.com/apache/hertzbeat/master/manager/src/main/resources/define/app-coreos.yml),
[OpenSUSE](https://raw.githubusercontent.com/apache/hertzbeat/master/manager/src/main/resources/define/app-opensuse.yml), [Rocky Linux](https://raw.githubusercontent.com/apache/hertzbeat/master/manager/src/main/resources/define/app-rockylinux.yml),
[Red Hat](https://raw.githubusercontent.com/apache/hertzbeat/master/manager/src/main/resources/define/app-redhat.yml), [FreeBSD](https://raw.githubusercontent.com/apache/hertzbeat/master/manager/src/main/resources/define/app-freebsd.yml),
[AlmaLinux](https://raw.githubusercontent.com/apache/hertzbeat/master/manager/src/main/resources/define/app-almalinux.yml), [Debian Linux](https://raw.githubusercontent.com/apache/hertzbeat/master/manager/src/main/resources/define/app-debian.yml)
- [Tomcat](https://raw.githubusercontent.com/apache/hertzbeat/master/manager/src/main/resources/define/app-tomcat.yml), [Nacos](https://raw.githubusercontent.com/apache/hertzbeat/master/manager/src/main/resources/define/app-nacos.yml),
[Zookeeper](https://raw.githubusercontent.com/apache/hertzbeat/master/manager/src/main/resources/define/app-zookeeper.yml), [RabbitMQ](https://raw.githubusercontent.com/apache/hertzbeat/master/manager/src/main/resources/define/app-rabbitmq.yml),
[Flink](https://raw.githubusercontent.com/apache/hertzbeat/master/manager/src/main/resources/define/app-flink.yml), [Kafka](https://raw.githubusercontent.com/apache/hertzbeat/master/manager/src/main/resources/define/app-kafka.yml),
[ShenYu](https://raw.githubusercontent.com/apache/hertzbeat/master/manager/src/main/resources/define/app-shenyu.yml), [DynamicTp](https://raw.githubusercontent.com/apache/hertzbeat/master/manager/src/main/resources/define/app-dynamic_tp.yml),
[Jetty](https://raw.githubusercontent.com/apache/hertzbeat/master/manager/src/main/resources/define/app-jetty.yml), [ActiveMQ](https://raw.githubusercontent.com/apache/hertzbeat/master/manager/src/main/resources/define/app-activemq.yml),
[Spring Gateway](https://raw.githubusercontent.com/apache/hertzbeat/master/manager/src/main/resources/define/app-spring_gateway.yml), [EMQX MQTT](https://raw.githubusercontent.com/apache/hertzbeat/master/manager/src/main/resources/define/app-emqx.yml),
[AirFlow](https://raw.githubusercontent.com/apache/hertzbeat/master/manager/src/main/resources/define/app-airflow.yml), [Hive](https://raw.githubusercontent.com/apache/hertzbeat/master/manager/src/main/resources/define/app-hive.yml),
[Spark](https://raw.githubusercontent.com/apache/hertzbeat/master/manager/src/main/resources/define/app-spark.yml), [Hadoop](https://raw.githubusercontent.com/apache/hertzbeat/master/manager/src/main/resources/define/app-hadoop.yml)
- [Kubernetes](https://raw.githubusercontent.com/apache/hertzbeat/master/manager/src/main/resources/define/app-kubernetes.yml), [Docker](https://raw.githubusercontent.com/apache/hertzbeat/master/manager/src/main/resources/define/app-docker.yml)
- [CiscoSwitch](https://raw.githubusercontent.com/apache/hertzbeat/master/manager/src/main/resources/define/app-cisco_switch.yml), [HpeSwitch](https://raw.githubusercontent.com/apache/hertzbeat/master/manager/src/main/resources/define/app-hpe_switch.yml),
[HuaweiSwitch](https://raw.githubusercontent.com/apache/hertzbeat/master/manager/src/main/resources/define/app-huawei_switch.yml), [TpLinkSwitch](https://raw.githubusercontent.com/apache/hertzbeat/master/manager/src/main/resources/define/app-tplink_switch.yml),
[H3cSwitch](https://raw.githubusercontent.com/apache/hertzbeat/master/manager/src/main/resources/define/app-h3c_switch.yml)
- And More Your Custom Template.
- Notified Support `Discord` `Slack` `Telegram` `Email` `Dingtalk` `WeChat` `FeiShu` `Webhook` `SMS` `ServerChan`.
## 🐕 Quick Start
## 🐕 Quick Start
- If you wish to deploy HertzBeat locally, please refer to the following Deployment Documentation for instructions.
### 🍞 Install HertzBeat
### 🍞 Install HertzBeat
> HertzBeat supports installation through source code, docker or package, cpu support x86/arm64.
> HertzBeat supports installation through source code, docker or package, cpu support x86/arm64.
##### 1Install quickly via docker
##### 1Install quickly via docker
1. Just one command to get started:
1. Just one command to get started
```docker run -d -p 1157:1157 -p 1158:1158 --name hertzbeat apache/hertzbeat```
```shell
docker run -d -p 1157:1157 -p 1158:1158 --name hertzbeat apache/hertzbeat
```
2. Access `http://localhost:1157` to start, default account: `admin/hertzbeat`
2. Access `http://localhost:1157` to start, default account: `admin/hertzbeat`
3. Deploy collector clusters (Optional)
```
docker run -d -e IDENTITY=custom-collector-name -e MANAGER_HOST=127.0.0.1 -e MANAGER_PORT=1158 --name hertzbeat-collector apache/hertzbeat-collector
```
- `-e IDENTITY=custom-collector-name` : set the collector unique identity name.
- `-e MODE=public` : set the running mode(public or private), public cluster or private cloud-edge.
- `-e MANAGER_HOST=127.0.0.1` : set the main hertzbeat server ip.
- `-e MANAGER_PORT=1158` : set the main hertzbeat server port, default 1158.
```shell
docker run -d -e IDENTITY=custom-collector-name -e MANAGER_HOST=127.0.0.1 -e MANAGER_PORT=1158 --name hertzbeat-collector apache/hertzbeat-collector
```
Detailed config refer to [Install HertzBeat via Docker](https://hertzbeat.apache.org/docs/start/docker-deploy)
- `-e IDENTITY=custom-collector-name` : set the collector unique identity name.
- `-e MODE=public` : set the running mode(public or private), public cluster or private cloud-edge.
- `-e MANAGER_HOST=127.0.0.1` : set the main hertzbeat server ip.
- `-e MANAGER_PORT=1158` : set the main hertzbeat server port, default 1158.
##### 2Install via package
1. Download the release package `hertzbeat-xx.tar.gz` [GITHUB Release](https://github.com/apache/hertzbeat/releases)
2. Configure the HertzBeat configuration yml file `hertzbeat/config/application.yml` (optional)
3. Run command `$ ./bin/startup.sh ` or `bin/startup.bat`
4. Access `http://localhost:1157` to start, default account: `admin/hertzbeat`
Detailed config refer to [Install HertzBeat via Docker](https://hertzbeat.apache.org/docs/start/docker-deploy)
##### 2Install via package
1. Download the release package `apache-hertzbeat-xx-bin.tar.gz` [Download](https://hertzbeat.apache.org/docs/download)
2. Configure the HertzBeat configuration yml file `hertzbeat/config/application.yml` (optional)
3. Run command `$ ./bin/startup.sh ` or `bin/startup.bat`
4. Access `http://localhost:1157` to start, default account: `admin/hertzbeat`
5. Deploy collector clusters (Optional)
- Download the release package `hertzbeat-collector-xx.tar.gz` to new machine [GITHUB Release](https://github.com/apache/hertzbeat/releases)
- Download the release package `apache-hertzbeat-collector-xx-bin.tar.gz` (JVM collector) or the native collector package for your platform, such as `apache-hertzbeat-collector-native-xx-linux-amd64-bin.tar.gz` or `apache-hertzbeat-collector-native-xx-windows-amd64-bin.zip`, to the new machine [Download](https://hertzbeat.apache.org/docs/download)
- Configure the collector configuration yml file `hertzbeat-collector/config/application.yml`: unique `identity` name, running `mode` (public or private), hertzbeat `manager-host`, hertzbeat `manager-port`
```yaml
collector:
@@ -146,27 +101,29 @@ Detailed config refer to [Install HertzBeat via Docker](https://hertzbeat.apache
manager-host: ${MANAGER_HOST:127.0.0.1}
manager-port: ${MANAGER_PORT:1158}
```
- Run command `$ ./bin/startup.sh ` or `bin/startup.bat`
- Access `http://localhost:1157` and you will see the registered new collector in dashboard
- If you do not provide JDBC drivers in `ext-lib`, MySQL, MariaDB, and OceanBase can use the built-in query engine and run on the native collector package as well. TiDB follows the same rule for its SQL query metric set.
- If `mysql-connector-j` is present in `ext-lib`, the built-in server collector or JVM collector automatically prefers JDBC after restart for MySQL, MariaDB, and OceanBase. TiDB follows the same rule for its SQL query metric set, while its HTTP metrics are unchanged. Oracle and DB2 still require the JVM collector package because they depend on external JDBC drivers.
- Run `$ ./bin/startup.sh ` or `bin/startup.bat` for the JVM collector package. Run `$ ./bin/startup.sh ` for Linux or macOS native collector packages, and `bin\\startup.bat` for the Windows native collector package.
- Access `http://localhost:1157` and you will see the registered new collector in dashboard
Detailed config refer to [Install HertzBeat via Package](https://hertzbeat.apache.org/docs/start/package-deploy)
Detailed config refer to [Install HertzBeat via Package](https://hertzbeat.apache.org/docs/start/package-deploy)
##### 3Start via source code
##### 3Start via source code
1. Local source code debugging needs to start the back-end project `manager` and the front-end project `web-app`.
2. Backendneed `maven3+`, `java17`, `lombok`, start the `manager` service.
3. Webneed `nodejs npm angular-cli` environment, Run `ng serve --open` in `web-app` directory after backend startup.
4. Access `http://localhost:4200` to start, default account: `admin/hertzbeat`
1. Local source code debugging needs to start the back-end project `hertzbeat-startup` and the front-end project `web-app`.
2. Backendneed `maven3+`, `java25`, `lombok`, add VM options in IDE: ` --add-opens=java.base/java.nio=org.apache.arrow.memory.core,ALL-UNNAMED `, then start the `hertzbeat-startup` service.
3. Webneed `nodejs` and `pnpm` environment, run `pnpm install` then `pnpm start` in `web-app` directory after backend startup.
4. Access `http://localhost:4200` to start, default account: `admin/hertzbeat`
Detailed steps refer to [CONTRIBUTING](CONTRIBUTING.md)
Detailed steps refer to [CONTRIBUTING](CONTRIBUTING.md)
##### 4Install All(hertzbeat+mysql+tsdb) via Docker-compose
##### 4Install All(hertzbeat+postgresql+tsdb) via Docker-compose
Install the mysql/postgresql database, iotdb/tdengine/victoria-metrics database and hertzbeat at one time through [docker-compose deployment script](script/docker-compose).
Install the postgresql/mysql database, victoria-metrics/iotdb/tdengine database and hertzbeat at one time through [docker-compose deployment script](script/docker-compose).
Detailed steps refer to [Install via Docker-Compose](script/docker-compose/README.md)
Detailed steps refer to [Install via Docker-Compose](script/docker-compose/README.md)
##### 5. Install All(hertzbeat+collector+mysql+tsdb) via kubernetes helm charts
##### 5: Install All(hertzbeat+collector+postgresql+tsdb) via kubernetes helm charts
Install HertzBeat cluster in a Kubernetes cluster by Helm chart.
@@ -174,14 +131,10 @@ Detailed steps refer to [Artifact Hub](https://artifacthub.io/packages/helm/hert
**HAVE FUN**
## 🥐 Roadmap
![hertzBeat](home/static/img/docs/hertzbeat-roadmap.png)
## ✨ Contributors
Thanks to these wonderful people, welcome to join us:
[Contributor Guide](CONTRIBUTING.md)
Thanks to these wonderful people, welcome to join us:
[Contributor Guide](CONTRIBUTING.md)
<!-- ALL-CONTRIBUTORS-LIST:START - Do not remove or modify this section -->
<!-- prettier-ignore-start -->
@@ -220,7 +173,7 @@ Thanks to these wonderful people, welcome to join us:
<td align="center" valign="top" width="14.28%"><a href="http://mroldx.xyz/"><img src="https://avatars.githubusercontent.com/u/34847828?v=4?s=100" width="100px;" alt="mroldx"/><br /><sub><b>mroldx</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=mroldx" title="Documentation">📖</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/woshiniusange"><img src="https://avatars.githubusercontent.com/u/91513022?v=4?s=100" width="100px;" alt="woshiniusange"/><br /><sub><b>woshiniusange</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=woshiniusange" title="Documentation">📖</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://vampireachao.github.io/"><img src="https://avatars.githubusercontent.com/u/52746628?v=4?s=100" width="100px;" alt="VampireAchao"/><br /><sub><b>VampireAchao</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=VampireAchao" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/Ceilzcx"><img src="https://avatars.githubusercontent.com/u/48920254?v=4?s=100" width="100px;" alt="zcx"/><br /><sub><b>zcx</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=Ceilzcx" title="Code">💻</a> <a href="https://github.com/apache/hertzbeat/issues?q=author%3ACeilzcx" title="Bug reports">🐛</a> <a href="#design-Ceilzcx" title="Design">🎨</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/Ceilzcx"><img src="https://avatars.githubusercontent.com/u/48920254?v=4?s=100" width="100px;" alt="zcx"/><br /><sub><b>zcx</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=Ceilzcx" title="Code">💻</a> <a href="https://github.com/apache/hertzbeat/issues?q=author%3ACeilzcx" title="Bug reports">🐛</a> <a href="#design-Ceilzcx" title="Design">🎨</a> <a href="https://github.com/apache/hertzbeat/commits?author=Ceilzcx" title="Tests">⚠️</a> <a href="#blog-Ceilzcx" title="Blogposts">📝</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/CharlieXCL"><img src="https://avatars.githubusercontent.com/u/91540487?v=4?s=100" width="100px;" alt="CharlieXCL"/><br /><sub><b>CharlieXCL</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=CharlieXCL" title="Documentation">📖</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/Privauto"><img src="https://avatars.githubusercontent.com/u/36581456?v=4?s=100" width="100px;" alt="Privauto"/><br /><sub><b>Privauto</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=Privauto" title="Code">💻</a> <a href="https://github.com/apache/hertzbeat/commits?author=Privauto" title="Documentation">📖</a></td>
</tr>
@@ -234,7 +187,7 @@ Thanks to these wonderful people, welcome to join us:
<td align="center" valign="top" width="14.28%"><a href="https://www.zhihu.com/people/kevinbauer"><img src="https://avatars.githubusercontent.com/u/28581579?v=4?s=100" width="100px;" alt="Kevin Huang"/><br /><sub><b>Kevin Huang</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=kevinhuangwl" title="Documentation">📖</a></td>
</tr>
<tr>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/TJxiaobao"><img src="https://avatars.githubusercontent.com/u/85919258?v=4?s=100" width="100px;" alt="铁甲小宝"/><br /><sub><b>铁甲小宝</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/issues?q=author%3ATJxiaobao" title="Bug reports">🐛</a> <a href="https://github.com/apache/hertzbeat/commits?author=TJxiaobao" title="Code">💻</a> <a href="https://github.com/apache/hertzbeat/commits?author=TJxiaobao" title="Documentation">📖</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/TJxiaobao"><img src="https://avatars.githubusercontent.com/u/85919258?v=4?s=100" width="100px;" alt="铁甲小宝"/><br /><sub><b>铁甲小宝</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/issues?q=author%3ATJxiaobao" title="Bug reports">🐛</a> <a href="https://github.com/apache/hertzbeat/commits?author=TJxiaobao" title="Code">💻</a> <a href="https://github.com/apache/hertzbeat/commits?author=TJxiaobao" title="Documentation">📖</a> <a href="https://github.com/apache/hertzbeat/commits?author=TJxiaobao" title="Tests">⚠️</a> <a href="#design-TJxiaobao" title="Design">🎨</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/Jack-123-power"><img src="https://avatars.githubusercontent.com/u/84333501?v=4?s=100" width="100px;" alt="Captain Jack"/><br /><sub><b>Captain Jack</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=Jack-123-power" title="Documentation">📖</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/haibo-duan"><img src="https://avatars.githubusercontent.com/u/7974845?v=4?s=100" width="100px;" alt="haibo.duan"/><br /><sub><b>haibo.duan</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=haibo-duan" title="Tests">⚠️</a> <a href="https://github.com/apache/hertzbeat/commits?author=haibo-duan" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/assassinfym"><img src="https://avatars.githubusercontent.com/u/15188754?v=4?s=100" width="100px;" alt="assassin"/><br /><sub><b>assassin</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/issues?q=author%3Aassassinfym" title="Bug reports">🐛</a> <a href="https://github.com/apache/hertzbeat/commits?author=assassinfym" title="Code">💻</a></td>
@@ -276,7 +229,7 @@ Thanks to these wonderful people, welcome to join us:
<td align="center" valign="top" width="14.28%"><a href="https://wjl110.xyz/"><img src="https://avatars.githubusercontent.com/u/53851034?v=4?s=100" width="100px;" alt="wjl110"/><br /><sub><b>wjl110</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=wjl110" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/ngyhd"><img src="https://avatars.githubusercontent.com/u/29095207?v=4?s=100" width="100px;" alt="Sean"/><br /><sub><b>Sean</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=ngyhd" title="Documentation">📖</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/Daydreamer-ia"><img src="https://avatars.githubusercontent.com/u/83362909?v=4?s=100" width="100px;" alt="chenyiqin"/><br /><sub><b>chenyiqin</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=Daydreamer-ia" title="Code">💻</a> <a href="https://github.com/apache/hertzbeat/commits?author=Daydreamer-ia" title="Tests">⚠️</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/hudongdong129"><img src="https://avatars.githubusercontent.com/u/34374227?v=4?s=100" width="100px;" alt="hudongdong129"/><br /><sub><b>hudongdong129</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=hudongdong129" title="Code">💻</a> <a href="https://github.com/apache/hertzbeat/commits?author=hudongdong129" title="Tests">⚠️</a> <a href="https://github.com/apache/hertzbeat/commits?author=hudongdong129" title="Documentation">📖</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/hudongdong129"><img src="https://avatars.githubusercontent.com/u/34374227?v=4?s=100" width="100px;" alt="hudongdong129"/><br /><sub><b>hudongdong129</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=hudongdong129" title="Code">💻</a> <a href="https://github.com/apache/hertzbeat/commits?author=hudongdong129" title="Tests">⚠️</a> <a href="https://github.com/apache/hertzbeat/commits?author=hudongdong129" title="Documentation">📖</a> <a href="#design-hudongdong129" title="Design">🎨</a></td>
</tr>
<tr>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/TherChenYang"><img src="https://avatars.githubusercontent.com/u/124348939?v=4?s=100" width="100px;" alt="TherChenYang"/><br /><sub><b>TherChenYang</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=TherChenYang" title="Code">💻</a> <a href="https://github.com/apache/hertzbeat/commits?author=TherChenYang" title="Tests">⚠️</a></td>
@@ -292,7 +245,7 @@ Thanks to these wonderful people, welcome to join us:
<td align="center" valign="top" width="14.28%"><a href="https://github.com/baiban114"><img src="https://avatars.githubusercontent.com/u/59152619?v=4?s=100" width="100px;" alt="TableRow"/><br /><sub><b>TableRow</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=baiban114" title="Documentation">📖</a> <a href="https://github.com/apache/hertzbeat/commits?author=baiban114" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/ByteIDance"><img src="https://avatars.githubusercontent.com/u/100207562?v=4?s=100" width="100px;" alt="ByteIDance"/><br /><sub><b>ByteIDance</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=ByteIDance" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/mangel2002"><img src="https://avatars.githubusercontent.com/u/9348020?v=4?s=100" width="100px;" alt="Jangfe"/><br /><sub><b>Jangfe</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=mangel2002" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/zqr10159"><img src="https://avatars.githubusercontent.com/u/30048352?v=4?s=100" width="100px;" alt="zqr10159"/><br /><sub><b>zqr10159</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=zqr10159" title="Documentation">📖</a> <a href="https://github.com/apache/hertzbeat/commits?author=zqr10159" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/zqr10159"><img src="https://avatars.githubusercontent.com/u/30048352?v=4?s=100" width="100px;" alt="zqr10159"/><br /><sub><b>zqr10159</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=zqr10159" title="Documentation">📖</a> <a href="https://github.com/apache/hertzbeat/commits?author=zqr10159" title="Code">💻</a> <a href="#blog-zqr10159" title="Blogposts">📝</a> <a href="https://github.com/apache/hertzbeat/issues?q=author%3Azqr10159" title="Bug reports">🐛</a> <a href="https://github.com/apache/hertzbeat/commits?author=zqr10159" title="Tests">⚠️</a> <a href="#design-zqr10159" title="Design">🎨</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/vinci-897"><img src="https://avatars.githubusercontent.com/u/55838224?v=4?s=100" width="100px;" alt="vinci"/><br /><sub><b>vinci</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=vinci-897" title="Code">💻</a> <a href="https://github.com/apache/hertzbeat/commits?author=vinci-897" title="Documentation">📖</a> <a href="#design-vinci-897" title="Design">🎨</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/js110"><img src="https://avatars.githubusercontent.com/u/51191863?v=4?s=100" width="100px;" alt="js110"/><br /><sub><b>js110</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=js110" title="Code">💻</a></td>
</tr>
@@ -306,8 +259,8 @@ Thanks to these wonderful people, welcome to join us:
<td align="center" valign="top" width="14.28%"><a href="https://github.com/ZangJuxy"><img src="https://avatars.githubusercontent.com/u/71380295?v=4?s=100" width="100px;" alt="ZangJuxy"/><br /><sub><b>ZangJuxy</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=ZangJuxy" title="Documentation">📖</a></td>
</tr>
<tr>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/l646505418"><img src="https://avatars.githubusercontent.com/u/50475131?v=4?s=100" width="100px;" alt="l646505418"/><br /><sub><b>l646505418</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=l646505418" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="http://www.carpewang.com"><img src="https://avatars.githubusercontent.com/u/78642589?v=4?s=100" width="100px;" alt="Carpe-Wang"/><br /><sub><b>Carpe-Wang</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=Carpe-Wang" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/l646505418"><img src="https://avatars.githubusercontent.com/u/50475131?v=4?s=100" width="100px;" alt="l646505418"/><br /><sub><b>l646505418</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=l646505418" title="Code">💻</a> <a href="https://github.com/apache/hertzbeat/issues?q=author%3Al646505418" title="Bug reports">🐛</a></td>
<td align="center" valign="top" width="14.28%"><a href="http://www.carpewang.com"><img src="https://avatars.githubusercontent.com/u/78642589?v=4?s=100" width="100px;" alt="Carpe-Wang"/><br /><sub><b>Carpe-Wang</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=Carpe-Wang" title="Code">💻</a> <a href="https://github.com/apache/hertzbeat/issues?q=author%3ACarpe-Wang" title="Bug reports">🐛</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/moshu023"><img src="https://avatars.githubusercontent.com/u/48593205?v=4?s=100" width="100px;" alt="莫枢"/><br /><sub><b>莫枢</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=moshu023" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/huangcanda"><img src="https://avatars.githubusercontent.com/u/4470566?v=4?s=100" width="100px;" alt="huangcanda"/><br /><sub><b>huangcanda</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=huangcanda" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://www.zrkizzy.com"><img src="https://avatars.githubusercontent.com/u/85340613?v=4?s=100" width="100px;" alt="世纪末的架构师"/><br /><sub><b>世纪末的架构师</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=Architect-Java" title="Code">💻</a></td>
@@ -357,7 +310,7 @@ Thanks to these wonderful people, welcome to join us:
<td align="center" valign="top" width="14.28%"><a href="https://github.com/lisongning"><img src="https://avatars.githubusercontent.com/u/93140178?v=4?s=100" width="100px;" alt="lisongning"/><br /><sub><b>lisongning</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=lisongning" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/YutingNie"><img src="https://avatars.githubusercontent.com/u/104416402?v=4?s=100" width="100px;" alt="YutingNie"/><br /><sub><b>YutingNie</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=YutingNie" title="Code">💻</a> <a href="https://github.com/apache/hertzbeat/commits?author=YutingNie" title="Documentation">📖</a> <a href="#design-YutingNie" title="Design">🎨</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/mikezzb"><img src="https://avatars.githubusercontent.com/u/23418428?v=4?s=100" width="100px;" alt="Mike Zhou"/><br /><sub><b>Mike Zhou</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=mikezzb" title="Code">💻</a> <a href="https://github.com/apache/hertzbeat/commits?author=mikezzb" title="Documentation">📖</a> <a href="#design-mikezzb" title="Design">🎨</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/a-little-fool"><img src="https://avatars.githubusercontent.com/u/105542329?v=4?s=100" width="100px;" alt="小笨蛋"/><br /><sub><b>小笨蛋</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=a-little-fool" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/lynx009"><img src="https://avatars.githubusercontent.com/u/105542329?v=4?s=100" width="100px;" alt="lynx009"/><br /><sub><b>lynx009</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=lynx009" title="Documentation">📖</a></td>
</tr>
<tr>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/littlezhongzer"><img src="https://avatars.githubusercontent.com/u/33685289?v=4?s=100" width="100px;" alt="littlezhongzer"/><br /><sub><b>littlezhongzer</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=littlezhongzer" title="Code">💻</a></td>
@@ -366,7 +319,7 @@ Thanks to these wonderful people, welcome to join us:
<td align="center" valign="top" width="14.28%"><a href="https://github.com/XimfengYao"><img src="https://avatars.githubusercontent.com/u/17541537?v=4?s=100" width="100px;" alt="姚贤丰"/><br /><sub><b>姚贤丰</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=XimfengYao" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/LINGLUOJUN"><img src="https://avatars.githubusercontent.com/u/16778977?v=4?s=100" width="100px;" alt="lingluojun"/><br /><sub><b>lingluojun</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=LINGLUOJUN" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="http://www.luelueking.com"><img src="https://avatars.githubusercontent.com/u/93204032?v=4?s=100" width="100px;" alt="1ue"/><br /><sub><b>1ue</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=luelueking" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="http://www.jimmyqiao.top"><img src="https://avatars.githubusercontent.com/u/67301054?v=4?s=100" width="100px;" alt="qyaaaa"/><br /><sub><b>qyaaaa</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=qyaaaa" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="http://www.jimmyqiao.top"><img src="https://avatars.githubusercontent.com/u/67301054?v=4?s=100" width="100px;" alt="qyaaaa"/><br /><sub><b>qyaaaa</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=qyaaaa" title="Code">💻</a> <a href="https://github.com/apache/hertzbeat/issues?q=author%3Aqyaaaa" title="Bug reports">🐛</a></td>
</tr>
<tr>
<td align="center" valign="top" width="14.28%"><a href="https://novohit.top"><img src="https://avatars.githubusercontent.com/u/101090395?v=4?s=100" width="100px;" alt="novohit"/><br /><sub><b>novohit</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=novohit" title="Code">💻</a></td>
@@ -380,14 +333,14 @@ Thanks to these wonderful people, welcome to join us:
<tr>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/1036664317"><img src="https://avatars.githubusercontent.com/u/7696697?v=4?s=100" width="100px;" alt="moghn"/><br /><sub><b>moghn</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=1036664317" title="Documentation">📖</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/xiaoguolong"><img src="https://avatars.githubusercontent.com/u/33684988?v=4?s=100" width="100px;" alt="xiaoguolong"/><br /><sub><b>xiaoguolong</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=xiaoguolong" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/Clownsw"><img src="https://avatars.githubusercontent.com/u/28394742?v=4?s=100" width="100px;" alt="Smliexx"/><br /><sub><b>Smliexx</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=Clownsw" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/Calvin979"><img src="https://avatars.githubusercontent.com/u/131688897?v=4?s=100" width="100px;" alt="Naruse"/><br /><sub><b>Naruse</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=Calvin979" title="Documentation">📖</a> <a href="https://github.com/apache/hertzbeat/commits?author=Calvin979" title="Code">💻</a> <a href="#design-Calvin979" title="Design">🎨</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/Clownsw"><img src="https://avatars.githubusercontent.com/u/28394742?v=4?s=100" width="100px;" alt="Smliexx"/><br /><sub><b>Smliexx</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=Clownsw" title="Code">💻</a> <a href="https://github.com/apache/hertzbeat/issues?q=author%3AClownsw" title="Bug reports">🐛</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/Calvin979"><img src="https://avatars.githubusercontent.com/u/131688897?v=4?s=100" width="100px;" alt="Calvin"/><br /><sub><b>Calvin</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=Calvin979" title="Documentation">📖</a> <a href="https://github.com/apache/hertzbeat/commits?author=Calvin979" title="Code">💻</a> <a href="#design-Calvin979" title="Design">🎨</a> <a href="https://github.com/apache/hertzbeat/issues?q=author%3ACalvin979" title="Bug reports">🐛</a> <a href="https://github.com/apache/hertzbeat/commits?author=Calvin979" title="Tests">⚠️</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/bbelide2"><img src="https://avatars.githubusercontent.com/u/26840796?v=4?s=100" width="100px;" alt="Bala Sukesh"/><br /><sub><b>Bala Sukesh</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=bbelide2" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/jinyaoMa"><img src="https://avatars.githubusercontent.com/u/25066570?v=4?s=100" width="100px;" alt="Jinyao Ma"/><br /><sub><b>Jinyao Ma</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=jinyaoMa" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://linuxsuren.github.io/open-source-best-practice/"><img src="https://avatars.githubusercontent.com/u/1450685?v=4?s=100" width="100px;" alt="Rick"/><br /><sub><b>Rick</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=LinuxSuRen" title="Code">💻</a> <a href="https://github.com/apache/hertzbeat/commits?author=LinuxSuRen" title="Tests">⚠️</a></td>
</tr>
<tr>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/ZY945"><img src="https://avatars.githubusercontent.com/u/74083801?v=4?s=100" width="100px;" alt="东风"/><br /><sub><b>东风</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=ZY945" title="Code">💻</a> <a href="#design-ZY945" title="Design">🎨</a> <a href="https://github.com/apache/hertzbeat/commits?author=ZY945" title="Documentation">📖</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/ZY945"><img src="https://avatars.githubusercontent.com/u/74083801?v=4?s=100" width="100px;" alt="东风"/><br /><sub><b>东风</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=ZY945" title="Code">💻</a> <a href="#design-ZY945" title="Design">🎨</a> <a href="https://github.com/apache/hertzbeat/commits?author=ZY945" title="Documentation">📖</a> <a href="https://github.com/apache/hertzbeat/issues?q=author%3AZY945" title="Bug reports">🐛</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/prolevel1"><img src="https://avatars.githubusercontent.com/u/51995525?v=4?s=100" width="100px;" alt="sonam singh"/><br /><sub><b>sonam singh</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=prolevel1" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/ZhangZixuan1994"><img src="https://avatars.githubusercontent.com/u/20011653?v=4?s=100" width="100px;" alt="ZhangZixuan1994"/><br /><sub><b>ZhangZixuan1994</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=ZhangZixuan1994" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/hurenjie1"><img src="https://avatars.githubusercontent.com/u/40120355?v=4?s=100" width="100px;" alt="SHIG"/><br /><sub><b>SHIG</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=hurenjie1" title="Code">💻</a></td>
@@ -397,29 +350,29 @@ Thanks to these wonderful people, welcome to join us:
</tr>
<tr>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/avvCode"><img src="https://avatars.githubusercontent.com/u/113538532?v=4?s=100" width="100px;" alt="avv"/><br /><sub><b>avv</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=avvCode" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/yqxxgh"><img src="https://avatars.githubusercontent.com/u/42080876?v=4?s=100" width="100px;" alt="yqxxgh"/><br /><sub><b>yqxxgh</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=yqxxgh" title="Documentation">📖</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/yqxxgh"><img src="https://avatars.githubusercontent.com/u/42080876?v=4?s=100" width="100px;" alt="yqxxgh"/><br /><sub><b>yqxxgh</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=yqxxgh" title="Documentation">📖</a> <a href="https://github.com/apache/hertzbeat/commits?author=yqxxgh" title="Code">💻</a> <a href="https://github.com/apache/hertzbeat/issues?q=author%3Ayqxxgh" title="Bug reports">🐛</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/CharlieShi46"><img src="https://avatars.githubusercontent.com/u/149798885?v=4?s=100" width="100px;" alt="CharlieShi46"/><br /><sub><b>CharlieShi46</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=CharlieShi46" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/Nctllnty"><img src="https://avatars.githubusercontent.com/u/33241818?v=4?s=100" width="100px;" alt="Nctllnty"/><br /><sub><b>Nctllnty</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=Nctllnty" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/Wang-Yonghao"><img src="https://avatars.githubusercontent.com/u/48146606?v=4?s=100" width="100px;" alt="Wang-Yonghao"/><br /><sub><b>Wang-Yonghao</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=Wang-Yonghao" title="Documentation">📖</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://www.yuque.com/dudiao/yy"><img src="https://avatars.githubusercontent.com/u/38355949?v=4?s=100" width="100px;" alt="读钓"/><br /><sub><b>读钓</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=dudiao" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/starmilkxin"><img src="https://avatars.githubusercontent.com/u/55646681?v=4?s=100" width="100px;" alt="Xin"/><br /><sub><b>Xin</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=starmilkxin" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/starmilkxin"><img src="https://avatars.githubusercontent.com/u/55646681?v=4?s=100" width="100px;" alt="Xin"/><br /><sub><b>Xin</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=starmilkxin" title="Code">💻</a> <a href="https://github.com/apache/hertzbeat/issues?q=author%3Astarmilkxin" title="Bug reports">🐛</a></td>
</tr>
<tr>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/handy-git"><img src="https://avatars.githubusercontent.com/u/32837980?v=4?s=100" width="100px;" alt="handy"/><br /><sub><b>handy</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=handy-git" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/LiuTianyou"><img src="https://avatars.githubusercontent.com/u/30208283?v=4?s=100" width="100px;" alt="LiuTianyou"/><br /><sub><b>LiuTianyou</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=LiuTianyou" title="Code">💻</a> <a href="https://github.com/apache/hertzbeat/commits?author=LiuTianyou" title="Documentation">📖</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/LiuTianyou"><img src="https://avatars.githubusercontent.com/u/30208283?v=4?s=100" width="100px;" alt="LiuTianyou"/><br /><sub><b>LiuTianyou</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=LiuTianyou" title="Code">💻</a> <a href="https://github.com/apache/hertzbeat/commits?author=LiuTianyou" title="Documentation">📖</a> <a href="https://github.com/apache/hertzbeat/issues?q=author%3ALiuTianyou" title="Bug reports">🐛</a> <a href="https://github.com/apache/hertzbeat/commits?author=LiuTianyou" title="Tests">⚠️</a> <a href="#blog-LiuTianyou" title="Blogposts">📝</a> <a href="#design-LiuTianyou" title="Design">🎨</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/WinterKi1ler"><img src="https://avatars.githubusercontent.com/u/160592092?v=4?s=100" width="100px;" alt="WinterKi1ler"/><br /><sub><b>WinterKi1ler</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=WinterKi1ler" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="http://sharehoo.cn/"><img src="https://avatars.githubusercontent.com/u/45377370?v=4?s=100" width="100px;" alt="miki"/><br /><sub><b>miki</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=miki-hmt" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://codeflex.substack.com/"><img src="https://avatars.githubusercontent.com/u/85513042?v=4?s=100" width="100px;" alt="Keshav Carpenter"/><br /><sub><b>Keshav Carpenter</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=alpha951" title="Code">💻</a> <a href="https://github.com/apache/hertzbeat/commits?author=alpha951" title="Documentation">📖</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/makechoicenow"><img src="https://avatars.githubusercontent.com/u/9911918?v=4?s=100" width="100px;" alt="makechoicenow"/><br /><sub><b>makechoicenow</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=makechoicenow" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/gjjjj0101"><img src="https://avatars.githubusercontent.com/u/71874373?v=4?s=100" width="100px;" alt="Gao Jian"/><br /><sub><b>Gao Jian</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=gjjjj0101" title="Code">💻</a> <a href="#design-gjjjj0101" title="Design">🎨</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/gjjjj0101"><img src="https://avatars.githubusercontent.com/u/71874373?v=4?s=100" width="100px;" alt="Gao Jian"/><br /><sub><b>Gao Jian</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=gjjjj0101" title="Tests">⚠️</a> <a href="https://github.com/apache/hertzbeat/commits?author=gjjjj0101" title="Code">💻</a> <a href="https://github.com/apache/hertzbeat/commits?author=gjjjj0101" title="Documentation">📖</a> <a href="#design-gjjjj0101" title="Design">🎨</a> <a href="https://github.com/apache/hertzbeat/issues?q=author%3Agjjjj0101" title="Bug reports">🐛</a></td>
</tr>
<tr>
<td align="center" valign="top" width="14.28%"><a href="https://jangto.tistory.com/"><img src="https://avatars.githubusercontent.com/u/37864182?v=4?s=100" width="100px;" alt="Hyeon Sung"/><br /><sub><b>Hyeon Sung</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=dukbong" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://crossoverjie.top/"><img src="https://avatars.githubusercontent.com/u/15684156?v=4?s=100" width="100px;" alt="crossoverJie"/><br /><sub><b>crossoverJie</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=crossoverJie" title="Code">💻</a> <a href="https://github.com/apache/hertzbeat/commits?author=crossoverJie" title="Documentation">📖</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://jangto.tistory.com/"><img src="https://avatars.githubusercontent.com/u/37864182?v=4?s=100" width="100px;" alt="Hyeon Sung"/><br /><sub><b>Hyeon Sung</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=dukbong" title="Code">💻</a> <a href="https://github.com/apache/hertzbeat/commits?author=dukbong" title="Documentation">📖</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://crossoverjie.top/"><img src="https://avatars.githubusercontent.com/u/15684156?v=4?s=100" width="100px;" alt="crossoverJie"/><br /><sub><b>crossoverJie</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=crossoverJie" title="Code">💻</a> <a href="https://github.com/apache/hertzbeat/commits?author=crossoverJie" title="Documentation">📖</a> <a href="#blog-crossoverJie" title="Blogposts">📝</a> <a href="https://github.com/apache/hertzbeat/commits?author=crossoverJie" title="Tests">⚠️</a> <a href="#design-crossoverJie" title="Design">🎨</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/PeixyJ"><img src="https://avatars.githubusercontent.com/u/45998593?v=4?s=100" width="100px;" alt="PeixyJ"/><br /><sub><b>PeixyJ</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=PeixyJ" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/Hi-Mr-Wind"><img src="https://avatars.githubusercontent.com/u/85803831?v=4?s=100" width="100px;" alt="风如歌"/><br /><sub><b>风如歌</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=Hi-Mr-Wind" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/MananPoojara"><img src="https://avatars.githubusercontent.com/u/104253184?v=4?s=100" width="100px;" alt="Manan Pujara"/><br /><sub><b>Manan Pujara</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=MananPoojara" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/xuziyang"><img src="https://avatars.githubusercontent.com/u/8465969?v=4?s=100" width="100px;" alt="xuziyang"/><br /><sub><b>xuziyang</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=xuziyang" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/xuziyang"><img src="https://avatars.githubusercontent.com/u/8465969?v=4?s=100" width="100px;" alt="xuziyang"/><br /><sub><b>xuziyang</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=xuziyang" title="Code">💻</a> <a href="https://github.com/apache/hertzbeat/commits?author=xuziyang" title="Documentation">📖</a> <a href="https://github.com/apache/hertzbeat/issues?q=author%3Axuziyang" title="Bug reports">🐛</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/lwqzz"><img src="https://avatars.githubusercontent.com/u/62584513?v=4?s=100" width="100px;" alt="lwqzz"/><br /><sub><b>lwqzz</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=lwqzz" title="Code">💻</a></td>
</tr>
<tr>
@@ -427,25 +380,159 @@ Thanks to these wonderful people, welcome to join us:
<td align="center" valign="top" width="14.28%"><a href="https://github.com/tomorrowshipyltm"><img src="https://avatars.githubusercontent.com/u/61336903?v=4?s=100" width="100px;" alt="tomorrowshipyltm"/><br /><sub><b>tomorrowshipyltm</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=tomorrowshipyltm" title="Documentation">📖</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/15613060203"><img src="https://avatars.githubusercontent.com/u/41351615?v=4?s=100" width="100px;" alt="栗磊"/><br /><sub><b>栗磊</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=15613060203" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/Alanxtl"><img src="https://avatars.githubusercontent.com/u/25652981?v=4?s=100" width="100px;" alt="Alan"/><br /><sub><b>Alan</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=Alanxtl" title="Documentation">📖</a></td>
<td align="center" valign="top" width="14.28%"><a href="http://www.hadoop.wiki/"><img src="https://avatars.githubusercontent.com/u/29418975?v=4?s=100" width="100px;" alt="Jast"/><br /><sub><b>Jast</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=zhangshenghang" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/zuobiao-zhou"><img src="https://avatars.githubusercontent.com/u/61108539?v=4?s=100" width="100px;" alt="Zhang Yuxuan"/><br /><sub><b>Zhang Yuxuan</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=zuobiao-zhou" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="http://www.hadoop.wiki/"><img src="https://avatars.githubusercontent.com/u/29418975?v=4?s=100" width="100px;" alt="Jast"/><br /><sub><b>Jast</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=zhangshenghang" title="Code">💻</a> <a href="#ideas-zhangshenghang" title="Ideas, Planning, & Feedback">🤔</a> <a href="https://github.com/apache/hertzbeat/commits?author=zhangshenghang" title="Documentation">📖</a> <a href="#blog-zhangshenghang" title="Blogposts">📝</a> <a href="https://github.com/apache/hertzbeat/issues?q=author%3Azhangshenghang" title="Bug reports">🐛</a> <a href="https://github.com/apache/hertzbeat/commits?author=zhangshenghang" title="Tests">⚠️</a> <a href="#design-zhangshenghang" title="Design">🎨</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/zuobiao-zhou"><img src="https://avatars.githubusercontent.com/u/61108539?v=4?s=100" width="100px;" alt="Zhang Yuxuan"/><br /><sub><b>Zhang Yuxuan</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=zuobiao-zhou" title="Code">💻</a> <a href="https://github.com/apache/hertzbeat/commits?author=zuobiao-zhou" title="Documentation">📖</a> <a href="https://github.com/apache/hertzbeat/issues?q=author%3Azuobiao-zhou" title="Bug reports">🐛</a> <a href="#blog-zuobiao-zhou" title="Blogposts">📝</a> <a href="https://github.com/apache/hertzbeat/commits?author=zuobiao-zhou" title="Tests">⚠️</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/Pzz-2021"><img src="https://avatars.githubusercontent.com/u/118056735?v=4?s=100" width="100px;" alt="P.P."/><br /><sub><b>P.P.</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=Pzz-2021" title="Code">💻</a></td>
</tr>
<tr>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/LLP2333"><img src="https://avatars.githubusercontent.com/u/61670545?v=4?s=100" width="100px;" alt="llp2333"/><br /><sub><b>llp2333</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=LLP2333" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/HeartLinked"><img src="https://avatars.githubusercontent.com/u/78212101?v=4?s=100" width="100px;" alt="feiyang li"/><br /><sub><b>feiyang li</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=HeartLinked" title="Documentation">📖</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/Aias00"><img src="https://avatars.githubusercontent.com/u/25810623?v=4?s=100" width="100px;" alt="aias00"/><br /><sub><b>aias00</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=Aias00" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/Aias00"><img src="https://avatars.githubusercontent.com/u/25810623?v=4?s=100" width="100px;" alt="aias00"/><br /><sub><b>aias00</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=Aias00" title="Code">💻</a> <a href="https://github.com/apache/hertzbeat/commits?author=Aias00" title="Documentation">📖</a> <a href="https://github.com/apache/hertzbeat/issues?q=author%3AAias00" title="Bug reports">🐛</a> <a href="#ideas-Aias00" title="Ideas, Planning, & Feedback">🤔</a> <a href="https://github.com/apache/hertzbeat/commits?author=Aias00" title="Tests">⚠️</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/westboy"><img src="https://avatars.githubusercontent.com/u/6385565?v=4?s=100" width="100px;" alt="Jin"/><br /><sub><b>Jin</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=westboy" title="Documentation">📖</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://blog.csdn.net/qq_52397471"><img src="https://avatars.githubusercontent.com/u/77964041?v=4?s=100" width="100px;" alt="YuLuo"/><br /><sub><b>YuLuo</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=yuluo-yx" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/Yanshuming1"><img src="https://avatars.githubusercontent.com/u/118667222?v=4?s=100" width="100px;" alt="xiaoming student"/><br /><sub><b>xiaoming student</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=Yanshuming1" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://blog.csdn.net/qq_52397471"><img src="https://avatars.githubusercontent.com/u/77964041?v=4?s=100" width="100px;" alt="YuLuo"/><br /><sub><b>YuLuo</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=yuluo-yx" title="Code">💻</a> <a href="https://github.com/apache/hertzbeat/issues?q=author%3Ayuluo-yx" title="Bug reports">🐛</a> <a href="https://github.com/apache/hertzbeat/commits?author=yuluo-yx" title="Tests">⚠️</a> <a href="#blog-yuluo-yx" title="Blogposts">📝</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/Yanshuming1"><img src="https://avatars.githubusercontent.com/u/118667222?v=4?s=100" width="100px;" alt="linDong"/><br /><sub><b>linDong</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=Yanshuming1" title="Code">💻</a> <a href="https://github.com/apache/hertzbeat/commits?author=Yanshuming1" title="Documentation">📖</a> <a href="https://github.com/apache/hertzbeat/issues?q=author%3AYanshuming1" title="Bug reports">🐛</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/lwjxy"><img src="https://avatars.githubusercontent.com/u/52726400?v=4?s=100" width="100px;" alt="lwjxy"/><br /><sub><b>lwjxy</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=lwjxy" title="Code">💻</a></td>
</tr>
<tr>
<td align="center" valign="top" width="14.28%"><a href="https://thespica.github.io/"><img src="https://avatars.githubusercontent.com/u/119573640?v=4?s=100" width="100px;" alt="John"/><br /><sub><b>John</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=Thespica" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://thespica.github.io/"><img src="https://avatars.githubusercontent.com/u/119573640?v=4?s=100" width="100px;" alt="John"/><br /><sub><b>John</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=Thespica" title="Code">💻</a> <a href="https://github.com/apache/hertzbeat/commits?author=Thespica" title="Documentation">📖</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/boatrainlsz"><img src="https://avatars.githubusercontent.com/u/18243785?v=4?s=100" width="100px;" alt="boatrainlsz"/><br /><sub><b>boatrainlsz</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=boatrainlsz" title="Documentation">📖</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://www.yitianyigexiangfa.com/"><img src="https://avatars.githubusercontent.com/u/3973419?v=4?s=100" width="100px;" alt="Bill Lau"/><br /><sub><b>Bill Lau</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=JavaProgrammerLB" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/lw-yang"><img src="https://avatars.githubusercontent.com/u/23456873?v=4?s=100" width="100px;" alt="lwyang"/><br /><sub><b>lwyang</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=lw-yang" title="Documentation">📖</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/xfl12345"><img src="https://avatars.githubusercontent.com/u/17960863?v=4?s=100" width="100px;" alt="xfl12345"/><br /><sub><b>xfl12345</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=xfl12345" title="Documentation">📖</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/yykaue"><img src="https://avatars.githubusercontent.com/u/22905143?v=4?s=100" width="100px;" alt="Limbo"/><br /><sub><b>Limbo</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=yykaue" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/irenhongyan"><img src="https://avatars.githubusercontent.com/u/53438321?v=4?s=100" width="100px;" alt="哈哈哈哈哈哈哈哈哈"/><br /><sub><b>哈哈哈哈哈哈哈哈哈</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=irenhongyan" title="Code">💻</a></td>
</tr>
<tr>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/ileonli"><img src="https://avatars.githubusercontent.com/u/45332412?v=4?s=100" width="100px;" alt="Leon Li"/><br /><sub><b>Leon Li</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=ileonli" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="http://fnil.net/"><img src="https://avatars.githubusercontent.com/u/14142?v=4?s=100" width="100px;" alt="dennis zhuang"/><br /><sub><b>dennis zhuang</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=killme2008" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/kerwin612"><img src="https://avatars.githubusercontent.com/u/3371163?v=4?s=100" width="100px;" alt="Kerwin Bryant"/><br /><sub><b>Kerwin Bryant</b></sub></a><br /><a href="#design-kerwin612" title="Design">🎨</a> <a href="https://github.com/apache/hertzbeat/commits?author=kerwin612" title="Code">💻</a> <a href="https://github.com/apache/hertzbeat/commits?author=kerwin612" title="Documentation">📖</a> <a href="https://github.com/apache/hertzbeat/issues?q=author%3Akerwin612" title="Bug reports">🐛</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/ShineDevelopment"><img src="https://avatars.githubusercontent.com/u/59306780?v=4?s=100" width="100px;" alt="daixianglong"/><br /><sub><b>daixianglong</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=ShineDevelopment" title="Documentation">📖</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/mchgood"><img src="https://avatars.githubusercontent.com/u/38482005?v=4?s=100" width="100px;" alt="mchgood"/><br /><sub><b>mchgood</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=mchgood" title="Documentation">📖</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/pwallk"><img src="https://avatars.githubusercontent.com/u/69385076?v=4?s=100" width="100px;" alt="kangli"/><br /><sub><b>kangli</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=pwallk" title="Code">💻</a> <a href="https://github.com/apache/hertzbeat/commits?author=pwallk" title="Documentation">📖</a> <a href="https://github.com/apache/hertzbeat/issues?q=author%3Apwallk" title="Bug reports">🐛</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/cdphantom"><img src="https://avatars.githubusercontent.com/u/12674795?v=4?s=100" width="100px;" alt="cdphantom"/><br /><sub><b>cdphantom</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=cdphantom" title="Code">💻</a></td>
</tr>
<tr>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/asd108908382"><img src="https://avatars.githubusercontent.com/u/77717999?v=4?s=100" width="100px;" alt="jiawei.guo"/><br /><sub><b>jiawei.guo</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=asd108908382" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/QBH-insist"><img src="https://avatars.githubusercontent.com/u/39401478?v=4?s=100" width="100px;" alt="QBH-insist"/><br /><sub><b>QBH-insist</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=QBH-insist" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/jiangsh-ui"><img src="https://avatars.githubusercontent.com/u/86990361?v=4?s=100" width="100px;" alt="jiangsh"/><br /><sub><b>jiangsh</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=jiangsh-ui" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/keaifafafa"><img src="https://avatars.githubusercontent.com/u/83876361?v=4?s=100" width="100px;" alt="Keaifa"/><br /><sub><b>Keaifa</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=keaifafafa" title="Code">💻</a> <a href="https://github.com/apache/hertzbeat/issues?q=author%3Akeaifafafa" title="Bug reports">🐛</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/loong95"><img src="https://avatars.githubusercontent.com/u/16333958?v=4?s=100" width="100px;" alt="Loong"/><br /><sub><b>Loong</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=loong95" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/ceekay47"><img src="https://avatars.githubusercontent.com/u/104664857?v=4?s=100" width="100px;" alt="Chandrakant Vankayalapati"/><br /><sub><b>Chandrakant Vankayalapati</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=ceekay47" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/MRgenial"><img src="https://avatars.githubusercontent.com/u/49973336?v=4?s=100" width="100px;" alt="b_mountain"/><br /><sub><b>b_mountain</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=MRgenial" title="Code">💻</a></td>
</tr>
<tr>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/TemirlanBasitov"><img src="https://avatars.githubusercontent.com/u/57500808?v=4?s=100" width="100px;" alt="TemirlanBasitov"/><br /><sub><b>TemirlanBasitov</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=TemirlanBasitov" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/wyfvsfy"><img src="https://avatars.githubusercontent.com/u/11973517?v=4?s=100" width="100px;" alt="wyfvsfy"/><br /><sub><b>wyfvsfy</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=wyfvsfy" title="Documentation">📖</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/sherry-peng2333"><img src="https://avatars.githubusercontent.com/u/70619577?v=4?s=100" width="100px;" alt="sherry-peng2333"/><br /><sub><b>sherry-peng2333</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=sherry-peng2333" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/lixiaobaivv"><img src="https://avatars.githubusercontent.com/u/39290771?v=4?s=100" width="100px;" alt="Yzzz"/><br /><sub><b>Yzzz</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=lixiaobaivv" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="http://www.bckf.cn/"><img src="https://avatars.githubusercontent.com/u/13309008?v=4?s=100" width="100px;" alt="puruidong"/><br /><sub><b>puruidong</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=pruidong" title="Documentation">📖</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/shinestare"><img src="https://avatars.githubusercontent.com/u/13570619?v=4?s=100" width="100px;" alt="shinestare"/><br /><sub><b>shinestare</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=shinestare" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/po-168"><img src="https://avatars.githubusercontent.com/u/185745593?v=4?s=100" width="100px;" alt="po-168"/><br /><sub><b>po-168</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=po-168" title="Code">💻</a></td>
</tr>
<tr>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/All-The-Best-for"><img src="https://avatars.githubusercontent.com/u/76414672?v=4?s=100" width="100px;" alt="wbs99"/><br /><sub><b>wbs99</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=All-The-Best-for" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/starryCoder"><img src="https://avatars.githubusercontent.com/u/46510059?v=4?s=100" width="100px;" alt="starryCoder"/><br /><sub><b>starryCoder</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=starryCoder" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/hasimmollah"><img src="https://avatars.githubusercontent.com/u/32538599?v=4?s=100" width="100px;" alt="hasimmollah"/><br /><sub><b>hasimmollah</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=hasimmollah" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/ayu-v0"><img src="https://avatars.githubusercontent.com/u/127600988?v=4?s=100" width="100px;" alt="Ayu"/><br /><sub><b>Ayu</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=ayu-v0" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/Rancho-7"><img src="https://avatars.githubusercontent.com/u/59016860?v=4?s=100" width="100px;" alt="Nick Guo"/><br /><sub><b>Nick Guo</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=Rancho-7" title="Documentation">📖</a> <a href="https://github.com/apache/hertzbeat/commits?author=Rancho-7" title="Code">💻</a> <a href="https://github.com/apache/hertzbeat/issues?q=author%3ARancho-7" title="Bug reports">🐛</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/doveLin0818"><img src="https://avatars.githubusercontent.com/u/190927907?v=4?s=100" width="100px;" alt="doveLin"/><br /><sub><b>doveLin</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=doveLin0818" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://zzrl.cc/"><img src="https://avatars.githubusercontent.com/u/91836599?v=4?s=100" width="100px;" alt="yunfan24"/><br /><sub><b>yunfan24</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=yunfan24" title="Code">💻</a> <a href="https://github.com/apache/hertzbeat/commits?author=yunfan24" title="Documentation">📖</a> <a href="https://github.com/apache/hertzbeat/issues?q=author%3Ayunfan24" title="Bug reports">🐛</a> <a href="https://github.com/apache/hertzbeat/commits?author=yunfan24" title="Tests">⚠️</a> <a href="#blog-yunfan24" title="Blogposts">📝</a></td>
</tr>
<tr>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/lctking"><img src="https://avatars.githubusercontent.com/u/168249998?v=4?s=100" width="100px;" alt="nullwli"/><br /><sub><b>nullwli</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=lctking" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://simonsigre.com/"><img src="https://avatars.githubusercontent.com/u/14932913?v=4?s=100" width="100px;" alt="Simon Sigré"/><br /><sub><b>Simon Sigré</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=simonsigre" title="Documentation">📖</a> <a href="https://github.com/apache/hertzbeat/commits?author=simonsigre" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="http://www.ponfee.cn/"><img src="https://avatars.githubusercontent.com/u/46117331?v=4?s=100" width="100px;" alt="ponfee"/><br /><sub><b>ponfee</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=ponfee" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/Vedant7789"><img src="https://avatars.githubusercontent.com/u/147625492?v=4?s=100" width="100px;" alt="Vedant7789"/><br /><sub><b>Vedant7789</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=Vedant7789" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/Craaaaazy77"><img src="https://avatars.githubusercontent.com/u/23025522?v=4?s=100" width="100px;" alt="Craaaaazy77"/><br /><sub><b>Craaaaazy77</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=Craaaaazy77" title="Documentation">📖</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/Suvrat1629"><img src="https://avatars.githubusercontent.com/u/140749446?v=4?s=100" width="100px;" alt="Suvrat1629"/><br /><sub><b>Suvrat1629</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=Suvrat1629" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="http://ghyghoo8.github.io/"><img src="https://avatars.githubusercontent.com/u/363129?v=4?s=100" width="100px;" alt="ghy"/><br /><sub><b>ghy</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=ghyghoo8" title="Code">💻</a></td>
</tr>
<tr>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/helei1030"><img src="https://avatars.githubusercontent.com/u/11839080?v=4?s=100" width="100px;" alt="helei1030"/><br /><sub><b>helei1030</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=helei1030" title="Documentation">📖</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://medium.com/@pjfanning"><img src="https://avatars.githubusercontent.com/u/11783444?v=4?s=100" width="100px;" alt="PJ Fanning"/><br /><sub><b>PJ Fanning</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=pjfanning" title="Code">💻</a> <a href="https://github.com/apache/hertzbeat/issues?q=author%3Apjfanning" title="Bug reports">🐛</a> <a href="https://github.com/apache/hertzbeat/commits?author=pjfanning" title="Tests">⚠️</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/MonsterChenzhuo"><img src="https://avatars.githubusercontent.com/u/60029759?v=4?s=100" width="100px;" alt="monster"/><br /><sub><b>monster</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=MonsterChenzhuo" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/MasamiYui"><img src="https://avatars.githubusercontent.com/u/22274133?v=4?s=100" width="100px;" alt="Sherlock Yin"/><br /><sub><b>Sherlock Yin</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=MasamiYui" title="Code">💻</a> <a href="https://github.com/apache/hertzbeat/commits?author=MasamiYui" title="Documentation">📖</a> <a href="https://github.com/apache/hertzbeat/issues?q=author%3AMasamiYui" title="Bug reports">🐛</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/wanhao23"><img src="https://avatars.githubusercontent.com/u/29560961?v=4?s=100" width="100px;" alt="wanhao"/><br /><sub><b>wanhao</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=wanhao23" title="Code">💻</a> <a href="https://github.com/apache/hertzbeat/commits?author=wanhao23" title="Documentation">📖</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/jonasHanhan"><img src="https://avatars.githubusercontent.com/u/130035609?v=4?s=100" width="100px;" alt="jonasHanhan"/><br /><sub><b>jonasHanhan</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=jonasHanhan" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/NikhilMurugesan"><img src="https://avatars.githubusercontent.com/u/49281792?v=4?s=100" width="100px;" alt="NikhilMurugesan"/><br /><sub><b>NikhilMurugesan</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=NikhilMurugesan" title="Code">💻</a></td>
</tr>
<tr>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/myangle1120"><img src="https://avatars.githubusercontent.com/u/19237013?v=4?s=100" width="100px;" alt="myangle1120"/><br /><sub><b>myangle1120</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=myangle1120" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/yasminvo"><img src="https://avatars.githubusercontent.com/u/107528848?v=4?s=100" width="100px;" alt="yasminvo"/><br /><sub><b>yasminvo</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=yasminvo" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/notbugggg"><img src="https://avatars.githubusercontent.com/u/147966331?v=4?s=100" width="100px;" alt="不关银渐层的事哦"/><br /><sub><b>不关银渐层的事哦</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=notbugggg" title="Code">💻</a> <a href="https://github.com/apache/hertzbeat/issues?q=author%3Anotbugggg" title="Bug reports">🐛</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/yyahang"><img src="https://avatars.githubusercontent.com/u/90464876?v=4?s=100" width="100px;" alt="yyahang"/><br /><sub><b>yyahang</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=yyahang" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/JuJinPark"><img src="https://avatars.githubusercontent.com/u/44892459?v=4?s=100" width="100px;" alt="jujin"/><br /><sub><b>jujin</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=JuJinPark" title="Code">💻</a> <a href="https://github.com/apache/hertzbeat/commits?author=JuJinPark" title="Documentation">📖</a> <a href="#ideas-JuJinPark" title="Ideas, Planning, & Feedback">🤔</a> <a href="#blog-JuJinPark" title="Blogposts">📝</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/LL-LIN"><img src="https://avatars.githubusercontent.com/u/43002118?v=4?s=100" width="100px;" alt="LL-LIN"/><br /><sub><b>LL-LIN</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=LL-LIN" title="Code">💻</a> <a href="https://github.com/apache/hertzbeat/issues?q=author%3ALL-LIN" title="Bug reports">🐛</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://bigcyy.github.io/"><img src="https://avatars.githubusercontent.com/u/73413979?v=4?s=100" width="100px;" alt="Yang Chen"/><br /><sub><b>Yang Chen</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=bigcyy" title="Code">💻</a> <a href="https://github.com/apache/hertzbeat/commits?author=bigcyy" title="Documentation">📖</a> <a href="https://github.com/apache/hertzbeat/issues?q=author%3Abigcyy" title="Bug reports">🐛</a></td>
</tr>
<tr>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/sarthakeash"><img src="https://avatars.githubusercontent.com/u/74091160?v=4?s=100" width="100px;" alt="Sarthak Arora"/><br /><sub><b>Sarthak Arora</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=sarthakeash" title="Code">💻</a> <a href="https://github.com/apache/hertzbeat/commits?author=sarthakeash" title="Documentation">📖</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/PengJingzhao"><img src="https://avatars.githubusercontent.com/u/97368949?v=4?s=100" width="100px;" alt="彭镜肇"/><br /><sub><b>彭镜肇</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=PengJingzhao" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/gagaradio"><img src="https://avatars.githubusercontent.com/u/18532370?v=4?s=100" width="100px;" alt="Walter Jia"/><br /><sub><b>Walter Jia</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=gagaradio" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/boyucjz"><img src="https://avatars.githubusercontent.com/u/18730041?v=4?s=100" width="100px;" alt="boyucjz"/><br /><sub><b>boyucjz</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=boyucjz" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/Cyanty"><img src="https://avatars.githubusercontent.com/u/153884653?v=4?s=100" width="100px;" alt="Cyanty"/><br /><sub><b>Cyanty</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=Cyanty" title="Code">💻</a> <a href="https://github.com/apache/hertzbeat/commits?author=Cyanty" title="Documentation">📖</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/KevinLLF"><img src="https://avatars.githubusercontent.com/u/85452733?v=4?s=100" width="100px;" alt="Jay丿167"/><br /><sub><b>Jay丿167</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=KevinLLF" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/Duansg"><img src="https://avatars.githubusercontent.com/u/112607719?v=4?s=100" width="100px;" alt="Duansg"/><br /><sub><b>Duansg</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=Duansg" title="Documentation">📖</a></td>
</tr>
<tr>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/xiaomizhou2"><img src="https://avatars.githubusercontent.com/u/47807926?v=4?s=100" width="100px;" alt="zhangyaxi"/><br /><sub><b>zhangyaxi</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=xiaomizhou2" title="Code">💻</a> <a href="https://github.com/apache/hertzbeat/commits?author=xiaomizhou2" title="Tests">⚠️</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/RainBondsongyg"><img src="https://avatars.githubusercontent.com/u/94501396?v=4?s=100" width="100px;" alt="songyg"/><br /><sub><b>songyg</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=RainBondsongyg" title="Documentation">📖</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/lx1229"><img src="https://avatars.githubusercontent.com/u/44620005?v=4?s=100" width="100px;" alt="Liuxin"/><br /><sub><b>Liuxin</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=lx1229" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/yy549159265"><img src="https://avatars.githubusercontent.com/u/40821310?v=4?s=100" width="100px;" alt="yy549159265"/><br /><sub><b>yy549159265</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=yy549159265" title="Code">💻</a> <a href="https://github.com/apache/hertzbeat/commits?author=yy549159265" title="Tests">⚠️</a> <a href="#design-yy549159265" title="Design">🎨</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/cto-huhang"><img src="https://avatars.githubusercontent.com/u/53338629?v=4?s=100" width="100px;" alt="cto-huhang"/><br /><sub><b>cto-huhang</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=cto-huhang" title="Documentation">📖</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/Saramanda9988"><img src="https://avatars.githubusercontent.com/u/176664901?v=4?s=100" width="100px;" alt="LunaRain_079"/><br /><sub><b>LunaRain_079</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=Saramanda9988" title="Documentation">📖</a> <a href="https://github.com/apache/hertzbeat/commits?author=Saramanda9988" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/delei"><img src="https://avatars.githubusercontent.com/u/17263766?v=4?s=100" width="100px;" alt="DeleiGuo"/><br /><sub><b>DeleiGuo</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=delei" title="Documentation">📖</a> <a href="https://github.com/apache/hertzbeat/commits?author=delei" title="Code">💻</a> <a href="https://github.com/apache/hertzbeat/commits?author=delei" title="Tests">⚠️</a> <a href="https://github.com/apache/hertzbeat/issues?q=author%3Adelei" title="Bug reports">🐛</a></td>
</tr>
<tr>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/chingjustwe"><img src="https://avatars.githubusercontent.com/u/13643747?v=4?s=100" width="100px;" alt="Rocky, Chi"/><br /><sub><b>Rocky, Chi</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=chingjustwe" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/rowankid"><img src="https://avatars.githubusercontent.com/u/18652781?v=4?s=100" width="100px;" alt="Wenqi Luo"/><br /><sub><b>Wenqi Luo</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/issues?q=author%3Arowankid" title="Bug reports">🐛</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/tuzuy"><img src="https://avatars.githubusercontent.com/u/95274591?v=4?s=100" width="100px;" alt="tuzuy"/><br /><sub><b>tuzuy</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=tuzuy" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/carlpinto25"><img src="https://avatars.githubusercontent.com/u/117299909?v=4?s=100" width="100px;" alt="carl pinto"/><br /><sub><b>carl pinto</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=carlpinto25" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://cxhello.top/"><img src="https://avatars.githubusercontent.com/u/49056040?v=4?s=100" width="100px;" alt="cxhello"/><br /><sub><b>cxhello</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=cxhello" title="Documentation">📖</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/jl15988"><img src="https://avatars.githubusercontent.com/u/70638770?v=4?s=100" width="100px;" alt="会功夫的李白"/><br /><sub><b>会功夫的李白</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=jl15988" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://blog.aytop.cloud/"><img src="https://avatars.githubusercontent.com/u/37127008?v=4?s=100" width="100px;" alt="Albert.Yang"/><br /><sub><b>Albert.Yang</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=AlbertYang0801" title="Code">💻</a></td>
</tr>
<tr>
<td align="center" valign="top" width="14.28%"><a href="https://blog.tokenlen.top/"><img src="https://avatars.githubusercontent.com/u/150590575?v=4?s=100" width="100px;" alt="zhou yong kang"/><br /><sub><b>zhou yong kang</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=mengnankkkk" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/warrobe"><img src="https://avatars.githubusercontent.com/u/89446159?v=4?s=100" width="100px;" alt="warrobe"/><br /><sub><b>warrobe</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=warrobe" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/Jetiaime"><img src="https://avatars.githubusercontent.com/u/93769000?v=4?s=100" width="100px;" alt="TeAmo"/><br /><sub><b>TeAmo</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=Jetiaime" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/pentium100"><img src="https://avatars.githubusercontent.com/u/27917?v=4?s=100" width="100px;" alt="pentium100"/><br /><sub><b>pentium100</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=pentium100" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/dedyks"><img src="https://avatars.githubusercontent.com/u/23741665?v=4?s=100" width="100px;" alt="Dedy Kurniawan Santoso"/><br /><sub><b>Dedy Kurniawan Santoso</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=dedyks" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/KOYR"><img src="https://avatars.githubusercontent.com/u/53216619?v=4?s=100" width="100px;" alt="KOYR"/><br /><sub><b>KOYR</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=KOYR" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/Lathika226"><img src="https://avatars.githubusercontent.com/u/178710568?v=4?s=100" width="100px;" alt="LathikaBaddam"/><br /><sub><b>LathikaBaddam</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=Lathika226" title="Documentation">📖</a></td>
</tr>
<tr>
<td align="center" valign="top" width="14.28%"><a href="https://shadwal.space/"><img src="https://avatars.githubusercontent.com/u/119167601?v=4?s=100" width="100px;" alt="Sahil Shadwal"/><br /><sub><b>Sahil Shadwal</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=Sahil-Shadwal" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/BhanuNidumolu"><img src="https://avatars.githubusercontent.com/u/180380413?v=4?s=100" width="100px;" alt="N.Bhanu Prasad"/><br /><sub><b>N.Bhanu Prasad</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=BhanuNidumolu" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://prakashh-portfolio.vercel.app/"><img src="https://avatars.githubusercontent.com/u/183058331?v=4?s=100" width="100px;" alt="Prakash Kumar"/><br /><sub><b>Prakash Kumar</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=Prakash1185" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/orangeCatDeveloper"><img src="https://avatars.githubusercontent.com/u/95899648?v=4?s=100" width="100px;" alt="NekoPunch"/><br /><sub><b>NekoPunch</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=orangeCatDeveloper" title="Code">💻</a> <a href="https://github.com/apache/hertzbeat/commits?author=orangeCatDeveloper" title="Documentation">📖</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://wy471x.github.io/"><img src="https://avatars.githubusercontent.com/u/52033069?v=4?s=100" width="100px;" alt="wy471x"/><br /><sub><b>wy471x</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=wy471x" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/hengyuss"><img src="https://avatars.githubusercontent.com/u/81064732?v=4?s=100" width="100px;" alt="hengyuss"/><br /><sub><b>hengyuss</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=hengyuss" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://moduvoice.com/"><img src="https://avatars.githubusercontent.com/u/291867022?v=4?s=100" width="100px;" alt="moduvoice"/><br /><sub><b>moduvoice</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=moduvoice" title="Documentation">📖</a></td>
</tr>
<tr>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/hutiefang76"><img src="https://avatars.githubusercontent.com/u/137664623?v=4?s=100" width="100px;" alt="hutiefang76"/><br /><sub><b>hutiefang76</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=hutiefang76" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://zylatent.com/"><img src="https://avatars.githubusercontent.com/u/250777154?v=4?s=100" width="100px;" alt="柳含知 Liu Hanzhi"/><br /><sub><b>柳含知 Liu Hanzhi</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=ZhouYinLong-lab" title="Documentation">📖</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/wilmerdooley"><img src="https://avatars.githubusercontent.com/u/259930736?v=4?s=100" width="100px;" alt="wilmerdooley"/><br /><sub><b>wilmerdooley</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=wilmerdooley" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/Zmjjeff7"><img src="https://avatars.githubusercontent.com/u/175370943?v=4?s=100" width="100px;" alt="Zhenhong Guo"/><br /><sub><b>Zhenhong Guo</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=Zmjjeff7" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/abhyudayareddy"><img src="https://avatars.githubusercontent.com/u/54602866?v=4?s=100" width="100px;" alt="abhyudayareddy"/><br /><sub><b>abhyudayareddy</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=abhyudayareddy" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/neon-hippo"><img src="https://avatars.githubusercontent.com/u/165560498?v=4?s=100" width="100px;" alt="neon-hippo"/><br /><sub><b>neon-hippo</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=neon-hippo" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/P-Peaceful"><img src="https://avatars.githubusercontent.com/u/52856161?v=4?s=100" width="100px;" alt="P_Peaceful"/><br /><sub><b>P_Peaceful</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=P-Peaceful" title="Code">💻</a> <a href="https://github.com/apache/hertzbeat/commits?author=P-Peaceful" title="Documentation">📖</a></td>
</tr>
<tr>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/zhusaidong"><img src="https://avatars.githubusercontent.com/u/3039961?v=4?s=100" width="100px;" alt="zhusaidong"/><br /><sub><b>zhusaidong</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=zhusaidong" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/zhehenlu"><img src="https://avatars.githubusercontent.com/u/31504542?v=4?s=100" width="100px;" alt="zhlu"/><br /><sub><b>zhlu</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=zhehenlu" title="Code">💻</a> <a href="https://github.com/apache/hertzbeat/commits?author=zhehenlu" title="Documentation">📖</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/brettgervasoni"><img src="https://avatars.githubusercontent.com/u/34056000?v=4?s=100" width="100px;" alt="brettgervasoni"/><br /><sub><b>brettgervasoni</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=brettgervasoni" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/Darshan-paul"><img src="https://avatars.githubusercontent.com/u/211450705?v=4?s=100" width="100px;" alt="Darshan-paul"/><br /><sub><b>Darshan-paul</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=Darshan-paul" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/04cb"><img src="https://avatars.githubusercontent.com/u/111667698?v=4?s=100" width="100px;" alt="layla"/><br /><sub><b>layla</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=04cb" title="Documentation">📖</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/miantalha45"><img src="https://avatars.githubusercontent.com/u/155809113?v=4?s=100" width="100px;" alt="Talha Amjad"/><br /><sub><b>Talha Amjad</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=miantalha45" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://turanalmammadov.com/"><img src="https://avatars.githubusercontent.com/u/16321061?v=4?s=100" width="100px;" alt="Turan Almammadov"/><br /><sub><b>Turan Almammadov</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=turanalmammadov" title="Code">💻</a> <a href="https://github.com/apache/hertzbeat/commits?author=turanalmammadov" title="Documentation">📖</a></td>
</tr>
<tr>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/zhaoyangplus"><img src="https://avatars.githubusercontent.com/u/245090302?v=4?s=100" width="100px;" alt="zhaoyangplus"/><br /><sub><b>zhaoyangplus</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=zhaoyangplus" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/yexuanyang"><img src="https://avatars.githubusercontent.com/u/73885401?v=4?s=100" width="100px;" alt="Yang Yexuan"/><br /><sub><b>Yang Yexuan</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=yexuanyang" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/markguo123"><img src="https://avatars.githubusercontent.com/u/155072651?v=4?s=100" width="100px;" alt="markguo123"/><br /><sub><b>markguo123</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=markguo123" title="Documentation">📖</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/leo-934"><img src="https://avatars.githubusercontent.com/u/55838224?v=4?s=100" width="100px;" alt="leo"/><br /><sub><b>leo</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=leo-934" title="Code">💻</a> <a href="https://github.com/apache/hertzbeat/commits?author=leo-934" title="Documentation">📖</a> <a href="#blog-leo-934" title="Blogposts">📝</a></td>
</tr>
</tbody>
</table>
@@ -453,7 +540,7 @@ Thanks to these wonderful people, welcome to join us:
<!-- markdownlint-restore -->
<!-- prettier-ignore-end -->
<!-- ALL-CONTRIBUTORS-LIST:END -->
<!-- ALL-CONTRIBUTORS-LIST:END -->
## 💬 Join discussion
@@ -463,17 +550,13 @@ Thanks to these wonderful people, welcome to join us:
[Chat On Discord](https://discord.gg/Fb6M73htGr)
WeChat Group : Add friend `tan-cloud` and invite to the group.
WeChat Group : Add friend `ahertzbeat` and invite to the group.
WeChat Public : Search ID `usthecom`.
[QQ Group](https://jq.qq.com/?_wv=1027&k=Bud9OzdI) : Group num `630061200`
WeChat Official Account : Search ID `usthecom`.
[Github Discussion](https://github.com/apache/hertzbeat/discussions)
[Reddit Community](https://www.reddit.com/r/hertzbeat/)
[Follow Us Twitter](https://twitter.com/hertzbeat1024)
[Follow Us Twitter](https://x.com/hertzbeat1024)
[Subscribe YouTube](https://www.youtube.com/channel/UCri75zfWX0GHqJFPENEbLow)
@@ -489,15 +572,9 @@ HertzBeat is built on so many great open source projects, thanks to them!
<p align="left">
<img src="./home/static/img/home/cncf-landscape-left-logo.svg" width="300">&nbsp;&nbsp;<img src="./home/static/img/home/cncf-right-logo.svg" width="345" />
<br /><br />
HertzBeat has been included in the <a href="https://landscape.cncf.io/guide?item=observability-and-analysis--monitoring--hertzbeat#observability-and-analysis--monitoring">
CNCF Observability And Analysis - Monitoring Landscape.</a>
HertzBeat has been included in the <a href="https://landscape.cncf.io/?item=observability-and-analysis--observability--hertzbeat">
CNCF Observability And Analysis - Observability Landscape.</a>
</p>
## Star History
[![Star History Chart](https://api.star-history.com/svg?repos=apache/hertzbeat&type=Date)](https://star-history.com/#apache/hertzbeat&Date)
## 🛡️ License
[`Apache License, Version 2.0`](https://www.apache.org/licenses/LICENSE-2.0.html)
+217 -140
View File
@@ -4,135 +4,90 @@
</a>
</p>
<h4 align="center">
<a href="README_CN.md">中文文档</a> | <a href="README.md">English Document</a>
</h4>
> 实时监控系统,无需 Agent,性能集群,兼容 Prometheus,自定义监控和状态页构建能力。
<p align="center">
<b>Readme</b>:
<a href="README.md">English</a> | <b><a href="README_CN.md">中文</a></b> | <a href="README_JP.md">日本語</a>
</p>
[![Discord](https://img.shields.io/badge/Chat-Discord-7289DA?logo=discord)](https://discord.gg/Fb6M73htGr)
[![Reddit](https://img.shields.io/badge/Reddit-Community-7289DA?logo=reddit)](https://www.reddit.com/r/hertzbeat/)
[![Twitter](https://img.shields.io/twitter/follow/hertzbeat1024?logo=twitter)](https://twitter.com/hertzbeat1024)
[![Twitter](https://img.shields.io/twitter/follow/hertzbeat1024?logo=twitter)](https://x.com/hertzbeat1024)
[![OpenSSF Best Practices](https://www.bestpractices.dev/projects/8139/badge)](https://www.bestpractices.dev/projects/8139)
[![Docker Pulls](https://img.shields.io/docker/pulls/apache/hertzbeat?style=%20for-the-badge&logo=docker&label=DockerHub%20Download)](https://hub.docker.com/repository/docker/apache/hertzbeat/general)
[![codecov](https://codecov.io/gh/apache/HertzBeat/branch/master/graph/badge.svg)](https://app.codecov.io/gh/apache/hertzbeat)
[![Docker Pulls](https://img.shields.io/docker/pulls/apache/hertzbeat?style=%20for-the-badge&logo=docker&label=DockerHub%20Download)](https://hub.docker.com/r/apache/hertzbeat)
[![Artifact Hub](https://img.shields.io/endpoint?url=https://artifacthub.io/badge/repository/hertzbeat)](https://artifacthub.io/packages/search?repo=hertzbeat)
[![YouTube Channel Subscribers](https://img.shields.io/youtube/channel/subscribers/UCri75zfWX0GHqJFPENEbLow?logo=youtube&label=YouTube%20Channel)](https://www.youtube.com/channel/UCri75zfWX0GHqJFPENEbLow)
[![Contribute with Gitpod](https://img.shields.io/badge/Contribute%20with-Gitpod-908a85?logo=gitpod&color=green)](https://gitpod.io/#https://github.com/apache/hertzbeat)
**官网: [hertzbeat.apache.org](https://hertzbeat.apache.org)**
**官网: [hertzbeat.apache.org](https://hertzbeat.apache.org)**
**邮件: <a href="mailto:dev-subscribe@hertzbeat.apache.org">发送至 ```dev-subscribe@hertzbeat.apache.org```</a>** 订阅邮件列表
## 🎡 <font color="green">介绍</font>
[Apache HertzBeat](https://github.com/apache/hertzbeat) (incubating)是一个易用友好的开源实时监控告警系统,无需 Agent,高性能集群,兼容 Prometheus提供强大的自定义监控和状态页构建能力。
[Apache HertzBeat](https://github.com/apache/hertzbeat) 是 AI 驱动的下一代开源实时观测系统。指标日志统一收集,告警一站分发,智能管控分析。无需 Agent,高性能集群,提供强大的自定义监控和状态页构建能力。
### 特点
- **监控+告警+通知** 为一体,支持对应用服务,应用程序,数据库,缓存,操作系统,大数据,中间件,Web 服务器,云原生,网络,自定义等监控阈值告警通知一步到位
- 易用友好,无需 `Agent`,全 `WEB` 页面操作,鼠标点一点就能监控告警,零上手学习成本。
- `Http, Jmx, Ssh, Snmp, Jdbc, Prometheus` 等协议规范可配置化,只需在浏览器配置监控模版 `YML` 就能使用这些协议去自定义采集想要的指标。您相信只需配置下就能立刻适配一款 `K8s``Docker` 等新的监控类型吗?
- 兼容 `Prometheus` 的系统生态并且更多,只需页面操作就可以监控 `Prometheus` 所能监控的
-```采集+分析+告警+通知```为一体,HertzBeat AI 驱动下的新交互与功能,也内置 MCP Server 对外能力
- 统一的指标平台,无需 Agent,兼容 Prometheus,支持应用服务,程序,数据库,缓存,操作系统,大数据,中间件,Web 服务器,云原生,网络,自定义等。
- 统一的日志平台,通过 OTLP 协议多日志源无缝对接上报。
- 统一的告警平台,内部告警与外部多种告警源集成接入,统一告警处理分析,灵活的实时与周期阈值规则,分组收敛,静默,抑制等
- 统一的消息分发,告警平台处理后通过 `邮件` `Discord` `Slack` `Telegram` `钉钉` `微信` `飞书` `短信` `Webhook` `Server酱` 等方式分发通知。
-`Http, Jmx, Ssh, Snmp, Jdbc, Prometheus` 等协议规范可配置化,只需配置模板 `YML` 就能自定义采集指标。您相信只需简单配置即可快速适配一款 `K8s``Docker` 等新的监控类型吗?
- 高性能,支持多采集器集群横向扩展,支持多隔离网络监控,云边协同。
- 自由的告警阈值规则,`邮件` `Discord` `Slack` `Telegram` `钉钉` `微信` `飞书` `短信` `Webhook` `Server酱` 等方式消息及时送达。
- 提供强大的状态页构建能力,轻松向用户传达您产品服务的实时状态。
> `HertzBeat`的强大自定义,多类型支持,高性能,易扩展,低耦合,希望能帮助用户快速搭建自有监控系统。
> `HertzBeat`的统一平台,AI智能,强大自定义,多类型支持,高性能,易扩展,希望能帮助用户快速方便实现观测需求。
----
----
![hertzbeat](home/static/img/home/1.png)
----
![hertzbeat](home/static/img/home/status.png)
## 🥐 模块
![hertzbeat](home/static/img/home/9.png)
![hertzBeat](home/static/img/docs/hertzbeat-arch.png)
----
## 🐕 快速开始
## 🥐 模块
![hertzBeat](home/static/img/docs/hertzbeat-arch.png)
## ⛄ 已支持
> 我们将监控采集类型(mysql,jvm,k8s)都定义为 `yml` 监控模版,用户可以导入这些模版来支持对应类型的监控!
> 欢迎大家一起贡献你使用过程中自定义的通用监控类型监控模版。
- [Website](https://raw.githubusercontent.com/apache/hertzbeat/master/manager/src/main/resources/define/app-website.yml), [Port Telnet](https://raw.githubusercontent.com/apache/hertzbeat/master/manager/src/main/resources/define/app-port.yml),
[Http Api](https://raw.githubusercontent.com/apache/hertzbeat/master/manager/src/main/resources/define/app-api.yml), [Ping Connect](https://raw.githubusercontent.com/apache/hertzbeat/master/manager/src/main/resources/define/app-ping.yml),
[Jvm](https://raw.githubusercontent.com/apache/hertzbeat/master/manager/src/main/resources/define/app-jvm.yml), [SiteMap](https://raw.githubusercontent.com/apache/hertzbeat/master/manager/src/main/resources/define/app-fullsite.yml),
[Ssl Certificate](https://raw.githubusercontent.com/apache/hertzbeat/master/manager/src/main/resources/define/app-ssl_cert.yml), [SpringBoot2](https://raw.githubusercontent.com/apache/hertzbeat/master/manager/src/main/resources/define/app-springboot2.yml),
[FTP Server](https://raw.githubusercontent.com/apache/hertzbeat/master/manager/src/main/resources/define/app-ftp.yml), [SpringBoot3](https://raw.githubusercontent.com/apache/hertzbeat/master/manager/src/main/resources/define/app-springboot3.yml),
[Udp Port](https://raw.githubusercontent.com/apache/hertzbeat/master/manager/src/main/resources/define/app-udp.yml), [Dns](https://raw.githubusercontent.com/apache/hertzbeat/master/manager/src/main/resources/define/app-dns.yml),
[Pop3](https://raw.githubusercontent.com/apache/hertzbeat/master/manager/src/main/resources/define/app-pop3.yml), [Ntp](https://raw.githubusercontent.com/apache/hertzbeat/master/manager/src/main/resources/define/app-ntp.yml),
[Api Code](https://raw.githubusercontent.com/apache/hertzbeat/master/manager/src/main/resources/define/app-api_code.yml), [Smtp](https://raw.githubusercontent.com/apache/hertzbeat/master/manager/src/main/resources/define/app-smtp.yml),
[Nginx](https://raw.githubusercontent.com/apache/hertzbeat/master/manager/src/main/resources/define/app-nginx.yml)
- [Mysql](https://raw.githubusercontent.com/apache/hertzbeat/master/manager/src/main/resources/define/app-mysql.yml), [PostgreSQL](https://raw.githubusercontent.com/apache/hertzbeat/master/manager/src/main/resources/define/app-postgresql.yml),
[MariaDB](https://raw.githubusercontent.com/apache/hertzbeat/master/manager/src/main/resources/define/app-mariadb.yml), [Redis](https://raw.githubusercontent.com/apache/hertzbeat/master/manager/src/main/resources/define/app-redis.yml),
[ElasticSearch](https://raw.githubusercontent.com/apache/hertzbeat/master/manager/src/main/resources/define/app-elasticsearch.yml), [SqlServer](https://raw.githubusercontent.com/apache/hertzbeat/master/manager/src/main/resources/define/app-sqlserver.yml),
[Oracle](https://raw.githubusercontent.com/apache/hertzbeat/master/manager/src/main/resources/define/app-oracle.yml), [MongoDB](https://raw.githubusercontent.com/apache/hertzbeat/master/manager/src/main/resources/define/app-mongodb.yml),
[DM](https://raw.githubusercontent.com/apache/hertzbeat/master/manager/src/main/resources/define/app-dm.yml), [OpenGauss](https://raw.githubusercontent.com/apache/hertzbeat/master/manager/src/main/resources/define/app-opengauss.yml),
[ClickHouse](https://raw.githubusercontent.com/apache/hertzbeat/master/manager/src/main/resources/define/app-clickhouse.yml), [IoTDB](https://raw.githubusercontent.com/apache/hertzbeat/master/manager/src/main/resources/define/app-iotdb.yml),
[Redis Cluster](https://raw.githubusercontent.com/apache/hertzbeat/master/manager/src/main/resources/define/app-redis_cluster.yml), [Redis Sentinel](https://raw.githubusercontent.com/apache/hertzbeat/master/manager/src/main/resources/define/app-redis_sentinel.yml)
[Doris BE](https://github.com/apache/hertzbeat/blob/master/manager/src/main/resources/define/app-doris_be.yml), [Doris FE](https://github.com/apache/hertzbeat/blob/master/manager/src/main/resources/define/app-doris_fe.yml),
[Memcached](https://github.com/apache/hertzbeat/blob/master/manager/src/main/resources/define/app-memcached.yml), [NebulaGraph](https://github.com/apache/hertzbeat/blob/master/manager/src/main/resources/define/app-nebulaGraph.yml)
- [Linux](https://raw.githubusercontent.com/apache/hertzbeat/master/manager/src/main/resources/define/app-linux.yml), [Ubuntu](https://raw.githubusercontent.com/apache/hertzbeat/master/manager/src/main/resources/define/app-ubuntu.yml),
[CentOS](https://raw.githubusercontent.com/apache/hertzbeat/master/manager/src/main/resources/define/app-centos.yml), [Windows](https://raw.githubusercontent.com/apache/hertzbeat/master/manager/src/main/resources/define/app-windows.yml),
[EulerOS](https://raw.githubusercontent.com/apache/hertzbeat/master/manager/src/main/resources/define/app-euleros.yml), [Fedora CoreOS](https://raw.githubusercontent.com/apache/hertzbeat/master/manager/src/main/resources/define/app-coreos.yml),
[OpenSUSE](https://raw.githubusercontent.com/apache/hertzbeat/master/manager/src/main/resources/define/app-opensuse.yml), [Rocky Linux](https://raw.githubusercontent.com/apache/hertzbeat/master/manager/src/main/resources/define/app-rockylinux.yml),
[Red Hat](https://raw.githubusercontent.com/apache/hertzbeat/master/manager/src/main/resources/define/app-redhat.yml), [FreeBSD](https://raw.githubusercontent.com/apache/hertzbeat/master/manager/src/main/resources/define/app-freebsd.yml),
[AlmaLinux](https://raw.githubusercontent.com/apache/hertzbeat/master/manager/src/main/resources/define/app-almalinux.yml), [Debian Linux](https://raw.githubusercontent.com/apache/hertzbeat/master/manager/src/main/resources/define/app-debian.yml)
- [Tomcat](https://raw.githubusercontent.com/apache/hertzbeat/master/manager/src/main/resources/define/app-tomcat.yml), [Nacos](https://raw.githubusercontent.com/apache/hertzbeat/master/manager/src/main/resources/define/app-nacos.yml),
[Zookeeper](https://raw.githubusercontent.com/apache/hertzbeat/master/manager/src/main/resources/define/app-zookeeper.yml), [RabbitMQ](https://raw.githubusercontent.com/apache/hertzbeat/master/manager/src/main/resources/define/app-rabbitmq.yml),
[Flink](https://raw.githubusercontent.com/apache/hertzbeat/master/manager/src/main/resources/define/app-flink.yml), [Kafka](https://raw.githubusercontent.com/apache/hertzbeat/master/manager/src/main/resources/define/app-kafka.yml),
[ShenYu](https://raw.githubusercontent.com/apache/hertzbeat/master/manager/src/main/resources/define/app-shenyu.yml), [DynamicTp](https://raw.githubusercontent.com/apache/hertzbeat/master/manager/src/main/resources/define/app-dynamic_tp.yml),
[Jetty](https://raw.githubusercontent.com/apache/hertzbeat/master/manager/src/main/resources/define/app-jetty.yml), [ActiveMQ](https://raw.githubusercontent.com/apache/hertzbeat/master/manager/src/main/resources/define/app-activemq.yml),
[Spring Gateway](https://raw.githubusercontent.com/apache/hertzbeat/master/manager/src/main/resources/define/app-spring_gateway.yml), [EMQX MQTT](https://raw.githubusercontent.com/apache/hertzbeat/master/manager/src/main/resources/define/app-emqx.yml),
[AirFlow](https://raw.githubusercontent.com/apache/hertzbeat/master/manager/src/main/resources/define/app-airflow.yml), [Hive](https://raw.githubusercontent.com/apache/hertzbeat/master/manager/src/main/resources/define/app-hive.yml),
[Spark](https://raw.githubusercontent.com/apache/hertzbeat/master/manager/src/main/resources/define/app-spark.yml), [Hadoop](https://raw.githubusercontent.com/apache/hertzbeat/master/manager/src/main/resources/define/app-hadoop.yml)
- [Kubernetes](https://raw.githubusercontent.com/apache/hertzbeat/master/manager/src/main/resources/define/app-kubernetes.yml), [Docker](https://raw.githubusercontent.com/apache/hertzbeat/master/manager/src/main/resources/define/app-docker.yml)
- [CiscoSwitch](https://raw.githubusercontent.com/apache/hertzbeat/master/manager/src/main/resources/define/app-cisco_switch.yml), [HpeSwitch](https://raw.githubusercontent.com/apache/hertzbeat/master/manager/src/main/resources/define/app-hpe_switch.yml),
[HuaweiSwitch](https://raw.githubusercontent.com/apache/hertzbeat/master/manager/src/main/resources/define/app-huawei_switch.yml), [TpLinkSwitch](https://raw.githubusercontent.com/apache/hertzbeat/master/manager/src/main/resources/define/app-tplink_switch.yml),
[H3cSwitch](https://raw.githubusercontent.com/apache/hertzbeat/master/manager/src/main/resources/define/app-h3c_switch.yml)
- 和更多自定义监控模版。
- 通知支持 `Discord` `Slack` `Telegram` `邮件` `钉钉` `微信` `飞书` `短信` `Webhook` `Server酱`
## 🐕 快速开始
- 如果您是想将 HertzBeat 部署到内网环境搭建监控系统,请参考下面的部署文档进行操作。
- 如果您是想将 HertzBeat 部署到内网环境搭建监控系统,请参考下面的部署文档进行操作。
### 🍞 HertzBeat 安装
> HertzBeat 支持通过源码安装启动,Docker 容器运行和安装包方式安装部署,CPU 架构支持 x86/arm64。
##### 方式一:Docker 方式快速安装
##### 方式一:Docker 方式快速安装
1. `docker` 环境仅需一条命令即可开始
1. `docker` 环境仅需一条命令即可开始
```docker run -d -p 1157:1157 -p 1158:1158 --name hertzbeat apache/hertzbeat```
```shell
docker run -d -p 1157:1157 -p 1158:1158 --name hertzbeat apache/hertzbeat
```
2. 浏览器访问 `http://localhost:1157` 即可开始,默认账号密码 `admin/hertzbeat`
3. 部署采集器集群(可选)
3. 部署采集器集群可选
```shell
docker run -d -e IDENTITY=custom-collector-name -e MANAGER_HOST=127.0.0.1 -e MANAGER_PORT=1158 --name hertzbeat-collector apache/hertzbeat-collector
```
```
docker run -d -e IDENTITY=custom-collector-name -e MANAGER_HOST=127.0.0.1 -e MANAGER_PORT=1158 --name hertzbeat-collector apache/hertzbeat-collector
```
- `-e IDENTITY=custom-collector-name` : 配置此采集器的唯一性标识符名称,多个采集器名称不能相同,建议自定义英文名称。
- `-e MODE=public` : 配置运行模式(public or private), 公共集群模式或私有云边模式。
- `-e MANAGER_HOST=127.0.0.1` : 配置连接主 HertaBeat 服务的对外 IP。
- `-e MANAGER_PORT=1158` : 配置连接主 HertzBeat 服务的对外端口,默认1158。
- `-e MODE=public` : 配置运行模式(public or private), 公共集群模式或私有云边模式。
- `-e MANAGER_HOST=127.0.0.1` : 配置连接主 HertzBeat 服务的对外 IP。
- `-e MANAGER_PORT=1158` : 配置连接主 HertzBeat 服务的对外端口,默认1158。
更多配置详细步骤参考 [通过Docker方式安装HertzBeat](https://hertzbeat.apache.org/docs/start/docker-deploy)
更多配置详细步骤参考 [通过 Docker 方式安装 HertzBeat](https://hertzbeat.apache.org/docs/start/docker-deploy)
##### 方式二:通过安装包安装
1. 下载您系统环境对应的安装包 `hertzbeat-xx.tar.gz` [GITHUB Release](https://github.com/apache/hertzbeat/releases)
1. 下载您系统环境对应的安装包 `apache-hertzbeat-xx-bin.tar.gz` [Download](https://hertzbeat.apache.org/docs/download)
2. 配置 HertzBeat 的配置文件 `hertzbeat/config/application.yml` (可选)
3. 部署启动 `$ ./bin/startup.sh ` 或 `bin/startup.bat`
4. 浏览器访问 `http://localhost:1157` 即可开始,默认账号密码 `admin/hertzbeat`
5. 部署采集器集群(可选)
- 下载采集器安装包 `hertzbeat-collector-xx.tar.gz` 到规划的另一台部署主机上 [GITHUB Release](https://github.com/apache/hertzbeat/releases)
5. 部署采集器集群可选
- 下载采集器安装包 `apache-hertzbeat-collector-xx-bin.tar.gz`(JVM 采集器)或与你目标平台匹配的 Native 采集器安装包,例如 `apache-hertzbeat-collector-native-xx-linux-amd64-bin.tar.gz`、`apache-hertzbeat-collector-native-xx-windows-amd64-bin.zip`,到规划的另一台部署主机上 [Download](https://hertzbeat.apache.org/docs/download)
- 配置采集器的配置文件 `hertzbeat-collector/config/application.yml` 里面的连接主 HertzBeat 服务的对外 IP,端口,当前采集器名称(需保证唯一性)等参数 `identity` `mode` (public or private) `manager-host` `manager-port`
```yaml
collector:
@@ -145,27 +100,29 @@ docker run -d -e IDENTITY=custom-collector-name -e MANAGER_HOST=127.0.0.1 -e MAN
manager-host: ${MANAGER_HOST:127.0.0.1}
manager-port: ${MANAGER_PORT:1158}
```
- 启动 `$ ./bin/startup.sh ` 或 `bin/startup.bat`
- 如果没有在 `ext-lib` 中提供 JDBC 驱动,MySQL、MariaDB、OceanBase 可以直接使用内置查询引擎,也可以使用 Native 采集器安装包;TiDB 的 SQL 查询指标也遵循同样规则。
- 如果在 `ext-lib` 中放入了 `mysql-connector-j`,主程序内置采集器或 JVM 采集器会在重启后自动优先走 JDBC;这一点现在适用于 MySQL、MariaDB、OceanBaseTiDB 的 SQL 查询指标也遵循同样规则,而它的 HTTP 指标不受影响。Oracle、DB2 仍然必须使用 JVM 采集器安装包,因为它们依赖外置 JDBC 驱动。
- JVM 采集器安装包使用 `$ ./bin/startup.sh ` 或 `bin/startup.bat` 启动。Linux 或 macOS 的 Native 采集器安装包使用 `$ ./bin/startup.sh ` 启动,Windows 的 Native 采集器安装包使用 `bin\\startup.bat` 启动
- 浏览器访问主 HertzBeat 服务 `http://localhost:1157` 查看概览页面即可看到注册上来的新采集器
更多配置详细步骤参考 [通过安装包安装HertzBeat](https://hertzbeat.apache.org/docs/start/package-deploy)
##### 方式三:本地代码启动
1. 此为前后端分离项目,本地代码调试需要分别启动后端工程 `manager` 和前端工程 `web-app`
2. 后端:需要 `maven3+`, `java17` 和 `lombok` 环境,修改 `YML` 配置信息并启动 `manager` 服务
3. 前端:需要 `nodejs npm angular-cli`环境,待本地后端启动后,在 `web-app` 目录下启动 `ng serve --open`
1. 此为前后端分离项目,本地代码调试需要分别启动后端工程 `hertzbeat-startup` 和前端工程 `web-app`
2. 后端:需要 `maven3+`, `java25` 和 `lombok` 环境,修改 `YML` 配置信息,添加JVM参数`--add-opens=java.base/java.nio=org.apache.arrow.memory.core,ALL-UNNAMED`后启动 `hertzbeat-startup` 服务即可。
3. 前端:需要 `nodejs` 和 `pnpm` 环境,待本地后端启动后,在 `web-app` 目录下执行 `pnpm install` 再执行 `pnpm start`
4. 浏览器访问 `http://localhost:4200` 即可开始,默认账号密码 `admin/hertzbeat`
详细步骤参考 [参与贡献之本地代码启动](CONTRIBUTING.md)
##### 方式四:Docker-Compose 统一安装 hertzbeat+mysql+tsdb
##### 方式四:Docker-Compose 统一安装 hertzbeat+postgresql+tsdb
通过 [Docker-Compose 部署脚本](script/docker-compose) 一次性把 mysql/postgresql 数据库, iotdb/tdengine/victoria-metrics 时序数据库和 hertzbeat 安装部署。
通过 [Docker-Compose 部署脚本](script/docker-compose) 一次性把 postgresql/mysql 数据库, victoria-metrics/iotdb/tdengine 时序数据库和 hertzbeat 安装部署。
详细步骤参考 [通过Docker-Compose安装HertzBeat](script/docker-compose/README.md)
详细步骤参考 [通过 Docker-Compose 安装 HertzBeat](script/docker-compose/README.md)
##### 方式五:Kubernetes Helm Charts 部署 hertzbeat+collector+mysql+tsdb
##### 方式五:Kubernetes Helm Charts 部署 hertzbeat+collector+postgresql+tsdb
通过 Helm Chart 一次性将 HertzBeat 集群组件部署到 Kubernetes 集群中。
@@ -173,14 +130,10 @@ docker run -d -e IDENTITY=custom-collector-name -e MANAGER_HOST=127.0.0.1 -e MAN
**HAVE FUN**
## 🥐 路线图
![hertzBeat](home/static/img/docs/hertzbeat-roadmap.png)
## ✨ Contributors
Thanks these wonderful people, welcome to join us:
[贡献者指南](CONTRIBUTING.md)
Thanks these wonderful people, welcome to join us:
[贡献者指南](CONTRIBUTING.md)
<!-- ALL-CONTRIBUTORS-LIST:START - Do not remove or modify this section -->
<!-- prettier-ignore-start -->
@@ -219,7 +172,7 @@ Thanks these wonderful people, welcome to join us:
<td align="center" valign="top" width="14.28%"><a href="http://mroldx.xyz/"><img src="https://avatars.githubusercontent.com/u/34847828?v=4?s=100" width="100px;" alt="mroldx"/><br /><sub><b>mroldx</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=mroldx" title="Documentation">📖</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/woshiniusange"><img src="https://avatars.githubusercontent.com/u/91513022?v=4?s=100" width="100px;" alt="woshiniusange"/><br /><sub><b>woshiniusange</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=woshiniusange" title="Documentation">📖</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://vampireachao.github.io/"><img src="https://avatars.githubusercontent.com/u/52746628?v=4?s=100" width="100px;" alt="VampireAchao"/><br /><sub><b>VampireAchao</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=VampireAchao" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/Ceilzcx"><img src="https://avatars.githubusercontent.com/u/48920254?v=4?s=100" width="100px;" alt="zcx"/><br /><sub><b>zcx</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=Ceilzcx" title="Code">💻</a> <a href="https://github.com/apache/hertzbeat/issues?q=author%3ACeilzcx" title="Bug reports">🐛</a> <a href="#design-Ceilzcx" title="Design">🎨</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/Ceilzcx"><img src="https://avatars.githubusercontent.com/u/48920254?v=4?s=100" width="100px;" alt="zcx"/><br /><sub><b>zcx</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=Ceilzcx" title="Code">💻</a> <a href="https://github.com/apache/hertzbeat/issues?q=author%3ACeilzcx" title="Bug reports">🐛</a> <a href="#design-Ceilzcx" title="Design">🎨</a> <a href="https://github.com/apache/hertzbeat/commits?author=Ceilzcx" title="Tests">⚠️</a> <a href="#blog-Ceilzcx" title="Blogposts">📝</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/CharlieXCL"><img src="https://avatars.githubusercontent.com/u/91540487?v=4?s=100" width="100px;" alt="CharlieXCL"/><br /><sub><b>CharlieXCL</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=CharlieXCL" title="Documentation">📖</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/Privauto"><img src="https://avatars.githubusercontent.com/u/36581456?v=4?s=100" width="100px;" alt="Privauto"/><br /><sub><b>Privauto</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=Privauto" title="Code">💻</a> <a href="https://github.com/apache/hertzbeat/commits?author=Privauto" title="Documentation">📖</a></td>
</tr>
@@ -233,7 +186,7 @@ Thanks these wonderful people, welcome to join us:
<td align="center" valign="top" width="14.28%"><a href="https://www.zhihu.com/people/kevinbauer"><img src="https://avatars.githubusercontent.com/u/28581579?v=4?s=100" width="100px;" alt="Kevin Huang"/><br /><sub><b>Kevin Huang</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=kevinhuangwl" title="Documentation">📖</a></td>
</tr>
<tr>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/TJxiaobao"><img src="https://avatars.githubusercontent.com/u/85919258?v=4?s=100" width="100px;" alt="铁甲小宝"/><br /><sub><b>铁甲小宝</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/issues?q=author%3ATJxiaobao" title="Bug reports">🐛</a> <a href="https://github.com/apache/hertzbeat/commits?author=TJxiaobao" title="Code">💻</a> <a href="https://github.com/apache/hertzbeat/commits?author=TJxiaobao" title="Documentation">📖</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/TJxiaobao"><img src="https://avatars.githubusercontent.com/u/85919258?v=4?s=100" width="100px;" alt="铁甲小宝"/><br /><sub><b>铁甲小宝</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/issues?q=author%3ATJxiaobao" title="Bug reports">🐛</a> <a href="https://github.com/apache/hertzbeat/commits?author=TJxiaobao" title="Code">💻</a> <a href="https://github.com/apache/hertzbeat/commits?author=TJxiaobao" title="Documentation">📖</a> <a href="https://github.com/apache/hertzbeat/commits?author=TJxiaobao" title="Tests">⚠️</a> <a href="#design-TJxiaobao" title="Design">🎨</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/Jack-123-power"><img src="https://avatars.githubusercontent.com/u/84333501?v=4?s=100" width="100px;" alt="Captain Jack"/><br /><sub><b>Captain Jack</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=Jack-123-power" title="Documentation">📖</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/haibo-duan"><img src="https://avatars.githubusercontent.com/u/7974845?v=4?s=100" width="100px;" alt="haibo.duan"/><br /><sub><b>haibo.duan</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=haibo-duan" title="Tests">⚠️</a> <a href="https://github.com/apache/hertzbeat/commits?author=haibo-duan" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/assassinfym"><img src="https://avatars.githubusercontent.com/u/15188754?v=4?s=100" width="100px;" alt="assassin"/><br /><sub><b>assassin</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/issues?q=author%3Aassassinfym" title="Bug reports">🐛</a> <a href="https://github.com/apache/hertzbeat/commits?author=assassinfym" title="Code">💻</a></td>
@@ -275,7 +228,7 @@ Thanks these wonderful people, welcome to join us:
<td align="center" valign="top" width="14.28%"><a href="https://wjl110.xyz/"><img src="https://avatars.githubusercontent.com/u/53851034?v=4?s=100" width="100px;" alt="wjl110"/><br /><sub><b>wjl110</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=wjl110" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/ngyhd"><img src="https://avatars.githubusercontent.com/u/29095207?v=4?s=100" width="100px;" alt="Sean"/><br /><sub><b>Sean</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=ngyhd" title="Documentation">📖</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/Daydreamer-ia"><img src="https://avatars.githubusercontent.com/u/83362909?v=4?s=100" width="100px;" alt="chenyiqin"/><br /><sub><b>chenyiqin</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=Daydreamer-ia" title="Code">💻</a> <a href="https://github.com/apache/hertzbeat/commits?author=Daydreamer-ia" title="Tests">⚠️</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/hudongdong129"><img src="https://avatars.githubusercontent.com/u/34374227?v=4?s=100" width="100px;" alt="hudongdong129"/><br /><sub><b>hudongdong129</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=hudongdong129" title="Code">💻</a> <a href="https://github.com/apache/hertzbeat/commits?author=hudongdong129" title="Tests">⚠️</a> <a href="https://github.com/apache/hertzbeat/commits?author=hudongdong129" title="Documentation">📖</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/hudongdong129"><img src="https://avatars.githubusercontent.com/u/34374227?v=4?s=100" width="100px;" alt="hudongdong129"/><br /><sub><b>hudongdong129</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=hudongdong129" title="Code">💻</a> <a href="https://github.com/apache/hertzbeat/commits?author=hudongdong129" title="Tests">⚠️</a> <a href="https://github.com/apache/hertzbeat/commits?author=hudongdong129" title="Documentation">📖</a> <a href="#design-hudongdong129" title="Design">🎨</a></td>
</tr>
<tr>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/TherChenYang"><img src="https://avatars.githubusercontent.com/u/124348939?v=4?s=100" width="100px;" alt="TherChenYang"/><br /><sub><b>TherChenYang</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=TherChenYang" title="Code">💻</a> <a href="https://github.com/apache/hertzbeat/commits?author=TherChenYang" title="Tests">⚠️</a></td>
@@ -291,7 +244,7 @@ Thanks these wonderful people, welcome to join us:
<td align="center" valign="top" width="14.28%"><a href="https://github.com/baiban114"><img src="https://avatars.githubusercontent.com/u/59152619?v=4?s=100" width="100px;" alt="TableRow"/><br /><sub><b>TableRow</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=baiban114" title="Documentation">📖</a> <a href="https://github.com/apache/hertzbeat/commits?author=baiban114" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/ByteIDance"><img src="https://avatars.githubusercontent.com/u/100207562?v=4?s=100" width="100px;" alt="ByteIDance"/><br /><sub><b>ByteIDance</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=ByteIDance" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/mangel2002"><img src="https://avatars.githubusercontent.com/u/9348020?v=4?s=100" width="100px;" alt="Jangfe"/><br /><sub><b>Jangfe</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=mangel2002" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/zqr10159"><img src="https://avatars.githubusercontent.com/u/30048352?v=4?s=100" width="100px;" alt="zqr10159"/><br /><sub><b>zqr10159</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=zqr10159" title="Documentation">📖</a> <a href="https://github.com/apache/hertzbeat/commits?author=zqr10159" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/zqr10159"><img src="https://avatars.githubusercontent.com/u/30048352?v=4?s=100" width="100px;" alt="zqr10159"/><br /><sub><b>zqr10159</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=zqr10159" title="Documentation">📖</a> <a href="https://github.com/apache/hertzbeat/commits?author=zqr10159" title="Code">💻</a> <a href="#blog-zqr10159" title="Blogposts">📝</a> <a href="https://github.com/apache/hertzbeat/issues?q=author%3Azqr10159" title="Bug reports">🐛</a> <a href="https://github.com/apache/hertzbeat/commits?author=zqr10159" title="Tests">⚠️</a> <a href="#design-zqr10159" title="Design">🎨</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/vinci-897"><img src="https://avatars.githubusercontent.com/u/55838224?v=4?s=100" width="100px;" alt="vinci"/><br /><sub><b>vinci</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=vinci-897" title="Code">💻</a> <a href="https://github.com/apache/hertzbeat/commits?author=vinci-897" title="Documentation">📖</a> <a href="#design-vinci-897" title="Design">🎨</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/js110"><img src="https://avatars.githubusercontent.com/u/51191863?v=4?s=100" width="100px;" alt="js110"/><br /><sub><b>js110</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=js110" title="Code">💻</a></td>
</tr>
@@ -305,8 +258,8 @@ Thanks these wonderful people, welcome to join us:
<td align="center" valign="top" width="14.28%"><a href="https://github.com/ZangJuxy"><img src="https://avatars.githubusercontent.com/u/71380295?v=4?s=100" width="100px;" alt="ZangJuxy"/><br /><sub><b>ZangJuxy</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=ZangJuxy" title="Documentation">📖</a></td>
</tr>
<tr>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/l646505418"><img src="https://avatars.githubusercontent.com/u/50475131?v=4?s=100" width="100px;" alt="l646505418"/><br /><sub><b>l646505418</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=l646505418" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="http://www.carpewang.com"><img src="https://avatars.githubusercontent.com/u/78642589?v=4?s=100" width="100px;" alt="Carpe-Wang"/><br /><sub><b>Carpe-Wang</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=Carpe-Wang" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/l646505418"><img src="https://avatars.githubusercontent.com/u/50475131?v=4?s=100" width="100px;" alt="l646505418"/><br /><sub><b>l646505418</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=l646505418" title="Code">💻</a> <a href="https://github.com/apache/hertzbeat/issues?q=author%3Al646505418" title="Bug reports">🐛</a></td>
<td align="center" valign="top" width="14.28%"><a href="http://www.carpewang.com"><img src="https://avatars.githubusercontent.com/u/78642589?v=4?s=100" width="100px;" alt="Carpe-Wang"/><br /><sub><b>Carpe-Wang</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=Carpe-Wang" title="Code">💻</a> <a href="https://github.com/apache/hertzbeat/issues?q=author%3ACarpe-Wang" title="Bug reports">🐛</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/moshu023"><img src="https://avatars.githubusercontent.com/u/48593205?v=4?s=100" width="100px;" alt="莫枢"/><br /><sub><b>莫枢</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=moshu023" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/huangcanda"><img src="https://avatars.githubusercontent.com/u/4470566?v=4?s=100" width="100px;" alt="huangcanda"/><br /><sub><b>huangcanda</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=huangcanda" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://www.zrkizzy.com"><img src="https://avatars.githubusercontent.com/u/85340613?v=4?s=100" width="100px;" alt="世纪末的架构师"/><br /><sub><b>世纪末的架构师</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=Architect-Java" title="Code">💻</a></td>
@@ -356,7 +309,7 @@ Thanks these wonderful people, welcome to join us:
<td align="center" valign="top" width="14.28%"><a href="https://github.com/lisongning"><img src="https://avatars.githubusercontent.com/u/93140178?v=4?s=100" width="100px;" alt="lisongning"/><br /><sub><b>lisongning</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=lisongning" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/YutingNie"><img src="https://avatars.githubusercontent.com/u/104416402?v=4?s=100" width="100px;" alt="YutingNie"/><br /><sub><b>YutingNie</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=YutingNie" title="Code">💻</a> <a href="https://github.com/apache/hertzbeat/commits?author=YutingNie" title="Documentation">📖</a> <a href="#design-YutingNie" title="Design">🎨</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/mikezzb"><img src="https://avatars.githubusercontent.com/u/23418428?v=4?s=100" width="100px;" alt="Mike Zhou"/><br /><sub><b>Mike Zhou</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=mikezzb" title="Code">💻</a> <a href="https://github.com/apache/hertzbeat/commits?author=mikezzb" title="Documentation">📖</a> <a href="#design-mikezzb" title="Design">🎨</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/a-little-fool"><img src="https://avatars.githubusercontent.com/u/105542329?v=4?s=100" width="100px;" alt="小笨蛋"/><br /><sub><b>小笨蛋</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=a-little-fool" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/lynx009"><img src="https://avatars.githubusercontent.com/u/105542329?v=4?s=100" width="100px;" alt="lynx009"/><br /><sub><b>lynx009</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=lynx009" title="Documentation">📖</a></td>
</tr>
<tr>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/littlezhongzer"><img src="https://avatars.githubusercontent.com/u/33685289?v=4?s=100" width="100px;" alt="littlezhongzer"/><br /><sub><b>littlezhongzer</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=littlezhongzer" title="Code">💻</a></td>
@@ -365,7 +318,7 @@ Thanks these wonderful people, welcome to join us:
<td align="center" valign="top" width="14.28%"><a href="https://github.com/XimfengYao"><img src="https://avatars.githubusercontent.com/u/17541537?v=4?s=100" width="100px;" alt="姚贤丰"/><br /><sub><b>姚贤丰</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=XimfengYao" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/LINGLUOJUN"><img src="https://avatars.githubusercontent.com/u/16778977?v=4?s=100" width="100px;" alt="lingluojun"/><br /><sub><b>lingluojun</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=LINGLUOJUN" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="http://www.luelueking.com"><img src="https://avatars.githubusercontent.com/u/93204032?v=4?s=100" width="100px;" alt="1ue"/><br /><sub><b>1ue</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=luelueking" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="http://www.jimmyqiao.top"><img src="https://avatars.githubusercontent.com/u/67301054?v=4?s=100" width="100px;" alt="qyaaaa"/><br /><sub><b>qyaaaa</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=qyaaaa" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="http://www.jimmyqiao.top"><img src="https://avatars.githubusercontent.com/u/67301054?v=4?s=100" width="100px;" alt="qyaaaa"/><br /><sub><b>qyaaaa</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=qyaaaa" title="Code">💻</a> <a href="https://github.com/apache/hertzbeat/issues?q=author%3Aqyaaaa" title="Bug reports">🐛</a></td>
</tr>
<tr>
<td align="center" valign="top" width="14.28%"><a href="https://novohit.top"><img src="https://avatars.githubusercontent.com/u/101090395?v=4?s=100" width="100px;" alt="novohit"/><br /><sub><b>novohit</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=novohit" title="Code">💻</a></td>
@@ -379,14 +332,14 @@ Thanks these wonderful people, welcome to join us:
<tr>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/1036664317"><img src="https://avatars.githubusercontent.com/u/7696697?v=4?s=100" width="100px;" alt="moghn"/><br /><sub><b>moghn</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=1036664317" title="Documentation">📖</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/xiaoguolong"><img src="https://avatars.githubusercontent.com/u/33684988?v=4?s=100" width="100px;" alt="xiaoguolong"/><br /><sub><b>xiaoguolong</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=xiaoguolong" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/Clownsw"><img src="https://avatars.githubusercontent.com/u/28394742?v=4?s=100" width="100px;" alt="Smliexx"/><br /><sub><b>Smliexx</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=Clownsw" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/Calvin979"><img src="https://avatars.githubusercontent.com/u/131688897?v=4?s=100" width="100px;" alt="Naruse"/><br /><sub><b>Naruse</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=Calvin979" title="Documentation">📖</a> <a href="https://github.com/apache/hertzbeat/commits?author=Calvin979" title="Code">💻</a> <a href="#design-Calvin979" title="Design">🎨</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/Clownsw"><img src="https://avatars.githubusercontent.com/u/28394742?v=4?s=100" width="100px;" alt="Smliexx"/><br /><sub><b>Smliexx</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=Clownsw" title="Code">💻</a> <a href="https://github.com/apache/hertzbeat/issues?q=author%3AClownsw" title="Bug reports">🐛</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/Calvin979"><img src="https://avatars.githubusercontent.com/u/131688897?v=4?s=100" width="100px;" alt="Calvin"/><br /><sub><b>Calvin</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=Calvin979" title="Documentation">📖</a> <a href="https://github.com/apache/hertzbeat/commits?author=Calvin979" title="Code">💻</a> <a href="#design-Calvin979" title="Design">🎨</a> <a href="https://github.com/apache/hertzbeat/issues?q=author%3ACalvin979" title="Bug reports">🐛</a> <a href="https://github.com/apache/hertzbeat/commits?author=Calvin979" title="Tests">⚠️</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/bbelide2"><img src="https://avatars.githubusercontent.com/u/26840796?v=4?s=100" width="100px;" alt="Bala Sukesh"/><br /><sub><b>Bala Sukesh</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=bbelide2" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/jinyaoMa"><img src="https://avatars.githubusercontent.com/u/25066570?v=4?s=100" width="100px;" alt="Jinyao Ma"/><br /><sub><b>Jinyao Ma</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=jinyaoMa" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://linuxsuren.github.io/open-source-best-practice/"><img src="https://avatars.githubusercontent.com/u/1450685?v=4?s=100" width="100px;" alt="Rick"/><br /><sub><b>Rick</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=LinuxSuRen" title="Code">💻</a> <a href="https://github.com/apache/hertzbeat/commits?author=LinuxSuRen" title="Tests">⚠️</a></td>
</tr>
<tr>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/ZY945"><img src="https://avatars.githubusercontent.com/u/74083801?v=4?s=100" width="100px;" alt="东风"/><br /><sub><b>东风</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=ZY945" title="Code">💻</a> <a href="#design-ZY945" title="Design">🎨</a> <a href="https://github.com/apache/hertzbeat/commits?author=ZY945" title="Documentation">📖</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/ZY945"><img src="https://avatars.githubusercontent.com/u/74083801?v=4?s=100" width="100px;" alt="东风"/><br /><sub><b>东风</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=ZY945" title="Code">💻</a> <a href="#design-ZY945" title="Design">🎨</a> <a href="https://github.com/apache/hertzbeat/commits?author=ZY945" title="Documentation">📖</a> <a href="https://github.com/apache/hertzbeat/issues?q=author%3AZY945" title="Bug reports">🐛</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/prolevel1"><img src="https://avatars.githubusercontent.com/u/51995525?v=4?s=100" width="100px;" alt="sonam singh"/><br /><sub><b>sonam singh</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=prolevel1" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/ZhangZixuan1994"><img src="https://avatars.githubusercontent.com/u/20011653?v=4?s=100" width="100px;" alt="ZhangZixuan1994"/><br /><sub><b>ZhangZixuan1994</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=ZhangZixuan1994" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/hurenjie1"><img src="https://avatars.githubusercontent.com/u/40120355?v=4?s=100" width="100px;" alt="SHIG"/><br /><sub><b>SHIG</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=hurenjie1" title="Code">💻</a></td>
@@ -396,29 +349,29 @@ Thanks these wonderful people, welcome to join us:
</tr>
<tr>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/avvCode"><img src="https://avatars.githubusercontent.com/u/113538532?v=4?s=100" width="100px;" alt="avv"/><br /><sub><b>avv</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=avvCode" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/yqxxgh"><img src="https://avatars.githubusercontent.com/u/42080876?v=4?s=100" width="100px;" alt="yqxxgh"/><br /><sub><b>yqxxgh</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=yqxxgh" title="Documentation">📖</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/yqxxgh"><img src="https://avatars.githubusercontent.com/u/42080876?v=4?s=100" width="100px;" alt="yqxxgh"/><br /><sub><b>yqxxgh</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=yqxxgh" title="Documentation">📖</a> <a href="https://github.com/apache/hertzbeat/commits?author=yqxxgh" title="Code">💻</a> <a href="https://github.com/apache/hertzbeat/issues?q=author%3Ayqxxgh" title="Bug reports">🐛</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/CharlieShi46"><img src="https://avatars.githubusercontent.com/u/149798885?v=4?s=100" width="100px;" alt="CharlieShi46"/><br /><sub><b>CharlieShi46</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=CharlieShi46" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/Nctllnty"><img src="https://avatars.githubusercontent.com/u/33241818?v=4?s=100" width="100px;" alt="Nctllnty"/><br /><sub><b>Nctllnty</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=Nctllnty" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/Wang-Yonghao"><img src="https://avatars.githubusercontent.com/u/48146606?v=4?s=100" width="100px;" alt="Wang-Yonghao"/><br /><sub><b>Wang-Yonghao</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=Wang-Yonghao" title="Documentation">📖</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://www.yuque.com/dudiao/yy"><img src="https://avatars.githubusercontent.com/u/38355949?v=4?s=100" width="100px;" alt="读钓"/><br /><sub><b>读钓</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=dudiao" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/starmilkxin"><img src="https://avatars.githubusercontent.com/u/55646681?v=4?s=100" width="100px;" alt="Xin"/><br /><sub><b>Xin</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=starmilkxin" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/starmilkxin"><img src="https://avatars.githubusercontent.com/u/55646681?v=4?s=100" width="100px;" alt="Xin"/><br /><sub><b>Xin</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=starmilkxin" title="Code">💻</a> <a href="https://github.com/apache/hertzbeat/issues?q=author%3Astarmilkxin" title="Bug reports">🐛</a></td>
</tr>
<tr>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/handy-git"><img src="https://avatars.githubusercontent.com/u/32837980?v=4?s=100" width="100px;" alt="handy"/><br /><sub><b>handy</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=handy-git" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/LiuTianyou"><img src="https://avatars.githubusercontent.com/u/30208283?v=4?s=100" width="100px;" alt="LiuTianyou"/><br /><sub><b>LiuTianyou</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=LiuTianyou" title="Code">💻</a> <a href="https://github.com/apache/hertzbeat/commits?author=LiuTianyou" title="Documentation">📖</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/LiuTianyou"><img src="https://avatars.githubusercontent.com/u/30208283?v=4?s=100" width="100px;" alt="LiuTianyou"/><br /><sub><b>LiuTianyou</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=LiuTianyou" title="Code">💻</a> <a href="https://github.com/apache/hertzbeat/commits?author=LiuTianyou" title="Documentation">📖</a> <a href="https://github.com/apache/hertzbeat/issues?q=author%3ALiuTianyou" title="Bug reports">🐛</a> <a href="https://github.com/apache/hertzbeat/commits?author=LiuTianyou" title="Tests">⚠️</a> <a href="#blog-LiuTianyou" title="Blogposts">📝</a> <a href="#design-LiuTianyou" title="Design">🎨</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/WinterKi1ler"><img src="https://avatars.githubusercontent.com/u/160592092?v=4?s=100" width="100px;" alt="WinterKi1ler"/><br /><sub><b>WinterKi1ler</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=WinterKi1ler" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="http://sharehoo.cn/"><img src="https://avatars.githubusercontent.com/u/45377370?v=4?s=100" width="100px;" alt="miki"/><br /><sub><b>miki</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=miki-hmt" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://codeflex.substack.com/"><img src="https://avatars.githubusercontent.com/u/85513042?v=4?s=100" width="100px;" alt="Keshav Carpenter"/><br /><sub><b>Keshav Carpenter</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=alpha951" title="Code">💻</a> <a href="https://github.com/apache/hertzbeat/commits?author=alpha951" title="Documentation">📖</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/makechoicenow"><img src="https://avatars.githubusercontent.com/u/9911918?v=4?s=100" width="100px;" alt="makechoicenow"/><br /><sub><b>makechoicenow</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=makechoicenow" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/gjjjj0101"><img src="https://avatars.githubusercontent.com/u/71874373?v=4?s=100" width="100px;" alt="Gao Jian"/><br /><sub><b>Gao Jian</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=gjjjj0101" title="Code">💻</a> <a href="#design-gjjjj0101" title="Design">🎨</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/gjjjj0101"><img src="https://avatars.githubusercontent.com/u/71874373?v=4?s=100" width="100px;" alt="Gao Jian"/><br /><sub><b>Gao Jian</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=gjjjj0101" title="Tests">⚠️</a> <a href="https://github.com/apache/hertzbeat/commits?author=gjjjj0101" title="Code">💻</a> <a href="https://github.com/apache/hertzbeat/commits?author=gjjjj0101" title="Documentation">📖</a> <a href="#design-gjjjj0101" title="Design">🎨</a> <a href="https://github.com/apache/hertzbeat/issues?q=author%3Agjjjj0101" title="Bug reports">🐛</a></td>
</tr>
<tr>
<td align="center" valign="top" width="14.28%"><a href="https://jangto.tistory.com/"><img src="https://avatars.githubusercontent.com/u/37864182?v=4?s=100" width="100px;" alt="Hyeon Sung"/><br /><sub><b>Hyeon Sung</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=dukbong" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://crossoverjie.top/"><img src="https://avatars.githubusercontent.com/u/15684156?v=4?s=100" width="100px;" alt="crossoverJie"/><br /><sub><b>crossoverJie</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=crossoverJie" title="Code">💻</a> <a href="https://github.com/apache/hertzbeat/commits?author=crossoverJie" title="Documentation">📖</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://jangto.tistory.com/"><img src="https://avatars.githubusercontent.com/u/37864182?v=4?s=100" width="100px;" alt="Hyeon Sung"/><br /><sub><b>Hyeon Sung</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=dukbong" title="Code">💻</a> <a href="https://github.com/apache/hertzbeat/commits?author=dukbong" title="Documentation">📖</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://crossoverjie.top/"><img src="https://avatars.githubusercontent.com/u/15684156?v=4?s=100" width="100px;" alt="crossoverJie"/><br /><sub><b>crossoverJie</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=crossoverJie" title="Code">💻</a> <a href="https://github.com/apache/hertzbeat/commits?author=crossoverJie" title="Documentation">📖</a> <a href="#blog-crossoverJie" title="Blogposts">📝</a> <a href="https://github.com/apache/hertzbeat/commits?author=crossoverJie" title="Tests">⚠️</a> <a href="#design-crossoverJie" title="Design">🎨</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/PeixyJ"><img src="https://avatars.githubusercontent.com/u/45998593?v=4?s=100" width="100px;" alt="PeixyJ"/><br /><sub><b>PeixyJ</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=PeixyJ" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/Hi-Mr-Wind"><img src="https://avatars.githubusercontent.com/u/85803831?v=4?s=100" width="100px;" alt="风如歌"/><br /><sub><b>风如歌</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=Hi-Mr-Wind" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/MananPoojara"><img src="https://avatars.githubusercontent.com/u/104253184?v=4?s=100" width="100px;" alt="Manan Pujara"/><br /><sub><b>Manan Pujara</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=MananPoojara" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/xuziyang"><img src="https://avatars.githubusercontent.com/u/8465969?v=4?s=100" width="100px;" alt="xuziyang"/><br /><sub><b>xuziyang</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=xuziyang" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/xuziyang"><img src="https://avatars.githubusercontent.com/u/8465969?v=4?s=100" width="100px;" alt="xuziyang"/><br /><sub><b>xuziyang</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=xuziyang" title="Code">💻</a> <a href="https://github.com/apache/hertzbeat/commits?author=xuziyang" title="Documentation">📖</a> <a href="https://github.com/apache/hertzbeat/issues?q=author%3Axuziyang" title="Bug reports">🐛</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/lwqzz"><img src="https://avatars.githubusercontent.com/u/62584513?v=4?s=100" width="100px;" alt="lwqzz"/><br /><sub><b>lwqzz</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=lwqzz" title="Code">💻</a></td>
</tr>
<tr>
@@ -426,25 +379,159 @@ Thanks these wonderful people, welcome to join us:
<td align="center" valign="top" width="14.28%"><a href="https://github.com/tomorrowshipyltm"><img src="https://avatars.githubusercontent.com/u/61336903?v=4?s=100" width="100px;" alt="tomorrowshipyltm"/><br /><sub><b>tomorrowshipyltm</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=tomorrowshipyltm" title="Documentation">📖</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/15613060203"><img src="https://avatars.githubusercontent.com/u/41351615?v=4?s=100" width="100px;" alt="栗磊"/><br /><sub><b>栗磊</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=15613060203" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/Alanxtl"><img src="https://avatars.githubusercontent.com/u/25652981?v=4?s=100" width="100px;" alt="Alan"/><br /><sub><b>Alan</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=Alanxtl" title="Documentation">📖</a></td>
<td align="center" valign="top" width="14.28%"><a href="http://www.hadoop.wiki/"><img src="https://avatars.githubusercontent.com/u/29418975?v=4?s=100" width="100px;" alt="Jast"/><br /><sub><b>Jast</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=zhangshenghang" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/zuobiao-zhou"><img src="https://avatars.githubusercontent.com/u/61108539?v=4?s=100" width="100px;" alt="Zhang Yuxuan"/><br /><sub><b>Zhang Yuxuan</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=zuobiao-zhou" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="http://www.hadoop.wiki/"><img src="https://avatars.githubusercontent.com/u/29418975?v=4?s=100" width="100px;" alt="Jast"/><br /><sub><b>Jast</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=zhangshenghang" title="Code">💻</a> <a href="#ideas-zhangshenghang" title="Ideas, Planning, & Feedback">🤔</a> <a href="https://github.com/apache/hertzbeat/commits?author=zhangshenghang" title="Documentation">📖</a> <a href="#blog-zhangshenghang" title="Blogposts">📝</a> <a href="https://github.com/apache/hertzbeat/issues?q=author%3Azhangshenghang" title="Bug reports">🐛</a> <a href="https://github.com/apache/hertzbeat/commits?author=zhangshenghang" title="Tests">⚠️</a> <a href="#design-zhangshenghang" title="Design">🎨</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/zuobiao-zhou"><img src="https://avatars.githubusercontent.com/u/61108539?v=4?s=100" width="100px;" alt="Zhang Yuxuan"/><br /><sub><b>Zhang Yuxuan</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=zuobiao-zhou" title="Code">💻</a> <a href="https://github.com/apache/hertzbeat/commits?author=zuobiao-zhou" title="Documentation">📖</a> <a href="https://github.com/apache/hertzbeat/issues?q=author%3Azuobiao-zhou" title="Bug reports">🐛</a> <a href="#blog-zuobiao-zhou" title="Blogposts">📝</a> <a href="https://github.com/apache/hertzbeat/commits?author=zuobiao-zhou" title="Tests">⚠️</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/Pzz-2021"><img src="https://avatars.githubusercontent.com/u/118056735?v=4?s=100" width="100px;" alt="P.P."/><br /><sub><b>P.P.</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=Pzz-2021" title="Code">💻</a></td>
</tr>
<tr>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/LLP2333"><img src="https://avatars.githubusercontent.com/u/61670545?v=4?s=100" width="100px;" alt="llp2333"/><br /><sub><b>llp2333</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=LLP2333" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/HeartLinked"><img src="https://avatars.githubusercontent.com/u/78212101?v=4?s=100" width="100px;" alt="feiyang li"/><br /><sub><b>feiyang li</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=HeartLinked" title="Documentation">📖</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/Aias00"><img src="https://avatars.githubusercontent.com/u/25810623?v=4?s=100" width="100px;" alt="aias00"/><br /><sub><b>aias00</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=Aias00" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/Aias00"><img src="https://avatars.githubusercontent.com/u/25810623?v=4?s=100" width="100px;" alt="aias00"/><br /><sub><b>aias00</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=Aias00" title="Code">💻</a> <a href="https://github.com/apache/hertzbeat/commits?author=Aias00" title="Documentation">📖</a> <a href="https://github.com/apache/hertzbeat/issues?q=author%3AAias00" title="Bug reports">🐛</a> <a href="#ideas-Aias00" title="Ideas, Planning, & Feedback">🤔</a> <a href="https://github.com/apache/hertzbeat/commits?author=Aias00" title="Tests">⚠️</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/westboy"><img src="https://avatars.githubusercontent.com/u/6385565?v=4?s=100" width="100px;" alt="Jin"/><br /><sub><b>Jin</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=westboy" title="Documentation">📖</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://blog.csdn.net/qq_52397471"><img src="https://avatars.githubusercontent.com/u/77964041?v=4?s=100" width="100px;" alt="YuLuo"/><br /><sub><b>YuLuo</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=yuluo-yx" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/Yanshuming1"><img src="https://avatars.githubusercontent.com/u/118667222?v=4?s=100" width="100px;" alt="xiaoming student"/><br /><sub><b>xiaoming student</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=Yanshuming1" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://blog.csdn.net/qq_52397471"><img src="https://avatars.githubusercontent.com/u/77964041?v=4?s=100" width="100px;" alt="YuLuo"/><br /><sub><b>YuLuo</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=yuluo-yx" title="Code">💻</a> <a href="https://github.com/apache/hertzbeat/issues?q=author%3Ayuluo-yx" title="Bug reports">🐛</a> <a href="https://github.com/apache/hertzbeat/commits?author=yuluo-yx" title="Tests">⚠️</a> <a href="#blog-yuluo-yx" title="Blogposts">📝</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/Yanshuming1"><img src="https://avatars.githubusercontent.com/u/118667222?v=4?s=100" width="100px;" alt="linDong"/><br /><sub><b>linDong</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=Yanshuming1" title="Code">💻</a> <a href="https://github.com/apache/hertzbeat/commits?author=Yanshuming1" title="Documentation">📖</a> <a href="https://github.com/apache/hertzbeat/issues?q=author%3AYanshuming1" title="Bug reports">🐛</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/lwjxy"><img src="https://avatars.githubusercontent.com/u/52726400?v=4?s=100" width="100px;" alt="lwjxy"/><br /><sub><b>lwjxy</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=lwjxy" title="Code">💻</a></td>
</tr>
<tr>
<td align="center" valign="top" width="14.28%"><a href="https://thespica.github.io/"><img src="https://avatars.githubusercontent.com/u/119573640?v=4?s=100" width="100px;" alt="John"/><br /><sub><b>John</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=Thespica" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://thespica.github.io/"><img src="https://avatars.githubusercontent.com/u/119573640?v=4?s=100" width="100px;" alt="John"/><br /><sub><b>John</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=Thespica" title="Code">💻</a> <a href="https://github.com/apache/hertzbeat/commits?author=Thespica" title="Documentation">📖</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/boatrainlsz"><img src="https://avatars.githubusercontent.com/u/18243785?v=4?s=100" width="100px;" alt="boatrainlsz"/><br /><sub><b>boatrainlsz</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=boatrainlsz" title="Documentation">📖</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://www.yitianyigexiangfa.com/"><img src="https://avatars.githubusercontent.com/u/3973419?v=4?s=100" width="100px;" alt="Bill Lau"/><br /><sub><b>Bill Lau</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=JavaProgrammerLB" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/lw-yang"><img src="https://avatars.githubusercontent.com/u/23456873?v=4?s=100" width="100px;" alt="lwyang"/><br /><sub><b>lwyang</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=lw-yang" title="Documentation">📖</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/xfl12345"><img src="https://avatars.githubusercontent.com/u/17960863?v=4?s=100" width="100px;" alt="xfl12345"/><br /><sub><b>xfl12345</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=xfl12345" title="Documentation">📖</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/yykaue"><img src="https://avatars.githubusercontent.com/u/22905143?v=4?s=100" width="100px;" alt="Limbo"/><br /><sub><b>Limbo</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=yykaue" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/irenhongyan"><img src="https://avatars.githubusercontent.com/u/53438321?v=4?s=100" width="100px;" alt="哈哈哈哈哈哈哈哈哈"/><br /><sub><b>哈哈哈哈哈哈哈哈哈</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=irenhongyan" title="Code">💻</a></td>
</tr>
<tr>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/ileonli"><img src="https://avatars.githubusercontent.com/u/45332412?v=4?s=100" width="100px;" alt="Leon Li"/><br /><sub><b>Leon Li</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=ileonli" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="http://fnil.net/"><img src="https://avatars.githubusercontent.com/u/14142?v=4?s=100" width="100px;" alt="dennis zhuang"/><br /><sub><b>dennis zhuang</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=killme2008" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/kerwin612"><img src="https://avatars.githubusercontent.com/u/3371163?v=4?s=100" width="100px;" alt="Kerwin Bryant"/><br /><sub><b>Kerwin Bryant</b></sub></a><br /><a href="#design-kerwin612" title="Design">🎨</a> <a href="https://github.com/apache/hertzbeat/commits?author=kerwin612" title="Code">💻</a> <a href="https://github.com/apache/hertzbeat/commits?author=kerwin612" title="Documentation">📖</a> <a href="https://github.com/apache/hertzbeat/issues?q=author%3Akerwin612" title="Bug reports">🐛</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/ShineDevelopment"><img src="https://avatars.githubusercontent.com/u/59306780?v=4?s=100" width="100px;" alt="daixianglong"/><br /><sub><b>daixianglong</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=ShineDevelopment" title="Documentation">📖</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/mchgood"><img src="https://avatars.githubusercontent.com/u/38482005?v=4?s=100" width="100px;" alt="mchgood"/><br /><sub><b>mchgood</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=mchgood" title="Documentation">📖</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/pwallk"><img src="https://avatars.githubusercontent.com/u/69385076?v=4?s=100" width="100px;" alt="kangli"/><br /><sub><b>kangli</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=pwallk" title="Code">💻</a> <a href="https://github.com/apache/hertzbeat/commits?author=pwallk" title="Documentation">📖</a> <a href="https://github.com/apache/hertzbeat/issues?q=author%3Apwallk" title="Bug reports">🐛</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/cdphantom"><img src="https://avatars.githubusercontent.com/u/12674795?v=4?s=100" width="100px;" alt="cdphantom"/><br /><sub><b>cdphantom</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=cdphantom" title="Code">💻</a></td>
</tr>
<tr>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/asd108908382"><img src="https://avatars.githubusercontent.com/u/77717999?v=4?s=100" width="100px;" alt="jiawei.guo"/><br /><sub><b>jiawei.guo</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=asd108908382" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/QBH-insist"><img src="https://avatars.githubusercontent.com/u/39401478?v=4?s=100" width="100px;" alt="QBH-insist"/><br /><sub><b>QBH-insist</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=QBH-insist" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/jiangsh-ui"><img src="https://avatars.githubusercontent.com/u/86990361?v=4?s=100" width="100px;" alt="jiangsh"/><br /><sub><b>jiangsh</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=jiangsh-ui" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/keaifafafa"><img src="https://avatars.githubusercontent.com/u/83876361?v=4?s=100" width="100px;" alt="Keaifa"/><br /><sub><b>Keaifa</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=keaifafafa" title="Code">💻</a> <a href="https://github.com/apache/hertzbeat/issues?q=author%3Akeaifafafa" title="Bug reports">🐛</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/loong95"><img src="https://avatars.githubusercontent.com/u/16333958?v=4?s=100" width="100px;" alt="Loong"/><br /><sub><b>Loong</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=loong95" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/ceekay47"><img src="https://avatars.githubusercontent.com/u/104664857?v=4?s=100" width="100px;" alt="Chandrakant Vankayalapati"/><br /><sub><b>Chandrakant Vankayalapati</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=ceekay47" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/MRgenial"><img src="https://avatars.githubusercontent.com/u/49973336?v=4?s=100" width="100px;" alt="b_mountain"/><br /><sub><b>b_mountain</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=MRgenial" title="Code">💻</a></td>
</tr>
<tr>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/TemirlanBasitov"><img src="https://avatars.githubusercontent.com/u/57500808?v=4?s=100" width="100px;" alt="TemirlanBasitov"/><br /><sub><b>TemirlanBasitov</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=TemirlanBasitov" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/wyfvsfy"><img src="https://avatars.githubusercontent.com/u/11973517?v=4?s=100" width="100px;" alt="wyfvsfy"/><br /><sub><b>wyfvsfy</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=wyfvsfy" title="Documentation">📖</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/sherry-peng2333"><img src="https://avatars.githubusercontent.com/u/70619577?v=4?s=100" width="100px;" alt="sherry-peng2333"/><br /><sub><b>sherry-peng2333</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=sherry-peng2333" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/lixiaobaivv"><img src="https://avatars.githubusercontent.com/u/39290771?v=4?s=100" width="100px;" alt="Yzzz"/><br /><sub><b>Yzzz</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=lixiaobaivv" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="http://www.bckf.cn/"><img src="https://avatars.githubusercontent.com/u/13309008?v=4?s=100" width="100px;" alt="puruidong"/><br /><sub><b>puruidong</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=pruidong" title="Documentation">📖</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/shinestare"><img src="https://avatars.githubusercontent.com/u/13570619?v=4?s=100" width="100px;" alt="shinestare"/><br /><sub><b>shinestare</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=shinestare" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/po-168"><img src="https://avatars.githubusercontent.com/u/185745593?v=4?s=100" width="100px;" alt="po-168"/><br /><sub><b>po-168</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=po-168" title="Code">💻</a></td>
</tr>
<tr>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/All-The-Best-for"><img src="https://avatars.githubusercontent.com/u/76414672?v=4?s=100" width="100px;" alt="wbs99"/><br /><sub><b>wbs99</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=All-The-Best-for" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/starryCoder"><img src="https://avatars.githubusercontent.com/u/46510059?v=4?s=100" width="100px;" alt="starryCoder"/><br /><sub><b>starryCoder</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=starryCoder" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/hasimmollah"><img src="https://avatars.githubusercontent.com/u/32538599?v=4?s=100" width="100px;" alt="hasimmollah"/><br /><sub><b>hasimmollah</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=hasimmollah" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/ayu-v0"><img src="https://avatars.githubusercontent.com/u/127600988?v=4?s=100" width="100px;" alt="Ayu"/><br /><sub><b>Ayu</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=ayu-v0" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/Rancho-7"><img src="https://avatars.githubusercontent.com/u/59016860?v=4?s=100" width="100px;" alt="Nick Guo"/><br /><sub><b>Nick Guo</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=Rancho-7" title="Documentation">📖</a> <a href="https://github.com/apache/hertzbeat/commits?author=Rancho-7" title="Code">💻</a> <a href="https://github.com/apache/hertzbeat/issues?q=author%3ARancho-7" title="Bug reports">🐛</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/doveLin0818"><img src="https://avatars.githubusercontent.com/u/190927907?v=4?s=100" width="100px;" alt="doveLin"/><br /><sub><b>doveLin</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=doveLin0818" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://zzrl.cc/"><img src="https://avatars.githubusercontent.com/u/91836599?v=4?s=100" width="100px;" alt="yunfan24"/><br /><sub><b>yunfan24</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=yunfan24" title="Code">💻</a> <a href="https://github.com/apache/hertzbeat/commits?author=yunfan24" title="Documentation">📖</a> <a href="https://github.com/apache/hertzbeat/issues?q=author%3Ayunfan24" title="Bug reports">🐛</a> <a href="https://github.com/apache/hertzbeat/commits?author=yunfan24" title="Tests">⚠️</a> <a href="#blog-yunfan24" title="Blogposts">📝</a></td>
</tr>
<tr>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/lctking"><img src="https://avatars.githubusercontent.com/u/168249998?v=4?s=100" width="100px;" alt="nullwli"/><br /><sub><b>nullwli</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=lctking" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://simonsigre.com/"><img src="https://avatars.githubusercontent.com/u/14932913?v=4?s=100" width="100px;" alt="Simon Sigré"/><br /><sub><b>Simon Sigré</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=simonsigre" title="Documentation">📖</a> <a href="https://github.com/apache/hertzbeat/commits?author=simonsigre" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="http://www.ponfee.cn/"><img src="https://avatars.githubusercontent.com/u/46117331?v=4?s=100" width="100px;" alt="ponfee"/><br /><sub><b>ponfee</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=ponfee" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/Vedant7789"><img src="https://avatars.githubusercontent.com/u/147625492?v=4?s=100" width="100px;" alt="Vedant7789"/><br /><sub><b>Vedant7789</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=Vedant7789" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/Craaaaazy77"><img src="https://avatars.githubusercontent.com/u/23025522?v=4?s=100" width="100px;" alt="Craaaaazy77"/><br /><sub><b>Craaaaazy77</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=Craaaaazy77" title="Documentation">📖</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/Suvrat1629"><img src="https://avatars.githubusercontent.com/u/140749446?v=4?s=100" width="100px;" alt="Suvrat1629"/><br /><sub><b>Suvrat1629</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=Suvrat1629" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="http://ghyghoo8.github.io/"><img src="https://avatars.githubusercontent.com/u/363129?v=4?s=100" width="100px;" alt="ghy"/><br /><sub><b>ghy</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=ghyghoo8" title="Code">💻</a></td>
</tr>
<tr>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/helei1030"><img src="https://avatars.githubusercontent.com/u/11839080?v=4?s=100" width="100px;" alt="helei1030"/><br /><sub><b>helei1030</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=helei1030" title="Documentation">📖</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://medium.com/@pjfanning"><img src="https://avatars.githubusercontent.com/u/11783444?v=4?s=100" width="100px;" alt="PJ Fanning"/><br /><sub><b>PJ Fanning</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=pjfanning" title="Code">💻</a> <a href="https://github.com/apache/hertzbeat/issues?q=author%3Apjfanning" title="Bug reports">🐛</a> <a href="https://github.com/apache/hertzbeat/commits?author=pjfanning" title="Tests">⚠️</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/MonsterChenzhuo"><img src="https://avatars.githubusercontent.com/u/60029759?v=4?s=100" width="100px;" alt="monster"/><br /><sub><b>monster</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=MonsterChenzhuo" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/MasamiYui"><img src="https://avatars.githubusercontent.com/u/22274133?v=4?s=100" width="100px;" alt="Sherlock Yin"/><br /><sub><b>Sherlock Yin</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=MasamiYui" title="Code">💻</a> <a href="https://github.com/apache/hertzbeat/commits?author=MasamiYui" title="Documentation">📖</a> <a href="https://github.com/apache/hertzbeat/issues?q=author%3AMasamiYui" title="Bug reports">🐛</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/wanhao23"><img src="https://avatars.githubusercontent.com/u/29560961?v=4?s=100" width="100px;" alt="wanhao"/><br /><sub><b>wanhao</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=wanhao23" title="Code">💻</a> <a href="https://github.com/apache/hertzbeat/commits?author=wanhao23" title="Documentation">📖</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/jonasHanhan"><img src="https://avatars.githubusercontent.com/u/130035609?v=4?s=100" width="100px;" alt="jonasHanhan"/><br /><sub><b>jonasHanhan</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=jonasHanhan" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/NikhilMurugesan"><img src="https://avatars.githubusercontent.com/u/49281792?v=4?s=100" width="100px;" alt="NikhilMurugesan"/><br /><sub><b>NikhilMurugesan</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=NikhilMurugesan" title="Code">💻</a></td>
</tr>
<tr>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/myangle1120"><img src="https://avatars.githubusercontent.com/u/19237013?v=4?s=100" width="100px;" alt="myangle1120"/><br /><sub><b>myangle1120</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=myangle1120" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/yasminvo"><img src="https://avatars.githubusercontent.com/u/107528848?v=4?s=100" width="100px;" alt="yasminvo"/><br /><sub><b>yasminvo</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=yasminvo" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/notbugggg"><img src="https://avatars.githubusercontent.com/u/147966331?v=4?s=100" width="100px;" alt="不关银渐层的事哦"/><br /><sub><b>不关银渐层的事哦</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=notbugggg" title="Code">💻</a> <a href="https://github.com/apache/hertzbeat/issues?q=author%3Anotbugggg" title="Bug reports">🐛</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/yyahang"><img src="https://avatars.githubusercontent.com/u/90464876?v=4?s=100" width="100px;" alt="yyahang"/><br /><sub><b>yyahang</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=yyahang" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/JuJinPark"><img src="https://avatars.githubusercontent.com/u/44892459?v=4?s=100" width="100px;" alt="jujin"/><br /><sub><b>jujin</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=JuJinPark" title="Code">💻</a> <a href="https://github.com/apache/hertzbeat/commits?author=JuJinPark" title="Documentation">📖</a> <a href="#ideas-JuJinPark" title="Ideas, Planning, & Feedback">🤔</a> <a href="#blog-JuJinPark" title="Blogposts">📝</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/LL-LIN"><img src="https://avatars.githubusercontent.com/u/43002118?v=4?s=100" width="100px;" alt="LL-LIN"/><br /><sub><b>LL-LIN</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=LL-LIN" title="Code">💻</a> <a href="https://github.com/apache/hertzbeat/issues?q=author%3ALL-LIN" title="Bug reports">🐛</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://bigcyy.github.io/"><img src="https://avatars.githubusercontent.com/u/73413979?v=4?s=100" width="100px;" alt="Yang Chen"/><br /><sub><b>Yang Chen</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=bigcyy" title="Code">💻</a> <a href="https://github.com/apache/hertzbeat/commits?author=bigcyy" title="Documentation">📖</a> <a href="https://github.com/apache/hertzbeat/issues?q=author%3Abigcyy" title="Bug reports">🐛</a></td>
</tr>
<tr>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/sarthakeash"><img src="https://avatars.githubusercontent.com/u/74091160?v=4?s=100" width="100px;" alt="Sarthak Arora"/><br /><sub><b>Sarthak Arora</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=sarthakeash" title="Code">💻</a> <a href="https://github.com/apache/hertzbeat/commits?author=sarthakeash" title="Documentation">📖</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/PengJingzhao"><img src="https://avatars.githubusercontent.com/u/97368949?v=4?s=100" width="100px;" alt="彭镜肇"/><br /><sub><b>彭镜肇</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=PengJingzhao" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/gagaradio"><img src="https://avatars.githubusercontent.com/u/18532370?v=4?s=100" width="100px;" alt="Walter Jia"/><br /><sub><b>Walter Jia</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=gagaradio" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/boyucjz"><img src="https://avatars.githubusercontent.com/u/18730041?v=4?s=100" width="100px;" alt="boyucjz"/><br /><sub><b>boyucjz</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=boyucjz" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/Cyanty"><img src="https://avatars.githubusercontent.com/u/153884653?v=4?s=100" width="100px;" alt="Cyanty"/><br /><sub><b>Cyanty</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=Cyanty" title="Code">💻</a> <a href="https://github.com/apache/hertzbeat/commits?author=Cyanty" title="Documentation">📖</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/KevinLLF"><img src="https://avatars.githubusercontent.com/u/85452733?v=4?s=100" width="100px;" alt="Jay丿167"/><br /><sub><b>Jay丿167</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=KevinLLF" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/Duansg"><img src="https://avatars.githubusercontent.com/u/112607719?v=4?s=100" width="100px;" alt="Duansg"/><br /><sub><b>Duansg</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=Duansg" title="Documentation">📖</a></td>
</tr>
<tr>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/xiaomizhou2"><img src="https://avatars.githubusercontent.com/u/47807926?v=4?s=100" width="100px;" alt="zhangyaxi"/><br /><sub><b>zhangyaxi</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=xiaomizhou2" title="Code">💻</a> <a href="https://github.com/apache/hertzbeat/commits?author=xiaomizhou2" title="Tests">⚠️</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/RainBondsongyg"><img src="https://avatars.githubusercontent.com/u/94501396?v=4?s=100" width="100px;" alt="songyg"/><br /><sub><b>songyg</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=RainBondsongyg" title="Documentation">📖</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/lx1229"><img src="https://avatars.githubusercontent.com/u/44620005?v=4?s=100" width="100px;" alt="Liuxin"/><br /><sub><b>Liuxin</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=lx1229" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/yy549159265"><img src="https://avatars.githubusercontent.com/u/40821310?v=4?s=100" width="100px;" alt="yy549159265"/><br /><sub><b>yy549159265</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=yy549159265" title="Code">💻</a> <a href="https://github.com/apache/hertzbeat/commits?author=yy549159265" title="Tests">⚠️</a> <a href="#design-yy549159265" title="Design">🎨</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/cto-huhang"><img src="https://avatars.githubusercontent.com/u/53338629?v=4?s=100" width="100px;" alt="cto-huhang"/><br /><sub><b>cto-huhang</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=cto-huhang" title="Documentation">📖</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/Saramanda9988"><img src="https://avatars.githubusercontent.com/u/176664901?v=4?s=100" width="100px;" alt="LunaRain_079"/><br /><sub><b>LunaRain_079</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=Saramanda9988" title="Documentation">📖</a> <a href="https://github.com/apache/hertzbeat/commits?author=Saramanda9988" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/delei"><img src="https://avatars.githubusercontent.com/u/17263766?v=4?s=100" width="100px;" alt="DeleiGuo"/><br /><sub><b>DeleiGuo</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=delei" title="Documentation">📖</a> <a href="https://github.com/apache/hertzbeat/commits?author=delei" title="Code">💻</a> <a href="https://github.com/apache/hertzbeat/commits?author=delei" title="Tests">⚠️</a> <a href="https://github.com/apache/hertzbeat/issues?q=author%3Adelei" title="Bug reports">🐛</a></td>
</tr>
<tr>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/chingjustwe"><img src="https://avatars.githubusercontent.com/u/13643747?v=4?s=100" width="100px;" alt="Rocky, Chi"/><br /><sub><b>Rocky, Chi</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=chingjustwe" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/rowankid"><img src="https://avatars.githubusercontent.com/u/18652781?v=4?s=100" width="100px;" alt="Wenqi Luo"/><br /><sub><b>Wenqi Luo</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/issues?q=author%3Arowankid" title="Bug reports">🐛</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/tuzuy"><img src="https://avatars.githubusercontent.com/u/95274591?v=4?s=100" width="100px;" alt="tuzuy"/><br /><sub><b>tuzuy</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=tuzuy" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/carlpinto25"><img src="https://avatars.githubusercontent.com/u/117299909?v=4?s=100" width="100px;" alt="carl pinto"/><br /><sub><b>carl pinto</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=carlpinto25" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://cxhello.top/"><img src="https://avatars.githubusercontent.com/u/49056040?v=4?s=100" width="100px;" alt="cxhello"/><br /><sub><b>cxhello</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=cxhello" title="Documentation">📖</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/jl15988"><img src="https://avatars.githubusercontent.com/u/70638770?v=4?s=100" width="100px;" alt="会功夫的李白"/><br /><sub><b>会功夫的李白</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=jl15988" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://blog.aytop.cloud/"><img src="https://avatars.githubusercontent.com/u/37127008?v=4?s=100" width="100px;" alt="Albert.Yang"/><br /><sub><b>Albert.Yang</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=AlbertYang0801" title="Code">💻</a></td>
</tr>
<tr>
<td align="center" valign="top" width="14.28%"><a href="https://blog.tokenlen.top/"><img src="https://avatars.githubusercontent.com/u/150590575?v=4?s=100" width="100px;" alt="zhou yong kang"/><br /><sub><b>zhou yong kang</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=mengnankkkk" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/warrobe"><img src="https://avatars.githubusercontent.com/u/89446159?v=4?s=100" width="100px;" alt="warrobe"/><br /><sub><b>warrobe</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=warrobe" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/Jetiaime"><img src="https://avatars.githubusercontent.com/u/93769000?v=4?s=100" width="100px;" alt="TeAmo"/><br /><sub><b>TeAmo</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=Jetiaime" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/pentium100"><img src="https://avatars.githubusercontent.com/u/27917?v=4?s=100" width="100px;" alt="pentium100"/><br /><sub><b>pentium100</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=pentium100" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/dedyks"><img src="https://avatars.githubusercontent.com/u/23741665?v=4?s=100" width="100px;" alt="Dedy Kurniawan Santoso"/><br /><sub><b>Dedy Kurniawan Santoso</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=dedyks" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/KOYR"><img src="https://avatars.githubusercontent.com/u/53216619?v=4?s=100" width="100px;" alt="KOYR"/><br /><sub><b>KOYR</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=KOYR" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/Lathika226"><img src="https://avatars.githubusercontent.com/u/178710568?v=4?s=100" width="100px;" alt="LathikaBaddam"/><br /><sub><b>LathikaBaddam</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=Lathika226" title="Documentation">📖</a></td>
</tr>
<tr>
<td align="center" valign="top" width="14.28%"><a href="https://shadwal.space/"><img src="https://avatars.githubusercontent.com/u/119167601?v=4?s=100" width="100px;" alt="Sahil Shadwal"/><br /><sub><b>Sahil Shadwal</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=Sahil-Shadwal" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/BhanuNidumolu"><img src="https://avatars.githubusercontent.com/u/180380413?v=4?s=100" width="100px;" alt="N.Bhanu Prasad"/><br /><sub><b>N.Bhanu Prasad</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=BhanuNidumolu" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://prakashh-portfolio.vercel.app/"><img src="https://avatars.githubusercontent.com/u/183058331?v=4?s=100" width="100px;" alt="Prakash Kumar"/><br /><sub><b>Prakash Kumar</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=Prakash1185" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/orangeCatDeveloper"><img src="https://avatars.githubusercontent.com/u/95899648?v=4?s=100" width="100px;" alt="NekoPunch"/><br /><sub><b>NekoPunch</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=orangeCatDeveloper" title="Code">💻</a> <a href="https://github.com/apache/hertzbeat/commits?author=orangeCatDeveloper" title="Documentation">📖</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://wy471x.github.io/"><img src="https://avatars.githubusercontent.com/u/52033069?v=4?s=100" width="100px;" alt="wy471x"/><br /><sub><b>wy471x</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=wy471x" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/hengyuss"><img src="https://avatars.githubusercontent.com/u/81064732?v=4?s=100" width="100px;" alt="hengyuss"/><br /><sub><b>hengyuss</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=hengyuss" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://moduvoice.com/"><img src="https://avatars.githubusercontent.com/u/291867022?v=4?s=100" width="100px;" alt="moduvoice"/><br /><sub><b>moduvoice</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=moduvoice" title="Documentation">📖</a></td>
</tr>
<tr>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/hutiefang76"><img src="https://avatars.githubusercontent.com/u/137664623?v=4?s=100" width="100px;" alt="hutiefang76"/><br /><sub><b>hutiefang76</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=hutiefang76" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://zylatent.com/"><img src="https://avatars.githubusercontent.com/u/250777154?v=4?s=100" width="100px;" alt="柳含知 Liu Hanzhi"/><br /><sub><b>柳含知 Liu Hanzhi</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=ZhouYinLong-lab" title="Documentation">📖</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/wilmerdooley"><img src="https://avatars.githubusercontent.com/u/259930736?v=4?s=100" width="100px;" alt="wilmerdooley"/><br /><sub><b>wilmerdooley</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=wilmerdooley" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/Zmjjeff7"><img src="https://avatars.githubusercontent.com/u/175370943?v=4?s=100" width="100px;" alt="Zhenhong Guo"/><br /><sub><b>Zhenhong Guo</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=Zmjjeff7" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/abhyudayareddy"><img src="https://avatars.githubusercontent.com/u/54602866?v=4?s=100" width="100px;" alt="abhyudayareddy"/><br /><sub><b>abhyudayareddy</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=abhyudayareddy" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/neon-hippo"><img src="https://avatars.githubusercontent.com/u/165560498?v=4?s=100" width="100px;" alt="neon-hippo"/><br /><sub><b>neon-hippo</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=neon-hippo" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/P-Peaceful"><img src="https://avatars.githubusercontent.com/u/52856161?v=4?s=100" width="100px;" alt="P_Peaceful"/><br /><sub><b>P_Peaceful</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=P-Peaceful" title="Code">💻</a> <a href="https://github.com/apache/hertzbeat/commits?author=P-Peaceful" title="Documentation">📖</a></td>
</tr>
<tr>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/zhusaidong"><img src="https://avatars.githubusercontent.com/u/3039961?v=4?s=100" width="100px;" alt="zhusaidong"/><br /><sub><b>zhusaidong</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=zhusaidong" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/zhehenlu"><img src="https://avatars.githubusercontent.com/u/31504542?v=4?s=100" width="100px;" alt="zhlu"/><br /><sub><b>zhlu</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=zhehenlu" title="Code">💻</a> <a href="https://github.com/apache/hertzbeat/commits?author=zhehenlu" title="Documentation">📖</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/brettgervasoni"><img src="https://avatars.githubusercontent.com/u/34056000?v=4?s=100" width="100px;" alt="brettgervasoni"/><br /><sub><b>brettgervasoni</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=brettgervasoni" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/Darshan-paul"><img src="https://avatars.githubusercontent.com/u/211450705?v=4?s=100" width="100px;" alt="Darshan-paul"/><br /><sub><b>Darshan-paul</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=Darshan-paul" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/04cb"><img src="https://avatars.githubusercontent.com/u/111667698?v=4?s=100" width="100px;" alt="layla"/><br /><sub><b>layla</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=04cb" title="Documentation">📖</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/miantalha45"><img src="https://avatars.githubusercontent.com/u/155809113?v=4?s=100" width="100px;" alt="Talha Amjad"/><br /><sub><b>Talha Amjad</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=miantalha45" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://turanalmammadov.com/"><img src="https://avatars.githubusercontent.com/u/16321061?v=4?s=100" width="100px;" alt="Turan Almammadov"/><br /><sub><b>Turan Almammadov</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=turanalmammadov" title="Code">💻</a> <a href="https://github.com/apache/hertzbeat/commits?author=turanalmammadov" title="Documentation">📖</a></td>
</tr>
<tr>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/zhaoyangplus"><img src="https://avatars.githubusercontent.com/u/245090302?v=4?s=100" width="100px;" alt="zhaoyangplus"/><br /><sub><b>zhaoyangplus</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=zhaoyangplus" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/yexuanyang"><img src="https://avatars.githubusercontent.com/u/73885401?v=4?s=100" width="100px;" alt="Yang Yexuan"/><br /><sub><b>Yang Yexuan</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=yexuanyang" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/markguo123"><img src="https://avatars.githubusercontent.com/u/155072651?v=4?s=100" width="100px;" alt="markguo123"/><br /><sub><b>markguo123</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=markguo123" title="Documentation">📖</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/leo-934"><img src="https://avatars.githubusercontent.com/u/55838224?v=4?s=100" width="100px;" alt="leo"/><br /><sub><b>leo</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=leo-934" title="Code">💻</a> <a href="https://github.com/apache/hertzbeat/commits?author=leo-934" title="Documentation">📖</a> <a href="#blog-leo-934" title="Blogposts">📝</a></td>
</tr>
</tbody>
</table>
@@ -452,27 +539,23 @@ Thanks these wonderful people, welcome to join us:
<!-- markdownlint-restore -->
<!-- prettier-ignore-end -->
<!-- ALL-CONTRIBUTORS-LIST:END -->
<!-- ALL-CONTRIBUTORS-LIST:END -->
## 💬 社区交流
##### Channel
##### Channel
[订阅邮件列表](https://lists.apache.org/list.html?dev@hertzbeat.apache.org) : 发送邮件至 `dev-subscribe@hertzbeat.apache.org` 来订阅邮件列表.
[Chat On Discord](https://discord.gg/Fb6M73htGr)
微信交流群 : 加 `tan-cloud` 好友邀请进群.
微信交流群 : 加 `ahertzbeat` 好友邀请进群.
微信公众号 : 搜索 ID `usthecom`.
[QQ交流群](https://jq.qq.com/?_wv=1027&k=Bud9OzdI) : 群号 `630061200`
[Github Discussion](https://github.com/apache/hertzbeat/discussions)
[Reddit Community](https://www.reddit.com/r/hertzbeat/)
[Follow Us Twitter](https://twitter.com/hertzbeat1024)
[Follow Us Twitter](https://x.com/hertzbeat1024)
[Subscribe YouTube](https://www.youtube.com/channel/UCri75zfWX0GHqJFPENEbLow)
@@ -490,15 +573,9 @@ HertzBeat is built on so many great open source projects, thanks to them!
<p align="left">
<img src="./home/static/img/home/cncf-landscape-left-logo.svg" width="300">&nbsp;&nbsp;<img src="./home/static/img/home/cncf-right-logo.svg" width="345" />
<br /><br />
HertzBeat has been included in the <a href="https://landscape.cncf.io/guide?item=observability-and-analysis--monitoring--hertzbeat#observability-and-analysis--monitoring">
CNCF Observability And Analysis - Monitoring Landscape.</a>
HertzBeat has been included in the <a href="https://landscape.cncf.io/?item=observability-and-analysis--observability--hertzbeat">
CNCF Observability And Analysis - Observability Landscape.</a>
</p>
## Star History
[![Star History Chart](https://api.star-history.com/svg?repos=apache/hertzbeat&type=Date)](https://star-history.com/#apache/hertzbeat&Date)
## 🛡️ License
[`Apache License, Version 2.0`](https://www.apache.org/licenses/LICENSE-2.0.html)
+584
View File
@@ -0,0 +1,584 @@
<p align="center">
<a href="https://hertzbeat.apache.org">
<img alt="hertzbeat" src="/home/static/img/hertzbeat-brand.svg" width="260">
</a>
</p>
<p align="center">
<b>Readme</b>:
<a href="README.md">English</a> | <a href="README_CN.md">中文</a> | <b><a href="README_JP.md">日本語</a></b>
</p>
[![Discord](https://img.shields.io/badge/Chat-Discord-7289DA?logo=discord)](https://discord.gg/Fb6M73htGr)
[![Twitter](https://img.shields.io/twitter/follow/hertzbeat1024?logo=twitter)](https://x.com/hertzbeat1024)
[![OpenSSF Best Practices](https://www.bestpractices.dev/projects/8139/badge)](https://www.bestpractices.dev/projects/8139)
[![codecov](https://codecov.io/gh/apache/HertzBeat/branch/master/graph/badge.svg)](https://app.codecov.io/gh/apache/hertzbeat)
[![Docker Pulls](https://img.shields.io/docker/pulls/apache/hertzbeat?style=%20for-the-badge&logo=docker&label=DockerHub%20Download)](https://hub.docker.com/r/apache/hertzbeat)
[![Artifact Hub](https://img.shields.io/endpoint?url=https://artifacthub.io/badge/repository/hertzbeat)](https://artifacthub.io/packages/search?repo=hertzbeat)
[![YouTube Channel Subscribers](https://img.shields.io/youtube/channel/subscribers/UCri75zfWX0GHqJFPENEbLow?logo=youtube&label=YouTube%20Channel)](https://www.youtube.com/channel/UCri75zfWX0GHqJFPENEbLow)
[![Contribute with Gitpod](https://img.shields.io/badge/Contribute%20with-Gitpod-908a85?logo=gitpod&color=green)](https://gitpod.io/#https://github.com/apache/hertzbeat)
**公式サイト: [hertzbeat.apache.org](https://hertzbeat.apache.org)**
**メール:** メーリングリストに登録するために、<a href="mailto:dev-subscribe@hertzbeat.apache.org">dev-subscribe@hertzbeat.apache.org</a>にメールを送ってください。
## 🎡 <font color="green">紹介</font>
[Apache HertzBeat™](https://github.com/apache/hertzbeat) は AI 駆動の次世代オープンソースリアルタイム観測システムです。メトリクスとログの統一収集、アラートの一元配信、インテリジェント管理分析。エージェント不要、高性能クラスタ、強力なカスタム監視とステータスページ構築機能を提供します。
### 特性
- **収集+分析+アラート+通知**を一つのプラットフォームに統合し、HertzBeat AI 駆動の新しいインタラクションと機能、内蔵 MCP Server 機能を提供。
- 統一メトリクスプラットフォーム、エージェントレス、Prometheus互換、アプリケーションサービス、プログラム、データベース、キャッシュ、オペレーティングシステム、ビッグデータ、ミドルウェア、Webサーバー、クラウドネイティブ、ネットワーク、カスタム監視などをサポート。
- 統一ログプラットフォーム、OTLP プロトコルを通じて複数のログソースをシームレスに統合してレポート。
- 統一アラートプラットフォーム、内部アラートと様々な外部アラートソースを統合接続、統一アラート処理分析、柔軟なリアルタイムと周期的閾値ルール、グループ収束、サイレンス、抑制など。
- 統一メッセージ配信、アラートプラットフォームで処理後、`メール` `Discord` `Slack` `Telegram` `DingTalk` `WeChat` `FeiShu` `SMS` `Webhook` `ServerChan` などの方法で配信通知。
- `Http、Jmx、Ssh、Snmp、Jdbc、Prometheus`などのプロトコルを設定可能にし、テンプレート`YML`ファイルをオンラインで設定するだけで、あらゆるメトリクスを収集できるようにします。HertzBeatでオンライン設定するだけで、`K8s``Docker`のような新しい監視タイプに素早く対応できることを想像してみてください。
- 高性能で、コレクタークラスタの水平拡張、マルチ分離ネットワーク監視、クラウドエッジ協調をサポート。
- 強力なステータスページ構築機能を提供し、サービスのリアルタイムステータスをユーザーに簡単に伝達。
> `HertzBeat`の統一プラットフォーム、AI インテリジェンス、強力なカスタマイズ、多種類サポート、高性能、容易な拡張性は、ユーザーが迅速かつ便利に観測要件を実現することを支援することを目的としています。
----
----
## 🥐 モジュール
![hertzBeat](home/static/img/docs/hertzbeat-arch.png)
## 🐕 クイックスタート
- HertzBeat をローカルに展開する場合は、以下のデプロイメントドキュメントを参照してください。
### 🍞 HertzBeatのインストール
> HertzBeatは、ソースコードのインストールとブート、Dockerコンテナの実行とインストールパッケージによるインストールとデプロイをサポートし、CPUアーキテクチャはx86/arm64をサポートします。
##### 方式1:Docker
1. `docker` で以下の指令を実行します:
```shell
docker run -d -p 1157:1157 -p 1158:1158 --name hertzbeat apache/hertzbeat
```
2. スタート:`http://localhost:1157`にアクセスします。デフォルトのアカウントとパスワード:`admin/hertzbeat`。
3. コレクタークラスタのデプロイメント(オプション)
```shell
docker run -d -e IDENTITY=custom-collector-name -e MANAGER_HOST=127.0.0.1 -e MANAGER_PORT=1158 --name hertzbeat-collector apache/hertzbeat-collector
```
- `-e IDENTITY=custom-collector-name` :コレクターのユニーク ID。
- `-e MODE=public` :実行モード(パブリッククラスタまたはプライベートクラウドエッジ)。
- `-e MANAGER_HOST=127.0.0.1` :メインhertzbeatサーバーのIP。
- `-e MANAGER_PORT=1158` :メインhertzbeatサーバポート。
詳細ステップ [Dockerで HertzBeat をインストール](https://hertzbeat.apache.org/docs/start/docker-deploy)
##### 方式2:インストールパッケージ
1. リリースパッケージ `apache-hertzbeat-xx-bin.tar.gz` をダウンロードします [Download](https://hertzbeat.apache.org/docs/download)
2. HertzBeat の設定ファイル `hertzbeat/config/application.yml` を編集します(任意)
3. コマンド `$ ./bin/startup.sh` または `bin/startup.bat` を実行します
4. ブラウザで `http://localhost:1157` にアクセスします。デフォルトのアカウントとパスワードは `admin/hertzbeat` です
5. コレクタークラスタのデプロイメント(オプション)
- 別ホストにコレクターのインストールパッケージ `apache-hertzbeat-collector-xx-bin.tar.gz`(JVM コレクター)または対象プラットフォーム向けの Native コレクターパッケージ(例: `apache-hertzbeat-collector-native-xx-linux-amd64-bin.tar.gz`、`apache-hertzbeat-collector-native-xx-windows-amd64-bin.zip`)をダウンロードします [Download](https://hertzbeat.apache.org/docs/download)
- コレクターの設定ファイル `hertzbeat-collector/config/application.yml` を編集します
```yaml
collector:
dispatch:
entrance:
netty:
enabled: true
identity: ${IDENTITY:}
mode: ${MODE:public}
manager-host: ${MANAGER_HOST:127.0.0.1}
manager-port: ${MANAGER_PORT:1158}
```
- `identity: ${IDENTITY:}`:コレクターのユニークID。
- `mode: ${MODE:public}`:実行モード(パブリッククラスタまたはプライベートクラウドエッジ)。
- `manager-host: ${MANAGER_HOST:127.0.0.1}`:メインhertzbeatサーバーのIP。
- `manager-port: ${MANAGER_PORT:1158}`:メインhertzbeatサーバポート。
- `ext-lib` に JDBC ドライバーを置かない場合、MySQL、MariaDB、OceanBase は組み込みのクエリエンジンを使って Native コレクターパッケージでも監視できます。TiDB も SQL クエリのメトリクスセットについては同じルールです。
- `ext-lib` に `mysql-connector-j` を置いた場合は、再起動後に組み込みサーバーコレクターまたは JVM コレクターが MySQL、MariaDB、OceanBase で自動的に JDBC を優先します。TiDB も SQL クエリのメトリクスセットについては同じルールで、HTTP メトリクスは影響を受けません。Oracle と DB2 は引き続き外部 JDBC ドライバーに依存するため、JVM コレクターパッケージを使用してください。
- JVM コレクターのインストールパッケージは `$ ./bin/startup.sh` または `bin/startup.bat`、Linux/macOS の Native コレクターパッケージは `$ ./bin/startup.sh`、Windows の Native コレクターパッケージは `bin\\startup.bat` で起動します。
- メインの HertzBeat サービス `http://localhost:1157` にアクセスすると、登録された新しいコレクターを確認できます。
詳細ステップ [インストールパッケージで HertzBeat をインストール](https://hertzbeat.apache.org/docs/start/package-deploy)
##### 方式3:ローカルの実行
1. ローカルの実行には、バックエンドのプロジェクト`hertzbeat-startup`とフロントエンドのプロジェクト`web-app`を起動する必要があります。
2. バックエンド:`maven3+`、`Java25`、`lombok` の環境が必要です。`YML` 設定を修正し、Java 仮想マシンパラメータに `--add-opens=java.base/java.nio=org.apache.arrow.memory.core,ALL-UNNAMED` を追加して `hertzbeat-startup` を起動します。
3. フロントエンド:`nodejs` と `pnpm` の環境が必要です。ローカルのバックエンドが立ち上がったら、`web-app` ディレクトリで `pnpm install` を実行し、続けて `pnpm start` を実行します。
4. スタート:`http://localhost:4200`にアクセスします。デフォルトのアカウントとパスワード:`admin/hertzbeat`。
詳細ステップ [貢献ガイド](CONTRIBUTING.md)
##### 方式4:Docker-Compose
[Docker-Compose 部署脚本](script/docker-compose)でpostgresql/mysqlデータベース、victoria-metrics、iotdb、またはtdengine時系列データベースとHertzBeat一括デプロイ。
詳細ステップ [Docker-Compose で HertzBeat をインストール](script/docker-compose/README.md)
##### 方式5:Kubernetes Helm Charts
Helm ChartでHertzBeatクラスタコンポーネントをKubernetesクラスタに一括デプロイ。
詳細ステップ [Artifact Hub](https://artifacthub.io/packages/helm/hertzbeat/hertzbeat)
**HAVE FUN**
## ✨ Contributors
Thanks these wonderful people, welcome to join us:
[貢献ガイド](CONTRIBUTING.md)
<!-- ALL-CONTRIBUTORS-LIST:START - Do not remove or modify this section -->
<!-- prettier-ignore-start -->
<!-- markdownlint-disable -->
<table>
<tbody>
<tr>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/tomsun28"><img src="https://avatars.githubusercontent.com/u/24788200?v=4?s=100" width="100px;" alt="tomsun28"/><br /><sub><b>tomsun28</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=tomsun28" title="Code">💻</a> <a href="https://github.com/apache/hertzbeat/commits?author=tomsun28" title="Documentation">📖</a> <a href="#design-tomsun28" title="Design">🎨</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/wang1027-wqh"><img src="https://avatars.githubusercontent.com/u/71161318?v=4?s=100" width="100px;" alt="会编程的王学长"/><br /><sub><b>会编程的王学长</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=wang1027-wqh" title="Code">💻</a> <a href="https://github.com/apache/hertzbeat/commits?author=wang1027-wqh" title="Documentation">📖</a> <a href="#design-wang1027-wqh" title="Design">🎨</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://www.maxkey.top/"><img src="https://avatars.githubusercontent.com/u/1563377?v=4?s=100" width="100px;" alt="MaxKey"/><br /><sub><b>MaxKey</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=shimingxy" title="Code">💻</a> <a href="#design-shimingxy" title="Design">🎨</a> <a href="#ideas-shimingxy" title="Ideas, Planning, & Feedback">🤔</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://blog.gcdd.top/"><img src="https://avatars.githubusercontent.com/u/26523525?v=4?s=100" width="100px;" alt="观沧海"/><br /><sub><b>观沧海</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=gcdd1993" title="Code">💻</a> <a href="#design-gcdd1993" title="Design">🎨</a> <a href="https://github.com/apache/hertzbeat/issues?q=author%3Agcdd1993" title="Bug reports">🐛</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/a25017012"><img src="https://avatars.githubusercontent.com/u/32265356?v=4?s=100" width="100px;" alt="yuye"/><br /><sub><b>yuye</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=a25017012" title="Code">💻</a> <a href="https://github.com/apache/hertzbeat/commits?author=a25017012" title="Documentation">📖</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/jx10086"><img src="https://avatars.githubusercontent.com/u/5323228?v=4?s=100" width="100px;" alt="jx10086"/><br /><sub><b>jx10086</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=jx10086" title="Code">💻</a> <a href="https://github.com/apache/hertzbeat/issues?q=author%3Ajx10086" title="Bug reports">🐛</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/winnerTimer"><img src="https://avatars.githubusercontent.com/u/76024658?v=4?s=100" width="100px;" alt="winnerTimer"/><br /><sub><b>winnerTimer</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=winnerTimer" title="Code">💻</a> <a href="https://github.com/apache/hertzbeat/issues?q=author%3AwinnerTimer" title="Bug reports">🐛</a></td>
</tr>
<tr>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/goo-kits"><img src="https://avatars.githubusercontent.com/u/13163673?v=4?s=100" width="100px;" alt="goo-kits"/><br /><sub><b>goo-kits</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=goo-kits" title="Code">💻</a> <a href="https://github.com/apache/hertzbeat/issues?q=author%3Agoo-kits" title="Bug reports">🐛</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/brave4Time"><img src="https://avatars.githubusercontent.com/u/105094014?v=4?s=100" width="100px;" alt="brave4Time"/><br /><sub><b>brave4Time</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=brave4Time" title="Code">💻</a> <a href="https://github.com/apache/hertzbeat/issues?q=author%3Abrave4Time" title="Bug reports">🐛</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/walkerlee-lab"><img src="https://avatars.githubusercontent.com/u/8426753?v=4?s=100" width="100px;" alt="WalkerLee"/><br /><sub><b>WalkerLee</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=walkerlee-lab" title="Code">💻</a> <a href="https://github.com/apache/hertzbeat/issues?q=author%3Awalkerlee-lab" title="Bug reports">🐛</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/fullofjoy"><img src="https://avatars.githubusercontent.com/u/30247571?v=4?s=100" width="100px;" alt="jianghang"/><br /><sub><b>jianghang</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=fullofjoy" title="Code">💻</a> <a href="https://github.com/apache/hertzbeat/issues?q=author%3Afullofjoy" title="Bug reports">🐛</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/ChineseTony"><img src="https://avatars.githubusercontent.com/u/24618786?v=4?s=100" width="100px;" alt="ChineseTony"/><br /><sub><b>ChineseTony</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=ChineseTony" title="Code">💻</a> <a href="https://github.com/apache/hertzbeat/issues?q=author%3AChineseTony" title="Bug reports">🐛</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/wyt199905"><img src="https://avatars.githubusercontent.com/u/85098809?v=4?s=100" width="100px;" alt="wyt199905"/><br /><sub><b>wyt199905</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=wyt199905" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/weifuqing"><img src="https://avatars.githubusercontent.com/u/13931013?v=4?s=100" width="100px;" alt="卫傅庆"/><br /><sub><b>卫傅庆</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=weifuqing" title="Code">💻</a> <a href="https://github.com/apache/hertzbeat/issues?q=author%3Aweifuqing" title="Bug reports">🐛</a></td>
</tr>
<tr>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/zklmcookle"><img src="https://avatars.githubusercontent.com/u/107192352?v=4?s=100" width="100px;" alt="zklmcookle"/><br /><sub><b>zklmcookle</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=zklmcookle" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/DevilX5"><img src="https://avatars.githubusercontent.com/u/13269921?v=4?s=100" width="100px;" alt="DevilX5"/><br /><sub><b>DevilX5</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=DevilX5" title="Documentation">📖</a> <a href="https://github.com/apache/hertzbeat/commits?author=DevilX5" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/djzeng"><img src="https://avatars.githubusercontent.com/u/14074864?v=4?s=100" width="100px;" alt="tea"/><br /><sub><b>tea</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=djzeng" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/yangshihui"><img src="https://avatars.githubusercontent.com/u/28550208?v=4?s=100" width="100px;" alt="yangshihui"/><br /><sub><b>yangshihui</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=yangshihui" title="Code">💻</a> <a href="https://github.com/apache/hertzbeat/issues?q=author%3Ayangshihui" title="Bug reports">🐛</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/DreamGirl524"><img src="https://avatars.githubusercontent.com/u/81132838?v=4?s=100" width="100px;" alt="DreamGirl524"/><br /><sub><b>DreamGirl524</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=DreamGirl524" title="Code">💻</a> <a href="https://github.com/apache/hertzbeat/commits?author=DreamGirl524" title="Documentation">📖</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/gzwlly"><img src="https://avatars.githubusercontent.com/u/83171907?v=4?s=100" width="100px;" alt="gzwlly"/><br /><sub><b>gzwlly</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=gzwlly" title="Documentation">📖</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/cuipiheqiuqiu"><img src="https://avatars.githubusercontent.com/u/76642201?v=4?s=100" width="100px;" alt="cuipiheqiuqiu"/><br /><sub><b>cuipiheqiuqiu</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=cuipiheqiuqiu" title="Code">💻</a> <a href="https://github.com/apache/hertzbeat/commits?author=cuipiheqiuqiu" title="Tests">⚠️</a> <a href="#design-cuipiheqiuqiu" title="Design">🎨</a></td>
</tr>
<tr>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/oyiyou"><img src="https://avatars.githubusercontent.com/u/39228891?v=4?s=100" width="100px;" alt="lambert"/><br /><sub><b>lambert</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=oyiyou" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="http://mroldx.xyz/"><img src="https://avatars.githubusercontent.com/u/34847828?v=4?s=100" width="100px;" alt="mroldx"/><br /><sub><b>mroldx</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=mroldx" title="Documentation">📖</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/woshiniusange"><img src="https://avatars.githubusercontent.com/u/91513022?v=4?s=100" width="100px;" alt="woshiniusange"/><br /><sub><b>woshiniusange</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=woshiniusange" title="Documentation">📖</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://vampireachao.github.io/"><img src="https://avatars.githubusercontent.com/u/52746628?v=4?s=100" width="100px;" alt="VampireAchao"/><br /><sub><b>VampireAchao</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=VampireAchao" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/Ceilzcx"><img src="https://avatars.githubusercontent.com/u/48920254?v=4?s=100" width="100px;" alt="zcx"/><br /><sub><b>zcx</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=Ceilzcx" title="Code">💻</a> <a href="https://github.com/apache/hertzbeat/issues?q=author%3ACeilzcx" title="Bug reports">🐛</a> <a href="#design-Ceilzcx" title="Design">🎨</a> <a href="https://github.com/apache/hertzbeat/commits?author=Ceilzcx" title="Tests">⚠️</a> <a href="#blog-Ceilzcx" title="Blogposts">📝</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/CharlieXCL"><img src="https://avatars.githubusercontent.com/u/91540487?v=4?s=100" width="100px;" alt="CharlieXCL"/><br /><sub><b>CharlieXCL</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=CharlieXCL" title="Documentation">📖</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/Privauto"><img src="https://avatars.githubusercontent.com/u/36581456?v=4?s=100" width="100px;" alt="Privauto"/><br /><sub><b>Privauto</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=Privauto" title="Code">💻</a> <a href="https://github.com/apache/hertzbeat/commits?author=Privauto" title="Documentation">📖</a></td>
</tr>
<tr>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/emrys-he"><img src="https://avatars.githubusercontent.com/u/5848915?v=4?s=100" width="100px;" alt="emrys"/><br /><sub><b>emrys</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=emrys-he" title="Documentation">📖</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/SxLiuYu"><img src="https://avatars.githubusercontent.com/u/95198625?v=4?s=100" width="100px;" alt="SxLiuYu"/><br /><sub><b>SxLiuYu</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/issues?q=author%3ASxLiuYu" title="Bug reports">🐛</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://allcontributors.org"><img src="https://avatars.githubusercontent.com/u/46410174?v=4?s=100" width="100px;" alt="All Contributors"/><br /><sub><b>All Contributors</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=all-contributors" title="Documentation">📖</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/gxc-myh"><img src="https://avatars.githubusercontent.com/u/85919258?v=4?s=100" width="100px;" alt="铁甲小宝"/><br /><sub><b>铁甲小宝</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=gxc-myh" title="Code">💻</a> <a href="https://github.com/apache/hertzbeat/commits?author=gxc-myh" title="Documentation">📖</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/click33"><img src="https://avatars.githubusercontent.com/u/36243476?v=4?s=100" width="100px;" alt="click33"/><br /><sub><b>click33</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=click33" title="Documentation">📖</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://jpom.io/"><img src="https://avatars.githubusercontent.com/u/16408873?v=4?s=100" width="100px;" alt="蒋小小"/><br /><sub><b>蒋小小</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=bwcx-jzy" title="Documentation">📖</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://www.zhihu.com/people/kevinbauer"><img src="https://avatars.githubusercontent.com/u/28581579?v=4?s=100" width="100px;" alt="Kevin Huang"/><br /><sub><b>Kevin Huang</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=kevinhuangwl" title="Documentation">📖</a></td>
</tr>
<tr>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/TJxiaobao"><img src="https://avatars.githubusercontent.com/u/85919258?v=4?s=100" width="100px;" alt="铁甲小宝"/><br /><sub><b>铁甲小宝</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/issues?q=author%3ATJxiaobao" title="Bug reports">🐛</a> <a href="https://github.com/apache/hertzbeat/commits?author=TJxiaobao" title="Code">💻</a> <a href="https://github.com/apache/hertzbeat/commits?author=TJxiaobao" title="Documentation">📖</a> <a href="https://github.com/apache/hertzbeat/commits?author=TJxiaobao" title="Tests">⚠️</a> <a href="#design-TJxiaobao" title="Design">🎨</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/Jack-123-power"><img src="https://avatars.githubusercontent.com/u/84333501?v=4?s=100" width="100px;" alt="Captain Jack"/><br /><sub><b>Captain Jack</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=Jack-123-power" title="Documentation">📖</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/haibo-duan"><img src="https://avatars.githubusercontent.com/u/7974845?v=4?s=100" width="100px;" alt="haibo.duan"/><br /><sub><b>haibo.duan</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=haibo-duan" title="Tests">⚠️</a> <a href="https://github.com/apache/hertzbeat/commits?author=haibo-duan" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/assassinfym"><img src="https://avatars.githubusercontent.com/u/15188754?v=4?s=100" width="100px;" alt="assassin"/><br /><sub><b>assassin</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/issues?q=author%3Aassassinfym" title="Bug reports">🐛</a> <a href="https://github.com/apache/hertzbeat/commits?author=assassinfym" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/csyshu"><img src="https://avatars.githubusercontent.com/u/46591658?v=4?s=100" width="100px;" alt="Reverse wind"/><br /><sub><b>Reverse wind</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=csyshu" title="Tests">⚠️</a> <a href="https://github.com/apache/hertzbeat/commits?author=csyshu" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/luxx-lq"><img src="https://avatars.githubusercontent.com/u/58515565?v=4?s=100" width="100px;" alt="luxx"/><br /><sub><b>luxx</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=luxx-lq" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://bandism.net/"><img src="https://avatars.githubusercontent.com/u/22633385?v=4?s=100" width="100px;" alt="Ikko Ashimine"/><br /><sub><b>Ikko Ashimine</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=eltociear" title="Documentation">📖</a></td>
</tr>
<tr>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/zenan08"><img src="https://avatars.githubusercontent.com/u/80514991?v=4?s=100" width="100px;" alt="leizenan"/><br /><sub><b>leizenan</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=zenan08" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/BKing2020"><img src="https://avatars.githubusercontent.com/u/28869121?v=4?s=100" width="100px;" alt="BKing"/><br /><sub><b>BKing</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=BKing2020" title="Documentation">📖</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/xingshuaiLi"><img src="https://avatars.githubusercontent.com/u/119487588?v=4?s=100" width="100px;" alt="xingshuaiLi"/><br /><sub><b>xingshuaiLi</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=xingshuaiLi" title="Documentation">📖</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/wangke6666"><img src="https://avatars.githubusercontent.com/u/113656595?v=4?s=100" width="100px;" alt="wangke6666"/><br /><sub><b>wangke6666</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=wangke6666" title="Documentation">📖</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/LWBobo"><img src="https://avatars.githubusercontent.com/u/50368698?v=4?s=100" width="100px;" alt="刺猬"/><br /><sub><b>刺猬</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/issues?q=author%3ALWBobo" title="Bug reports">🐛</a> <a href="https://github.com/apache/hertzbeat/commits?author=LWBobo" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="http://www.zanglikun.com"><img src="https://avatars.githubusercontent.com/u/61591648?v=4?s=100" width="100px;" alt="Haste"/><br /><sub><b>Haste</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=zanglikun" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/SuitSmile"><img src="https://avatars.githubusercontent.com/u/38679717?v=4?s=100" width="100px;" alt="zhongshi.yi"/><br /><sub><b>zhongshi.yi</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=SuitSmile" title="Documentation">📖</a></td>
</tr>
<tr>
<td align="center" valign="top" width="14.28%"><a href="https://www.smallq.cn"><img src="https://avatars.githubusercontent.com/u/39754275?v=4?s=100" width="100px;" alt="Qi Zhang"/><br /><sub><b>Qi Zhang</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=zzzhangqi" title="Documentation">📖</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/MrAndyMing"><img src="https://avatars.githubusercontent.com/u/49541483?v=4?s=100" width="100px;" alt="MrAndyMing"/><br /><sub><b>MrAndyMing</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=MrAndyMing" title="Documentation">📖</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://idongliming.github.io/"><img src="https://avatars.githubusercontent.com/u/31564353?v=4?s=100" width="100px;" alt="idongliming"/><br /><sub><b>idongliming</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=idongliming" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://earthjasonlin.github.io"><img src="https://avatars.githubusercontent.com/u/83632110?v=4?s=100" width="100px;" alt="Zichao Lin"/><br /><sub><b>Zichao Lin</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=earthjasonlin" title="Code">💻</a> <a href="https://github.com/apache/hertzbeat/commits?author=earthjasonlin" title="Documentation">📖</a></td>
<td align="center" valign="top" width="14.28%"><a href="http://blog.liudonghua.com"><img src="https://avatars.githubusercontent.com/u/2276718?v=4?s=100" width="100px;" alt="liudonghua"/><br /><sub><b>liudonghua</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=liudonghua123" title="Code">💻</a> <a href="#ideas-liudonghua123" title="Ideas, Planning, & Feedback">🤔</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/orangeyts"><img src="https://avatars.githubusercontent.com/u/4250869?v=4?s=100" width="100px;" alt="Jerry"/><br /><sub><b>Jerry</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=orangeyts" title="Code">💻</a> <a href="https://github.com/apache/hertzbeat/commits?author=orangeyts" title="Tests">⚠️</a> <a href="#ideas-orangeyts" title="Ideas, Planning, & Feedback">🤔</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://dynamictp.cn"><img src="https://avatars.githubusercontent.com/u/13051908?v=4?s=100" width="100px;" alt="yanhom"/><br /><sub><b>yanhom</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=yanhom1314" title="Documentation">📖</a></td>
</tr>
<tr>
<td align="center" valign="top" width="14.28%"><a href="https://www.jianshu.com/u/a8f822c04f67"><img src="https://avatars.githubusercontent.com/u/18587688?v=4?s=100" width="100px;" alt="fsl"/><br /><sub><b>fsl</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=fengshunli" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/xttttv"><img src="https://avatars.githubusercontent.com/u/116323904?v=4?s=100" width="100px;" alt="xttttv"/><br /><sub><b>xttttv</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=xttttv" title="Documentation">📖</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/NavinKumarBarnwal"><img src="https://avatars.githubusercontent.com/u/44504274?v=4?s=100" width="100px;" alt="NavinKumarBarnwal"/><br /><sub><b>NavinKumarBarnwal</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=NavinKumarBarnwal" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/z641205699"><img src="https://avatars.githubusercontent.com/u/45276423?v=4?s=100" width="100px;" alt="Zakkary"/><br /><sub><b>Zakkary</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=z641205699" title="Documentation">📖</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/898349230"><img src="https://avatars.githubusercontent.com/u/21972532?v=4?s=100" width="100px;" alt="sunxinbo"/><br /><sub><b>sunxinbo</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=898349230" title="Code">💻</a> <a href="https://github.com/apache/hertzbeat/commits?author=898349230" title="Tests">⚠️</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/ldzbook"><img src="https://avatars.githubusercontent.com/u/13903790?v=4?s=100" width="100px;" alt="ldzbook"/><br /><sub><b>ldzbook</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=ldzbook" title="Documentation">📖</a> <a href="https://github.com/apache/hertzbeat/issues?q=author%3Aldzbook" title="Bug reports">🐛</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/SurryChen"><img src="https://avatars.githubusercontent.com/u/91116490?v=4?s=100" width="100px;" alt="余与雨"/><br /><sub><b>余与雨</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=SurryChen" title="Code">💻</a> <a href="https://github.com/apache/hertzbeat/commits?author=SurryChen" title="Tests">⚠️</a></td>
</tr>
<tr>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/MysticalDream"><img src="https://avatars.githubusercontent.com/u/78899028?v=4?s=100" width="100px;" alt="MysticalDream"/><br /><sub><b>MysticalDream</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=MysticalDream" title="Code">💻</a> <a href="https://github.com/apache/hertzbeat/commits?author=MysticalDream" title="Tests">⚠️</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/zhouyoulin12"><img src="https://avatars.githubusercontent.com/u/17086633?v=4?s=100" width="100px;" alt="zhouyoulin12"/><br /><sub><b>zhouyoulin12</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=zhouyoulin12" title="Code">💻</a> <a href="https://github.com/apache/hertzbeat/commits?author=zhouyoulin12" title="Tests">⚠️</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/jerjjj"><img src="https://avatars.githubusercontent.com/u/93431283?v=4?s=100" width="100px;" alt="jerjjj"/><br /><sub><b>jerjjj</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=jerjjj" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://wjl110.xyz/"><img src="https://avatars.githubusercontent.com/u/53851034?v=4?s=100" width="100px;" alt="wjl110"/><br /><sub><b>wjl110</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=wjl110" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/ngyhd"><img src="https://avatars.githubusercontent.com/u/29095207?v=4?s=100" width="100px;" alt="Sean"/><br /><sub><b>Sean</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=ngyhd" title="Documentation">📖</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/Daydreamer-ia"><img src="https://avatars.githubusercontent.com/u/83362909?v=4?s=100" width="100px;" alt="chenyiqin"/><br /><sub><b>chenyiqin</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=Daydreamer-ia" title="Code">💻</a> <a href="https://github.com/apache/hertzbeat/commits?author=Daydreamer-ia" title="Tests">⚠️</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/hudongdong129"><img src="https://avatars.githubusercontent.com/u/34374227?v=4?s=100" width="100px;" alt="hudongdong129"/><br /><sub><b>hudongdong129</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=hudongdong129" title="Code">💻</a> <a href="https://github.com/apache/hertzbeat/commits?author=hudongdong129" title="Tests">⚠️</a> <a href="https://github.com/apache/hertzbeat/commits?author=hudongdong129" title="Documentation">📖</a> <a href="#design-hudongdong129" title="Design">🎨</a></td>
</tr>
<tr>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/TherChenYang"><img src="https://avatars.githubusercontent.com/u/124348939?v=4?s=100" width="100px;" alt="TherChenYang"/><br /><sub><b>TherChenYang</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=TherChenYang" title="Code">💻</a> <a href="https://github.com/apache/hertzbeat/commits?author=TherChenYang" title="Tests">⚠️</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/HattoriHenzo"><img src="https://avatars.githubusercontent.com/u/5141285?v=4?s=100" width="100px;" alt="HattoriHenzo"/><br /><sub><b>HattoriHenzo</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=HattoriHenzo" title="Code">💻</a> <a href="https://github.com/apache/hertzbeat/commits?author=HattoriHenzo" title="Tests">⚠️</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/ycilry"><img src="https://avatars.githubusercontent.com/u/63967101?v=4?s=100" width="100px;" alt="ycilry"/><br /><sub><b>ycilry</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=ycilry" title="Documentation">📖</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/aoshiguchen"><img src="https://avatars.githubusercontent.com/u/10580997?v=4?s=100" width="100px;" alt="aoshiguchen"/><br /><sub><b>aoshiguchen</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=aoshiguchen" title="Documentation">📖</a> <a href="https://github.com/apache/hertzbeat/commits?author=aoshiguchen" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/caibenxiang"><img src="https://avatars.githubusercontent.com/u/4568241?v=4?s=100" width="100px;" alt="蔡本祥"/><br /><sub><b>蔡本祥</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=caibenxiang" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="http://www.fckeverything.cn:4000/"><img src="https://avatars.githubusercontent.com/u/13827124?v=4?s=100" width="100px;" alt="浮游"/><br /><sub><b>浮游</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=lifefloating" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/Grass-Life"><img src="https://avatars.githubusercontent.com/u/114381513?v=4?s=100" width="100px;" alt="Grass-Life"/><br /><sub><b>Grass-Life</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=Grass-Life" title="Code">💻</a></td>
</tr>
<tr>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/xiaohe428"><img src="https://avatars.githubusercontent.com/u/99130317?v=4?s=100" width="100px;" alt="xiaohe428"/><br /><sub><b>xiaohe428</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=xiaohe428" title="Code">💻</a> <a href="https://github.com/apache/hertzbeat/commits?author=xiaohe428" title="Documentation">📖</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/baiban114"><img src="https://avatars.githubusercontent.com/u/59152619?v=4?s=100" width="100px;" alt="TableRow"/><br /><sub><b>TableRow</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=baiban114" title="Documentation">📖</a> <a href="https://github.com/apache/hertzbeat/commits?author=baiban114" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/ByteIDance"><img src="https://avatars.githubusercontent.com/u/100207562?v=4?s=100" width="100px;" alt="ByteIDance"/><br /><sub><b>ByteIDance</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=ByteIDance" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/mangel2002"><img src="https://avatars.githubusercontent.com/u/9348020?v=4?s=100" width="100px;" alt="Jangfe"/><br /><sub><b>Jangfe</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=mangel2002" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/zqr10159"><img src="https://avatars.githubusercontent.com/u/30048352?v=4?s=100" width="100px;" alt="zqr10159"/><br /><sub><b>zqr10159</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=zqr10159" title="Documentation">📖</a> <a href="https://github.com/apache/hertzbeat/commits?author=zqr10159" title="Code">💻</a> <a href="#blog-zqr10159" title="Blogposts">📝</a> <a href="https://github.com/apache/hertzbeat/issues?q=author%3Azqr10159" title="Bug reports">🐛</a> <a href="https://github.com/apache/hertzbeat/commits?author=zqr10159" title="Tests">⚠️</a> <a href="#design-zqr10159" title="Design">🎨</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/vinci-897"><img src="https://avatars.githubusercontent.com/u/55838224?v=4?s=100" width="100px;" alt="vinci"/><br /><sub><b>vinci</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=vinci-897" title="Code">💻</a> <a href="https://github.com/apache/hertzbeat/commits?author=vinci-897" title="Documentation">📖</a> <a href="#design-vinci-897" title="Design">🎨</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/js110"><img src="https://avatars.githubusercontent.com/u/51191863?v=4?s=100" width="100px;" alt="js110"/><br /><sub><b>js110</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=js110" title="Code">💻</a></td>
</tr>
<tr>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/JavaLionLi"><img src="https://avatars.githubusercontent.com/u/31852897?v=4?s=100" width="100px;" alt="CrazyLionLi"/><br /><sub><b>CrazyLionLi</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=JavaLionLi" title="Documentation">📖</a></td>
<td align="center" valign="top" width="14.28%"><a href="http://www.banmajio.com"><img src="https://avatars.githubusercontent.com/u/53471385?v=4?s=100" width="100px;" alt="banmajio"/><br /><sub><b>banmajio</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=banmajio" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://suder.fun"><img src="https://avatars.githubusercontent.com/u/69955165?v=4?s=100" width="100px;" alt="topsuder"/><br /><sub><b>topsuder</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=topsuder" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/richar2022"><img src="https://avatars.githubusercontent.com/u/129016397?v=4?s=100" width="100px;" alt="richar2022"/><br /><sub><b>richar2022</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=richar2022" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/fcb-xiaobo"><img src="https://avatars.githubusercontent.com/u/60566194?v=4?s=100" width="100px;" alt="fcb-xiaobo"/><br /><sub><b>fcb-xiaobo</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=fcb-xiaobo" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/wenkyzhang"><img src="https://avatars.githubusercontent.com/u/13983669?v=4?s=100" width="100px;" alt="wenkyzhang"/><br /><sub><b>wenkyzhang</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=wenkyzhang" title="Documentation">📖</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/ZangJuxy"><img src="https://avatars.githubusercontent.com/u/71380295?v=4?s=100" width="100px;" alt="ZangJuxy"/><br /><sub><b>ZangJuxy</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=ZangJuxy" title="Documentation">📖</a></td>
</tr>
<tr>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/l646505418"><img src="https://avatars.githubusercontent.com/u/50475131?v=4?s=100" width="100px;" alt="l646505418"/><br /><sub><b>l646505418</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=l646505418" title="Code">💻</a> <a href="https://github.com/apache/hertzbeat/issues?q=author%3Al646505418" title="Bug reports">🐛</a></td>
<td align="center" valign="top" width="14.28%"><a href="http://www.carpewang.com"><img src="https://avatars.githubusercontent.com/u/78642589?v=4?s=100" width="100px;" alt="Carpe-Wang"/><br /><sub><b>Carpe-Wang</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=Carpe-Wang" title="Code">💻</a> <a href="https://github.com/apache/hertzbeat/issues?q=author%3ACarpe-Wang" title="Bug reports">🐛</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/moshu023"><img src="https://avatars.githubusercontent.com/u/48593205?v=4?s=100" width="100px;" alt="莫枢"/><br /><sub><b>莫枢</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=moshu023" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/huangcanda"><img src="https://avatars.githubusercontent.com/u/4470566?v=4?s=100" width="100px;" alt="huangcanda"/><br /><sub><b>huangcanda</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=huangcanda" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://www.zrkizzy.com"><img src="https://avatars.githubusercontent.com/u/85340613?v=4?s=100" width="100px;" alt="世纪末的架构师"/><br /><sub><b>世纪末的架构师</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=Architect-Java" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/ShuningWan"><img src="https://avatars.githubusercontent.com/u/31086770?v=4?s=100" width="100px;" alt="ShuningWan"/><br /><sub><b>ShuningWan</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=ShuningWan" title="Documentation">📖</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/MrYZhou"><img src="https://avatars.githubusercontent.com/u/44339602?v=4?s=100" width="100px;" alt="MrYZhou"/><br /><sub><b>MrYZhou</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=MrYZhou" title="Documentation">📖</a></td>
</tr>
<tr>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/suncqujsj"><img src="https://avatars.githubusercontent.com/u/8012932?v=4?s=100" width="100px;" alt="suncqujsj"/><br /><sub><b>suncqujsj</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=suncqujsj" title="Documentation">📖</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/sunqinbo"><img src="https://avatars.githubusercontent.com/u/1428540?v=4?s=100" width="100px;" alt="sunqinbo"/><br /><sub><b>sunqinbo</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=sunqinbo" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/haoww"><img src="https://avatars.githubusercontent.com/u/32739294?v=4?s=100" width="100px;" alt="haoww"/><br /><sub><b>haoww</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=haoww" title="Documentation">📖</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/i-mayuan"><img src="https://avatars.githubusercontent.com/u/101498477?v=4?s=100" width="100px;" alt="i-mayuan"/><br /><sub><b>i-mayuan</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=i-mayuan" title="Documentation">📖</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/fengruge"><img src="https://avatars.githubusercontent.com/u/85803831?v=4?s=100" width="100px;" alt="fengruge"/><br /><sub><b>fengruge</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=fengruge" title="Documentation">📖</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/aystzh"><img src="https://avatars.githubusercontent.com/u/38125392?v=4?s=100" width="100px;" alt="zhanghuan"/><br /><sub><b>zhanghuan</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=aystzh" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/shenyumin"><img src="https://avatars.githubusercontent.com/u/8438506?v=4?s=100" width="100px;" alt="shenymin"/><br /><sub><b>shenymin</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=shenyumin" title="Code">💻</a></td>
</tr>
<tr>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/dhruva1995"><img src="https://avatars.githubusercontent.com/u/12976351?v=4?s=100" width="100px;" alt="Dhruva Chandra"/><br /><sub><b>Dhruva Chandra</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=dhruva1995" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/weiwang988"><img src="https://avatars.githubusercontent.com/u/58241726?v=4?s=100" width="100px;" alt="miss_z"/><br /><sub><b>miss_z</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=weiwang988" title="Documentation">📖</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/wyt990"><img src="https://avatars.githubusercontent.com/u/86013697?v=4?s=100" width="100px;" alt="wyt990"/><br /><sub><b>wyt990</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=wyt990" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/licocon"><img src="https://avatars.githubusercontent.com/u/36863277?v=4?s=100" width="100px;" alt="licocon"/><br /><sub><b>licocon</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=licocon" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/2406450951"><img src="https://avatars.githubusercontent.com/u/48074721?v=4?s=100" width="100px;" alt="Mi Na"/><br /><sub><b>Mi Na</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=2406450951" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/Kylin-Guo"><img src="https://avatars.githubusercontent.com/u/131239856?v=4?s=100" width="100px;" alt="Kylin-Guo"/><br /><sub><b>Kylin-Guo</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=Kylin-Guo" title="Documentation">📖</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/1797899698"><img src="https://avatars.githubusercontent.com/u/40411650?v=4?s=100" width="100px;" alt="Mr灬Dong先生"/><br /><sub><b>Mr灬Dong先生</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=1797899698" title="Code">💻</a></td>
</tr>
<tr>
<td align="center" valign="top" width="14.28%"><a href="http://neilblaze.live"><img src="https://avatars.githubusercontent.com/u/48355572?v=4?s=100" width="100px;" alt="Pratyay Banerjee"/><br /><sub><b>Pratyay Banerjee</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=Neilblaze" title="Documentation">📖</a> <a href="https://github.com/apache/hertzbeat/commits?author=Neilblaze" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/yujianzhong520"><img src="https://avatars.githubusercontent.com/u/63705063?v=4?s=100" width="100px;" alt="yujianzhong520"/><br /><sub><b>yujianzhong520</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=yujianzhong520" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://sppan24.github.io/"><img src="https://avatars.githubusercontent.com/u/15795173?v=4?s=100" width="100px;" alt="SPPan"/><br /><sub><b>SPPan</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=sppan24" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/1130600015"><img src="https://avatars.githubusercontent.com/u/67859663?v=4?s=100" width="100px;" alt="ZhangJiashu"/><br /><sub><b>ZhangJiashu</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=1130600015" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/QZmp236478"><img src="https://avatars.githubusercontent.com/u/56623162?v=4?s=100" width="100px;" alt="impress"/><br /><sub><b>impress</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=QZmp236478" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/jx3775250"><img src="https://avatars.githubusercontent.com/u/40455946?v=4?s=100" width="100px;" alt="凌晨一点半"/><br /><sub><b>凌晨一点半</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=jx3775250" title="Documentation">📖</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/eeshaanSA"><img src="https://avatars.githubusercontent.com/u/100678386?v=4?s=100" width="100px;" alt="Eeshaan Sawant"/><br /><sub><b>Eeshaan Sawant</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=eeshaanSA" title="Code">💻</a></td>
</tr>
<tr>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/nandofromthebando"><img src="https://avatars.githubusercontent.com/u/87321214?v=4?s=100" width="100px;" alt="nandofromthebando"/><br /><sub><b>nandofromthebando</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=nandofromthebando" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/caiboking"><img src="https://avatars.githubusercontent.com/u/6509883?v=4?s=100" width="100px;" alt="caiboking"/><br /><sub><b>caiboking</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=caiboking" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/baixing99"><img src="https://avatars.githubusercontent.com/u/73473087?v=4?s=100" width="100px;" alt="baixing99"/><br /><sub><b>baixing99</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=baixing99" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/ifrenzyc"><img src="https://avatars.githubusercontent.com/u/543927?v=4?s=100" width="100px;" alt="Yang Chuang"/><br /><sub><b>Yang Chuang</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=ifrenzyc" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/wlin20"><img src="https://avatars.githubusercontent.com/u/20657577?v=4?s=100" width="100px;" alt="wlin20"/><br /><sub><b>wlin20</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=wlin20" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/guojing1983"><img src="https://avatars.githubusercontent.com/u/60596094?v=4?s=100" width="100px;" alt="guojing1983"/><br /><sub><b>guojing1983</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=guojing1983" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/itxxq"><img src="https://avatars.githubusercontent.com/u/46962357?v=4?s=100" width="100px;" alt="moxi"/><br /><sub><b>moxi</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=itxxq" title="Documentation">📖</a></td>
</tr>
<tr>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/qq471754603"><img src="https://avatars.githubusercontent.com/u/23146592?v=4?s=100" width="100px;" alt="qq471754603"/><br /><sub><b>qq471754603</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=qq471754603" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/san346596324"><img src="https://avatars.githubusercontent.com/u/30828520?v=4?s=100" width="100px;" alt="渭雨"/><br /><sub><b>渭雨</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=san346596324" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/luoxuanzao"><img src="https://avatars.githubusercontent.com/u/44692579?v=4?s=100" width="100px;" alt="liuxuezhuo"/><br /><sub><b>liuxuezhuo</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=luoxuanzao" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/lisongning"><img src="https://avatars.githubusercontent.com/u/93140178?v=4?s=100" width="100px;" alt="lisongning"/><br /><sub><b>lisongning</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=lisongning" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/YutingNie"><img src="https://avatars.githubusercontent.com/u/104416402?v=4?s=100" width="100px;" alt="YutingNie"/><br /><sub><b>YutingNie</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=YutingNie" title="Code">💻</a> <a href="https://github.com/apache/hertzbeat/commits?author=YutingNie" title="Documentation">📖</a> <a href="#design-YutingNie" title="Design">🎨</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/mikezzb"><img src="https://avatars.githubusercontent.com/u/23418428?v=4?s=100" width="100px;" alt="Mike Zhou"/><br /><sub><b>Mike Zhou</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=mikezzb" title="Code">💻</a> <a href="https://github.com/apache/hertzbeat/commits?author=mikezzb" title="Documentation">📖</a> <a href="#design-mikezzb" title="Design">🎨</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/lynx009"><img src="https://avatars.githubusercontent.com/u/105542329?v=4?s=100" width="100px;" alt="lynx009"/><br /><sub><b>lynx009</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=lynx009" title="Documentation">📖</a></td>
</tr>
<tr>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/littlezhongzer"><img src="https://avatars.githubusercontent.com/u/33685289?v=4?s=100" width="100px;" alt="littlezhongzer"/><br /><sub><b>littlezhongzer</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=littlezhongzer" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/ChenXiangxxxxx"><img src="https://avatars.githubusercontent.com/u/90089594?v=4?s=100" width="100px;" alt="ChenXiangxxxxx"/><br /><sub><b>ChenXiangxxxxx</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=ChenXiangxxxxx" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/Mr-zhou315"><img src="https://avatars.githubusercontent.com/u/10276100?v=4?s=100" width="100px;" alt="Mr.zhou"/><br /><sub><b>Mr.zhou</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=Mr-zhou315" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/XimfengYao"><img src="https://avatars.githubusercontent.com/u/17541537?v=4?s=100" width="100px;" alt="姚贤丰"/><br /><sub><b>姚贤丰</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=XimfengYao" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/LINGLUOJUN"><img src="https://avatars.githubusercontent.com/u/16778977?v=4?s=100" width="100px;" alt="lingluojun"/><br /><sub><b>lingluojun</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=LINGLUOJUN" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="http://www.luelueking.com"><img src="https://avatars.githubusercontent.com/u/93204032?v=4?s=100" width="100px;" alt="1ue"/><br /><sub><b>1ue</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=luelueking" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="http://www.jimmyqiao.top"><img src="https://avatars.githubusercontent.com/u/67301054?v=4?s=100" width="100px;" alt="qyaaaa"/><br /><sub><b>qyaaaa</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=qyaaaa" title="Code">💻</a> <a href="https://github.com/apache/hertzbeat/issues?q=author%3Aqyaaaa" title="Bug reports">🐛</a></td>
</tr>
<tr>
<td align="center" valign="top" width="14.28%"><a href="https://novohit.top"><img src="https://avatars.githubusercontent.com/u/101090395?v=4?s=100" width="100px;" alt="novohit"/><br /><sub><b>novohit</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=novohit" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/rbsrcy"><img src="https://avatars.githubusercontent.com/u/4798540?v=4?s=100" width="100px;" alt="zhuoshangyi"/><br /><sub><b>zhuoshangyi</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=rbsrcy" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/ruanliang-hualun"><img src="https://avatars.githubusercontent.com/u/65543716?v=4?s=100" width="100px;" alt="ruanliang"/><br /><sub><b>ruanliang</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=ruanliang-hualun" title="Documentation">📖</a> <a href="https://github.com/apache/hertzbeat/commits?author=ruanliang-hualun" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/Eden4701"><img src="https://avatars.githubusercontent.com/u/68422437?v=4?s=100" width="100px;" alt="Eden4701"/><br /><sub><b>Eden4701</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=Eden4701" title="Code">💻</a> <a href="https://github.com/apache/hertzbeat/commits?author=Eden4701" title="Documentation">📖</a> <a href="#design-Eden4701" title="Design">🎨</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/XiaTian688"><img src="https://avatars.githubusercontent.com/u/111830921?v=4?s=100" width="100px;" alt="XiaTian688"/><br /><sub><b>XiaTian688</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=XiaTian688" title="Documentation">📖</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/liyin"><img src="https://avatars.githubusercontent.com/u/863169?v=4?s=100" width="100px;" alt="liyinjiang"/><br /><sub><b>liyinjiang</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=liyin" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/jiashu1024"><img src="https://avatars.githubusercontent.com/u/67859663?v=4?s=100" width="100px;" alt="ZhangJiashu"/><br /><sub><b>ZhangJiashu</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=jiashu1024" title="Documentation">📖</a></td>
</tr>
<tr>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/1036664317"><img src="https://avatars.githubusercontent.com/u/7696697?v=4?s=100" width="100px;" alt="moghn"/><br /><sub><b>moghn</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=1036664317" title="Documentation">📖</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/xiaoguolong"><img src="https://avatars.githubusercontent.com/u/33684988?v=4?s=100" width="100px;" alt="xiaoguolong"/><br /><sub><b>xiaoguolong</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=xiaoguolong" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/Clownsw"><img src="https://avatars.githubusercontent.com/u/28394742?v=4?s=100" width="100px;" alt="Smliexx"/><br /><sub><b>Smliexx</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=Clownsw" title="Code">💻</a> <a href="https://github.com/apache/hertzbeat/issues?q=author%3AClownsw" title="Bug reports">🐛</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/Calvin979"><img src="https://avatars.githubusercontent.com/u/131688897?v=4?s=100" width="100px;" alt="Calvin"/><br /><sub><b>Calvin</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=Calvin979" title="Documentation">📖</a> <a href="https://github.com/apache/hertzbeat/commits?author=Calvin979" title="Code">💻</a> <a href="#design-Calvin979" title="Design">🎨</a> <a href="https://github.com/apache/hertzbeat/issues?q=author%3ACalvin979" title="Bug reports">🐛</a> <a href="https://github.com/apache/hertzbeat/commits?author=Calvin979" title="Tests">⚠️</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/bbelide2"><img src="https://avatars.githubusercontent.com/u/26840796?v=4?s=100" width="100px;" alt="Bala Sukesh"/><br /><sub><b>Bala Sukesh</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=bbelide2" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/jinyaoMa"><img src="https://avatars.githubusercontent.com/u/25066570?v=4?s=100" width="100px;" alt="Jinyao Ma"/><br /><sub><b>Jinyao Ma</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=jinyaoMa" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://linuxsuren.github.io/open-source-best-practice/"><img src="https://avatars.githubusercontent.com/u/1450685?v=4?s=100" width="100px;" alt="Rick"/><br /><sub><b>Rick</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=LinuxSuRen" title="Code">💻</a> <a href="https://github.com/apache/hertzbeat/commits?author=LinuxSuRen" title="Tests">⚠️</a></td>
</tr>
<tr>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/ZY945"><img src="https://avatars.githubusercontent.com/u/74083801?v=4?s=100" width="100px;" alt="东风"/><br /><sub><b>东风</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=ZY945" title="Code">💻</a> <a href="#design-ZY945" title="Design">🎨</a> <a href="https://github.com/apache/hertzbeat/commits?author=ZY945" title="Documentation">📖</a> <a href="https://github.com/apache/hertzbeat/issues?q=author%3AZY945" title="Bug reports">🐛</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/prolevel1"><img src="https://avatars.githubusercontent.com/u/51995525?v=4?s=100" width="100px;" alt="sonam singh"/><br /><sub><b>sonam singh</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=prolevel1" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/ZhangZixuan1994"><img src="https://avatars.githubusercontent.com/u/20011653?v=4?s=100" width="100px;" alt="ZhangZixuan1994"/><br /><sub><b>ZhangZixuan1994</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=ZhangZixuan1994" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/hurenjie1"><img src="https://avatars.githubusercontent.com/u/40120355?v=4?s=100" width="100px;" alt="SHIG"/><br /><sub><b>SHIG</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=hurenjie1" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://tslj1024.github.io/"><img src="https://avatars.githubusercontent.com/u/155222677?v=4?s=100" width="100px;" alt="泰上老菌"/><br /><sub><b>泰上老菌</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=tslj1024" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/ldysdu"><img src="https://avatars.githubusercontent.com/u/15815338?v=4?s=100" width="100px;" alt="ldysdu"/><br /><sub><b>ldysdu</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=ldysdu" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/GEM0816g"><img src="https://avatars.githubusercontent.com/u/85116017?v=4?s=100" width="100px;" alt="梁同学"/><br /><sub><b>梁同学</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=GEM0816g" title="Code">💻</a></td>
</tr>
<tr>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/avvCode"><img src="https://avatars.githubusercontent.com/u/113538532?v=4?s=100" width="100px;" alt="avv"/><br /><sub><b>avv</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=avvCode" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/yqxxgh"><img src="https://avatars.githubusercontent.com/u/42080876?v=4?s=100" width="100px;" alt="yqxxgh"/><br /><sub><b>yqxxgh</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=yqxxgh" title="Documentation">📖</a> <a href="https://github.com/apache/hertzbeat/commits?author=yqxxgh" title="Code">💻</a> <a href="https://github.com/apache/hertzbeat/issues?q=author%3Ayqxxgh" title="Bug reports">🐛</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/CharlieShi46"><img src="https://avatars.githubusercontent.com/u/149798885?v=4?s=100" width="100px;" alt="CharlieShi46"/><br /><sub><b>CharlieShi46</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=CharlieShi46" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/Nctllnty"><img src="https://avatars.githubusercontent.com/u/33241818?v=4?s=100" width="100px;" alt="Nctllnty"/><br /><sub><b>Nctllnty</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=Nctllnty" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/Wang-Yonghao"><img src="https://avatars.githubusercontent.com/u/48146606?v=4?s=100" width="100px;" alt="Wang-Yonghao"/><br /><sub><b>Wang-Yonghao</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=Wang-Yonghao" title="Documentation">📖</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://www.yuque.com/dudiao/yy"><img src="https://avatars.githubusercontent.com/u/38355949?v=4?s=100" width="100px;" alt="读钓"/><br /><sub><b>读钓</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=dudiao" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/starmilkxin"><img src="https://avatars.githubusercontent.com/u/55646681?v=4?s=100" width="100px;" alt="Xin"/><br /><sub><b>Xin</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=starmilkxin" title="Code">💻</a> <a href="https://github.com/apache/hertzbeat/issues?q=author%3Astarmilkxin" title="Bug reports">🐛</a></td>
</tr>
<tr>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/handy-git"><img src="https://avatars.githubusercontent.com/u/32837980?v=4?s=100" width="100px;" alt="handy"/><br /><sub><b>handy</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=handy-git" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/LiuTianyou"><img src="https://avatars.githubusercontent.com/u/30208283?v=4?s=100" width="100px;" alt="LiuTianyou"/><br /><sub><b>LiuTianyou</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=LiuTianyou" title="Code">💻</a> <a href="https://github.com/apache/hertzbeat/commits?author=LiuTianyou" title="Documentation">📖</a> <a href="https://github.com/apache/hertzbeat/issues?q=author%3ALiuTianyou" title="Bug reports">🐛</a> <a href="https://github.com/apache/hertzbeat/commits?author=LiuTianyou" title="Tests">⚠️</a> <a href="#blog-LiuTianyou" title="Blogposts">📝</a> <a href="#design-LiuTianyou" title="Design">🎨</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/WinterKi1ler"><img src="https://avatars.githubusercontent.com/u/160592092?v=4?s=100" width="100px;" alt="WinterKi1ler"/><br /><sub><b>WinterKi1ler</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=WinterKi1ler" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="http://sharehoo.cn/"><img src="https://avatars.githubusercontent.com/u/45377370?v=4?s=100" width="100px;" alt="miki"/><br /><sub><b>miki</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=miki-hmt" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://codeflex.substack.com/"><img src="https://avatars.githubusercontent.com/u/85513042?v=4?s=100" width="100px;" alt="Keshav Carpenter"/><br /><sub><b>Keshav Carpenter</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=alpha951" title="Code">💻</a> <a href="https://github.com/apache/hertzbeat/commits?author=alpha951" title="Documentation">📖</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/makechoicenow"><img src="https://avatars.githubusercontent.com/u/9911918?v=4?s=100" width="100px;" alt="makechoicenow"/><br /><sub><b>makechoicenow</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=makechoicenow" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/gjjjj0101"><img src="https://avatars.githubusercontent.com/u/71874373?v=4?s=100" width="100px;" alt="Gao Jian"/><br /><sub><b>Gao Jian</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=gjjjj0101" title="Tests">⚠️</a> <a href="https://github.com/apache/hertzbeat/commits?author=gjjjj0101" title="Code">💻</a> <a href="https://github.com/apache/hertzbeat/commits?author=gjjjj0101" title="Documentation">📖</a> <a href="#design-gjjjj0101" title="Design">🎨</a> <a href="https://github.com/apache/hertzbeat/issues?q=author%3Agjjjj0101" title="Bug reports">🐛</a></td>
</tr>
<tr>
<td align="center" valign="top" width="14.28%"><a href="https://jangto.tistory.com/"><img src="https://avatars.githubusercontent.com/u/37864182?v=4?s=100" width="100px;" alt="Hyeon Sung"/><br /><sub><b>Hyeon Sung</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=dukbong" title="Code">💻</a> <a href="https://github.com/apache/hertzbeat/commits?author=dukbong" title="Documentation">📖</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://crossoverjie.top/"><img src="https://avatars.githubusercontent.com/u/15684156?v=4?s=100" width="100px;" alt="crossoverJie"/><br /><sub><b>crossoverJie</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=crossoverJie" title="Code">💻</a> <a href="https://github.com/apache/hertzbeat/commits?author=crossoverJie" title="Documentation">📖</a> <a href="#blog-crossoverJie" title="Blogposts">📝</a> <a href="https://github.com/apache/hertzbeat/commits?author=crossoverJie" title="Tests">⚠️</a> <a href="#design-crossoverJie" title="Design">🎨</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/PeixyJ"><img src="https://avatars.githubusercontent.com/u/45998593?v=4?s=100" width="100px;" alt="PeixyJ"/><br /><sub><b>PeixyJ</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=PeixyJ" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/Hi-Mr-Wind"><img src="https://avatars.githubusercontent.com/u/85803831?v=4?s=100" width="100px;" alt="风如歌"/><br /><sub><b>风如歌</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=Hi-Mr-Wind" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/MananPoojara"><img src="https://avatars.githubusercontent.com/u/104253184?v=4?s=100" width="100px;" alt="Manan Pujara"/><br /><sub><b>Manan Pujara</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=MananPoojara" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/xuziyang"><img src="https://avatars.githubusercontent.com/u/8465969?v=4?s=100" width="100px;" alt="xuziyang"/><br /><sub><b>xuziyang</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=xuziyang" title="Code">💻</a> <a href="https://github.com/apache/hertzbeat/commits?author=xuziyang" title="Documentation">📖</a> <a href="https://github.com/apache/hertzbeat/issues?q=author%3Axuziyang" title="Bug reports">🐛</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/lwqzz"><img src="https://avatars.githubusercontent.com/u/62584513?v=4?s=100" width="100px;" alt="lwqzz"/><br /><sub><b>lwqzz</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=lwqzz" title="Code">💻</a></td>
</tr>
<tr>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/YxYL6125"><img src="https://avatars.githubusercontent.com/u/91076160?v=4?s=100" width="100px;" alt="YxYL"/><br /><sub><b>YxYL</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=YxYL6125" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/tomorrowshipyltm"><img src="https://avatars.githubusercontent.com/u/61336903?v=4?s=100" width="100px;" alt="tomorrowshipyltm"/><br /><sub><b>tomorrowshipyltm</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=tomorrowshipyltm" title="Documentation">📖</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/15613060203"><img src="https://avatars.githubusercontent.com/u/41351615?v=4?s=100" width="100px;" alt="栗磊"/><br /><sub><b>栗磊</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=15613060203" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/Alanxtl"><img src="https://avatars.githubusercontent.com/u/25652981?v=4?s=100" width="100px;" alt="Alan"/><br /><sub><b>Alan</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=Alanxtl" title="Documentation">📖</a></td>
<td align="center" valign="top" width="14.28%"><a href="http://www.hadoop.wiki/"><img src="https://avatars.githubusercontent.com/u/29418975?v=4?s=100" width="100px;" alt="Jast"/><br /><sub><b>Jast</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=zhangshenghang" title="Code">💻</a> <a href="#ideas-zhangshenghang" title="Ideas, Planning, & Feedback">🤔</a> <a href="https://github.com/apache/hertzbeat/commits?author=zhangshenghang" title="Documentation">📖</a> <a href="#blog-zhangshenghang" title="Blogposts">📝</a> <a href="https://github.com/apache/hertzbeat/issues?q=author%3Azhangshenghang" title="Bug reports">🐛</a> <a href="https://github.com/apache/hertzbeat/commits?author=zhangshenghang" title="Tests">⚠️</a> <a href="#design-zhangshenghang" title="Design">🎨</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/zuobiao-zhou"><img src="https://avatars.githubusercontent.com/u/61108539?v=4?s=100" width="100px;" alt="Zhang Yuxuan"/><br /><sub><b>Zhang Yuxuan</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=zuobiao-zhou" title="Code">💻</a> <a href="https://github.com/apache/hertzbeat/commits?author=zuobiao-zhou" title="Documentation">📖</a> <a href="https://github.com/apache/hertzbeat/issues?q=author%3Azuobiao-zhou" title="Bug reports">🐛</a> <a href="#blog-zuobiao-zhou" title="Blogposts">📝</a> <a href="https://github.com/apache/hertzbeat/commits?author=zuobiao-zhou" title="Tests">⚠️</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/Pzz-2021"><img src="https://avatars.githubusercontent.com/u/118056735?v=4?s=100" width="100px;" alt="P.P."/><br /><sub><b>P.P.</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=Pzz-2021" title="Code">💻</a></td>
</tr>
<tr>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/LLP2333"><img src="https://avatars.githubusercontent.com/u/61670545?v=4?s=100" width="100px;" alt="llp2333"/><br /><sub><b>llp2333</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=LLP2333" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/HeartLinked"><img src="https://avatars.githubusercontent.com/u/78212101?v=4?s=100" width="100px;" alt="feiyang li"/><br /><sub><b>feiyang li</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=HeartLinked" title="Documentation">📖</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/Aias00"><img src="https://avatars.githubusercontent.com/u/25810623?v=4?s=100" width="100px;" alt="aias00"/><br /><sub><b>aias00</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=Aias00" title="Code">💻</a> <a href="https://github.com/apache/hertzbeat/commits?author=Aias00" title="Documentation">📖</a> <a href="https://github.com/apache/hertzbeat/issues?q=author%3AAias00" title="Bug reports">🐛</a> <a href="#ideas-Aias00" title="Ideas, Planning, & Feedback">🤔</a> <a href="https://github.com/apache/hertzbeat/commits?author=Aias00" title="Tests">⚠️</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/westboy"><img src="https://avatars.githubusercontent.com/u/6385565?v=4?s=100" width="100px;" alt="Jin"/><br /><sub><b>Jin</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=westboy" title="Documentation">📖</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://blog.csdn.net/qq_52397471"><img src="https://avatars.githubusercontent.com/u/77964041?v=4?s=100" width="100px;" alt="YuLuo"/><br /><sub><b>YuLuo</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=yuluo-yx" title="Code">💻</a> <a href="https://github.com/apache/hertzbeat/issues?q=author%3Ayuluo-yx" title="Bug reports">🐛</a> <a href="https://github.com/apache/hertzbeat/commits?author=yuluo-yx" title="Tests">⚠️</a> <a href="#blog-yuluo-yx" title="Blogposts">📝</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/Yanshuming1"><img src="https://avatars.githubusercontent.com/u/118667222?v=4?s=100" width="100px;" alt="linDong"/><br /><sub><b>linDong</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=Yanshuming1" title="Code">💻</a> <a href="https://github.com/apache/hertzbeat/commits?author=Yanshuming1" title="Documentation">📖</a> <a href="https://github.com/apache/hertzbeat/issues?q=author%3AYanshuming1" title="Bug reports">🐛</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/lwjxy"><img src="https://avatars.githubusercontent.com/u/52726400?v=4?s=100" width="100px;" alt="lwjxy"/><br /><sub><b>lwjxy</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=lwjxy" title="Code">💻</a></td>
</tr>
<tr>
<td align="center" valign="top" width="14.28%"><a href="https://thespica.github.io/"><img src="https://avatars.githubusercontent.com/u/119573640?v=4?s=100" width="100px;" alt="John"/><br /><sub><b>John</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=Thespica" title="Code">💻</a> <a href="https://github.com/apache/hertzbeat/commits?author=Thespica" title="Documentation">📖</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/boatrainlsz"><img src="https://avatars.githubusercontent.com/u/18243785?v=4?s=100" width="100px;" alt="boatrainlsz"/><br /><sub><b>boatrainlsz</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=boatrainlsz" title="Documentation">📖</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://www.yitianyigexiangfa.com/"><img src="https://avatars.githubusercontent.com/u/3973419?v=4?s=100" width="100px;" alt="Bill Lau"/><br /><sub><b>Bill Lau</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=JavaProgrammerLB" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/lw-yang"><img src="https://avatars.githubusercontent.com/u/23456873?v=4?s=100" width="100px;" alt="lwyang"/><br /><sub><b>lwyang</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=lw-yang" title="Documentation">📖</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/xfl12345"><img src="https://avatars.githubusercontent.com/u/17960863?v=4?s=100" width="100px;" alt="xfl12345"/><br /><sub><b>xfl12345</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=xfl12345" title="Documentation">📖</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/yykaue"><img src="https://avatars.githubusercontent.com/u/22905143?v=4?s=100" width="100px;" alt="Limbo"/><br /><sub><b>Limbo</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=yykaue" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/irenhongyan"><img src="https://avatars.githubusercontent.com/u/53438321?v=4?s=100" width="100px;" alt="哈哈哈哈哈哈哈哈哈"/><br /><sub><b>哈哈哈哈哈哈哈哈哈</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=irenhongyan" title="Code">💻</a></td>
</tr>
<tr>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/ileonli"><img src="https://avatars.githubusercontent.com/u/45332412?v=4?s=100" width="100px;" alt="Leon Li"/><br /><sub><b>Leon Li</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=ileonli" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="http://fnil.net/"><img src="https://avatars.githubusercontent.com/u/14142?v=4?s=100" width="100px;" alt="dennis zhuang"/><br /><sub><b>dennis zhuang</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=killme2008" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/kerwin612"><img src="https://avatars.githubusercontent.com/u/3371163?v=4?s=100" width="100px;" alt="Kerwin Bryant"/><br /><sub><b>Kerwin Bryant</b></sub></a><br /><a href="#design-kerwin612" title="Design">🎨</a> <a href="https://github.com/apache/hertzbeat/commits?author=kerwin612" title="Code">💻</a> <a href="https://github.com/apache/hertzbeat/commits?author=kerwin612" title="Documentation">📖</a> <a href="https://github.com/apache/hertzbeat/issues?q=author%3Akerwin612" title="Bug reports">🐛</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/ShineDevelopment"><img src="https://avatars.githubusercontent.com/u/59306780?v=4?s=100" width="100px;" alt="daixianglong"/><br /><sub><b>daixianglong</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=ShineDevelopment" title="Documentation">📖</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/mchgood"><img src="https://avatars.githubusercontent.com/u/38482005?v=4?s=100" width="100px;" alt="mchgood"/><br /><sub><b>mchgood</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=mchgood" title="Documentation">📖</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/pwallk"><img src="https://avatars.githubusercontent.com/u/69385076?v=4?s=100" width="100px;" alt="kangli"/><br /><sub><b>kangli</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=pwallk" title="Code">💻</a> <a href="https://github.com/apache/hertzbeat/commits?author=pwallk" title="Documentation">📖</a> <a href="https://github.com/apache/hertzbeat/issues?q=author%3Apwallk" title="Bug reports">🐛</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/cdphantom"><img src="https://avatars.githubusercontent.com/u/12674795?v=4?s=100" width="100px;" alt="cdphantom"/><br /><sub><b>cdphantom</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=cdphantom" title="Code">💻</a></td>
</tr>
<tr>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/asd108908382"><img src="https://avatars.githubusercontent.com/u/77717999?v=4?s=100" width="100px;" alt="jiawei.guo"/><br /><sub><b>jiawei.guo</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=asd108908382" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/QBH-insist"><img src="https://avatars.githubusercontent.com/u/39401478?v=4?s=100" width="100px;" alt="QBH-insist"/><br /><sub><b>QBH-insist</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=QBH-insist" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/jiangsh-ui"><img src="https://avatars.githubusercontent.com/u/86990361?v=4?s=100" width="100px;" alt="jiangsh"/><br /><sub><b>jiangsh</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=jiangsh-ui" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/keaifafafa"><img src="https://avatars.githubusercontent.com/u/83876361?v=4?s=100" width="100px;" alt="Keaifa"/><br /><sub><b>Keaifa</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=keaifafafa" title="Code">💻</a> <a href="https://github.com/apache/hertzbeat/issues?q=author%3Akeaifafafa" title="Bug reports">🐛</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/loong95"><img src="https://avatars.githubusercontent.com/u/16333958?v=4?s=100" width="100px;" alt="Loong"/><br /><sub><b>Loong</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=loong95" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/ceekay47"><img src="https://avatars.githubusercontent.com/u/104664857?v=4?s=100" width="100px;" alt="Chandrakant Vankayalapati"/><br /><sub><b>Chandrakant Vankayalapati</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=ceekay47" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/MRgenial"><img src="https://avatars.githubusercontent.com/u/49973336?v=4?s=100" width="100px;" alt="b_mountain"/><br /><sub><b>b_mountain</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=MRgenial" title="Code">💻</a></td>
</tr>
<tr>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/TemirlanBasitov"><img src="https://avatars.githubusercontent.com/u/57500808?v=4?s=100" width="100px;" alt="TemirlanBasitov"/><br /><sub><b>TemirlanBasitov</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=TemirlanBasitov" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/wyfvsfy"><img src="https://avatars.githubusercontent.com/u/11973517?v=4?s=100" width="100px;" alt="wyfvsfy"/><br /><sub><b>wyfvsfy</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=wyfvsfy" title="Documentation">📖</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/sherry-peng2333"><img src="https://avatars.githubusercontent.com/u/70619577?v=4?s=100" width="100px;" alt="sherry-peng2333"/><br /><sub><b>sherry-peng2333</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=sherry-peng2333" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/lixiaobaivv"><img src="https://avatars.githubusercontent.com/u/39290771?v=4?s=100" width="100px;" alt="Yzzz"/><br /><sub><b>Yzzz</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=lixiaobaivv" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="http://www.bckf.cn/"><img src="https://avatars.githubusercontent.com/u/13309008?v=4?s=100" width="100px;" alt="puruidong"/><br /><sub><b>puruidong</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=pruidong" title="Documentation">📖</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/shinestare"><img src="https://avatars.githubusercontent.com/u/13570619?v=4?s=100" width="100px;" alt="shinestare"/><br /><sub><b>shinestare</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=shinestare" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/po-168"><img src="https://avatars.githubusercontent.com/u/185745593?v=4?s=100" width="100px;" alt="po-168"/><br /><sub><b>po-168</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=po-168" title="Code">💻</a></td>
</tr>
<tr>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/All-The-Best-for"><img src="https://avatars.githubusercontent.com/u/76414672?v=4?s=100" width="100px;" alt="wbs99"/><br /><sub><b>wbs99</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=All-The-Best-for" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/starryCoder"><img src="https://avatars.githubusercontent.com/u/46510059?v=4?s=100" width="100px;" alt="starryCoder"/><br /><sub><b>starryCoder</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=starryCoder" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/hasimmollah"><img src="https://avatars.githubusercontent.com/u/32538599?v=4?s=100" width="100px;" alt="hasimmollah"/><br /><sub><b>hasimmollah</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=hasimmollah" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/ayu-v0"><img src="https://avatars.githubusercontent.com/u/127600988?v=4?s=100" width="100px;" alt="Ayu"/><br /><sub><b>Ayu</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=ayu-v0" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/Rancho-7"><img src="https://avatars.githubusercontent.com/u/59016860?v=4?s=100" width="100px;" alt="Nick Guo"/><br /><sub><b>Nick Guo</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=Rancho-7" title="Documentation">📖</a> <a href="https://github.com/apache/hertzbeat/commits?author=Rancho-7" title="Code">💻</a> <a href="https://github.com/apache/hertzbeat/issues?q=author%3ARancho-7" title="Bug reports">🐛</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/doveLin0818"><img src="https://avatars.githubusercontent.com/u/190927907?v=4?s=100" width="100px;" alt="doveLin"/><br /><sub><b>doveLin</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=doveLin0818" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://zzrl.cc/"><img src="https://avatars.githubusercontent.com/u/91836599?v=4?s=100" width="100px;" alt="yunfan24"/><br /><sub><b>yunfan24</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=yunfan24" title="Code">💻</a> <a href="https://github.com/apache/hertzbeat/commits?author=yunfan24" title="Documentation">📖</a> <a href="https://github.com/apache/hertzbeat/issues?q=author%3Ayunfan24" title="Bug reports">🐛</a> <a href="https://github.com/apache/hertzbeat/commits?author=yunfan24" title="Tests">⚠️</a> <a href="#blog-yunfan24" title="Blogposts">📝</a></td>
</tr>
<tr>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/lctking"><img src="https://avatars.githubusercontent.com/u/168249998?v=4?s=100" width="100px;" alt="nullwli"/><br /><sub><b>nullwli</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=lctking" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://simonsigre.com/"><img src="https://avatars.githubusercontent.com/u/14932913?v=4?s=100" width="100px;" alt="Simon Sigré"/><br /><sub><b>Simon Sigré</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=simonsigre" title="Documentation">📖</a> <a href="https://github.com/apache/hertzbeat/commits?author=simonsigre" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="http://www.ponfee.cn/"><img src="https://avatars.githubusercontent.com/u/46117331?v=4?s=100" width="100px;" alt="ponfee"/><br /><sub><b>ponfee</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=ponfee" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/Vedant7789"><img src="https://avatars.githubusercontent.com/u/147625492?v=4?s=100" width="100px;" alt="Vedant7789"/><br /><sub><b>Vedant7789</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=Vedant7789" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/Craaaaazy77"><img src="https://avatars.githubusercontent.com/u/23025522?v=4?s=100" width="100px;" alt="Craaaaazy77"/><br /><sub><b>Craaaaazy77</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=Craaaaazy77" title="Documentation">📖</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/Suvrat1629"><img src="https://avatars.githubusercontent.com/u/140749446?v=4?s=100" width="100px;" alt="Suvrat1629"/><br /><sub><b>Suvrat1629</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=Suvrat1629" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="http://ghyghoo8.github.io/"><img src="https://avatars.githubusercontent.com/u/363129?v=4?s=100" width="100px;" alt="ghy"/><br /><sub><b>ghy</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=ghyghoo8" title="Code">💻</a></td>
</tr>
<tr>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/helei1030"><img src="https://avatars.githubusercontent.com/u/11839080?v=4?s=100" width="100px;" alt="helei1030"/><br /><sub><b>helei1030</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=helei1030" title="Documentation">📖</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://medium.com/@pjfanning"><img src="https://avatars.githubusercontent.com/u/11783444?v=4?s=100" width="100px;" alt="PJ Fanning"/><br /><sub><b>PJ Fanning</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=pjfanning" title="Code">💻</a> <a href="https://github.com/apache/hertzbeat/issues?q=author%3Apjfanning" title="Bug reports">🐛</a> <a href="https://github.com/apache/hertzbeat/commits?author=pjfanning" title="Tests">⚠️</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/MonsterChenzhuo"><img src="https://avatars.githubusercontent.com/u/60029759?v=4?s=100" width="100px;" alt="monster"/><br /><sub><b>monster</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=MonsterChenzhuo" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/MasamiYui"><img src="https://avatars.githubusercontent.com/u/22274133?v=4?s=100" width="100px;" alt="Sherlock Yin"/><br /><sub><b>Sherlock Yin</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=MasamiYui" title="Code">💻</a> <a href="https://github.com/apache/hertzbeat/commits?author=MasamiYui" title="Documentation">📖</a> <a href="https://github.com/apache/hertzbeat/issues?q=author%3AMasamiYui" title="Bug reports">🐛</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/wanhao23"><img src="https://avatars.githubusercontent.com/u/29560961?v=4?s=100" width="100px;" alt="wanhao"/><br /><sub><b>wanhao</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=wanhao23" title="Code">💻</a> <a href="https://github.com/apache/hertzbeat/commits?author=wanhao23" title="Documentation">📖</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/jonasHanhan"><img src="https://avatars.githubusercontent.com/u/130035609?v=4?s=100" width="100px;" alt="jonasHanhan"/><br /><sub><b>jonasHanhan</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=jonasHanhan" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/NikhilMurugesan"><img src="https://avatars.githubusercontent.com/u/49281792?v=4?s=100" width="100px;" alt="NikhilMurugesan"/><br /><sub><b>NikhilMurugesan</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=NikhilMurugesan" title="Code">💻</a></td>
</tr>
<tr>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/myangle1120"><img src="https://avatars.githubusercontent.com/u/19237013?v=4?s=100" width="100px;" alt="myangle1120"/><br /><sub><b>myangle1120</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=myangle1120" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/yasminvo"><img src="https://avatars.githubusercontent.com/u/107528848?v=4?s=100" width="100px;" alt="yasminvo"/><br /><sub><b>yasminvo</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=yasminvo" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/notbugggg"><img src="https://avatars.githubusercontent.com/u/147966331?v=4?s=100" width="100px;" alt="不关银渐层的事哦"/><br /><sub><b>不关银渐层的事哦</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=notbugggg" title="Code">💻</a> <a href="https://github.com/apache/hertzbeat/issues?q=author%3Anotbugggg" title="Bug reports">🐛</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/yyahang"><img src="https://avatars.githubusercontent.com/u/90464876?v=4?s=100" width="100px;" alt="yyahang"/><br /><sub><b>yyahang</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=yyahang" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/JuJinPark"><img src="https://avatars.githubusercontent.com/u/44892459?v=4?s=100" width="100px;" alt="jujin"/><br /><sub><b>jujin</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=JuJinPark" title="Code">💻</a> <a href="https://github.com/apache/hertzbeat/commits?author=JuJinPark" title="Documentation">📖</a> <a href="#ideas-JuJinPark" title="Ideas, Planning, & Feedback">🤔</a> <a href="#blog-JuJinPark" title="Blogposts">📝</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/LL-LIN"><img src="https://avatars.githubusercontent.com/u/43002118?v=4?s=100" width="100px;" alt="LL-LIN"/><br /><sub><b>LL-LIN</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=LL-LIN" title="Code">💻</a> <a href="https://github.com/apache/hertzbeat/issues?q=author%3ALL-LIN" title="Bug reports">🐛</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://bigcyy.github.io/"><img src="https://avatars.githubusercontent.com/u/73413979?v=4?s=100" width="100px;" alt="Yang Chen"/><br /><sub><b>Yang Chen</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=bigcyy" title="Code">💻</a> <a href="https://github.com/apache/hertzbeat/commits?author=bigcyy" title="Documentation">📖</a> <a href="https://github.com/apache/hertzbeat/issues?q=author%3Abigcyy" title="Bug reports">🐛</a></td>
</tr>
<tr>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/sarthakeash"><img src="https://avatars.githubusercontent.com/u/74091160?v=4?s=100" width="100px;" alt="Sarthak Arora"/><br /><sub><b>Sarthak Arora</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=sarthakeash" title="Code">💻</a> <a href="https://github.com/apache/hertzbeat/commits?author=sarthakeash" title="Documentation">📖</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/PengJingzhao"><img src="https://avatars.githubusercontent.com/u/97368949?v=4?s=100" width="100px;" alt="彭镜肇"/><br /><sub><b>彭镜肇</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=PengJingzhao" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/gagaradio"><img src="https://avatars.githubusercontent.com/u/18532370?v=4?s=100" width="100px;" alt="Walter Jia"/><br /><sub><b>Walter Jia</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=gagaradio" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/boyucjz"><img src="https://avatars.githubusercontent.com/u/18730041?v=4?s=100" width="100px;" alt="boyucjz"/><br /><sub><b>boyucjz</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=boyucjz" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/Cyanty"><img src="https://avatars.githubusercontent.com/u/153884653?v=4?s=100" width="100px;" alt="Cyanty"/><br /><sub><b>Cyanty</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=Cyanty" title="Code">💻</a> <a href="https://github.com/apache/hertzbeat/commits?author=Cyanty" title="Documentation">📖</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/KevinLLF"><img src="https://avatars.githubusercontent.com/u/85452733?v=4?s=100" width="100px;" alt="Jay丿167"/><br /><sub><b>Jay丿167</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=KevinLLF" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/Duansg"><img src="https://avatars.githubusercontent.com/u/112607719?v=4?s=100" width="100px;" alt="Duansg"/><br /><sub><b>Duansg</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=Duansg" title="Documentation">📖</a></td>
</tr>
<tr>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/xiaomizhou2"><img src="https://avatars.githubusercontent.com/u/47807926?v=4?s=100" width="100px;" alt="zhangyaxi"/><br /><sub><b>zhangyaxi</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=xiaomizhou2" title="Code">💻</a> <a href="https://github.com/apache/hertzbeat/commits?author=xiaomizhou2" title="Tests">⚠️</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/RainBondsongyg"><img src="https://avatars.githubusercontent.com/u/94501396?v=4?s=100" width="100px;" alt="songyg"/><br /><sub><b>songyg</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=RainBondsongyg" title="Documentation">📖</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/lx1229"><img src="https://avatars.githubusercontent.com/u/44620005?v=4?s=100" width="100px;" alt="Liuxin"/><br /><sub><b>Liuxin</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=lx1229" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/yy549159265"><img src="https://avatars.githubusercontent.com/u/40821310?v=4?s=100" width="100px;" alt="yy549159265"/><br /><sub><b>yy549159265</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=yy549159265" title="Code">💻</a> <a href="https://github.com/apache/hertzbeat/commits?author=yy549159265" title="Tests">⚠️</a> <a href="#design-yy549159265" title="Design">🎨</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/cto-huhang"><img src="https://avatars.githubusercontent.com/u/53338629?v=4?s=100" width="100px;" alt="cto-huhang"/><br /><sub><b>cto-huhang</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=cto-huhang" title="Documentation">📖</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/Saramanda9988"><img src="https://avatars.githubusercontent.com/u/176664901?v=4?s=100" width="100px;" alt="LunaRain_079"/><br /><sub><b>LunaRain_079</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=Saramanda9988" title="Documentation">📖</a> <a href="https://github.com/apache/hertzbeat/commits?author=Saramanda9988" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/delei"><img src="https://avatars.githubusercontent.com/u/17263766?v=4?s=100" width="100px;" alt="DeleiGuo"/><br /><sub><b>DeleiGuo</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=delei" title="Documentation">📖</a> <a href="https://github.com/apache/hertzbeat/commits?author=delei" title="Code">💻</a> <a href="https://github.com/apache/hertzbeat/commits?author=delei" title="Tests">⚠️</a> <a href="https://github.com/apache/hertzbeat/issues?q=author%3Adelei" title="Bug reports">🐛</a></td>
</tr>
<tr>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/chingjustwe"><img src="https://avatars.githubusercontent.com/u/13643747?v=4?s=100" width="100px;" alt="Rocky, Chi"/><br /><sub><b>Rocky, Chi</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=chingjustwe" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/rowankid"><img src="https://avatars.githubusercontent.com/u/18652781?v=4?s=100" width="100px;" alt="Wenqi Luo"/><br /><sub><b>Wenqi Luo</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/issues?q=author%3Arowankid" title="Bug reports">🐛</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/tuzuy"><img src="https://avatars.githubusercontent.com/u/95274591?v=4?s=100" width="100px;" alt="tuzuy"/><br /><sub><b>tuzuy</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=tuzuy" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/carlpinto25"><img src="https://avatars.githubusercontent.com/u/117299909?v=4?s=100" width="100px;" alt="carl pinto"/><br /><sub><b>carl pinto</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=carlpinto25" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://cxhello.top/"><img src="https://avatars.githubusercontent.com/u/49056040?v=4?s=100" width="100px;" alt="cxhello"/><br /><sub><b>cxhello</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=cxhello" title="Documentation">📖</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/jl15988"><img src="https://avatars.githubusercontent.com/u/70638770?v=4?s=100" width="100px;" alt="会功夫的李白"/><br /><sub><b>会功夫的李白</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=jl15988" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://blog.aytop.cloud/"><img src="https://avatars.githubusercontent.com/u/37127008?v=4?s=100" width="100px;" alt="Albert.Yang"/><br /><sub><b>Albert.Yang</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=AlbertYang0801" title="Code">💻</a></td>
</tr>
<tr>
<td align="center" valign="top" width="14.28%"><a href="https://blog.tokenlen.top/"><img src="https://avatars.githubusercontent.com/u/150590575?v=4?s=100" width="100px;" alt="zhou yong kang"/><br /><sub><b>zhou yong kang</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=mengnankkkk" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/warrobe"><img src="https://avatars.githubusercontent.com/u/89446159?v=4?s=100" width="100px;" alt="warrobe"/><br /><sub><b>warrobe</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=warrobe" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/Jetiaime"><img src="https://avatars.githubusercontent.com/u/93769000?v=4?s=100" width="100px;" alt="TeAmo"/><br /><sub><b>TeAmo</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=Jetiaime" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/pentium100"><img src="https://avatars.githubusercontent.com/u/27917?v=4?s=100" width="100px;" alt="pentium100"/><br /><sub><b>pentium100</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=pentium100" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/dedyks"><img src="https://avatars.githubusercontent.com/u/23741665?v=4?s=100" width="100px;" alt="Dedy Kurniawan Santoso"/><br /><sub><b>Dedy Kurniawan Santoso</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=dedyks" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/KOYR"><img src="https://avatars.githubusercontent.com/u/53216619?v=4?s=100" width="100px;" alt="KOYR"/><br /><sub><b>KOYR</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=KOYR" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/Lathika226"><img src="https://avatars.githubusercontent.com/u/178710568?v=4?s=100" width="100px;" alt="LathikaBaddam"/><br /><sub><b>LathikaBaddam</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=Lathika226" title="Documentation">📖</a></td>
</tr>
<tr>
<td align="center" valign="top" width="14.28%"><a href="https://shadwal.space/"><img src="https://avatars.githubusercontent.com/u/119167601?v=4?s=100" width="100px;" alt="Sahil Shadwal"/><br /><sub><b>Sahil Shadwal</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=Sahil-Shadwal" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/BhanuNidumolu"><img src="https://avatars.githubusercontent.com/u/180380413?v=4?s=100" width="100px;" alt="N.Bhanu Prasad"/><br /><sub><b>N.Bhanu Prasad</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=BhanuNidumolu" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://prakashh-portfolio.vercel.app/"><img src="https://avatars.githubusercontent.com/u/183058331?v=4?s=100" width="100px;" alt="Prakash Kumar"/><br /><sub><b>Prakash Kumar</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=Prakash1185" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/orangeCatDeveloper"><img src="https://avatars.githubusercontent.com/u/95899648?v=4?s=100" width="100px;" alt="NekoPunch"/><br /><sub><b>NekoPunch</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=orangeCatDeveloper" title="Code">💻</a> <a href="https://github.com/apache/hertzbeat/commits?author=orangeCatDeveloper" title="Documentation">📖</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://wy471x.github.io/"><img src="https://avatars.githubusercontent.com/u/52033069?v=4?s=100" width="100px;" alt="wy471x"/><br /><sub><b>wy471x</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=wy471x" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/hengyuss"><img src="https://avatars.githubusercontent.com/u/81064732?v=4?s=100" width="100px;" alt="hengyuss"/><br /><sub><b>hengyuss</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=hengyuss" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://moduvoice.com/"><img src="https://avatars.githubusercontent.com/u/291867022?v=4?s=100" width="100px;" alt="moduvoice"/><br /><sub><b>moduvoice</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=moduvoice" title="Documentation">📖</a></td>
</tr>
<tr>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/hutiefang76"><img src="https://avatars.githubusercontent.com/u/137664623?v=4?s=100" width="100px;" alt="hutiefang76"/><br /><sub><b>hutiefang76</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=hutiefang76" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://zylatent.com/"><img src="https://avatars.githubusercontent.com/u/250777154?v=4?s=100" width="100px;" alt="柳含知 Liu Hanzhi"/><br /><sub><b>柳含知 Liu Hanzhi</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=ZhouYinLong-lab" title="Documentation">📖</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/wilmerdooley"><img src="https://avatars.githubusercontent.com/u/259930736?v=4?s=100" width="100px;" alt="wilmerdooley"/><br /><sub><b>wilmerdooley</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=wilmerdooley" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/Zmjjeff7"><img src="https://avatars.githubusercontent.com/u/175370943?v=4?s=100" width="100px;" alt="Zhenhong Guo"/><br /><sub><b>Zhenhong Guo</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=Zmjjeff7" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/abhyudayareddy"><img src="https://avatars.githubusercontent.com/u/54602866?v=4?s=100" width="100px;" alt="abhyudayareddy"/><br /><sub><b>abhyudayareddy</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=abhyudayareddy" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/neon-hippo"><img src="https://avatars.githubusercontent.com/u/165560498?v=4?s=100" width="100px;" alt="neon-hippo"/><br /><sub><b>neon-hippo</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=neon-hippo" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/P-Peaceful"><img src="https://avatars.githubusercontent.com/u/52856161?v=4?s=100" width="100px;" alt="P_Peaceful"/><br /><sub><b>P_Peaceful</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=P-Peaceful" title="Code">💻</a> <a href="https://github.com/apache/hertzbeat/commits?author=P-Peaceful" title="Documentation">📖</a></td>
</tr>
<tr>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/zhusaidong"><img src="https://avatars.githubusercontent.com/u/3039961?v=4?s=100" width="100px;" alt="zhusaidong"/><br /><sub><b>zhusaidong</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=zhusaidong" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/zhehenlu"><img src="https://avatars.githubusercontent.com/u/31504542?v=4?s=100" width="100px;" alt="zhlu"/><br /><sub><b>zhlu</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=zhehenlu" title="Code">💻</a> <a href="https://github.com/apache/hertzbeat/commits?author=zhehenlu" title="Documentation">📖</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/brettgervasoni"><img src="https://avatars.githubusercontent.com/u/34056000?v=4?s=100" width="100px;" alt="brettgervasoni"/><br /><sub><b>brettgervasoni</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=brettgervasoni" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/Darshan-paul"><img src="https://avatars.githubusercontent.com/u/211450705?v=4?s=100" width="100px;" alt="Darshan-paul"/><br /><sub><b>Darshan-paul</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=Darshan-paul" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/04cb"><img src="https://avatars.githubusercontent.com/u/111667698?v=4?s=100" width="100px;" alt="layla"/><br /><sub><b>layla</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=04cb" title="Documentation">📖</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/miantalha45"><img src="https://avatars.githubusercontent.com/u/155809113?v=4?s=100" width="100px;" alt="Talha Amjad"/><br /><sub><b>Talha Amjad</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=miantalha45" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://turanalmammadov.com/"><img src="https://avatars.githubusercontent.com/u/16321061?v=4?s=100" width="100px;" alt="Turan Almammadov"/><br /><sub><b>Turan Almammadov</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=turanalmammadov" title="Code">💻</a> <a href="https://github.com/apache/hertzbeat/commits?author=turanalmammadov" title="Documentation">📖</a></td>
</tr>
<tr>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/zhaoyangplus"><img src="https://avatars.githubusercontent.com/u/245090302?v=4?s=100" width="100px;" alt="zhaoyangplus"/><br /><sub><b>zhaoyangplus</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=zhaoyangplus" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/yexuanyang"><img src="https://avatars.githubusercontent.com/u/73885401?v=4?s=100" width="100px;" alt="Yang Yexuan"/><br /><sub><b>Yang Yexuan</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=yexuanyang" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/markguo123"><img src="https://avatars.githubusercontent.com/u/155072651?v=4?s=100" width="100px;" alt="markguo123"/><br /><sub><b>markguo123</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=markguo123" title="Documentation">📖</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/leo-934"><img src="https://avatars.githubusercontent.com/u/55838224?v=4?s=100" width="100px;" alt="leo"/><br /><sub><b>leo</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=leo-934" title="Code">💻</a> <a href="https://github.com/apache/hertzbeat/commits?author=leo-934" title="Documentation">📖</a> <a href="#blog-leo-934" title="Blogposts">📝</a></td>
</tr>
</tbody>
</table>
<!-- markdownlint-restore -->
<!-- prettier-ignore-end -->
<!-- ALL-CONTRIBUTORS-LIST:END -->
## 💬 コミュニティ交流
##### チャネル
[メール](https://lists.apache.org/list.html?dev@hertzbeat.apache.org) : メーリングリストに登録するために、```dev-subscribe@hertzbeat.apache.org```にメールを送ってください。
[Chat On Discord](https://discord.gg/Fb6M73htGr)
WeChatグループ : `ahertzbeat` を検索.
WeChat公式アカウント : `usthecom`を検索.
[Github Discussion](https://github.com/apache/hertzbeat/discussions)
[Follow Us Twitter](https://x.com/hertzbeat1024)
[Subscribe YouTube](https://www.youtube.com/channel/UCri75zfWX0GHqJFPENEbLow)
##### Open-Source Project Build From Open-Source
HertzBeat is built on so many great open source projects, thanks to them!
- `Java Spring SpringBoot Jpa Maven Assembly Netty Lombok Sureness Protobuf HttpClient Guava SnakeYaml JsonPath ...`
- `TypeScript Angular NG-ZORRO NG-ALAIN NodeJs Npm Html Less Echarts Rxjs ZoneJs MonacoEditor SlickCarousel Docusaurus ...`
## Landscape
<p align="left">
<img src="./home/static/img/home/cncf-landscape-left-logo.svg" width="300">&nbsp;&nbsp;<img src="./home/static/img/home/cncf-right-logo.svg" width="345" />
<br /><br />
HertzBeat has been included in the <a href="https://landscape.cncf.io/?item=observability-and-analysis--observability--hertzbeat">
CNCF Observability And Analysis - Observability Landscape.</a>
</p>
## 🛡️ License
[`Apache License, Version 2.0`](https://www.apache.org/licenses/LICENSE-2.0.html)
+9 -6
View File
@@ -1,12 +1,9 @@
# Security Policy
**[Version Releases](https://github.com/apache/hertzbeat/releases)**
Apache HertzBeat™ follows the [ASF vulnerability handling process](https://apache.org/security/#vulnerability-handling)
## Supported Versions
Use this section to tell people about which versions of your project are
currently being supported with security updates.
| Version | Supported |
|-------------------|--------------------|
| Latest Version | :white_check_mark: |
@@ -14,6 +11,12 @@ currently being supported with security updates.
## Reporting a Vulnerability
Use this section to tell people how to report a vulnerability.
Please do not file GitHub issues for security vulnerabilities as they are public!
Please report vulnerability disclosures to `security@apache.org`.
To report a new vulnerability you have discovered please follow the [ASF vulnerability reporting process](https://apache.org/security/#reporting-a-vulnerability).
## Extra Information
- [Apache HertzBeat™ Security Model](https://hertzbeat.apache.org/docs/help/security_model)
- [ASF Security](https://www.apache.org/security/)
- [Apache HertzBeat™ Document](https://hertzbeat.apache.org/docs/)
-87
View File
@@ -1,87 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
~ Licensed to the Apache Software Foundation (ASF) under one or more
~ contributor license agreements. See the NOTICE file distributed with
~ this work for additional information regarding copyright ownership.
~ The ASF licenses this file to You under the Apache License, Version 2.0
~ (the "License"); you may not use this file except in compliance with
~ the License. You may obtain a copy of the License at
~
~ http://www.apache.org/licenses/LICENSE-2.0
~
~ Unless required by applicable law or agreed to in writing, software
~ distributed under the License is distributed on an "AS IS" BASIS,
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
~ See the License for the specific language governing permissions and
~ limitations under the License.
-->
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>hertzbeat</artifactId>
<groupId>org.apache.hertzbeat</groupId>
<version>2.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>hertzbeat-alerter</artifactId>
<name>${project.artifactId}</name>
<properties>
</properties>
<dependencies>
<!-- common -->
<dependency>
<groupId>org.apache.hertzbeat</groupId>
<artifactId>hertzbeat-common</artifactId>
<scope>provided</scope>
</dependency>
<!-- spring -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-autoconfigure</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>
<!-- kafka -->
<dependency>
<groupId>org.apache.kafka</groupId>
<artifactId>kafka-clients</artifactId>
</dependency>
<!--redis-->
<dependency>
<groupId>io.lettuce</groupId>
<artifactId>lettuce-core</artifactId>
<scope>provided</scope>
</dependency>
<!-- swagger -->
<dependency>
<groupId>org.springdoc</groupId>
<artifactId>springdoc-openapi-starter-webmvc-ui</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>cn.afterturn</groupId>
<artifactId>easypoi-annotation</artifactId>
<version>4.3.0</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi</artifactId>
<version>4.1.1</version>
<scope>compile</scope>
</dependency>
</dependencies>
</project>
@@ -1,68 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.hertzbeat.alert;
import com.google.common.util.concurrent.ThreadFactoryBuilder;
import java.util.concurrent.RejectedExecutionException;
import java.util.concurrent.SynchronousQueue;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
/**
* alarm module thread pool
*/
@Component
@Slf4j
public class AlerterWorkerPool {
private ThreadPoolExecutor workerExecutor;
public AlerterWorkerPool() {
initWorkExecutor();
}
private void initWorkExecutor() {
ThreadFactory threadFactory = new ThreadFactoryBuilder()
.setUncaughtExceptionHandler((thread, throwable) -> {
log.error("workerExecutor has uncaughtException.");
log.error(throwable.getMessage(), throwable);
})
.setDaemon(true)
.setNameFormat("alerter-worker-%d")
.build();
workerExecutor = new ThreadPoolExecutor(6,
10,
10,
TimeUnit.SECONDS,
new SynchronousQueue<>(),
threadFactory,
new ThreadPoolExecutor.AbortPolicy());
}
/**
* Run the alerter task
* @param runnable task
* @throws RejectedExecutionException when The thread pool is full of
*/
public void executeJob(Runnable runnable) throws RejectedExecutionException {
workerExecutor.execute(runnable);
}
}
@@ -1,482 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.hertzbeat.alert.calculate;
import static org.apache.hertzbeat.common.constants.CommonConstants.ALERT_STATUS_CODE_NOT_REACH;
import static org.apache.hertzbeat.common.constants.CommonConstants.ALERT_STATUS_CODE_PENDING;
import static org.apache.hertzbeat.common.constants.CommonConstants.ALERT_STATUS_CODE_SOLVED;
import static org.apache.hertzbeat.common.constants.CommonConstants.TAG_CODE;
import static org.apache.hertzbeat.common.constants.CommonConstants.TAG_METRIC;
import static org.apache.hertzbeat.common.constants.CommonConstants.TAG_METRICS;
import static org.apache.hertzbeat.common.constants.CommonConstants.TAG_MONITOR_APP;
import static org.apache.hertzbeat.common.constants.CommonConstants.TAG_MONITOR_ID;
import static org.apache.hertzbeat.common.constants.CommonConstants.TAG_MONITOR_NAME;
import jakarta.persistence.criteria.Predicate;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.ResourceBundle;
import java.util.concurrent.ConcurrentHashMap;
import java.util.stream.Collectors;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.jexl3.JexlException;
import org.apache.commons.jexl3.JexlExpression;
import org.apache.commons.lang3.StringUtils;
import org.apache.hertzbeat.alert.AlerterWorkerPool;
import org.apache.hertzbeat.alert.dao.AlertMonitorDao;
import org.apache.hertzbeat.alert.reduce.AlarmCommonReduce;
import org.apache.hertzbeat.alert.service.AlertDefineService;
import org.apache.hertzbeat.alert.service.AlertService;
import org.apache.hertzbeat.alert.util.AlertTemplateUtil;
import org.apache.hertzbeat.common.constants.CommonConstants;
import org.apache.hertzbeat.common.entity.alerter.Alert;
import org.apache.hertzbeat.common.entity.alerter.AlertDefine;
import org.apache.hertzbeat.common.entity.manager.Monitor;
import org.apache.hertzbeat.common.entity.manager.TagItem;
import org.apache.hertzbeat.common.entity.message.CollectRep;
import org.apache.hertzbeat.common.queue.CommonDataQueue;
import org.apache.hertzbeat.common.support.event.MonitorDeletedEvent;
import org.apache.hertzbeat.common.support.event.SystemConfigChangeEvent;
import org.apache.hertzbeat.common.util.CommonUtil;
import org.apache.hertzbeat.common.util.JexlExpressionRunner;
import org.apache.hertzbeat.common.util.ResourceBundleUtil;
import org.springframework.context.event.EventListener;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;
/**
* Calculate alarms based on the alarm definition rules and collected data
*/
@Component
@Slf4j
public class CalculateAlarm {
private static final String SYSTEM_VALUE_ROW_COUNT = "system_value_row_count";
/**
* The alarm in the process is triggered
* key - monitorId+alertDefineId+tags The alarm is a common threshold alarm
* key - monitorId Indicates the monitoring status availability reachability alarm
*/
private final Map<String, Alert> triggeredAlertMap;
/**
* The not recover alert
* key - monitorId + alertDefineId + tags
*/
private final Map<String, Alert> notRecoveredAlertMap;
private final AlerterWorkerPool workerPool;
private final CommonDataQueue dataQueue;
private final AlertDefineService alertDefineService;
private final AlarmCommonReduce alarmCommonReduce;
private ResourceBundle bundle;
private final AlertService alertService;
public CalculateAlarm(AlerterWorkerPool workerPool, CommonDataQueue dataQueue,
AlertDefineService alertDefineService, AlertMonitorDao monitorDao,
AlarmCommonReduce alarmCommonReduce, AlertService alertService) {
this.workerPool = workerPool;
this.dataQueue = dataQueue;
this.alarmCommonReduce = alarmCommonReduce;
this.alertDefineService = alertDefineService;
this.alertService = alertService;
this.bundle = ResourceBundleUtil.getBundle("alerter");
this.triggeredAlertMap = new ConcurrentHashMap<>(16);
this.notRecoveredAlertMap = new ConcurrentHashMap<>(16);
// Initialize stateAlertMap
List<Monitor> monitors = monitorDao.findMonitorsByStatus(CommonConstants.MONITOR_DOWN_CODE);
if (monitors != null) {
for (Monitor monitor : monitors) {
HashMap<String, String> tags = new HashMap<>(8);
tags.put(TAG_MONITOR_ID, String.valueOf(monitor.getId()));
tags.put(TAG_MONITOR_NAME, monitor.getName());
tags.put(TAG_MONITOR_APP, monitor.getApp());
this.notRecoveredAlertMap.put(monitor.getId() + CommonConstants.AVAILABILITY,
Alert.builder().tags(tags).target(CommonConstants.AVAILABILITY).status(ALERT_STATUS_CODE_PENDING).build());
}
}
startCalculate();
}
private void startCalculate() {
Runnable runnable = () -> {
while (!Thread.currentThread().isInterrupted()) {
try {
CollectRep.MetricsData metricsData = dataQueue.pollMetricsDataToAlerter();
if (metricsData != null) {
calculate(metricsData);
}
} catch (InterruptedException ignored) {
} catch (Exception e) {
log.error("calculate alarm error: {}.", e.getMessage(), e);
}
}
};
workerPool.executeJob(runnable);
workerPool.executeJob(runnable);
workerPool.executeJob(runnable);
}
private void calculate(CollectRep.MetricsData metricsData) {
long currentTimeMilli = System.currentTimeMillis();
long monitorId = metricsData.getId();
String app = metricsData.getApp();
if (app.startsWith(CommonConstants.PROMETHEUS_APP_PREFIX)) {
app = CommonConstants.PROMETHEUS;
}
String metrics = metricsData.getMetrics();
// If the metrics whose scheduling priority is 0 has the status of collecting response data UN_REACHABLE/UN_CONNECTABLE,
// the highest severity alarm is generated to monitor the status change
if (metricsData.getPriority() == 0) {
handlerAvailableMetrics(monitorId, app, metricsData);
}
// Query the alarm definitions associated with the metrics of the monitoring type
// field - define[]
Map<String, List<AlertDefine>> defineMap = alertDefineService.getMonitorBindAlertDefines(monitorId, app, metrics);
if (defineMap.isEmpty()) {
return;
}
List<CollectRep.Field> fields = metricsData.getFieldsList();
Map<String, Object> fieldValueMap = new HashMap<>(8);
int valueRowCount = metricsData.getValuesCount();
for (Map.Entry<String, List<AlertDefine>> entry : defineMap.entrySet()) {
List<AlertDefine> defines = entry.getValue();
for (AlertDefine define : defines) {
final String expr = define.getExpr();
if (StringUtils.isBlank(expr)) {
continue;
}
if (expr.contains(SYSTEM_VALUE_ROW_COUNT) && metricsData.getValuesCount() == 0) {
fieldValueMap.put(SYSTEM_VALUE_ROW_COUNT, valueRowCount);
try {
boolean match = execAlertExpression(fieldValueMap, expr);
try {
if (match) {
// If the threshold rule matches, the number of times the threshold has been triggered is determined and an alarm is triggered
afterThresholdRuleMatch(currentTimeMilli, monitorId, app, metrics, "", fieldValueMap, define);
// if the threshold is triggered, ignore other data rows
continue;
} else {
String alarmKey = String.valueOf(monitorId) + define.getId();
triggeredAlertMap.remove(alarmKey);
if (define.isRecoverNotice()) {
handleRecoveredAlert(currentTimeMilli, define, expr, alarmKey);
}
}
} catch (Exception e) {
log.error(e.getMessage(), e);
}
} catch (Exception ignored) {}
}
for (CollectRep.ValueRow valueRow : metricsData.getValuesList()) {
if (CollectionUtils.isEmpty(valueRow.getColumnsList())) {
continue;
}
fieldValueMap.clear();
fieldValueMap.put(SYSTEM_VALUE_ROW_COUNT, valueRowCount);
StringBuilder tagBuilder = new StringBuilder();
for (int index = 0; index < valueRow.getColumnsList().size(); index++) {
String valueStr = valueRow.getColumns(index);
if (CommonConstants.NULL_VALUE.equals(valueStr)) {
continue;
}
final CollectRep.Field field = fields.get(index);
final int fieldType = field.getType();
if (fieldType == CommonConstants.TYPE_NUMBER) {
final Double doubleValue;
if ((doubleValue = CommonUtil.parseStrDouble(valueStr)) != null) {
fieldValueMap.put(field.getName(), doubleValue);
}
} else if (fieldType == CommonConstants.TYPE_TIME) {
final Integer integerValue;
if ((integerValue = CommonUtil.parseStrInteger(valueStr)) != null) {
fieldValueMap.put(field.getName(), integerValue);
}
} else {
if (StringUtils.isNotEmpty(valueStr)) {
fieldValueMap.put(field.getName(), valueStr);
}
}
if (field.getLabel()) {
tagBuilder.append("-").append(valueStr);
}
}
try {
boolean match = execAlertExpression(fieldValueMap, expr);
try {
if (match) {
// If the threshold rule matches, the number of times the threshold has been triggered is determined and an alarm is triggered
afterThresholdRuleMatch(currentTimeMilli, monitorId, app, metrics, tagBuilder.toString(), fieldValueMap, define);
} else {
String alarmKey = String.valueOf(monitorId) + define.getId() + tagBuilder;
triggeredAlertMap.remove(alarmKey);
if (define.isRecoverNotice()) {
handleRecoveredAlert(currentTimeMilli, define, expr, alarmKey);
}
}
} catch (Exception e) {
log.error(e.getMessage(), e);
}
} catch (Exception ignored) {}
}
}
}
}
private void handleRecoveredAlert(long currentTimeMilli, AlertDefine define, String expr, String alarmKey) {
Alert notResolvedAlert = notRecoveredAlertMap.remove(alarmKey);
if (notResolvedAlert != null) {
// Sending an alarm Restore
Map<String, String> tags = notResolvedAlert.getTags();
String content = this.bundle.getString("alerter.alarm.recover") + " : " + expr;
Alert resumeAlert = Alert.builder()
.tags(tags)
.target(define.getApp() + "." + define.getMetric() + "." + define.getField())
.content(content)
.priority(CommonConstants.ALERT_PRIORITY_CODE_WARNING)
.status(CommonConstants.ALERT_STATUS_CODE_RESTORED)
.firstAlarmTime(currentTimeMilli)
.lastAlarmTime(notResolvedAlert.getLastAlarmTime())
.triggerTimes(1)
.build();
alarmCommonReduce.reduceAndSendAlarm(resumeAlert);
}
}
private void afterThresholdRuleMatch(long currentTimeMilli, long monitorId, String app, String metrics, String tagStr,
Map<String, Object> fieldValueMap, AlertDefine define) {
String alarmKey = String.valueOf(monitorId) + define.getId() + tagStr;
Alert triggeredAlert = triggeredAlertMap.get(alarmKey);
if (triggeredAlert != null) {
int times = triggeredAlert.getTriggerTimes() + 1;
triggeredAlert.setTriggerTimes(times);
triggeredAlert.setFirstAlarmTime(currentTimeMilli);
triggeredAlert.setLastAlarmTime(currentTimeMilli);
int defineTimes = define.getTimes() == null ? 1 : define.getTimes();
if (times >= defineTimes) {
triggeredAlert.setStatus(ALERT_STATUS_CODE_PENDING);
triggeredAlertMap.remove(alarmKey);
notRecoveredAlertMap.put(alarmKey, triggeredAlert);
alarmCommonReduce.reduceAndSendAlarm(triggeredAlert.clone());
}
} else {
fieldValueMap.put(TAG_MONITOR_APP, app);
fieldValueMap.put(TAG_METRICS, metrics);
fieldValueMap.put(TAG_METRIC, define.getField());
Map<String, String> tags = new HashMap<>(8);
tags.put(TAG_MONITOR_ID, String.valueOf(monitorId));
tags.put(TAG_MONITOR_APP, app);
tags.put(CommonConstants.TAG_THRESHOLD_ID, String.valueOf(define.getId()));
if (!CollectionUtils.isEmpty(define.getTags())) {
for (TagItem tagItem : define.getTags()) {
fieldValueMap.put(tagItem.getName(), tagItem.getValue());
tags.put(tagItem.getName(), tagItem.getValue());
}
}
Alert alert = Alert.builder()
.tags(tags)
.priority(define.getPriority())
.status(ALERT_STATUS_CODE_NOT_REACH)
.target(app + "." + metrics + "." + define.getField())
.triggerTimes(1)
.firstAlarmTime(currentTimeMilli)
.lastAlarmTime(currentTimeMilli)
// Keyword matching and substitution in the template
.content(AlertTemplateUtil.render(define.getTemplate(), fieldValueMap))
.build();
int defineTimes = define.getTimes() == null ? 1 : define.getTimes();
if (1 >= defineTimes) {
alert.setStatus(ALERT_STATUS_CODE_PENDING);
notRecoveredAlertMap.put(alarmKey, alert);
alarmCommonReduce.reduceAndSendAlarm(alert.clone());
} else {
triggeredAlertMap.put(alarmKey, alert);
}
}
}
private boolean execAlertExpression(Map<String, Object> fieldValueMap, String expr) {
Boolean match;
JexlExpression expression;
try {
expression = JexlExpressionRunner.compile(expr);
} catch (JexlException jexlException) {
log.error("Alarm Rule: {} Compile Error: {}.", expr, jexlException.getMessage());
throw jexlException;
} catch (Exception e) {
log.error("Alarm Rule: {} Unknown Error: {}.", expr, e.getMessage());
throw e;
}
try {
match = (Boolean) JexlExpressionRunner.evaluate(expression, fieldValueMap);
} catch (JexlException jexlException) {
log.error("Alarm Rule: {} Run Error: {}.", expr, jexlException.getMessage());
throw jexlException;
} catch (Exception e) {
log.error("Alarm Rule: {} Unknown Error: {}.", expr, e.getMessage());
throw e;
}
return match != null && match;
}
private void handlerAvailableMetrics(long monitorId, String app, CollectRep.MetricsData metricsData) {
if (metricsData.getCode() == CollectRep.Code.TIMEOUT) {
return;
}
// TODO CACHE getMonitorBindAlertAvaDefine
AlertDefine avaAlertDefine = alertDefineService.getMonitorBindAlertAvaDefine(monitorId, app, CommonConstants.AVAILABILITY);
if (avaAlertDefine == null) {
return;
}
long currentTimeMill = System.currentTimeMillis();
if (metricsData.getCode() != CollectRep.Code.SUCCESS) {
Alert preAlert = triggeredAlertMap.get(String.valueOf(monitorId));
Map<String, String> tags = new HashMap<>(6);
tags.put(TAG_MONITOR_ID, String.valueOf(monitorId));
tags.put(TAG_MONITOR_APP, app);
tags.put(CommonConstants.TAG_THRESHOLD_ID, String.valueOf(avaAlertDefine.getId()));
tags.put(TAG_METRICS, CommonConstants.AVAILABILITY);
tags.put(TAG_CODE, metricsData.getCode().name());
Map<String, Object> valueMap = tags.entrySet().stream()
.collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
if (!CollectionUtils.isEmpty(avaAlertDefine.getTags())) {
for (TagItem tagItem : avaAlertDefine.getTags()) {
valueMap.put(tagItem.getName(), tagItem.getValue());
tags.put(tagItem.getName(), tagItem.getValue());
}
}
if (preAlert == null) {
Alert.AlertBuilder alertBuilder = Alert.builder()
.tags(tags)
.priority(avaAlertDefine.getPriority())
.status(ALERT_STATUS_CODE_NOT_REACH)
.target(CommonConstants.AVAILABILITY)
.content(AlertTemplateUtil.render(avaAlertDefine.getTemplate(), valueMap))
.firstAlarmTime(currentTimeMill)
.lastAlarmTime(currentTimeMill)
.triggerTimes(1);
if (avaAlertDefine.getTimes() == null || avaAlertDefine.getTimes() <= 1) {
String notResolvedAlertKey = monitorId + CommonConstants.AVAILABILITY;
alertBuilder.status(ALERT_STATUS_CODE_PENDING);
notRecoveredAlertMap.put(notResolvedAlertKey, alertBuilder.build());
alarmCommonReduce.reduceAndSendAlarm(alertBuilder.build());
} else {
triggeredAlertMap.put(String.valueOf(monitorId), alertBuilder.build());
}
} else {
int times = preAlert.getTriggerTimes() + 1;
preAlert.setTriggerTimes(times);
preAlert.setFirstAlarmTime(currentTimeMill);
preAlert.setLastAlarmTime(currentTimeMill);
int defineTimes = avaAlertDefine.getTimes() == null ? 1 : avaAlertDefine.getTimes();
if (times >= defineTimes) {
preAlert.setStatus(ALERT_STATUS_CODE_PENDING);
String notResolvedAlertKey = monitorId + CommonConstants.AVAILABILITY;
notRecoveredAlertMap.put(notResolvedAlertKey, preAlert.clone());
alarmCommonReduce.reduceAndSendAlarm(preAlert.clone());
triggeredAlertMap.remove(String.valueOf(monitorId));
}
}
} else {
// Check whether an availability or unreachable alarm is generated before the association monitoring
// and send a clear alarm to clear the monitoring status
triggeredAlertMap.remove(String.valueOf(monitorId));
String notResolvedAlertKey = monitorId + CommonConstants.AVAILABILITY;
Alert notResolvedAlert = notRecoveredAlertMap.remove(notResolvedAlertKey);
if (notResolvedAlert != null) {
// Sending an alarm Restore
Map<String, String> tags = notResolvedAlert.getTags();
if (!avaAlertDefine.isRecoverNotice()) {
tags.put(CommonConstants.IGNORE, CommonConstants.IGNORE);
}
String content = this.bundle.getString("alerter.availability.recover");
Alert resumeAlert = Alert.builder()
.tags(tags)
.target(CommonConstants.AVAILABILITY)
.content(content)
.priority(CommonConstants.ALERT_PRIORITY_CODE_WARNING)
.status(CommonConstants.ALERT_STATUS_CODE_RESTORED)
.firstAlarmTime(currentTimeMill)
.lastAlarmTime(notResolvedAlert.getLastAlarmTime())
.triggerTimes(1)
.build();
alarmCommonReduce.reduceAndSendAlarm(resumeAlert);
Runnable updateStatusJob = () -> {
// todo update pre all type alarm status
updateAvailabilityAlertStatus(monitorId, resumeAlert);
};
workerPool.executeJob(updateStatusJob);
}
}
}
private void updateAvailabilityAlertStatus(long monitorId, Alert restoreAlert) {
List<Alert> availabilityAlerts = queryAvailabilityAlerts(monitorId, restoreAlert);
availabilityAlerts.stream().parallel().forEach(alert -> {
log.info("updating alert status solved id: {}", alert.getId());
alertService.editAlertStatus(ALERT_STATUS_CODE_SOLVED, List.of(alert.getId()));
});
}
private List<Alert> queryAvailabilityAlerts(long monitorId, Alert restoreAlert) {
//create query condition
Specification<Alert> specification = (root, query, criteriaBuilder) -> {
List<Predicate> andList = new ArrayList<>();
Predicate predicateTags = criteriaBuilder.like(root.get("tags").as(String.class), "%" + monitorId + "%");
andList.add(predicateTags);
Predicate predicatePriority = criteriaBuilder.equal(root.get("priority"), CommonConstants.ALERT_PRIORITY_CODE_EMERGENCY);
andList.add(predicatePriority);
Predicate predicateStatus = criteriaBuilder.equal(root.get("status"), ALERT_STATUS_CODE_PENDING);
andList.add(predicateStatus);
Predicate predicateAlertTime = criteriaBuilder.lessThanOrEqualTo(root.get("lastAlarmTime"), restoreAlert.getLastAlarmTime());
andList.add(predicateAlertTime);
Predicate[] predicates = new Predicate[andList.size()];
return criteriaBuilder.and(andList.toArray(predicates));
};
//query results
return alertService.getAlerts(specification);
}
@EventListener(SystemConfigChangeEvent.class)
public void onSystemConfigChangeEvent(SystemConfigChangeEvent event) {
log.info("calculate alarm receive system config change event: {}.", event.getSource());
this.bundle = ResourceBundleUtil.getBundle("alerter");
}
@EventListener(MonitorDeletedEvent.class)
public void onMonitorDeletedEvent(MonitorDeletedEvent event) {
log.info("calculate alarm receive monitor {} has been deleted.", event.getMonitorId());
this.triggeredAlertMap.remove(String.valueOf(event.getMonitorId()));
}
}
@@ -1,27 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.hertzbeat.alert.config;
import org.springframework.context.annotation.ComponentScan;
/**
* Alert auto configuration.
*/
@ComponentScan(basePackages = "org.apache.hertzbeat.alert")
public class AlerterAutoConfiguration {
}
@@ -1,79 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.hertzbeat.alert.controller;
import static org.apache.hertzbeat.common.constants.CommonConstants.MONITOR_NOT_EXIST_CODE;
import static org.springframework.http.MediaType.APPLICATION_JSON_VALUE;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.validation.Valid;
import org.apache.hertzbeat.alert.service.AlertConvergeService;
import org.apache.hertzbeat.common.entity.alerter.AlertConverge;
import org.apache.hertzbeat.common.entity.dto.Message;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* Alarm Converge management API
*/
@Tag(name = "Alert Converge API")
@RestController
@RequestMapping(path = "/api/alert/converge", produces = {APPLICATION_JSON_VALUE})
public class AlertConvergeController {
@Autowired
private AlertConvergeService alertConvergeService;
@PostMapping
@Operation(summary = "New Alarm Converge", description = "Added an alarm Converge")
public ResponseEntity<Message<Void>> addNewAlertConverge(@Valid @RequestBody AlertConverge alertConverge) {
alertConvergeService.validate(alertConverge, false);
alertConvergeService.addAlertConverge(alertConverge);
return ResponseEntity.ok(Message.success("Add success"));
}
@PutMapping
@Operation(summary = "Modifying an Alarm Converge", description = "Modify an existing alarm Converge")
public ResponseEntity<Message<Void>> modifyAlertConverge(@Valid @RequestBody AlertConverge alertConverge) {
alertConvergeService.validate(alertConverge, true);
alertConvergeService.modifyAlertConverge(alertConverge);
return ResponseEntity.ok(Message.success("Modify success"));
}
@GetMapping(path = "/{id}")
@Operation(summary = "Querying Alarm Converge",
description = "You can obtain alarm Converge information based on the alarm Converge ID")
public ResponseEntity<Message<AlertConverge>> getAlertConverge(
@Parameter(description = "Alarm Converge ID", example = "6565463543") @PathVariable("id") long id) {
AlertConverge alertConverge = alertConvergeService.getAlertConverge(id);
if (alertConverge == null) {
return ResponseEntity.ok(Message.fail(MONITOR_NOT_EXIST_CODE, "AlertConverge not exist."));
} else {
return ResponseEntity.ok(Message.success(alertConverge));
}
}
}
@@ -1,106 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.hertzbeat.alert.controller;
import static org.springframework.http.MediaType.APPLICATION_JSON_VALUE;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.persistence.criteria.CriteriaBuilder;
import jakarta.persistence.criteria.Predicate;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import org.apache.hertzbeat.alert.service.AlertConvergeService;
import org.apache.hertzbeat.common.entity.alerter.AlertConverge;
import org.apache.hertzbeat.common.entity.dto.Message;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.http.ResponseEntity;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
/**
* Converge the batch API for alarms
*/
@Tag(name = "Alert Converge Batch API")
@RestController
@RequestMapping(path = "/api/alert/converges", produces = {APPLICATION_JSON_VALUE})
public class AlertConvergesController {
@Autowired
private AlertConvergeService alertConvergeService;
@GetMapping
@Operation(summary = "Query the alarm converge list",
description = "You can obtain the list of alarm converge by querying filter items")
public ResponseEntity<Message<Page<AlertConverge>>> getAlertConverges(
@Parameter(description = "Alarm Converge ID", example = "6565463543") @RequestParam(required = false) List<Long> ids,
@Parameter(description = "Search Name", example = "x") @RequestParam(required = false) String search,
@Parameter(description = "Sort field, default id", example = "id") @RequestParam(defaultValue = "id") String sort,
@Parameter(description = "Sort mode: asc: ascending, desc: descending", example = "desc") @RequestParam(defaultValue = "desc") String order,
@Parameter(description = "List current page", example = "0") @RequestParam(defaultValue = "0") int pageIndex,
@Parameter(description = "Number of list pages", example = "8") @RequestParam(defaultValue = "8") int pageSize) {
Specification<AlertConverge> specification = (root, query, criteriaBuilder) -> {
List<Predicate> andList = new ArrayList<>();
if (ids != null && !ids.isEmpty()) {
CriteriaBuilder.In<Long> inPredicate = criteriaBuilder.in(root.get("id"));
for (long id : ids) {
inPredicate.value(id);
}
andList.add(inPredicate);
}
if (StringUtils.hasText(search)) {
Predicate predicate = criteriaBuilder.or(
criteriaBuilder.like(
criteriaBuilder.lower(root.get("name")),
"%" + search.toLowerCase() + "%"
)
);
andList.add(predicate);
}
Predicate[] predicates = new Predicate[andList.size()];
return criteriaBuilder.and(andList.toArray(predicates));
};
Sort sortExp = Sort.by(new Sort.Order(Sort.Direction.fromString(order), sort));
PageRequest pageRequest = PageRequest.of(pageIndex, pageSize, sortExp);
Page<AlertConverge> alertConvergePage = alertConvergeService.getAlertConverges(specification, pageRequest);
return ResponseEntity.ok(Message.success(alertConvergePage));
}
@DeleteMapping
@Operation(summary = "Delete alarm converge in batches",
description = "Delete alarm converge in batches based on the alarm converge ID list")
public ResponseEntity<Message<Void>> deleteAlertDefines(
@Parameter(description = "Alarm Converge IDs", example = "6565463543") @RequestParam(required = false) List<Long> ids
) {
if (ids != null && !ids.isEmpty()) {
alertConvergeService.deleteAlertConverges(new HashSet<>(ids));
}
return ResponseEntity.ok(Message.success());
}
}
@@ -1,116 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.hertzbeat.alert.controller;
import static org.apache.hertzbeat.common.constants.CommonConstants.MONITOR_NOT_EXIST_CODE;
import static org.springframework.http.MediaType.APPLICATION_JSON_VALUE;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.validation.Valid;
import java.util.List;
import java.util.stream.Collectors;
import org.apache.hertzbeat.alert.service.AlertDefineService;
import org.apache.hertzbeat.common.entity.alerter.AlertDefine;
import org.apache.hertzbeat.common.entity.alerter.AlertDefineMonitorBind;
import org.apache.hertzbeat.common.entity.dto.Message;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* Alarm definition management API
*/
@Tag(name = "Alert Define API")
@RestController
@RequestMapping(path = "/api/alert/define", produces = {APPLICATION_JSON_VALUE})
public class AlertDefineController {
@Autowired
private AlertDefineService alertDefineService;
@PostMapping
@Operation(summary = "New Alarm Definition", description = "Added an alarm definition")
public ResponseEntity<Message<Void>> addNewAlertDefine(@Valid @RequestBody AlertDefine alertDefine) {
// Verify request data
alertDefineService.validate(alertDefine, false);
alertDefineService.addAlertDefine(alertDefine);
return ResponseEntity.ok(Message.success("Add success"));
}
@PutMapping
@Operation(summary = "Modifying an Alarm Definition", description = "Modify an existing alarm definition")
public ResponseEntity<Message<Void>> modifyAlertDefine(@Valid @RequestBody AlertDefine alertDefine) {
// Verify request data
alertDefineService.validate(alertDefine, true);
alertDefineService.modifyAlertDefine(alertDefine);
return ResponseEntity.ok(Message.success("Modify success"));
}
@GetMapping(path = "/{id}")
@Operation(summary = "Querying Alarm Definitions",
description = "You can obtain alarm definition information based on the alarm definition ID")
public ResponseEntity<Message<AlertDefine>> getAlertDefine(
@Parameter(description = "Alarm Definition ID", example = "6565463543") @PathVariable("id") long id) {
// Obtaining Monitoring Information
AlertDefine alertDefine = alertDefineService.getAlertDefine(id);
if (alertDefine == null) {
return ResponseEntity.ok(Message.fail(MONITOR_NOT_EXIST_CODE, "AlertDefine not exist."));
} else {
return ResponseEntity.ok(Message.success(alertDefine));
}
}
@DeleteMapping(path = "/{id}")
@Operation(summary = "Deleting an Alarm Definition",
description = "If the alarm definition does not exist, the alarm is deleted successfully")
public ResponseEntity<Message<Void>> deleteAlertDefine(
@Parameter(description = "Alarm Definition ID", example = "6565463543") @PathVariable("id") long id) {
// If the alarm definition does not exist or is deleted successfully, the deletion succeeds
alertDefineService.deleteAlertDefine(id);
return ResponseEntity.ok(Message.success("Delete success"));
}
@PostMapping(path = "/{alertDefineId}/monitors")
@Operation(summary = "Application alarm definition is associated with monitoring",
description = "Applies the association between specified alarm definitions and monitoring")
public ResponseEntity<Message<Void>> applyAlertDefineMonitorsBind(
@Parameter(description = "Alarm Definition ID", example = "6565463543") @PathVariable("alertDefineId") long alertDefineId,
@RequestBody List<AlertDefineMonitorBind> alertDefineMonitorBinds) {
alertDefineService.applyBindAlertDefineMonitors(alertDefineId, alertDefineMonitorBinds);
return ResponseEntity.ok(Message.success("Apply success"));
}
@GetMapping(path = "/{alertDefineId}/monitors")
@Operation(summary = "Application alarm definition is associated with monitoring",
description = "Applies the association between specified alarm definitions and monitoring")
public ResponseEntity<Message<List<AlertDefineMonitorBind>>> getAlertDefineMonitorsBind(
@Parameter(description = "Alarm Definition ID", example = "6565463543") @PathVariable("alertDefineId") long alertDefineId) {
List<AlertDefineMonitorBind> defineBinds = alertDefineService.getBindAlertDefineMonitors(alertDefineId);
defineBinds = defineBinds.stream().filter(item -> item.getMonitor() != null).collect(Collectors.toList());
return ResponseEntity.ok(Message.success(defineBinds));
}
}
@@ -1,145 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.hertzbeat.alert.controller;
import static org.springframework.http.MediaType.APPLICATION_JSON_VALUE;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.persistence.criteria.CriteriaBuilder;
import jakarta.persistence.criteria.Predicate;
import jakarta.servlet.http.HttpServletResponse;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import org.apache.hertzbeat.alert.service.AlertDefineService;
import org.apache.hertzbeat.common.entity.alerter.AlertDefine;
import org.apache.hertzbeat.common.entity.dto.Message;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.http.ResponseEntity;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
/**
* Define the batch API for alarms
*/
@Tag(name = "Alert Define Batch API")
@RestController
@RequestMapping(path = "/api/alert/defines", produces = {APPLICATION_JSON_VALUE})
public class AlertDefinesController {
@Autowired
private AlertDefineService alertDefineService;
@GetMapping
@Operation(summary = "Example Query the alarm definition list",
description = "You can obtain the list of alarm definitions by querying filter items")
public ResponseEntity<Message<Page<AlertDefine>>> getAlertDefines(
@Parameter(description = "Alarm Definition ID", example = "6565463543") @RequestParam(required = false) List<Long> ids,
@Parameter(description = "Search-Target Expr Template", example = "x") @RequestParam(required = false) String search,
@Parameter(description = "Alarm Definition Severity", example = "6565463543") @RequestParam(required = false) Byte priority,
@Parameter(description = "Sort field, default id", example = "id") @RequestParam(defaultValue = "id") String sort,
@Parameter(description = "Sort mode: asc: ascending, desc: descending", example = "desc") @RequestParam(defaultValue = "desc") String order,
@Parameter(description = "List current page", example = "0") @RequestParam(defaultValue = "0") int pageIndex,
@Parameter(description = "Number of list pages", example = "8") @RequestParam(defaultValue = "8") int pageSize) {
Specification<AlertDefine> specification = (root, query, criteriaBuilder) -> {
List<Predicate> andList = new ArrayList<>();
if (ids != null && !ids.isEmpty()) {
CriteriaBuilder.In<Long> inPredicate = criteriaBuilder.in(root.get("id"));
for (long id : ids) {
inPredicate.value(id);
}
andList.add(inPredicate);
}
if (StringUtils.hasText(search)) {
Predicate predicate = criteriaBuilder.or(
criteriaBuilder.like(
criteriaBuilder.lower(root.get("app")),
"%" + search.toLowerCase() + "%"
),
criteriaBuilder.like(
criteriaBuilder.lower(root.get("metric")),
"%" + search.toLowerCase() + "%"
),
criteriaBuilder.like(
criteriaBuilder.lower(root.get("field")),
"%" + search.toLowerCase() + "%"
),
criteriaBuilder.like(
criteriaBuilder.lower(root.get("expr")),
"%" + search.toLowerCase() + "%"
),
criteriaBuilder.like(
criteriaBuilder.lower(root.get("template")),
"%" + search.toLowerCase() + "%"
)
);
andList.add(predicate);
}
if (priority != null) {
Predicate predicate = criteriaBuilder.equal(root.get("priority"), priority);
andList.add(predicate);
}
Predicate[] predicates = new Predicate[andList.size()];
return criteriaBuilder.and(andList.toArray(predicates));
};
Sort sortExp = Sort.by(new Sort.Order(Sort.Direction.fromString(order), sort));
PageRequest pageRequest = PageRequest.of(pageIndex, pageSize, sortExp);
Page<AlertDefine> alertDefinePage = alertDefineService.getAlertDefines(specification, pageRequest);
return ResponseEntity.ok(Message.success(alertDefinePage));
}
@DeleteMapping
@Operation(summary = "Delete alarm definitions in batches",
description = "Delete alarm definitions in batches based on the alarm definition ID list")
public ResponseEntity<Message<Void>> deleteAlertDefines(
@Parameter(description = "Alarm Definition IDs", example = "6565463543") @RequestParam(required = false) List<Long> ids
) {
if (ids != null && !ids.isEmpty()) {
alertDefineService.deleteAlertDefines(new HashSet<>(ids));
}
return ResponseEntity.ok(Message.success());
}
@GetMapping("/export")
@Operation(summary = "export alertDefine config", description = "export alarm definition configuration")
public void export(
@Parameter(description = "AlertDefine ID List", example = "656937901") @RequestParam List<Long> ids,
@Parameter(description = "Export Type:JSON,EXCEL,YAML") @RequestParam(defaultValue = "JSON") String type,
HttpServletResponse res) throws Exception {
alertDefineService.export(ids, type, res);
}
@PostMapping("/import")
@Operation(summary = "import alertDefine config", description = "import alarm definition configuration")
public ResponseEntity<Message<Void>> importDefines(MultipartFile file) throws Exception {
alertDefineService.importConfig(file);
return ResponseEntity.ok(Message.success("Import success"));
}
}
@@ -1,102 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.hertzbeat.alert.controller;
import static org.springframework.http.MediaType.APPLICATION_JSON_VALUE;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import java.util.Date;
import java.util.Optional;
import lombok.extern.slf4j.Slf4j;
import org.apache.hertzbeat.alert.dto.CloudAlertReportAbstract;
import org.apache.hertzbeat.alert.dto.GeneralCloudAlertReport;
import org.apache.hertzbeat.alert.enums.CloudServiceAlarmInformationEnum;
import org.apache.hertzbeat.alert.service.AlertService;
import org.apache.hertzbeat.common.entity.dto.AlertReport;
import org.apache.hertzbeat.common.entity.dto.Message;
import org.apache.hertzbeat.common.util.JsonUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* Extern Alarm Manage API
*/
@Tag(name = "Extern Alarm Manage API")
@RestController
@RequestMapping(path = "/api/alerts/report", produces = {APPLICATION_JSON_VALUE})
@Slf4j
public class AlertReportController {
@Autowired
private AlertService alertService;
@PostMapping("/{cloud}")
@Operation(summary = "Interface for reporting external alarm information of cloud service")
public ResponseEntity<Message<Void>> addNewAlertReportFromCloud(@PathVariable("cloud") String cloudServiceName,
@RequestBody String alertReport) {
CloudServiceAlarmInformationEnum cloudService = CloudServiceAlarmInformationEnum
.getEnumFromCloudServiceName(cloudServiceName);
AlertReport alert = null;
if (cloudService != null) {
try {
CloudAlertReportAbstract cloudAlertReport = JsonUtil
.fromJson(alertReport, cloudService.getCloudServiceAlarmInformationEntity());
assert cloudAlertReport != null;
alert = AlertReport.builder()
.content(cloudAlertReport.getContent())
.alertName(cloudAlertReport.getAlertName())
.alertTime(cloudAlertReport.getAlertTime())
.alertDuration(cloudAlertReport.getAlertDuration())
.priority(cloudAlertReport.getPriority())
.reportType(cloudAlertReport.getReportType())
.labels(cloudAlertReport.getLabels())
.annotations(cloudAlertReport.getAnnotations())
.build();
} catch (Exception e) {
log.error("[alert report] parse cloud service alarm content failed! cloud service: {} conrent: {}",
cloudService.name(), alertReport);
}
} else {
alert = AlertReport.builder()
.content("error do not has cloud service api")
.alertName("/api/alerts/report/" + cloudServiceName)
.alertTime(new Date().getTime())
.priority(1)
.reportType(1)
.build();
}
Optional.ofNullable(alert).ifPresent(alertReportPresent ->
alertService.addNewAlertReport(alertReportPresent));
return ResponseEntity.ok(Message.success("Add report success"));
}
@PostMapping
@Operation(summary = "Interface for reporting external and general alarm information",
description = "The interface is used to report external and general alarm information")
public ResponseEntity<Message<Void>> addNewAlertReport(@RequestBody GeneralCloudAlertReport alertReport) {
alertReport.refreshAlertTime();
alertService.addNewAlertReport(alertReport);
return ResponseEntity.ok(Message.success("Add report success"));
}
}
@@ -1,108 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.hertzbeat.alert.controller;
import static org.springframework.http.MediaType.APPLICATION_JSON_VALUE;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.persistence.criteria.CriteriaBuilder;
import jakarta.persistence.criteria.Predicate;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import org.apache.hertzbeat.alert.service.AlertSilenceService;
import org.apache.hertzbeat.common.entity.alerter.AlertSilence;
import org.apache.hertzbeat.common.entity.dto.Message;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.http.ResponseEntity;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
/**
* Silence the batch API for alarms
*/
@Tag(name = "Alert Silence Batch API")
@RestController
@RequestMapping(path = "/api/alert/silences", produces = {APPLICATION_JSON_VALUE})
public class AlertSilencesController {
@Autowired
private AlertSilenceService alertSilenceService;
@GetMapping
@Operation(summary = "Query the alarm silence list",
description = "You can obtain the list of alarm silence by querying filter items")
public ResponseEntity<Message<Page<AlertSilence>>> getAlertSilences(
@Parameter(description = "Alarm Silence ID", example = "6565463543") @RequestParam(required = false) List<Long> ids,
@Parameter(description = "Search Name", example = "x") @RequestParam(required = false) String search,
@Parameter(description = "Sort field, default id", example = "id") @RequestParam(defaultValue = "id") String sort,
@Parameter(description = "Sort mode: asc: ascending, desc: descending", example = "desc") @RequestParam(defaultValue = "desc") String order,
@Parameter(description = "List current page", example = "0") @RequestParam(defaultValue = "0") int pageIndex,
@Parameter(description = "Number of list pages", example = "8") @RequestParam(defaultValue = "8") int pageSize) {
Specification<AlertSilence> specification = (root, query, criteriaBuilder) -> {
List<Predicate> andList = new ArrayList<>();
if (ids != null && !ids.isEmpty()) {
CriteriaBuilder.In<Long> inPredicate = criteriaBuilder.in(root.get("id"));
for (long id : ids) {
inPredicate.value(id);
}
andList.add(inPredicate);
}
if (StringUtils.hasText(search)) {
Predicate predicate = criteriaBuilder.or(
criteriaBuilder.like(
criteriaBuilder.lower(root.get("name")),
"%" + search.toLowerCase() + "%"
)
);
andList.add(predicate);
}
Predicate[] predicates = new Predicate[andList.size()];
return criteriaBuilder.and(andList.toArray(predicates));
};
Sort sortExp = Sort.by(new Sort.Order(Sort.Direction.fromString(order), sort));
PageRequest pageRequest = PageRequest.of(pageIndex, pageSize, sortExp);
Page<AlertSilence> alertSilencePage = alertSilenceService.getAlertSilences(specification, pageRequest);
Message<Page<AlertSilence>> message = Message.success(alertSilencePage);
return ResponseEntity.ok(message);
}
@DeleteMapping
@Operation(summary = "Delete alarm silence in batches",
description = "Delete alarm silence in batches based on the alarm silence ID list")
public ResponseEntity<Message<Void>> deleteAlertDefines(
@Parameter(description = "Alarm Silence IDs", example = "6565463543") @RequestParam(required = false) List<Long> ids
) {
if (ids != null && !ids.isEmpty()) {
alertSilenceService.deleteAlertSilences(new HashSet<>(ids));
}
Message<Void> message = Message.success();
return ResponseEntity.ok(message);
}
}
@@ -1,146 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.hertzbeat.alert.controller;
import static org.springframework.http.MediaType.APPLICATION_JSON_VALUE;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.persistence.criteria.CriteriaBuilder;
import jakarta.persistence.criteria.Predicate;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import org.apache.hertzbeat.alert.dto.AlertSummary;
import org.apache.hertzbeat.alert.service.AlertService;
import org.apache.hertzbeat.common.entity.alerter.Alert;
import org.apache.hertzbeat.common.entity.dto.Message;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
/**
* Alarm Management API
*/
@Tag(name = "Alarm Manage Batch API")
@RestController
@RequestMapping(path = "/api/alerts", produces = {APPLICATION_JSON_VALUE})
public class AlertsController {
@Autowired
private AlertService alertService;
@GetMapping
@Operation(summary = "Get a list of alarm information based on query filter items", description = "according to the query filter items to obtain a list of alarm information")
public ResponseEntity<Message<Page<Alert>>> getAlerts(
@Parameter(description = "Alarm ID List", example = "6565466456") @RequestParam(required = false) List<Long> ids,
@Parameter(description = "Alarm monitor object ID", example = "6565463543") @RequestParam(required = false) Long monitorId,
@Parameter(description = "Alarm level", example = "6565463543") @RequestParam(required = false) Byte priority,
@Parameter(description = "Alarm Status", example = "6565463543") @RequestParam(required = false) Byte status,
@Parameter(description = "Alarm content fuzzy query", example = "linux") @RequestParam(required = false) String content,
@Parameter(description = "Sort field, default id", example = "name") @RequestParam(defaultValue = "id") String sort,
@Parameter(description = "Sort Type", example = "desc") @RequestParam(defaultValue = "desc") String order,
@Parameter(description = "List current page", example = "0") @RequestParam(defaultValue = "0") int pageIndex,
@Parameter(description = "Number of list pagination", example = "8") @RequestParam(defaultValue = "8") int pageSize) {
Specification<Alert> specification = (root, query, criteriaBuilder) -> {
List<Predicate> andList = new ArrayList<>();
if (ids != null && !ids.isEmpty()) {
CriteriaBuilder.In<Long> inPredicate = criteriaBuilder.in(root.get("id"));
for (long id : ids) {
inPredicate.value(id);
}
andList.add(inPredicate);
}
if (monitorId != null) {
Predicate predicate = criteriaBuilder.like(root.get("tags").as(String.class), "%" + monitorId + "%");
andList.add(predicate);
}
if (priority != null) {
Predicate predicate = criteriaBuilder.equal(root.get("priority"), priority);
andList.add(predicate);
}
if (status != null) {
Predicate predicate = criteriaBuilder.equal(root.get("status"), status);
andList.add(predicate);
}
if (content != null && !content.isEmpty()) {
Predicate predicateContent = criteriaBuilder.like(root.get("content"), "%" + content + "%");
andList.add(predicateContent);
}
Predicate[] predicates = new Predicate[andList.size()];
return criteriaBuilder.and(andList.toArray(predicates));
};
Sort sortExp = Sort.by(new Sort.Order(Sort.Direction.fromString(order), sort));
PageRequest pageRequest = PageRequest.of(pageIndex, pageSize, sortExp);
Page<Alert> alertPage = alertService.getAlerts(specification, pageRequest);
Message<Page<Alert>> message = Message.success(alertPage);
return ResponseEntity.ok(message);
}
@DeleteMapping
@Operation(summary = "Delete alarms in batches", description = "according to the alarm ID list to delete the alarm information in batches")
public ResponseEntity<Message<Void>> deleteAlerts(
@Parameter(description = "Alarm List ID", example = "6565463543") @RequestParam(required = false) List<Long> ids) {
if (ids != null && !ids.isEmpty()) {
alertService.deleteAlerts(new HashSet<>(ids));
}
Message<Void> message = Message.success();
return ResponseEntity.ok(message);
}
@DeleteMapping("/clear")
@Operation(summary = "Delete alarms in batches", description = "delete all alarm information")
public ResponseEntity<Message<Void>> clearAllAlerts() {
alertService.clearAlerts();
Message<Void> message = Message.success();
return ResponseEntity.ok(message);
}
@PutMapping(path = "/status/{status}")
@Operation(summary = "Batch modify alarm status, set read and unread", description = "Batch modify alarm status, set read and unread")
public ResponseEntity<Message<Void>> applyAlertDefinesStatus(
@Parameter(description = "Alarm status value", example = "0") @PathVariable Byte status,
@Parameter(description = "Alarm List IDS", example = "6565463543") @RequestParam(required = false) List<Long> ids) {
if (ids != null && status != null && !ids.isEmpty()) {
alertService.editAlertStatus(status, ids);
}
Message<Void> message = Message.success();
return ResponseEntity.ok(message);
}
@GetMapping(path = "/summary")
@Operation(summary = "Get alarm statistics", description = "Get alarm statistics information")
public ResponseEntity<Message<AlertSummary>> getAlertsSummary() {
AlertSummary alertSummary = alertService.getAlertsSummary();
Message<AlertSummary> message = Message.success(alertSummary);
return ResponseEntity.ok(message);
}
}
@@ -1,37 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.hertzbeat.alert.dao;
import java.util.Set;
import org.apache.hertzbeat.common.entity.alerter.AlertConverge;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
import org.springframework.data.jpa.repository.Modifying;
/**
* AlertConverge Dao
*/
public interface AlertConvergeDao extends JpaRepository<AlertConverge, Long>, JpaSpecificationExecutor<AlertConverge> {
/**
* Delete alarm converge based on the ID list
* @param convergeIds alert converge id list
*/
@Modifying
void deleteAlertConvergesByIdIn(Set<Long> convergeIds);
}
@@ -1,56 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.hertzbeat.alert.dao;
import java.util.List;
import java.util.Set;
import org.apache.hertzbeat.alert.dto.AlertPriorityNum;
import org.apache.hertzbeat.common.entity.alerter.Alert;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
import org.springframework.data.jpa.repository.Modifying;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;
/**
* Alert Database Operations
*/
public interface AlertDao extends JpaRepository<Alert, Long>, JpaSpecificationExecutor<Alert> {
/**
* Delete alerts based on ID list
* @param alertIds Alert ID List
*/
void deleteAlertsByIdIn(Set<Long> alertIds);
/**
* Updates the alarm status based on the alarm ID-status value
* @param status status value
* @param ids alarm ids
*/
@Modifying
@Query("update Alert set status = :status where id in :ids")
void updateAlertsStatus(@Param(value = "status") Byte status, @Param(value = "ids") List<Long> ids);
/**
* Query the number of unhandled alarms of each alarm severity
* @return List of alerts num
*/
@Query("select new org.apache.hertzbeat.alert.dto.AlertPriorityNum(mo.priority, count(mo.id)) from Alert mo where mo.status = 0 group by mo.priority")
List<AlertPriorityNum> findAlertPriorityNum();
}
@@ -1,67 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.hertzbeat.alert.dao;
import java.util.List;
import java.util.Set;
import org.apache.hertzbeat.common.entity.alerter.AlertDefine;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;
/**
* AlertDefine Dao
*/
public interface AlertDefineDao extends JpaRepository<AlertDefine, Long>, JpaSpecificationExecutor<AlertDefine> {
/**
* Delete alarm definitions based on the ID list
* @param alertDefineIds alarm define ids
*/
void deleteAlertDefinesByIdIn(Set<Long> alertDefineIds);
/**
* Query the default alarm thresholds based on the monitoring metrics type
* @param app monitoring type
* @param metric metrics
* @return alarm defines
*/
List<AlertDefine> queryAlertDefinesByAppAndMetricAndPresetTrueAndEnableTrue(String app, String metric);
/**
* Query app metric alert define
* @param app app
* @param metric metric
* @return alert define
*/
List<AlertDefine> queryAlertDefineByAppAndMetric(String app, String metric);
/**
* Query the alarm definition list associated with the monitoring ID
* @param monitorId monitor id
* @param app monitor type
* @param metrics metrics
* @return Alarm Definition List
*/
@Query("select define from AlertDefine define join AlertDefineMonitorBind bind on bind.alertDefineId = define.id "
+ "where bind.monitorId = :monitorId and define.app = :app and define.metric = :metrics and define.enable = true and define.preset = false")
List<AlertDefine> queryAlertDefinesByMonitor(@Param(value = "monitorId") Long monitorId,
@Param(value = "app") String app,
@Param(value = "metrics") String metrics);
}
@@ -1,78 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.hertzbeat.alert.dto;
import com.fasterxml.jackson.annotation.JsonIgnore;
import java.util.Map;
import org.apache.hertzbeat.common.entity.dto.AlertReport;
/**
* Abstract parent of cloud service alarm information
* {@link AlertReport} - The method corresponds to the parameter of this class one by one. For details about the method, see this class
*/
public abstract class CloudAlertReportAbstract {
/**
* This parameter specifies the alarm name when a cloud alarm is converted to an internal alarm
*/
@JsonIgnore
public abstract String getAlertName();
/**
* Interval when a cloud alarm is converted to an internal alarm
*/
@JsonIgnore
public abstract Integer getAlertDuration();
/**
* Specifies the alarm time when a cloud alarm is converted to an internal alarm
*/
@JsonIgnore
public abstract long getAlertTime();
/**
* Severity of an alarm when a cloud alarm is converted to an internal alarm
*/
@JsonIgnore
public abstract Integer getPriority();
/**
* This parameter specifies the alarm type when a cloud alarm is converted to an internal alarm
*/
@JsonIgnore
public abstract Integer getReportType();
/**
* Alarm label information about a cloud alarm that is converted to an internal alarm
*/
@JsonIgnore
public abstract Map<String, String> getLabels();
/**
* Alarm labels when a cloud alarm is converted to an internal alarm
*/
@JsonIgnore
public abstract Map<String, String> getAnnotations();
/**
* This topic describes the alarm content when a cloud alarm is converted to an internal alarm
*/
@JsonIgnore
public abstract String getContent();
}
@@ -1,79 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.hertzbeat.alert.dto;
import java.util.Optional;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor;
import org.apache.commons.lang3.StringUtils;
import org.apache.hertzbeat.alert.util.DateUtil;
import org.apache.hertzbeat.common.entity.dto.AlertReport;
/**
* Generic cloud alarm entity class
*/
@Data
@AllArgsConstructor
@NoArgsConstructor
@EqualsAndHashCode(callSuper = true)
public class GeneralCloudAlertReport extends AlertReport {
/**
* Alarm date and time
*/
private String alertDateTime;
/**
* DATE TIME FORMAT
*/
private String dateTimeFormat;
/**
* You can refresh the timestamp of the alarm time with enhanced properties
*/
public void refreshAlertTime() {
if (getAlertTime() != 0L) {
return;
}
if (StringUtils.isNotBlank(alertDateTime)) {
Long timeStamp = null;
if (StringUtils.isNotBlank(dateTimeFormat)) {
Optional<Long> tsf = DateUtil.getTimeStampFromFormat(alertDateTime, dateTimeFormat);
boolean present = tsf.isPresent();
if (present) {
timeStamp = tsf.get();
}
}
if (timeStamp == null) {
Optional<Long> tsf = DateUtil.getTimeStampFromSomeFormats(alertDateTime);
boolean present = tsf.isPresent();
if (present) {
timeStamp = tsf.get();
}
}
if (timeStamp != null) {
setAlertTime(timeStamp);
return;
}
}
throw new RuntimeException("parse alarm time error");
}
}
@@ -1,229 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.hertzbeat.alert.dto;
import com.fasterxml.jackson.annotation.JsonProperty;
import java.io.Serializable;
import java.util.Map;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor;
import org.apache.hertzbeat.alert.util.DateUtil;
/**
*
* Tencent cloud alarm entity class
*/
@Data
@AllArgsConstructor
@NoArgsConstructor
@EqualsAndHashCode(callSuper = true)
@Builder
public class TenCloudAlertReport extends CloudAlertReportAbstract implements Serializable {
@JsonProperty("sessionID")
private String sessionId;
private String alarmStatus;
private String alarmType;
private AlarmObjInfo alarmObjInfo;
private AlarmPolicyInfo alarmPolicyInfo;
private String firstOccurTime;
private int durationTime;
private String recoverTime;
/**
* Alarm Object information
*/
@Data
@AllArgsConstructor
@NoArgsConstructor
public static class AlarmObjInfo {
private String region;
private String namespace;
@JsonProperty("appID")
private String appId;
private String uin;
private Dimensions dimensions;
}
/**
* Uniform Resource ID information
*/
@Data
@AllArgsConstructor
@NoArgsConstructor
public static class Dimensions {
@JsonProperty("unInstanceID")
private String unInstanceId;
@JsonProperty("objID")
private String objId;
}
/**
* Alarm policy information
*/
@Data
@AllArgsConstructor
@NoArgsConstructor
public static class AlarmPolicyInfo {
@JsonProperty("policyID")
private String policyId;
private String policyType;
private String policyName;
@JsonProperty("policyTypeCName")
private String policyTypeCname;
private Conditions conditions;
}
/**
* Parameters of indicator alarms
*/
@Data
@AllArgsConstructor
@NoArgsConstructor
public static class Conditions {
// alarm metrics parameters
private String metricName;
private String metricShowName;
private String calcType;
private String calcValue;
private String calcUnit;
private String currentValue;
private String historyValue;
private String unit;
private String period;
private String periodNum;
private String alarmNotifyType;
private long alarmNotifyPeriod;
// alarm event parameters
private String productName;
private String productShowName;
private String eventName;
private String eventShowName;
}
@Override
public String getAlertName() {
return "TenCloud|腾讯云";
}
@Override
public Integer getAlertDuration() {
return this.durationTime;
}
@Override
public long getAlertTime() {
return DateUtil.getTimeStampFromFormat(getFirstOccurTime(), "yyyy-MM-dd HH:mm:ss")
.orElse(0L);
}
@Override
public Integer getPriority() {
return 1;
}
@Override
public Integer getReportType() {
return 1;
}
@Override
public Map<String, String> getLabels() {
return Map.of("app", "TenCloud");
}
@Override
public Map<String, String> getAnnotations() {
return Map.of("app", "TenCloud");
}
/**
* Transaction alarm
*/
private static final String EVENT = "event";
/**
* Indicator alarm
*/
private static final String METRIC = "metric";
/**
* If the following alarm types increase, the entity class can be divided into a parent class and multiple subclasses, and then the method can be implemented in the subclass
* Since there are only two, it will not be split for the time being
*/
@Override
public String getContent() {
StringBuilder contentBuilder = new StringBuilder();
// 判断类型
if (EVENT.equals(getAlarmType())) {
contentBuilder
.append("[")
.append("告警状态 | ")
.append("0".equals(alarmStatus) ? "恢复" : "告警")
.append("]\n")
.append("[")
.append("告警对象信息 | ")
.append(getAlarmObjInfo().getRegion() == null ? "" : "region:" + getAlarmObjInfo().getRegion())
.append(";").append("appId:").append(getAlarmObjInfo().getAppId())
.append(";").append("uni:").append(getAlarmObjInfo().getUin())
.append(";").append("unInstanceId:").append(getAlarmObjInfo().getDimensions().getUnInstanceId())
.append("]\n")
.append("[")
.append("告警策略组信息 | ")
.append("名称:").append(getAlarmPolicyInfo().getPolicyName())
.append(";")
.append("策略类型展示名称:").append(getAlarmPolicyInfo().getConditions().getProductName())
.append(",").append(getAlarmPolicyInfo().getConditions().getProductShowName())
.append(";")
.append("事件告警名称:").append(getAlarmPolicyInfo().getConditions().getEventName())
.append(",").append(getAlarmPolicyInfo().getConditions().getEventShowName())
.append("]");
} else if (METRIC.equals(getAlarmType())) {
contentBuilder
.append("[")
.append("告警对象:")
.append(getAlarmObjInfo().getRegion() == null ? "" : getAlarmObjInfo().getRegion())
.append(getAlarmObjInfo().getRegion() == null ? "" : "|")
.append(getAlarmObjInfo().getNamespace())
.append("]")
.append("[")
.append("告警内容:")
.append(getAlarmPolicyInfo().getPolicyTypeCname()).append("|")
.append(getAlarmPolicyInfo().getConditions().getMetricShowName()).append("|")
.append(getAlarmPolicyInfo().getConditions().getMetricName())
.append(getAlarmPolicyInfo().getConditions().getCalcType())
.append(getAlarmPolicyInfo().getConditions().getCalcValue())
.append(getAlarmPolicyInfo().getConditions().getCalcUnit())
.append("]")
.append("[")
.append("当前数据")
.append(getAlarmPolicyInfo().getConditions().getCurrentValue())
.append(getAlarmPolicyInfo().getConditions().getCalcUnit())
.append("]");
}
return contentBuilder.toString();
}
}
@@ -1,52 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.hertzbeat.alert.enums;
import java.util.Arrays;
import lombok.AllArgsConstructor;
import lombok.Getter;
import org.apache.hertzbeat.alert.dto.CloudAlertReportAbstract;
import org.apache.hertzbeat.alert.dto.TenCloudAlertReport;
/**
* Cloud server alarm enum
*/
@AllArgsConstructor
@Getter
public enum CloudServiceAlarmInformationEnum {
TencentCloud("tencloud", TenCloudAlertReport.class);
/**
* cloud service name
*/
private final String cloudServiceName;
/**
* cloud service body
*/
private final Class<? extends CloudAlertReportAbstract> cloudServiceAlarmInformationEntity;
public static CloudServiceAlarmInformationEnum getEnumFromCloudServiceName(String name) {
return Arrays.stream(CloudServiceAlarmInformationEnum.values())
.filter(cloudService -> cloudService.cloudServiceName.equals(name))
.findFirst()
.orElse(null);
}
}
@@ -1,73 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.hertzbeat.alert.reduce;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.hertzbeat.alert.dao.AlertMonitorDao;
import org.apache.hertzbeat.common.constants.CommonConstants;
import org.apache.hertzbeat.common.entity.alerter.Alert;
import org.apache.hertzbeat.common.entity.manager.Tag;
import org.apache.hertzbeat.common.queue.CommonDataQueue;
import org.springframework.stereotype.Service;
/**
* reduce alarm and send alert data
*/
@Service
@RequiredArgsConstructor
@Slf4j
public class AlarmCommonReduce {
private final AlarmSilenceReduce alarmSilenceReduce;
private final AlarmConvergeReduce alarmConvergeReduce;
private final CommonDataQueue dataQueue;
private final AlertMonitorDao alertMonitorDao;
public void reduceAndSendAlarm(Alert alert) {
alert.setTimes(1);
Map<String, String> tags = alert.getTags();
if (tags == null) {
tags = new HashMap<>(8);
alert.setTags(tags);
}
String monitorIdStr = tags.get(CommonConstants.TAG_MONITOR_ID);
if (monitorIdStr == null) {
log.debug("receiver extern alarm message: {}", alert);
} else {
long monitorId = Long.parseLong(monitorIdStr);
List<Tag> tagList = alertMonitorDao.findMonitorIdBindTags(monitorId);
for (Tag tag : tagList) {
if (!tags.containsKey(tag.getName())) {
tags.put(tag.getName(), tag.getTagValue());
}
}
}
// converge -> silence
if (alarmConvergeReduce.filterConverge(alert) && alarmSilenceReduce.filterSilence(alert)) {
dataQueue.sendAlertsData(alert);
}
}
}
@@ -1,160 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.hertzbeat.alert.reduce;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.concurrent.ConcurrentHashMap;
import org.apache.hertzbeat.alert.dao.AlertConvergeDao;
import org.apache.hertzbeat.common.cache.CacheFactory;
import org.apache.hertzbeat.common.cache.CommonCacheService;
import org.apache.hertzbeat.common.constants.CommonConstants;
import org.apache.hertzbeat.common.entity.alerter.Alert;
import org.apache.hertzbeat.common.entity.alerter.AlertConverge;
import org.apache.hertzbeat.common.entity.manager.TagItem;
import org.springframework.stereotype.Service;
/**
* alarm converge
*/
@Service
public class AlarmConvergeReduce {
private final AlertConvergeDao alertConvergeDao;
private final Map<Integer, Alert> converageAlertMap;
public AlarmConvergeReduce(AlertConvergeDao alertConvergeDao) {
this.alertConvergeDao = alertConvergeDao;
this.converageAlertMap = new ConcurrentHashMap<>(16);
}
/**
* currentAlert converge filter data
*
* @param currentAlert currentAlert
* @return true when not filter
*/
@SuppressWarnings("unchecked")
public boolean filterConverge(Alert currentAlert) {
// ignore monitor status auto recover notice
if (currentAlert.getTags() != null && currentAlert.getTags().containsKey(CommonConstants.IGNORE)) {
return true;
}
if (currentAlert.getStatus() == CommonConstants.ALERT_STATUS_CODE_RESTORED) {
// restored alert
int alertHash = Objects.hash(CommonConstants.ALERT_PRIORITY_CODE_CRITICAL)
+ Arrays.hashCode(currentAlert.getTags().keySet().toArray(new String[0]))
+ Arrays.hashCode(currentAlert.getTags().values().toArray(new String[0]));
converageAlertMap.remove(alertHash);
alertHash = Objects.hash(CommonConstants.ALERT_PRIORITY_CODE_EMERGENCY)
+ Arrays.hashCode(currentAlert.getTags().keySet().toArray(new String[0]))
+ Arrays.hashCode(currentAlert.getTags().values().toArray(new String[0]));
converageAlertMap.remove(alertHash);
alertHash = Objects.hash(CommonConstants.ALERT_PRIORITY_CODE_WARNING)
+ Arrays.hashCode(currentAlert.getTags().keySet().toArray(new String[0]))
+ Arrays.hashCode(currentAlert.getTags().values().toArray(new String[0]));
converageAlertMap.remove(alertHash);
return true;
}
CommonCacheService<String, Object> convergeCache = CacheFactory.getAlertConvergeCache();
List<AlertConverge> alertConvergeList = (List<AlertConverge>) convergeCache.get(CommonConstants.CACHE_ALERT_CONVERGE);
if (alertConvergeList == null) {
alertConvergeList = alertConvergeDao.findAll();
// matchAll is in the last
alertConvergeList.sort((item1, item2) -> {
if (item1.isMatchAll()) {
return 1;
} else if (item2.isMatchAll()) {
return -1;
} else {
return 0;
}
});
convergeCache.put(CommonConstants.CACHE_ALERT_CONVERGE, alertConvergeList);
}
for (AlertConverge alertConverge : alertConvergeList) {
if (!alertConverge.isEnable()) {
continue;
}
boolean match = alertConverge.isMatchAll();
if (!match) {
List<TagItem> tags = alertConverge.getTags();
if (currentAlert.getTags() != null && !currentAlert.getTags().isEmpty()) {
Map<String, String> alertTagMap = currentAlert.getTags();
match = tags.stream().anyMatch(item -> {
if (alertTagMap.containsKey(item.getName())) {
String tagValue = alertTagMap.get(item.getName());
if (tagValue == null && item.getValue() == null) {
return true;
} else {
return tagValue != null && tagValue.equals(item.getValue());
}
} else {
return false;
}
});
} else {
match = true;
}
if (match && alertConverge.getPriorities() != null && !alertConverge.getPriorities().isEmpty()) {
match = alertConverge.getPriorities().stream().anyMatch(item -> item != null && item == currentAlert.getPriority());
}
}
if (match) {
long evalInterval = alertConverge.getEvalInterval() * 1000L;
long now = System.currentTimeMillis();
if (evalInterval <= 0) {
return true;
}
int alertHash = Objects.hash(currentAlert.getPriority())
+ Arrays.hashCode(currentAlert.getTags().keySet().toArray(new String[0]))
+ Arrays.hashCode(currentAlert.getTags().values().toArray(new String[0]));
Alert preAlert = converageAlertMap.get(alertHash);
if (preAlert == null) {
currentAlert.setTimes(1);
currentAlert.setFirstAlarmTime(now);
currentAlert.setLastAlarmTime(now);
converageAlertMap.put(alertHash, currentAlert.clone());
return true;
} else {
if (now - preAlert.getFirstAlarmTime() < evalInterval) {
preAlert.setTimes(preAlert.getTimes() + 1);
preAlert.setLastAlarmTime(now);
return false;
} else {
currentAlert.setTimes(preAlert.getTimes());
if (preAlert.getTimes() == 1) {
currentAlert.setFirstAlarmTime(now);
} else {
currentAlert.setFirstAlarmTime(preAlert.getFirstAlarmTime());
}
currentAlert.setLastAlarmTime(now);
preAlert.setFirstAlarmTime(now);
preAlert.setLastAlarmTime(now);
preAlert.setTimes(1);
return true;
}
}
}
}
return true;
}
}
@@ -1,120 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.hertzbeat.alert.reduce;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import lombok.RequiredArgsConstructor;
import org.apache.hertzbeat.alert.dao.AlertSilenceDao;
import org.apache.hertzbeat.common.cache.CacheFactory;
import org.apache.hertzbeat.common.cache.CommonCacheService;
import org.apache.hertzbeat.common.constants.CommonConstants;
import org.apache.hertzbeat.common.entity.alerter.Alert;
import org.apache.hertzbeat.common.entity.alerter.AlertSilence;
import org.apache.hertzbeat.common.entity.manager.TagItem;
import org.springframework.stereotype.Service;
/**
* silence alarm
*/
@Service
@RequiredArgsConstructor
public class AlarmSilenceReduce {
private final AlertSilenceDao alertSilenceDao;
/**
* alert silence filter data
* @param alert alert
* @return true when not filter
*/
@SuppressWarnings("unchecked")
public boolean filterSilence(Alert alert) {
CommonCacheService<String, Object> silenceCache = CacheFactory.getAlertSilenceCache();
List<AlertSilence> alertSilenceList = (List<AlertSilence>) silenceCache.get(CommonConstants.CACHE_ALERT_SILENCE);
if (alertSilenceList == null) {
alertSilenceList = alertSilenceDao.findAll();
silenceCache.put(CommonConstants.CACHE_ALERT_SILENCE, alertSilenceList);
}
for (AlertSilence alertSilence : alertSilenceList) {
if (!alertSilence.isEnable()) {
continue;
}
// if match the silence rule, return
boolean match = alertSilence.isMatchAll();
if (!match) {
List<TagItem> tags = alertSilence.getTags();
if (alert.getTags() != null && !alert.getTags().isEmpty()) {
Map<String, String> alertTagMap = alert.getTags();
match = tags.stream().anyMatch(item -> {
if (alertTagMap.containsKey(item.getName())) {
String tagValue = alertTagMap.get(item.getName());
if (tagValue == null && item.getValue() == null) {
return true;
} else {
return tagValue != null && tagValue.equals(item.getValue());
}
} else {
return false;
}
});
} else {
match = true;
}
if (match && alertSilence.getPriorities() != null && !alertSilence.getPriorities().isEmpty()) {
match = alertSilence.getPriorities().stream().anyMatch(item -> item != null && item == alert.getPriority());
}
}
if (match) {
LocalDateTime nowDate = LocalDateTime.now();
if (alertSilence.getType() == 0) {
// once time
boolean startMatch = alertSilence.getPeriodStart() == null || nowDate.isAfter(alertSilence.getPeriodStart().toLocalDateTime());
boolean endMatch = alertSilence.getPeriodEnd() == null || nowDate.isBefore(alertSilence.getPeriodEnd().toLocalDateTime());
if (startMatch && endMatch) {
int times = Optional.ofNullable(alertSilence.getTimes()).orElse(0);
alertSilence.setTimes(times + 1);
alertSilenceDao.save(alertSilence);
return false;
}
} else if (alertSilence.getType() == 1) {
// cyc time
int currentDayOfWeek = nowDate.toLocalDate().getDayOfWeek().getValue();
if (alertSilence.getDays() != null && !alertSilence.getDays().isEmpty()) {
boolean dayMatch = alertSilence.getDays().stream().anyMatch(item -> item == currentDayOfWeek);
if (dayMatch) {
LocalTime nowTime = nowDate.toLocalTime();
boolean startMatch = alertSilence.getPeriodStart() == null || nowTime.isAfter(alertSilence.getPeriodStart().toLocalTime());
boolean endMatch = alertSilence.getPeriodEnd() == null || nowTime.isBefore(alertSilence.getPeriodEnd().toLocalTime());
if (startMatch && endMatch) {
int times = Optional.ofNullable(alertSilence.getTimes()).orElse(0);
alertSilence.setTimes(times + 1);
alertSilenceDao.save(alertSilence);
return false;
}
}
}
}
}
}
return true;
}
}
@@ -1,75 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.hertzbeat.alert.service;
import java.util.Set;
import org.apache.hertzbeat.common.entity.alerter.AlertConverge;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.jpa.domain.Specification;
/**
* management interface service for alert converge
*/
public interface AlertConvergeService {
/**
* Verify the correctness of the request data parameters
* @param alertConverge AlertConverge
* @param isModify whether modify
* @throws IllegalArgumentException A checksum parameter error is thrown
*/
void validate(AlertConverge alertConverge, boolean isModify) throws IllegalArgumentException;
/**
* New AlertConverge
* @param alertConverge AlertConverge Entity
* @throws RuntimeException Added procedure exception throwing
*/
void addAlertConverge(AlertConverge alertConverge) throws RuntimeException;
/**
* Modifying an AlertConverge
* @param alertConverge Alarm definition Entity
* @throws RuntimeException Exception thrown during modification
*/
void modifyAlertConverge(AlertConverge alertConverge) throws RuntimeException;
/**
* Obtain AlertConverge information
* @param convergeId AlertConverge ID
* @return AlertConverge
* @throws RuntimeException An exception was thrown during the query
*/
AlertConverge getAlertConverge(long convergeId) throws RuntimeException;
/**
* Delete AlertConverge in batches
* @param convergeIds AlertConverge IDs
* @throws RuntimeException Exception thrown during deletion
*/
void deleteAlertConverges(Set<Long> convergeIds) throws RuntimeException;
/**
* Dynamic conditional query
* @param specification Query conditions
* @param pageRequest Paging parameters
* @return The query results
*/
Page<AlertConverge> getAlertConverges(Specification<AlertConverge> specification, PageRequest pageRequest);
}
@@ -1,144 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.hertzbeat.alert.service;
import jakarta.servlet.http.HttpServletResponse;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.apache.hertzbeat.common.entity.alerter.AlertDefine;
import org.apache.hertzbeat.common.entity.alerter.AlertDefineMonitorBind;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.web.multipart.MultipartFile;
/**
* Alarm define manager service
*/
public interface AlertDefineService {
/**
* Verify the correctness of the request data parameters
* @param alertDefine alertDefine
* @param isModify whether modify
* @throws IllegalArgumentException A checksum parameter error is thrown
*/
void validate(AlertDefine alertDefine, boolean isModify) throws IllegalArgumentException;
/**
* New Alarm Definition
* @param alertDefine Alarm definition Entity
* @throws RuntimeException Added procedure exception throwing
*/
void addAlertDefine(AlertDefine alertDefine) throws RuntimeException;
/**
* Modifying an Alarm Definition
* @param alertDefine Alarm definition Entity
* @throws RuntimeException Exception thrown during modification
*/
void modifyAlertDefine(AlertDefine alertDefine) throws RuntimeException;
/**
* Deleting an Alarm Definition
* @param alertId Alarm Definition ID
* @throws RuntimeException Exception thrown during deletion
*/
void deleteAlertDefine(long alertId) throws RuntimeException;
/**
* Obtain alarm definition information
* @param alertId Monitor the ID
* @return AlertDefine
* @throws RuntimeException An exception was thrown during the query
*/
AlertDefine getAlertDefine(long alertId) throws RuntimeException;
/**
* Delete alarm definitions in batches
* @param alertIds Alarm Definition IDs
* @throws RuntimeException Exception thrown during deletion
*/
void deleteAlertDefines(Set<Long> alertIds) throws RuntimeException;
/**
* Dynamic conditional query
* @param specification Query conditions
* @param pageRequest Paging parameters
* @return The query results
*/
Page<AlertDefine> getMonitorBindAlertDefines(Specification<AlertDefine> specification, PageRequest pageRequest);
/**
* Association between application alarm schedule and monitoring
* @param alertId Alarm Definition ID
* @param alertDefineBinds correlation
*/
void applyBindAlertDefineMonitors(Long alertId, List<AlertDefineMonitorBind> alertDefineBinds);
/**
* Query the alarm definitions that match the specified metrics associated with the monitoring ID
* @param monitorId Monitor the ID
* @param app Monitoring type
* @param metrics metrics
* @return field - define[]
*/
Map<String, List<AlertDefine>> getMonitorBindAlertDefines(long monitorId, String app, String metrics);
/**
* Query the alarm definitions that match the specified metrics associated with the monitoring ID
* @param monitorId Monitor the ID
* @param app Monitoring type
* @param metrics metrics
* @return field - define[]
*/
AlertDefine getMonitorBindAlertAvaDefine(long monitorId, String app, String metrics);
/**
* Dynamic conditional query
* @param specification Query conditions
* @param pageRequest Paging parameters
* @return The query results
*/
Page<AlertDefine> getAlertDefines(Specification<AlertDefine> specification, PageRequest pageRequest);
/**
* Query the associated monitoring list information based on the alarm definition ID
* @param alertDefineId Alarm Definition ID
* @return Associated information about the monitoring list
*/
List<AlertDefineMonitorBind> getBindAlertDefineMonitors(long alertDefineId);
/**
* Export file configuration of specified type based on ID list and export file type
* @param ids AlertDefine ID
* @param type File Type
* @param res Response
* @throws Exception An exception was thrown during the export
*/
void export(List<Long> ids, String type, HttpServletResponse res) throws Exception;
/**
* Add alarm threshold rules based on the uploaded alarm threshold file
* @param file Upload File
* @throws Exception An exception was thrown during the importConfig
*/
void importConfig(MultipartFile file) throws Exception;
}
@@ -1,85 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.hertzbeat.alert.service;
import java.util.HashSet;
import java.util.List;
import org.apache.hertzbeat.alert.dto.AlertSummary;
import org.apache.hertzbeat.common.entity.alerter.Alert;
import org.apache.hertzbeat.common.entity.dto.AlertReport;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.jpa.domain.Specification;
/**
* Alarm information management interface
*/
public interface AlertService {
/**
* Add alarm record
* @param alert Alert entity
* @throws RuntimeException Add process exception throw
*/
void addAlert(Alert alert) throws RuntimeException;
/**
* Dynamic conditional query
* @param specification Query conditions
* @param pageRequest pagination parameters
* @return search result
*/
Page<Alert> getAlerts(Specification<Alert> specification, PageRequest pageRequest);
/**
* Delete alarms in batches according to the alarm ID list
* @param ids Alarm ID List
*/
void deleteAlerts(HashSet<Long> ids);
/**
* Clear all alerts
*/
void clearAlerts();
/**
* Update the alarm status according to the alarm ID-status value
* @param status Alarm status to be modified
* @param ids Alarm ID List to be modified
*/
void editAlertStatus(Byte status, List<Long> ids);
/**
* Get alarm statistics information
* @return Alarm statistics information
*/
AlertSummary getAlertsSummary();
/**
* A third party reports an alarm
* @param alertReport The alarm information
*/
void addNewAlertReport(AlertReport alertReport);
/**
* Dynamic conditional query
* @param specification Query conditions
* @return search result
*/
List<Alert> getAlerts(Specification<Alert> specification);
}
@@ -1,83 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.hertzbeat.alert.service.impl;
import java.util.Set;
import lombok.extern.slf4j.Slf4j;
import org.apache.hertzbeat.alert.dao.AlertConvergeDao;
import org.apache.hertzbeat.alert.service.AlertConvergeService;
import org.apache.hertzbeat.common.cache.CacheFactory;
import org.apache.hertzbeat.common.cache.CommonCacheService;
import org.apache.hertzbeat.common.constants.CommonConstants;
import org.apache.hertzbeat.common.entity.alerter.AlertConverge;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
/**
* implement for alert converge service
*/
@Service
@Transactional(rollbackFor = Exception.class)
@Slf4j
public class AlertConvergeServiceImpl implements AlertConvergeService {
@Autowired
private AlertConvergeDao alertConvergeDao;
@Override
public void validate(AlertConverge alertConverge, boolean isModify) throws IllegalArgumentException {
// todo
}
@Override
public void addAlertConverge(AlertConverge alertConverge) throws RuntimeException {
alertConvergeDao.save(alertConverge);
clearAlertConvergesCache();
}
@Override
public void modifyAlertConverge(AlertConverge alertConverge) throws RuntimeException {
alertConvergeDao.save(alertConverge);
clearAlertConvergesCache();
}
@Override
public AlertConverge getAlertConverge(long convergeId) throws RuntimeException {
return alertConvergeDao.findById(convergeId).orElse(null);
}
@Override
public void deleteAlertConverges(Set<Long> convergeIds) throws RuntimeException {
alertConvergeDao.deleteAlertConvergesByIdIn(convergeIds);
clearAlertConvergesCache();
}
@Override
public Page<AlertConverge> getAlertConverges(Specification<AlertConverge> specification, PageRequest pageRequest) {
return alertConvergeDao.findAll(specification, pageRequest);
}
private void clearAlertConvergesCache() {
CommonCacheService<String, Object> convergeCache = CacheFactory.getAlertConvergeCache();
convergeCache.remove(CommonConstants.CACHE_ALERT_CONVERGE);
}
}
@@ -1,151 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.hertzbeat.alert.service.impl;
import cn.afterturn.easypoi.excel.annotation.Excel;
import cn.afterturn.easypoi.excel.annotation.ExcelTarget;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonInclude;
import jakarta.annotation.Resource;
import java.io.InputStream;
import java.io.OutputStream;
import java.time.LocalDate;
import java.util.List;
import java.util.stream.Collectors;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.apache.hertzbeat.alert.service.AlertDefineImExportService;
import org.apache.hertzbeat.alert.service.AlertDefineService;
import org.apache.hertzbeat.common.entity.alerter.AlertDefine;
import org.apache.hertzbeat.common.entity.manager.TagItem;
import org.springframework.beans.BeanUtils;
import org.springframework.context.annotation.Lazy;
import org.springframework.util.CollectionUtils;
/**
* Configuration Import Export
*/
@Slf4j
public abstract class AlertDefineAbstractImExportServiceImpl implements AlertDefineImExportService {
@Resource
@Lazy
private AlertDefineService alertDefineService;
@Override
public void importConfig(InputStream is) {
var formList = parseImport(is)
.stream()
.map(this::convert)
.collect(Collectors.toUnmodifiableList());
if (!CollectionUtils.isEmpty(formList)) {
formList.forEach(alertDefine -> {
alertDefineService.validate(alertDefine, false);
alertDefineService.addAlertDefine(alertDefine);
});
}
}
@Override
public void exportConfig(OutputStream os, List<Long> configList) {
var monitorList = configList.stream()
.map(it -> alertDefineService.getAlertDefine(it))
.map(this::convert)
.collect(Collectors.toUnmodifiableList());
writeOs(monitorList, os);
}
/**
* Parsing an input stream into a form
*
* @param is input stream
* @return form list
*/
abstract List<ExportAlertDefineDTO> parseImport(InputStream is);
/**
* Export Configuration to Output Stream
* @param exportAlertDefineList configuration list
* @param os output stream
*/
abstract void writeOs(List<ExportAlertDefineDTO> exportAlertDefineList, OutputStream os);
private ExportAlertDefineDTO convert(AlertDefine alertDefine) {
var exportAlertDefine = new ExportAlertDefineDTO();
var alertDefineDTO = new AlertDefineDTO();
BeanUtils.copyProperties(alertDefine, alertDefineDTO);
exportAlertDefine.setAlertDefine(alertDefineDTO);
return exportAlertDefine;
}
private AlertDefine convert(ExportAlertDefineDTO exportAlertDefineDTO) {
var alertDefine = new AlertDefine();
var alertDefineDTO = exportAlertDefineDTO.getAlertDefine();
BeanUtils.copyProperties(alertDefineDTO, alertDefine);
return alertDefine;
}
protected String fileNamePrefix() {
return "hertzbeat_alertDefine_" + LocalDate.now();
}
/**
* Export data transfer objects for alert configurations
*/
@Data
@JsonInclude(JsonInclude.Include.NON_NULL)
@JsonIgnoreProperties(ignoreUnknown = true)
@ExcelTarget(value = "ExportAlertDefineDTO")
protected static class ExportAlertDefineDTO {
@Excel(name = "AlertDefine")
private AlertDefineDTO alertDefine;
}
/**
* Data transfer object for alert configuration
*/
@Data
@JsonInclude(JsonInclude.Include.NON_NULL)
@JsonIgnoreProperties(ignoreUnknown = true)
@ExcelTarget(value = "AlertDefineDTO")
protected static class AlertDefineDTO {
@Excel(name = "App")
private String app;
@Excel(name = "Metric")
private String metric;
@Excel(name = "Field")
private String field;
@Excel(name = "Preset")
private Boolean preset;
@Excel(name = "Expr")
private String expr;
@Excel(name = "Priority")
private Byte priority;
@Excel(name = "Times")
private Integer times;
@Excel(name = "Tags")
private List<TagItem> tags;
@Excel(name = "Enable")
private Boolean enable;
@Excel(name = "RecoverNotice")
private Boolean recoverNotice;
@Excel(name = "Template")
private String template;
}
}
@@ -1,265 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.hertzbeat.alert.service.impl;
import com.fasterxml.jackson.core.type.TypeReference;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import lombok.extern.slf4j.Slf4j;
import org.apache.hertzbeat.common.entity.manager.TagItem;
import org.apache.hertzbeat.common.util.JsonUtil;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.CellStyle;
import org.apache.poi.ss.usermodel.CellType;
import org.apache.poi.ss.usermodel.Font;
import org.apache.poi.ss.usermodel.HorizontalAlignment;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.ss.usermodel.WorkbookFactory;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
/**
* Configure the import and export EXCEL format
*/
@Slf4j
@Service
public class AlertDefineExcelImExportServiceImpl extends AlertDefineAbstractImExportServiceImpl {
public static final String TYPE = "EXCEL";
public static final String FILE_SUFFIX = ".xlsx";
/**
* Export file type
* @return file type
*/
@Override
public String type() {
return TYPE;
}
/**
* Get Export File Name
* @return file name
*/
@Override
public String getFileName() {
return fileNamePrefix() + FILE_SUFFIX;
}
/**
* Parsing an input stream into a form
* @param is input stream
* @return form list
*/
@Override
List<ExportAlertDefineDTO> parseImport(InputStream is) {
try (Workbook workbook = WorkbookFactory.create(is)) {
Sheet sheet = workbook.getSheetAt(0);
List<ExportAlertDefineDTO> alertDefines = new ArrayList<>();
for (Row row : sheet) {
if (row.getRowNum() == 0) {
continue;
}
String app = getCellValueAsString(row.getCell(0));
if (StringUtils.hasText(app)) {
AlertDefineDTO alertDefineDTO = extractAlertDefineDataFromRow(row);
ExportAlertDefineDTO exportAlertDefineDTO = new ExportAlertDefineDTO();
exportAlertDefineDTO.setAlertDefine(alertDefineDTO);
alertDefines.add(exportAlertDefineDTO);
}
}
return alertDefines;
} catch (IOException e) {
throw new RuntimeException("Failed to parse alertDefine data", e);
}
}
private TagItem extractTagDataFromRow(Row row) {
String name = getCellValueAsString(row.getCell(7));
if (StringUtils.hasText(name)) {
TagItem tagItem = new TagItem();
tagItem.setName(name);
tagItem.setValue(getCellValueAsString(row.getCell(8)));
return tagItem;
}
return null;
}
private List<TagItem> extractTagDataFromRow(Cell cell) {
String jsonStr = getCellValueAsString(cell);
if (StringUtils.hasText(jsonStr)) {
return JsonUtil.fromJson(jsonStr, new TypeReference<>() {
});
}
return null;
}
private String getCellValueAsString(Cell cell) {
if (cell == null) {
return null;
}
return switch (cell.getCellType()) {
case STRING -> cell.getStringCellValue();
case NUMERIC -> String.valueOf(cell.getNumericCellValue());
default -> null;
};
}
private boolean getCellValueAsBoolean(Cell cell) {
if (cell == null) {
return false;
}
if (Objects.requireNonNull(cell.getCellType()) == CellType.BOOLEAN) {
return cell.getBooleanCellValue();
}
return false;
}
private Integer getCellValueAsInteger(Cell cell) {
if (cell == null) {
return null;
}
if (Objects.requireNonNull(cell.getCellType()) == CellType.NUMERIC) {
return (int) cell.getNumericCellValue();
}
return null;
}
private Byte getCellValueAsByte(Cell cell) {
if (cell == null) {
return null;
}
if (Objects.requireNonNull(cell.getCellType()) == CellType.NUMERIC) {
return (byte) cell.getNumericCellValue();
}
return null;
}
private AlertDefineDTO extractAlertDefineDataFromRow(Row row) {
AlertDefineDTO alertDefineDTO = new AlertDefineDTO();
alertDefineDTO.setApp(getCellValueAsString(row.getCell(0)));
alertDefineDTO.setMetric(getCellValueAsString(row.getCell(1)));
alertDefineDTO.setField(getCellValueAsString(row.getCell(2)));
alertDefineDTO.setPreset(getCellValueAsBoolean(row.getCell(3)));
alertDefineDTO.setExpr(getCellValueAsString(row.getCell(4)));
alertDefineDTO.setPriority(getCellValueAsByte(row.getCell(5)));
alertDefineDTO.setTimes(getCellValueAsInteger(row.getCell(6)));
alertDefineDTO.setTags(extractTagDataFromRow(row.getCell(7)));
alertDefineDTO.setEnable(getCellValueAsBoolean(row.getCell(8)));
alertDefineDTO.setRecoverNotice(getCellValueAsBoolean(row.getCell(9)));
alertDefineDTO.setTemplate(getCellValueAsString(row.getCell(10)));
return alertDefineDTO;
}
/**
* Export Configuration to Output Stream
* @param exportAlertDefineList exportAlertDefineList
* @param os output stream
*/
@Override
void writeOs(List<ExportAlertDefineDTO> exportAlertDefineList, OutputStream os) {
try {
Workbook workbook = WorkbookFactory.create(true);
String sheetName = "Export AlertDefine";
Sheet sheet = workbook.createSheet(sheetName);
sheet.setDefaultColumnWidth(20);
sheet.setColumnWidth(9, 40 * 256);
sheet.setColumnWidth(10, 40 * 256);
// set header style
CellStyle headerCellStyle = workbook.createCellStyle();
Font headerFont = workbook.createFont();
headerFont.setBold(true);
headerCellStyle.setFont(headerFont);
headerCellStyle.setAlignment(HorizontalAlignment.CENTER);
// set cell style
CellStyle cellStyle = workbook.createCellStyle();
cellStyle.setAlignment(HorizontalAlignment.CENTER);
// set header
String[] headers = {"app", "metric", "field", "preset", "expr", "priority", "times", "tags",
"enable", "recoverNotice", "template"};
Row headerRow = sheet.createRow(0);
for (int i = 0; i < headers.length; i++) {
Cell cell = headerRow.createCell(i);
cell.setCellValue(headers[i]);
cell.setCellStyle(headerCellStyle);
}
// Traverse the threshold rule list, each threshold rule object corresponds to a row of data
int rowIndex = 1;
for (ExportAlertDefineDTO alertDefine : exportAlertDefineList) {
AlertDefineDTO alertDefineDTO = alertDefine.getAlertDefine();
Row row = sheet.createRow(rowIndex++);
// Threshold rule information only needs to be written once
Cell appCell = row.createCell(0);
appCell.setCellValue(alertDefineDTO.getApp());
appCell.setCellStyle(cellStyle);
Cell metricCell = row.createCell(1);
metricCell.setCellValue(alertDefineDTO.getMetric());
metricCell.setCellStyle(cellStyle);
Cell fieldCell = row.createCell(2);
fieldCell.setCellValue(alertDefineDTO.getField());
fieldCell.setCellStyle(cellStyle);
Cell presetCell = row.createCell(3);
presetCell.setCellValue(alertDefineDTO.getPreset() != null
&& alertDefineDTO.getPreset());
presetCell.setCellStyle(cellStyle);
Cell exprCell = row.createCell(4);
exprCell.setCellValue(alertDefineDTO.getExpr());
exprCell.setCellStyle(cellStyle);
Cell priorityCell = row.createCell(5);
priorityCell.setCellValue(alertDefineDTO.getPriority());
priorityCell.setCellStyle(cellStyle);
Cell timesCell = row.createCell(6);
timesCell.setCellValue(alertDefineDTO.getTimes());
Cell tagCell = row.createCell(7);
// get tags
List<TagItem> tagList = alertDefineDTO.getTags();
String tagValue = tagList == null || tagList.isEmpty() ? "" : JsonUtil.toJson(tagList);
tagCell.setCellValue(tagValue);
tagCell.setCellStyle(cellStyle);
Cell enableCell = row.createCell(8);
enableCell.setCellValue(alertDefineDTO.getEnable() != null
&& alertDefineDTO.getEnable());
enableCell.setCellStyle(cellStyle);
Cell recoverNoticeCell = row.createCell(9);
recoverNoticeCell.setCellValue(alertDefineDTO.getRecoverNotice() != null
&& alertDefineDTO.getRecoverNotice());
recoverNoticeCell.setCellStyle(cellStyle);
Cell templateCell = row.createCell(10);
templateCell.setCellValue(alertDefineDTO.getTemplate());
recoverNoticeCell.setCellStyle(cellStyle);
}
workbook.write(os);
os.close();
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}
@@ -1,72 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.hertzbeat.alert.service.impl;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.List;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
/**
* Configure the import and export JSON format
*/
@Slf4j
@RequiredArgsConstructor
@Service
public class AlertDefineJsonImExportServiceImpl extends AlertDefineAbstractImExportServiceImpl {
public static final String TYPE = "JSON";
public static final String FILE_SUFFIX = ".json";
private final ObjectMapper objectMapper;
@Override
public String type() {
return TYPE;
}
@Override
public String getFileName() {
return fileNamePrefix() + FILE_SUFFIX;
}
@Override
List<ExportAlertDefineDTO> parseImport(InputStream is) {
try {
return objectMapper.readValue(is, new TypeReference<>() {
});
} catch (IOException ex) {
log.error("import alertDefine failed.", ex);
throw new RuntimeException("import alertDefine failed");
}
}
@Override
void writeOs(List<ExportAlertDefineDTO> exportAlertDefineList, OutputStream os) {
try {
objectMapper.writeValue(os, exportAlertDefineList);
} catch (IOException ex) {
log.error("export alertDefine failed.", ex);
throw new RuntimeException("export alertDefine failed");
}
}
}
@@ -1,189 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.hertzbeat.alert.service.impl;
import jakarta.servlet.http.HttpServletResponse;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
import java.util.stream.Collectors;
import lombok.extern.slf4j.Slf4j;
import org.apache.hertzbeat.alert.dao.AlertDefineBindDao;
import org.apache.hertzbeat.alert.dao.AlertDefineDao;
import org.apache.hertzbeat.alert.service.AlertDefineImExportService;
import org.apache.hertzbeat.alert.service.AlertDefineService;
import org.apache.hertzbeat.common.entity.alerter.AlertDefine;
import org.apache.hertzbeat.common.entity.alerter.AlertDefineMonitorBind;
import org.apache.hertzbeat.common.util.JexlExpressionRunner;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.http.HttpHeaders;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;
import org.springframework.web.multipart.MultipartFile;
/**
* Alarm definition management interface implementation
*/
@Service
@Transactional(rollbackFor = Exception.class)
@Slf4j
public class AlertDefineServiceImpl implements AlertDefineService {
@Autowired
private AlertDefineDao alertDefineDao;
@Autowired
private AlertDefineBindDao alertDefineBindDao;
private final Map<String, AlertDefineImExportService> alertDefineImExportServiceMap = new HashMap<>();
public AlertDefineServiceImpl(List<AlertDefineImExportService> alertDefineImExportServiceList) {
alertDefineImExportServiceList.forEach(it -> alertDefineImExportServiceMap.put(it.type(), it));
}
@Override
public void validate(AlertDefine alertDefine, boolean isModify) throws IllegalArgumentException {
// todo
if (StringUtils.hasText(alertDefine.getExpr())) {
try {
JexlExpressionRunner.compile(alertDefine.getExpr());
} catch (Exception e) {
throw new IllegalArgumentException("alert expr error: " + e.getMessage());
}
}
}
@Override
public void addAlertDefine(AlertDefine alertDefine) throws RuntimeException {
alertDefineDao.save(alertDefine);
}
@Override
public void modifyAlertDefine(AlertDefine alertDefine) throws RuntimeException {
alertDefineDao.save(alertDefine);
}
@Override
public void deleteAlertDefine(long alertId) throws RuntimeException {
alertDefineDao.deleteById(alertId);
}
@Override
public AlertDefine getAlertDefine(long alertId) throws RuntimeException {
Optional<AlertDefine> optional = alertDefineDao.findById(alertId);
return optional.orElse(null);
}
@Override
public void deleteAlertDefines(Set<Long> alertIds) throws RuntimeException {
alertDefineDao.deleteAlertDefinesByIdIn(alertIds);
}
@Override
public Page<AlertDefine> getMonitorBindAlertDefines(Specification<AlertDefine> specification, PageRequest pageRequest) {
return alertDefineDao.findAll(specification, pageRequest);
}
@Override
public void applyBindAlertDefineMonitors(Long alertId, List<AlertDefineMonitorBind> alertDefineBinds) {
// todo checks whether the alarm definition and monitoring exist
if (!alertDefineBindDao.existsById(alertId)){
alertDefineBindDao.deleteAlertDefineBindsByAlertDefineIdEquals(alertId);
}
// Delete all associations of this alarm
alertDefineBindDao.deleteAlertDefineBindsByAlertDefineIdEquals(alertId);
// Save the associated
alertDefineBindDao.saveAll(alertDefineBinds);
}
@Override
public Map<String, List<AlertDefine>> getMonitorBindAlertDefines(long monitorId, String app, String metrics) {
List<AlertDefine> defines = alertDefineDao.queryAlertDefinesByMonitor(monitorId, app, metrics);
List<AlertDefine> defaultDefines = alertDefineDao.queryAlertDefinesByAppAndMetricAndPresetTrueAndEnableTrue(app, metrics);
defines.addAll(defaultDefines);
Set<AlertDefine> defineSet = defines.stream().filter(item -> item.getField() != null).collect(Collectors.toSet());
// The alarm thresholds are defined in ascending order of the alarm severity from 0 to 3.
// The lower the number, the higher the alarm is. That is, the alarm is calculated from the highest alarm threshold
return defineSet.stream().sorted(Comparator.comparing(AlertDefine::getPriority))
.collect(Collectors.groupingBy(AlertDefine::getField));
}
@Override
public AlertDefine getMonitorBindAlertAvaDefine(long monitorId, String app, String metrics) {
List<AlertDefine> defines = alertDefineDao.queryAlertDefinesByMonitor(monitorId, app, metrics);
List<AlertDefine> defaultDefines = alertDefineDao.queryAlertDefinesByAppAndMetricAndPresetTrueAndEnableTrue(app, metrics);
defines.addAll(defaultDefines);
return defines.stream().findFirst().orElse(null);
}
@Override
public Page<AlertDefine> getAlertDefines(Specification<AlertDefine> specification, PageRequest pageRequest) {
return alertDefineDao.findAll(specification, pageRequest);
}
@Override
public List<AlertDefineMonitorBind> getBindAlertDefineMonitors(long alertDefineId) {
return alertDefineBindDao.getAlertDefineBindsByAlertDefineIdEquals(alertDefineId);
}
@Override
public void export(List<Long> ids, String type, HttpServletResponse res) throws Exception {
var imExportService = alertDefineImExportServiceMap.get(type);
if (imExportService == null) {
throw new IllegalArgumentException("not support export type: " + type);
}
var fileName = imExportService.getFileName();
res.setHeader("content-type", "application/octet-stream;charset=UTF-8");
res.setContentType("application/octet-stream;charset=UTF-8");
res.setHeader(HttpHeaders.CONTENT_DISPOSITION, "attachment;filename=" + URLEncoder.encode(fileName, StandardCharsets.UTF_8));
res.setHeader("Access-Control-Expose-Headers", "Content-Disposition");
imExportService.exportConfig(res.getOutputStream(), ids);
}
@Override
public void importConfig(MultipartFile file) throws Exception {
var fileName = file.getOriginalFilename();
if (!StringUtils.hasText(fileName)) {
return;
}
var type = "";
if (fileName.toLowerCase().endsWith(AlertDefineJsonImExportServiceImpl.FILE_SUFFIX)) {
type = AlertDefineJsonImExportServiceImpl.TYPE;
}
if (fileName.toLowerCase().endsWith(AlertDefineExcelImExportServiceImpl.FILE_SUFFIX)) {
type = AlertDefineExcelImExportServiceImpl.TYPE;
}
if (fileName.toLowerCase().endsWith(AlertDefineYamlImExportServiceImpl.FILE_SUFFIX)) {
type = AlertDefineYamlImExportServiceImpl.TYPE;
}
if (!alertDefineImExportServiceMap.containsKey(type)) {
throw new RuntimeException("file " + fileName + " is not supported.");
}
var imExportService = alertDefineImExportServiceMap.get(type);
imExportService.importConfig(file.getInputStream());
}
}
@@ -1,65 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.hertzbeat.alert.service.impl;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.nio.charset.StandardCharsets;
import java.util.List;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.yaml.snakeyaml.DumperOptions;
import org.yaml.snakeyaml.Yaml;
/**
* Configure the import and export Yaml format
*/
@Slf4j
@Service
public class AlertDefineYamlImExportServiceImpl extends AlertDefineAbstractImExportServiceImpl {
public static final String TYPE = "YAML";
public static final String FILE_SUFFIX = ".yaml";
@Override
public String type() {
return TYPE;
}
@Override
public String getFileName() {
return fileNamePrefix() + FILE_SUFFIX;
}
@Override
List<ExportAlertDefineDTO> parseImport(InputStream is) {
Yaml yaml = new Yaml();
return yaml.load(is);
}
@Override
void writeOs(List<ExportAlertDefineDTO> exportAlertDefineList, OutputStream os) {
DumperOptions options = new DumperOptions();
options.setDefaultFlowStyle(DumperOptions.FlowStyle.BLOCK);
options.setIndent(2);
options.setPrettyFlow(true);
Yaml yaml = new Yaml(options);
yaml.dump(exportAlertDefineList, new OutputStreamWriter(os, StandardCharsets.UTF_8));
}
}
@@ -1,161 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.hertzbeat.alert.service.impl;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.Instant;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import lombok.extern.slf4j.Slf4j;
import org.apache.hertzbeat.alert.dao.AlertDao;
import org.apache.hertzbeat.alert.dto.AlertPriorityNum;
import org.apache.hertzbeat.alert.dto.AlertSummary;
import org.apache.hertzbeat.alert.reduce.AlarmCommonReduce;
import org.apache.hertzbeat.alert.service.AlertService;
import org.apache.hertzbeat.common.constants.CommonConstants;
import org.apache.hertzbeat.common.entity.alerter.Alert;
import org.apache.hertzbeat.common.entity.dto.AlertReport;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
/**
* Realization of Alarm Information Service
*/
@Service
@Transactional(rollbackFor = Exception.class)
@Slf4j
public class AlertServiceImpl implements AlertService {
@Autowired
private AlertDao alertDao;
@Autowired
private AlarmCommonReduce alarmCommonReduce;
@Override
public void addAlert(Alert alert) throws RuntimeException {
alertDao.save(alert);
}
@Override
public Page<Alert> getAlerts(Specification<Alert> specification, PageRequest pageRequest) {
return alertDao.findAll(specification, pageRequest);
}
@Override
public void deleteAlerts(HashSet<Long> ids) {
alertDao.deleteAlertsByIdIn(ids);
}
@Override
public void clearAlerts() {
alertDao.deleteAll();
}
@Override
public void editAlertStatus(Byte status, List<Long> ids) {
alertDao.updateAlertsStatus(status, ids);
}
@Override
public AlertSummary getAlertsSummary() {
AlertSummary alertSummary = new AlertSummary();
// Statistics on the alarm information in the alarm state
List<AlertPriorityNum> priorityNums = alertDao.findAlertPriorityNum();
if (priorityNums != null) {
for (AlertPriorityNum priorityNum : priorityNums) {
switch (priorityNum.getPriority()) {
case CommonConstants
.ALERT_PRIORITY_CODE_WARNING -> alertSummary.setPriorityWarningNum(priorityNum.getNum());
case CommonConstants.ALERT_PRIORITY_CODE_CRITICAL -> alertSummary.setPriorityCriticalNum(priorityNum.getNum());
case CommonConstants.ALERT_PRIORITY_CODE_EMERGENCY -> alertSummary.setPriorityEmergencyNum(priorityNum.getNum());
default -> {}
}
}
}
long total = alertDao.count();
alertSummary.setTotal(total);
long dealNum = total - alertSummary.getPriorityCriticalNum()
- alertSummary.getPriorityEmergencyNum() - alertSummary.getPriorityWarningNum();
alertSummary.setDealNum(dealNum);
try {
if (total == 0) {
alertSummary.setRate(100);
} else {
float rate = BigDecimal.valueOf(100 * (float) dealNum / total)
.setScale(2, RoundingMode.HALF_UP)
.floatValue();
alertSummary.setRate(rate);
}
} catch (Exception e) {
log.error(e.getMessage(), e);
}
return alertSummary;
}
@Override
public void addNewAlertReport(AlertReport alertReport) {
alarmCommonReduce.reduceAndSendAlarm(buildAlertData(alertReport));
}
@Override
public List<Alert> getAlerts(Specification<Alert> specification) {
return alertDao.findAll(specification);
}
/**
* The external alarm information is converted to Alert
* @param alertReport alarm body
* @return Alert entity
*/
private Alert buildAlertData(AlertReport alertReport){
Map<String, String> annotations = alertReport.getAnnotations();
StringBuilder sb = new StringBuilder();
if (alertReport.getContent() == null || alertReport.getContent().length() <= 0){
StringBuilder finalSb = sb;
annotations.forEach((k, v) -> {
finalSb.append(k).append(":").append(v).append("\n");
});
} else {
sb = new StringBuilder(alertReport.getContent());
}
LocalDateTime dateTime = LocalDateTime.ofInstant(Instant.ofEpochMilli(alertReport.getAlertTime()),
ZoneId.systemDefault());
return Alert.builder()
.content("Alert Center\n" + sb)
.priority(alertReport.getPriority().byteValue())
.status(CommonConstants.ALERT_STATUS_CODE_PENDING)
.tags(alertReport.getLabels())
.target(alertReport.getAlertName())
.triggerTimes(1)
.firstAlarmTime(alertReport.getAlertTime())
.lastAlarmTime(alertReport.getAlertTime())
.gmtCreate(dateTime)
.gmtUpdate(dateTime)
.build();
}
}
@@ -1,88 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.hertzbeat.alert.service.impl;
import java.util.Arrays;
import java.util.Set;
import lombok.extern.slf4j.Slf4j;
import org.apache.hertzbeat.alert.dao.AlertSilenceDao;
import org.apache.hertzbeat.alert.service.AlertSilenceService;
import org.apache.hertzbeat.common.cache.CacheFactory;
import org.apache.hertzbeat.common.cache.CommonCacheService;
import org.apache.hertzbeat.common.constants.CommonConstants;
import org.apache.hertzbeat.common.entity.alerter.AlertSilence;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
/**
* management interface service implement for alert silence
*/
@Service
@Transactional(rollbackFor = Exception.class)
@Slf4j
public class AlertSilenceServiceImpl implements AlertSilenceService {
@Autowired
private AlertSilenceDao alertSilenceDao;
@Override
public void validate(AlertSilence alertSilence, boolean isModify) throws IllegalArgumentException {
// todo
// if the alarm silent selection date set in periodic situations is empty, it will be deemed to be all checked.
if (alertSilence.getType() == 1 && alertSilence.getDays() == null) {
alertSilence.setDays(Arrays.asList((byte) 7, (byte) 1, (byte) 2, (byte) 3, (byte) 4, (byte) 5, (byte) 6));
}
}
@Override
public void addAlertSilence(AlertSilence alertSilence) throws RuntimeException {
alertSilenceDao.save(alertSilence);
clearAlertSilencesCache();
}
@Override
public void modifyAlertSilence(AlertSilence alertSilence) throws RuntimeException {
alertSilenceDao.save(alertSilence);
clearAlertSilencesCache();
}
@Override
public AlertSilence getAlertSilence(long silenceId) throws RuntimeException {
return alertSilenceDao.findById(silenceId).orElse(null);
}
@Override
public void deleteAlertSilences(Set<Long> silenceIds) throws RuntimeException {
alertSilenceDao.deleteAlertSilencesByIdIn(silenceIds);
clearAlertSilencesCache();
}
@Override
public Page<AlertSilence> getAlertSilences(Specification<AlertSilence> specification, PageRequest pageRequest) {
return alertSilenceDao.findAll(specification, pageRequest);
}
private void clearAlertSilencesCache() {
CommonCacheService<String, Object> silenceCache = CacheFactory.getAlertSilenceCache();
silenceCache.remove(CommonConstants.CACHE_ALERT_SILENCE);
}
}
@@ -1,63 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.hertzbeat.alert.util;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import lombok.extern.slf4j.Slf4j;
/**
* Alarm template keyword matching replacement engine tool
*/
@Slf4j
public final class AlertTemplateUtil {
private AlertTemplateUtil() {
}
/**
* Match the variable ${key}
* eg: Alert, the instance: ${instance} metrics: ${metrics} is over flow.
*/
private static final Pattern PATTERN = Pattern.compile("\\$\\{(\\w+)\\}");
public static String render(String template, Map<String, Object> replaceData) {
if (template == null) {
return null;
}
if (replaceData == null) {
log.warn("The replaceData is null.");
return template;
}
try {
Matcher matcher = PATTERN.matcher(template);
StringBuilder builder = new StringBuilder();
while (matcher.find()) {
Object objectValue = replaceData.getOrDefault(matcher.group(1), "NullValue");
String value = objectValue.toString();
matcher.appendReplacement(builder, Matcher.quoteReplacement(value));
}
matcher.appendTail(builder);
return builder.toString();
} catch (Exception e) {
log.error(e.getMessage(), e);
return template;
}
}
}
@@ -1,17 +0,0 @@
# Licensed to the Apache Software Foundation (ASF) under one or more
# contributor license agreements. See the NOTICE file distributed with
# this work for additional information regarding copyright ownership.
# The ASF licenses this file to You under the Apache License, Version 2.0
# (the "License"); you may not use this file except in compliance with
# the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
org.apache.hertzbeat.alert.config.AlerterAutoConfiguration
@@ -1,32 +0,0 @@
# Licensed to the Apache Software Foundation (ASF) under one or more
# contributor license agreements. See the NOTICE file distributed with
# this work for additional information regarding copyright ownership.
# The ASF licenses this file to You under the Apache License, Version 2.0
# (the "License"); you may not use this file except in compliance with
# the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
alerter.availability.recover = Availability Alert Resolved, Monitor Status Normal Now
alerter.alarm.recover = Alert Resolved Notice
alerter.notify.title = HertzBeat Alert Notify
alerter.notify.target = Monitor Target
alerter.notify.monitorId = Monitor ID
alerter.notify.monitorName = Monitor Name
alerter.notify.monitorHost = Monitor Host
alerter.notify.priority = Alert Priority
alerter.notify.triggerTime = Alert Trigger Time
alerter.notify.restoreTime = Alert Restore Time
alerter.notify.times = Alert Trigger Times
alerter.notify.tags = Alert Labels
alerter.notify.content = Alert Content
alerter.notify.console = Console Login
alerter.priority.0 = Emergency Alert
alerter.priority.1 = Critical Alert
alerter.priority.2 = Warning Alert
@@ -1,55 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.hertzbeat.alert;
import static org.junit.jupiter.api.Assertions.assertEquals;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.atomic.AtomicInteger;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
/**
* Test case for {@link AlerterWorkerPool}
*/
class AlerterWorkerPoolTest {
private static final int NUMBER_OF_THREADS = 10;
private AlerterWorkerPool pool;
private AtomicInteger counter;
private CountDownLatch latch;
@BeforeEach
void setUp() {
pool = new AlerterWorkerPool();
counter = new AtomicInteger();
latch = new CountDownLatch(NUMBER_OF_THREADS);
}
@Test
void executeJob() throws InterruptedException {
for (int i = 0; i < NUMBER_OF_THREADS; i++) {
pool.executeJob(() -> {
counter.incrementAndGet();
latch.countDown();
});
}
latch.await();
assertEquals(NUMBER_OF_THREADS, counter.get());
}
}
@@ -1,171 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.hertzbeat.alert.controller;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
import java.util.Collections;
import java.util.List;
import org.apache.hertzbeat.alert.service.impl.AlertDefineServiceImpl;
import org.apache.hertzbeat.common.constants.CommonConstants;
import org.apache.hertzbeat.common.entity.alerter.AlertDefine;
import org.apache.hertzbeat.common.entity.alerter.AlertDefineMonitorBind;
import org.apache.hertzbeat.common.entity.manager.Monitor;
import org.apache.hertzbeat.common.util.JsonUtil;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.Mockito;
import org.mockito.junit.jupiter.MockitoExtension;
import org.springframework.http.MediaType;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
/**
* Test case for {@link AlertDefineController}
*/
@ExtendWith(MockitoExtension.class)
class AlertDefineControllerTest {
private MockMvc mockMvc;
private AlertDefine alertDefine;
private List<AlertDefineMonitorBind> alertDefineMonitorBinds;
@Mock
private AlertDefineServiceImpl alertDefineService;
@InjectMocks
private AlertDefineController alertDefineController;
@BeforeEach
void setUp() {
// standaloneSetup: Standalone setup, not integrated with a web environment for testing
this.mockMvc = MockMvcBuilders.standaloneSetup(alertDefineController).build();
this.alertDefine = AlertDefine.builder()
.id(1L)
.app("app")
.metric("test")
.field("test")
.preset(false)
.expr("1 > 0")
.priority((byte) 1)
.times(1)
.template("template")
.creator("tom")
.modifier("tom")
.build();
this.alertDefineMonitorBinds = Collections.singletonList(
AlertDefineMonitorBind.builder()
.id(1L)
.alertDefineId(this.alertDefine.getId())
.monitorId(1L)
.monitor(
Monitor.builder()
.id(1L)
.app("app")
.host("localhost")
.name("monitor")
.build()
)
.build()
);
}
@Test
void addNewAlertDefine() throws Exception {
// Simulate the client sending a request to the server
mockMvc.perform(MockMvcRequestBuilders.post("/api/alert/define")
.contentType(MediaType.APPLICATION_JSON)
.content(JsonUtil.toJson(this.alertDefine)))
.andExpect(status().isOk())
.andExpect(jsonPath("$.code").value((int) CommonConstants.SUCCESS_CODE))
.andReturn();
}
@Test
void modifyAlertDefine() throws Exception {
mockMvc.perform(MockMvcRequestBuilders.put("/api/alert/define")
.contentType(MediaType.APPLICATION_JSON)
.content(JsonUtil.toJson(this.alertDefine)))
.andExpect(status().isOk())
.andExpect(jsonPath("$.code").value((int) CommonConstants.SUCCESS_CODE))
.andReturn();
}
@Test
void getAlertDefine() throws Exception {
// Simulate returning data from getAlertDefine
Mockito.when(alertDefineService.getAlertDefine(this.alertDefine.getId()))
.thenReturn(this.alertDefine);
mockMvc.perform(MockMvcRequestBuilders.get("/api/alert/define/" + this.alertDefine.getId())
.contentType(MediaType.APPLICATION_JSON))
.andExpect(status().isOk())
.andExpect(jsonPath("$.code").value((int) CommonConstants.SUCCESS_CODE))
.andExpect(jsonPath("$.data.id").value(alertDefine.getId()))
.andExpect(jsonPath("$.data.app").value(alertDefine.getApp()))
.andExpect(jsonPath("$.data.metric").value(alertDefine.getMetric()))
.andExpect(jsonPath("$.data.field").value(alertDefine.getField()))
.andExpect(jsonPath("$.data.expr").value(alertDefine.getExpr()))
.andExpect(jsonPath("$.data.template").value(alertDefine.getTemplate()))
.andExpect(jsonPath("$.data.gmtCreate").value(alertDefine.getGmtCreate()))
.andExpect(jsonPath("$.data.gmtUpdate").value(alertDefine.getGmtUpdate()))
.andReturn();
}
@Test
void deleteAlertDefine() throws Exception {
mockMvc.perform(MockMvcRequestBuilders.delete("/api/alert/define/" + this.alertDefine.getId())
.contentType(MediaType.APPLICATION_JSON)
.content(JsonUtil.toJson(this.alertDefine)))
.andExpect(status().isOk())
.andExpect(jsonPath("$.code").value((int) CommonConstants.SUCCESS_CODE))
.andReturn();
}
@Test
void applyAlertDefineMonitorsBind() throws Exception {
mockMvc.perform(MockMvcRequestBuilders.post("/api/alert/define/" + this.alertDefine.getId() + "/monitors")
.contentType(MediaType.APPLICATION_JSON)
.content(JsonUtil.toJson(this.alertDefineMonitorBinds)))
.andExpect(status().isOk())
.andExpect(jsonPath("$.code").value((int) CommonConstants.SUCCESS_CODE))
.andReturn();
}
@Test
void getAlertDefineMonitorsBind() throws Exception {
Mockito.when(alertDefineService.getBindAlertDefineMonitors(this.alertDefine.getId()))
.thenReturn(this.alertDefineMonitorBinds);
mockMvc.perform(MockMvcRequestBuilders.get("/api/alert/define/" + this.alertDefine.getId() + "/monitors")
.contentType(MediaType.APPLICATION_JSON))
.andExpect(status().isOk())
.andExpect(jsonPath("$.code").value((int) CommonConstants.SUCCESS_CODE))
.andExpect(jsonPath("$.data[0].id").value(alertDefineMonitorBinds.get(0).getId()))
.andExpect(jsonPath("$.data[0].monitor.id").value(alertDefineMonitorBinds.get(0).getMonitor().getId()))
.andReturn();
}
}
@@ -1,151 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.hertzbeat.alert.controller;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import org.apache.hertzbeat.alert.service.AlertDefineService;
import org.apache.hertzbeat.common.constants.CommonConstants;
import org.apache.hertzbeat.common.entity.alerter.AlertDefine;
import org.apache.hertzbeat.common.util.JsonUtil;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.Mockito;
import org.mockito.junit.jupiter.MockitoExtension;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
import org.springframework.http.MediaType;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
/**
* Test case for {@link AlertDefinesController}
* Test whether the data mocked at the mock is correct, and test whether the format of the returned data is correct
*/
@ExtendWith(MockitoExtension.class)
class AlertDefinesControllerTest {
private MockMvc mockMvc;
@InjectMocks
private AlertDefinesController alertDefinesController;
@Mock
AlertDefineService alertDefineService;
// Parameters to avoid default values interference, default values have been replaced
List<Long> ids = Stream.of(6565463543L, 6565463544L).collect(Collectors.toList());
Byte priority = Byte.parseByte("1");
String sort = "gmtCreate";
String order = "asc";
Integer pageIndex = 1;
Integer pageSize = 7;
// Parameter collection
Map<String, Object> content = new HashMap<>();
// Object for mock
PageRequest pageRequest;
// Since the specification is used in dynamic proxy, it cannot be mocked
// Missing debugging parameters are ids, priority
// The missing part has been manually output for testing
@BeforeEach
void setUp() {
this.mockMvc = MockMvcBuilders.standaloneSetup(alertDefinesController).build();
content.put("ids", ids);
content.put("priority", priority);
content.put("sort", sort);
content.put("order", order);
content.put("pageIndex", pageIndex);
content.put("pageSize", pageSize);
Sort sortExp = Sort.by(new Sort.Order(Sort.Direction.fromString(content.get("order").toString()), content.get("sort").toString()));
pageRequest = PageRequest.of((Integer) content.get("pageIndex"), (Integer) content.get("pageSize"), sortExp);
}
// @Test
// todo: fix this test
void getAlertDefines() throws Exception {
// Test the correctness of the mock
// Although objects cannot be mocked, stubs can be stored using class files
// Mockito.when(alertDefineService.getAlertDefines(Mockito.any(Specification.class), Mockito.argThat(new ArgumentMatcher<PageRequest>() {
// @Override
// public boolean matches(PageRequest pageRequestMidden) {
// // There are three methods in the source code that need to be compared, namely getPageNumber(), getPageSize(), getSort()
// if(pageRequestMidden.getPageSize() == pageRequest.getPageSize() &&
// pageRequestMidden.getPageNumber() == pageRequest.getPageNumber() &&
// pageRequestMidden.getSort().equals(pageRequest.getSort())) {
// return true;
// }
// return false;
// }
// }))).thenReturn(new PageImpl<AlertDefine>(new ArrayList<AlertDefine>()));
AlertDefine define = AlertDefine.builder().id(9L).app("linux").metric("disk").field("usage").expr("x").times(1).tags(new LinkedList<>()).build();
Mockito.when(alertDefineService.getAlertDefines(Mockito.any(), Mockito.any())).thenReturn(new PageImpl<>(Collections.singletonList(define)));
mockMvc.perform(MockMvcRequestBuilders.get(
"/api/alert/defines")
.param("ids", ids.toString().substring(1, ids.toString().length() - 1))
.param("priority", priority.toString())
.param("sort", sort)
.param("order", order)
.param("pageIndex", pageIndex.toString())
.param("pageSize", pageSize.toString()))
.andExpect(status().isOk())
.andExpect(jsonPath("$.code").value((int) CommonConstants.SUCCESS_CODE))
.andExpect(jsonPath("$.data.content").value(new ArrayList<>()))
.andExpect(jsonPath("$.data.pageable").value("INSTANCE"))
.andExpect(jsonPath("$.data.totalPages").value(1))
.andExpect(jsonPath("$.data.totalElements").value(0))
.andExpect(jsonPath("$.data.last").value(true))
.andExpect(jsonPath("$.data.number").value(0))
.andExpect(jsonPath("$.data.size").value(0))
.andExpect(jsonPath("$.data.first").value(true))
.andExpect(jsonPath("$.data.numberOfElements").value(0))
.andExpect(jsonPath("$.data.empty").value(true))
.andExpect(jsonPath("$.data.sort.empty").value(true))
.andExpect(jsonPath("$.data.sort.sorted").value(false))
.andExpect(jsonPath("$.data.sort.unsorted").value(true))
.andReturn();
}
@Test
void deleteAlertDefines() throws Exception {
this.mockMvc.perform(MockMvcRequestBuilders.delete("/api/alert/defines")
.contentType(MediaType.APPLICATION_JSON)
.content(JsonUtil.toJson(ids)))
.andExpect(status().isOk())
.andExpect(jsonPath("$.code").value((int) CommonConstants.SUCCESS_CODE))
.andReturn();
}
}
@@ -1,124 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.hertzbeat.alert.controller;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
import org.apache.hertzbeat.alert.dto.GeneralCloudAlertReport;
import org.apache.hertzbeat.alert.dto.TenCloudAlertReport;
import org.apache.hertzbeat.alert.service.AlertService;
import org.apache.hertzbeat.common.constants.CommonConstants;
import org.apache.hertzbeat.common.util.JsonUtil;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;
import org.springframework.http.MediaType;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
/**
* unit test for {@link AlertReportController }
*/
@ExtendWith(MockitoExtension.class)
class AlertReportControllerTest {
private MockMvc mockMvc;
@Mock
private AlertService alertService;
@InjectMocks
private AlertReportController alertReportController;
@BeforeEach
void setUp() {
this.mockMvc = MockMvcBuilders.standaloneSetup(alertReportController).build();
}
@Test
void addNewAlertReportTencent() throws Exception {
TenCloudAlertReport.Dimensions dimensions = new TenCloudAlertReport.Dimensions();
dimensions.setUnInstanceId("3333");
TenCloudAlertReport.AlarmObjInfo alarmObjInfo = new TenCloudAlertReport.AlarmObjInfo();
alarmObjInfo.setRegion("Guangzhou");
alarmObjInfo.setNamespace("Guangzhou1");
alarmObjInfo.setAppId("1111");
alarmObjInfo.setUin("2222");
alarmObjInfo.setDimensions(dimensions);
TenCloudAlertReport.Conditions conditions = new TenCloudAlertReport.Conditions();
conditions.setMetricName("xx");
conditions.setMetricShowName("xxx");
conditions.setCalcType("a");
conditions.setCalcValue("aa");
conditions.setCalcUnit("aaa");
conditions.setCurrentValue("b");
conditions.setCalcUnit("bb");
conditions.setProductName("guangzhou");
conditions.setProductShowName("Guangzhou1");
conditions.setEventName("CVS");
conditions.setEventShowName("Core error");
TenCloudAlertReport.AlarmPolicyInfo alarmPolicyInfo = new TenCloudAlertReport.AlarmPolicyInfo();
alarmPolicyInfo.setPolicyTypeCname("x");
alarmPolicyInfo.setPolicyName("Test1");
alarmPolicyInfo.setConditions(conditions);
TenCloudAlertReport report = TenCloudAlertReport.builder()
.sessionId("123")
.alarmStatus("1")
.alarmType("event")
.durationTime(2)
.firstOccurTime("2023-08-14 11:11:11")
.alarmObjInfo(alarmObjInfo)
.alarmPolicyInfo(alarmPolicyInfo)
.build();
mockMvc.perform(
MockMvcRequestBuilders
.post("/api/alerts/report/tencloud")
.contentType(MediaType.APPLICATION_JSON)
.content(JsonUtil.toJson(report))
)
.andExpect(status().isOk())
.andExpect(jsonPath("$.code").value((int) CommonConstants.SUCCESS_CODE))
.andExpect(content().json("{\"data\":null,\"msg\":\"Add report success\",\"code\":0}"))
.andReturn();
}
@Test
void addNewAlertReport() throws Exception {
GeneralCloudAlertReport generalCloudAlertReport = new GeneralCloudAlertReport();
generalCloudAlertReport.setAlertDateTime("2023-02-22T07:27:15.404000000Z");
mockMvc.perform(MockMvcRequestBuilders
.post("/api/alerts/report")
.contentType(MediaType.APPLICATION_JSON)
.content(JsonUtil.toJson(generalCloudAlertReport))
)
.andExpect(status().isOk())
.andExpect(jsonPath("$.code").value((int) CommonConstants.SUCCESS_CODE))
.andExpect(content().json("{\"data\":null,\"msg\":\"Add report success\",\"code\":0}"))
.andReturn();
}
}
@@ -1,161 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.hertzbeat.alert.controller;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.LongStream;
import org.apache.hertzbeat.alert.dto.AlertSummary;
import org.apache.hertzbeat.alert.service.AlertService;
import org.apache.hertzbeat.common.constants.CommonConstants;
import org.apache.hertzbeat.common.entity.alerter.Alert;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.Mockito;
import org.mockito.junit.jupiter.MockitoExtension;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
/**
* Test case for {@link AlertsController}
*/
@ExtendWith(MockitoExtension.class)
class AlertsControllerTest {
private MockMvc mockMvc;
@InjectMocks
private AlertsController alertsController;
@Mock
private AlertService alertService;
private List<Long> ids;
@BeforeEach
void setUp() {
this.mockMvc = MockMvcBuilders.standaloneSetup(alertsController).build();
ids = LongStream.rangeClosed(1, 10).boxed().collect(Collectors.toList());
}
// todo: fix this test
void getAlerts() throws Exception {
String sortField = "id";
String orderType = "asc";
int pageIndex = 0;
int pageSize = 10;
PageRequest pageRequest = PageRequest.of(pageIndex, pageSize, Sort.by(new Sort.Order(Sort.Direction.fromString(orderType), sortField)));
Page<Alert> alertPage = new PageImpl<>(Collections.singletonList(Alert.builder().build()));
Mockito.when(
alertService.getAlerts(
Mockito.any(Specification.class)
, Mockito.argThat(
argument ->
argument.getPageNumber() == pageRequest.getPageNumber()
&& argument.getPageSize() == pageRequest.getPageSize()
&& argument.getSort().equals(pageRequest.getSort())
)
)
)
.thenReturn(alertPage);
mockMvc.perform(
MockMvcRequestBuilders
.get("/api/alerts")
.param("ids", ids.stream().map(String::valueOf).collect(Collectors.joining(",")))
.param("monitorId", "1")
.param("priority", "1")
.param("status", "1")
.param("content", "test")
.param("sort", sortField)
.param("order", orderType)
.param("pageIndex", String.valueOf(pageIndex))
.param("pageSize", String.valueOf(pageSize))
)
.andExpect(status().isOk())
.andExpect(jsonPath("$.code").value((int) CommonConstants.SUCCESS_CODE))
.andExpect(jsonPath("$.data.content.length()").value(1))
.andReturn();
}
@Test
void deleteAlerts() throws Exception {
mockMvc.perform(
MockMvcRequestBuilders
.delete("/api/alerts")
.param("ids", ids.stream().map(String::valueOf).collect(Collectors.joining(",")))
)
.andExpect(status().isOk())
.andExpect(jsonPath("$.code").value((int) CommonConstants.SUCCESS_CODE))
.andExpect(content().json("{\"data\":null,\"msg\":null,\"code\":0}"))
.andReturn();
}
@Test
void clearAllAlerts() throws Exception {
mockMvc.perform(
MockMvcRequestBuilders
.delete("/api/alerts/clear")
)
.andExpect(status().isOk())
.andExpect(jsonPath("$.code").value((int) CommonConstants.SUCCESS_CODE))
.andExpect(content().json("{\"data\":null,\"msg\":null,\"code\":0}"))
.andReturn();
}
@Test
void applyAlertDefinesStatus() throws Exception {
mockMvc.perform(
MockMvcRequestBuilders
.put("/api/alerts/status/1")
.param("ids", ids.stream().map(String::valueOf).collect(Collectors.joining(",")))
)
.andExpect(status().isOk())
.andExpect(jsonPath("$.code").value((int) CommonConstants.SUCCESS_CODE))
.andExpect(content().json("{\"data\":null,\"msg\":null,\"code\":0}"))
.andReturn();
}
@Test
void getAlertsSummary() throws Exception {
Mockito.when(alertService.getAlertsSummary()).thenReturn(new AlertSummary());
mockMvc.perform(
MockMvcRequestBuilders
.get("/api/alerts/summary")
)
.andExpect(status().isOk())
.andExpect(jsonPath("$.code").value((int) CommonConstants.SUCCESS_CODE))
.andExpect(content().json("{\"data\":{\"total\":0,\"dealNum\":0,\"rate\":0.0,\"priorityWarningNum\":0,\"priorityCriticalNum\":0,\"priorityEmergencyNum\":0},\"msg\":null,\"code\":0}"))
.andReturn();
}
}
@@ -1,190 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.hertzbeat.alert.service;
import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.mockito.Mockito.anySet;
import static org.mockito.Mockito.doNothing;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.reset;
import static org.mockito.Mockito.when;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Optional;
import org.apache.hertzbeat.alert.dao.AlertDefineBindDao;
import org.apache.hertzbeat.alert.dao.AlertDefineDao;
import org.apache.hertzbeat.alert.service.impl.AlertDefineServiceImpl;
import org.apache.hertzbeat.common.entity.alerter.AlertDefine;
import org.apache.hertzbeat.common.entity.alerter.AlertDefineMonitorBind;
import org.apache.hertzbeat.common.entity.manager.Monitor;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.test.util.ReflectionTestUtils;
/**
* Test case for {@link AlertDefineService}
*/
@ExtendWith(MockitoExtension.class)
class AlertDefineServiceTest {
private AlertDefine alertDefine;
private List<AlertDefineMonitorBind> alertDefineMonitorBinds;
@Mock
private AlertDefineDao alertDefineDao;
@Mock
private AlertDefineBindDao alertDefineBindDao;
@Mock
private List<AlertDefineImExportService> alertDefineImExportServiceList;
@InjectMocks
private AlertDefineServiceImpl alertDefineService;
@BeforeEach
void setUp() {
ReflectionTestUtils.setField(this.alertDefineService, "alertDefineDao", alertDefineDao);
ReflectionTestUtils.setField(this.alertDefineService, "alertDefineBindDao", alertDefineBindDao);
this.alertDefine = AlertDefine.builder()
.id(1L)
.app("app")
.metric("test")
.field("test")
.preset(false)
.expr("1 > 0")
.priority((byte) 1)
.times(1)
.template("template")
.creator("tom")
.modifier("tom")
.build();
this.alertDefineMonitorBinds = Collections.singletonList(
AlertDefineMonitorBind.builder()
.id(1L)
.alertDefineId(this.alertDefine.getId())
.monitorId(1L)
.monitor(
Monitor.builder()
.id(1L)
.app("app")
.host("localhost")
.name("monitor")
.build()
)
.build()
);
}
@Test
void validate() {
assertDoesNotThrow(() -> alertDefineService.validate(alertDefine, true));
assertDoesNotThrow(() -> alertDefineService.validate(alertDefine, false));
}
@Test
void addAlertDefine() {
assertDoesNotThrow(() -> alertDefineService.addAlertDefine(alertDefine));
when(alertDefineDao.save(alertDefine)).thenThrow(new RuntimeException());
assertThrows(RuntimeException.class, () -> alertDefineService.addAlertDefine(alertDefine));
}
@Test
void modifyAlertDefine() {
AlertDefine alertDefine = AlertDefine.builder().id(1L).build();
when(alertDefineDao.save(alertDefine)).thenReturn(alertDefine);
assertDoesNotThrow(() -> alertDefineService.modifyAlertDefine(alertDefine));
reset();
when(alertDefineDao.save(alertDefine)).thenThrow(new RuntimeException());
assertThrows(RuntimeException.class, () -> alertDefineService.modifyAlertDefine(alertDefine));
}
@Test
void deleteAlertDefine() {
long id = 1L;
doNothing().doThrow(new RuntimeException()).when(alertDefineDao).deleteById(id);
assertDoesNotThrow(() -> alertDefineService.deleteAlertDefine(id));
assertThrows(RuntimeException.class, () -> alertDefineService.deleteAlertDefine(id));
}
@Test
void getAlertDefine() {
long id = 1L;
AlertDefine alertDefine = AlertDefine.builder().id(id).build();
when(alertDefineDao.findById(id)).thenReturn(Optional.of(alertDefine));
assertDoesNotThrow(() -> alertDefineService.getAlertDefine(id));
}
@Test
void deleteAlertDefines() {
doNothing().when(alertDefineDao).deleteAlertDefinesByIdIn(anySet());
assertDoesNotThrow(() -> alertDefineService.deleteAlertDefines(new HashSet<>(1)));
}
@Test
void getMonitorBindAlertDefines() {
Specification<AlertDefine> specification = mock(Specification.class);
when(alertDefineDao.findAll(specification, PageRequest.of(1, 1))).thenReturn(Page.empty());
assertNotNull(alertDefineService.getMonitorBindAlertDefines(specification, PageRequest.of(1, 1)));
}
@Test
void applyBindAlertDefineMonitors() {
long id = 1L;
doNothing().when(alertDefineBindDao).deleteAlertDefineBindsByAlertDefineIdEquals(id);
when(alertDefineBindDao.saveAll(alertDefineMonitorBinds)).thenReturn(alertDefineMonitorBinds);
assertDoesNotThrow(() -> alertDefineService.applyBindAlertDefineMonitors(id, alertDefineMonitorBinds));
}
@Test
void testGetMonitorBindAlertDefines() {
List<AlertDefine> alertDefineList = new ArrayList<>();
alertDefineList.add(this.alertDefine);
when(alertDefineDao.queryAlertDefinesByMonitor(1L, "app", "test")).thenReturn(alertDefineList);
when(alertDefineDao.queryAlertDefinesByAppAndMetricAndPresetTrueAndEnableTrue("app", "test")).thenReturn(alertDefineList);
assertNotNull(alertDefineService.getMonitorBindAlertDefines(1L, "app", "test"));
}
@Test
void getAlertDefines() {
Specification<AlertDefine> specification = mock(Specification.class);
when(alertDefineDao.findAll(specification, PageRequest.of(1, 1))).thenReturn(Page.empty());
assertNotNull(alertDefineService.getAlertDefines(specification, PageRequest.of(1, 1)));
}
@Test
void getBindAlertDefineMonitors() {
long id = 1L;
when(alertDefineBindDao.getAlertDefineBindsByAlertDefineIdEquals(id)).thenReturn(alertDefineMonitorBinds);
assertDoesNotThrow(() -> alertDefineService.getBindAlertDefineMonitors(id));
}
}
@@ -1,59 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.hertzbeat.alert.service;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
/**
* Test case for {@link AlertService}
*/
class AlertServiceTest {
@BeforeEach
void setUp() {
}
@Test
void addAlert() {
}
@Test
void getAlerts() {
}
@Test
void deleteAlerts() {
}
@Test
void clearAlerts() {
}
@Test
void editAlertStatus() {
}
@Test
void getAlertsSummary() {
}
@Test
void addNewAlertReport() {
}
}
@@ -1,90 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.hertzbeat.alert.util;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNull;
import java.util.HashMap;
import java.util.Map;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
/**
* Test case for {@link AlertTemplateUtil}
*/
class AlertTemplateUtilTest {
@BeforeEach
void setUp() {
}
@Test
void render() {
// test null template case
Map<String, Object> param = new HashMap<>();
String template = null;
assertNull(AlertTemplateUtil.render(null, param));
// test null map case
template = "${key} for testing";
assertEquals(AlertTemplateUtil.render(template, null), template);
// test null template and null map case
assertNull(AlertTemplateUtil.render(null, null));
// test illegal template case
template = "";
param.put("key", "Just");
assertEquals(AlertTemplateUtil.render(template, param), template);
template = "key for testing!";
assertEquals(AlertTemplateUtil.render(template, param), template);
// test empty map case
param.clear();
template = "${key} for testing";
assertEquals(AlertTemplateUtil.render(template, param), "NullValue for testing");
// test illegal template and empty map case
param.clear();
template = "key for testing";
assertEquals(AlertTemplateUtil.render(template, param), template);
// test one param
param.put("key", "Just");
template = "${key} for testing";
assertEquals(AlertTemplateUtil.render(template, param), "Just for testing");
// test two param
param.put("key1", "Just");
param.put("key2", "testing");
template = "${key1} for ${key2}";
assertEquals(AlertTemplateUtil.render(template, param), "Just for testing");
// test all param
param.put("key1", "Just");
param.put("key2", "for");
param.put("key3", "testing");
template = "${key1} ${key2} ${key3}";
assertEquals(AlertTemplateUtil.render(template, param), "Just for testing");
}
@Test
void renderSpecialCharacters() {
Map<String, Object> param = new HashMap<>();
param.put("valueWithDollar", "$100");
param.put("valueWithBackslash", "C:\\Users");
String template = "The price is ${valueWithDollar} and the path is ${valueWithBackslash}";
// Expected to handle the dollar sign and backslash correctly without throwing an exception
String expectedResult = "The price is $100 and the path is C:\\Users";
assertEquals(expectedResult, AlertTemplateUtil.render(template, param));
}
}
-464
View File
@@ -1,464 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
~ Licensed to the Apache Software Foundation (ASF) under one or more
~ contributor license agreements. See the NOTICE file distributed with
~ this work for additional information regarding copyright ownership.
~ The ASF licenses this file to You under the Apache License, Version 2.0
~ (the "License"); you may not use this file except in compliance with
~ the License. You may obtain a copy of the License at
~
~ http://www.apache.org/licenses/LICENSE-2.0
~
~ Unless required by applicable law or agreed to in writing, software
~ distributed under the License is distributed on an "AS IS" BASIS,
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
~ See the License for the specific language governing permissions and
~ limitations under the License.
-->
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>hertzbeat</artifactId>
<groupId>org.apache.hertzbeat</groupId>
<version>2.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>hertzbeat-collector</artifactId>
<name>${project.artifactId}</name>
<properties>
<java.version>17</java.version>
<maven.compiler.source>${java.version}</maven.compiler.source>
<maven.compiler.target>${java.version}</maven.compiler.target>
<maven-jar-plugin.version>3.2.0</maven-jar-plugin.version>
<maven-assembly-plugin.version>3.3.0</maven-assembly-plugin.version>
</properties>
<dependencies>
<!-- spring -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-autoconfigure</artifactId>
</dependency>
<!-- common -->
<dependency>
<groupId>org.apache.hertzbeat</groupId>
<artifactId>hertzbeat-common</artifactId>
</dependency>
<!-- remoting -->
<dependency>
<groupId>org.apache.hertzbeat</groupId>
<artifactId>hertzbeat-remoting</artifactId>
</dependency>
<!-- run sql script-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
</dependency>
<!-- kafka -->
<dependency>
<groupId>org.apache.kafka</groupId>
<artifactId>kafka-clients</artifactId>
</dependency>
<!-- http -->
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
</dependency>
<!--network-->
<dependency>
<groupId>commons-net</groupId>
<artifactId>commons-net</artifactId>
<version>3.8.0</version>
</dependency>
<!--json path parser-->
<dependency>
<groupId>com.jayway.jsonpath</groupId>
<artifactId>json-path</artifactId>
</dependency>
<!-- lru hashmap -->
<dependency>
<groupId>com.googlecode.concurrentlinkedhashmap</groupId>
<artifactId>concurrentlinkedhashmap-lru</artifactId>
<version>1.4.2</version>
</dependency>
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
</dependency>
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
</dependency>
<!--collect-->
<!-- mysql -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>provided</scope>
</dependency>
<!-- clickhouse -->
<dependency>
<groupId>com.clickhouse</groupId>
<artifactId>clickhouse-jdbc</artifactId>
</dependency>
<!-- dm -->
<dependency>
<groupId>com.dameng</groupId>
<artifactId>DmJdbcDriver18</artifactId>
</dependency>
<!-- postgresql -->
<dependency>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
</dependency>
<!-- linux ssh -->
<dependency>
<groupId>org.apache.sshd</groupId>
<artifactId>sshd-core</artifactId>
<version>2.8.0</version>
</dependency>
<dependency>
<groupId>net.i2p.crypto</groupId>
<artifactId>eddsa</artifactId>
<version>0.3.0</version>
</dependency>
<!-- sql server -->
<dependency>
<groupId>com.microsoft.sqlserver</groupId>
<artifactId>mssql-jdbc</artifactId>
</dependency>
<!-- oracle -->
<dependency>
<groupId>com.oracle.database.jdbc</groupId>
<artifactId>ojdbc8</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.oracle.database.nls</groupId>
<artifactId>orai18n</artifactId>
<scope>provided</scope>
</dependency>
<!--redis-->
<dependency>
<groupId>io.lettuce</groupId>
<artifactId>lettuce-core</artifactId>
</dependency>
<!-- mongodb -->
<dependency>
<groupId>org.mongodb</groupId>
<artifactId>mongodb-driver-sync</artifactId>
</dependency>
<!--snmp-->
<dependency>
<groupId>org.snmp4j</groupId>
<artifactId>snmp4j</artifactId>
<version>3.6.7</version>
</dependency>
<!-- rocketmq -->
<dependency>
<groupId>org.apache.rocketmq</groupId>
<artifactId>rocketmq-tools</artifactId>
<version>4.9.4</version>
</dependency>
<!--dns-->
<dependency>
<groupId>dnsjava</groupId>
<artifactId>dnsjava</artifactId>
<version>3.5.2</version>
</dependency>
<!-- consul -->
<dependency>
<groupId>com.ecwid.consul</groupId>
<artifactId>consul-api</artifactId>
<version>1.4.5</version>
</dependency>
<!-- nacos -->
<dependency>
<groupId>com.alibaba.nacos</groupId>
<artifactId>nacos-client</artifactId>
<version>2.2.1</version>
</dependency>
<!-- nebula graph client -->
<dependency>
<groupId>com.vesoft</groupId>
<artifactId>client</artifactId>
<version>3.6.0</version>
<exclusions>
<exclusion>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
</exclusion>
<exclusion>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencies>
<build>
<finalName>apache-hertzbeat-collector-${hzb.version}</finalName>
</build>
<profiles>
<profile>
<id>inner</id>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>${maven-jar-plugin.version}</version>
<executions>
<execution>
<phase>package</phase>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
<profile>
<id>cluster</id>
<build>
<resources>
<resource>
<directory>src/main/resources</directory>
<filtering>true</filtering>
<includes>
<include>*.yml</include>
<include>*.properties</include>
<include>*.xml</include>
<include>banner.txt</include>
<include>META-INF/**</include>
</includes>
</resource>
</resources>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>17</source>
<target>17</target>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>${maven-jar-plugin.version}</version>
<configuration>
<classesDirectory>target/classes/</classesDirectory>
<archive>
<!--Generated JAR does not include Maven descriptor-related files-->
<addMavenDescriptor>false</addMavenDescriptor>
<manifest>
<!--Project startup class-->
<mainClass>org.apache.hertzbeat.collector.Collector</mainClass>
<useUniqueVersions>false</useUniqueVersions>
<!--Third-party JARs are added to the classpath using maven-dependency-plugin-->
<addClasspath>true</addClasspath>
<!--Location of external dependency JARs-->
<classpathPrefix>lib/</classpathPrefix>
</manifest>
<manifestEntries>
<Class-Path>. config</Class-Path>
</manifestEntries>
</archive>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
<version>${maven-assembly-plugin.version}</version>
<executions>
<execution>
<id>without-jdk</id>
<!--Bound Maven operation-->
<phase>package</phase>
<!--Run once-->
<goals>
<goal>single</goal>
</goals>
<configuration>
<descriptors>
<descriptor>../script/assembly/collector/assembly.xml</descriptor>
</descriptors>
<outputDirectory>../dist</outputDirectory>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
<profile>
<id>runtime</id>
<build>
<resources>
<resource>
<directory>src/main/resources</directory>
<filtering>true</filtering>
<includes>
<include>*.yml</include>
<include>*.properties</include>
<include>*.xml</include>
<include>banner.txt</include>
<include>META-INF/**</include>
</includes>
</resource>
</resources>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>17</source>
<target>17</target>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>${maven-jar-plugin.version}</version>
<configuration>
<classesDirectory>target/classes/</classesDirectory>
<archive>
<!--Generated JAR does not include Maven descriptor-related files-->
<addMavenDescriptor>false</addMavenDescriptor>
<manifest>
<!--Project startup class-->
<mainClass>org.apache.hertzbeat.collector.Collector</mainClass>
<useUniqueVersions>false</useUniqueVersions>
<!--Third-party JARs are added to the classpath using maven-dependency-plugin-->
<addClasspath>true</addClasspath>
<!--Location of external dependency JARs-->
<classpathPrefix>lib/</classpathPrefix>
</manifest>
<manifestEntries>
<Class-Path>. config</Class-Path>
</manifestEntries>
</archive>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
<version>${maven-assembly-plugin.version}</version>
<executions>
<execution>
<id>without-jdk</id>
<!--Bound Maven operation-->
<phase>package</phase>
<!--Run once-->
<goals>
<goal>single</goal>
</goals>
<configuration>
<descriptors>
<descriptor>../script/assembly/collector/assembly.xml</descriptor>
</descriptors>
<outputDirectory>../dist</outputDirectory>
</configuration>
</execution>
<execution>
<id>make-macos-arm64</id>
<!--Bound Maven operation-->
<phase>package</phase>
<!--Run once-->
<goals>
<goal>single</goal>
</goals>
<configuration>
<descriptors>
<descriptor>../script/assembly/collector/assembly-macos-arm64.xml</descriptor>
</descriptors>
<outputDirectory>../dist</outputDirectory>
</configuration>
</execution>
<execution>
<id>make-macos-amd64</id>
<!--Bound Maven operation-->
<phase>package</phase>
<!--Run once-->
<goals>
<goal>single</goal>
</goals>
<configuration>
<descriptors>
<descriptor>../script/assembly/collector/assembly-macos-amd64.xml</descriptor>
</descriptors>
<outputDirectory>../dist</outputDirectory>
</configuration>
</execution>
<execution>
<id>make-linux-arm64</id>
<!--Bound Maven operation-->
<phase>package</phase>
<!--Run once-->
<goals>
<goal>single</goal>
</goals>
<configuration>
<descriptors>
<descriptor>../script/assembly/collector/assembly-linux-arm64.xml</descriptor>
</descriptors>
<outputDirectory>../dist</outputDirectory>
</configuration>
</execution>
<execution>
<id>make-linux-amd64</id>
<!--Bound Maven operation-->
<phase>package</phase>
<!--Run once-->
<goals>
<goal>single</goal>
</goals>
<configuration>
<descriptors>
<descriptor>../script/assembly/collector/assembly-linux-amd64.xml</descriptor>
</descriptors>
<outputDirectory>../dist</outputDirectory>
</configuration>
</execution>
<execution>
<id>make-windows-64</id>
<!--Bound Maven operation-->
<phase>package</phase>
<!--Run once-->
<goals>
<goal>single</goal>
</goals>
<configuration>
<descriptors>
<descriptor>../script/assembly/collector/assembly-windows-64.xml</descriptor>
</descriptors>
<outputDirectory>../dist</outputDirectory>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
</profiles>
</project>
@@ -1,41 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.hertzbeat.collector;
import jakarta.annotation.PostConstruct;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.context.properties.ConfigurationPropertiesScan;
import org.springframework.context.annotation.ComponentScan;
/**
* collector startup
*/
@ComponentScan(basePackages = {"org.apache.hertzbeat"})
@ConfigurationPropertiesScan(basePackages = {"org.apache.hertzbeat"})
@SpringBootApplication
public class Collector {
public static void main(String[] args) {
SpringApplication.run(Collector.class, args);
}
@PostConstruct
public void init() {
System.setProperty("jdk.jndi.object.factoriesFilter", "!com.zaxxer.hikari.HikariJNDIFactory");
}
}
@@ -1,233 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.hertzbeat.collector.collect.common.cache;
import com.google.common.util.concurrent.ThreadFactoryBuilder;
import com.googlecode.concurrentlinkedhashmap.ConcurrentLinkedHashMap;
import java.util.Map;
import java.util.Optional;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ScheduledThreadPoolExecutor;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import lombok.extern.slf4j.Slf4j;
/**
* lru common resource cache for client-server connection
*/
@Slf4j
public class ConnectionCommonCache<T, C extends AbstractConnection<?>> {
/**
* default cache time 200s
*/
private static final long DEFAULT_CACHE_TIMEOUT = 200 * 1000L;
/**
* default max cache num
*/
private static final int DEFAULT_MAX_CAPACITY = 10000;
/**
* cacheTime length
*/
private static final int CACHE_TIME_LENGTH = 2;
/**
* cache timeout map
*/
private Map<T, Long[]> timeoutMap;
/**
* object cache
*/
private ConcurrentLinkedHashMap<T, C> cacheMap;
/**
* the executor who clean cache when timeout
*/
private ThreadPoolExecutor timeoutCleanerExecutor;
public ConnectionCommonCache() {
init();
}
private void init() {
cacheMap = new ConcurrentLinkedHashMap
.Builder<T, C>()
.maximumWeightedCapacity(DEFAULT_MAX_CAPACITY)
.listener((key, value) -> {
timeoutMap.remove(key);
try {
value.close();
} catch (Exception e) {
log.error("connection close error: {}.", e.getMessage(), e);
}
log.info("connection common cache discard key: {}, value: {}.", key, value);
}).build();
timeoutMap = new ConcurrentHashMap<>(DEFAULT_MAX_CAPACITY >> 6);
// last-first-coverage algorithm, run the first and last thread, discard mid
timeoutCleanerExecutor = new ThreadPoolExecutor(1, 1, 1, TimeUnit.SECONDS,
new ArrayBlockingQueue<>(1),
r -> new Thread(r, "connection-cache-timeout-cleaner"),
new ThreadPoolExecutor.DiscardOldestPolicy());
// init monitor available detector cyc task
ThreadFactory threadFactory = new ThreadFactoryBuilder()
.setNameFormat("connection-cache-ava-detector-%d")
.setDaemon(true)
.build();
ScheduledThreadPoolExecutor scheduledExecutor = new ScheduledThreadPoolExecutor(1, threadFactory);
scheduledExecutor.scheduleWithFixedDelay(this::detectCacheAvailable, 2, 20, TimeUnit.MINUTES);
}
/**
* detect all cache available, cleanup not ava connection
*/
private void detectCacheAvailable() {
try {
cacheMap.forEach((key, value) -> {
Long[] cacheTime = timeoutMap.get(key);
long currentTime = System.currentTimeMillis();
if (cacheTime == null || cacheTime.length != CACHE_TIME_LENGTH
|| cacheTime[0] + cacheTime[1] < currentTime) {
cacheMap.remove(key);
timeoutMap.remove(key);
try {
value.close();
} catch (Exception e) {
log.error("connection close error: {}.", e.getMessage(), e);
}
}
});
} catch (Exception e) {
log.error("connection common cache detect cache available error: {}.", e.getMessage(), e);
}
}
/**
* clean timeout cache
*/
private void cleanTimeoutCache() {
try {
cacheMap.forEach((key, value) -> {
// index 0 is startTime, 1 is timeDiff
Long[] cacheTime = timeoutMap.get(key);
long currentTime = System.currentTimeMillis();
if (cacheTime == null || cacheTime.length != CACHE_TIME_LENGTH) {
timeoutMap.put(key, new Long[]{currentTime, DEFAULT_CACHE_TIMEOUT});
} else if (cacheTime[0] + cacheTime[1] < currentTime) {
// timeout, remove this object cache
log.warn("[connection common cache] clean the timeout cache, key {}", key);
timeoutMap.remove(key);
cacheMap.remove(key);
try {
value.close();
} catch (Exception e) {
log.error("connection close error: {}.", e.getMessage(), e);
}
}
});
Thread.sleep(20 * 1000);
} catch (Exception e) {
log.error("[connection common cache] clean timeout cache error: {}.", e.getMessage(), e);
}
}
/**
* add update cache
*
* @param key cache key
* @param value cache value
* @param timeDiff cache time millis
*/
public void addCache(T key, C value, Long timeDiff) {
removeCache(key);
if (timeDiff == null) {
timeDiff = DEFAULT_CACHE_TIMEOUT;
}
cacheMap.put(key, value);
timeoutMap.put(key, new Long[]{System.currentTimeMillis(), timeDiff});
timeoutCleanerExecutor.execute(this::cleanTimeoutCache);
}
/**
* add update cache
*
* @param key cache key
* @param value cache value
*/
public void addCache(T key, C value) {
addCache(key, value, DEFAULT_CACHE_TIMEOUT);
}
/**
* get cache by key
*
* @param key cache key
* @param refreshCache is refresh cache
* @return cache object
*/
public Optional<C> getCache(T key, boolean refreshCache) {
Long[] cacheTime = timeoutMap.get(key);
if (cacheTime == null || cacheTime.length != CACHE_TIME_LENGTH) {
log.info("[connection common cache] not hit the cache, key {}.", key);
return Optional.empty();
}
if (cacheTime[0] + cacheTime[1] < System.currentTimeMillis()) {
log.warn("[connection common cache] is timeout, remove it, key {}.", key);
timeoutMap.remove(key);
cacheMap.remove(key);
return Optional.empty();
}
C value = cacheMap.compute(key, (k, v) -> {
if (v == null) {
log.error("[connection common cache] value is null, remove it, key {}.", key);
timeoutMap.remove(key);
return null;
}
if (refreshCache) {
cacheTime[0] = System.currentTimeMillis();
timeoutMap.put(key, cacheTime);
}
return v;
});
return Optional.ofNullable(value);
}
/**
* remove cache by key
*
* @param key key
*/
public void removeCache(T key) {
timeoutMap.remove(key);
C value = cacheMap.remove(key);
try {
if (value == null) {
return;
}
value.close();
} catch (Exception e) {
log.error("connection close error: {}.", e.getMessage(), e);
}
}
}
@@ -1,155 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.hertzbeat.collector.collect.common.http;
import com.google.common.util.concurrent.ThreadFactoryBuilder;
import java.security.cert.CertificateException;
import java.security.cert.CertificateExpiredException;
import java.security.cert.X509Certificate;
import java.util.Date;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.TimeUnit;
import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
import lombok.extern.slf4j.Slf4j;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.config.Registry;
import org.apache.http.config.RegistryBuilder;
import org.apache.http.conn.socket.ConnectionSocketFactory;
import org.apache.http.conn.socket.PlainConnectionSocketFactory;
import org.apache.http.conn.ssl.NoopHostnameVerifier;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
import org.apache.http.ssl.SSLContexts;
/**
* common http client
*/
@Slf4j
public class CommonHttpClient {
private static CloseableHttpClient httpClient;
private static PoolingHttpClientConnectionManager connectionManager;
/**
* all max total connection
*/
private static final int MAX_TOTAL_CONNECTIONS = 50000;
/**
* peer route max total connection
*/
private static final int MAX_PER_ROUTE_CONNECTIONS = 80;
/**
* timeout for get connect from pool(ms)
*/
private static final int REQUIRE_CONNECT_TIMEOUT = 4000;
/**
* tcp connect timeout(ms)
*/
private static final int CONNECT_TIMEOUT = 4000;
/**
* socket read timeout(ms)
*/
private static final int SOCKET_TIMEOUT = 60000;
/**
* validated time for idle connection. if when reuse this connection after this time, we will check it available.
*/
private static final int INACTIVITY_VALIDATED_TIME = 10000;
/**
* ssl supported version
*/
private static final String[] SUPPORTED_SSL = {"TLSv1", "TLSv1.1", "TLSv1.2", "SSLv3"};
static {
try {
SSLContext sslContext = SSLContexts.createDefault();
X509TrustManager x509TrustManager = new X509TrustManager() {
@Override
public void checkClientTrusted(X509Certificate[] x509Certificates, String s) { }
@Override
public void checkServerTrusted(X509Certificate[] x509Certificates, String s) throws CertificateException {
// check server ssl certificate expired
Date now = new Date();
if (x509Certificates != null) {
for (X509Certificate certificate : x509Certificates) {
Date deadline = certificate.getNotAfter();
if (deadline != null && now.after(deadline)) {
throw new CertificateExpiredException();
}
}
}
}
@Override
public X509Certificate[] getAcceptedIssuers() { return null; }
};
sslContext.init(null, new TrustManager[]{x509TrustManager}, null);
SSLConnectionSocketFactory sslFactory = new SSLConnectionSocketFactory(sslContext, SUPPORTED_SSL, null, new NoopHostnameVerifier());
Registry<ConnectionSocketFactory> registry = RegistryBuilder.<ConnectionSocketFactory>create()
.register("http", PlainConnectionSocketFactory.INSTANCE)
.register("https", sslFactory)
.build();
RequestConfig requestConfig = RequestConfig.custom()
.setConnectionRequestTimeout(REQUIRE_CONNECT_TIMEOUT)
.setConnectTimeout(CONNECT_TIMEOUT)
.setSocketTimeout(SOCKET_TIMEOUT)
// auto redirect when 301 302 response status
.setRedirectsEnabled(true)
.build();
// connection pool
connectionManager = new PoolingHttpClientConnectionManager(registry);
connectionManager.setMaxTotal(MAX_TOTAL_CONNECTIONS);
connectionManager.setDefaultMaxPerRoute(MAX_PER_ROUTE_CONNECTIONS);
connectionManager.setValidateAfterInactivity(INACTIVITY_VALIDATED_TIME);
httpClient = HttpClients.custom()
.setConnectionManager(connectionManager)
.setDefaultRequestConfig(requestConfig)
// clean up unavailable expired connections
.evictExpiredConnections()
// clean up available but idle connections
.evictIdleConnections(100, TimeUnit.SECONDS)
.build();
ThreadFactory threadFactory = new ThreadFactoryBuilder()
.setNameFormat("http-connection-pool-cleaner-%d")
.setDaemon(true)
.build();
ScheduledExecutorService scheduledExecutor = Executors.newScheduledThreadPool(1, threadFactory);
scheduledExecutor.scheduleWithFixedDelay(() -> {
connectionManager.closeExpiredConnections();
connectionManager.closeIdleConnections(100, TimeUnit.SECONDS);
}, 40L, 40L, TimeUnit.SECONDS);
} catch (Exception ignored) {}
}
public static CloseableHttpClient getHttpClient() {
return httpClient;
}
}
@@ -1,320 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.hertzbeat.collector.collect.database;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.HashMap;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
import lombok.extern.slf4j.Slf4j;
import org.apache.hertzbeat.collector.collect.AbstractCollect;
import org.apache.hertzbeat.collector.collect.common.cache.CacheIdentifier;
import org.apache.hertzbeat.collector.collect.common.cache.ConnectionCommonCache;
import org.apache.hertzbeat.collector.collect.common.cache.JdbcConnect;
import org.apache.hertzbeat.collector.dispatch.DispatchConstants;
import org.apache.hertzbeat.collector.util.CollectUtil;
import org.apache.hertzbeat.common.constants.CollectorConstants;
import org.apache.hertzbeat.common.constants.CommonConstants;
import org.apache.hertzbeat.common.entity.job.Metrics;
import org.apache.hertzbeat.common.entity.job.protocol.JdbcProtocol;
import org.apache.hertzbeat.common.entity.message.CollectRep;
import org.apache.hertzbeat.common.util.CommonUtil;
import org.postgresql.util.PSQLException;
import org.springframework.core.io.FileSystemResource;
import org.springframework.jdbc.datasource.init.ScriptUtils;
import org.springframework.util.StringUtils;
/**
* common query for database query
*/
@Slf4j
public class JdbcCommonCollect extends AbstractCollect {
private static final String QUERY_TYPE_ONE_ROW = "oneRow";
private static final String QUERY_TYPE_MULTI_ROW = "multiRow";
private static final String QUERY_TYPE_COLUMNS = "columns";
private static final String RUN_SCRIPT = "runScript";
private static final String[] VULNERABLE_KEYWORDS = {"allowLoadLocalInfile", "allowLoadLocalInfileInPath", "useLocalInfile"};
private final ConnectionCommonCache<CacheIdentifier, JdbcConnect> connectionCommonCache;
public JdbcCommonCollect(){
connectionCommonCache = new ConnectionCommonCache<>();
}
@Override
public void preCheck(Metrics metrics) throws IllegalArgumentException {
if (metrics == null || metrics.getJdbc() == null) {
throw new IllegalArgumentException("Database collect must has jdbc params");
}
if (StringUtils.hasText(metrics.getJdbc().getUrl())) {
for (String keyword : VULNERABLE_KEYWORDS) {
if (metrics.getJdbc().getUrl().contains(keyword)) {
throw new IllegalArgumentException("Jdbc url prohibit contains vulnerable param " + keyword);
}
}
}
}
@Override
public void collect(CollectRep.MetricsData.Builder builder, long monitorId, String app, Metrics metrics) {
long startTime = System.currentTimeMillis();
JdbcProtocol jdbcProtocol = metrics.getJdbc();
String databaseUrl = constructDatabaseUrl(jdbcProtocol);
int timeout = CollectUtil.getTimeout(jdbcProtocol.getTimeout());
Statement statement = null;
try {
statement = getConnection(jdbcProtocol.getUsername(),
jdbcProtocol.getPassword(), databaseUrl, timeout);
switch (jdbcProtocol.getQueryType()) {
case QUERY_TYPE_ONE_ROW -> queryOneRow(statement, jdbcProtocol.getSql(), metrics.getAliasFields(), builder, startTime);
case QUERY_TYPE_MULTI_ROW -> queryMultiRow(statement, jdbcProtocol.getSql(), metrics.getAliasFields(), builder, startTime);
case QUERY_TYPE_COLUMNS -> queryOneRowByMatchTwoColumns(statement, jdbcProtocol.getSql(), metrics.getAliasFields(), builder, startTime);
case RUN_SCRIPT -> {
Connection connection = statement.getConnection();
FileSystemResource rc = new FileSystemResource(jdbcProtocol.getSql());
ScriptUtils.executeSqlScript(connection, rc);
}
default -> {
builder.setCode(CollectRep.Code.FAIL);
builder.setMsg("Not support database query type: " + jdbcProtocol.getQueryType());
}
}
} catch (PSQLException psqlException) {
// for PostgreSQL 08001
if (CollectorConstants.POSTGRESQL_UN_REACHABLE_CODE.equals(psqlException.getSQLState())) {
// Peer connection failed, unreachable
builder.setCode(CollectRep.Code.UN_REACHABLE);
} else {
builder.setCode(CollectRep.Code.FAIL);
}
builder.setMsg("Error: " + psqlException.getMessage() + " Code: " + psqlException.getSQLState());
} catch (SQLException sqlException) {
log.warn("Jdbc sql error: {}, code: {}.", sqlException.getMessage(), sqlException.getErrorCode());
builder.setCode(CollectRep.Code.FAIL);
builder.setMsg("Query Error: " + sqlException.getMessage() + " Code: " + sqlException.getErrorCode());
} catch (Exception e) {
String errorMessage = CommonUtil.getMessageFromThrowable(e);
log.error("Jdbc error: {}.", errorMessage, e);
builder.setCode(CollectRep.Code.FAIL);
builder.setMsg("Query Error: " + errorMessage);
} finally {
if (statement != null) {
try {
statement.close();
} catch (Exception e) {
log.error("Jdbc close statement error: {}", e.getMessage());
}
}
}
}
@Override
public String supportProtocol() {
return DispatchConstants.PROTOCOL_JDBC;
}
private Statement getConnection(String username, String password, String url, Integer timeout) throws Exception {
CacheIdentifier identifier = CacheIdentifier.builder()
.ip(url)
.username(username).password(password).build();
Optional<JdbcConnect> cacheOption = connectionCommonCache.getCache(identifier, true);
Statement statement = null;
if (cacheOption.isPresent()) {
JdbcConnect jdbcConnect = cacheOption.get();
try {
statement = jdbcConnect.getConnection().createStatement();
// set query timeout
int timeoutSecond = timeout / 1000;
timeoutSecond = timeoutSecond <= 0 ? 1 : timeoutSecond;
statement.setQueryTimeout(timeoutSecond);
// set query max row number
statement.setMaxRows(1000);
} catch (Exception e) {
log.info("The jdbc connect from cache, create statement error: {}", e.getMessage());
try {
if (statement != null) {
statement.close();
}
jdbcConnect.close();
} catch (Exception e2) {
log.error(e2.getMessage());
}
statement = null;
connectionCommonCache.removeCache(identifier);
}
}
if (statement != null) {
return statement;
}
// renew connection when failed
Connection connection = DriverManager.getConnection(url, username, password);
statement = connection.createStatement();
int timeoutSecond = timeout / 1000;
timeoutSecond = timeoutSecond <= 0 ? 1 : timeoutSecond;
statement.setQueryTimeout(timeoutSecond);
statement.setMaxRows(1000);
JdbcConnect jdbcConnect = new JdbcConnect(connection);
connectionCommonCache.addCache(identifier, jdbcConnect);
return statement;
}
/**
* query one row record, response metrics header and one value row
* eg:
* query metricsone tow three four
* query sqlselect one, tow, three, four from book limit 1;
* @param statement statement
* @param sql sql
* @param columns query metrics field list
* @throws Exception when error happen
*/
private void queryOneRow(Statement statement, String sql, List<String> columns,
CollectRep.MetricsData.Builder builder, long startTime) throws Exception {
statement.setMaxRows(1);
try (ResultSet resultSet = statement.executeQuery(sql)) {
if (resultSet.next()) {
CollectRep.ValueRow.Builder valueRowBuilder = CollectRep.ValueRow.newBuilder();
for (String column : columns) {
if (CollectorConstants.RESPONSE_TIME.equals(column)) {
long time = System.currentTimeMillis() - startTime;
valueRowBuilder.addColumns(String.valueOf(time));
} else {
String value = resultSet.getString(column);
value = value == null ? CommonConstants.NULL_VALUE : value;
valueRowBuilder.addColumns(value);
}
}
builder.addValues(valueRowBuilder.build());
}
}
}
/**
* query two columns to mapping one row
* eg:
* query metricsone two three four
* query sqlselect key, value from book; the key is the query metrics fields
* select key, value from book;
* one - value1
* two - value2
* three - value3
* four - value4
* @param statement statement
* @param sql sql
* @param columns query metrics field list
* @throws Exception when error happen
*/
private void queryOneRowByMatchTwoColumns(Statement statement, String sql, List<String> columns,
CollectRep.MetricsData.Builder builder, long startTime) throws Exception {
try (ResultSet resultSet = statement.executeQuery(sql)) {
HashMap<String, String> values = new HashMap<>(columns.size());
while (resultSet.next()) {
if (resultSet.getString(1) != null) {
values.put(resultSet.getString(1).toLowerCase().trim(), resultSet.getString(2));
}
}
CollectRep.ValueRow.Builder valueRowBuilder = CollectRep.ValueRow.newBuilder();
for (String column : columns) {
if (CollectorConstants.RESPONSE_TIME.equals(column)) {
long time = System.currentTimeMillis() - startTime;
valueRowBuilder.addColumns(String.valueOf(time));
} else {
String value = values.get(column.toLowerCase());
value = value == null ? CommonConstants.NULL_VALUE : value;
valueRowBuilder.addColumns(value);
}
}
builder.addValues(valueRowBuilder.build());
}
}
/**
* query multi row record, response metrics header and multi value row
* eg:
* query metricsone tow three four
* query sqlselect one, tow, three, four from book;
* and return multi row record mapping with the metrics
* @param statement statement
* @param sql sql
* @param columns query metrics field list
* @throws Exception when error happen
*/
private void queryMultiRow(Statement statement, String sql, List<String> columns,
CollectRep.MetricsData.Builder builder, long startTime) throws Exception {
try (ResultSet resultSet = statement.executeQuery(sql)) {
while (resultSet.next()) {
CollectRep.ValueRow.Builder valueRowBuilder = CollectRep.ValueRow.newBuilder();
for (String column : columns) {
if (CollectorConstants.RESPONSE_TIME.equals(column)) {
long time = System.currentTimeMillis() - startTime;
valueRowBuilder.addColumns(String.valueOf(time));
} else {
String value = resultSet.getString(column);
value = value == null ? CommonConstants.NULL_VALUE : value;
valueRowBuilder.addColumns(value);
}
}
builder.addValues(valueRowBuilder.build());
}
}
}
/**
* construct jdbc url due the jdbc protocol
* @param jdbcProtocol jdbc
* @return URL
*/
private String constructDatabaseUrl(JdbcProtocol jdbcProtocol) {
if (Objects.nonNull(jdbcProtocol.getUrl())
&& !Objects.equals("", jdbcProtocol.getUrl())
&& jdbcProtocol.getUrl().startsWith("jdbc")) {
// when has config jdbc url, use it
return jdbcProtocol.getUrl();
}
return switch (jdbcProtocol.getPlatform()) {
case "mysql", "mariadb" ->
"jdbc:mysql://" + jdbcProtocol.getHost() + ":" + jdbcProtocol.getPort()
+ "/" + (jdbcProtocol.getDatabase() == null ? "" : jdbcProtocol.getDatabase())
+ "?useUnicode=true&characterEncoding=utf-8&useSSL=false";
case "postgresql" ->
"jdbc:postgresql://" + jdbcProtocol.getHost() + ":" + jdbcProtocol.getPort()
+ "/" + (jdbcProtocol.getDatabase() == null ? "" : jdbcProtocol.getDatabase());
case "clickhouse" ->
"jdbc:clickhouse://" + jdbcProtocol.getHost() + ":" + jdbcProtocol.getPort()
+ "/" + (jdbcProtocol.getDatabase() == null ? "" : jdbcProtocol.getDatabase());
case "sqlserver" ->
"jdbc:sqlserver://" + jdbcProtocol.getHost() + ":" + jdbcProtocol.getPort()
+ ";" + (jdbcProtocol.getDatabase() == null ? "" : "DatabaseName=" + jdbcProtocol.getDatabase())
+ ";trustServerCertificate=true;";
case "oracle" ->
"jdbc:oracle:thin:@" + jdbcProtocol.getHost() + ":" + jdbcProtocol.getPort()
+ "/" + (jdbcProtocol.getDatabase() == null ? "" : jdbcProtocol.getDatabase());
case "dm" ->
"jdbc:dm://" + jdbcProtocol.getHost() + ":" + jdbcProtocol.getPort();
default -> throw new IllegalArgumentException("Not support database platform: " + jdbcProtocol.getPlatform());
};
}
}
@@ -1,153 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.hertzbeat.collector.collect.ftp;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.net.ftp.FTPClient;
import org.apache.hertzbeat.collector.collect.AbstractCollect;
import org.apache.hertzbeat.collector.dispatch.DispatchConstants;
import org.apache.hertzbeat.common.constants.CommonConstants;
import org.apache.hertzbeat.common.entity.job.Metrics;
import org.apache.hertzbeat.common.entity.job.protocol.FtpProtocol;
import org.apache.hertzbeat.common.entity.message.CollectRep;
import org.apache.hertzbeat.common.util.CommonUtil;
import org.springframework.util.Assert;
import org.springframework.util.StringUtils;
/**
* ftp protocol collection implementation
*/
@Slf4j
public class FtpCollectImpl extends AbstractCollect {
private static final String ANONYMOUS = "anonymous";
private static final String PASSWORD = "password";
/**
* preCheck params
*/
public void preCheck(Metrics metrics) throws IllegalArgumentException{
if (metrics == null || metrics.getFtp() == null) {
throw new IllegalArgumentException("Ftp collect must has ftp params.");
}
FtpProtocol ftpProtocol = metrics.getFtp();
Assert.hasText(ftpProtocol.getHost(), "Ftp Protocol host is required.");
Assert.hasText(ftpProtocol.getPort(), "Ftp Protocol port is required.");
Assert.hasText(ftpProtocol.getDirection(), "Ftp Protocol direction is required.");
Assert.hasText(ftpProtocol.getTimeout(), "Ftp Protocol timeout is required.");
}
@Override
public void collect(CollectRep.MetricsData.Builder builder, long monitorId, String app, Metrics metrics) {
FTPClient ftpClient = new FTPClient();
FtpProtocol ftpProtocol = metrics.getFtp();
// Set timeout
ftpClient.setControlKeepAliveReplyTimeout(Integer.parseInt(ftpProtocol.getTimeout()));
// Collect data to load in CollectRep.ValueRow.Builder's object
CollectRep.ValueRow.Builder valueRowBuilder = CollectRep.ValueRow.newBuilder();
Map<String, String> valueMap;
try {
valueMap = collectValue(ftpClient, ftpProtocol);
metrics.getAliasFields().forEach(it -> {
if (valueMap.containsKey(it)) {
String fieldValue = valueMap.get(it);
valueRowBuilder.addColumns(Objects.requireNonNullElse(fieldValue, CommonConstants.NULL_VALUE));
} else {
valueRowBuilder.addColumns(CommonConstants.NULL_VALUE);
}
});
} catch (Exception e) {
builder.setCode(CollectRep.Code.UN_CONNECTABLE);
builder.setMsg(e.getMessage());
return;
}
builder.addValues(valueRowBuilder.build());
}
/**
* collect data: key-value
* Please modify this, if you want to add some metrics.
*/
private Map<String, String> collectValue(FTPClient ftpClient, FtpProtocol ftpProtocol) {
boolean isActive;
String responseTime;
try {
long startTime = System.currentTimeMillis();
connect(ftpClient, ftpProtocol);
login(ftpClient, ftpProtocol);
// In here, we can do some extended operation without changing the architecture
isActive = ftpClient.changeWorkingDirectory(ftpProtocol.getDirection());
long endTime = System.currentTimeMillis();
responseTime = String.valueOf(endTime - startTime);
ftpClient.disconnect();
} catch (Exception e) {
log.info("[FTPClient] error: {}", CommonUtil.getMessageFromThrowable(e), e);
throw new IllegalArgumentException(e.getMessage());
}
return new HashMap<>(8) {
{
put("isActive", Boolean.toString(isActive));
put("responseTime", responseTime);
}
};
}
/**
* login
*/
private void login(FTPClient ftpClient, FtpProtocol ftpProtocol) {
try {
// username: not empty, password: not empty
if (StringUtils.hasText(ftpProtocol.getUsername()) && StringUtils.hasText(ftpProtocol.getPassword())) {
if (!ftpClient.login(ftpProtocol.getUsername(), ftpProtocol.getPassword())) {
throw new IllegalArgumentException("The username or password may be wrong.");
}
return;
}
// anonymous access
if (!ftpClient.login(ANONYMOUS, PASSWORD)) {
throw new IllegalArgumentException("The server may not allow anonymous access, we need to username and password.");
}
} catch (Exception e) {
log.info("[ftp login] error: {}", CommonUtil.getMessageFromThrowable(e), e);
throw new IllegalArgumentException(e.getMessage());
}
}
/**
* connect
*/
private void connect(FTPClient ftpClient, FtpProtocol ftpProtocol) {
try {
ftpClient.connect(ftpProtocol.getHost(), Integer.parseInt(ftpProtocol.getPort()));
} catch (Exception e) {
log.info("[ftp connection] error: {}", CommonUtil.getMessageFromThrowable(e), e);
throw new IllegalArgumentException("The host or port may be wrong.");
}
}
@Override
public String supportProtocol() {
return DispatchConstants.PROTOCOL_FTP;
}
}
@@ -1,586 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.hertzbeat.collector.collect.http;
import static org.apache.hertzbeat.common.constants.SignConstants.RIGHT_DASH;
import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InterruptedIOException;
import java.net.ConnectException;
import java.net.UnknownHostException;
import java.nio.charset.StandardCharsets;
import java.util.Arrays;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import javax.net.ssl.SSLException;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.net.util.Base64;
import org.apache.hertzbeat.collector.collect.AbstractCollect;
import org.apache.hertzbeat.collector.collect.common.http.CommonHttpClient;
import org.apache.hertzbeat.collector.collect.http.promethus.AbstractPrometheusParse;
import org.apache.hertzbeat.collector.collect.http.promethus.PrometheusParseCreater;
import org.apache.hertzbeat.collector.collect.http.promethus.exporter.ExporterParser;
import org.apache.hertzbeat.collector.collect.http.promethus.exporter.MetricFamily;
import org.apache.hertzbeat.collector.dispatch.DispatchConstants;
import org.apache.hertzbeat.collector.util.CollectUtil;
import org.apache.hertzbeat.collector.util.JsonPathParser;
import org.apache.hertzbeat.collector.util.TimeExpressionUtil;
import org.apache.hertzbeat.common.constants.CollectorConstants;
import org.apache.hertzbeat.common.constants.CommonConstants;
import org.apache.hertzbeat.common.entity.job.Metrics;
import org.apache.hertzbeat.common.entity.job.protocol.HttpProtocol;
import org.apache.hertzbeat.common.entity.message.CollectRep;
import org.apache.hertzbeat.common.util.CommonUtil;
import org.apache.hertzbeat.common.util.IpDomainUtil;
import org.apache.http.HttpHeaders;
import org.apache.http.HttpHost;
import org.apache.http.HttpStatus;
import org.apache.http.auth.AuthScope;
import org.apache.http.auth.UsernamePasswordCredentials;
import org.apache.http.client.AuthCache;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.CredentialsProvider;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpUriRequest;
import org.apache.http.client.methods.RequestBuilder;
import org.apache.http.client.protocol.HttpClientContext;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.auth.DigestScheme;
import org.apache.http.impl.client.BasicAuthCache;
import org.apache.http.impl.client.BasicCredentialsProvider;
import org.apache.http.protocol.HttpContext;
import org.apache.http.util.EntityUtils;
import org.springframework.http.HttpMethod;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
/**
* http https collect
*/
@Slf4j
public class HttpCollectImpl extends AbstractCollect {
private static final Map<Long, ExporterParser> EXPORTER_PARSER_TABLE = new ConcurrentHashMap<>();
private final Set<Integer> defaultSuccessStatusCodes = Stream.of(HttpStatus.SC_OK, HttpStatus.SC_CREATED,
HttpStatus.SC_ACCEPTED, HttpStatus.SC_MULTIPLE_CHOICES, HttpStatus.SC_MOVED_PERMANENTLY,
HttpStatus.SC_MOVED_TEMPORARILY).collect(Collectors.toSet());
@Override
public void preCheck(Metrics metrics) throws IllegalArgumentException {
if (metrics == null || metrics.getHttp() == null) {
throw new IllegalArgumentException("Http/Https collect must has http params");
}
}
@Override
public void collect(CollectRep.MetricsData.Builder builder,
long monitorId, String app, Metrics metrics) {
long startTime = System.currentTimeMillis();
HttpProtocol httpProtocol = metrics.getHttp();
String url = httpProtocol.getUrl();
if (!StringUtils.hasText(url) || !url.startsWith(RIGHT_DASH)) {
httpProtocol.setUrl(StringUtils.hasText(url) ? RIGHT_DASH + url.trim() : RIGHT_DASH);
}
if (CollectionUtils.isEmpty(httpProtocol.getSuccessCodes())) {
httpProtocol.setSuccessCodes(List.of("200"));
}
HttpContext httpContext = createHttpContext(metrics.getHttp());
HttpUriRequest request = createHttpRequest(metrics.getHttp());
try (CloseableHttpResponse response = CommonHttpClient.getHttpClient().execute(request, httpContext)) {
int statusCode = response.getStatusLine().getStatusCode();
boolean isSuccessInvoke = checkSuccessInvoke(metrics, statusCode);
log.debug("http response status: {}", statusCode);
if (!isSuccessInvoke) {
builder.setCode(CollectRep.Code.FAIL);
builder.setMsg("StatusCode " + statusCode);
return;
}
// todo This code converts an InputStream directly to a String. For large data in Prometheus exporters,
// this could create large objects, potentially impacting JVM memory space significantly.
// Option 1: Parse using InputStream, but this requires significant code changes;
// Option 2: Manually trigger garbage collection, similar to how it's done in Dubbo for large inputs.
String resp = EntityUtils.toString(response.getEntity(), StandardCharsets.UTF_8);
if (StringUtils.hasText(resp)) {
log.info("http response entity is empty, status: {}.", statusCode);
}
Long responseTime = System.currentTimeMillis() - startTime;
String parseType = metrics.getHttp().getParseType();
try {
switch (parseType) {
case DispatchConstants.PARSE_JSON_PATH ->
parseResponseByJsonPath(resp, metrics.getAliasFields(), metrics.getHttp(), builder, responseTime);
case DispatchConstants.PARSE_PROM_QL ->
parseResponseByPromQl(resp, metrics.getAliasFields(), metrics.getHttp(), builder);
case DispatchConstants.PARSE_PROMETHEUS ->
parseResponseByPrometheusExporter(resp, metrics.getAliasFields(), builder);
case DispatchConstants.PARSE_XML_PATH ->
parseResponseByXmlPath(resp, metrics.getAliasFields(), metrics.getHttp(), builder);
case DispatchConstants.PARSE_WEBSITE ->
parseResponseByWebsite(resp, metrics.getAliasFields(), metrics.getHttp(), builder, responseTime);
case DispatchConstants.PARSE_SITE_MAP ->
parseResponseBySiteMap(resp, metrics.getAliasFields(), builder);
default ->
parseResponseByDefault(resp, metrics.getAliasFields(), metrics.getHttp(), builder, responseTime);
}
} catch (Exception e) {
log.info("parse error: {}.", e.getMessage(), e);
builder.setCode(CollectRep.Code.FAIL);
builder.setMsg("parse response data error:" + e.getMessage());
}
} catch (ClientProtocolException e1) {
String errorMsg = CommonUtil.getMessageFromThrowable(e1);
log.error(errorMsg);
builder.setCode(CollectRep.Code.UN_CONNECTABLE);
builder.setMsg(errorMsg);
} catch (UnknownHostException e2) {
String errorMsg = CommonUtil.getMessageFromThrowable(e2);
log.info(errorMsg);
builder.setCode(CollectRep.Code.UN_REACHABLE);
builder.setMsg("unknown host:" + errorMsg);
} catch (InterruptedIOException | ConnectException | SSLException e3) {
String errorMsg = CommonUtil.getMessageFromThrowable(e3);
log.info(errorMsg);
builder.setCode(CollectRep.Code.UN_CONNECTABLE);
builder.setMsg(errorMsg);
} catch (IOException e4) {
String errorMsg = CommonUtil.getMessageFromThrowable(e4);
log.info(errorMsg);
builder.setCode(CollectRep.Code.FAIL);
builder.setMsg(errorMsg);
} catch (Exception e) {
String errorMsg = CommonUtil.getMessageFromThrowable(e);
log.error(errorMsg, e);
builder.setCode(CollectRep.Code.FAIL);
builder.setMsg(errorMsg);
} finally {
if (request != null) {
request.abort();
}
}
}
@Override
public String supportProtocol() {
return DispatchConstants.PROTOCOL_HTTP;
}
private void parseResponseByWebsite(String resp, List<String> aliasFields, HttpProtocol http,
CollectRep.MetricsData.Builder builder, Long responseTime) {
CollectRep.ValueRow.Builder valueRowBuilder = CollectRep.ValueRow.newBuilder();
int keywordNum = CollectUtil.countMatchKeyword(resp, http.getKeyword());
for (String alias : aliasFields) {
if (CollectorConstants.RESPONSE_TIME.equalsIgnoreCase(alias)) {
valueRowBuilder.addColumns(responseTime.toString());
} else if (CollectorConstants.KEYWORD.equalsIgnoreCase(alias)) {
valueRowBuilder.addColumns(Integer.toString(keywordNum));
} else {
valueRowBuilder.addColumns(CommonConstants.NULL_VALUE);
}
}
builder.addValues(valueRowBuilder.build());
}
private void parseResponseBySiteMap(String resp, List<String> aliasFields,
CollectRep.MetricsData.Builder builder) {
List<String> siteUrls = new LinkedList<>();
boolean isXmlFormat = true;
try {
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
DocumentBuilder db = dbf.newDocumentBuilder();
Document document = db.parse(new ByteArrayInputStream(resp.getBytes(StandardCharsets.UTF_8)));
NodeList urlList = document.getElementsByTagName("url");
for (int i = 0; i < urlList.getLength(); i++) {
Node urlNode = urlList.item(i);
NodeList childNodes = urlNode.getChildNodes();
for (int k = 0; k < childNodes.getLength(); k++) {
Node currentNode = childNodes.item(k);
// distinguish between text nodes and element nodes
if (currentNode.getNodeType() == Node.ELEMENT_NODE && "loc".equals(currentNode.getNodeName())) {
// retrieves the value of the loc node
siteUrls.add(currentNode.getFirstChild().getNodeValue());
break;
}
}
}
} catch (Exception e) {
log.warn(e.getMessage());
isXmlFormat = false;
}
// if XML parsing fails, parse in TXT format
if (!isXmlFormat) {
try {
String[] urls = resp.split("\n");
// validate whether the given value is a URL
if (IpDomainUtil.isHasSchema(urls[0])) {
siteUrls.addAll(Arrays.asList(urls));
}
} catch (Exception e) {
log.warn(e.getMessage(), e);
}
}
// start looping through each site URL to collect its HTTP status code, response time, and exception information
for (String siteUrl : siteUrls) {
String errorMsg = "";
Integer statusCode = null;
long startTime = System.currentTimeMillis();
try {
HttpGet httpGet = new HttpGet(siteUrl);
CloseableHttpResponse response = CommonHttpClient.getHttpClient().execute(httpGet);
statusCode = response.getStatusLine().getStatusCode();
EntityUtils.consume(response.getEntity());
} catch (ClientProtocolException e1) {
if (e1.getCause() != null) {
errorMsg = e1.getCause().getMessage();
} else {
errorMsg = e1.getMessage();
}
} catch (UnknownHostException e2) {
errorMsg = "unknown host";
} catch (InterruptedIOException | ConnectException | SSLException e3) {
errorMsg = "connect error: " + e3.getMessage();
} catch (IOException e4) {
errorMsg = "io error: " + e4.getMessage();
} catch (Exception e) {
errorMsg = "error: " + e.getMessage();
}
long responseTime = System.currentTimeMillis() - startTime;
CollectRep.ValueRow.Builder valueRowBuilder = CollectRep.ValueRow.newBuilder();
for (String alias : aliasFields) {
if (CollectorConstants.URL.equalsIgnoreCase(alias)) {
valueRowBuilder.addColumns(siteUrl);
} else if (CollectorConstants.STATUS_CODE.equalsIgnoreCase(alias)) {
valueRowBuilder.addColumns(statusCode == null
? CommonConstants.NULL_VALUE : String.valueOf(statusCode));
} else if (CollectorConstants.RESPONSE_TIME.equalsIgnoreCase(alias)) {
valueRowBuilder.addColumns(String.valueOf(responseTime));
} else if (CollectorConstants.ERROR_MSG.equalsIgnoreCase(alias)) {
valueRowBuilder.addColumns(errorMsg);
} else {
valueRowBuilder.addColumns(CommonConstants.NULL_VALUE);
}
}
builder.addValues(valueRowBuilder.build());
}
}
private void parseResponseByXmlPath(String resp, List<String> aliasFields, HttpProtocol http,
CollectRep.MetricsData.Builder builder) {
}
private void parseResponseByJsonPath(String resp, List<String> aliasFields, HttpProtocol http,
CollectRep.MetricsData.Builder builder, Long responseTime) {
List<Object> results = JsonPathParser.parseContentWithJsonPath(resp, http.getParseScript());
int keywordNum = CollectUtil.countMatchKeyword(resp, http.getKeyword());
for (int i = 0; i < results.size(); i++) {
Object objectValue = results.get(i);
// if a property is missing or empty due to target version issues, filter it. Refer to the app-elasticsearch.yml configuration under name: nodes
if (objectValue == null) {
continue;
}
if (objectValue instanceof Map) {
Map<String, Object> stringMap = (Map<String, Object>) objectValue;
CollectRep.ValueRow.Builder valueRowBuilder = CollectRep.ValueRow.newBuilder();
for (String alias : aliasFields) {
Object value = stringMap.get(alias);
if (value != null) {
valueRowBuilder.addColumns(String.valueOf(value));
} else {
if (alias.startsWith("$.")) {
List<Object> subResults = JsonPathParser.parseContentWithJsonPath(resp, http.getParseScript() + alias.substring(1));
if (subResults != null && subResults.size() > i) {
Object resultValue = subResults.get(i);
valueRowBuilder.addColumns(resultValue == null ? CommonConstants.NULL_VALUE : String.valueOf(resultValue));
} else {
valueRowBuilder.addColumns(CommonConstants.NULL_VALUE);
}
} else if (CollectorConstants.RESPONSE_TIME.equalsIgnoreCase(alias)) {
valueRowBuilder.addColumns(responseTime.toString());
} else if (CollectorConstants.KEYWORD.equalsIgnoreCase(alias)) {
valueRowBuilder.addColumns(Integer.toString(keywordNum));
} else {
valueRowBuilder.addColumns(CommonConstants.NULL_VALUE);
}
}
}
builder.addValues(valueRowBuilder.build());
} else if (objectValue instanceof String stringValue) {
CollectRep.ValueRow.Builder valueRowBuilder = CollectRep.ValueRow.newBuilder();
for (String alias : aliasFields) {
if (CollectorConstants.RESPONSE_TIME.equalsIgnoreCase(alias)) {
valueRowBuilder.addColumns(responseTime.toString());
} else if (CollectorConstants.KEYWORD.equalsIgnoreCase(alias)) {
valueRowBuilder.addColumns(Integer.toString(keywordNum));
} else {
valueRowBuilder.addColumns(stringValue);
}
}
builder.addValues(valueRowBuilder.build());
}
}
}
private void parseResponseByPromQl(String resp, List<String> aliasFields, HttpProtocol http,
CollectRep.MetricsData.Builder builder) {
AbstractPrometheusParse prometheusParser = PrometheusParseCreater.getPrometheusParse();
prometheusParser.handle(resp, aliasFields, http, builder);
}
private void parseResponseByPrometheusExporter(String resp, List<String> aliasFields,
CollectRep.MetricsData.Builder builder) {
if (!EXPORTER_PARSER_TABLE.containsKey(builder.getId())) {
EXPORTER_PARSER_TABLE.put(builder.getId(), new ExporterParser());
}
ExporterParser parser = EXPORTER_PARSER_TABLE.get(builder.getId());
Map<String, MetricFamily> metricFamilyMap = parser.textToMetric(resp);
String metrics = builder.getMetrics();
if (metricFamilyMap.containsKey(metrics)) {
MetricFamily metricFamily = metricFamilyMap.get(metrics);
for (MetricFamily.Metric metric : metricFamily.getMetricList()) {
Map<String, String> labelMap = metric.getLabelPair()
.stream()
.collect(Collectors.toMap(MetricFamily.Label::getName, MetricFamily.Label::getValue));
CollectRep.ValueRow.Builder valueRowBuilder = CollectRep.ValueRow.newBuilder();
for (String aliasField : aliasFields) {
if ("value".equals(aliasField)) {
if (metric.getCounter() != null) {
valueRowBuilder.addColumns(String.valueOf(metric.getCounter().getValue()));
} else if (metric.getGauge() != null) {
valueRowBuilder.addColumns(String.valueOf(metric.getGauge().getValue()));
} else if (metric.getUntyped() != null) {
valueRowBuilder.addColumns(String.valueOf(metric.getUntyped().getValue()));
} else if (metric.getInfo() != null) {
valueRowBuilder.addColumns(String.valueOf(metric.getInfo().getValue()));
} else if (metric.getSummary() != null) {
valueRowBuilder.addColumns(String.valueOf(metric.getSummary().getValue()));
} else if (metric.getHistogram() != null) {
valueRowBuilder.addColumns(String.valueOf(metric.getHistogram().getValue()));
}
} else {
String columnValue = labelMap.get(aliasField);
valueRowBuilder.addColumns(columnValue == null ? CommonConstants.NULL_VALUE : columnValue);
}
}
builder.addValues(valueRowBuilder.build());
}
}
}
private void parseResponseByDefault(String resp, List<String> aliasFields, HttpProtocol http,
CollectRep.MetricsData.Builder builder, Long responseTime) {
JsonElement element = JsonParser.parseString(resp);
int keywordNum = CollectUtil.countMatchKeyword(resp, http.getKeyword());
if (element.isJsonArray()) {
JsonArray array = element.getAsJsonArray();
for (JsonElement jsonElement : array) {
getValueFromJson(aliasFields, builder, responseTime, jsonElement, keywordNum);
}
} else {
getValueFromJson(aliasFields, builder, responseTime, element, keywordNum);
}
}
private void getValueFromJson(List<String> aliasFields, CollectRep.MetricsData.Builder builder, Long responseTime, JsonElement element, int keywordNum) {
if (element.isJsonObject()) {
JsonObject object = element.getAsJsonObject();
CollectRep.ValueRow.Builder valueRowBuilder = CollectRep.ValueRow.newBuilder();
for (String alias : aliasFields) {
JsonElement valueElement = object.get(alias);
if (valueElement != null) {
String value = valueElement.getAsString();
valueRowBuilder.addColumns(value);
} else {
if (CollectorConstants.RESPONSE_TIME.equalsIgnoreCase(alias)) {
valueRowBuilder.addColumns(responseTime.toString());
} else if (CollectorConstants.KEYWORD.equalsIgnoreCase(alias)) {
valueRowBuilder.addColumns(Integer.toString(keywordNum));
} else {
valueRowBuilder.addColumns(CommonConstants.NULL_VALUE);
}
}
}
builder.addValues(valueRowBuilder.build());
}
}
/**
* create httpContext
*
* @param httpProtocol http protocol
* @return context
*/
public HttpContext createHttpContext(HttpProtocol httpProtocol) {
HttpProtocol.Authorization auth = httpProtocol.getAuthorization();
if (auth != null && DispatchConstants.DIGEST_AUTH.equals(auth.getType())) {
HttpClientContext clientContext = new HttpClientContext();
if (StringUtils.hasText(auth.getDigestAuthUsername())
&& StringUtils.hasText(auth.getDigestAuthPassword())) {
CredentialsProvider provider = new BasicCredentialsProvider();
UsernamePasswordCredentials credentials = new UsernamePasswordCredentials(auth.getDigestAuthUsername(),
auth.getDigestAuthPassword());
provider.setCredentials(AuthScope.ANY, credentials);
AuthCache authCache = new BasicAuthCache();
authCache.put(new HttpHost(httpProtocol.getHost(), Integer.parseInt(httpProtocol.getPort())), new DigestScheme());
clientContext.setCredentialsProvider(provider);
clientContext.setAuthCache(authCache);
return clientContext;
}
}
return null;
}
/**
* create http request
*
* @param httpProtocol http params
* @return http uri request
*/
public HttpUriRequest createHttpRequest(HttpProtocol httpProtocol) {
RequestBuilder requestBuilder;
String httpMethod = httpProtocol.getMethod().toUpperCase();
if (HttpMethod.GET.matches(httpMethod)) {
requestBuilder = RequestBuilder.get();
} else if (HttpMethod.POST.matches(httpMethod)) {
requestBuilder = RequestBuilder.post();
} else if (HttpMethod.PUT.matches(httpMethod)) {
requestBuilder = RequestBuilder.put();
} else if (HttpMethod.DELETE.matches(httpMethod)) {
requestBuilder = RequestBuilder.delete();
} else if (HttpMethod.PATCH.matches(httpMethod)) {
requestBuilder = RequestBuilder.patch();
} else {
// not support the method
log.error("not support the http method: {}.", httpProtocol.getMethod());
return null;
}
// params
Map<String, String> params = httpProtocol.getParams();
if (params != null && !params.isEmpty()) {
for (Map.Entry<String, String> param : params.entrySet()) {
if (StringUtils.hasText(param.getValue())) {
requestBuilder.addParameter(param.getKey(), TimeExpressionUtil.calculate(param.getValue()));
}
}
}
// The default request header can be overridden if customized
// keep-alive
requestBuilder.addHeader(HttpHeaders.CONNECTION, "keep-alive");
requestBuilder.addHeader(HttpHeaders.USER_AGENT, "Mozilla/5.0 (Windows NT 6.1; WOW64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2272.76 Safari/537.36");
// headers The custom request header is overwritten here
Map<String, String> headers = httpProtocol.getHeaders();
if (headers != null && !headers.isEmpty()) {
for (Map.Entry<String, String> header : headers.entrySet()) {
if (StringUtils.hasText(header.getValue())) {
requestBuilder.addHeader(CollectUtil.replaceUriSpecialChar(header.getKey()),
CollectUtil.replaceUriSpecialChar(header.getValue()));
}
}
}
// add accept
if (DispatchConstants.PARSE_DEFAULT.equals(httpProtocol.getParseType())
|| DispatchConstants.PARSE_JSON_PATH.equals(httpProtocol.getParseType())) {
requestBuilder.addHeader(HttpHeaders.ACCEPT, "application/json");
} else if (DispatchConstants.PARSE_XML_PATH.equals(httpProtocol.getParseType())) {
requestBuilder.addHeader(HttpHeaders.ACCEPT, "text/xml,application/xml");
} else {
requestBuilder.addHeader(HttpHeaders.ACCEPT, "*/*");
}
if (httpProtocol.getAuthorization() != null) {
HttpProtocol.Authorization authorization = httpProtocol.getAuthorization();
if (DispatchConstants.BEARER_TOKEN.equalsIgnoreCase(authorization.getType())) {
String value = DispatchConstants.BEARER + " " + authorization.getBearerTokenToken();
requestBuilder.addHeader(HttpHeaders.AUTHORIZATION, value);
} else if (DispatchConstants.BASIC_AUTH.equals(authorization.getType())) {
if (StringUtils.hasText(authorization.getBasicAuthUsername())
&& StringUtils.hasText(authorization.getBasicAuthPassword())) {
String authStr = authorization.getBasicAuthUsername() + ":" + authorization.getBasicAuthPassword();
String encodedAuth = new String(Base64.encodeBase64(authStr.getBytes(StandardCharsets.UTF_8)), StandardCharsets.UTF_8);
requestBuilder.addHeader(HttpHeaders.AUTHORIZATION, DispatchConstants.BASIC + " " + encodedAuth);
}
}
}
// if it has payload, would override post params
if (StringUtils.hasLength(httpProtocol.getPayload())) {
requestBuilder.setEntity(new StringEntity(httpProtocol.getPayload(), StandardCharsets.UTF_8));
}
// uri
String uri = CollectUtil.replaceUriSpecialChar(httpProtocol.getUrl());
if (IpDomainUtil.isHasSchema(httpProtocol.getHost())) {
requestBuilder.setUri(httpProtocol.getHost() + ":" + httpProtocol.getPort() + uri);
} else {
String ipAddressType = IpDomainUtil.checkIpAddressType(httpProtocol.getHost());
String baseUri = CollectorConstants.IPV6.equals(ipAddressType)
? String.format("[%s]:%s%s", httpProtocol.getHost(), httpProtocol.getPort(), uri)
: String.format("%s:%s%s", httpProtocol.getHost(), httpProtocol.getPort(), uri);
boolean ssl = Boolean.parseBoolean(httpProtocol.getSsl());
if (ssl) {
requestBuilder.setUri(CollectorConstants.HTTPS_HEADER + baseUri);
} else {
requestBuilder.setUri(CollectorConstants.HTTP_HEADER + baseUri);
}
}
// custom timeout
int timeout = CollectUtil.getTimeout(httpProtocol.getTimeout(), 0);
if (timeout > 0) {
RequestConfig requestConfig = RequestConfig.custom()
.setConnectTimeout(timeout)
.setSocketTimeout(timeout)
.setRedirectsEnabled(true)
.build();
requestBuilder.setConfig(requestConfig);
}
return requestBuilder.build();
}
private boolean checkSuccessInvoke(Metrics metrics, int statusCode) {
List<String> successCodes = metrics.getHttp().getSuccessCodes();
Set<Integer> successCodeSet = successCodes != null ? successCodes.stream().map(code -> {
try {
return Integer.valueOf(code);
} catch (Exception ignored) {
return null;
}
}).filter(Objects::nonNull).collect(Collectors.toSet()) : defaultSuccessStatusCodes;
if (successCodeSet.isEmpty()) {
successCodeSet = defaultSuccessStatusCodes;
}
return successCodeSet.contains(statusCode);
}
}
@@ -1,163 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.hertzbeat.collector.collect.http;
import static org.apache.hertzbeat.common.constants.SignConstants.RIGHT_DASH;
import java.io.IOException;
import java.io.InterruptedIOException;
import java.net.ConnectException;
import java.net.URL;
import java.net.UnknownHostException;
import java.security.cert.Certificate;
import java.security.cert.X509Certificate;
import java.util.Date;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLException;
import javax.net.ssl.SSLPeerUnverifiedException;
import lombok.extern.slf4j.Slf4j;
import org.apache.hertzbeat.collector.collect.AbstractCollect;
import org.apache.hertzbeat.collector.dispatch.DispatchConstants;
import org.apache.hertzbeat.common.constants.CollectorConstants;
import org.apache.hertzbeat.common.constants.CommonConstants;
import org.apache.hertzbeat.common.entity.job.Metrics;
import org.apache.hertzbeat.common.entity.job.protocol.HttpProtocol;
import org.apache.hertzbeat.common.entity.message.CollectRep;
import org.apache.hertzbeat.common.util.CommonUtil;
import org.apache.hertzbeat.common.util.IpDomainUtil;
import org.springframework.util.StringUtils;
/**
* ssl Certificate
*/
@Slf4j
public class SslCertificateCollectImpl extends AbstractCollect {
private static final String NAME_SUBJECT = "subject";
private static final String NAME_EXPIRED = "expired";
private static final String NAME_START_TIME = "start_time";
private static final String NAME_START_TIMESTAMP = "start_timestamp";
private static final String NAME_END_TIME = "end_time";
private static final String NAME_END_TIMESTAMP = "end_timestamp";
@Override
public void preCheck(Metrics metrics) throws IllegalArgumentException {
if (metrics == null || metrics.getHttp() == null) {
throw new IllegalArgumentException("Http/Https collect must has http params");
}
}
@Override
public void collect(CollectRep.MetricsData.Builder builder,
long monitorId, String app, Metrics metrics) {
long startTime = System.currentTimeMillis();
HttpProtocol httpProtocol = metrics.getHttp();
String url = httpProtocol.getUrl();
if (!StringUtils.hasText(url) || !url.startsWith(RIGHT_DASH)) {
httpProtocol.setUrl(StringUtils.hasText(url) ? RIGHT_DASH + url.trim() : RIGHT_DASH);
}
HttpsURLConnection urlConnection = null;
try {
String uri = "";
if (IpDomainUtil.isHasSchema(httpProtocol.getHost())) {
uri = httpProtocol.getHost() + ":" + httpProtocol.getPort();
} else {
uri = "https://" + httpProtocol.getHost() + ":" + httpProtocol.getPort();
}
urlConnection = (HttpsURLConnection) new URL(uri).openConnection();
urlConnection.connect();
Certificate[] certificates = urlConnection.getServerCertificates();
if (certificates == null || certificates.length == 0) {
builder.setCode(CollectRep.Code.FAIL);
builder.setMsg("Ssl certificate does not exist.");
return;
}
long responseTime = System.currentTimeMillis() - startTime;
for (Certificate certificate : urlConnection.getServerCertificates()) {
X509Certificate x509Certificate = (X509Certificate) certificate;
Date now = new Date();
Date deadline = x509Certificate.getNotAfter();
boolean expired = deadline != null && now.after(deadline);
CollectRep.ValueRow.Builder valueRowBuilder = CollectRep.ValueRow.newBuilder();
for (String alias : metrics.getAliasFields()) {
if (CollectorConstants.RESPONSE_TIME.equalsIgnoreCase(alias)) {
valueRowBuilder.addColumns(Long.toString(responseTime));
} else if (NAME_SUBJECT.equalsIgnoreCase(alias)) {
valueRowBuilder.addColumns(x509Certificate.getSubjectX500Principal().getName());
} else if (NAME_EXPIRED.equalsIgnoreCase(alias)) {
valueRowBuilder.addColumns(Boolean.toString(expired));
} else if (NAME_START_TIME.equalsIgnoreCase(alias)) {
valueRowBuilder.addColumns(x509Certificate.getNotBefore().toLocaleString());
} else if (NAME_START_TIMESTAMP.equalsIgnoreCase(alias)) {
valueRowBuilder.addColumns(String.valueOf(x509Certificate.getNotBefore().getTime()));
} else if (NAME_END_TIME.equalsIgnoreCase(alias)) {
valueRowBuilder.addColumns(x509Certificate.getNotAfter().toLocaleString());
} else if (NAME_END_TIMESTAMP.equalsIgnoreCase(alias)) {
valueRowBuilder.addColumns(String.valueOf(x509Certificate.getNotAfter().getTime()));
} else {
valueRowBuilder.addColumns(CommonConstants.NULL_VALUE);
}
}
builder.addValues(valueRowBuilder.build());
}
} catch (SSLPeerUnverifiedException e1) {
String errorMsg = "Ssl certificate does not exist.";
if (e1.getMessage() != null) {
errorMsg = e1.getMessage();
log.error(errorMsg);
}
builder.setCode(CollectRep.Code.FAIL);
builder.setMsg(errorMsg);
} catch (UnknownHostException e2) {
String errorMsg = CommonUtil.getMessageFromThrowable(e2);
log.info(errorMsg);
builder.setCode(CollectRep.Code.UN_REACHABLE);
builder.setMsg("unknown host:" + errorMsg);
} catch (InterruptedIOException | ConnectException | SSLException e3) {
String errorMsg = CommonUtil.getMessageFromThrowable(e3);
log.info(errorMsg);
builder.setCode(CollectRep.Code.UN_CONNECTABLE);
builder.setMsg(errorMsg);
} catch (IOException e4) {
String errorMsg = CommonUtil.getMessageFromThrowable(e4);
log.info(errorMsg);
builder.setCode(CollectRep.Code.FAIL);
builder.setMsg(errorMsg);
} catch (Exception e) {
String errorMsg = CommonUtil.getMessageFromThrowable(e);
log.error(errorMsg, e);
builder.setCode(CollectRep.Code.FAIL);
builder.setMsg(errorMsg);
} finally {
if (urlConnection != null) {
urlConnection.disconnect();
}
}
}
@Override
public String supportProtocol() {
return DispatchConstants.PROTOCOL_SSL_CERT;
}
private void validateParams(Metrics metrics) {
}
}
@@ -1,44 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.hertzbeat.collector.collect.http.promethus;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.stereotype.Component;
/**
* prometheus parse creater
*/
@Slf4j
@Component
public class PrometheusParseCreater implements InitializingBean {
private static AbstractPrometheusParse PROMETHEUSPARSE = new PrometheusVectorParser();
private static void create() {
PROMETHEUSPARSE.setInstance(new PrometheusMatrixParser().setInstance(new PrometheusLastParser()));
}
public static AbstractPrometheusParse getPrometheusParse(){
return PROMETHEUSPARSE;
}
@Override
public void afterPropertiesSet() throws Exception {
create();
}
}
@@ -1,429 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.hertzbeat.collector.collect.http.promethus.exporter;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
import lombok.extern.slf4j.Slf4j;
import org.apache.hertzbeat.collector.collect.http.promethus.ParseException;
import org.apache.hertzbeat.common.util.StrBuffer;
/**
* Resolves the data passed by prometheus's exporter interface http:xxx/metrics
* Reference: prometheus text_parse.go code, entry: TextToMetricFamilies
*/
@Slf4j
public class ExporterParser {
private static final String HELP = "HELP";
private static final String TYPE = "TYPE";
private static final String EOF = "EOF";
private static final String METRIC_NAME_LABEL = ".name";
private static final String QUANTILE_LABEL = "quantile";
private static final String BUCKET_LABEL = "le";
private static final String NAME_LABEL = "__name__";
private static final String SUM_SUFFIX = "_sum";
private static final String COUNT_SUFFIX = "_count";
private static final char LEFT_CURLY_BRACKET = '{';
private static final char RIGHT_CURLY_BRACKET = '}';
private static final char EQUALS = '=';
private static final char QUOTES = '"';
private static final char ENTER = '\n';
private static final char SPACE = ' ';
private static final char COMMA = ',';
private final Lock lock = new ReentrantLock();
private MetricFamily currentMetricFamily;
private String currentQuantile;
private String currentBucket;
public Map<String, MetricFamily> textToMetric(String resp) {
// key: metric name, value: metric family
Map<String, MetricFamily> metricMap = new ConcurrentHashMap<>(10);
lock.lock();
try {
String[] lines = resp.split("\n");
for (String line : lines) {
this.parseLine(metricMap, new StrBuffer(line));
}
return metricMap;
} catch (Exception e) {
log.error("parse prometheus exporter data error, msg: {}", e.getMessage());
} finally {
lock.unlock();
}
return metricMap;
}
private void parseLine(Map<String, MetricFamily> metricMap, StrBuffer buffer) {
buffer.skipBlankTabs();
if (buffer.isEmpty()) return;
switch (buffer.charAt(0)) {
case '#' -> {
buffer.read();
this.currentMetricFamily = null;
this.parseComment(metricMap, buffer);
}
case ENTER -> {
}
default -> {
this.currentBucket = null;
this.currentQuantile = null;
this.parseMetric(buffer);
}
}
}
private void parseComment(Map<String, MetricFamily> metricMap, StrBuffer buffer) {
buffer.skipBlankTabs();
if (buffer.isEmpty()) {
return;
}
String token = this.readTokenUnitWhitespace(buffer);
if (EOF.equals(token)) {
return;
}
if (!HELP.equals(token) && !TYPE.equals(token)) {
log.error("parse comment error {}, start without {} or {}", buffer.toStr(), HELP, TYPE);
return;
}
String metricName = this.readTokenAsMetricName(buffer);
this.currentMetricFamily = metricMap.computeIfAbsent(metricName, key -> new MetricFamily());
this.currentMetricFamily.setName(metricName);
switch (token) {
case HELP -> this.parseHelp(buffer);
case TYPE -> this.parseType(buffer);
default -> {
}
}
}
private void parseHelp(StrBuffer line) {
line.skipBlankTabs();
this.currentMetricFamily.setHelp(line.toStr());
}
private void parseType(StrBuffer line) {
line.skipBlankTabs();
String type = line.toStr().toLowerCase();
MetricType metricType = MetricType.getType(type);
if (metricType == null) {
throw new ParseException("pare type error");
}
this.currentMetricFamily.setMetricType(metricType);
}
private void parseMetric(StrBuffer buffer) {
String metricName = this.readTokenAsMetricName(buffer);
MetricFamily.Label label = new MetricFamily.Label();
label.setName(METRIC_NAME_LABEL);
label.setValue(metricName);
if (metricName.isEmpty()) {
log.error("error parse metric, metric name is null, line: {}", buffer.toStr());
return;
}
List<MetricFamily.Metric> metricList = this.currentMetricFamily.getMetricList();
if (metricList == null) {
metricList = new ArrayList<>();
this.currentMetricFamily.setMetricList(metricList);
}
// TODO For the time being, the data is displayed in the form of labels. If there is a better chart display method in the future, we will optimize it.
MetricFamily.Metric metric = new MetricFamily.Metric();
metricList.add(metric);
metric.setLabelPair(new ArrayList<>());
metric.getLabelPair().add(label);
this.readLabels(metric, buffer);
}
private void readLabels(MetricFamily.Metric metric, StrBuffer buffer) {
buffer.skipBlankTabs();
if (buffer.isEmpty()) {
return;
}
if (buffer.charAt(0) == LEFT_CURLY_BRACKET) {
buffer.read();
this.startReadLabelName(metric, buffer);
} else {
this.readLabelValue(metric, null, buffer);
}
}
private void startReadLabelName(MetricFamily.Metric metric, StrBuffer buffer) {
buffer.skipBlankTabs();
if (buffer.isEmpty()) {
return;
}
if (buffer.charAt(0) == RIGHT_CURLY_BRACKET) {
buffer.read();
buffer.skipBlankTabs();
if (buffer.isEmpty()) {
return;
}
this.readLabelValue(metric, new MetricFamily.Label(), buffer);
return;
}
String labelName = this.readTokenAsLabelName(buffer);
if (labelName.isEmpty() || labelName.equals(NAME_LABEL)) {
throw new ParseException("invalid label name" + labelName + ", label name size = 0 or label name equals " + NAME_LABEL);
}
MetricFamily.Label label = new MetricFamily.Label();
label.setName(labelName);
if (buffer.read() != EQUALS) {
throw new ParseException("parse error, not match the format of labelName=labelValue");
}
this.startReadLabelValue(metric, label, buffer);
}
private void startReadLabelValue(MetricFamily.Metric metric, MetricFamily.Label label, StrBuffer buffer) {
buffer.skipBlankTabs();
if (buffer.isEmpty()) {
return;
}
char c = buffer.read();
if (c != QUOTES) {
throw new ParseException("expected '\"' at start of label value, line: " + buffer.toStr());
}
String labelValue = this.readTokenAsLabelValue(buffer);
label.setValue(labelValue);
if (!this.isValidLabelValue(labelValue)) {
throw new ParseException("no valid label value: " + labelValue);
}
if (this.currentMetricFamily.getMetricType().equals(MetricType.SUMMARY) && label.getName().equals(QUANTILE_LABEL)) {
this.currentQuantile = labelValue;
} else if (this.currentMetricFamily.getMetricType().equals(MetricType.HISTOGRAM) && label.getName().equals(BUCKET_LABEL)) {
this.currentBucket = labelValue;
}
metric.getLabelPair().add(label);
if (buffer.isEmpty()) {
return;
}
c = buffer.read();
switch (c) {
case COMMA -> this.startReadLabelName(metric, buffer);
case RIGHT_CURLY_BRACKET -> this.readLabelValue(metric, label, buffer);
default -> throw new ParseException("expected '}' or ',' at end of label value, line: " + buffer.toStr());
}
}
private void readLabelValue(MetricFamily.Metric metric, MetricFamily.Label label, StrBuffer buffer) {
buffer.skipBlankTabs();
if (buffer.isEmpty()) return;
switch (this.currentMetricFamily.getMetricType()) {
case INFO -> {
MetricFamily.Info info = new MetricFamily.Info();
info.setValue(buffer.toDouble());
metric.setInfo(info);
}
case COUNTER -> {
MetricFamily.Counter counter = new MetricFamily.Counter();
counter.setValue(buffer.toDouble());
metric.setCounter(counter);
}
case GAUGE -> {
MetricFamily.Gauge gauge = new MetricFamily.Gauge();
gauge.setValue(buffer.toDouble());
metric.setGauge(gauge);
}
case UNTYPED -> {
MetricFamily.Untyped untyped = new MetricFamily.Untyped();
untyped.setValue(buffer.toDouble());
metric.setUntyped(untyped);
}
case SUMMARY -> {
// For the time being, the data is displayed in the form of labels. If there is a better chart display method in the future, we will optimize it.
MetricFamily.Summary summary = new MetricFamily.Summary();
summary.setValue(buffer.toDouble());
metric.setSummary(summary);
}
case HISTOGRAM -> {
// For the time being, the data is displayed in the form of labels. If there is a better chart display method in the future, we will optimize it.
MetricFamily.Histogram histogram = new MetricFamily.Histogram();
histogram.setValue(buffer.toDouble());
metric.setHistogram(histogram);
}
default -> throw new ParseException("no such type in metricFamily");
}
}
/**
* Reads the token before the first whitespace
*
* @param buffer A line data object
* @return token unit
*/
private String readTokenUnitWhitespace(StrBuffer buffer) {
StringBuilder builder = new StringBuilder();
while (!buffer.isEmpty()) {
char c = buffer.read();
if (c == SPACE) {
break;
}
builder.append(c);
}
return builder.toString();
}
/**
* Gets the name of the metric
*
* @param buffer A line data object
* @return token name
*/
private String readTokenAsMetricName(StrBuffer buffer) {
buffer.skipBlankTabs();
StringBuilder builder = new StringBuilder();
if (this.isValidMetricNameStart(buffer.charAt(0))) {
while (!buffer.isEmpty()) {
char c = buffer.read();
if (!this.isValidMetricNameContinuation(c)) {
buffer.rollback();
break;
}
builder.append(c);
}
return builder.toString();
}
throw new ParseException("parse metric name error");
}
/**
* Gets the name of the label
*
* @param buffer A line data object
* @return label name
*/
private String readTokenAsLabelName(StrBuffer buffer) {
buffer.skipBlankTabs();
StringBuilder builder = new StringBuilder();
char c = buffer.read();
if (this.isValidLabelNameStart(c)) {
builder.append(c);
while (!buffer.isEmpty()) {
c = buffer.read();
if (!this.isValidLabelNameContinuation(c)) {
buffer.rollback();
break;
}
builder.append(c);
}
return builder.toString();
}
throw new ParseException("parse label name error");
}
/**
* Gets the value of the label
*
* @param buffer A line data object
* @return label value
*/
private String readTokenAsLabelValue(StrBuffer buffer) {
StringBuilder builder = new StringBuilder();
boolean escaped = false;
while (!buffer.isEmpty()) {
char c = buffer.read();
// Handle '\\' escape sequences
if (escaped) {
switch (c) {
case QUOTES, '\\' -> builder.append(c);
case 'n' -> builder.append('\n');
default -> throw new ParseException("parse label value error");
}
escaped = false;
} else {
switch (c) {
case QUOTES -> {
return builder.toString();
}
case ENTER -> throw new ParseException("parse label value error, next line");
case '\\' -> escaped = true;
default -> builder.append(c);
}
}
}
return builder.toString();
}
/**
* Checks whether a character conforms to the first character rule for metric names
*
* @param c metric character
* @return true/false
*/
private boolean isValidMetricNameStart(char c) {
return isValidLabelNameStart(c) || c == ':';
}
/**
* Checks whether a character conforms to rules for metric name characters other than the first
*
* @param c metric character
* @return true/false
*/
private boolean isValidMetricNameContinuation(char c) {
return isValidLabelNameContinuation(c) || c == ':';
}
/**
* Checks whether a character conforms to the first character rule for label names
*
* @param c metric character
* @return true/false
*/
private boolean isValidLabelNameStart(char c) {
return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || c == '_';
}
/**
* Checks whether a character conforms to rules for label name characters other than the first
*
* @param c metric character
* @return true/false
*/
private boolean isValidLabelNameContinuation(char c) {
return isValidLabelNameStart(c) || (c >= '0' && c <= '9');
}
/**
* Checks if a string is a valid UTF-8 encoded string
*
* @param s label value
* @return true/false
*/
private boolean isValidLabelValue(String s) {
return s != null && s.equals(new String(s.getBytes(StandardCharsets.UTF_8)));
}
private boolean isSum(String s) {
return s != null && s.endsWith(SUM_SUFFIX);
}
private boolean isCount(String s) {
return s != null && s.endsWith(COUNT_SUFFIX);
}
}
@@ -1,252 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.hertzbeat.collector.collect.http.promethus.exporter;
import java.util.ArrayList;
import java.util.List;
import lombok.Data;
import lombok.ToString;
/**
* MetricFamily.
*/
@Data
@ToString
public class MetricFamily {
/**
* metric name
*/
private String name;
/**
* metric help
*/
private String help;
/**
* metric type
*/
private MetricType metricType;
/**
* Specific metric
*/
private List<Metric> metricList;
/**
* Metric
*/
@Data
public static class Metric {
/**
* Label data, mainly corresponding to the content within {}
*/
private List<Label> labelPair;
/**
* info
*/
private Info info;
/**
* gauge
*/
private Gauge gauge;
/**
* counter
*/
private Counter counter;
/**
* summary
*/
private Summary summary;
/**
* untyped
*/
private Untyped untyped;
/**
* histogram
*/
private Histogram histogram;
/**
* timestampMs
*/
private Long timestampMs;
}
/**
* Label
*/
@Data
public static class Label {
/**
* name
*/
private String name;
/**
* value
*/
private String value;
}
/**
* Info
*/
@Data
public static class Info {
/**
* value
*/
private double value;
}
/**
* Counter
*/
@Data
public static class Counter {
/**
* value
*/
private double value;
// Exemplar
}
/**
* Gauge
*/
@Data
public static class Gauge {
/**
* value
*/
private double value;
}
/**
* untyped
*/
@Data
public static class Untyped {
/**
* value
*/
private double value;
}
/**
* Summary
*/
@Data
public static class Summary {
/**
* value
*/
private double value;
/**
* count
*/
private long count;
/**
* sum
*/
private double sum;
/**
* quantileList
*/
private List<Quantile> quantileList = new ArrayList<>();
}
/**
* Quantile
*/
@Data
public static class Quantile {
/**
* Corresponding to the quantile field in Prometheus
*/
private double xLabel;
/**
* value
*/
private double value;
}
/**
* Histogram
*/
@Data
public static class Histogram {
/**
* value
*/
private double value;
/**
* count
*/
private long count;
/**
* sum
*/
private double sum;
/**
* bucketList
*/
private List<Bucket> bucketList = new ArrayList<>();
}
/**
* Bucket
*/
@Data
public static class Bucket {
/**
* cumulativeCount
*/
private long cumulativeCount;
/**
* upperBound
*/
private double upperBound;
}
}
@@ -1,52 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.hertzbeat.collector.collect.http.promethus.exporter;
/**
* prometheus metrics type
*/
public enum MetricType {
// for string metric info
INFO("info"),
// Represents a monotonically increasing counter, e.g., counting occurrences
COUNTER("counter"),
// A metric type that can fluctuate up and down, e.g., CPU usage rate
GAUGE("gauge"),
SUMMARY("summary"),
UNTYPED("untyped"),
HISTOGRAM("histogram");
private final String value;
MetricType(String value) {
this.value = value;
}
public String getValue() {
return value;
}
public static MetricType getType(String value) {
for (MetricType metricType : values()) {
if (metricType.getValue().equals(value)) {
return metricType;
}
}
return null;
}
}
@@ -1,127 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.hertzbeat.collector.collect.httpsd;
import com.ecwid.consul.transport.TransportException;
import com.google.common.annotations.VisibleForTesting;
import java.lang.reflect.Field;
import java.util.Objects;
import lombok.Setter;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.hertzbeat.collector.collect.AbstractCollect;
import org.apache.hertzbeat.collector.collect.httpsd.discovery.DiscoveryClient;
import org.apache.hertzbeat.collector.collect.httpsd.discovery.DiscoveryClientManagement;
import org.apache.hertzbeat.collector.collect.httpsd.discovery.entity.ServerInfo;
import org.apache.hertzbeat.collector.dispatch.DispatchConstants;
import org.apache.hertzbeat.common.constants.CollectorConstants;
import org.apache.hertzbeat.common.constants.CommonConstants;
import org.apache.hertzbeat.common.entity.job.Metrics;
import org.apache.hertzbeat.common.entity.job.protocol.HttpsdProtocol;
import org.apache.hertzbeat.common.entity.message.CollectRep;
import org.apache.hertzbeat.common.util.CommonUtil;
/**
* http_sd protocol collection implementation
*/
@Slf4j
public class HttpsdImpl extends AbstractCollect {
private static final String SERVER = "server";
@Setter
@VisibleForTesting
private DiscoveryClientManagement discoveryClientManagement = new DiscoveryClientManagement();
@Override
public void preCheck(Metrics metrics) throws IllegalArgumentException {
HttpsdProtocol httpsdProtocol = metrics.getHttpsd();
if (Objects.isNull(httpsdProtocol) || httpsdProtocol.isInvalid()){
throw new IllegalArgumentException("http_sd collect must have a valid http_sd protocol param! ");
}
}
@Override
public void collect(CollectRep.MetricsData.Builder builder, long monitorId, String app, Metrics metrics) {
HttpsdProtocol httpsdProtocol = metrics.getHttpsd();
try (DiscoveryClient discoveryClient = discoveryClientManagement.getClient(httpsdProtocol)) {
collectMetrics(builder, metrics, discoveryClient);
} catch (TransportException e1) {
String errorMsg = "Consul " + CommonUtil.getMessageFromThrowable(e1);
log.error(errorMsg);
builder.setCode(CollectRep.Code.FAIL);
builder.setMsg(errorMsg);
} catch (Exception e) {
String errorMsg = CommonUtil.getMessageFromThrowable(e);
log.error(errorMsg, e);
builder.setCode(CollectRep.Code.FAIL);
builder.setMsg(errorMsg);
}
}
private void collectMetrics(CollectRep.MetricsData.Builder builder, Metrics metrics, DiscoveryClient discoveryClient) {
long beginTime = System.currentTimeMillis();
// Available and Server monitor
if (StringUtils.equals(metrics.getName(), SERVER)) {
CollectRep.ValueRow.Builder valueRowBuilder = CollectRep.ValueRow.newBuilder();
ServerInfo serverInfo = discoveryClient.getServerInfo();
metrics.getAliasFields().forEach(fieldName -> {
if (StringUtils.equalsAnyIgnoreCase(CollectorConstants.RESPONSE_TIME, fieldName)) {
valueRowBuilder.addColumns(String.valueOf(System.currentTimeMillis() - beginTime));
} else {
addColumnIfMatched(fieldName, serverInfo, valueRowBuilder);
}
});
builder.addValues(valueRowBuilder.build());
} else {
// Service instances monitor
discoveryClient.getServices().forEach(serviceInstance -> {
CollectRep.ValueRow.Builder valueRowBuilder = CollectRep.ValueRow.newBuilder();
metrics.getAliasFields().forEach(fieldName -> addColumnIfMatched(fieldName, serviceInstance, valueRowBuilder));
builder.addValues(valueRowBuilder.build());
});
}
}
@Override
public String supportProtocol() {
return DispatchConstants.PROTOCOL_HTTP_SD;
}
private boolean checkParamsFailed(HttpsdProtocol httpsd) {
return Objects.isNull(httpsd) || httpsd.isInvalid();
}
private void addColumnIfMatched(String fieldName, Object sourceObj, CollectRep.ValueRow.Builder valueRowBuilder) {
String columnValue = null;
try {
Field declaredField = sourceObj.getClass().getDeclaredField(fieldName);
declaredField.setAccessible(Boolean.TRUE);
columnValue = String.valueOf(declaredField.get(sourceObj));
} catch (NoSuchFieldException | IllegalAccessException e) {
log.warn("No such field for {}", fieldName);
}
valueRowBuilder.addColumns(StringUtils.isBlank(columnValue)
? CommonConstants.NULL_VALUE
: columnValue);
}
}
@@ -1,64 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.hertzbeat.collector.collect.httpsd.discovery;
import java.util.List;
import org.apache.hertzbeat.collector.collect.httpsd.discovery.entity.ConnectConfig;
import org.apache.hertzbeat.collector.collect.httpsd.discovery.entity.ServerInfo;
import org.apache.hertzbeat.collector.collect.httpsd.discovery.entity.ServiceInstance;
import org.apache.hertzbeat.common.entity.job.protocol.HttpsdProtocol;
/**
* DiscoveryClient interface.
*/
public interface DiscoveryClient extends AutoCloseable {
/**
* Build connect config.
* @param httpsdProtocol httpsd protocol.
* @return connect config object.
*/
ConnectConfig buildConnectConfig(HttpsdProtocol httpsdProtocol);
/**
* Initialize client.
* @param connectConfig connect config.
*/
void initClient(ConnectConfig connectConfig);
/**
* Get server info.
* @return server info object.
*/
ServerInfo getServerInfo();
/**
* Get services.
* @return service instance list.
*/
List<ServiceInstance> getServices();
/**
* Discovery client Health check.
* @return true if health check pass, otherwise false
*/
boolean healthCheck();
}
@@ -1,55 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.hertzbeat.collector.collect.httpsd.discovery;
import java.util.Objects;
import org.apache.hertzbeat.collector.collect.httpsd.constant.DiscoveryClientInstance;
import org.apache.hertzbeat.collector.collect.httpsd.discovery.impl.ConsulDiscoveryClient;
import org.apache.hertzbeat.collector.collect.httpsd.discovery.impl.NacosDiscoveryClient;
import org.apache.hertzbeat.common.entity.job.protocol.HttpsdProtocol;
/**
* Discovery Client Management
*/
public class DiscoveryClientManagement {
public DiscoveryClient getClient(HttpsdProtocol httpsdProtocol) {
return createClient(httpsdProtocol, DiscoveryClientInstance.getByName(httpsdProtocol.getDiscoveryClientTypeName()));
}
private DiscoveryClient createClient(HttpsdProtocol httpsdProtocol, DiscoveryClientInstance discoveryClientInstance) {
if (Objects.equals(discoveryClientInstance, DiscoveryClientInstance.NOT_SUPPORT)) {
return null;
}
return doCreateClient(httpsdProtocol, discoveryClientInstance);
}
private DiscoveryClient doCreateClient(HttpsdProtocol httpsdProtocol, DiscoveryClientInstance discoveryClientInstance) {
DiscoveryClient discoveryClient;
switch (discoveryClientInstance) {
case CONSUL -> discoveryClient = new ConsulDiscoveryClient();
case NACOS -> discoveryClient = new NacosDiscoveryClient();
default -> { return null; }
}
discoveryClient.initClient(discoveryClient.buildConnectConfig(httpsdProtocol));
return discoveryClient;
}
}
@@ -1,37 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.hertzbeat.collector.collect.httpsd.discovery.entity;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
/**
* Server Info
*/
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class ServerInfo {
private String address;
private String port;
}
@@ -1,132 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.hertzbeat.collector.collect.httpsd.discovery.impl;
import com.alibaba.nacos.api.exception.NacosException;
import com.alibaba.nacos.api.naming.NamingFactory;
import com.alibaba.nacos.api.naming.NamingService;
import com.google.common.collect.Lists;
import java.util.Collections;
import java.util.List;
import java.util.Objects;
import lombok.extern.slf4j.Slf4j;
import org.apache.hertzbeat.collector.collect.httpsd.constant.DiscoveryClientHealthStatus;
import org.apache.hertzbeat.collector.collect.httpsd.discovery.DiscoveryClient;
import org.apache.hertzbeat.collector.collect.httpsd.discovery.entity.ConnectConfig;
import org.apache.hertzbeat.collector.collect.httpsd.discovery.entity.ServerInfo;
import org.apache.hertzbeat.collector.collect.httpsd.discovery.entity.ServiceInstance;
import org.apache.hertzbeat.common.entity.job.protocol.HttpsdProtocol;
/**
* DiscoveryClient impl of Nacos
*/
@Slf4j
public class NacosDiscoveryClient implements DiscoveryClient {
private NamingService namingService;
private ConnectConfig localConnectConfig;
@Override
public ConnectConfig buildConnectConfig(HttpsdProtocol httpsdProtocol) {
return ConnectConfig.builder()
.host(httpsdProtocol.getHost())
.port(Integer.parseInt(httpsdProtocol.getPort()))
.build();
}
@Override
public void initClient(ConnectConfig connectConfig) {
try {
localConnectConfig = connectConfig;
namingService = NamingFactory.createNamingService(connectConfig.getHost() + ":" + connectConfig.getPort());
} catch (NacosException exception) {
throw new RuntimeException("Failed to init namingService");
}
}
@Override
public ServerInfo getServerInfo() {
if (Objects.isNull(namingService)) {
throw new NullPointerException("NamingService is null");
}
ServerInfo serverInfo;
if (healthCheck()) {
serverInfo = ServerInfo.builder()
.address(localConnectConfig.getHost())
.port(String.valueOf(localConnectConfig.getPort()))
.build();
} else {
throw new RuntimeException("NamingService is not healthy");
}
return serverInfo;
}
@Override
public List<ServiceInstance> getServices() {
if (Objects.isNull(namingService)) {
log.error("NamingService is null");
return Collections.emptyList();
}
if (!healthCheck()) {
log.error("NamingService is not healthy");
return Collections.emptyList();
}
List<ServiceInstance> serviceInstanceList = Lists.newArrayList();
try {
for (String serviceName : namingService.getServicesOfServer(0, 9999).getData()) {
namingService.getAllInstances(serviceName).forEach(instance ->
serviceInstanceList.add(ServiceInstance.builder()
.serviceId(instance.getInstanceId())
.serviceName(instance.getServiceName())
.address(instance.getIp())
.weight(instance.getWeight())
.metadata(instance.getMetadata())
.port(instance.getPort())
.healthStatus(instance.isHealthy()
? DiscoveryClientHealthStatus.UP
: DiscoveryClientHealthStatus.DOWN)
.build()));
}
} catch (NacosException e) {
throw new RuntimeException("Failed to fetch instance info");
}
return serviceInstanceList;
}
@Override
public boolean healthCheck() {
return namingService.getServerStatus().equals(DiscoveryClientHealthStatus.UP);
}
@Override
public void close() {
if (namingService == null) {
return;
}
try {
namingService.shutDown();
} catch (NacosException exception) {
log.error("Nacos client close exception: {}", exception.toString());
}
}
}
@@ -1,218 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.hertzbeat.collector.collect.jmx;
import java.io.IOException;
import java.util.Arrays;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;
import javax.management.Attribute;
import javax.management.AttributeList;
import javax.management.MBeanAttributeInfo;
import javax.management.MBeanFeatureInfo;
import javax.management.MBeanInfo;
import javax.management.MBeanServerConnection;
import javax.management.ObjectInstance;
import javax.management.ObjectName;
import javax.management.openmbean.CompositeData;
import javax.management.openmbean.CompositeType;
import javax.management.remote.JMXConnector;
import javax.management.remote.JMXConnectorFactory;
import javax.management.remote.JMXServiceURL;
import javax.management.remote.rmi.RMIConnectorServer;
import javax.naming.Context;
import javax.rmi.ssl.SslRMIClientSocketFactory;
import lombok.extern.slf4j.Slf4j;
import org.apache.hertzbeat.collector.collect.AbstractCollect;
import org.apache.hertzbeat.collector.collect.common.cache.CacheIdentifier;
import org.apache.hertzbeat.collector.collect.common.cache.ConnectionCommonCache;
import org.apache.hertzbeat.collector.collect.common.cache.JmxConnect;
import org.apache.hertzbeat.collector.dispatch.DispatchConstants;
import org.apache.hertzbeat.common.constants.CommonConstants;
import org.apache.hertzbeat.common.entity.job.Metrics;
import org.apache.hertzbeat.common.entity.job.protocol.JmxProtocol;
import org.apache.hertzbeat.common.entity.message.CollectRep;
import org.apache.hertzbeat.common.util.CommonUtil;
import org.springframework.util.Assert;
import org.springframework.util.StringUtils;
/**
* jmx protocol acquisition implementation
*/
@Slf4j
public class JmxCollectImpl extends AbstractCollect {
private static final String JMX_URL_PREFIX = "service:jmx:rmi:///jndi/rmi://";
private static final String JMX_URL_SUFFIX = "/jmxrmi";
private static final String IGNORED_STUB = "/stub/";
private static final String SUB_ATTRIBUTE = "->";
private final ConnectionCommonCache<CacheIdentifier, JmxConnect> connectionCommonCache;
public JmxCollectImpl() {
connectionCommonCache = new ConnectionCommonCache<>();
}
@Override
public void preCheck(Metrics metrics) throws IllegalArgumentException {
Assert.isTrue(metrics != null && metrics.getJmx() != null, "JMX collect must have JMX params");
String url = metrics.getJmx().getUrl();
if (StringUtils.hasText(url)) {
Assert.doesNotContain(url, IGNORED_STUB, "JMX url prohibit contains stub, please check");
}
}
@Override
public void collect(CollectRep.MetricsData.Builder builder, long monitorId, String app, Metrics metrics) {
try {
JmxProtocol jmxProtocol = metrics.getJmx();
// Create a jndi remote connection
JMXConnector jmxConnector = getConnectSession(jmxProtocol);
MBeanServerConnection serverConnection = jmxConnector.getMBeanServerConnection();
ObjectName objectName = new ObjectName(jmxProtocol.getObjectName());
Set<ObjectInstance> objectInstanceSet = serverConnection.queryMBeans(objectName, null);
Set<String> attributeNameSet = metrics.getAliasFields().stream()
.map(field -> field.split(SUB_ATTRIBUTE)[0]).collect(Collectors.toSet());
for (ObjectInstance objectInstance : objectInstanceSet) {
ObjectName currentObjectName = objectInstance.getObjectName();
MBeanInfo beanInfo = serverConnection.getMBeanInfo(currentObjectName);
MBeanAttributeInfo[] attrInfos = beanInfo.getAttributes();
String[] attributes = new String[attributeNameSet.size()];
attributes = Arrays.stream(attrInfos)
.filter(item -> item.isReadable() && attributeNameSet.contains(item.getName()))
.map(MBeanFeatureInfo::getName)
.collect(Collectors.toList()).toArray(attributes);
AttributeList attributeList = serverConnection.getAttributes(currentObjectName, attributes);
Map<String, String> attributeValueMap = extractAttributeValue(attributeList);
CollectRep.ValueRow.Builder valueRowBuilder = CollectRep.ValueRow.newBuilder();
for (String aliasField : metrics.getAliasFields()) {
String fieldValue = attributeValueMap.get(aliasField);
valueRowBuilder.addColumns(fieldValue != null ? fieldValue : CommonConstants.NULL_VALUE);
}
builder.addValues(valueRowBuilder.build());
}
} catch (IOException exception) {
String errorMsg = CommonUtil.getMessageFromThrowable(exception);
log.error("JMX IOException :{}", errorMsg);
builder.setCode(CollectRep.Code.UN_CONNECTABLE);
builder.setMsg(errorMsg);
} catch (Exception e) {
String errorMsg = CommonUtil.getMessageFromThrowable(e);
log.error("JMX Error :{}", errorMsg);
builder.setCode(CollectRep.Code.FAIL);
builder.setMsg(errorMsg);
}
}
@Override
public String supportProtocol() {
return DispatchConstants.PROTOCOL_JMX;
}
private Map<String, String> extractAttributeValue(AttributeList attributeList) {
if (attributeList == null || attributeList.isEmpty()) {
throw new RuntimeException("attributeList is empty");
}
Map<String, String> attributeValueMap = new HashMap<>(attributeList.size());
for (Attribute attribute : attributeList.asList()) {
Object value = attribute.getValue();
if (value == null) {
log.info("attribute {} value is null.", attribute.getName());
continue;
}
if (value instanceof Number || value instanceof String || value instanceof ObjectName
|| value instanceof Boolean || value instanceof Date || value instanceof TimeUnit) {
attributeValueMap.put(attribute.getName(), value.toString());
} else if (value instanceof CompositeData compositeData) {
CompositeType compositeType = compositeData.getCompositeType();
for (String typeKey : compositeType.keySet()) {
Object fieldValue = compositeData.get(typeKey);
attributeValueMap.put(attribute.getName() + SUB_ATTRIBUTE + typeKey, fieldValue.toString());
}
} else if (value instanceof String[] values) {
StringBuilder builder = new StringBuilder();
for (int index = 0; index < values.length; index++) {
builder.append(values[index]);
if (index < values.length - 1) {
builder.append(",");
}
}
attributeValueMap.put(attribute.getName(), builder.toString());
} else {
log.warn("attribute value type {} not support.", value.getClass().getName());
}
}
return attributeValueMap;
}
private JMXConnector getConnectSession(JmxProtocol jmxProtocol) throws IOException {
CacheIdentifier identifier = CacheIdentifier.builder().ip(jmxProtocol.getHost())
.port(jmxProtocol.getPort()).username(jmxProtocol.getUsername())
.password(jmxProtocol.getPassword()).build();
Optional<JmxConnect> cacheOption = connectionCommonCache.getCache(identifier, true);
JMXConnector conn = null;
if (cacheOption.isPresent()) {
JmxConnect jmxConnect = cacheOption.get();
conn = jmxConnect.getConnection();
try {
conn.getMBeanServerConnection();
} catch (Exception e) {
conn = null;
connectionCommonCache.removeCache(identifier);
}
}
if (conn != null) {
return conn;
}
String url;
if (jmxProtocol.getUrl() != null) {
url = jmxProtocol.getUrl();
} else {
url = JMX_URL_PREFIX + jmxProtocol.getHost() + ":" + jmxProtocol.getPort() + JMX_URL_SUFFIX;
}
Map<String, Object> environment = new HashMap<>(4);
if (StringUtils.hasText(jmxProtocol.getUsername()) && StringUtils.hasText(jmxProtocol.getPassword())) {
String[] credential = new String[] {jmxProtocol.getUsername(), jmxProtocol.getPassword()};
environment.put(javax.management.remote.JMXConnector.CREDENTIALS, credential);
}
if (Boolean.TRUE.toString().equals(jmxProtocol.getSsl())) {
environment.put(Context.SECURITY_PROTOCOL, "ssl");
SslRMIClientSocketFactory clientSocketFactory = new SslRMIClientSocketFactory();
environment.put(RMIConnectorServer.RMI_CLIENT_SOCKET_FACTORY_ATTRIBUTE, clientSocketFactory);
environment.put("com.sun.jndi.rmi.factory.socket", clientSocketFactory);
}
JMXServiceURL jmxServiceUrl = new JMXServiceURL(url);
conn = JMXConnectorFactory.connect(jmxServiceUrl, environment);
connectionCommonCache.addCache(identifier, new JmxConnect(conn));
return conn;
}
}

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