mirror of
https://github.com/dromara/hertzbeat.git
synced 2026-09-17 18:19:02 +00:00
Compare commits
544
Commits
release-1.6.0
..
dev
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
51bdb56592 | ||
|
|
3562e870d8 | ||
|
|
6f9ee2f4e6 | ||
|
|
917c11f298 | ||
|
|
bf8d5b79bb | ||
|
|
7178c444f2 | ||
|
|
bc2dc1d567 | ||
|
|
9714123c98 | ||
|
|
8ca2f70153 | ||
|
|
126268f7ec | ||
|
|
12d1f4990d | ||
|
|
4b21df556c | ||
|
|
893d91c4f0 | ||
|
|
4236c438be | ||
|
|
6a64752af0 | ||
|
|
c5cce27cb4 | ||
|
|
364de609bf | ||
|
|
5d81c32f9d | ||
|
|
6aff6ed053 | ||
|
|
5ba09cf5c1 | ||
|
|
a746e35dcf | ||
|
|
a27777adcb | ||
|
|
4b7dfb4c8e | ||
|
|
ceda4a65f9 | ||
|
|
d4f6fc1ae8 | ||
|
|
e999360da8 | ||
|
|
948fcb739a | ||
|
|
cdf060e9ac | ||
|
|
1280c61af1 | ||
|
|
86ad10ad7b | ||
|
|
8961cf70a3 | ||
|
|
f31909a30d | ||
|
|
2df7e1d269 | ||
|
|
c10ebf0b60 | ||
|
|
1fe70a60cc | ||
|
|
3ea4c0e7da | ||
|
|
8228938bd1 | ||
|
|
5acaf4844a | ||
|
|
fc8be06ad5 | ||
|
|
509a9c9651 | ||
|
|
754b18c9ba | ||
|
|
8cdc92ab56 | ||
|
|
f0cb2af031 | ||
|
|
bd937bf7b8 | ||
|
|
8852713e4d | ||
|
|
12f4ecce01 | ||
|
|
ca9934ec81 | ||
|
|
eaaf589083 | ||
|
|
be84a0abae | ||
|
|
9a00f5a776 | ||
|
|
fb4626dd07 | ||
|
|
f28996255a | ||
|
|
0b79222bd0 | ||
|
|
120f3a12fe | ||
|
|
b8b1885657 | ||
|
|
caf13c09bd | ||
|
|
dca3e351ed | ||
|
|
6298e7ae90 | ||
|
|
4b2c3756b1 | ||
|
|
d32ec249b4 | ||
|
|
611ddc22e3 | ||
|
|
4373ab23f3 | ||
|
|
bff75757db | ||
|
|
50dd262fbf | ||
|
|
dc9743b7a5 | ||
|
|
8dc0fdee27 | ||
|
|
1267fcae5a | ||
|
|
afe68ba4f8 | ||
|
|
4da00d445b | ||
|
|
e3d09ef427 | ||
|
|
bb0a22c42f | ||
|
|
291f7cb351 | ||
|
|
ba4f1e35f8 | ||
|
|
32f8cd5188 | ||
|
|
1f22a610ce | ||
|
|
fac3f5b927 | ||
|
|
efa2dc3969 | ||
|
|
a0995d26ec | ||
|
|
4f18c2c930 | ||
|
|
739e678dd5 | ||
|
|
2856c3fe65 | ||
|
|
bad49ce17e | ||
|
|
64c68a4593 | ||
|
|
cc47db793f | ||
|
|
108cc4db5a | ||
|
|
7e3d009536 | ||
|
|
5dabc7b7fd | ||
|
|
f2eb663e02 | ||
|
|
ebe7a6f8fe | ||
|
|
163a5a05ed | ||
|
|
ec195c1dbf | ||
|
|
5fa88ec577 | ||
|
|
1e4dd6793e | ||
|
|
a811b9f6cb | ||
|
|
a8790c856b | ||
|
|
b9fdfbd50e | ||
|
|
85b4a4ef0c | ||
|
|
febc911639 | ||
|
|
001e76db4b | ||
|
|
ca27605640 | ||
|
|
06ce10ec3a | ||
|
|
1c17c7cb44 | ||
|
|
a34ccdd769 | ||
|
|
f5a8ebeeca | ||
|
|
6c36d1d60a | ||
|
|
90c027d6cc | ||
|
|
c30295cf9c | ||
|
|
bb0e2ea41c | ||
|
|
16f52d1b6e | ||
|
|
ff3139e1de | ||
|
|
65639da9c4 | ||
|
|
af0dc23b45 | ||
|
|
4b81ae4abf | ||
|
|
d5fdccf1d2 | ||
|
|
4d9900b56b | ||
|
|
dab66d4f16 | ||
|
|
cd028d8464 | ||
|
|
c4c56c6f85 | ||
|
|
6a852b2b8d | ||
|
|
c153433165 | ||
|
|
27175ef3ef | ||
|
|
c507f952de | ||
|
|
b00a50a469 | ||
|
|
98354f267e | ||
|
|
9080ccd2ba | ||
|
|
bd3420c4a7 | ||
|
|
7506429fc4 | ||
|
|
e9bfee6e7e | ||
|
|
b8a2e865cd | ||
|
|
83c5a3a08a | ||
|
|
4b7178af02 | ||
|
|
1841ed59d8 | ||
|
|
4080f5f068 | ||
|
|
25ee822c5f | ||
|
|
969c4a95c5 | ||
|
|
a15a106a46 | ||
|
|
74ed750860 | ||
|
|
ef377912ef | ||
|
|
cb11f11ace | ||
|
|
589b0d915d | ||
|
|
50a18f2813 | ||
|
|
86ca715a64 | ||
|
|
7b886fe72d | ||
|
|
9024b2aca2 | ||
|
|
5cd9590907 | ||
|
|
8e38b8ba9b | ||
|
|
47e632a088 | ||
|
|
4a691777aa | ||
|
|
ec92f4ee97 | ||
|
|
714f216470 | ||
|
|
16cb8f681c | ||
|
|
3ec150c586 | ||
|
|
31fcb0d839 | ||
|
|
3e1d87b59f | ||
|
|
2076693a16 | ||
|
|
7bb049f2df | ||
|
|
19955fa59a | ||
|
|
049c0937bc | ||
|
|
2763ee4dc4 | ||
|
|
497fc915c3 | ||
|
|
e945c42632 | ||
|
|
59398bd7c6 | ||
|
|
d49cb37c6f | ||
|
|
89be682a88 | ||
|
|
0d73ac6fc4 | ||
|
|
17636ed582 | ||
|
|
9cb50b7190 | ||
|
|
0e49e100d8 | ||
|
|
24678c2ca0 | ||
|
|
6074c08e1a | ||
|
|
3eb6fb35f4 | ||
|
|
466ac37e66 | ||
|
|
a5bc6327f9 | ||
|
|
2e9021a12d | ||
|
|
1dd08b8b19 | ||
|
|
6117396377 | ||
|
|
d71b9aa048 | ||
|
|
525980f919 | ||
|
|
6e430bcab6 | ||
|
|
12a53c69da | ||
|
|
1799e00ec9 | ||
|
|
5d416e855b | ||
|
|
5eef247a5b | ||
|
|
77f725cf42 | ||
|
|
b7969e78c9 | ||
|
|
2f4343c453 | ||
|
|
857e4118f0 | ||
|
|
c3ffad76ca | ||
|
|
102c72bcc6 | ||
|
|
88aeb9fc21 | ||
|
|
20f89f3b3b | ||
|
|
7facbe827c | ||
|
|
e3a1b8345f | ||
|
|
0f0f00c700 | ||
|
|
51699e34cd | ||
|
|
343afd517d | ||
|
|
b602d8ceb6 | ||
|
|
bad28bccdb | ||
|
|
eea68d2a27 | ||
|
|
fff291da82 | ||
|
|
97aada9956 | ||
|
|
d056ce2aa6 | ||
|
|
c2d92eb57d | ||
|
|
4dceb42dc7 | ||
|
|
1fac6ab2fa | ||
|
|
235df8bca1 | ||
|
|
603bc3222a | ||
|
|
a1d73a292c | ||
|
|
bdfffeec4c | ||
|
|
bc47768bfb | ||
|
|
98b03b62c7 | ||
|
|
ceab3023b1 | ||
|
|
a49fa3d91b | ||
|
|
5d87275206 | ||
|
|
a2bd61947b | ||
|
|
7ac21d3171 | ||
|
|
4fdc048287 | ||
|
|
e10e4b2d8d | ||
|
|
27d66a11c1 | ||
|
|
19c7d84e53 | ||
|
|
031e83d701 | ||
|
|
5b50307e8c | ||
|
|
4f7ba7355f | ||
|
|
4733ac2eba | ||
|
|
e157d82a18 | ||
|
|
f1a123ee76 | ||
|
|
584b70a726 | ||
|
|
9d62270131 | ||
|
|
53a506569a | ||
|
|
0ec6a3b6ba | ||
|
|
c8560e6b16 | ||
|
|
361e573d8e | ||
|
|
c12b4c0d84 | ||
|
|
9b065f7ec0 | ||
|
|
ffa81a68f7 | ||
|
|
ed21cc3a94 | ||
|
|
35616d2763 | ||
|
|
fbb74199c9 | ||
|
|
3a2350b86d | ||
|
|
b39602f15d | ||
|
|
86c7c2dadf | ||
|
|
ddfa60e597 | ||
|
|
e34b64062e | ||
|
|
0634e7bb2e | ||
|
|
0920910738 | ||
|
|
8ae4d0e2d3 | ||
|
|
1c5b3f9c3f | ||
|
|
a55a098983 | ||
|
|
a8c1c48390 | ||
|
|
9f7be0292a | ||
|
|
3250bc714d | ||
|
|
3d3d881722 | ||
|
|
3c01298e86 | ||
|
|
c650972f3d | ||
|
|
df4272a2f8 | ||
|
|
23d16ae921 | ||
|
|
aeac1ffed4 | ||
|
|
bac607f6dd | ||
|
|
8faa13e7b4 | ||
|
|
3113487192 | ||
|
|
7a7d4792cd | ||
|
|
ec8cc517d1 | ||
|
|
12fee7fb01 | ||
|
|
339a33a0bd | ||
|
|
e3a0fb4537 | ||
|
|
9b328ce34c | ||
|
|
e8dc6482ff | ||
|
|
c4fa738d65 | ||
|
|
6ac092dcd5 | ||
|
|
fe403ed880 | ||
|
|
d6b19691fb | ||
|
|
c2c00d44c7 | ||
|
|
e9da2d2925 | ||
|
|
58e6e1a2a7 | ||
|
|
0c2cc59b55 | ||
|
|
111f0f6b99 | ||
|
|
e560502d8e | ||
|
|
67983c2702 | ||
|
|
033240341b | ||
|
|
35a8ec4275 | ||
|
|
9ac45ab343 | ||
|
|
4b5a97044c | ||
|
|
477af0959f | ||
|
|
a5b8f59242 | ||
|
|
98b8d95b92 | ||
|
|
c0ef4a436e | ||
|
|
254421bc46 | ||
|
|
deb827a572 | ||
|
|
7eef0c21f1 | ||
|
|
58920978c3 | ||
|
|
a4c6a6045f | ||
|
|
6e47da758e | ||
|
|
ae03111a75 | ||
|
|
69b8db7048 | ||
|
|
de657f9144 | ||
|
|
822825b614 | ||
|
|
7672502c3d | ||
|
|
598ed2ea16 | ||
|
|
aee969a18a | ||
|
|
b0438da537 | ||
|
|
c85e182119 | ||
|
|
7446d3ebbf | ||
|
|
f6e8e64e23 | ||
|
|
2a3f4dfa80 | ||
|
|
3d99835487 | ||
|
|
3a7d5829ad | ||
|
|
51b1a9bdc7 | ||
|
|
181ca5aa5e | ||
|
|
a5c444a49a | ||
|
|
2784c8fa6b | ||
|
|
ae4a5b1c63 | ||
|
|
c7f4390638 | ||
|
|
c998d3b850 | ||
|
|
861e9d377f | ||
|
|
c1252fbe2b | ||
|
|
dce9a4b15e | ||
|
|
15768d8077 | ||
|
|
2824542037 | ||
|
|
f9bce29523 | ||
|
|
6b7dbd53f4 | ||
|
|
f5e88db841 | ||
|
|
82219d14df | ||
|
|
05bce69b84 | ||
|
|
bc49280c3c | ||
|
|
90035cac5d | ||
|
|
3487e4a16b | ||
|
|
974b27e878 | ||
|
|
22459c5b6f | ||
|
|
64e156be2a | ||
|
|
a9827bbcef | ||
|
|
0ed1355d76 | ||
|
|
0b81717a9e | ||
|
|
86ca62c67a | ||
|
|
7488dfadc9 | ||
|
|
50fe51bd95 | ||
|
|
8233a62aea | ||
|
|
7367b7315b | ||
|
|
9e305f7a59 | ||
|
|
3d9be220e6 | ||
|
|
659346ddd7 | ||
|
|
7f0b340663 | ||
|
|
a427099db7 | ||
|
|
d1d28e6763 | ||
|
|
ba70b2f269 | ||
|
|
2352ceef3d | ||
|
|
927625a79f | ||
|
|
16a6620ff6 | ||
|
|
a1d016e5d5 | ||
|
|
40aa5a4d73 | ||
|
|
aef7ac23c4 | ||
|
|
348b50c4c6 | ||
|
|
88538890b4 | ||
|
|
fa4a3fd9e1 | ||
|
|
3a24edb309 | ||
|
|
e142a498e2 | ||
|
|
f4685aa75a | ||
|
|
f038ec5326 | ||
|
|
06186c5ccc | ||
|
|
6c931956fa | ||
|
|
809f679375 | ||
|
|
b31d8b1380 | ||
|
|
1bba56bfbc | ||
|
|
357068cc8f | ||
|
|
8a88607be9 | ||
|
|
15e9bd0656 | ||
|
|
aa58f0af7f | ||
|
|
115f7b40c5 | ||
|
|
d2c19cbf95 | ||
|
|
173733784b | ||
|
|
df4115a64c | ||
|
|
8d34de4422 | ||
|
|
a482d24770 | ||
|
|
aee8481204 | ||
|
|
497338e00f | ||
|
|
e5236259ff | ||
|
|
712c54186e | ||
|
|
7aa3be8f7d | ||
|
|
f84e1fc5bf | ||
|
|
a8c1921fa3 | ||
|
|
43afb0bc63 | ||
|
|
ee9bdf6773 | ||
|
|
229b4158cc | ||
|
|
3d49b288bb | ||
|
|
e0caceda92 | ||
|
|
0b73e0900b | ||
|
|
1a09611ad6 | ||
|
|
be0de49646 | ||
|
|
061423d301 | ||
|
|
6421fef548 | ||
|
|
70af0669c6 | ||
|
|
55b3dd7f0c | ||
|
|
91111e5555 | ||
|
|
07913e7d51 | ||
|
|
38d466b7f8 | ||
|
|
9770c9321e | ||
|
|
7e5283ea0d | ||
|
|
8f659f0fd1 | ||
|
|
7a4ee880c3 | ||
|
|
3b323e1882 | ||
|
|
acc617f9bd | ||
|
|
5585993503 | ||
|
|
fd0e216818 | ||
|
|
999b37ec4f | ||
|
|
823430bca9 | ||
|
|
9a7e0411a1 | ||
|
|
3a2e0b3dd2 | ||
|
|
25d27880aa | ||
|
|
8a11dacdba | ||
|
|
467c595802 | ||
|
|
c70cc5d9b7 | ||
|
|
8f9143001f | ||
|
|
3e50b96322 | ||
|
|
9cf0e6f4ee | ||
|
|
d47d3be6b4 | ||
|
|
6cabe3ca0c | ||
|
|
874f7bdab3 | ||
|
|
f90d1e6242 | ||
|
|
afcb0c19fb | ||
|
|
0e7323fc04 | ||
|
|
feb60a7da9 | ||
|
|
2e7616cd56 | ||
|
|
2d53abdaab | ||
|
|
9fed2c8a36 | ||
|
|
a4db859eee | ||
|
|
9a3a2f0a54 | ||
|
|
da05b6a151 | ||
|
|
78621f2f14 | ||
|
|
a618ff00ea | ||
|
|
044c6d4bad | ||
|
|
53787cc215 | ||
|
|
d884278fed | ||
|
|
21a7788522 | ||
|
|
c7d192996a | ||
|
|
78ce1cdc1f | ||
|
|
12230b47ca | ||
|
|
753ea44d2b | ||
|
|
c3faea07c2 | ||
|
|
4149a027a7 | ||
|
|
65d69eb191 | ||
|
|
5e2e78fe95 | ||
|
|
e992da78cd | ||
|
|
2fd0090e83 | ||
|
|
a86fc85ffc | ||
|
|
f3cecea307 | ||
|
|
cbf6536923 | ||
|
|
336eaffd27 | ||
|
|
b9f8b7de72 | ||
|
|
5b44a95298 | ||
|
|
97e5435296 | ||
|
|
9b31fe785f | ||
|
|
f6fcd52a50 | ||
|
|
19a59004de | ||
|
|
f9b04ceb0c | ||
|
|
7ee227196d | ||
|
|
20f3b01251 | ||
|
|
9260bca057 | ||
|
|
6cdffbefac | ||
|
|
0699e89346 | ||
|
|
6222c51f41 | ||
|
|
ccbc7c698e | ||
|
|
b5c7705f4a | ||
|
|
eeba46af9f | ||
|
|
b4d0e77c99 | ||
|
|
1cb293ac03 | ||
|
|
2ffdda8f26 | ||
|
|
4f1c62fa3a | ||
|
|
bfe68d8a06 | ||
|
|
215271716d | ||
|
|
fafc6a8212 | ||
|
|
e860e63f62 | ||
|
|
702446190d | ||
|
|
7251fb4185 | ||
|
|
12bb21cb8d | ||
|
|
a7f30fc1f6 | ||
|
|
2cc779ce1c | ||
|
|
27c394d9f7 | ||
|
|
b25f1834e8 | ||
|
|
c878ac8fad | ||
|
|
0ebcffa408 | ||
|
|
5ef96061c9 | ||
|
|
c06f53c926 | ||
|
|
51765d8f9a | ||
|
|
1fe37d3789 | ||
|
|
baf2d5f536 | ||
|
|
5757d7427d | ||
|
|
cbb4b8c736 | ||
|
|
dbac0dfe63 | ||
|
|
8c0b39f69b | ||
|
|
a54d8cdd11 | ||
|
|
ec1c41cf68 | ||
|
|
93635a0482 | ||
|
|
59266ccb8a | ||
|
|
bc4b399a21 | ||
|
|
87756f16d9 | ||
|
|
e1cda5066e | ||
|
|
fa0e9ef50a | ||
|
|
a10c2bfbd8 | ||
|
|
33877615c5 | ||
|
|
13411105ed | ||
|
|
e2faa44f18 | ||
|
|
657de4f5b6 | ||
|
|
dfa6895a7e | ||
|
|
a9de486744 | ||
|
|
31d8712299 | ||
|
|
c4a6e36977 | ||
|
|
41c3bf50ee | ||
|
|
957cce93d9 | ||
|
|
9b7b00e09c | ||
|
|
b3976295f5 | ||
|
|
1be2631af7 | ||
|
|
5f5f4d0346 | ||
|
|
95c30f54cd | ||
|
|
855abf6ada | ||
|
|
bdf82751a5 | ||
|
|
f49e20535c | ||
|
|
a32757ea7a | ||
|
|
bd52e0527e | ||
|
|
1bac42b094 | ||
|
|
a71c61a0d8 | ||
|
|
56db540721 | ||
|
|
bc104dfe9f | ||
|
|
fc6ea4a2e0 | ||
|
|
55c48d167c | ||
|
|
393bb95878 | ||
|
|
915fcbf1d9 | ||
|
|
26b982a59b | ||
|
|
3186aa5eb6 | ||
|
|
a6ac326581 | ||
|
|
53b796ff57 | ||
|
|
b7217b5d48 | ||
|
|
b8f2bf30fd | ||
|
|
bc4ddefc76 | ||
|
|
2fcd100fec | ||
|
|
365de4657e | ||
|
|
d4e6317a30 | ||
|
|
cc19831f7c | ||
|
|
f10e5dbd06 | ||
|
|
af1f59e009 | ||
|
|
009a512ba0 | ||
|
|
dc381ea338 | ||
|
|
3ed52c54af | ||
|
|
c5808a0430 | ||
|
|
ed390a50c9 | ||
|
|
cfe93bf19d |
+276
-3
@@ -1652,7 +1652,8 @@
|
||||
"profile": "https://github.com/gjjjj0101",
|
||||
"contributions": [
|
||||
"code",
|
||||
"design"
|
||||
"design",
|
||||
"test"
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -1829,7 +1830,7 @@
|
||||
},
|
||||
{
|
||||
"login": "Yanshuming1",
|
||||
"name": "xiaoming student",
|
||||
"name": "linDong",
|
||||
"avatar_url": "https://avatars.githubusercontent.com/u/118667222?v=4",
|
||||
"profile": "https://github.com/Yanshuming1",
|
||||
"contributions": [
|
||||
@@ -1851,7 +1852,8 @@
|
||||
"avatar_url": "https://avatars.githubusercontent.com/u/119573640?v=4",
|
||||
"profile": "https://thespica.github.io/",
|
||||
"contributions": [
|
||||
"code"
|
||||
"code",
|
||||
"doc"
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -1889,6 +1891,277 @@
|
||||
"contributions": [
|
||||
"doc"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "yykaue",
|
||||
"name": "Limbo",
|
||||
"avatar_url": "https://avatars.githubusercontent.com/u/22905143?v=4",
|
||||
"profile": "https://github.com/yykaue",
|
||||
"contributions": [
|
||||
"code"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "irenhongyan",
|
||||
"name": "哈哈哈哈哈哈哈哈哈",
|
||||
"avatar_url": "https://avatars.githubusercontent.com/u/53438321?v=4",
|
||||
"profile": "https://github.com/irenhongyan",
|
||||
"contributions": [
|
||||
"code"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "ileonli",
|
||||
"name": "Leon Li",
|
||||
"avatar_url": "https://avatars.githubusercontent.com/u/45332412?v=4",
|
||||
"profile": "https://github.com/ileonli",
|
||||
"contributions": [
|
||||
"code"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "killme2008",
|
||||
"name": "dennis zhuang",
|
||||
"avatar_url": "https://avatars.githubusercontent.com/u/14142?v=4",
|
||||
"profile": "http://fnil.net/",
|
||||
"contributions": [
|
||||
"code"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "kerwin612",
|
||||
"name": "Kerwin Bryant",
|
||||
"avatar_url": "https://avatars.githubusercontent.com/u/3371163?v=4",
|
||||
"profile": "https://github.com/kerwin612",
|
||||
"contributions": [
|
||||
"code",
|
||||
"design"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "ShineDevelopment",
|
||||
"name": "daixianglong",
|
||||
"avatar_url": "https://avatars.githubusercontent.com/u/59306780?v=4",
|
||||
"profile": "https://github.com/ShineDevelopment",
|
||||
"contributions": [
|
||||
"doc"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "mchgood",
|
||||
"name": "mchgood",
|
||||
"avatar_url": "https://avatars.githubusercontent.com/u/38482005?v=4",
|
||||
"profile": "https://github.com/mchgood",
|
||||
"contributions": [
|
||||
"doc"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "pwallk",
|
||||
"name": "kangli",
|
||||
"avatar_url": "https://avatars.githubusercontent.com/u/69385076?v=4",
|
||||
"profile": "https://github.com/pwallk",
|
||||
"contributions": [
|
||||
"code"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "cdphantom",
|
||||
"name": "cdphantom",
|
||||
"avatar_url": "https://avatars.githubusercontent.com/u/12674795?v=4",
|
||||
"profile": "https://github.com/cdphantom",
|
||||
"contributions": [
|
||||
"code"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "asd108908382",
|
||||
"name": "jiawei.guo",
|
||||
"avatar_url": "https://avatars.githubusercontent.com/u/77717999?v=4",
|
||||
"profile": "https://github.com/asd108908382",
|
||||
"contributions": [
|
||||
"code"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "QBH-insist",
|
||||
"name": "QBH-insist",
|
||||
"avatar_url": "https://avatars.githubusercontent.com/u/39401478?v=4",
|
||||
"profile": "https://github.com/QBH-insist",
|
||||
"contributions": [
|
||||
"code"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "jiangsh-ui",
|
||||
"name": "jiangsh",
|
||||
"avatar_url": "https://avatars.githubusercontent.com/u/86990361?v=4",
|
||||
"profile": "https://github.com/jiangsh-ui",
|
||||
"contributions": [
|
||||
"code"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "keaifafafa",
|
||||
"name": "Keaifa",
|
||||
"avatar_url": "https://avatars.githubusercontent.com/u/83876361?v=4",
|
||||
"profile": "https://github.com/keaifafafa",
|
||||
"contributions": [
|
||||
"code"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "loong95",
|
||||
"name": "Loong",
|
||||
"avatar_url": "https://avatars.githubusercontent.com/u/16333958?v=4",
|
||||
"profile": "https://github.com/loong95",
|
||||
"contributions": [
|
||||
"code"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "ceekay47",
|
||||
"name": "Chandrakant Vankayalapati",
|
||||
"avatar_url": "https://avatars.githubusercontent.com/u/104664857?v=4",
|
||||
"profile": "https://github.com/ceekay47",
|
||||
"contributions": [
|
||||
"code"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "MRgenial",
|
||||
"name": "b_mountain",
|
||||
"avatar_url": "https://avatars.githubusercontent.com/u/49973336?v=4",
|
||||
"profile": "https://github.com/MRgenial",
|
||||
"contributions": [
|
||||
"code"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "TemirlanBasitov",
|
||||
"name": "TemirlanBasitov",
|
||||
"avatar_url": "https://avatars.githubusercontent.com/u/57500808?v=4",
|
||||
"profile": "https://github.com/TemirlanBasitov",
|
||||
"contributions": [
|
||||
"code"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "wyfvsfy",
|
||||
"name": "wyfvsfy",
|
||||
"avatar_url": "https://avatars.githubusercontent.com/u/11973517?v=4",
|
||||
"profile": "https://github.com/wyfvsfy",
|
||||
"contributions": [
|
||||
"doc"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "sherry-peng2333",
|
||||
"name": "sherry-peng2333",
|
||||
"avatar_url": "https://avatars.githubusercontent.com/u/70619577?v=4",
|
||||
"profile": "https://github.com/sherry-peng2333",
|
||||
"contributions": [
|
||||
"code"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "lixiaobaivv",
|
||||
"name": "Yzzz",
|
||||
"avatar_url": "https://avatars.githubusercontent.com/u/39290771?v=4",
|
||||
"profile": "https://github.com/lixiaobaivv",
|
||||
"contributions": [
|
||||
"code"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "pruidong",
|
||||
"name": "puruidong",
|
||||
"avatar_url": "https://avatars.githubusercontent.com/u/13309008?v=4",
|
||||
"profile": "http://www.bckf.cn/",
|
||||
"contributions": [
|
||||
"doc"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "shinestare",
|
||||
"name": "shinestare",
|
||||
"avatar_url": "https://avatars.githubusercontent.com/u/13570619?v=4",
|
||||
"profile": "https://github.com/shinestare",
|
||||
"contributions": [
|
||||
"code"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "po-168",
|
||||
"name": "po-168",
|
||||
"avatar_url": "https://avatars.githubusercontent.com/u/185745593?v=4",
|
||||
"profile": "https://github.com/po-168",
|
||||
"contributions": [
|
||||
"code"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "All-The-Best-for",
|
||||
"name": "wbs99",
|
||||
"avatar_url": "https://avatars.githubusercontent.com/u/76414672?v=4",
|
||||
"profile": "https://github.com/All-The-Best-for",
|
||||
"contributions": [
|
||||
"code"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "starryCoder",
|
||||
"name": "starryCoder",
|
||||
"avatar_url": "https://avatars.githubusercontent.com/u/46510059?v=4",
|
||||
"profile": "https://github.com/starryCoder",
|
||||
"contributions": [
|
||||
"code"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "hasimmollah",
|
||||
"name": "hasimmollah",
|
||||
"avatar_url": "https://avatars.githubusercontent.com/u/32538599?v=4",
|
||||
"profile": "https://github.com/hasimmollah",
|
||||
"contributions": [
|
||||
"code"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "ayu-v0",
|
||||
"name": "Ayu",
|
||||
"avatar_url": "https://avatars.githubusercontent.com/u/127600988?v=4",
|
||||
"profile": "https://github.com/ayu-v0",
|
||||
"contributions": [
|
||||
"code"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "Rancho-7",
|
||||
"name": "Nick Guo",
|
||||
"avatar_url": "https://avatars.githubusercontent.com/u/59016860?v=4",
|
||||
"profile": "https://github.com/Rancho-7",
|
||||
"contributions": [
|
||||
"doc"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "doveLin0818",
|
||||
"name": "doveLin",
|
||||
"avatar_url": "https://avatars.githubusercontent.com/u/190927907?v=4",
|
||||
"profile": "https://github.com/doveLin0818",
|
||||
"contributions": [
|
||||
"code"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "yunfan24",
|
||||
"name": "yunfan24",
|
||||
"avatar_url": "https://avatars.githubusercontent.com/u/91836599?v=4",
|
||||
"profile": "https://zzrl.cc/",
|
||||
"contributions": [
|
||||
"code"
|
||||
]
|
||||
}
|
||||
],
|
||||
"contributorsPerLine": 7,
|
||||
|
||||
@@ -0,0 +1,38 @@
|
||||
{
|
||||
"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": {},
|
||||
// same extensions as Gitpod, should match /.gitpod.yml
|
||||
"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"
|
||||
}
|
||||
@@ -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.
|
||||
|
||||
@@ -53,4 +53,4 @@ body:
|
||||
validations:
|
||||
required: false
|
||||
- type: markdown
|
||||
value: "Please read the [Contribution Guideline](https://hertzbeat.apache.org/docs/others/contributing) before submitting the PR"
|
||||
value: "Please read the [Contribution Guideline](https://hertzbeat.apache.org/docs/community/contribution) before submitting the PR"
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -22,7 +22,7 @@ name: Backend CI
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [ master, dev ]
|
||||
branches: [ master, dev, action* ]
|
||||
paths-ignore:
|
||||
- '**.md'
|
||||
- 'home/**'
|
||||
@@ -39,29 +39,45 @@ on:
|
||||
- 'material/**'
|
||||
|
||||
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: mvn clean -B package -Prelease -Dmaven.test.skip=false --file pom.xml
|
||||
|
||||
- name: Upload coverage reports to Codecov
|
||||
uses: codecov/codecov-action@v4.0.1
|
||||
with:
|
||||
token: ${{ secrets.CODECOV_TOKEN }}
|
||||
verbose: true
|
||||
|
||||
- name: Build Image
|
||||
uses: docker/build-push-action@v3
|
||||
with:
|
||||
context: ./dist
|
||||
file: ./script/docker/server/Dockerfile
|
||||
push: false
|
||||
tags: apache/hertzbeat:test
|
||||
|
||||
- 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
|
||||
|
||||
cd e2e
|
||||
sudo docker-compose version
|
||||
sudo docker-compose up --exit-code-from testing --remove-orphans
|
||||
|
||||
# upload application logs
|
||||
- name: Upload logs & API test reports
|
||||
uses: actions/upload-artifact@v3
|
||||
if: always()
|
||||
with:
|
||||
name: hz-logs-${{ github.run_id }}
|
||||
path: |
|
||||
e2e/logs/
|
||||
e2e/report/
|
||||
|
||||
cd e2e && ./start.sh
|
||||
|
||||
@@ -47,7 +47,7 @@ jobs:
|
||||
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v3
|
||||
uses: actions/checkout@v4
|
||||
|
||||
# Initializes the CodeQL tools for scanning.
|
||||
- name: Initialize CodeQL
|
||||
|
||||
@@ -28,91 +28,37 @@ on:
|
||||
- 'home/**'
|
||||
|
||||
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: actions/setup-python@v4
|
||||
with:
|
||||
python-version: '3.8'
|
||||
|
||||
- name: Check Markdown
|
||||
uses: DavidAnson/markdownlint-cli2-action@v16
|
||||
with:
|
||||
globs: './home/**/*.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")
|
||||
sudo npm install -g markdown-link-check@3.8.7
|
||||
for file in $(find ./home -name "*.md"); do
|
||||
if ! grep -Fxq "$file" ./script/ci/exclude_files.txt; then
|
||||
markdown-link-check -c ./script/ci/link_check.json -q "$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
|
||||
done
|
||||
|
||||
- name: NPM INSTALL
|
||||
working-directory: home
|
||||
run: npm install
|
||||
|
||||
- name: NPM BUILD
|
||||
working-directory: home
|
||||
run: npm run build
|
||||
|
||||
@@ -53,4 +53,3 @@ jobs:
|
||||
path: docs-en.pdf
|
||||
if-no-files-found: error
|
||||
retention-days: 1
|
||||
|
||||
|
||||
@@ -34,7 +34,7 @@ jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/checkout@v4
|
||||
- name: Yarn Install
|
||||
working-directory: web-app
|
||||
run: yarn
|
||||
|
||||
@@ -32,7 +32,7 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 10
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
submodules: true
|
||||
- name: Check license header
|
||||
|
||||
@@ -0,0 +1,72 @@
|
||||
# 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* ]
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
if: ${{ github.repository == 'apache/hertzbeat' }}
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: ./script/ci/github-actions/setup-deps
|
||||
|
||||
- name: Build the Frontend
|
||||
run: |
|
||||
cd web-app
|
||||
yarn install
|
||||
yarn package
|
||||
|
||||
- name: Build the Backend
|
||||
run: |
|
||||
mvn clean install
|
||||
mvn clean package -Prelease -DskipTests
|
||||
cd collector
|
||||
mvn clean package -Pcluster -DskipTests
|
||||
|
||||
- uses: docker/setup-qemu-action@v3
|
||||
- uses: docker/setup-buildx-action@v3
|
||||
- name: Log in to Docker Hub
|
||||
uses: docker/login-action@v3
|
||||
with:
|
||||
username: ${{ secrets.DOCKERHUB_USER }}
|
||||
password: ${{ secrets.DOCKERHUB_TOKEN }}
|
||||
|
||||
- name: Build and Push Server
|
||||
uses: docker/build-push-action@v6
|
||||
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@v6
|
||||
with:
|
||||
context: ./dist
|
||||
file: ./script/docker/collector/Dockerfile
|
||||
platforms: linux/amd64,linux/arm64
|
||||
push: true
|
||||
tags: apache/hertzbeat-collector:nightly
|
||||
+21
@@ -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
|
||||
+53
@@ -0,0 +1,53 @@
|
||||
tasks:
|
||||
|
||||
- name: Run backend
|
||||
before: cd hertzbeat-manager
|
||||
command: |
|
||||
gp sync-await setup-backend
|
||||
mvn spring-boot:run
|
||||
|
||||
- name: Run frontend
|
||||
before: cd web-app
|
||||
command: |
|
||||
gp sync-await setup-frontend
|
||||
yarn start --public-host "`gp url 4200`"
|
||||
openMode: split-right
|
||||
|
||||
- name: Setup backend
|
||||
init: |
|
||||
sdk install java 17.0.11.fx-zulu < /dev/null
|
||||
sdk default java 17.0.11.fx-zulu < /dev/null
|
||||
mvn clean install -DskipTests
|
||||
command: |
|
||||
gp sync-done setup-backend
|
||||
exit 0
|
||||
|
||||
- name: Setup frontend
|
||||
init: |
|
||||
cd web-app && yarn 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
|
||||
+4
-2
@@ -62,6 +62,8 @@ header:
|
||||
- '.stylelintrc'
|
||||
- '.prettierignore'
|
||||
- '.prettierrc.js'
|
||||
- '.gitpod.Dockerfile'
|
||||
- '.gitpod.yml'
|
||||
- 'karma.conf.js'
|
||||
- 'proxy.conf.js'
|
||||
- '.helmignore'
|
||||
@@ -92,12 +94,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
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,47 @@
|
||||
//
|
||||
// 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.
|
||||
//
|
||||
{
|
||||
"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"]
|
||||
},
|
||||
"MD036": false,
|
||||
"MD040": true,
|
||||
"MD045": true,
|
||||
"MD046": true,
|
||||
"MD047": true,
|
||||
"MD052": true
|
||||
},
|
||||
"ignore": [
|
||||
"node_modules/",
|
||||
"target/",
|
||||
"dist/"
|
||||
]
|
||||
}
|
||||
+39
-34
@@ -38,7 +38,9 @@ Even small corrections to typos are very welcome :)
|
||||
|
||||
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 manager` service: `manager/src/main/java/org/apache/hertzbeat/hertzbeat-manager/Manager.java`
|
||||
|
||||
#### Frontend start
|
||||
|
||||
@@ -68,23 +70,23 @@ Of course, if you have a good idea, you can also propose it directly on GitHub D
|
||||
|
||||
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
|
||||
```
|
||||
```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
|
||||
```
|
||||
```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
|
||||
```
|
||||
```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
|
||||
```
|
||||
```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.
|
||||
@@ -127,17 +129,17 @@ With the above steps, you are a contributor to HertzBeat. Repeat the previous st
|
||||
|
||||
[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.
|
||||
- **[manager](https://github.com/apache/hertzbeat/tree/master/hertzbeat-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.
|
||||
- **[alerter](https://github.com/apache/hertzbeat/tree/master/hertzbeat-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.
|
||||
@@ -189,7 +191,10 @@ Add WeChat account `tan-cloud` to pull you into the WeChat group.
|
||||
|
||||
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 manager`服务 `manager/src/main/java/org/apache/hertzbeat/hertzbeat-manager/Manager.java`
|
||||
|
||||
|
||||
#### 前端启动
|
||||
|
||||
@@ -218,23 +223,23 @@ Add WeChat account `tan-cloud` to pull you into the WeChat group.
|
||||
|
||||
1. 首先您需要 Fork 目标仓库 [hertzbeat repository](https://github.com/apache/hertzbeat).
|
||||
2. 然后 用git命令 将代码下载到本地:
|
||||
```shell
|
||||
git clone git@github.com:${YOUR_USERNAME}/hertzbeat.git #Recommended
|
||||
```
|
||||
```shell
|
||||
git clone git@github.com:${YOUR_USERNAME}/hertzbeat.git #Recommended
|
||||
```
|
||||
3. 下载完成后,请参考目标仓库的入门指南或者 README 文件对项目进行初始化。
|
||||
4. 接着,您可以参考如下命令进行代码的提交, 切换新的分支, 进行开发:
|
||||
```shell
|
||||
git checkout -b a-feature-branch #Recommended
|
||||
```
|
||||
```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
|
||||
```
|
||||
```shell
|
||||
git add <modified file/path>
|
||||
git commit -m '[docs]feature: necessary instructions' #Recommended
|
||||
```
|
||||
6. 推送到远程仓库
|
||||
```shell
|
||||
git push origin a-feature-branch
|
||||
```
|
||||
```shell
|
||||
git push origin a-feature-branch
|
||||
```
|
||||
7. 然后您就可以在 GitHub 上发起新的 PR (Pull Request)。
|
||||
|
||||
请注意 PR 的标题需要符合我们的规范,并且在 PR 中写上必要的说明,来方便 Committer 和其他贡献者进行代码审查。
|
||||
@@ -277,17 +282,17 @@ git pull upstream master
|
||||
|
||||
[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)** 提供监控管理,系统管理基础服务
|
||||
- **[manager](https://github.com/apache/hertzbeat/tree/master/hertzbeat-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)** 提供告警服务
|
||||
- **[alerter](https://github.com/apache/hertzbeat/tree/master/hertzbeat-alerter)** 提供告警服务
|
||||
> 告警计算触发,任务状态联动,告警配置,告警通知。
|
||||
- **[web-app](https://github.com/apache/hertzbeat/tree/master/web-app)** 提供可视化控制台页面
|
||||
> 监控告警系统可视化控制台前端
|
||||
|
||||
@@ -14,9 +14,11 @@
|
||||
[](https://www.reddit.com/r/hertzbeat/)
|
||||
[](https://twitter.com/hertzbeat1024)
|
||||
[](https://www.bestpractices.dev/projects/8139)
|
||||
[](https://hub.docker.com/repository/docker/apache/hertzbeat/general)
|
||||
[](https://app.codecov.io/gh/apache/hertzbeat)
|
||||
[](https://hub.docker.com/r/apache/hertzbeat)
|
||||
[](https://artifacthub.io/packages/search?repo=hertzbeat)
|
||||
[](https://www.youtube.com/channel/UCri75zfWX0GHqJFPENEbLow)
|
||||
[](https://gitpod.io/#https://github.com/apache/hertzbeat)
|
||||
|
||||
**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**
|
||||
@@ -58,42 +60,42 @@
|
||||
> 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)
|
||||
- [Website](https://raw.githubusercontent.com/apache/hertzbeat/master/hertzbeat-manager/src/main/resources/define/app-website.yml), [Port Telnet](https://raw.githubusercontent.com/apache/hertzbeat/master/hertzbeat-manager/src/main/resources/define/app-port.yml),
|
||||
[Http Api](https://raw.githubusercontent.com/apache/hertzbeat/master/hertzbeat-manager/src/main/resources/define/app-api.yml), [Ping Connect](https://raw.githubusercontent.com/apache/hertzbeat/master/hertzbeat-manager/src/main/resources/define/app-ping.yml),
|
||||
[Jvm](https://raw.githubusercontent.com/apache/hertzbeat/master/hertzbeat-manager/src/main/resources/define/app-jvm.yml), [SiteMap](https://raw.githubusercontent.com/apache/hertzbeat/master/hertzbeat-manager/src/main/resources/define/app-fullsite.yml),
|
||||
[Ssl Certificate](https://raw.githubusercontent.com/apache/hertzbeat/master/hertzbeat-manager/src/main/resources/define/app-ssl_cert.yml), [SpringBoot2](https://raw.githubusercontent.com/apache/hertzbeat/master/hertzbeat-manager/src/main/resources/define/app-springboot2.yml),
|
||||
[FTP Server](https://raw.githubusercontent.com/apache/hertzbeat/master/hertzbeat-manager/src/main/resources/define/app-ftp.yml), [SpringBoot3](https://raw.githubusercontent.com/apache/hertzbeat/master/hertzbeat-manager/src/main/resources/define/app-springboot3.yml),
|
||||
[Udp Port](https://raw.githubusercontent.com/apache/hertzbeat/master/hertzbeat-manager/src/main/resources/define/app-udp_port.yml), [Dns](https://raw.githubusercontent.com/apache/hertzbeat/master/hertzbeat-manager/src/main/resources/define/app-dns.yml),
|
||||
[Pop3](https://raw.githubusercontent.com/apache/hertzbeat/master/hertzbeat-manager/src/main/resources/define/app-pop3.yml), [Ntp](https://raw.githubusercontent.com/apache/hertzbeat/master/hertzbeat-manager/src/main/resources/define/app-ntp.yml),
|
||||
[Api Code](https://raw.githubusercontent.com/apache/hertzbeat/master/hertzbeat-manager/src/main/resources/define/app-api_code.yml), [Smtp](https://raw.githubusercontent.com/apache/hertzbeat/master/hertzbeat-manager/src/main/resources/define/app-smtp.yml),
|
||||
[Nginx](https://raw.githubusercontent.com/apache/hertzbeat/master/hertzbeat-manager/src/main/resources/define/app-nginx.yml)
|
||||
- [Mysql](https://raw.githubusercontent.com/apache/hertzbeat/master/hertzbeat-manager/src/main/resources/define/app-mysql.yml), [PostgreSQL](https://raw.githubusercontent.com/apache/hertzbeat/master/hertzbeat-manager/src/main/resources/define/app-postgresql.yml),
|
||||
[MariaDB](https://raw.githubusercontent.com/apache/hertzbeat/master/hertzbeat-manager/src/main/resources/define/app-mariadb.yml), [Redis](https://raw.githubusercontent.com/apache/hertzbeat/master/hertzbeat-manager/src/main/resources/define/app-redis.yml),
|
||||
[ElasticSearch](https://raw.githubusercontent.com/apache/hertzbeat/master/hertzbeat-manager/src/main/resources/define/app-elasticsearch.yml), [SqlServer](https://raw.githubusercontent.com/apache/hertzbeat/master/hertzbeat-manager/src/main/resources/define/app-sqlserver.yml),
|
||||
[Oracle](https://raw.githubusercontent.com/apache/hertzbeat/master/hertzbeat-manager/src/main/resources/define/app-oracle.yml), [MongoDB](https://raw.githubusercontent.com/apache/hertzbeat/master/hertzbeat-manager/src/main/resources/define/app-mongodb.yml),
|
||||
[DM](https://raw.githubusercontent.com/apache/hertzbeat/master/hertzbeat-manager/src/main/resources/define/app-dm.yml), [OpenGauss](https://raw.githubusercontent.com/apache/hertzbeat/master/hertzbeat-manager/src/main/resources/define/app-opengauss.yml),
|
||||
[ClickHouse](https://raw.githubusercontent.com/apache/hertzbeat/master/hertzbeat-manager/src/main/resources/define/app-clickhouse.yml), [IoTDB](https://raw.githubusercontent.com/apache/hertzbeat/master/hertzbeat-manager/src/main/resources/define/app-iotdb.yml),
|
||||
[Redis Cluster](https://raw.githubusercontent.com/apache/hertzbeat/master/hertzbeat-manager/src/main/resources/define/app-redis_cluster.yml), [Redis Sentinel](https://raw.githubusercontent.com/apache/hertzbeat/master/hertzbeat-manager/src/main/resources/define/app-redis_sentinel.yml)
|
||||
[Doris BE](https://github.com/apache/hertzbeat/blob/master/hertzbeat-manager/src/main/resources/define/app-doris_be.yml), [Doris FE](https://github.com/apache/hertzbeat/blob/master/hertzbeat-manager/src/main/resources/define/app-doris_fe.yml),
|
||||
[Memcached](https://github.com/apache/hertzbeat/blob/master/hertzbeat-manager/src/main/resources/define/app-memcached.yml), [NebulaGraph](https://github.com/apache/hertzbeat/blob/master/hertzbeat-manager/src/main/resources/define/app-nebula_graph.yml)
|
||||
- [Linux](https://raw.githubusercontent.com/apache/hertzbeat/master/hertzbeat-manager/src/main/resources/define/app-linux.yml), [Ubuntu](https://raw.githubusercontent.com/apache/hertzbeat/master/hertzbeat-manager/src/main/resources/define/app-ubuntu.yml),
|
||||
[CentOS](https://raw.githubusercontent.com/apache/hertzbeat/master/hertzbeat-manager/src/main/resources/define/app-centos.yml), [Windows](https://raw.githubusercontent.com/apache/hertzbeat/master/hertzbeat-manager/src/main/resources/define/app-windows.yml),
|
||||
[EulerOS](https://raw.githubusercontent.com/apache/hertzbeat/master/hertzbeat-manager/src/main/resources/define/app-euleros.yml), [Fedora CoreOS](https://raw.githubusercontent.com/apache/hertzbeat/master/hertzbeat-manager/src/main/resources/define/app-coreos.yml),
|
||||
[OpenSUSE](https://raw.githubusercontent.com/apache/hertzbeat/master/hertzbeat-manager/src/main/resources/define/app-opensuse.yml), [Rocky Linux](https://raw.githubusercontent.com/apache/hertzbeat/master/hertzbeat-manager/src/main/resources/define/app-rockylinux.yml),
|
||||
[Red Hat](https://raw.githubusercontent.com/apache/hertzbeat/master/hertzbeat-manager/src/main/resources/define/app-redhat.yml), [FreeBSD](https://raw.githubusercontent.com/apache/hertzbeat/master/hertzbeat-manager/src/main/resources/define/app-freebsd.yml),
|
||||
[AlmaLinux](https://raw.githubusercontent.com/apache/hertzbeat/master/hertzbeat-manager/src/main/resources/define/app-almalinux.yml), [Debian Linux](https://raw.githubusercontent.com/apache/hertzbeat/master/hertzbeat-manager/src/main/resources/define/app-debian.yml)
|
||||
- [Tomcat](https://raw.githubusercontent.com/apache/hertzbeat/master/hertzbeat-manager/src/main/resources/define/app-tomcat.yml), [Nacos](https://raw.githubusercontent.com/apache/hertzbeat/master/hertzbeat-manager/src/main/resources/define/app-nacos.yml),
|
||||
[Zookeeper](https://raw.githubusercontent.com/apache/hertzbeat/master/hertzbeat-manager/src/main/resources/define/app-zookeeper.yml), [RabbitMQ](https://raw.githubusercontent.com/apache/hertzbeat/master/hertzbeat-manager/src/main/resources/define/app-rabbitmq.yml),
|
||||
[Flink](https://raw.githubusercontent.com/apache/hertzbeat/master/hertzbeat-manager/src/main/resources/define/app-flink.yml), [Kafka](https://raw.githubusercontent.com/apache/hertzbeat/master/hertzbeat-manager/src/main/resources/define/app-kafka.yml),
|
||||
[ShenYu](https://raw.githubusercontent.com/apache/hertzbeat/master/hertzbeat-manager/src/main/resources/define/app-shenyu.yml), [DynamicTp](https://raw.githubusercontent.com/apache/hertzbeat/master/hertzbeat-manager/src/main/resources/define/app-dynamic_tp.yml),
|
||||
[Jetty](https://raw.githubusercontent.com/apache/hertzbeat/master/hertzbeat-manager/src/main/resources/define/app-jetty.yml), [ActiveMQ](https://raw.githubusercontent.com/apache/hertzbeat/master/hertzbeat-manager/src/main/resources/define/app-activemq.yml),
|
||||
[Spring Gateway](https://raw.githubusercontent.com/apache/hertzbeat/master/hertzbeat-manager/src/main/resources/define/app-spring_gateway.yml), [EMQX MQTT](https://raw.githubusercontent.com/apache/hertzbeat/master/hertzbeat-manager/src/main/resources/define/app-emqx.yml),
|
||||
[AirFlow](https://raw.githubusercontent.com/apache/hertzbeat/master/hertzbeat-manager/src/main/resources/define/app-airflow.yml), [Hive](https://raw.githubusercontent.com/apache/hertzbeat/master/hertzbeat-manager/src/main/resources/define/app-hive.yml),
|
||||
[Spark](https://raw.githubusercontent.com/apache/hertzbeat/master/hertzbeat-manager/src/main/resources/define/app-spark.yml), [Hadoop](https://raw.githubusercontent.com/apache/hertzbeat/master/hertzbeat-manager/src/main/resources/define/app-hadoop.yml)
|
||||
- [Kubernetes](https://raw.githubusercontent.com/apache/hertzbeat/master/hertzbeat-manager/src/main/resources/define/app-kubernetes.yml), [Docker](https://raw.githubusercontent.com/apache/hertzbeat/master/hertzbeat-manager/src/main/resources/define/app-docker.yml)
|
||||
- [CiscoSwitch](https://raw.githubusercontent.com/apache/hertzbeat/master/hertzbeat-manager/src/main/resources/define/app-cisco_switch.yml), [HpeSwitch](https://raw.githubusercontent.com/apache/hertzbeat/master/hertzbeat-manager/src/main/resources/define/app-hpe_switch.yml),
|
||||
[HuaweiSwitch](https://raw.githubusercontent.com/apache/hertzbeat/master/hertzbeat-manager/src/main/resources/define/app-huawei_switch.yml), [TpLinkSwitch](https://raw.githubusercontent.com/apache/hertzbeat/master/hertzbeat-manager/src/main/resources/define/app-tplink_switch.yml),
|
||||
[H3cSwitch](https://raw.githubusercontent.com/apache/hertzbeat/master/hertzbeat-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`.
|
||||
|
||||
@@ -108,32 +110,36 @@
|
||||
|
||||
##### 1:Install 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`
|
||||
|
||||
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
|
||||
```
|
||||
|
||||
- `-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.
|
||||
|
||||
|
||||
Detailed config refer to [Install HertzBeat via Docker](https://hertzbeat.apache.org/docs/start/docker-deploy)
|
||||
|
||||
##### 2:Install via package
|
||||
|
||||
1. Download the release package `hertzbeat-xx.tar.gz` [GITHUB Release](https://github.com/apache/hertzbeat/releases)
|
||||
1. Download the release package `hertzbeat-xx.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 `hertzbeat-collector-xx.tar.gz` to 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:
|
||||
@@ -154,19 +160,19 @@ Detailed config refer to [Install HertzBeat via Package](https://hertzbeat.apach
|
||||
##### 3:Start via source code
|
||||
|
||||
1. Local source code debugging needs to start the back-end project `manager` and the front-end project `web-app`.
|
||||
2. Backend:need `maven3+`, `java17`, `lombok`, start the `manager` service.
|
||||
2. Backend:need `maven3+`, `java17`, `lombok`, add VM options in IDE: ` --add-opens=java.base/java.nio=org.apache.arrow.memory.core,ALL-UNNAMED `, then start the `manager` service.
|
||||
3. Web:need `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`
|
||||
|
||||
Detailed steps refer to [CONTRIBUTING](CONTRIBUTING.md)
|
||||
|
||||
##### 4:Install All(hertzbeat+mysql+tsdb) via Docker-compose
|
||||
##### 4:Install 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)
|
||||
|
||||
##### 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,10 +180,6 @@ Detailed steps refer to [Artifact Hub](https://artifacthub.io/packages/helm/hert
|
||||
|
||||
**HAVE FUN**
|
||||
|
||||
## 🥐 Roadmap
|
||||
|
||||

|
||||
|
||||
## ✨ Contributors
|
||||
|
||||
Thanks to these wonderful people, welcome to join us:
|
||||
@@ -411,7 +413,7 @@ Thanks to these wonderful people, welcome to join us:
|
||||
<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="Code">💻</a> <a href="#design-gjjjj0101" title="Design">🎨</a> <a href="https://github.com/apache/hertzbeat/commits?author=gjjjj0101" title="Tests">⚠️</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>
|
||||
@@ -437,15 +439,53 @@ Thanks to these wonderful people, welcome to join us:
|
||||
<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/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://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></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="https://github.com/apache/hertzbeat/commits?author=kerwin612" title="Code">💻</a> <a href="#design-kerwin612" title="Design">🎨</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></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></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></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></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
@@ -463,7 +503,7 @@ 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`.
|
||||
|
||||
@@ -493,11 +533,5 @@ HertzBeat has been included in the <a href="https://landscape.cncf.io/guide?item
|
||||
CNCF Observability And Analysis - Monitoring Landscape.</a>
|
||||
</p>
|
||||
|
||||
|
||||
## Star History
|
||||
|
||||
[](https://star-history.com/#apache/hertzbeat&Date)
|
||||
|
||||
|
||||
## 🛡️ License
|
||||
[`Apache License, Version 2.0`](https://www.apache.org/licenses/LICENSE-2.0.html)
|
||||
|
||||
+104
-70
@@ -14,9 +14,11 @@
|
||||
[](https://www.reddit.com/r/hertzbeat/)
|
||||
[](https://twitter.com/hertzbeat1024)
|
||||
[](https://www.bestpractices.dev/projects/8139)
|
||||
[](https://hub.docker.com/repository/docker/apache/hertzbeat/general)
|
||||
[](https://app.codecov.io/gh/apache/hertzbeat)
|
||||
[](https://hub.docker.com/r/apache/hertzbeat)
|
||||
[](https://artifacthub.io/packages/search?repo=hertzbeat)
|
||||
[](https://www.youtube.com/channel/UCri75zfWX0GHqJFPENEbLow)
|
||||
[](https://gitpod.io/#https://github.com/apache/hertzbeat)
|
||||
|
||||
|
||||
**官网: [hertzbeat.apache.org](https://hertzbeat.apache.org)**
|
||||
@@ -40,7 +42,7 @@
|
||||
|
||||
> `HertzBeat`的强大自定义,多类型支持,高性能,易扩展,低耦合,希望能帮助用户快速搭建自有监控系统。
|
||||
|
||||
----
|
||||
----
|
||||
|
||||

|
||||
|
||||
@@ -48,7 +50,7 @@
|
||||
|
||||

|
||||
|
||||
----
|
||||
----
|
||||
|
||||
## 🥐 模块
|
||||
|
||||
@@ -59,42 +61,42 @@
|
||||
> 我们将监控采集类型(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)
|
||||
- [Website](https://raw.githubusercontent.com/apache/hertzbeat/master/hertzbeat-manager/src/main/resources/define/app-website.yml), [Port Telnet](https://raw.githubusercontent.com/apache/hertzbeat/master/hertzbeat-manager/src/main/resources/define/app-port.yml),
|
||||
[Http Api](https://raw.githubusercontent.com/apache/hertzbeat/master/hertzbeat-manager/src/main/resources/define/app-api.yml), [Ping Connect](https://raw.githubusercontent.com/apache/hertzbeat/master/hertzbeat-manager/src/main/resources/define/app-ping.yml),
|
||||
[Jvm](https://raw.githubusercontent.com/apache/hertzbeat/master/hertzbeat-manager/src/main/resources/define/app-jvm.yml), [SiteMap](https://raw.githubusercontent.com/apache/hertzbeat/master/hertzbeat-manager/src/main/resources/define/app-fullsite.yml),
|
||||
[Ssl Certificate](https://raw.githubusercontent.com/apache/hertzbeat/master/hertzbeat-manager/src/main/resources/define/app-ssl_cert.yml), [SpringBoot2](https://raw.githubusercontent.com/apache/hertzbeat/master/hertzbeat-manager/src/main/resources/define/app-springboot2.yml),
|
||||
[FTP Server](https://raw.githubusercontent.com/apache/hertzbeat/master/hertzbeat-manager/src/main/resources/define/app-ftp.yml), [SpringBoot3](https://raw.githubusercontent.com/apache/hertzbeat/master/hertzbeat-manager/src/main/resources/define/app-springboot3.yml),
|
||||
[Udp Port](https://raw.githubusercontent.com/apache/hertzbeat/master/hertzbeat-manager/src/main/resources/define/app-udp_port.yml), [Dns](https://raw.githubusercontent.com/apache/hertzbeat/master/hertzbeat-manager/src/main/resources/define/app-dns.yml),
|
||||
[Pop3](https://raw.githubusercontent.com/apache/hertzbeat/master/hertzbeat-manager/src/main/resources/define/app-pop3.yml), [Ntp](https://raw.githubusercontent.com/apache/hertzbeat/master/hertzbeat-manager/src/main/resources/define/app-ntp.yml),
|
||||
[Api Code](https://raw.githubusercontent.com/apache/hertzbeat/master/hertzbeat-manager/src/main/resources/define/app-api_code.yml), [Smtp](https://raw.githubusercontent.com/apache/hertzbeat/master/hertzbeat-manager/src/main/resources/define/app-smtp.yml),
|
||||
[Nginx](https://raw.githubusercontent.com/apache/hertzbeat/master/hertzbeat-manager/src/main/resources/define/app-nginx.yml)
|
||||
- [Mysql](https://raw.githubusercontent.com/apache/hertzbeat/master/hertzbeat-manager/src/main/resources/define/app-mysql.yml), [PostgreSQL](https://raw.githubusercontent.com/apache/hertzbeat/master/hertzbeat-manager/src/main/resources/define/app-postgresql.yml),
|
||||
[MariaDB](https://raw.githubusercontent.com/apache/hertzbeat/master/hertzbeat-manager/src/main/resources/define/app-mariadb.yml), [Redis](https://raw.githubusercontent.com/apache/hertzbeat/master/hertzbeat-manager/src/main/resources/define/app-redis.yml),
|
||||
[ElasticSearch](https://raw.githubusercontent.com/apache/hertzbeat/master/hertzbeat-manager/src/main/resources/define/app-elasticsearch.yml), [SqlServer](https://raw.githubusercontent.com/apache/hertzbeat/master/hertzbeat-manager/src/main/resources/define/app-sqlserver.yml),
|
||||
[Oracle](https://raw.githubusercontent.com/apache/hertzbeat/master/hertzbeat-manager/src/main/resources/define/app-oracle.yml), [MongoDB](https://raw.githubusercontent.com/apache/hertzbeat/master/hertzbeat-manager/src/main/resources/define/app-mongodb.yml),
|
||||
[DM](https://raw.githubusercontent.com/apache/hertzbeat/master/hertzbeat-manager/src/main/resources/define/app-dm.yml), [OpenGauss](https://raw.githubusercontent.com/apache/hertzbeat/master/hertzbeat-manager/src/main/resources/define/app-opengauss.yml),
|
||||
[ClickHouse](https://raw.githubusercontent.com/apache/hertzbeat/master/hertzbeat-manager/src/main/resources/define/app-clickhouse.yml), [IoTDB](https://raw.githubusercontent.com/apache/hertzbeat/master/hertzbeat-manager/src/main/resources/define/app-iotdb.yml),
|
||||
[Redis Cluster](https://raw.githubusercontent.com/apache/hertzbeat/master/hertzbeat-manager/src/main/resources/define/app-redis_cluster.yml), [Redis Sentinel](https://raw.githubusercontent.com/apache/hertzbeat/master/hertzbeat-manager/src/main/resources/define/app-redis_sentinel.yml)
|
||||
[Doris BE](https://github.com/apache/hertzbeat/blob/master/hertzbeat-manager/src/main/resources/define/app-doris_be.yml), [Doris FE](https://github.com/apache/hertzbeat/blob/master/hertzbeat-manager/src/main/resources/define/app-doris_fe.yml),
|
||||
[Memcached](https://github.com/apache/hertzbeat/blob/master/hertzbeat-manager/src/main/resources/define/app-memcached.yml), [NebulaGraph](https://github.com/apache/hertzbeat/blob/master/hertzbeat-manager/src/main/resources/define/app-nebula_graph.yml)
|
||||
- [Linux](https://raw.githubusercontent.com/apache/hertzbeat/master/hertzbeat-manager/src/main/resources/define/app-linux.yml), [Ubuntu](https://raw.githubusercontent.com/apache/hertzbeat/master/hertzbeat-manager/src/main/resources/define/app-ubuntu.yml),
|
||||
[CentOS](https://raw.githubusercontent.com/apache/hertzbeat/master/hertzbeat-manager/src/main/resources/define/app-centos.yml), [Windows](https://raw.githubusercontent.com/apache/hertzbeat/master/hertzbeat-manager/src/main/resources/define/app-windows.yml),
|
||||
[EulerOS](https://raw.githubusercontent.com/apache/hertzbeat/master/hertzbeat-manager/src/main/resources/define/app-euleros.yml), [Fedora CoreOS](https://raw.githubusercontent.com/apache/hertzbeat/master/hertzbeat-manager/src/main/resources/define/app-coreos.yml),
|
||||
[OpenSUSE](https://raw.githubusercontent.com/apache/hertzbeat/master/hertzbeat-manager/src/main/resources/define/app-opensuse.yml), [Rocky Linux](https://raw.githubusercontent.com/apache/hertzbeat/master/hertzbeat-manager/src/main/resources/define/app-rockylinux.yml),
|
||||
[Red Hat](https://raw.githubusercontent.com/apache/hertzbeat/master/hertzbeat-manager/src/main/resources/define/app-redhat.yml), [FreeBSD](https://raw.githubusercontent.com/apache/hertzbeat/master/hertzbeat-manager/src/main/resources/define/app-freebsd.yml),
|
||||
[AlmaLinux](https://raw.githubusercontent.com/apache/hertzbeat/master/hertzbeat-manager/src/main/resources/define/app-almalinux.yml), [Debian Linux](https://raw.githubusercontent.com/apache/hertzbeat/master/hertzbeat-manager/src/main/resources/define/app-debian.yml)
|
||||
- [Tomcat](https://raw.githubusercontent.com/apache/hertzbeat/master/hertzbeat-manager/src/main/resources/define/app-tomcat.yml), [Nacos](https://raw.githubusercontent.com/apache/hertzbeat/master/hertzbeat-manager/src/main/resources/define/app-nacos.yml),
|
||||
[Zookeeper](https://raw.githubusercontent.com/apache/hertzbeat/master/hertzbeat-manager/src/main/resources/define/app-zookeeper.yml), [RabbitMQ](https://raw.githubusercontent.com/apache/hertzbeat/master/hertzbeat-manager/src/main/resources/define/app-rabbitmq.yml),
|
||||
[Flink](https://raw.githubusercontent.com/apache/hertzbeat/master/hertzbeat-manager/src/main/resources/define/app-flink.yml), [Kafka](https://raw.githubusercontent.com/apache/hertzbeat/master/hertzbeat-manager/src/main/resources/define/app-kafka.yml),
|
||||
[ShenYu](https://raw.githubusercontent.com/apache/hertzbeat/master/hertzbeat-manager/src/main/resources/define/app-shenyu.yml), [DynamicTp](https://raw.githubusercontent.com/apache/hertzbeat/master/hertzbeat-manager/src/main/resources/define/app-dynamic_tp.yml),
|
||||
[Jetty](https://raw.githubusercontent.com/apache/hertzbeat/master/hertzbeat-manager/src/main/resources/define/app-jetty.yml), [ActiveMQ](https://raw.githubusercontent.com/apache/hertzbeat/master/hertzbeat-manager/src/main/resources/define/app-activemq.yml),
|
||||
[Spring Gateway](https://raw.githubusercontent.com/apache/hertzbeat/master/hertzbeat-manager/src/main/resources/define/app-spring_gateway.yml), [EMQX MQTT](https://raw.githubusercontent.com/apache/hertzbeat/master/hertzbeat-manager/src/main/resources/define/app-emqx.yml),
|
||||
[AirFlow](https://raw.githubusercontent.com/apache/hertzbeat/master/hertzbeat-manager/src/main/resources/define/app-airflow.yml), [Hive](https://raw.githubusercontent.com/apache/hertzbeat/master/hertzbeat-manager/src/main/resources/define/app-hive.yml),
|
||||
[Spark](https://raw.githubusercontent.com/apache/hertzbeat/master/hertzbeat-manager/src/main/resources/define/app-spark.yml), [Hadoop](https://raw.githubusercontent.com/apache/hertzbeat/master/hertzbeat-manager/src/main/resources/define/app-hadoop.yml)
|
||||
- [Kubernetes](https://raw.githubusercontent.com/apache/hertzbeat/master/hertzbeat-manager/src/main/resources/define/app-kubernetes.yml), [Docker](https://raw.githubusercontent.com/apache/hertzbeat/master/hertzbeat-manager/src/main/resources/define/app-docker.yml)
|
||||
- [CiscoSwitch](https://raw.githubusercontent.com/apache/hertzbeat/master/hertzbeat-manager/src/main/resources/define/app-cisco_switch.yml), [HpeSwitch](https://raw.githubusercontent.com/apache/hertzbeat/master/hertzbeat-manager/src/main/resources/define/app-hpe_switch.yml),
|
||||
[HuaweiSwitch](https://raw.githubusercontent.com/apache/hertzbeat/master/hertzbeat-manager/src/main/resources/define/app-huawei_switch.yml), [TpLinkSwitch](https://raw.githubusercontent.com/apache/hertzbeat/master/hertzbeat-manager/src/main/resources/define/app-tplink_switch.yml),
|
||||
[H3cSwitch](https://raw.githubusercontent.com/apache/hertzbeat/master/hertzbeat-manager/src/main/resources/define/app-h3c_switch.yml)
|
||||
- 和更多自定义监控模版。
|
||||
- 通知支持 `Discord` `Slack` `Telegram` `邮件` `钉钉` `微信` `飞书` `短信` `Webhook` `Server酱`。
|
||||
|
||||
@@ -109,30 +111,34 @@
|
||||
|
||||
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` : 配置连接主 HertaBeat 服务的对外 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. 下载您系统环境对应的安装包 `hertzbeat-xx.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. 部署采集器集群(可选)
|
||||
- 下载采集器安装包 `hertzbeat-collector-xx.tar.gz` 到规划的另一台部署主机上 [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:
|
||||
@@ -153,19 +159,19 @@ docker run -d -e IDENTITY=custom-collector-name -e MANAGER_HOST=127.0.0.1 -e MAN
|
||||
##### 方式三:本地代码启动
|
||||
|
||||
1. 此为前后端分离项目,本地代码调试需要分别启动后端工程 `manager` 和前端工程 `web-app`
|
||||
2. 后端:需要 `maven3+`, `java17` 和 `lombok` 环境,修改 `YML` 配置信息并启动 `manager` 服务
|
||||
2. 后端:需要 `maven3+`, `java17` 和 `lombok` 环境,修改 `YML` 配置信息,添加JVM参数`--add-opens=java.base/java.nio=org.apache.arrow.memory.core,ALL-UNNAMED`后启动 `manager` 服务即可。
|
||||
3. 前端:需要 `nodejs npm angular-cli`环境,待本地后端启动后,在 `web-app` 目录下启动 `ng serve --open`
|
||||
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,10 +179,6 @@ docker run -d -e IDENTITY=custom-collector-name -e MANAGER_HOST=127.0.0.1 -e MAN
|
||||
|
||||
**HAVE FUN**
|
||||
|
||||
## 🥐 路线图
|
||||
|
||||

|
||||
|
||||
## ✨ Contributors
|
||||
|
||||
Thanks these wonderful people, welcome to join us:
|
||||
@@ -410,7 +412,7 @@ Thanks these wonderful people, welcome to join us:
|
||||
<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="Code">💻</a> <a href="#design-gjjjj0101" title="Design">🎨</a> <a href="https://github.com/apache/hertzbeat/commits?author=gjjjj0101" title="Tests">⚠️</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>
|
||||
@@ -436,15 +438,53 @@ Thanks these wonderful people, welcome to join us:
|
||||
<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/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://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></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="https://github.com/apache/hertzbeat/commits?author=kerwin612" title="Code">💻</a> <a href="#design-kerwin612" title="Design">🎨</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></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></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></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></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
@@ -462,7 +502,7 @@ Thanks these wonderful people, welcome to join us:
|
||||
|
||||
[Chat On Discord](https://discord.gg/Fb6M73htGr)
|
||||
|
||||
微信交流群 : 加 `tan-cloud` 好友邀请进群.
|
||||
微信交流群 : 加 `ahertzbeat` 好友邀请进群.
|
||||
|
||||
微信公众号 : 搜索 ID `usthecom`.
|
||||
|
||||
@@ -494,11 +534,5 @@ HertzBeat has been included in the <a href="https://landscape.cncf.io/guide?item
|
||||
CNCF Observability And Analysis - Monitoring Landscape.</a>
|
||||
</p>
|
||||
|
||||
|
||||
## Star History
|
||||
|
||||
[](https://star-history.com/#apache/hertzbeat&Date)
|
||||
|
||||
|
||||
## 🛡️ License
|
||||
[`Apache License, Version 2.0`](https://www.apache.org/licenses/LICENSE-2.0.html)
|
||||
|
||||
+9
-6
@@ -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/)
|
||||
|
||||
-233
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
-65
@@ -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.collector.dispatch.unit.impl;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.math.RoundingMode;
|
||||
import org.apache.hertzbeat.collector.dispatch.unit.TimeLengthUnit;
|
||||
import org.apache.hertzbeat.collector.dispatch.unit.UnitConvert;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
/**
|
||||
* the convert of time length
|
||||
*/
|
||||
@Component
|
||||
public final class TimeLengthConvert implements UnitConvert {
|
||||
|
||||
|
||||
@Override
|
||||
public String convert(String value, String originUnit, String newUnit) {
|
||||
if (value == null || value.isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
BigDecimal length = new BigDecimal(value);
|
||||
// Idea: Value is converted to nanoseconds through origin unit,
|
||||
// and then converted to the value corresponding to the new unit unit
|
||||
for (TimeLengthUnit timeLengthUnit : TimeLengthUnit.values()) {
|
||||
if (timeLengthUnit.getUnit().equals(originUnit.toUpperCase())) {
|
||||
length = length.multiply(new BigDecimal(timeLengthUnit.getScale()));
|
||||
}
|
||||
if (timeLengthUnit.getUnit().equals(newUnit.toUpperCase())) {
|
||||
length = length.divide(new BigDecimal(timeLengthUnit.getScale()), 12, RoundingMode.HALF_UP);
|
||||
}
|
||||
}
|
||||
return length.setScale(4, RoundingMode.HALF_UP).stripTrailingZeros().toPlainString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean checkUnit(String unit) {
|
||||
if (unit == null || unit.isEmpty()) {
|
||||
return false;
|
||||
}
|
||||
for (TimeLengthUnit timeUnit : TimeLengthUnit.values()) {
|
||||
// not case-sensitive
|
||||
if (timeUnit.getUnit().equals(unit.toUpperCase())) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
Vendored
-112
@@ -1,112 +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 static org.junit.jupiter.api.Assertions.assertFalse;
|
||||
import static org.junit.jupiter.api.Assertions.assertSame;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
import java.util.Optional;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
/**
|
||||
* Test case for {@link ConnectionCommonCache}
|
||||
*/
|
||||
class CommonCacheTest {
|
||||
|
||||
private AbstractConnection<?> mockConnection;
|
||||
|
||||
private ConnectionCommonCache<String, AbstractConnection<?>> cache;
|
||||
|
||||
@BeforeEach
|
||||
void setUp() {
|
||||
cache = new ConnectionCommonCache<>();
|
||||
mockConnection = new AbstractConnection<>() {
|
||||
@Override
|
||||
public Object getConnection() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void closeConnection() throws Exception {
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@Test
|
||||
void testAddAndRetrieveCache() {
|
||||
String key = "testKey";
|
||||
cache.addCache(key, mockConnection);
|
||||
|
||||
Optional<AbstractConnection<?>> retrieved = cache.getCache(key, false);
|
||||
assertTrue(retrieved.isPresent());
|
||||
assertSame(mockConnection, retrieved.get());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testCacheTimeout() throws InterruptedException {
|
||||
String key = "timeoutKey";
|
||||
cache.addCache(key, mockConnection, 1L);
|
||||
|
||||
Thread.sleep(2);
|
||||
Optional<AbstractConnection<?>> retrieved = cache.getCache(key, false);
|
||||
assertFalse(retrieved.isPresent());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testRemoveCache() {
|
||||
String key = "removeKey";
|
||||
cache.addCache(key, mockConnection);
|
||||
cache.removeCache(key);
|
||||
|
||||
Optional<AbstractConnection<?>> retrieved = cache.getCache(key, false);
|
||||
assertFalse(retrieved.isPresent());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testRefreshCache() {
|
||||
String key = "refreshKey";
|
||||
cache.addCache(key, mockConnection, 5000L);
|
||||
|
||||
Optional<AbstractConnection<?>> firstRetrieval = cache.getCache(key, true);
|
||||
assertTrue(firstRetrieval.isPresent());
|
||||
|
||||
|
||||
Optional<AbstractConnection<?>> secondRetrieval = cache.getCache(key, false);
|
||||
assertTrue(secondRetrieval.isPresent());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testConcurrentAccess() throws InterruptedException {
|
||||
String key = "concurrentKey";
|
||||
cache.addCache(key, mockConnection);
|
||||
|
||||
Runnable accessCache = () -> {
|
||||
Optional<AbstractConnection<?>> retrieved = cache.getCache(key, false);
|
||||
assertTrue(retrieved.isPresent());
|
||||
};
|
||||
|
||||
Thread thread1 = new Thread(accessCache);
|
||||
Thread thread2 = new Thread(accessCache);
|
||||
thread1.start();
|
||||
thread2.start();
|
||||
|
||||
thread1.join();
|
||||
thread2.join();
|
||||
}
|
||||
}
|
||||
-78
@@ -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.collector.collect.http.promethus.exporter;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import java.util.Map;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
/**
|
||||
* Test case for {@link ExporterParser}
|
||||
*/
|
||||
class ExporterParserTest {
|
||||
|
||||
@Test
|
||||
void textToMetric() {
|
||||
String resp = "# HELP disk_total_bytes Total space for path\n"
|
||||
+ "# TYPE disk_total_bytes gauge\n"
|
||||
+ "disk_total_bytes{path=\"C:\\\\hertzbeat\\\\repo\\\\testpath\",} 4.29496725504E11\n"
|
||||
+ "# HELP go_gc_cycles_automatic_gc_cycles_total Count of completed GC cycles generated by the Go runtime.\n"
|
||||
+ "# TYPE go_gc_cycles_automatic_gc_cycles_total counter\n"
|
||||
+ "go_gc_cycles_automatic_gc_cycles_total 0\n"
|
||||
+ "# HELP go_gc_cycles_forced_gc_cycles_total Count of completed GC cycles forced by the application.\n"
|
||||
+ "# TYPE go_gc_cycles_forced_gc_cycles_total counter\n"
|
||||
+ "go_gc_cycles_forced_gc_cycles_total 0\n"
|
||||
+ "# HELP go_gc_cycles_total_gc_cycles_total Count of all completed GC cycles.\n"
|
||||
+ "# TYPE go_gc_cycles_total_gc_cycles_total counter\n"
|
||||
+ "go_gc_cycles_total_gc_cycles_total 0\n"
|
||||
+ "# HELP go_gc_duration_seconds A summary of the pause duration of garbage collection cycles.\n"
|
||||
+ "# TYPE go_gc_duration_seconds summary\n"
|
||||
+ "go_gc_duration_seconds{quantile=\"0\"} 0\n"
|
||||
+ "go_gc_duration_seconds{quantile=\"0.25\"} 0\n"
|
||||
+ "go_gc_duration_seconds{quantile=\"0.5\"} 0\n"
|
||||
+ "go_gc_duration_seconds{quantile=\"0.75\"} 0\n"
|
||||
+ "go_gc_duration_seconds{quantile=\"1\"} 0\n"
|
||||
+ "# TYPE jvm info\n"
|
||||
+ "# HELP jvm VM version info\n"
|
||||
+ "jvm_info{runtime=\"OpenJDK Runtime Environment\",vendor=\"Azul Systems, Inc.\",version=\"11.0.13+8-LTS\"} 1.0\n"
|
||||
+ "# TYPE jvm_gc_collection_seconds summary\n"
|
||||
+ "# HELP jvm_gc_collection_seconds Time spent in a given JVM garbage collector in seconds.\n"
|
||||
+ "jvm_gc_collection_seconds_count{gc=\"G1 Young Generation\"} 10.0\n"
|
||||
+ "jvm_gc_collection_seconds_sum{gc=\"G1 Young Generation\"} 0.051\n"
|
||||
+ "jvm_gc_collection_seconds_count{gc=\"G1 Old Generation\"} 0.0\n"
|
||||
+ "jvm_gc_collection_seconds_sum{gc=\"G1 Old Generation\"} 0.0\n"
|
||||
+ "# TYPE resource_group_aggregate_usage_secs summary\n"
|
||||
+ "resource_group_aggregate_usage_secs{cluster=\"standalone\",quantile=\"0.5\"} 2.69245E-4\n"
|
||||
+ "resource_group_aggregate_usage_secs{cluster=\"standalone\",quantile=\"0.9\"} 3.49601E-4\n"
|
||||
+ "resource_group_aggregate_usage_secs_count{cluster=\"standalone\"} 13.0\n"
|
||||
+ "resource_group_aggregate_usage_secs_sum{cluster=\"standalone\"} 0.004832498\n"
|
||||
+ "resource_group_aggregate_usage_secs_created{cluster=\"standalone\"} 1.715842140749E9\n"
|
||||
+ "# TYPE metadata_store_ops_latency_ms histogram\n"
|
||||
+ "metadata_store_ops_latency_ms_bucket{cluster=\"standalone\",name=\"metadata-store\",type=\"get\",status=\"success\",le=\"1.0\"} 59.0\n"
|
||||
+ "metadata_store_ops_latency_ms_bucket{cluster=\"standalone\",name=\"metadata-store\",type=\"get\",status=\"success\",le=\"3.0\"} 61.0\n"
|
||||
+ "metadata_store_ops_latency_ms_bucket{cluster=\"standalone\",name=\"metadata-store\",type=\"get\",status=\"success\",le=\"5.0\"} 61.0\n"
|
||||
+ "# EOF";
|
||||
|
||||
ExporterParser parser = new ExporterParser();
|
||||
Map<String, MetricFamily> metricFamilyMap = parser.textToMetric(resp);
|
||||
assertEquals(5, metricFamilyMap.get("resource_group_aggregate_usage_secs").getMetricList().size());
|
||||
assertEquals(3, metricFamilyMap.get("metadata_store_ops_latency_ms").getMetricList().size());
|
||||
assertEquals(5, metricFamilyMap.get("go_gc_duration_seconds").getMetricList().size());
|
||||
assertEquals(9, metricFamilyMap.size());
|
||||
}
|
||||
}
|
||||
@@ -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.collector.util;
|
||||
|
||||
import java.io.IOException;
|
||||
import org.junit.jupiter.api.DisplayName;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
/**
|
||||
* test case for {@link PrivateKeyUtils}
|
||||
*/
|
||||
class PrivateKeyUtilsTest {
|
||||
|
||||
@DisplayName("write key to ~/.ssh")
|
||||
@Test
|
||||
void writePrivateKey() throws IOException {
|
||||
var key = "-----BEGIN RSA PRIVATE KEY-----\n"
|
||||
+ "MIIEogIBAAKCAQEA4ctFYk/xy89L6/6YFeeMrwCW9lCP/ThXMn+9G63s5bGn4oIN\n"
|
||||
+ "8cEf/JYkmGw8vMP41IAP9dyH8ji2wIZSLeTPWucEK6P6jA01iIBQ95ng6RTsnQgL\n"
|
||||
+ "h4pYHxlEaNHcXkjy5GlMdzaWadjdRevpThGR1VOtWFtK3yoC0c/te2Junu04f+11\n"
|
||||
+ "cpk8QvmVfzrBUooVnG0/7oekwUy1c5sSl0qVoLzXOv4XG9w34cyvacFC30zv1Nl8\n"
|
||||
+ "ASi2pmOBVx9njPvqQ7qZrDk0nwn+RZUmGh/PbmHxrBV7ZA5NjZcEnf2VGIfjGUVu\n"
|
||||
+ "qE4VnkbvS4j03afV2rsp1yo74K+k/ZC6GCHB5QIBIwKCAQBG9r4I9I3SVxfcdJYy\n"
|
||||
+ "xR2WFiDREgFeNkdKYqkl9NVsws5dIY9am8g5cQQv54DNnK1KGZ6dulaclXtD0nGZ\n"
|
||||
+ "ZSs505OYr+EHcd2f7dBN0Uavp32QcD4jSLycD0FixZ0HsIbaEnceJxlUd1t8YBYf\n"
|
||||
+ "2aLcpUUbxOulORbUOgjPAa286uDeQYN5IbdruDfvbuFFm7hBoGZoKLJ7FPcJ0U3A\n"
|
||||
+ "14KRK+Z1oCYJIS0ubaHbhaPIVPPQEmTNHpsvxIJXfZtVy9+XIuBGmD3+Aq6SSFPC\n"
|
||||
+ "A8mU1iKzzdRCXZwvPeUiivIIZc6DRXjhtJ2Lya/XndKidOT/QUj8Z+f9pWAonlzM\n"
|
||||
+ "3PMXAoGBAPvzctkkDjUJjLyEuYQq8soYokS4n4ykFTP5oFgnodK/cYocbxTT6Tn9\n"
|
||||
+ "vH7b6lK6ZAf+tZk8rcEeIO650pOvmaa1/OuZSxfcFUGBvOvYXiHF7zmkePh/pQgB\n"
|
||||
+ "7Cl0RYrI52Cjbd9aCUIYK3A82qsUq30INGeOhMNrfaHn2pgx8xlDAoGBAOVsNctw\n"
|
||||
+ "CHnLaIQX8eS+eUcQEm+NZppnDBJavdpP48ZZM/t5v/2fQ5ytbYqk0KEzIGu0dP8g\n"
|
||||
+ "jfB76JbMvStvTfB+TrXsfhGyA3oJrEcG+3IUshsRU2sohT1ScY27z2VMLgilnWvF\n"
|
||||
+ "7t49sQm9uB/yn669n8LIciHxDItOpvqgKdG3AoGBAO2NxA6PtZ+4jAIz/19bsbc7\n"
|
||||
+ "zDIqaovrKe8tMMglXg/ZE0e0aLvdvqRkRAKU1Z51Ob5lLuDwEYoyWZCgk1gL90Vp\n"
|
||||
+ "wpT+P3zlcyCBo39IWMDB8C8IydRbF/GbaaNtoKds92m+qWwwUd87XCf+3M0wvvI6\n"
|
||||
+ "75TW1PLEbyOgFz8Khh8hAoGBAJbDc87Ul9sCAtp2Ip2hvWk2coPR8vfADz9C8cn5\n"
|
||||
+ "/BShBOcVfipSt2b1n8GCP/TnFU4XgBVeiSkA9+4Rg6AzMzejdY1+JvWvfqCnRVM/\n"
|
||||
+ "GkOnMzZb17tyZi+ck8OKC/IcHkAyUYFWL0GWQSOojvBsPQxt+0V8aEIwsHjNSSha\n"
|
||||
+ "nyNpAoGAd0XqdByRxbWgg5ZsvM0tvrpMITpEZsGMG9VeQPGl0wsQvC2zw5QGLvz/\n"
|
||||
+ "57YhofOOr0M3yElcFA9Imvek5CYZsyL8eIWGZyadfRiYvGOUyvDDO3BYRG4DmhyF\n"
|
||||
+ "KVk3URjEuOCC29ORvZ/7HaCO9iuEbvAA/mrAtd7KdCA+3PzfEOw=\n"
|
||||
+ "-----END RSA PRIVATE KEY-----";
|
||||
PrivateKeyUtils.writePrivateKey("127.0.0.1", key);
|
||||
}
|
||||
}
|
||||
@@ -1,316 +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.common.config;
|
||||
|
||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
|
||||
/**
|
||||
* common module properties
|
||||
*/
|
||||
@ConfigurationProperties(prefix = "common")
|
||||
public class CommonProperties {
|
||||
|
||||
/**
|
||||
* secret key for password aes entry, must 16 bits
|
||||
*/
|
||||
private String secret;
|
||||
|
||||
/**
|
||||
* data queue impl
|
||||
*/
|
||||
private DataQueueProperties queue;
|
||||
|
||||
/**
|
||||
* sms impl properties
|
||||
*/
|
||||
private SmsProperties sms;
|
||||
|
||||
public String getSecret() {
|
||||
return secret;
|
||||
}
|
||||
|
||||
public DataQueueProperties getQueue() {
|
||||
return queue;
|
||||
}
|
||||
|
||||
public SmsProperties getSms() {
|
||||
return sms;
|
||||
}
|
||||
|
||||
public void setSecret(String secret) {
|
||||
this.secret = secret;
|
||||
}
|
||||
|
||||
public void setQueue(DataQueueProperties queue) {
|
||||
this.queue = queue;
|
||||
}
|
||||
|
||||
public void setSms(SmsProperties sms) {
|
||||
this.sms = sms;
|
||||
}
|
||||
|
||||
/**
|
||||
* data queue properties
|
||||
*/
|
||||
public static class DataQueueProperties {
|
||||
|
||||
private QueueType type = QueueType.Memory;
|
||||
|
||||
private KafkaProperties kafka;
|
||||
|
||||
public QueueType getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
public void setType(QueueType type) {
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
public KafkaProperties getKafka() {
|
||||
return kafka;
|
||||
}
|
||||
|
||||
public void setKafka(KafkaProperties kafka) {
|
||||
this.kafka = kafka;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* data queue type
|
||||
*/
|
||||
public enum QueueType {
|
||||
/** in memory **/
|
||||
Memory,
|
||||
/** kafka **/
|
||||
Kafka,
|
||||
/** with netty connect **/
|
||||
Netty,
|
||||
/** rabbit mq **/
|
||||
Rabbit_Mq
|
||||
}
|
||||
|
||||
/**
|
||||
* kafka data queue properties
|
||||
*/
|
||||
public static class KafkaProperties {
|
||||
/**
|
||||
* kafka's connection server url
|
||||
*/
|
||||
private String servers;
|
||||
/**
|
||||
* metrics data topic
|
||||
*/
|
||||
private String metricsDataTopic;
|
||||
/**
|
||||
* alerts data topic
|
||||
*/
|
||||
private String alertsDataTopic;
|
||||
|
||||
public String getServers() {
|
||||
return servers;
|
||||
}
|
||||
|
||||
public void setServers(String servers) {
|
||||
this.servers = servers;
|
||||
}
|
||||
|
||||
public String getMetricsDataTopic() {
|
||||
return metricsDataTopic;
|
||||
}
|
||||
|
||||
public void setMetricsDataTopic(String metricsDataTopic) {
|
||||
this.metricsDataTopic = metricsDataTopic;
|
||||
}
|
||||
|
||||
public String getAlertsDataTopic() {
|
||||
return alertsDataTopic;
|
||||
}
|
||||
|
||||
public void setAlertsDataTopic(String alertsDataTopic) {
|
||||
this.alertsDataTopic = alertsDataTopic;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* sms properties
|
||||
*/
|
||||
public static class SmsProperties {
|
||||
//Tencent cloud SMS configuration
|
||||
private TencentSmsProperties tencent;
|
||||
//Ali cloud SMS configuration
|
||||
private AliYunSmsProperties aliYun;
|
||||
|
||||
public TencentSmsProperties getTencent() {
|
||||
return tencent;
|
||||
}
|
||||
|
||||
public void setTencent(TencentSmsProperties tencent) {
|
||||
this.tencent = tencent;
|
||||
}
|
||||
|
||||
public AliYunSmsProperties getAliYun() {
|
||||
return aliYun;
|
||||
}
|
||||
|
||||
public void setAliYun(AliYunSmsProperties aliYun) {
|
||||
this.aliYun = aliYun;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* tencent sms properties
|
||||
*/
|
||||
public static class TencentSmsProperties {
|
||||
|
||||
/**
|
||||
* Tencent cloud account secret id
|
||||
*/
|
||||
private String secretId;
|
||||
|
||||
/**
|
||||
* Tencent cloud account secret key
|
||||
*/
|
||||
private String secretKey;
|
||||
|
||||
/**
|
||||
* SMS app id
|
||||
*/
|
||||
private String appId;
|
||||
|
||||
/**
|
||||
* SMS signature
|
||||
*/
|
||||
private String signName;
|
||||
|
||||
/**
|
||||
* SMS template ID
|
||||
*/
|
||||
private String templateId;
|
||||
|
||||
public String getSecretId() {
|
||||
return secretId;
|
||||
}
|
||||
|
||||
public void setSecretId(String secretId) {
|
||||
this.secretId = secretId;
|
||||
}
|
||||
|
||||
public String getSecretKey() {
|
||||
return secretKey;
|
||||
}
|
||||
|
||||
public void setSecretKey(String secretKey) {
|
||||
this.secretKey = secretKey;
|
||||
}
|
||||
|
||||
public String getAppId() {
|
||||
return appId;
|
||||
}
|
||||
|
||||
public void setAppId(String appId) {
|
||||
this.appId = appId;
|
||||
}
|
||||
|
||||
public String getSignName() {
|
||||
return signName;
|
||||
}
|
||||
|
||||
public void setSignName(String signName) {
|
||||
this.signName = signName;
|
||||
}
|
||||
|
||||
public String getTemplateId() {
|
||||
return templateId;
|
||||
}
|
||||
|
||||
public void setTemplateId(String templateId) {
|
||||
this.templateId = templateId;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* aliYun sms properties
|
||||
*/
|
||||
public static class AliYunSmsProperties {
|
||||
|
||||
/**
|
||||
* Aliyun account access key id
|
||||
*/
|
||||
private String secretId;
|
||||
|
||||
/**
|
||||
* Ali Cloud account access key
|
||||
*/
|
||||
private String secretKey;
|
||||
|
||||
/**
|
||||
* SMS app id
|
||||
*/
|
||||
private String appId;
|
||||
|
||||
/**
|
||||
* SMS signature
|
||||
*/
|
||||
private String signName;
|
||||
|
||||
/**
|
||||
* ID of the SMS template
|
||||
*/
|
||||
private String templateId;
|
||||
|
||||
public String getAppId() {
|
||||
return appId;
|
||||
}
|
||||
|
||||
public void setAppId(String appId) {
|
||||
this.appId = appId;
|
||||
}
|
||||
|
||||
public String getSecretId() {
|
||||
return secretId;
|
||||
}
|
||||
|
||||
public void setSecretId(String secretId) {
|
||||
this.secretId = secretId;
|
||||
}
|
||||
|
||||
public String getSecretKey() {
|
||||
return secretKey;
|
||||
}
|
||||
|
||||
public void setSecretKey(String secretKey) {
|
||||
this.secretKey = secretKey;
|
||||
}
|
||||
|
||||
public String getSignName() {
|
||||
return signName;
|
||||
}
|
||||
|
||||
public void setSignName(String signName) {
|
||||
this.signName = signName;
|
||||
}
|
||||
|
||||
public String getTemplateId() {
|
||||
return templateId;
|
||||
}
|
||||
|
||||
public void setTemplateId(String templateId) {
|
||||
this.templateId = templateId;
|
||||
}
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -1,255 +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.common.util.prometheus;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.math.BigDecimal;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* prometheus metric sparser
|
||||
*/
|
||||
public final class PrometheusUtil {
|
||||
|
||||
//An unknown format occurred during parsing because parsing cannot continue
|
||||
// or the end of the input stream has been reached
|
||||
private static final int ERROR_FORMAT = -1;
|
||||
|
||||
//The input stream ends normally
|
||||
private static final int NORMAL_END = -2;
|
||||
|
||||
private static final int COMMENT_LINE = -3;
|
||||
|
||||
private PrometheusUtil() {
|
||||
}
|
||||
|
||||
private static int parseMetricName(InputStream inputStream, Metric.MetricBuilder metricBuilder) throws IOException {
|
||||
StringBuilder stringBuilder = new StringBuilder();
|
||||
int i;
|
||||
i = inputStream.read();
|
||||
if (i == -1) {
|
||||
return NORMAL_END;
|
||||
}
|
||||
else if (i == '#') {
|
||||
return COMMENT_LINE;
|
||||
}
|
||||
|
||||
while (i != -1) {
|
||||
if (i == ' ' || i == '{') {
|
||||
metricBuilder.metricName(stringBuilder.toString());
|
||||
return i;
|
||||
}
|
||||
stringBuilder.append((char) i);
|
||||
i = inputStream.read();
|
||||
}
|
||||
|
||||
return ERROR_FORMAT;
|
||||
}
|
||||
|
||||
private static int parseLabel(InputStream inputStream, List<Label> labelList) throws IOException {
|
||||
Label.LabelBuilder labelBuilder = new Label.LabelBuilder();
|
||||
int i;
|
||||
|
||||
StringBuilder labelName = new StringBuilder();
|
||||
i = inputStream.read();
|
||||
while (i != -1 && i != '=') {
|
||||
labelName.append((char) i);
|
||||
i = inputStream.read();
|
||||
}
|
||||
if (i == -1) {
|
||||
return ERROR_FORMAT;
|
||||
}
|
||||
labelBuilder.name(labelName.toString());
|
||||
|
||||
if (inputStream.read() != '\"') {
|
||||
return ERROR_FORMAT;
|
||||
}
|
||||
|
||||
StringBuilder labelValue = new StringBuilder();
|
||||
i = inputStream.read();
|
||||
while (i != -1 && i != ',' && i != '}') {
|
||||
labelValue.append((char) i);
|
||||
i = inputStream.read();
|
||||
}
|
||||
if (i == -1 || labelValue.charAt(labelValue.length() - 1) != '\"') {
|
||||
return ERROR_FORMAT;
|
||||
}
|
||||
|
||||
// skip space only in this condition
|
||||
if (i == '}' && inputStream.read() != ' ') {
|
||||
return ERROR_FORMAT;
|
||||
}
|
||||
|
||||
labelValue.deleteCharAt(labelValue.length() - 1);
|
||||
labelBuilder.value(labelValue.toString());
|
||||
|
||||
labelList.add(labelBuilder.build());
|
||||
return i;
|
||||
}
|
||||
|
||||
private static int parseLabelList(InputStream inputStream, Metric.MetricBuilder metricBuilder) throws IOException {
|
||||
List<Label> labelList = new ArrayList<>();
|
||||
int i;
|
||||
|
||||
i = parseLabel(inputStream, labelList);
|
||||
while (i == ',') {
|
||||
i = parseLabel(inputStream, labelList);
|
||||
}
|
||||
if (i == -1) {
|
||||
return ERROR_FORMAT;
|
||||
}
|
||||
|
||||
metricBuilder.labelList(labelList);
|
||||
return i;
|
||||
}
|
||||
|
||||
private static int parseValue(InputStream inputStream, Metric.MetricBuilder metricBuilder) throws IOException {
|
||||
int i;
|
||||
|
||||
StringBuilder stringBuilder = new StringBuilder();
|
||||
i = inputStream.read();
|
||||
while (i != -1 && i != ' ' && i != '\n') {
|
||||
stringBuilder.append((char) i);
|
||||
i = inputStream.read();
|
||||
}
|
||||
|
||||
String string = stringBuilder.toString();
|
||||
|
||||
switch (string) {
|
||||
case "NaN":
|
||||
metricBuilder.value(Double.NaN);
|
||||
break;
|
||||
case "+Inf":
|
||||
metricBuilder.value(Double.POSITIVE_INFINITY);
|
||||
break;
|
||||
case "-Inf":
|
||||
metricBuilder.value(Double.NEGATIVE_INFINITY);
|
||||
break;
|
||||
default:
|
||||
try {
|
||||
BigDecimal bigDecimal = new BigDecimal(string);
|
||||
metricBuilder.value(bigDecimal.doubleValue());
|
||||
} catch (NumberFormatException e) {
|
||||
return ERROR_FORMAT;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if (i == -1) {
|
||||
return NORMAL_END;
|
||||
}
|
||||
else {
|
||||
return i; // ' ' or \n'
|
||||
}
|
||||
}
|
||||
|
||||
private static int parseTimestamp(InputStream inputStream, Metric.MetricBuilder metricBuilder) throws IOException {
|
||||
int i;
|
||||
|
||||
StringBuilder stringBuilder = new StringBuilder();
|
||||
i = inputStream.read();
|
||||
while (i != -1 && i != '\n') {
|
||||
stringBuilder.append((char) i);
|
||||
i = inputStream.read();
|
||||
}
|
||||
|
||||
String string = stringBuilder.toString();
|
||||
try {
|
||||
metricBuilder.timestamp(Long.parseLong(string));
|
||||
} catch (NumberFormatException e) {
|
||||
return ERROR_FORMAT;
|
||||
}
|
||||
|
||||
if (i == -1) {
|
||||
return NORMAL_END;
|
||||
}
|
||||
else {
|
||||
return i; // '\n'
|
||||
}
|
||||
}
|
||||
|
||||
// return value:
|
||||
// -1: error format
|
||||
// -2: normal end
|
||||
// '\n': more lines
|
||||
private static int parseMetric(InputStream inputStream, List<Metric> metrics) throws IOException {
|
||||
Metric.MetricBuilder metricBuilder = new Metric.MetricBuilder();
|
||||
|
||||
int i = parseMetricName(inputStream, metricBuilder); // RET: -1, -2, -3, '{', ' '
|
||||
if (i == ERROR_FORMAT || i == NORMAL_END || i == COMMENT_LINE) {
|
||||
return i;
|
||||
}
|
||||
|
||||
if (i == '{') {
|
||||
i = parseLabelList(inputStream, metricBuilder); // RET: -1, '}'
|
||||
if (i == ERROR_FORMAT) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
i = parseValue(inputStream, metricBuilder); // RET: -1, -2, '\n', ' '
|
||||
if (i != ' ') {
|
||||
metrics.add(metricBuilder.build());
|
||||
return i;
|
||||
}
|
||||
|
||||
i = parseTimestamp(inputStream, metricBuilder); // RET: -1, -2, '\n'
|
||||
|
||||
metrics.add(metricBuilder.build());
|
||||
return i;
|
||||
|
||||
}
|
||||
|
||||
private static int skipCommentLine(InputStream inputStream) throws IOException {
|
||||
int i = inputStream.read();
|
||||
while (i != -1 && i != '\n') {
|
||||
i = inputStream.read();
|
||||
}
|
||||
if (i == -1) {
|
||||
return NORMAL_END;
|
||||
}
|
||||
return i;
|
||||
}
|
||||
|
||||
public static List<Metric> parseMetrics(InputStream inputStream) throws IOException {
|
||||
List<Metric> metricList = new ArrayList<>();
|
||||
int i = parseMetric(inputStream, metricList);
|
||||
while (i == '\n' || i == COMMENT_LINE) {
|
||||
if (i == COMMENT_LINE) {
|
||||
if (skipCommentLine(inputStream) == NORMAL_END) {
|
||||
return metricList;
|
||||
}
|
||||
|
||||
}
|
||||
i = parseMetric(inputStream, metricList);
|
||||
}
|
||||
if (i == NORMAL_END) {
|
||||
return metricList;
|
||||
}
|
||||
else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -1,77 +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.
|
||||
*/
|
||||
|
||||
syntax = "proto3";
|
||||
package org.apache.hertzbeat.common.entity.message;
|
||||
|
||||
message MetricsData
|
||||
{
|
||||
// monitoring id
|
||||
uint64 id = 1;
|
||||
// tenant id
|
||||
uint64 tenantId = 2;
|
||||
// monitoring app eg: linux | mysql | jvm
|
||||
string app = 3;
|
||||
// monitoring metrics eg: cpu | memory | health
|
||||
string metrics = 4;
|
||||
// monitoring collect priority >=0
|
||||
uint32 priority = 5;
|
||||
// collect timestamp
|
||||
uint64 time = 6;
|
||||
// collect response code
|
||||
Code code = 7;
|
||||
// collect response error message
|
||||
string msg = 8;
|
||||
// monitoring collect metric field
|
||||
repeated Field fields = 9;
|
||||
// monitoring collect metric data, mapping with the fields
|
||||
repeated ValueRow values = 10;
|
||||
}
|
||||
|
||||
message Field
|
||||
{
|
||||
// monitoring collect metric field name
|
||||
string name = 1;
|
||||
// monitoring collect metrics field type, 0-number 1-string
|
||||
uint32 type = 2;
|
||||
// monitoring collect metrics field unit, % MB GB TB S...
|
||||
string unit = 3;
|
||||
// is label field
|
||||
bool label = 4;
|
||||
}
|
||||
|
||||
message ValueRow
|
||||
{
|
||||
// monitoring collect metrics value, mapping with the fields
|
||||
repeated string columns = 1;
|
||||
}
|
||||
|
||||
enum Code
|
||||
{
|
||||
// collect success
|
||||
SUCCESS = 0;
|
||||
// collector not available
|
||||
UN_AVAILABLE = 1;
|
||||
// peer network un reachable(icmp)
|
||||
UN_REACHABLE = 2;
|
||||
// peer network server un connectable(tcp,udp...)
|
||||
UN_CONNECTABLE = 3;
|
||||
// collect metrics data failed(http,ssh,snmp...)
|
||||
FAIL = 4;
|
||||
// collect metrics data timeout
|
||||
TIMEOUT = 5;
|
||||
}
|
||||
@@ -1,57 +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.common.util;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertFalse;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
/**
|
||||
* Test case for {@link CommonUtil}
|
||||
*/
|
||||
class CommonUtilTest {
|
||||
|
||||
@Test
|
||||
void testParseDoubleStr() {
|
||||
assertEquals("9.3454", CommonUtil.parseDoubleStr("9.345435345", null));
|
||||
assertEquals("9.3454", CommonUtil.parseDoubleStr("9.345435345%", "%"));
|
||||
assertEquals("10", CommonUtil.parseDoubleStr("10%", "%"));
|
||||
assertEquals("588", CommonUtil.parseDoubleStr("588Mb", "Mb"));
|
||||
}
|
||||
|
||||
@Test
|
||||
void validateEmail() {
|
||||
assertTrue(CommonUtil.validateEmail("tom@usthe.com"));
|
||||
assertTrue(CommonUtil.validateEmail("demo@qq.com"));
|
||||
assertFalse(CommonUtil.validateEmail("tom.usthe.com"));
|
||||
}
|
||||
|
||||
@Test
|
||||
void validatePhoneNum() {
|
||||
assertTrue(CommonUtil.validatePhoneNum("19234554432"));
|
||||
assertTrue(CommonUtil.validatePhoneNum("13234554432"));
|
||||
assertTrue(CommonUtil.validatePhoneNum("14234554432"));
|
||||
assertTrue(CommonUtil.validatePhoneNum("16234554432"));
|
||||
assertFalse(CommonUtil.validatePhoneNum("12234554432"));
|
||||
assertFalse(CommonUtil.validatePhoneNum("11234554432"));
|
||||
assertFalse(CommonUtil.validatePhoneNum("35234554432"));
|
||||
assertFalse(CommonUtil.validatePhoneNum("46234554432"));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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.common.util;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertFalse;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
/**
|
||||
* Test case for {@link IpDomainUtil}
|
||||
*/
|
||||
class IpDomainUtilTest {
|
||||
|
||||
@Test
|
||||
void validateIpDomain() {
|
||||
assertTrue(IpDomainUtil.validateIpDomain("127.7.5.3"));
|
||||
assertTrue(IpDomainUtil.validateIpDomain("255.255.4.3"));
|
||||
assertTrue(IpDomainUtil.validateIpDomain("255.255.255.255"));
|
||||
assertTrue(IpDomainUtil.validateIpDomain("tancloud.cn"));
|
||||
assertTrue(IpDomainUtil.validateIpDomain("tancloud.com.cn"));
|
||||
assertTrue(IpDomainUtil.validateIpDomain("student.dev.com.cn"));
|
||||
assertTrue(IpDomainUtil.validateIpDomain("www.student.dev.com.cn"));
|
||||
assertTrue(IpDomainUtil.validateIpDomain("www.baidu.com"));
|
||||
assertTrue(IpDomainUtil.validateIpDomain("good.didi"));
|
||||
assertTrue(IpDomainUtil.validateIpDomain("spider_rds.sogou"));
|
||||
assertTrue(IpDomainUtil.validateIpDomain("_redis.hn.sogou"));
|
||||
assertTrue(IpDomainUtil.validateIpDomain("host"));
|
||||
assertTrue(IpDomainUtil.validateIpDomain("host-1"));
|
||||
assertFalse(IpDomainUtil.validateIpDomain("www.baidu.com."));
|
||||
assertFalse(IpDomainUtil.validateIpDomain("good."));
|
||||
assertFalse(IpDomainUtil.validateIpDomain(".good."));
|
||||
assertFalse(IpDomainUtil.validateIpDomain("www.baidu..com"));
|
||||
assertFalse(IpDomainUtil.validateIpDomain("www.baidu*com"));
|
||||
assertFalse(IpDomainUtil.validateIpDomain("host$-1"));
|
||||
}
|
||||
|
||||
@Test
|
||||
void isHasSchema() {
|
||||
assertTrue(IpDomainUtil.isHasSchema("http://www.baidu.com"));
|
||||
assertTrue(IpDomainUtil.isHasSchema("https://www.baidu.com"));
|
||||
assertFalse(IpDomainUtil.isHasSchema("www.baidu.com"));
|
||||
assertFalse(IpDomainUtil.isHasSchema("https_www.baidu.com"));
|
||||
}
|
||||
}
|
||||
@@ -1,23 +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.
|
||||
|
||||
FROM ghcr.io/linuxsuren/api-testing:v0.0.16
|
||||
|
||||
WORKDIR /workspace
|
||||
COPY . .
|
||||
|
||||
CMD [ "/workspace/entrypoint.sh" ]
|
||||
@@ -1,19 +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.
|
||||
|
||||
demo:
|
||||
docker compose up hertzbeat
|
||||
+2
-2
@@ -1,7 +1,7 @@
|
||||
Please add the corresponding e2e (aka end-to-end) test cases if you add or update APIs.
|
||||
|
||||
## How to work
|
||||
* Start and watch the [docker-compose](https://docs.docker.com/compose/) via [the script](start.sh)
|
||||
* Start and watch the [docker-compose](https://docs.docker.com/compose/) via [the script](script/start.sh)
|
||||
* Run the e2e testing via [api-testing](https://github.com/LinuxSuRen/api-testing)
|
||||
* It will run the test cases from top to bottom
|
||||
* You can add the necessary asserts to it
|
||||
@@ -11,4 +11,4 @@ Please follow these steps if you want to run the e2e testing locally.
|
||||
|
||||
> Please make sure you have installed docker-compose v2
|
||||
|
||||
* Change the directory to `e2e`, then execute `./start.sh`
|
||||
* Change the directory to `e2e`, then execute `./script/start.sh`
|
||||
|
||||
@@ -12,22 +12,22 @@
|
||||
{
|
||||
"field": "host",
|
||||
"type": 1,
|
||||
"value": "127.0.0.1"
|
||||
"paramValue": "127.0.0.1"
|
||||
},
|
||||
{
|
||||
"field": "port",
|
||||
"type": 0,
|
||||
"value": 21
|
||||
"paramValue": 21
|
||||
},
|
||||
{
|
||||
"field": "direction",
|
||||
"type": 1,
|
||||
"value": "127.0.0.1"
|
||||
"paramValue": "127.0.0.1"
|
||||
},
|
||||
{
|
||||
"field": "timeout",
|
||||
"type": 0,
|
||||
"value": 1000
|
||||
"paramValue": 1000
|
||||
},
|
||||
{
|
||||
"field": "username",
|
||||
|
||||
+75
-77
@@ -1,80 +1,78 @@
|
||||
|
||||
{
|
||||
"detected": false,
|
||||
"collector": "",
|
||||
"monitor": {
|
||||
"intervals": 60,
|
||||
"tags": [],
|
||||
"app": "api",
|
||||
"host": "127.0.0.1",
|
||||
"detected": false,
|
||||
"collector": "",
|
||||
"monitor": {
|
||||
"intervals": 60,
|
||||
"tags": [],
|
||||
"app": "api",
|
||||
"host": "127.0.0.1",
|
||||
"name": "{{.param.monitorHTTP}}"
|
||||
},
|
||||
"params": [
|
||||
{
|
||||
"field": "host",
|
||||
"type": 1,
|
||||
"paramValue": "127.0.0.1"
|
||||
},
|
||||
"params": [
|
||||
{
|
||||
"field": "host",
|
||||
"type": 1,
|
||||
"value": "127.0.0.1"
|
||||
},
|
||||
{
|
||||
"field": "port",
|
||||
"type": 0,
|
||||
"value": 80
|
||||
},
|
||||
{
|
||||
"field": "method",
|
||||
"type": 1,
|
||||
"value": "GET"
|
||||
},
|
||||
{
|
||||
"field": "uri",
|
||||
"type": 1,
|
||||
"value": ""
|
||||
},
|
||||
{
|
||||
"field": "ssl",
|
||||
"type": 1,
|
||||
"value": false
|
||||
},
|
||||
{
|
||||
"field": "headers",
|
||||
"type": 3
|
||||
},
|
||||
{
|
||||
"field": "params",
|
||||
"type": 3
|
||||
},
|
||||
{
|
||||
"field": "timeout",
|
||||
"type": 0
|
||||
},
|
||||
{
|
||||
"field": "contentType",
|
||||
"type": 1
|
||||
},
|
||||
{
|
||||
"field": "payload",
|
||||
"type": 1
|
||||
},
|
||||
{
|
||||
"field": "authType",
|
||||
"type": 1
|
||||
},
|
||||
{
|
||||
"field": "username",
|
||||
"type": 1
|
||||
},
|
||||
{
|
||||
"field": "password",
|
||||
"type": 1
|
||||
},
|
||||
{
|
||||
"field": "keyword",
|
||||
"type": 1
|
||||
},
|
||||
{
|
||||
"field": "successCode",
|
||||
"type": 4,
|
||||
"value": "200, 201"
|
||||
}
|
||||
]
|
||||
}
|
||||
{
|
||||
"field": "port",
|
||||
"type": 0,
|
||||
"paramValue": 80
|
||||
},
|
||||
{
|
||||
"field": "httpMethod",
|
||||
"type": 1,
|
||||
"paramValue": "GET"
|
||||
},
|
||||
{
|
||||
"field": "uri",
|
||||
"type": 1
|
||||
},
|
||||
{
|
||||
"field": "ssl",
|
||||
"type": 1,
|
||||
"paramValue": false
|
||||
},
|
||||
{
|
||||
"field": "headers",
|
||||
"type": 3
|
||||
},
|
||||
{
|
||||
"field": "params",
|
||||
"type": 3
|
||||
},
|
||||
{
|
||||
"field": "timeout",
|
||||
"type": 0
|
||||
},
|
||||
{
|
||||
"field": "contentType",
|
||||
"type": 1
|
||||
},
|
||||
{
|
||||
"field": "payload",
|
||||
"type": 1
|
||||
},
|
||||
{
|
||||
"field": "authType",
|
||||
"type": 1
|
||||
},
|
||||
{
|
||||
"field": "username",
|
||||
"type": 1
|
||||
},
|
||||
{
|
||||
"field": "password",
|
||||
"type": 1
|
||||
},
|
||||
{
|
||||
"field": "keyword",
|
||||
"type": 1
|
||||
},
|
||||
{
|
||||
"field": "successCode",
|
||||
"type": 4,
|
||||
"paramValue": "200, 201"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -12,12 +12,12 @@
|
||||
{
|
||||
"field": "host",
|
||||
"type": 1,
|
||||
"value": "127.0.0.1"
|
||||
"paramValue": "127.0.0.1"
|
||||
},
|
||||
{
|
||||
"field": "timeout",
|
||||
"type": 0,
|
||||
"value": 6000
|
||||
"paramValue": 6000
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
@@ -12,17 +12,17 @@
|
||||
{
|
||||
"field": "host",
|
||||
"type": 1,
|
||||
"value": "127.0.0.1"
|
||||
"paramValue": "127.0.0.1"
|
||||
},
|
||||
{
|
||||
"field": "port",
|
||||
"type": 0,
|
||||
"value": 80
|
||||
"paramValue": 80
|
||||
},
|
||||
{
|
||||
"field": "timeout",
|
||||
"type": 0,
|
||||
"value": 6000
|
||||
"paramValue": 6000
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
@@ -12,22 +12,22 @@
|
||||
{
|
||||
"field": "host",
|
||||
"type": 1,
|
||||
"value": "127.0.0.1"
|
||||
"paramValue": "127.0.0.1"
|
||||
},
|
||||
{
|
||||
"field": "port",
|
||||
"type": 0,
|
||||
"value": 80
|
||||
"paramValue": 80
|
||||
},
|
||||
{
|
||||
"field": "sitemap",
|
||||
"type": 1,
|
||||
"value": "sitemap.xml"
|
||||
"paramValue": "sitemap.xml"
|
||||
},
|
||||
{
|
||||
"field": "ssl",
|
||||
"type": 1,
|
||||
"value": false
|
||||
"paramValue": false
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
@@ -12,12 +12,12 @@
|
||||
{
|
||||
"field": "host",
|
||||
"type": 1,
|
||||
"value": "127.0.0.1"
|
||||
"paramValue": "127.0.0.1"
|
||||
},
|
||||
{
|
||||
"field": "port",
|
||||
"type": 0,
|
||||
"value": 443
|
||||
"paramValue": 443
|
||||
},
|
||||
{
|
||||
"field": "uri",
|
||||
|
||||
@@ -12,17 +12,17 @@
|
||||
{
|
||||
"field": "host",
|
||||
"type": 1,
|
||||
"value": "127.0.0.1"
|
||||
"paramValue": "127.0.0.1"
|
||||
},
|
||||
{
|
||||
"field": "port",
|
||||
"type": 0,
|
||||
"value": 81
|
||||
"paramValue": 81
|
||||
},
|
||||
{
|
||||
"field": "timeout",
|
||||
"type": 0,
|
||||
"value": 6000
|
||||
"paramValue": 6000
|
||||
},
|
||||
{
|
||||
"field": "content",
|
||||
|
||||
@@ -12,21 +12,21 @@
|
||||
{
|
||||
"field": "host",
|
||||
"type": 1,
|
||||
"value": "127.0.0.1"
|
||||
"paramValue": "127.0.0.1"
|
||||
},
|
||||
{
|
||||
"field": "port",
|
||||
"type": 0,
|
||||
"value": 80
|
||||
"paramValue": 80
|
||||
},
|
||||
{
|
||||
"field": "uri",
|
||||
"type": 1
|
||||
"paramValue": 1
|
||||
},
|
||||
{
|
||||
"field": "ssl",
|
||||
"type": 1,
|
||||
"value": false
|
||||
"paramValue": false
|
||||
},
|
||||
{
|
||||
"field": "timeout",
|
||||
|
||||
@@ -18,24 +18,39 @@
|
||||
version: '3.8'
|
||||
services:
|
||||
testing:
|
||||
build:
|
||||
context: .
|
||||
image: ghcr.io/linuxsuren/api-testing:v0.0.17
|
||||
environment:
|
||||
SERVER: http://hertzbeat:1157
|
||||
container_name: e2e-testing
|
||||
volumes:
|
||||
- ./data/:/work/data/
|
||||
- ./testsuite.yaml:/work/testsuite.yaml
|
||||
- ./report/report.md:/report.md
|
||||
command: atest run -p /work/testsuite.yaml --level debug --thread 3 --report md --report-file /report.md
|
||||
depends_on:
|
||||
hertzbeat:
|
||||
checker:
|
||||
condition: service_healthy
|
||||
links:
|
||||
- hertzbeat
|
||||
hertzbeat:
|
||||
image: apache/hertzbeat
|
||||
ports:
|
||||
- 1157:1157
|
||||
environment:
|
||||
ALLOW_NONE_AUTHENTICATION: "yes"
|
||||
- checker
|
||||
checker:
|
||||
image: alpine:latest
|
||||
container_name: e2e-checker
|
||||
command: sh -c "apk add --update curl && tail -f /dev/null"
|
||||
healthcheck:
|
||||
test: ["CMD", "bash", "-c", "cat < /dev/null > /dev/tcp/127.0.0.1/1157"]
|
||||
test: [ "CMD-SHELL",
|
||||
"curl -s -X POST -H \"Content-Type: application/json\" -d '{\"type\": 0,\"identifier\": \"admin\",\"credential\": \"hertzbeat\"}' http://hertzbeat:1157/api/account/auth/form | grep -q token"
|
||||
]
|
||||
interval: 3s
|
||||
timeout: 60s
|
||||
retries: 10
|
||||
start_period: 3s
|
||||
start_period: 10s
|
||||
hertzbeat:
|
||||
image: apache/hertzbeat:test
|
||||
container_name: e2e-hertzbeat
|
||||
volumes:
|
||||
- ./logs/:/opt/hertzbeat/logs/
|
||||
ports:
|
||||
- "1157:1157"
|
||||
environment:
|
||||
ALLOW_NONE_AUTHENTICATION: "yes"
|
||||
@@ -0,0 +1 @@
|
||||
keep, not delete!
|
||||
@@ -1,49 +0,0 @@
|
||||
#!/bin/bash
|
||||
# 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.
|
||||
|
||||
# Derived from Api Testing https://github.com/LinuxSuRen/api-testing/blob/master/e2e/start.sh
|
||||
|
||||
file=$1
|
||||
if [ "$file" == "" ]
|
||||
then
|
||||
file=compose.yaml
|
||||
fi
|
||||
|
||||
docker-compose version
|
||||
docker-compose -f "$file" up --build -d
|
||||
|
||||
while true
|
||||
do
|
||||
docker-compose -f "$file" ps | grep testing
|
||||
if [ $? -eq 1 ]
|
||||
then
|
||||
code=-1
|
||||
docker-compose -f "$file" logs | grep e2e-testing
|
||||
docker-compose -f "$file" logs | grep e2e-testing | grep Usage
|
||||
if [ $? -eq 1 ]
|
||||
then
|
||||
code=0
|
||||
echo "successed"
|
||||
fi
|
||||
|
||||
docker-compose -f "$file" down
|
||||
set -e
|
||||
exit $code
|
||||
fi
|
||||
sleep 1
|
||||
done
|
||||
+162
-32
@@ -58,11 +58,6 @@ items:
|
||||
}
|
||||
expect:
|
||||
statusCode: 409
|
||||
- name: missing-auth-header
|
||||
request:
|
||||
api: /api/monitors
|
||||
expect:
|
||||
statusCode: 401
|
||||
- name: monitorList
|
||||
request:
|
||||
api: /api/monitors?pageIndex=0&pageSize=8
|
||||
@@ -70,15 +65,12 @@ items:
|
||||
Authorization: Bearer {{.login.data.token}}
|
||||
expect:
|
||||
bodyFieldsExpect:
|
||||
code: 0
|
||||
- name: createHTTPMonitor
|
||||
code: "0"
|
||||
- name: missing-auth-header
|
||||
request:
|
||||
api: /api/monitor
|
||||
method: POST
|
||||
header:
|
||||
Authorization: Bearer {{.login.data.token}}
|
||||
Content-type: application/json
|
||||
bodyFromFile: data/monitor-http.json
|
||||
api: /api/monitors
|
||||
expect:
|
||||
statusCode: 401
|
||||
- name: createSitemapMonitor
|
||||
request:
|
||||
api: /api/monitor
|
||||
@@ -87,6 +79,26 @@ items:
|
||||
Authorization: Bearer {{.login.data.token}}
|
||||
Content-type: application/json
|
||||
bodyFromFile: data/monitor-sitemap.json
|
||||
- name: listSitemapMonitor
|
||||
request:
|
||||
api: /api/monitors?pageIndex=0&pageSize=8&app=fullsite
|
||||
header:
|
||||
Authorization: Bearer {{.login.data.token}}
|
||||
- name: cancelSitemapMonitor
|
||||
request:
|
||||
api: /api/monitors/manage?ids={{(index .listSitemapMonitor.data.content 0).id | int64}}
|
||||
query:
|
||||
type: JSON
|
||||
method: DELETE
|
||||
header:
|
||||
Authorization: Bearer {{.login.data.token}}
|
||||
- name: deleteSitemapMonitor
|
||||
request:
|
||||
api: /api/monitors?ids={{(index .listSitemapMonitor.data.content 0).id | int64}}
|
||||
method: DELETE
|
||||
header:
|
||||
Authorization: Bearer {{.login.data.token}}
|
||||
|
||||
- name: createPortMonitor
|
||||
request:
|
||||
api: /api/monitor
|
||||
@@ -95,6 +107,26 @@ items:
|
||||
Authorization: Bearer {{.login.data.token}}
|
||||
Content-type: application/json
|
||||
bodyFromFile: data/monitor-port.json
|
||||
- name: listPortMonitor
|
||||
request:
|
||||
api: /api/monitors?pageIndex=0&pageSize=8&app=port
|
||||
header:
|
||||
Authorization: Bearer {{.login.data.token}}
|
||||
- name: cancelPortMonitor
|
||||
request:
|
||||
api: /api/monitors/manage?ids={{(index .listPortMonitor.data.content 0).id | int64}}
|
||||
query:
|
||||
type: JSON
|
||||
method: DELETE
|
||||
header:
|
||||
Authorization: Bearer {{.login.data.token}}
|
||||
- name: deletePortMonitor
|
||||
request:
|
||||
api: /api/monitors?ids={{(index .listPortMonitor.data.content 0).id | int64}}
|
||||
method: DELETE
|
||||
header:
|
||||
Authorization: Bearer {{.login.data.token}}
|
||||
|
||||
- name: createSSLMonitor
|
||||
request:
|
||||
api: /api/monitor
|
||||
@@ -103,6 +135,26 @@ items:
|
||||
Authorization: Bearer {{.login.data.token}}
|
||||
Content-type: application/json
|
||||
bodyFromFile: data/monitor-ssl.json
|
||||
- name: listSSLMonitor
|
||||
request:
|
||||
api: /api/monitors?pageIndex=0&pageSize=8&app=ssl_cert
|
||||
header:
|
||||
Authorization: Bearer {{.login.data.token}}
|
||||
- name: cancelSSLMonitor
|
||||
request:
|
||||
api: /api/monitors/manage?ids={{(index .listSSLMonitor.data.content 0).id | int64}}
|
||||
query:
|
||||
type: JSON
|
||||
method: DELETE
|
||||
header:
|
||||
Authorization: Bearer {{.login.data.token}}
|
||||
- name: deleteSSLMonitor
|
||||
request:
|
||||
api: /api/monitors?ids={{(index .listSSLMonitor.data.content 0).id | int64}}
|
||||
method: DELETE
|
||||
header:
|
||||
Authorization: Bearer {{.login.data.token}}
|
||||
|
||||
- name: createPingMonitor
|
||||
request:
|
||||
api: /api/monitor
|
||||
@@ -111,6 +163,26 @@ items:
|
||||
Authorization: Bearer {{.login.data.token}}
|
||||
Content-type: application/json
|
||||
bodyFromFile: data/monitor-ping.json
|
||||
- name: listPingMonitor
|
||||
request:
|
||||
api: /api/monitors?pageIndex=0&pageSize=8&app=ping
|
||||
header:
|
||||
Authorization: Bearer {{.login.data.token}}
|
||||
- name: cancelPingMonitor
|
||||
request:
|
||||
api: /api/monitors/manage?ids={{(index .listPingMonitor.data.content 0).id | int64}}
|
||||
query:
|
||||
type: JSON
|
||||
method: DELETE
|
||||
header:
|
||||
Authorization: Bearer {{.login.data.token}}
|
||||
- name: deletePingMonitor
|
||||
request:
|
||||
api: /api/monitors?ids={{(index .listPingMonitor.data.content 0).id | int64}}
|
||||
method: DELETE
|
||||
header:
|
||||
Authorization: Bearer {{.login.data.token}}
|
||||
|
||||
- name: createUDPMonitor
|
||||
request:
|
||||
api: /api/monitor
|
||||
@@ -119,6 +191,26 @@ items:
|
||||
Authorization: Bearer {{.login.data.token}}
|
||||
Content-type: application/json
|
||||
bodyFromFile: data/monitor-udp.json
|
||||
- name: listUDPMonitor
|
||||
request:
|
||||
api: /api/monitors?pageIndex=0&pageSize=8&app=udp_port
|
||||
header:
|
||||
Authorization: Bearer {{.login.data.token}}
|
||||
- name: cancelUDPMonitor
|
||||
request:
|
||||
api: /api/monitors/manage?ids={{(index .listUDPMonitor.data.content 0).id | int64}}
|
||||
query:
|
||||
type: JSON
|
||||
method: DELETE
|
||||
header:
|
||||
Authorization: Bearer {{.login.data.token}}
|
||||
- name: deleteUDPMonitor
|
||||
request:
|
||||
api: /api/monitors?ids={{(index .listUDPMonitor.data.content 0).id | int64}}
|
||||
method: DELETE
|
||||
header:
|
||||
Authorization: Bearer {{.login.data.token}}
|
||||
|
||||
- name: createWebsiteMonitor
|
||||
request:
|
||||
api: /api/monitor
|
||||
@@ -127,6 +219,26 @@ items:
|
||||
Authorization: Bearer {{.login.data.token}}
|
||||
Content-type: application/json
|
||||
bodyFromFile: data/monitor-website.json
|
||||
- name: listWebsiteMonitor
|
||||
request:
|
||||
api: /api/monitors?pageIndex=0&pageSize=8&app=website
|
||||
header:
|
||||
Authorization: Bearer {{.login.data.token}}
|
||||
- name: cancelWebsiteMonitor
|
||||
request:
|
||||
api: /api/monitors/manage?ids={{(index .listWebsiteMonitor.data.content 0).id | int64}}
|
||||
query:
|
||||
type: JSON
|
||||
method: DELETE
|
||||
header:
|
||||
Authorization: Bearer {{.login.data.token}}
|
||||
- name: deleteWebsiteMonitor
|
||||
request:
|
||||
api: /api/monitors?ids={{(index .listWebsiteMonitor.data.content 0).id | int64}}
|
||||
method: DELETE
|
||||
header:
|
||||
Authorization: Bearer {{.login.data.token}}
|
||||
|
||||
- name: createFTPMonitor
|
||||
request:
|
||||
api: /api/monitor
|
||||
@@ -135,32 +247,54 @@ items:
|
||||
Authorization: Bearer {{.login.data.token}}
|
||||
Content-type: application/json
|
||||
bodyFromFile: data/monitor-ftp.json
|
||||
- name: listFTPMonitor
|
||||
request:
|
||||
api: /api/monitors?pageIndex=0&pageSize=8&app=ftp
|
||||
header:
|
||||
Authorization: Bearer {{.login.data.token}}
|
||||
- name: cancelFTPMonitor
|
||||
request:
|
||||
api: /api/monitors/manage?ids={{(index .listFTPMonitor.data.content 0).id | int64}}
|
||||
query:
|
||||
type: JSON
|
||||
method: DELETE
|
||||
header:
|
||||
Authorization: Bearer {{.login.data.token}}
|
||||
- name: deleteFTPMonitor
|
||||
request:
|
||||
api: /api/monitors?ids={{(index .listFTPMonitor.data.content 0).id | int64}}
|
||||
method: DELETE
|
||||
header:
|
||||
Authorization: Bearer {{.login.data.token}}
|
||||
|
||||
- name: createHTTPMonitor
|
||||
request:
|
||||
api: /api/monitor
|
||||
method: POST
|
||||
header:
|
||||
Authorization: Bearer {{.login.data.token}}
|
||||
Content-type: application/json
|
||||
bodyFromFile: data/monitor-http.json
|
||||
- name: listHTTPMonitor
|
||||
request:
|
||||
api: /api/monitors
|
||||
query:
|
||||
pageIndex: 0
|
||||
pageSize: 8
|
||||
app: api
|
||||
api: /api/monitors?pageIndex=0&pageSize=8&app=api
|
||||
header:
|
||||
Authorization: Bearer {{.login.data.token}}
|
||||
- name: cancelHTTPMonitor
|
||||
request:
|
||||
api: /api/monitors/manage
|
||||
api: /api/monitors/manage?ids={{(index .listHTTPMonitor.data.content 0).id | int64}}
|
||||
query:
|
||||
ids: "{{(index .listHTTPMonitor.data.content 0).id}}"
|
||||
type: JSON
|
||||
method: DELETE
|
||||
header:
|
||||
Authorization: Bearer {{.login.data.token}}
|
||||
- name: deleteHTTPMonitor
|
||||
request:
|
||||
api: /api/monitors
|
||||
query:
|
||||
ids: "{{(index .listHTTPMonitor.data.content 0).id}}"
|
||||
api: /api/monitors?ids={{(index .listHTTPMonitor.data.content 0).id | int64}}
|
||||
method: DELETE
|
||||
header:
|
||||
Authorization: Bearer {{.login.data.token}}
|
||||
|
||||
- name: listAlertDefines
|
||||
request:
|
||||
api: /api/alert/defines
|
||||
@@ -168,9 +302,7 @@ items:
|
||||
Authorization: Bearer {{.login.data.token}}
|
||||
- name: deleteAlertDefine
|
||||
request:
|
||||
api: /api/alert/defines
|
||||
query:
|
||||
ids: "{{(index .listAlertDefine.data.content 0).id}}"
|
||||
api: /api/alert/defines?ids={{(index .listAlertDefines.data.content 0).id | int64}}
|
||||
method: DELETE
|
||||
header:
|
||||
Authorization: Bearer {{.login.data.token}}
|
||||
@@ -227,7 +359,7 @@ items:
|
||||
]
|
||||
- name: listTags
|
||||
request:
|
||||
api: /api/tag
|
||||
api: /api/tag?pageIndex=0&pageSize=8&type=1
|
||||
header:
|
||||
Authorization: Bearer {{.login.data.token}}
|
||||
- name: updateTag
|
||||
@@ -239,9 +371,9 @@ items:
|
||||
Content-type: application/json
|
||||
body: |
|
||||
{
|
||||
"id": {{(index .listTags.data.content 0).id}},
|
||||
"id": {{(index .listTags.data.content 0).id | int64}},
|
||||
"name": "{{randAlpha 3}}",
|
||||
"value": "{{randAlpha 3}}",
|
||||
"tagValue": "{{randAlpha 3}}",
|
||||
"color": "#ff4081",
|
||||
"type": 1,
|
||||
"creator": "admin",
|
||||
@@ -252,9 +384,7 @@ items:
|
||||
code: "0"
|
||||
- name: deleteTag
|
||||
request:
|
||||
api: /api/tag
|
||||
query:
|
||||
ids: "{{(index .listTags.data.content 0).id}}"
|
||||
api: /api/tag?ids={{(index .listTags.data.content 0).id | int64}}
|
||||
method: DELETE
|
||||
header:
|
||||
Authorization: Bearer {{.login.data.token}}
|
||||
|
||||
@@ -28,9 +28,6 @@
|
||||
<artifactId>hertzbeat-alerter</artifactId>
|
||||
<name>${project.artifactId}</name>
|
||||
|
||||
<properties>
|
||||
</properties>
|
||||
|
||||
<dependencies>
|
||||
<!-- common -->
|
||||
<dependency>
|
||||
@@ -73,14 +70,16 @@
|
||||
<dependency>
|
||||
<groupId>cn.afterturn</groupId>
|
||||
<artifactId>easypoi-annotation</artifactId>
|
||||
<version>4.3.0</version>
|
||||
<version>${easy-poi.version}</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.poi</groupId>
|
||||
<artifactId>poi</artifactId>
|
||||
<version>4.1.1</version>
|
||||
<scope>compile</scope>
|
||||
<groupId>org.apache.arrow</groupId>
|
||||
<artifactId>arrow-vector</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.arrow</groupId>
|
||||
<artifactId>arrow-memory-netty</artifactId>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
+10
-18
@@ -19,22 +19,26 @@ package org.apache.hertzbeat.alert;
|
||||
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import org.apache.hertzbeat.common.config.BaseKafkaProperties;
|
||||
import org.apache.hertzbeat.common.constants.ConfigConstants;
|
||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
/**
|
||||
* alerter prop config
|
||||
*/
|
||||
@Component
|
||||
@ConfigurationProperties(prefix = "alerter")
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
@Component
|
||||
@ConfigurationProperties(prefix =
|
||||
ConfigConstants.FunctionModuleConstants.ALERTER)
|
||||
public class AlerterProperties {
|
||||
|
||||
/**
|
||||
* Alarm content console link
|
||||
*/
|
||||
private String consoleUrl = "https://console.tancloud.cn";
|
||||
private String consoleUrl = "https://console.tancloud.io";
|
||||
|
||||
/**
|
||||
* WeWork webhook url
|
||||
@@ -92,25 +96,13 @@ public class AlerterProperties {
|
||||
*/
|
||||
@Getter
|
||||
@Setter
|
||||
public static class KafkaProperties {
|
||||
public static class KafkaProperties extends BaseKafkaProperties {
|
||||
|
||||
/**
|
||||
* Whether the kafka data entry is started
|
||||
*/
|
||||
private boolean enabled = true;
|
||||
|
||||
/**
|
||||
* kafka's connection server url
|
||||
*/
|
||||
private String servers = "127.0.0.1:9092";
|
||||
/**
|
||||
* The name of the topic that receives the data
|
||||
*/
|
||||
private String topic;
|
||||
/**
|
||||
* Consumer Group ID
|
||||
*/
|
||||
private String groupId;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,99 @@
|
||||
/*
|
||||
* 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.LinkedBlockingQueue;
|
||||
import java.util.concurrent.RejectedExecutionException;
|
||||
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;
|
||||
private ThreadPoolExecutor notifyExecutor;
|
||||
|
||||
public AlerterWorkerPool() {
|
||||
initWorkExecutor();
|
||||
initNotifyExecutor();
|
||||
}
|
||||
|
||||
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(10,
|
||||
10,
|
||||
10,
|
||||
TimeUnit.SECONDS,
|
||||
new LinkedBlockingQueue<>(),
|
||||
threadFactory,
|
||||
new ThreadPoolExecutor.AbortPolicy());
|
||||
}
|
||||
|
||||
private void initNotifyExecutor() {
|
||||
ThreadFactory threadFactory = new ThreadFactoryBuilder()
|
||||
.setUncaughtExceptionHandler((thread, throwable) -> {
|
||||
log.error("notifyExecutor has uncaughtException.");
|
||||
log.error(throwable.getMessage(), throwable);
|
||||
})
|
||||
.setDaemon(true)
|
||||
.setNameFormat("notify-worker-%d")
|
||||
.build();
|
||||
notifyExecutor = new ThreadPoolExecutor(6,
|
||||
6,
|
||||
10,
|
||||
TimeUnit.SECONDS,
|
||||
new LinkedBlockingQueue<>(),
|
||||
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);
|
||||
}
|
||||
|
||||
/**
|
||||
* Executes the given runnable task using the notifyExecutor.
|
||||
*
|
||||
* @param runnable the task to be executed
|
||||
* @throws RejectedExecutionException if the task cannot be accepted for execution
|
||||
*/
|
||||
public void executeNotify(Runnable runnable) throws RejectedExecutionException {
|
||||
notifyExecutor.execute(runnable);
|
||||
}
|
||||
|
||||
}
|
||||
+93
-83
@@ -26,7 +26,10 @@ 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 com.google.common.collect.Maps;
|
||||
import jakarta.persistence.criteria.Predicate;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
@@ -45,8 +48,10 @@ 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.constants.MetricDataConstants;
|
||||
import org.apache.hertzbeat.common.entity.alerter.Alert;
|
||||
import org.apache.hertzbeat.common.entity.alerter.AlertDefine;
|
||||
import org.apache.hertzbeat.common.entity.arrow.RowWrapper;
|
||||
import org.apache.hertzbeat.common.entity.manager.Monitor;
|
||||
import org.apache.hertzbeat.common.entity.manager.TagItem;
|
||||
import org.apache.hertzbeat.common.entity.message.CollectRep;
|
||||
@@ -61,7 +66,6 @@ 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
|
||||
*/
|
||||
@@ -70,6 +74,8 @@ import org.springframework.util.CollectionUtils;
|
||||
public class CalculateAlarm {
|
||||
|
||||
private static final String SYSTEM_VALUE_ROW_COUNT = "system_value_row_count";
|
||||
|
||||
private static final int CALCULATE_THREADS = 3;
|
||||
|
||||
/**
|
||||
* The alarm in the process is triggered
|
||||
@@ -123,16 +129,17 @@ public class CalculateAlarm {
|
||||
if (metricsData != null) {
|
||||
calculate(metricsData);
|
||||
}
|
||||
dataQueue.sendMetricsDataToStorage(metricsData);
|
||||
} catch (InterruptedException ignored) {
|
||||
|
||||
Thread.currentThread().interrupt();
|
||||
} catch (Exception e) {
|
||||
log.error("calculate alarm error: {}.", e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
};
|
||||
workerPool.executeJob(runnable);
|
||||
workerPool.executeJob(runnable);
|
||||
workerPool.executeJob(runnable);
|
||||
for (int i = 0; i < CALCULATE_THREADS; i++) {
|
||||
workerPool.executeJob(runnable);
|
||||
}
|
||||
}
|
||||
|
||||
private void calculate(CollectRep.MetricsData metricsData) {
|
||||
@@ -154,94 +161,97 @@ public class CalculateAlarm {
|
||||
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()) {
|
||||
Map<String, Object> fieldValueMap = Maps.newHashMapWithExpectedSize(8);
|
||||
|
||||
if (CollectionUtils.isEmpty(valueRow.getColumnsList())) {
|
||||
try {
|
||||
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;
|
||||
}
|
||||
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);
|
||||
if (expr.contains(SYSTEM_VALUE_ROW_COUNT) && metricsData.getValues().size() == 0L) {
|
||||
fieldValueMap.put(SYSTEM_VALUE_ROW_COUNT, 0);
|
||||
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);
|
||||
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) {}
|
||||
}
|
||||
|
||||
RowWrapper rowWrapper = metricsData.readRow();
|
||||
while (rowWrapper.hasNextRow()) {
|
||||
rowWrapper = rowWrapper.nextRow();
|
||||
StringBuilder tagBuilder = new StringBuilder();
|
||||
fieldValueMap.clear();
|
||||
fieldValueMap.put(SYSTEM_VALUE_ROW_COUNT, metricsData.getValues().size());
|
||||
rowWrapper.cellStream().forEach(cell -> {
|
||||
String valueStr = cell.getValue();
|
||||
if (CommonConstants.NULL_VALUE.equals(valueStr)) {
|
||||
return;
|
||||
}
|
||||
|
||||
final String fieldName = cell.getField().getName();
|
||||
final int fieldType = cell.getMetadataAsInteger(MetricDataConstants.TYPE);
|
||||
|
||||
if (fieldType == CommonConstants.TYPE_NUMBER) {
|
||||
final Double doubleValue;
|
||||
if ((doubleValue = CommonUtil.parseStrDouble(valueStr)) != null) {
|
||||
fieldValueMap.put(fieldName, doubleValue);
|
||||
}
|
||||
} else if (fieldType == CommonConstants.TYPE_TIME) {
|
||||
final Integer integerValue;
|
||||
if ((integerValue = CommonUtil.parseStrInteger(valueStr)) != null) {
|
||||
fieldValueMap.put(fieldName, integerValue);
|
||||
}
|
||||
} else {
|
||||
String alarmKey = String.valueOf(monitorId) + define.getId() + tagBuilder;
|
||||
triggeredAlertMap.remove(alarmKey);
|
||||
if (define.isRecoverNotice()) {
|
||||
handleRecoveredAlert(currentTimeMilli, define, expr, alarmKey);
|
||||
if (StringUtils.isNotEmpty(valueStr)) {
|
||||
fieldValueMap.put(fieldName, valueStr);
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.error(e.getMessage(), e);
|
||||
}
|
||||
} catch (Exception ignored) {}
|
||||
|
||||
if (cell.getMetadataAsBoolean(MetricDataConstants.LABEL)) {
|
||||
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) {}
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.error(e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
|
||||
+34
@@ -0,0 +1,34 @@
|
||||
/*
|
||||
* 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.apache.hertzbeat.common.constants.ConfigConstants;
|
||||
import org.apache.hertzbeat.common.constants.SignConstants;
|
||||
import org.springframework.boot.autoconfigure.AutoConfiguration;
|
||||
import org.springframework.context.annotation.ComponentScan;
|
||||
|
||||
/**
|
||||
* Alert auto configuration.
|
||||
*/
|
||||
|
||||
@AutoConfiguration
|
||||
@ComponentScan(basePackages = ConfigConstants.PkgConstant.PKG
|
||||
+ SignConstants.DOT
|
||||
+ ConfigConstants.FunctionModuleConstants.ALERT)
|
||||
public class AlerterAutoConfiguration {
|
||||
}
|
||||
+5
-5
@@ -23,6 +23,7 @@ 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.Objects;
|
||||
import org.apache.hertzbeat.alert.service.AlertConvergeService;
|
||||
import org.apache.hertzbeat.common.entity.alerter.AlertConverge;
|
||||
import org.apache.hertzbeat.common.entity.dto.Message;
|
||||
@@ -69,11 +70,10 @@ public class AlertConvergeController {
|
||||
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));
|
||||
}
|
||||
|
||||
return Objects.isNull(alertConverge)
|
||||
? ResponseEntity.ok(Message.fail(MONITOR_NOT_EXIST_CODE, "AlertConverge not exist."))
|
||||
: ResponseEntity.ok(Message.success(alertConverge));
|
||||
}
|
||||
|
||||
}
|
||||
+1
-32
@@ -21,9 +21,6 @@ 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;
|
||||
@@ -31,11 +28,7 @@ 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;
|
||||
@@ -63,31 +56,7 @@ public class AlertConvergesController {
|
||||
@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);
|
||||
Page<AlertConverge> alertConvergePage = alertConvergeService.getAlertConverges(ids, search, sort, order, pageIndex, pageSize);
|
||||
return ResponseEntity.ok(Message.success(alertConvergePage));
|
||||
}
|
||||
|
||||
+5
-5
@@ -24,6 +24,7 @@ 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.Objects;
|
||||
import java.util.stream.Collectors;
|
||||
import org.apache.hertzbeat.alert.service.AlertDefineService;
|
||||
import org.apache.hertzbeat.common.entity.alerter.AlertDefine;
|
||||
@@ -76,11 +77,10 @@ public class AlertDefineController {
|
||||
@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));
|
||||
}
|
||||
|
||||
return Objects.isNull(alertDefine)
|
||||
? ResponseEntity.ok(Message.fail(MONITOR_NOT_EXIST_CODE, "AlertDefine not exist."))
|
||||
: ResponseEntity.ok(Message.success(alertDefine));
|
||||
}
|
||||
|
||||
@DeleteMapping(path = "/{id}")
|
||||
+1
-52
@@ -21,10 +21,7 @@ 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;
|
||||
@@ -32,11 +29,7 @@ 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;
|
||||
@@ -67,51 +60,7 @@ public class AlertDefinesController {
|
||||
@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);
|
||||
Page<AlertDefine> alertDefinePage = alertDefineService.getAlertDefines(ids, search, priority, sort, order, pageIndex, pageSize);
|
||||
return ResponseEntity.ok(Message.success(alertDefinePage));
|
||||
}
|
||||
|
||||
+1
-40
@@ -20,16 +20,10 @@ 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;
|
||||
@@ -54,40 +48,7 @@ public class AlertReportController {
|
||||
@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));
|
||||
alertService.addNewAlertReportFromCloud(cloudServiceName, alertReport);
|
||||
return ResponseEntity.ok(Message.success("Add report success"));
|
||||
}
|
||||
|
||||
+5
-5
@@ -23,6 +23,7 @@ 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.Objects;
|
||||
import org.apache.hertzbeat.alert.service.AlertSilenceService;
|
||||
import org.apache.hertzbeat.common.entity.alerter.AlertSilence;
|
||||
import org.apache.hertzbeat.common.entity.dto.Message;
|
||||
@@ -69,11 +70,10 @@ public class AlertSilenceController {
|
||||
public ResponseEntity<Message<AlertSilence>> getAlertSilence(
|
||||
@Parameter(description = "Alarm Silence ID", example = "6565463543") @PathVariable("id") long id) {
|
||||
AlertSilence alertSilence = alertSilenceService.getAlertSilence(id);
|
||||
if (alertSilence == null) {
|
||||
return ResponseEntity.ok(Message.fail(MONITOR_NOT_EXIST_CODE, "AlertSilence not exist."));
|
||||
} else {
|
||||
return ResponseEntity.ok(Message.success(alertSilence));
|
||||
}
|
||||
|
||||
return Objects.isNull(alertSilence)
|
||||
? ResponseEntity.ok(Message.fail(MONITOR_NOT_EXIST_CODE, "AlertSilence not exist."))
|
||||
: ResponseEntity.ok(Message.success(alertSilence));
|
||||
}
|
||||
|
||||
}
|
||||
+2
-34
@@ -21,9 +21,6 @@ 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;
|
||||
@@ -31,11 +28,7 @@ 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;
|
||||
@@ -63,33 +56,8 @@ public class AlertSilencesController {
|
||||
@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);
|
||||
Page<AlertSilence> alertSilencePage = alertSilenceService.getAlertSilences(ids, search, sort, order, pageIndex, pageSize);
|
||||
return ResponseEntity.ok(Message.success(alertSilencePage));
|
||||
}
|
||||
|
||||
@DeleteMapping
|
||||
+2
-41
@@ -21,9 +21,6 @@ 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;
|
||||
@@ -32,9 +29,6 @@ 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;
|
||||
@@ -67,41 +61,8 @@ public class AlertsController {
|
||||
@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);
|
||||
Page<Alert> alertPage = alertService.getAlerts(ids, monitorId, priority, status, content, sort, order, pageIndex, pageSize);
|
||||
return ResponseEntity.ok(Message.success(alertPage));
|
||||
}
|
||||
|
||||
@DeleteMapping
|
||||
@@ -0,0 +1,59 @@
|
||||
/*
|
||||
* 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 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 java.util.List;
|
||||
import lombok.Data;
|
||||
import org.apache.hertzbeat.common.entity.manager.TagItem;
|
||||
|
||||
/**
|
||||
* Data transfer object for alert configuration
|
||||
*/
|
||||
|
||||
@Data
|
||||
@JsonInclude(JsonInclude.Include.NON_NULL)
|
||||
@JsonIgnoreProperties(ignoreUnknown = true)
|
||||
@ExcelTarget(value = "AlertDefineDTO")
|
||||
public 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;
|
||||
}
|
||||
+38
@@ -0,0 +1,38 @@
|
||||
/*
|
||||
* 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 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 lombok.Data;
|
||||
|
||||
/**
|
||||
* Export data transfer objects for alert configurations
|
||||
*/
|
||||
|
||||
@Data
|
||||
@JsonInclude(JsonInclude.Include.NON_NULL)
|
||||
@JsonIgnoreProperties(ignoreUnknown = true)
|
||||
@ExcelTarget(value = "ExportAlertDefineDTO")
|
||||
public class ExportAlertDefineDTO {
|
||||
|
||||
@Excel(name = "AlertDefine")
|
||||
private AlertDefineDTO alertDefine;
|
||||
}
|
||||
+1
-3
@@ -174,7 +174,7 @@ public class TenCloudAlertReport extends CloudAlertReportAbstract implements Ser
|
||||
@Override
|
||||
public String getContent() {
|
||||
StringBuilder contentBuilder = new StringBuilder();
|
||||
// 判断类型
|
||||
// Check Type.
|
||||
if (EVENT.equals(getAlarmType())) {
|
||||
contentBuilder
|
||||
.append("[")
|
||||
@@ -225,5 +225,3 @@ public class TenCloudAlertReport extends CloudAlertReportAbstract implements Ser
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
+24
-16
@@ -55,25 +55,27 @@ public class AlarmConvergeReduce {
|
||||
@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) {
|
||||
if ((currentAlert.getTags() != null && currentAlert.getTags().containsKey(CommonConstants.IGNORE))
|
||||
|| 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]));
|
||||
boolean isHasIgnore = false;
|
||||
Map<String, String> tags = currentAlert.getTags();
|
||||
if (Objects.requireNonNull(tags).containsKey(CommonConstants.IGNORE)) {
|
||||
isHasIgnore = true;
|
||||
tags.remove(CommonConstants.IGNORE);
|
||||
}
|
||||
int alertHash = generateAlertHash(CommonConstants.ALERT_PRIORITY_CODE_CRITICAL, tags);
|
||||
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]));
|
||||
alertHash = generateAlertHash(CommonConstants.ALERT_PRIORITY_CODE_EMERGENCY, tags);
|
||||
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]));
|
||||
alertHash = generateAlertHash(CommonConstants.ALERT_PRIORITY_CODE_WARNING, tags);
|
||||
converageAlertMap.remove(alertHash);
|
||||
if (isHasIgnore) {
|
||||
tags.put(CommonConstants.IGNORE, CommonConstants.IGNORE);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
CommonCacheService<String, Object> convergeCache = CacheFactory.getAlertConvergeCache();
|
||||
List<AlertConverge> alertConvergeList = (List<AlertConverge>) convergeCache.get(CommonConstants.CACHE_ALERT_CONVERGE);
|
||||
if (alertConvergeList == null) {
|
||||
@@ -124,9 +126,7 @@ public class AlarmConvergeReduce {
|
||||
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]));
|
||||
int alertHash = generateAlertHash(currentAlert.getPriority(), currentAlert.getTags());
|
||||
Alert preAlert = converageAlertMap.get(alertHash);
|
||||
if (preAlert == null) {
|
||||
currentAlert.setTimes(1);
|
||||
@@ -157,4 +157,12 @@ public class AlarmConvergeReduce {
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private int generateAlertHash(byte priority, Map<String, String> tags) {
|
||||
List<String> keyList = tags.keySet().stream().filter(Objects::nonNull).sorted().toList();
|
||||
List<String> valueList = tags.values().stream().filter(Objects::nonNull).sorted().toList();
|
||||
return Objects.hash(priority)
|
||||
+ Arrays.hashCode(keyList.toArray(new String[0]))
|
||||
+ Arrays.hashCode(valueList.toArray(new String[0]));
|
||||
}
|
||||
}
|
||||
+25
-20
@@ -18,7 +18,6 @@
|
||||
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;
|
||||
@@ -84,32 +83,16 @@ public class AlarmSilenceReduce {
|
||||
}
|
||||
}
|
||||
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;
|
||||
}
|
||||
return checkAndSave(LocalDateTime.now(), alertSilence);
|
||||
} else if (alertSilence.getType() == 1) {
|
||||
// cyc time
|
||||
int currentDayOfWeek = nowDate.toLocalDate().getDayOfWeek().getValue();
|
||||
int currentDayOfWeek = LocalDateTime.now().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 checkAndSave(LocalDateTime.now(), alertSilence);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -117,4 +100,26 @@ public class AlarmSilenceReduce {
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check AlertSilence start and end match, to save alertSilence obj.
|
||||
* @param times LocalDateTime.
|
||||
* @param alertSilence {@link AlertSilence}
|
||||
* @return boolean
|
||||
*/
|
||||
private boolean checkAndSave(LocalDateTime times, AlertSilence alertSilence) {
|
||||
|
||||
boolean startMatch = alertSilence.getPeriodStart() == null || times.isAfter(alertSilence.getPeriodStart().toLocalDateTime());
|
||||
boolean endMatch = alertSilence.getPeriodEnd() == null || times.isBefore(alertSilence.getPeriodEnd().toLocalDateTime());
|
||||
|
||||
if (startMatch && endMatch) {
|
||||
|
||||
int time = Optional.ofNullable(alertSilence.getTimes()).orElse(0);
|
||||
alertSilence.setTimes(time + 1);
|
||||
alertSilenceDao.save(alertSilence);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
+8
-5
@@ -17,11 +17,10 @@
|
||||
|
||||
package org.apache.hertzbeat.alert.service;
|
||||
|
||||
import java.util.List;
|
||||
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
|
||||
@@ -67,9 +66,13 @@ public interface AlertConvergeService {
|
||||
|
||||
/**
|
||||
* Dynamic conditional query
|
||||
* @param specification Query conditions
|
||||
* @param pageRequest Paging parameters
|
||||
* @param convergeIds Alarm Converge ID List
|
||||
* @param search Search Name
|
||||
* @param sort Sort field
|
||||
* @param order Sort mode: asc: ascending, desc: descending
|
||||
* @param pageIndex List current page
|
||||
* @param pageSize Number of list pages
|
||||
* @return The query results
|
||||
*/
|
||||
Page<AlertConverge> getAlertConverges(Specification<AlertConverge> specification, PageRequest pageRequest);
|
||||
Page<AlertConverge> getAlertConverges(List<Long> convergeIds, String search, String sort, String order, int pageIndex, int pageSize);
|
||||
}
|
||||
+8
-3
@@ -113,11 +113,16 @@ public interface AlertDefineService {
|
||||
|
||||
/**
|
||||
* Dynamic conditional query
|
||||
* @param specification Query conditions
|
||||
* @param pageRequest Paging parameters
|
||||
* @param defineIds Alarm Definition ID List
|
||||
* @param search Search-Target Expr Template
|
||||
* @param priority Alarm Definition Severity
|
||||
* @param sort Sort field
|
||||
* @param order Sort mode: asc: ascending, desc: descending
|
||||
* @param pageIndex List current page
|
||||
* @param pageSize Number of list pages
|
||||
* @return The query results
|
||||
*/
|
||||
Page<AlertDefine> getAlertDefines(Specification<AlertDefine> specification, PageRequest pageRequest);
|
||||
Page<AlertDefine> getAlertDefines(List<Long> defineIds, String search, Byte priority, String sort, String order, int pageIndex, int pageSize);
|
||||
|
||||
/**
|
||||
* Query the associated monitoring list information based on the alarm definition ID
|
||||
+17
-4
@@ -23,7 +23,6 @@ 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;
|
||||
|
||||
/**
|
||||
@@ -40,11 +39,18 @@ public interface AlertService {
|
||||
|
||||
/**
|
||||
* Dynamic conditional query
|
||||
* @param specification Query conditions
|
||||
* @param pageRequest pagination parameters
|
||||
* @param alarmIds Alarm ID List
|
||||
* @param monitorId Monitor ID
|
||||
* @param priority Alarm level
|
||||
* @param status Alarm Status
|
||||
* @param content Alarm content fuzzy query
|
||||
* @param sort Sort field
|
||||
* @param order Sort Type
|
||||
* @param pageIndex List current page
|
||||
* @param pageSize Number of list pagination
|
||||
* @return search result
|
||||
*/
|
||||
Page<Alert> getAlerts(Specification<Alert> specification, PageRequest pageRequest);
|
||||
Page<Alert> getAlerts(List<Long> alarmIds, Long monitorId, Byte priority, Byte status, String content, String sort, String order, int pageIndex, int pageSize);
|
||||
|
||||
/**
|
||||
* Delete alarms in batches according to the alarm ID list
|
||||
@@ -76,6 +82,13 @@ public interface AlertService {
|
||||
*/
|
||||
void addNewAlertReport(AlertReport alertReport);
|
||||
|
||||
/**
|
||||
* Save external alarms of cloud services
|
||||
* @param cloudServiceName cloud service name,Such as tencloud
|
||||
* @param alertReport alert report json string
|
||||
*/
|
||||
void addNewAlertReportFromCloud(String cloudServiceName, String alertReport);
|
||||
|
||||
/**
|
||||
* Dynamic conditional query
|
||||
* @param specification Query conditions
|
||||
+8
-5
@@ -17,11 +17,10 @@
|
||||
|
||||
package org.apache.hertzbeat.alert.service;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import org.apache.hertzbeat.common.entity.alerter.AlertSilence;
|
||||
import org.springframework.data.domain.Page;
|
||||
import org.springframework.data.domain.PageRequest;
|
||||
import org.springframework.data.jpa.domain.Specification;
|
||||
|
||||
/**
|
||||
* management interface service for alert silence
|
||||
@@ -67,9 +66,13 @@ public interface AlertSilenceService {
|
||||
|
||||
/**
|
||||
* Dynamic conditional query
|
||||
* @param specification Query conditions
|
||||
* @param pageRequest Paging parameters
|
||||
* @param silenceIds Alarm Silence ID
|
||||
* @param search Search Name
|
||||
* @param sort Sort field
|
||||
* @param order Sort mode: asc: ascending, desc: descending
|
||||
* @param pageIndex List current page
|
||||
* @param pageSize Number of list pages
|
||||
* @return The query results
|
||||
*/
|
||||
Page<AlertSilence> getAlertSilences(Specification<AlertSilence> specification, PageRequest pageRequest);
|
||||
Page<AlertSilence> getAlertSilences(List<Long> silenceIds, String search, String sort, String order, int pageIndex, int pageSize);
|
||||
}
|
||||
+30
-1
@@ -17,6 +17,10 @@
|
||||
|
||||
package org.apache.hertzbeat.alert.service.impl;
|
||||
|
||||
import jakarta.persistence.criteria.CriteriaBuilder;
|
||||
import jakarta.persistence.criteria.Predicate;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.hertzbeat.alert.dao.AlertConvergeDao;
|
||||
@@ -28,9 +32,11 @@ 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.domain.Sort;
|
||||
import org.springframework.data.jpa.domain.Specification;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
/**
|
||||
* implement for alert converge service
|
||||
@@ -72,7 +78,30 @@ public class AlertConvergeServiceImpl implements AlertConvergeService {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Page<AlertConverge> getAlertConverges(Specification<AlertConverge> specification, PageRequest pageRequest) {
|
||||
public Page<AlertConverge> getAlertConverges(List<Long> convergeIds, String search, String sort, String order, int pageIndex, int pageSize) {
|
||||
Specification<AlertConverge> specification = (root, query, criteriaBuilder) -> {
|
||||
List<Predicate> andList = new ArrayList<>();
|
||||
if (convergeIds != null && !convergeIds.isEmpty()) {
|
||||
CriteriaBuilder.In<Long> inPredicate = criteriaBuilder.in(root.get("id"));
|
||||
for (long id : convergeIds) {
|
||||
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);
|
||||
return alertConvergeDao.findAll(specification, pageRequest);
|
||||
}
|
||||
|
||||
+4
-52
@@ -17,22 +17,17 @@
|
||||
|
||||
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.dto.AlertDefineDTO;
|
||||
import org.apache.hertzbeat.alert.dto.ExportAlertDefineDTO;
|
||||
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;
|
||||
@@ -51,7 +46,7 @@ public abstract class AlertDefineAbstractImExportServiceImpl implements AlertDef
|
||||
var formList = parseImport(is)
|
||||
.stream()
|
||||
.map(this::convert)
|
||||
.collect(Collectors.toUnmodifiableList());
|
||||
.toList();
|
||||
if (!CollectionUtils.isEmpty(formList)) {
|
||||
formList.forEach(alertDefine -> {
|
||||
alertDefineService.validate(alertDefine, false);
|
||||
@@ -65,7 +60,7 @@ public abstract class AlertDefineAbstractImExportServiceImpl implements AlertDef
|
||||
var monitorList = configList.stream()
|
||||
.map(it -> alertDefineService.getAlertDefine(it))
|
||||
.map(this::convert)
|
||||
.collect(Collectors.toUnmodifiableList());
|
||||
.toList();
|
||||
writeOs(monitorList, os);
|
||||
}
|
||||
|
||||
@@ -105,47 +100,4 @@ public abstract class AlertDefineAbstractImExportServiceImpl implements AlertDef
|
||||
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;
|
||||
}
|
||||
}
|
||||
+12
-39
@@ -17,6 +17,8 @@
|
||||
|
||||
package org.apache.hertzbeat.alert.service.impl;
|
||||
|
||||
import static org.apache.hertzbeat.common.constants.ExportFileConstants.ExcelFile.FILE_SUFFIX;
|
||||
import static org.apache.hertzbeat.common.constants.ExportFileConstants.ExcelFile.TYPE;
|
||||
import com.fasterxml.jackson.core.type.TypeReference;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
@@ -25,13 +27,15 @@ import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.hertzbeat.alert.dto.AlertDefineDTO;
|
||||
import org.apache.hertzbeat.alert.dto.ExportAlertDefineDTO;
|
||||
import org.apache.hertzbeat.common.entity.manager.TagItem;
|
||||
import org.apache.hertzbeat.common.util.JsonUtil;
|
||||
import org.apache.hertzbeat.common.util.export.ExcelExportUtils;
|
||||
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
|
||||
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;
|
||||
@@ -45,8 +49,6 @@ import org.springframework.util.StringUtils;
|
||||
@Slf4j
|
||||
@Service
|
||||
public class AlertDefineExcelImExportServiceImpl extends AlertDefineAbstractImExportServiceImpl {
|
||||
public static final String TYPE = "EXCEL";
|
||||
public static final String FILE_SUFFIX = ".xlsx";
|
||||
|
||||
/**
|
||||
* Export file type
|
||||
@@ -73,7 +75,7 @@ public class AlertDefineExcelImExportServiceImpl extends AlertDefineAbstractImEx
|
||||
* @return form list
|
||||
*/
|
||||
@Override
|
||||
List<ExportAlertDefineDTO> parseImport(InputStream is) {
|
||||
public List<ExportAlertDefineDTO> parseImport(InputStream is) {
|
||||
try (Workbook workbook = WorkbookFactory.create(is)) {
|
||||
Sheet sheet = workbook.getSheetAt(0);
|
||||
List<ExportAlertDefineDTO> alertDefines = new ArrayList<>();
|
||||
@@ -95,17 +97,6 @@ public class AlertDefineExcelImExportServiceImpl extends AlertDefineAbstractImEx
|
||||
}
|
||||
}
|
||||
|
||||
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)) {
|
||||
@@ -184,32 +175,14 @@ public class AlertDefineExcelImExportServiceImpl extends AlertDefineAbstractImEx
|
||||
* @param os output stream
|
||||
*/
|
||||
@Override
|
||||
void writeOs(List<ExportAlertDefineDTO> exportAlertDefineList, OutputStream os) {
|
||||
public void writeOs(List<ExportAlertDefineDTO> exportAlertDefineList, OutputStream os) {
|
||||
try {
|
||||
Workbook workbook = WorkbookFactory.create(true);
|
||||
|
||||
Workbook workbook = new HSSFWorkbook();
|
||||
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);
|
||||
Sheet sheet = ExcelExportUtils.setSheet(sheetName, workbook, AlertDefineDTO.class);
|
||||
// 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);
|
||||
}
|
||||
CellStyle cellStyle = ExcelExportUtils.setCellStyle(workbook);
|
||||
|
||||
// Traverse the threshold rule list, each threshold rule object corresponds to a row of data
|
||||
int rowIndex = 1;
|
||||
+5
-4
@@ -17,6 +17,8 @@
|
||||
|
||||
package org.apache.hertzbeat.alert.service.impl;
|
||||
|
||||
import static org.apache.hertzbeat.common.constants.ExportFileConstants.JsonFile.FILE_SUFFIX;
|
||||
import static org.apache.hertzbeat.common.constants.ExportFileConstants.JsonFile.TYPE;
|
||||
import com.fasterxml.jackson.core.type.TypeReference;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import java.io.IOException;
|
||||
@@ -25,6 +27,7 @@ import java.io.OutputStream;
|
||||
import java.util.List;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.hertzbeat.alert.dto.ExportAlertDefineDTO;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
/**
|
||||
@@ -34,8 +37,6 @@ import org.springframework.stereotype.Service;
|
||||
@RequiredArgsConstructor
|
||||
@Service
|
||||
public class AlertDefineJsonImExportServiceImpl extends AlertDefineAbstractImExportServiceImpl {
|
||||
public static final String TYPE = "JSON";
|
||||
public static final String FILE_SUFFIX = ".json";
|
||||
|
||||
private final ObjectMapper objectMapper;
|
||||
|
||||
@@ -50,7 +51,7 @@ public class AlertDefineJsonImExportServiceImpl extends AlertDefineAbstractImExp
|
||||
}
|
||||
|
||||
@Override
|
||||
List<ExportAlertDefineDTO> parseImport(InputStream is) {
|
||||
public List<ExportAlertDefineDTO> parseImport(InputStream is) {
|
||||
try {
|
||||
return objectMapper.readValue(is, new TypeReference<>() {
|
||||
});
|
||||
@@ -61,7 +62,7 @@ public class AlertDefineJsonImExportServiceImpl extends AlertDefineAbstractImExp
|
||||
}
|
||||
|
||||
@Override
|
||||
void writeOs(List<ExportAlertDefineDTO> exportAlertDefineList, OutputStream os) {
|
||||
public void writeOs(List<ExportAlertDefineDTO> exportAlertDefineList, OutputStream os) {
|
||||
try {
|
||||
objectMapper.writeValue(os, exportAlertDefineList);
|
||||
} catch (IOException ex) {
|
||||
+111
-37
@@ -17,33 +17,50 @@
|
||||
|
||||
package org.apache.hertzbeat.alert.service.impl;
|
||||
|
||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||
import com.fasterxml.jackson.core.type.TypeReference;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import jakarta.persistence.criteria.CriteriaBuilder;
|
||||
import jakarta.persistence.criteria.Predicate;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.hertzbeat.alert.dao.AlertDefineBindDao;
|
||||
import org.apache.hertzbeat.alert.dao.AlertDefineDao;
|
||||
import org.apache.hertzbeat.alert.dao.AlertMonitorDao;
|
||||
import org.apache.hertzbeat.alert.service.AlertDefineImExportService;
|
||||
import org.apache.hertzbeat.alert.service.AlertDefineService;
|
||||
import org.apache.hertzbeat.common.constants.ExportFileConstants;
|
||||
import org.apache.hertzbeat.common.constants.SignConstants;
|
||||
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.FileUtil;
|
||||
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.domain.Sort;
|
||||
import org.springframework.data.jpa.domain.Specification;
|
||||
import org.springframework.http.HttpHeaders;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
import org.springframework.util.StringUtils;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
import java.net.URLDecoder;
|
||||
import java.net.URLEncoder;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
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.function.Function;
|
||||
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
|
||||
@@ -59,8 +76,13 @@ public class AlertDefineServiceImpl implements AlertDefineService {
|
||||
@Autowired
|
||||
private AlertDefineBindDao alertDefineBindDao;
|
||||
|
||||
@Autowired
|
||||
private AlertMonitorDao alertMonitorDao;
|
||||
|
||||
private final Map<String, AlertDefineImExportService> alertDefineImExportServiceMap = new HashMap<>();
|
||||
|
||||
private static final String CONTENT_TYPE = MediaType.APPLICATION_OCTET_STREAM_VALUE + SignConstants.SINGLE_MARK + "charset=" + StandardCharsets.UTF_8;
|
||||
|
||||
public AlertDefineServiceImpl(List<AlertDefineImExportService> alertDefineImExportServiceList) {
|
||||
alertDefineImExportServiceList.forEach(it -> alertDefineImExportServiceMap.put(it.type(), it));
|
||||
}
|
||||
@@ -141,13 +163,76 @@ public class AlertDefineServiceImpl implements AlertDefineService {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Page<AlertDefine> getAlertDefines(Specification<AlertDefine> specification, PageRequest pageRequest) {
|
||||
public Page<AlertDefine> getAlertDefines(List<Long> defineIds, String search, Byte priority, String sort, String order, int pageIndex, int pageSize) {
|
||||
// parse translation content list
|
||||
ObjectMapper objectMapper = new ObjectMapper();
|
||||
List<String> searchList = Collections.emptyList();
|
||||
if (StringUtils.hasText(search)) {
|
||||
try {
|
||||
searchList = objectMapper.readValue(URLDecoder.decode(search, StandardCharsets.UTF_8), new TypeReference<>() {});
|
||||
} catch (JsonProcessingException e) {
|
||||
throw new IllegalArgumentException("Failed to parse search parameter", e);
|
||||
}
|
||||
}
|
||||
List<String> finalSearchList = searchList;
|
||||
// build search condition
|
||||
Specification<AlertDefine> specification = (root, query, criteriaBuilder) -> {
|
||||
List<Predicate> andList = new ArrayList<>();
|
||||
if (defineIds != null && !defineIds.isEmpty()) {
|
||||
CriteriaBuilder.In<Long> inPredicate = criteriaBuilder.in(root.get("id"));
|
||||
for (long id : defineIds) {
|
||||
inPredicate.value(id);
|
||||
}
|
||||
andList.add(inPredicate);
|
||||
}
|
||||
if (null != finalSearchList && !finalSearchList.isEmpty()) {
|
||||
List<Predicate> searchPredicates = new ArrayList<>();
|
||||
for (String searchContent : finalSearchList) {
|
||||
searchContent = searchContent.toLowerCase();
|
||||
Predicate predicate = criteriaBuilder.or(
|
||||
criteriaBuilder.like(criteriaBuilder.lower(root.get("app")), "%" + searchContent + "%"),
|
||||
criteriaBuilder.like(criteriaBuilder.lower(root.get("metric")), "%" + searchContent + "%"),
|
||||
criteriaBuilder.like(criteriaBuilder.lower(root.get("field")), "%" + searchContent + "%"),
|
||||
criteriaBuilder.like(criteriaBuilder.lower(root.get("expr")), "%" + searchContent + "%"),
|
||||
criteriaBuilder.like(criteriaBuilder.lower(root.get("template")), "%" + searchContent + "%")
|
||||
);
|
||||
searchPredicates.add(predicate);
|
||||
}
|
||||
// all search keywords are connected with or
|
||||
andList.add(criteriaBuilder.or(searchPredicates.toArray(new Predicate[0])));
|
||||
}
|
||||
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);
|
||||
return alertDefineDao.findAll(specification, pageRequest);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<AlertDefineMonitorBind> getBindAlertDefineMonitors(long alertDefineId) {
|
||||
return alertDefineBindDao.getAlertDefineBindsByAlertDefineIdEquals(alertDefineId);
|
||||
List<AlertDefineMonitorBind> defineMonitorBinds = alertDefineBindDao.getAlertDefineBindsByAlertDefineIdEquals(alertDefineId);
|
||||
if (defineMonitorBinds == null || defineMonitorBinds.isEmpty()) {
|
||||
return defineMonitorBinds;
|
||||
}
|
||||
List<Long> needLoadMonitorIds = defineMonitorBinds.stream()
|
||||
.filter(bind -> bind.getMonitor() == null)
|
||||
.map(AlertDefineMonitorBind::getMonitorId).toList();
|
||||
if (needLoadMonitorIds.isEmpty()) {
|
||||
return defineMonitorBinds;
|
||||
}
|
||||
Map<Long, Monitor> monitorMap = alertMonitorDao.findAllById(needLoadMonitorIds)
|
||||
.stream().collect(Collectors.toMap(Monitor::getId, Function.identity()));
|
||||
for (AlertDefineMonitorBind bind : defineMonitorBinds) {
|
||||
if (bind.getMonitor() == null) {
|
||||
bind.setMonitor(monitorMap.get(bind.getMonitorId()));
|
||||
}
|
||||
}
|
||||
return defineMonitorBinds;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -157,31 +242,20 @@ public class AlertDefineServiceImpl implements AlertDefineService {
|
||||
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_TYPE, CONTENT_TYPE);
|
||||
res.setContentType(CONTENT_TYPE);
|
||||
res.setHeader(HttpHeaders.CONTENT_DISPOSITION, "attachment;filename=" + URLEncoder.encode(fileName, StandardCharsets.UTF_8));
|
||||
res.setHeader("Access-Control-Expose-Headers", "Content-Disposition");
|
||||
res.setHeader(HttpHeaders.ACCESS_CONTROL_EXPOSE_HEADERS, HttpHeaders.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;
|
||||
}
|
||||
|
||||
var type = FileUtil.getFileType(file);
|
||||
var fileName = FileUtil.getFileName(file);
|
||||
if (!alertDefineImExportServiceMap.containsKey(type)) {
|
||||
throw new RuntimeException("file " + fileName + " is not supported.");
|
||||
throw new RuntimeException(ExportFileConstants.FILE + " " + fileName + " is not supported.");
|
||||
}
|
||||
var imExportService = alertDefineImExportServiceMap.get(type);
|
||||
imExportService.importConfig(file.getInputStream());
|
||||
+11
-15
@@ -17,26 +17,25 @@
|
||||
|
||||
package org.apache.hertzbeat.alert.service.impl;
|
||||
|
||||
import static org.apache.hertzbeat.common.constants.ExportFileConstants.YamlFile.FILE_SUFFIX;
|
||||
import static org.apache.hertzbeat.common.constants.ExportFileConstants.YamlFile.TYPE;
|
||||
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.apache.hertzbeat.alert.dto.ExportAlertDefineDTO;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.yaml.snakeyaml.DumperOptions;
|
||||
import org.apache.hertzbeat.common.util.export.YamlExportUtils;
|
||||
import org.yaml.snakeyaml.Yaml;
|
||||
|
||||
/**
|
||||
* Configure the import and export Yaml format
|
||||
* 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;
|
||||
@@ -48,18 +47,15 @@ public class AlertDefineYamlImExportServiceImpl extends AlertDefineAbstractImExp
|
||||
}
|
||||
|
||||
@Override
|
||||
List<ExportAlertDefineDTO> parseImport(InputStream is) {
|
||||
public 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));
|
||||
public void writeOs(List<ExportAlertDefineDTO> exportAlertDefineList, OutputStream os) {
|
||||
|
||||
YamlExportUtils.exportWriteOs(exportAlertDefineList, os);
|
||||
}
|
||||
|
||||
}
|
||||
+78
-4
@@ -17,26 +17,34 @@
|
||||
|
||||
package org.apache.hertzbeat.alert.service.impl;
|
||||
|
||||
import jakarta.persistence.criteria.CriteriaBuilder;
|
||||
import jakarta.persistence.criteria.Predicate;
|
||||
import java.math.BigDecimal;
|
||||
import java.math.RoundingMode;
|
||||
import java.time.Instant;
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.ZoneId;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
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.dto.CloudAlertReportAbstract;
|
||||
import org.apache.hertzbeat.alert.enums.CloudServiceAlarmInformationEnum;
|
||||
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.apache.hertzbeat.common.util.JsonUtil;
|
||||
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.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
@@ -61,7 +69,38 @@ public class AlertServiceImpl implements AlertService {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Page<Alert> getAlerts(Specification<Alert> specification, PageRequest pageRequest) {
|
||||
public Page<Alert> getAlerts(List<Long> alarmIds, Long monitorId, Byte priority, Byte status, String content, String sort, String order, int pageIndex, int pageSize) {
|
||||
Specification<Alert> specification = (root, query, criteriaBuilder) -> {
|
||||
List<Predicate> andList = new ArrayList<>();
|
||||
|
||||
if (alarmIds != null && !alarmIds.isEmpty()) {
|
||||
CriteriaBuilder.In<Long> inPredicate = criteriaBuilder.in(root.get("id"));
|
||||
for (long id : alarmIds) {
|
||||
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);
|
||||
return alertDao.findAll(specification, pageRequest);
|
||||
}
|
||||
|
||||
@@ -121,6 +160,43 @@ public class AlertServiceImpl implements AlertService {
|
||||
alarmCommonReduce.reduceAndSendAlarm(buildAlertData(alertReport));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addNewAlertReportFromCloud(String cloudServiceName, 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(Instant.now().getEpochSecond())
|
||||
.priority(1)
|
||||
.reportType(1)
|
||||
.build();
|
||||
}
|
||||
Optional.ofNullable(alert).ifPresent(this::addNewAlertReport);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Alert> getAlerts(Specification<Alert> specification) {
|
||||
|
||||
@@ -137,9 +213,7 @@ public class AlertServiceImpl implements AlertService {
|
||||
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");
|
||||
});
|
||||
annotations.forEach((k, v) -> finalSb.append(k).append(":").append(v).append("\n"));
|
||||
} else {
|
||||
sb = new StringBuilder(alertReport.getContent());
|
||||
}
|
||||
+30
-1
@@ -17,7 +17,11 @@
|
||||
|
||||
package org.apache.hertzbeat.alert.service.impl;
|
||||
|
||||
import jakarta.persistence.criteria.CriteriaBuilder;
|
||||
import jakarta.persistence.criteria.Predicate;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.hertzbeat.alert.dao.AlertSilenceDao;
|
||||
@@ -29,9 +33,11 @@ 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.domain.Sort;
|
||||
import org.springframework.data.jpa.domain.Specification;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
/**
|
||||
* management interface service implement for alert silence
|
||||
@@ -77,7 +83,30 @@ public class AlertSilenceServiceImpl implements AlertSilenceService {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Page<AlertSilence> getAlertSilences(Specification<AlertSilence> specification, PageRequest pageRequest) {
|
||||
public Page<AlertSilence> getAlertSilences(List<Long> silenceIds, String search, String sort, String order, int pageIndex, int pageSize) {
|
||||
Specification<AlertSilence> specification = (root, query, criteriaBuilder) -> {
|
||||
List<Predicate> andList = new ArrayList<>();
|
||||
if (silenceIds != null && !silenceIds.isEmpty()) {
|
||||
CriteriaBuilder.In<Long> inPredicate = criteriaBuilder.in(root.get("id"));
|
||||
for (long id : silenceIds) {
|
||||
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);
|
||||
return alertSilenceDao.findAll(specification, pageRequest);
|
||||
}
|
||||
|
||||
+1
-2
@@ -13,5 +13,4 @@
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
|
||||
org.apache.hertzbeat.push.config.PushAutoConfiguration
|
||||
org.apache.hertzbeat.alert.config.AlerterAutoConfiguration
|
||||
+124
@@ -0,0 +1,124 @@
|
||||
/*
|
||||
* 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.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.ArgumentMatchers.eq;
|
||||
import static org.mockito.Mockito.doNothing;
|
||||
import static org.mockito.Mockito.when;
|
||||
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
|
||||
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
|
||||
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.put;
|
||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
|
||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
|
||||
import static org.springframework.test.web.servlet.setup.MockMvcBuilders.standaloneSetup;
|
||||
import org.apache.hertzbeat.alert.service.AlertConvergeService;
|
||||
import org.apache.hertzbeat.common.constants.CommonConstants;
|
||||
import org.apache.hertzbeat.common.entity.alerter.AlertConverge;
|
||||
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;
|
||||
|
||||
/**
|
||||
* test case for {@link AlertConvergeController}
|
||||
*/
|
||||
|
||||
@ExtendWith(MockitoExtension.class)
|
||||
public class AlertConvergeControllerTest {
|
||||
|
||||
private MockMvc mockMvc;
|
||||
|
||||
@Mock
|
||||
private AlertConvergeService alertConvergeService;
|
||||
|
||||
private AlertConverge alertConverge;
|
||||
|
||||
@InjectMocks
|
||||
private AlertConvergeController alertConvergeController;
|
||||
|
||||
@BeforeEach
|
||||
void setUp() {
|
||||
|
||||
this.mockMvc = standaloneSetup(alertConvergeController).build();
|
||||
|
||||
alertConverge = AlertConverge.builder()
|
||||
.name("test")
|
||||
.creator("admin")
|
||||
.modifier("admin")
|
||||
.id(1L)
|
||||
.build();
|
||||
}
|
||||
|
||||
@Test
|
||||
void testAddNewAlertConverge() throws Exception {
|
||||
|
||||
doNothing().when(alertConvergeService).validate(any(AlertConverge.class), eq(false));
|
||||
doNothing().when(alertConvergeService).addAlertConverge(any(AlertConverge.class));
|
||||
|
||||
mockMvc.perform(post("/api/alert/converge")
|
||||
.contentType(MediaType.APPLICATION_JSON)
|
||||
.content(JsonUtil.toJson(alertConverge))
|
||||
).andExpect(status().isOk())
|
||||
.andExpect(jsonPath("$.code").value((int) CommonConstants.SUCCESS_CODE))
|
||||
.andExpect(jsonPath("$.msg").value("Add success"));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testModifyAlertConverge() throws Exception {
|
||||
|
||||
doNothing().when(alertConvergeService).validate(any(AlertConverge.class), eq(true));
|
||||
doNothing().when(alertConvergeService).modifyAlertConverge(any(AlertConverge.class));
|
||||
|
||||
mockMvc.perform(put("/api/alert/converge")
|
||||
.contentType(MediaType.APPLICATION_JSON)
|
||||
.content(JsonUtil.toJson(alertConverge))
|
||||
).andExpect(status().isOk())
|
||||
.andExpect(jsonPath("$.code").value((int) CommonConstants.SUCCESS_CODE))
|
||||
.andExpect(jsonPath("$.msg").value("Modify success"));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testGetAlertConvergeExists() throws Exception {
|
||||
|
||||
when(alertConvergeService.getAlertConverge(1L)).thenReturn(alertConverge);
|
||||
|
||||
mockMvc.perform(get("/api/alert/converge/{id}", 1L)
|
||||
.accept(MediaType.APPLICATION_JSON))
|
||||
.andExpect(status().isOk())
|
||||
.andExpect(jsonPath("$.data.id").value(alertConverge.getId()));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testGetAlertConvergeNotExists() throws Exception {
|
||||
|
||||
when(alertConvergeService.getAlertConverge(1L)).thenReturn(null);
|
||||
|
||||
mockMvc.perform(get("/api/alert/converge/{id}", 1L)
|
||||
.accept(MediaType.APPLICATION_JSON))
|
||||
.andExpect(status().isOk())
|
||||
.andExpect(jsonPath("$.code").value((int) CommonConstants.MONITOR_NOT_EXIST_CODE))
|
||||
.andExpect(jsonPath("$.msg").value("AlertConverge not exist."));
|
||||
}
|
||||
|
||||
}
|
||||
+120
@@ -0,0 +1,120 @@
|
||||
/*
|
||||
* 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.mockito.ArgumentMatchers.eq;
|
||||
import static org.mockito.Mockito.doNothing;
|
||||
import static org.mockito.Mockito.when;
|
||||
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.delete;
|
||||
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
|
||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
|
||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
|
||||
import static org.springframework.test.web.servlet.setup.MockMvcBuilders.standaloneSetup;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import org.apache.hertzbeat.alert.service.AlertConvergeService;
|
||||
import org.apache.hertzbeat.common.constants.CommonConstants;
|
||||
import org.apache.hertzbeat.common.entity.alerter.AlertConverge;
|
||||
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.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;
|
||||
|
||||
|
||||
/**
|
||||
* test case for {@link AlertConvergesController}
|
||||
*/
|
||||
|
||||
@ExtendWith(MockitoExtension.class)
|
||||
class AlertConvergesControllerTest {
|
||||
|
||||
private MockMvc mockMvc;
|
||||
|
||||
@Mock
|
||||
private AlertConvergeService alertConvergeService;
|
||||
|
||||
@InjectMocks
|
||||
private AlertConvergesController alertConvergesController;
|
||||
|
||||
private List<AlertConverge> alertConvergeList;
|
||||
|
||||
@BeforeEach
|
||||
void setUp() {
|
||||
|
||||
this.mockMvc = standaloneSetup(alertConvergesController).build();
|
||||
|
||||
AlertConverge alertConverge1 = AlertConverge.builder()
|
||||
.name("Converge1")
|
||||
.id(1L)
|
||||
.build();
|
||||
|
||||
AlertConverge alertConverge2 = AlertConverge.builder()
|
||||
.name("Converge2")
|
||||
.id(2L)
|
||||
.build();
|
||||
|
||||
alertConvergeList = Arrays.asList(alertConverge1, alertConverge2);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testGetAlertConverges() throws Exception {
|
||||
|
||||
Page<AlertConverge> alertConvergePage = new PageImpl<>(
|
||||
alertConvergeList,
|
||||
PageRequest.of(0, 8, Sort.by("id").descending()),
|
||||
alertConvergeList.size()
|
||||
);
|
||||
|
||||
when(alertConvergeService.getAlertConverges(null, null, "id", "desc", 0, 8)).thenReturn(alertConvergePage);
|
||||
|
||||
mockMvc.perform(get("/api/alert/converges")
|
||||
.param("pageIndex", "0")
|
||||
.param("pageSize", "8")
|
||||
.param("sort", "id")
|
||||
.param("order", "desc")
|
||||
.accept(MediaType.APPLICATION_JSON))
|
||||
.andExpect(status().isOk())
|
||||
.andExpect(jsonPath("$.data.content[0].id").value(1))
|
||||
.andExpect(jsonPath("$.data.content[0].name").value("Converge1"))
|
||||
.andExpect(jsonPath("$.data.content[1].id").value(2))
|
||||
.andExpect(jsonPath("$.data.content[1].name").value("Converge2"));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testDeleteAlertDefines() throws Exception {
|
||||
|
||||
doNothing().when(alertConvergeService).deleteAlertConverges(eq(new HashSet<>(Arrays.asList(1L, 2L))));
|
||||
|
||||
mockMvc.perform(delete("/api/alert/converges")
|
||||
.param("ids", "1,2")
|
||||
.accept(MediaType.APPLICATION_JSON))
|
||||
.andExpect(status().isOk())
|
||||
.andExpect(jsonPath("$.code").value((int) CommonConstants.SUCCESS_CODE));
|
||||
}
|
||||
}
|
||||
|
||||
+10
-10
@@ -97,8 +97,8 @@ class AlertDefineControllerTest {
|
||||
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)))
|
||||
.contentType(MediaType.APPLICATION_JSON)
|
||||
.content(JsonUtil.toJson(this.alertDefine)))
|
||||
.andExpect(status().isOk())
|
||||
.andExpect(jsonPath("$.code").value((int) CommonConstants.SUCCESS_CODE))
|
||||
.andReturn();
|
||||
@@ -107,8 +107,8 @@ class AlertDefineControllerTest {
|
||||
@Test
|
||||
void modifyAlertDefine() throws Exception {
|
||||
mockMvc.perform(MockMvcRequestBuilders.put("/api/alert/define")
|
||||
.contentType(MediaType.APPLICATION_JSON)
|
||||
.content(JsonUtil.toJson(this.alertDefine)))
|
||||
.contentType(MediaType.APPLICATION_JSON)
|
||||
.content(JsonUtil.toJson(this.alertDefine)))
|
||||
.andExpect(status().isOk())
|
||||
.andExpect(jsonPath("$.code").value((int) CommonConstants.SUCCESS_CODE))
|
||||
.andReturn();
|
||||
@@ -121,7 +121,7 @@ class AlertDefineControllerTest {
|
||||
.thenReturn(this.alertDefine);
|
||||
|
||||
mockMvc.perform(MockMvcRequestBuilders.get("/api/alert/define/" + this.alertDefine.getId())
|
||||
.contentType(MediaType.APPLICATION_JSON))
|
||||
.contentType(MediaType.APPLICATION_JSON))
|
||||
.andExpect(status().isOk())
|
||||
.andExpect(jsonPath("$.code").value((int) CommonConstants.SUCCESS_CODE))
|
||||
.andExpect(jsonPath("$.data.id").value(alertDefine.getId()))
|
||||
@@ -138,8 +138,8 @@ class AlertDefineControllerTest {
|
||||
@Test
|
||||
void deleteAlertDefine() throws Exception {
|
||||
mockMvc.perform(MockMvcRequestBuilders.delete("/api/alert/define/" + this.alertDefine.getId())
|
||||
.contentType(MediaType.APPLICATION_JSON)
|
||||
.content(JsonUtil.toJson(this.alertDefine)))
|
||||
.contentType(MediaType.APPLICATION_JSON)
|
||||
.content(JsonUtil.toJson(this.alertDefine)))
|
||||
.andExpect(status().isOk())
|
||||
.andExpect(jsonPath("$.code").value((int) CommonConstants.SUCCESS_CODE))
|
||||
.andReturn();
|
||||
@@ -148,8 +148,8 @@ class AlertDefineControllerTest {
|
||||
@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)))
|
||||
.contentType(MediaType.APPLICATION_JSON)
|
||||
.content(JsonUtil.toJson(this.alertDefineMonitorBinds)))
|
||||
.andExpect(status().isOk())
|
||||
.andExpect(jsonPath("$.code").value((int) CommonConstants.SUCCESS_CODE))
|
||||
.andReturn();
|
||||
@@ -161,7 +161,7 @@ class AlertDefineControllerTest {
|
||||
.thenReturn(this.alertDefineMonitorBinds);
|
||||
|
||||
mockMvc.perform(MockMvcRequestBuilders.get("/api/alert/define/" + this.alertDefine.getId() + "/monitors")
|
||||
.contentType(MediaType.APPLICATION_JSON))
|
||||
.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()))
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user