mirror of
https://github.com/dromara/hertzbeat.git
synced 2026-09-17 18:19:02 +00:00
Compare commits
1
Commits
fix-memory
..
v1.6.1
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e27845273b |
@@ -2081,250 +2081,6 @@
|
||||
"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"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "lctking",
|
||||
"name": "nullwli",
|
||||
"avatar_url": "https://avatars.githubusercontent.com/u/168249998?v=4",
|
||||
"profile": "https://github.com/lctking",
|
||||
"contributions": [
|
||||
"code"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "simonsigre",
|
||||
"name": "Simon Sigré",
|
||||
"avatar_url": "https://avatars.githubusercontent.com/u/14932913?v=4",
|
||||
"profile": "https://simonsigre.com/",
|
||||
"contributions": [
|
||||
"doc"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "ponfee",
|
||||
"name": "ponfee",
|
||||
"avatar_url": "https://avatars.githubusercontent.com/u/46117331?v=4",
|
||||
"profile": "http://www.ponfee.cn/",
|
||||
"contributions": [
|
||||
"code"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "Vedant7789",
|
||||
"name": "Vedant7789",
|
||||
"avatar_url": "https://avatars.githubusercontent.com/u/147625492?v=4",
|
||||
"profile": "https://github.com/Vedant7789",
|
||||
"contributions": [
|
||||
"code"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "Craaaaazy77",
|
||||
"name": "Craaaaazy77",
|
||||
"avatar_url": "https://avatars.githubusercontent.com/u/23025522?v=4",
|
||||
"profile": "https://github.com/Craaaaazy77",
|
||||
"contributions": [
|
||||
"doc"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "Suvrat1629",
|
||||
"name": "Suvrat1629",
|
||||
"avatar_url": "https://avatars.githubusercontent.com/u/140749446?v=4",
|
||||
"profile": "https://github.com/Suvrat1629",
|
||||
"contributions": [
|
||||
"code"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "ghyghoo8",
|
||||
"name": "ghy",
|
||||
"avatar_url": "https://avatars.githubusercontent.com/u/363129?v=4",
|
||||
"profile": "http://ghyghoo8.github.io/",
|
||||
"contributions": [
|
||||
"code"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "helei1030",
|
||||
"name": "helei1030",
|
||||
"avatar_url": "https://avatars.githubusercontent.com/u/11839080?v=4",
|
||||
"profile": "https://github.com/helei1030",
|
||||
"contributions": [
|
||||
"doc"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "pjfanning",
|
||||
"name": "PJ Fanning",
|
||||
"avatar_url": "https://avatars.githubusercontent.com/u/11783444?v=4",
|
||||
"profile": "https://medium.com/@pjfanning",
|
||||
"contributions": [
|
||||
"code"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "MonsterChenzhuo",
|
||||
"name": "monster",
|
||||
"avatar_url": "https://avatars.githubusercontent.com/u/60029759?v=4",
|
||||
"profile": "https://github.com/MonsterChenzhuo",
|
||||
"contributions": [
|
||||
"code"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "MasamiYui",
|
||||
"name": "Sherlock Yin",
|
||||
"avatar_url": "https://avatars.githubusercontent.com/u/22274133?v=4",
|
||||
"profile": "https://github.com/MasamiYui",
|
||||
"contributions": [
|
||||
"code"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "wanhao23",
|
||||
"name": "wanhao",
|
||||
"avatar_url": "https://avatars.githubusercontent.com/u/29560961?v=4",
|
||||
"profile": "https://github.com/wanhao23",
|
||||
"contributions": [
|
||||
"code",
|
||||
"doc"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "jonasHanhan",
|
||||
"name": "jonasHanhan",
|
||||
"avatar_url": "https://avatars.githubusercontent.com/u/130035609?v=4",
|
||||
"profile": "https://github.com/jonasHanhan",
|
||||
"contributions": [
|
||||
"code"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "NikhilMurugesan",
|
||||
"name": "NikhilMurugesan",
|
||||
"avatar_url": "https://avatars.githubusercontent.com/u/49281792?v=4",
|
||||
"profile": "https://github.com/NikhilMurugesan",
|
||||
"contributions": [
|
||||
"code"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "myangle1120",
|
||||
"name": "myangle1120",
|
||||
"avatar_url": "https://avatars.githubusercontent.com/u/19237013?v=4",
|
||||
"profile": "https://github.com/myangle1120",
|
||||
"contributions": [
|
||||
"code"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "yasminvo",
|
||||
"name": "yasminvo",
|
||||
"avatar_url": "https://avatars.githubusercontent.com/u/107528848?v=4",
|
||||
"profile": "https://github.com/yasminvo",
|
||||
"contributions": [
|
||||
"code"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "notbugggg",
|
||||
"name": "不关银渐层的事哦",
|
||||
"avatar_url": "https://avatars.githubusercontent.com/u/147966331?v=4",
|
||||
"profile": "https://github.com/notbugggg",
|
||||
"contributions": [
|
||||
"code"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "yyahang",
|
||||
"name": "yyahang",
|
||||
"avatar_url": "https://avatars.githubusercontent.com/u/90464876?v=4",
|
||||
"profile": "https://github.com/yyahang",
|
||||
"contributions": [
|
||||
"code"
|
||||
]
|
||||
}
|
||||
],
|
||||
"contributorsPerLine": 7,
|
||||
|
||||
@@ -53,4 +53,4 @@ body:
|
||||
validations:
|
||||
required: false
|
||||
- type: markdown
|
||||
value: "Please read the [Contribution Guideline](https://hertzbeat.apache.org/docs/community/contribution) before submitting the PR"
|
||||
value: "Please read the [Contribution Guideline](https://hertzbeat.apache.org/docs/others/contributing) before submitting the PR"
|
||||
|
||||
@@ -39,4 +39,4 @@ body:
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: |
|
||||
Please read the [Contribution Guideline](https://hertzbeat.apache.org/docs/community/contribution) before submitting the PR
|
||||
Please read the [Contribution Guideline](https://hertzbeat.com/docs/others/contributing/) before submitting the PR
|
||||
|
||||
@@ -30,5 +30,5 @@ body:
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: |
|
||||
Please read the [Contribution Guideline](https://hertzbeat.apache.org/docs/community/contribution) before submitting the PR
|
||||
Please read the [Contribution Guideline](https://hertzbeat.apache.org/docs/others/contributing/) before submitting the PR
|
||||
|
||||
|
||||
@@ -0,0 +1,71 @@
|
||||
# Licensed to the Apache Software Foundation (ASF) under one
|
||||
# or more contributor license agreements. See the NOTICE file
|
||||
# distributed with this work for additional information
|
||||
# regarding copyright ownership. The ASF licenses this file
|
||||
# to you under the Apache License, Version 2.0 (the
|
||||
# "License"); you may not use this file except in compliance
|
||||
# with the License. You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing,
|
||||
# software distributed under the License is distributed on an
|
||||
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
# KIND, either express or implied. See the License for the
|
||||
# specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
# This workflow will build a Java project with Maven
|
||||
# For more information see: https://help.github.com/actions/language-and-framework-guides/building-and-testing-java-with-maven
|
||||
|
||||
name: Backend CI
|
||||
|
||||
on:
|
||||
workflow_call:
|
||||
secrets:
|
||||
codecov_token:
|
||||
required: true
|
||||
workflow_dispatch:
|
||||
|
||||
jobs:
|
||||
backend-build:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: ./script/ci/github-actions/setup-deps
|
||||
|
||||
- name: Build with Maven
|
||||
run: mvn clean -B package -Prelease --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/
|
||||
@@ -40,44 +40,6 @@ on:
|
||||
|
||||
jobs:
|
||||
backend-build:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: ./script/ci/github-actions/setup-deps
|
||||
|
||||
- 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@v4
|
||||
if: always()
|
||||
with:
|
||||
name: hz-logs-${{ github.run_id }}
|
||||
path: |
|
||||
e2e/logs/
|
||||
e2e/report/
|
||||
|
||||
uses: ./.github/workflows/backend-build-test-reuse.yml
|
||||
secrets:
|
||||
codecov_token: ${{ secrets.CODECOV_TOKEN }}
|
||||
|
||||
@@ -39,7 +39,7 @@ jobs:
|
||||
run: npx docusaurus-prince-pdf -u https://hertzbeat.apache.org/docs --output docs-en.pdf
|
||||
|
||||
- name: Upload results
|
||||
uses: actions/upload-artifact@v4
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: docs-cn-pdf
|
||||
path: docs-cn.pdf
|
||||
@@ -47,7 +47,7 @@ jobs:
|
||||
retention-days: 1
|
||||
|
||||
- name: Upload results
|
||||
uses: actions/upload-artifact@v4
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: docs-en-pdf
|
||||
path: docs-en.pdf
|
||||
|
||||
+1
-1
@@ -1,7 +1,7 @@
|
||||
tasks:
|
||||
|
||||
- name: Run backend
|
||||
before: cd hertzbeat-manager
|
||||
before: cd manager
|
||||
command: |
|
||||
gp sync-await setup-backend
|
||||
mvn spring-boot:run
|
||||
|
||||
+6
-11
@@ -38,9 +38,7 @@ Even small corrections to typos are very welcome :)
|
||||
|
||||
3. Execute under the project root directory: `mvn clean install -DskipTests`
|
||||
|
||||
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`
|
||||
4. Start `springboot manager` service: `manager/src/main/java/org/apache/hertzbeat/manager/Manager.java`
|
||||
|
||||
#### Frontend start
|
||||
|
||||
@@ -133,13 +131,13 @@ Add WeChat account `ahertzbeat` to pull you into the WeChat group.
|
||||
|
||||
## 🥐 Architecture
|
||||
|
||||
- **[manager](https://github.com/apache/hertzbeat/tree/master/hertzbeat-manager)** Provide monitoring management, system management basic services.
|
||||
- **[manager](https://github.com/apache/hertzbeat/tree/master/manager)** Provide monitoring management, system management basic services.
|
||||
> Provides monitoring management, monitoring configuration management, system user management, etc.
|
||||
- **[collector](https://github.com/apache/hertzbeat/tree/master/collector)** Provide metrics data collection services.
|
||||
> Use common protocols to remotely collect and obtain peer-to-peer metrics data.
|
||||
- **[warehouse](https://github.com/apache/hertzbeat/tree/master/warehouse)** Provide monitoring data warehousing services.
|
||||
> Metrics data management, data query, calculation and statistics.
|
||||
- **[alerter](https://github.com/apache/hertzbeat/tree/master/hertzbeat-alerter)** Provide alert service.
|
||||
- **[alerter](https://github.com/apache/hertzbeat/tree/master/alerter)** Provide alert service.
|
||||
> Alarm calculation trigger, monitoring status linkage, alarm configuration, and alarm notification.
|
||||
- **[web-app](https://github.com/apache/hertzbeat/tree/master/web-app)** Provide web ui.
|
||||
> Angular Web UI.
|
||||
@@ -191,10 +189,7 @@ Add WeChat account `ahertzbeat` to pull you into the WeChat group.
|
||||
|
||||
3. 在项目根目录运行编译: `mvn clean install -DskipTests`
|
||||
|
||||
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`
|
||||
|
||||
4. 启动`springboot manager`服务 `manager/src/main/java/org/apache/hertzbeat/manager/Manager.java`
|
||||
|
||||
#### 前端启动
|
||||
|
||||
@@ -286,13 +281,13 @@ Add WeChat account `ahertzbeat` to pull you into the WeChat group.
|
||||
|
||||
### 模块
|
||||
|
||||
- **[manager](https://github.com/apache/hertzbeat/tree/master/hertzbeat-manager)** 提供监控管理,系统管理基础服务
|
||||
- **[manager](https://github.com/apache/hertzbeat/tree/master/manager)** 提供监控管理,系统管理基础服务
|
||||
> 提供对监控的管理,监控应用配置的管理,系统用户租户后台管理等。
|
||||
- **[collector](https://github.com/apache/hertzbeat/tree/master/collector)** 提供监控数据采集服务
|
||||
> 使用通用协议远程采集获取对端指标数据。
|
||||
- **[warehouse](https://github.com/apache/hertzbeat/tree/master/warehouse)** 提供监控数据仓储服务
|
||||
> 采集指标结果数据管理,数据落盘,查询,计算统计。
|
||||
- **[alerter](https://github.com/apache/hertzbeat/tree/master/hertzbeat-alerter)** 提供告警服务
|
||||
- **[alerter](https://github.com/apache/hertzbeat/tree/master/alerter)** 提供告警服务
|
||||
> 告警计算触发,任务状态联动,告警配置,告警通知。
|
||||
- **[web-app](https://github.com/apache/hertzbeat/tree/master/web-app)** 提供可视化控制台页面
|
||||
> 监控告警系统可视化控制台前端
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
|
||||
[](https://discord.gg/Fb6M73htGr)
|
||||
[](https://www.reddit.com/r/hertzbeat/)
|
||||
[](https://x.com/hertzbeat1024)
|
||||
[](https://twitter.com/hertzbeat1024)
|
||||
[](https://www.bestpractices.dev/projects/8139)
|
||||
[](https://app.codecov.io/gh/apache/hertzbeat)
|
||||
[](https://hub.docker.com/r/apache/hertzbeat)
|
||||
@@ -60,42 +60,42 @@
|
||||
> Welcome everyone to contribute your customized general monitoring type YML template during use.
|
||||
|
||||
|
||||
- [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)
|
||||
- [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_port.yml), [Dns](https://raw.githubusercontent.com/apache/hertzbeat/master/manager/src/main/resources/define/app-dns.yml),
|
||||
[Pop3](https://raw.githubusercontent.com/apache/hertzbeat/master/manager/src/main/resources/define/app-pop3.yml), [Ntp](https://raw.githubusercontent.com/apache/hertzbeat/master/manager/src/main/resources/define/app-ntp.yml),
|
||||
[Api Code](https://raw.githubusercontent.com/apache/hertzbeat/master/manager/src/main/resources/define/app-api_code.yml), [Smtp](https://raw.githubusercontent.com/apache/hertzbeat/master/manager/src/main/resources/define/app-smtp.yml),
|
||||
[Nginx](https://raw.githubusercontent.com/apache/hertzbeat/master/manager/src/main/resources/define/app-nginx.yml)
|
||||
- [Mysql](https://raw.githubusercontent.com/apache/hertzbeat/master/manager/src/main/resources/define/app-mysql.yml), [PostgreSQL](https://raw.githubusercontent.com/apache/hertzbeat/master/manager/src/main/resources/define/app-postgresql.yml),
|
||||
[MariaDB](https://raw.githubusercontent.com/apache/hertzbeat/master/manager/src/main/resources/define/app-mariadb.yml), [Redis](https://raw.githubusercontent.com/apache/hertzbeat/master/manager/src/main/resources/define/app-redis.yml),
|
||||
[ElasticSearch](https://raw.githubusercontent.com/apache/hertzbeat/master/manager/src/main/resources/define/app-elasticsearch.yml), [SqlServer](https://raw.githubusercontent.com/apache/hertzbeat/master/manager/src/main/resources/define/app-sqlserver.yml),
|
||||
[Oracle](https://raw.githubusercontent.com/apache/hertzbeat/master/manager/src/main/resources/define/app-oracle.yml), [MongoDB](https://raw.githubusercontent.com/apache/hertzbeat/master/manager/src/main/resources/define/app-mongodb.yml),
|
||||
[DM](https://raw.githubusercontent.com/apache/hertzbeat/master/manager/src/main/resources/define/app-dm.yml), [OpenGauss](https://raw.githubusercontent.com/apache/hertzbeat/master/manager/src/main/resources/define/app-opengauss.yml),
|
||||
[ClickHouse](https://raw.githubusercontent.com/apache/hertzbeat/master/manager/src/main/resources/define/app-clickhouse.yml), [IoTDB](https://raw.githubusercontent.com/apache/hertzbeat/master/manager/src/main/resources/define/app-iotdb.yml),
|
||||
[Redis Cluster](https://raw.githubusercontent.com/apache/hertzbeat/master/manager/src/main/resources/define/app-redis_cluster.yml), [Redis Sentinel](https://raw.githubusercontent.com/apache/hertzbeat/master/manager/src/main/resources/define/app-redis_sentinel.yml)
|
||||
[Doris BE](https://github.com/apache/hertzbeat/blob/master/manager/src/main/resources/define/app-doris_be.yml), [Doris FE](https://github.com/apache/hertzbeat/blob/master/manager/src/main/resources/define/app-doris_fe.yml),
|
||||
[Memcached](https://github.com/apache/hertzbeat/blob/master/manager/src/main/resources/define/app-memcached.yml), [NebulaGraph](https://github.com/apache/hertzbeat/blob/master/manager/src/main/resources/define/app-nebulaGraph.yml)
|
||||
- [Linux](https://raw.githubusercontent.com/apache/hertzbeat/master/manager/src/main/resources/define/app-linux.yml), [Ubuntu](https://raw.githubusercontent.com/apache/hertzbeat/master/manager/src/main/resources/define/app-ubuntu.yml),
|
||||
[CentOS](https://raw.githubusercontent.com/apache/hertzbeat/master/manager/src/main/resources/define/app-centos.yml), [Windows](https://raw.githubusercontent.com/apache/hertzbeat/master/manager/src/main/resources/define/app-windows.yml),
|
||||
[EulerOS](https://raw.githubusercontent.com/apache/hertzbeat/master/manager/src/main/resources/define/app-euleros.yml), [Fedora CoreOS](https://raw.githubusercontent.com/apache/hertzbeat/master/manager/src/main/resources/define/app-coreos.yml),
|
||||
[OpenSUSE](https://raw.githubusercontent.com/apache/hertzbeat/master/manager/src/main/resources/define/app-opensuse.yml), [Rocky Linux](https://raw.githubusercontent.com/apache/hertzbeat/master/manager/src/main/resources/define/app-rockylinux.yml),
|
||||
[Red Hat](https://raw.githubusercontent.com/apache/hertzbeat/master/manager/src/main/resources/define/app-redhat.yml), [FreeBSD](https://raw.githubusercontent.com/apache/hertzbeat/master/manager/src/main/resources/define/app-freebsd.yml),
|
||||
[AlmaLinux](https://raw.githubusercontent.com/apache/hertzbeat/master/manager/src/main/resources/define/app-almalinux.yml), [Debian Linux](https://raw.githubusercontent.com/apache/hertzbeat/master/manager/src/main/resources/define/app-debian.yml)
|
||||
- [Tomcat](https://raw.githubusercontent.com/apache/hertzbeat/master/manager/src/main/resources/define/app-tomcat.yml), [Nacos](https://raw.githubusercontent.com/apache/hertzbeat/master/manager/src/main/resources/define/app-nacos.yml),
|
||||
[Zookeeper](https://raw.githubusercontent.com/apache/hertzbeat/master/manager/src/main/resources/define/app-zookeeper.yml), [RabbitMQ](https://raw.githubusercontent.com/apache/hertzbeat/master/manager/src/main/resources/define/app-rabbitmq.yml),
|
||||
[Flink](https://raw.githubusercontent.com/apache/hertzbeat/master/manager/src/main/resources/define/app-flink.yml), [Kafka](https://raw.githubusercontent.com/apache/hertzbeat/master/manager/src/main/resources/define/app-kafka.yml),
|
||||
[ShenYu](https://raw.githubusercontent.com/apache/hertzbeat/master/manager/src/main/resources/define/app-shenyu.yml), [DynamicTp](https://raw.githubusercontent.com/apache/hertzbeat/master/manager/src/main/resources/define/app-dynamic_tp.yml),
|
||||
[Jetty](https://raw.githubusercontent.com/apache/hertzbeat/master/manager/src/main/resources/define/app-jetty.yml), [ActiveMQ](https://raw.githubusercontent.com/apache/hertzbeat/master/manager/src/main/resources/define/app-activemq.yml),
|
||||
[Spring Gateway](https://raw.githubusercontent.com/apache/hertzbeat/master/manager/src/main/resources/define/app-spring_gateway.yml), [EMQX MQTT](https://raw.githubusercontent.com/apache/hertzbeat/master/manager/src/main/resources/define/app-emqx.yml),
|
||||
[AirFlow](https://raw.githubusercontent.com/apache/hertzbeat/master/manager/src/main/resources/define/app-airflow.yml), [Hive](https://raw.githubusercontent.com/apache/hertzbeat/master/manager/src/main/resources/define/app-hive.yml),
|
||||
[Spark](https://raw.githubusercontent.com/apache/hertzbeat/master/manager/src/main/resources/define/app-spark.yml), [Hadoop](https://raw.githubusercontent.com/apache/hertzbeat/master/manager/src/main/resources/define/app-hadoop.yml)
|
||||
- [Kubernetes](https://raw.githubusercontent.com/apache/hertzbeat/master/manager/src/main/resources/define/app-kubernetes.yml), [Docker](https://raw.githubusercontent.com/apache/hertzbeat/master/manager/src/main/resources/define/app-docker.yml)
|
||||
- [CiscoSwitch](https://raw.githubusercontent.com/apache/hertzbeat/master/manager/src/main/resources/define/app-cisco_switch.yml), [HpeSwitch](https://raw.githubusercontent.com/apache/hertzbeat/master/manager/src/main/resources/define/app-hpe_switch.yml),
|
||||
[HuaweiSwitch](https://raw.githubusercontent.com/apache/hertzbeat/master/manager/src/main/resources/define/app-huawei_switch.yml), [TpLinkSwitch](https://raw.githubusercontent.com/apache/hertzbeat/master/manager/src/main/resources/define/app-tplink_switch.yml),
|
||||
[H3cSwitch](https://raw.githubusercontent.com/apache/hertzbeat/master/manager/src/main/resources/define/app-h3c_switch.yml)
|
||||
- And More Your Custom Template.
|
||||
- Notified Support `Discord` `Slack` `Telegram` `Email` `Dingtalk` `WeChat` `FeiShu` `Webhook` `SMS` `ServerChan`.
|
||||
|
||||
@@ -160,7 +160,7 @@ 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`, add VM options in IDE: ` --add-opens=java.base/java.nio=org.apache.arrow.memory.core,ALL-UNNAMED `, then start the `manager` service.
|
||||
2. Backend:need `maven3+`, `java17`, `lombok`, 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`
|
||||
|
||||
@@ -475,41 +475,6 @@ Thanks to these wonderful people, welcome to join us:
|
||||
<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>
|
||||
<tr>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/lctking"><img src="https://avatars.githubusercontent.com/u/168249998?v=4?s=100" width="100px;" alt="nullwli"/><br /><sub><b>nullwli</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=lctking" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://simonsigre.com/"><img src="https://avatars.githubusercontent.com/u/14932913?v=4?s=100" width="100px;" alt="Simon Sigré"/><br /><sub><b>Simon Sigré</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=simonsigre" title="Documentation">📖</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="http://www.ponfee.cn/"><img src="https://avatars.githubusercontent.com/u/46117331?v=4?s=100" width="100px;" alt="ponfee"/><br /><sub><b>ponfee</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=ponfee" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/Vedant7789"><img src="https://avatars.githubusercontent.com/u/147625492?v=4?s=100" width="100px;" alt="Vedant7789"/><br /><sub><b>Vedant7789</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=Vedant7789" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/Craaaaazy77"><img src="https://avatars.githubusercontent.com/u/23025522?v=4?s=100" width="100px;" alt="Craaaaazy77"/><br /><sub><b>Craaaaazy77</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=Craaaaazy77" title="Documentation">📖</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/Suvrat1629"><img src="https://avatars.githubusercontent.com/u/140749446?v=4?s=100" width="100px;" alt="Suvrat1629"/><br /><sub><b>Suvrat1629</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=Suvrat1629" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="http://ghyghoo8.github.io/"><img src="https://avatars.githubusercontent.com/u/363129?v=4?s=100" width="100px;" alt="ghy"/><br /><sub><b>ghy</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=ghyghoo8" title="Code">💻</a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/helei1030"><img src="https://avatars.githubusercontent.com/u/11839080?v=4?s=100" width="100px;" alt="helei1030"/><br /><sub><b>helei1030</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=helei1030" title="Documentation">📖</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://medium.com/@pjfanning"><img src="https://avatars.githubusercontent.com/u/11783444?v=4?s=100" width="100px;" alt="PJ Fanning"/><br /><sub><b>PJ Fanning</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=pjfanning" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/MonsterChenzhuo"><img src="https://avatars.githubusercontent.com/u/60029759?v=4?s=100" width="100px;" alt="monster"/><br /><sub><b>monster</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=MonsterChenzhuo" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/MasamiYui"><img src="https://avatars.githubusercontent.com/u/22274133?v=4?s=100" width="100px;" alt="Sherlock Yin"/><br /><sub><b>Sherlock Yin</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=MasamiYui" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/wanhao23"><img src="https://avatars.githubusercontent.com/u/29560961?v=4?s=100" width="100px;" alt="wanhao"/><br /><sub><b>wanhao</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=wanhao23" title="Code">💻</a> <a href="https://github.com/apache/hertzbeat/commits?author=wanhao23" title="Documentation">📖</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/jonasHanhan"><img src="https://avatars.githubusercontent.com/u/130035609?v=4?s=100" width="100px;" alt="jonasHanhan"/><br /><sub><b>jonasHanhan</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=jonasHanhan" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/NikhilMurugesan"><img src="https://avatars.githubusercontent.com/u/49281792?v=4?s=100" width="100px;" alt="NikhilMurugesan"/><br /><sub><b>NikhilMurugesan</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=NikhilMurugesan" title="Code">💻</a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/myangle1120"><img src="https://avatars.githubusercontent.com/u/19237013?v=4?s=100" width="100px;" alt="myangle1120"/><br /><sub><b>myangle1120</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=myangle1120" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/yasminvo"><img src="https://avatars.githubusercontent.com/u/107528848?v=4?s=100" width="100px;" alt="yasminvo"/><br /><sub><b>yasminvo</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=yasminvo" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/notbugggg"><img src="https://avatars.githubusercontent.com/u/147966331?v=4?s=100" width="100px;" alt="不关银渐层的事哦"/><br /><sub><b>不关银渐层的事哦</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=notbugggg" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/yyahang"><img src="https://avatars.githubusercontent.com/u/90464876?v=4?s=100" width="100px;" alt="yyahang"/><br /><sub><b>yyahang</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=yyahang" title="Code">💻</a></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
@@ -537,7 +502,7 @@ WeChat Public : Search ID `usthecom`.
|
||||
|
||||
[Reddit Community](https://www.reddit.com/r/hertzbeat/)
|
||||
|
||||
[Follow Us Twitter](https://x.com/hertzbeat1024)
|
||||
[Follow Us Twitter](https://twitter.com/hertzbeat1024)
|
||||
|
||||
[Subscribe YouTube](https://www.youtube.com/channel/UCri75zfWX0GHqJFPENEbLow)
|
||||
|
||||
|
||||
+39
-74
@@ -12,7 +12,7 @@
|
||||
|
||||
[](https://discord.gg/Fb6M73htGr)
|
||||
[](https://www.reddit.com/r/hertzbeat/)
|
||||
[](https://x.com/hertzbeat1024)
|
||||
[](https://twitter.com/hertzbeat1024)
|
||||
[](https://www.bestpractices.dev/projects/8139)
|
||||
[](https://app.codecov.io/gh/apache/hertzbeat)
|
||||
[](https://hub.docker.com/r/apache/hertzbeat)
|
||||
@@ -61,42 +61,42 @@
|
||||
> 我们将监控采集类型(mysql,jvm,k8s)都定义为 `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)
|
||||
- [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_port.yml), [Dns](https://raw.githubusercontent.com/apache/hertzbeat/master/manager/src/main/resources/define/app-dns.yml),
|
||||
[Pop3](https://raw.githubusercontent.com/apache/hertzbeat/master/manager/src/main/resources/define/app-pop3.yml), [Ntp](https://raw.githubusercontent.com/apache/hertzbeat/master/manager/src/main/resources/define/app-ntp.yml),
|
||||
[Api Code](https://raw.githubusercontent.com/apache/hertzbeat/master/manager/src/main/resources/define/app-api_code.yml), [Smtp](https://raw.githubusercontent.com/apache/hertzbeat/master/manager/src/main/resources/define/app-smtp.yml),
|
||||
[Nginx](https://raw.githubusercontent.com/apache/hertzbeat/master/manager/src/main/resources/define/app-nginx.yml)
|
||||
- [Mysql](https://raw.githubusercontent.com/apache/hertzbeat/master/manager/src/main/resources/define/app-mysql.yml), [PostgreSQL](https://raw.githubusercontent.com/apache/hertzbeat/master/manager/src/main/resources/define/app-postgresql.yml),
|
||||
[MariaDB](https://raw.githubusercontent.com/apache/hertzbeat/master/manager/src/main/resources/define/app-mariadb.yml), [Redis](https://raw.githubusercontent.com/apache/hertzbeat/master/manager/src/main/resources/define/app-redis.yml),
|
||||
[ElasticSearch](https://raw.githubusercontent.com/apache/hertzbeat/master/manager/src/main/resources/define/app-elasticsearch.yml), [SqlServer](https://raw.githubusercontent.com/apache/hertzbeat/master/manager/src/main/resources/define/app-sqlserver.yml),
|
||||
[Oracle](https://raw.githubusercontent.com/apache/hertzbeat/master/manager/src/main/resources/define/app-oracle.yml), [MongoDB](https://raw.githubusercontent.com/apache/hertzbeat/master/manager/src/main/resources/define/app-mongodb.yml),
|
||||
[DM](https://raw.githubusercontent.com/apache/hertzbeat/master/manager/src/main/resources/define/app-dm.yml), [OpenGauss](https://raw.githubusercontent.com/apache/hertzbeat/master/manager/src/main/resources/define/app-opengauss.yml),
|
||||
[ClickHouse](https://raw.githubusercontent.com/apache/hertzbeat/master/manager/src/main/resources/define/app-clickhouse.yml), [IoTDB](https://raw.githubusercontent.com/apache/hertzbeat/master/manager/src/main/resources/define/app-iotdb.yml),
|
||||
[Redis Cluster](https://raw.githubusercontent.com/apache/hertzbeat/master/manager/src/main/resources/define/app-redis_cluster.yml), [Redis Sentinel](https://raw.githubusercontent.com/apache/hertzbeat/master/manager/src/main/resources/define/app-redis_sentinel.yml)
|
||||
[Doris BE](https://github.com/apache/hertzbeat/blob/master/manager/src/main/resources/define/app-doris_be.yml), [Doris FE](https://github.com/apache/hertzbeat/blob/master/manager/src/main/resources/define/app-doris_fe.yml),
|
||||
[Memcached](https://github.com/apache/hertzbeat/blob/master/manager/src/main/resources/define/app-memcached.yml), [NebulaGraph](https://github.com/apache/hertzbeat/blob/master/manager/src/main/resources/define/app-nebulaGraph.yml)
|
||||
- [Linux](https://raw.githubusercontent.com/apache/hertzbeat/master/manager/src/main/resources/define/app-linux.yml), [Ubuntu](https://raw.githubusercontent.com/apache/hertzbeat/master/manager/src/main/resources/define/app-ubuntu.yml),
|
||||
[CentOS](https://raw.githubusercontent.com/apache/hertzbeat/master/manager/src/main/resources/define/app-centos.yml), [Windows](https://raw.githubusercontent.com/apache/hertzbeat/master/manager/src/main/resources/define/app-windows.yml),
|
||||
[EulerOS](https://raw.githubusercontent.com/apache/hertzbeat/master/manager/src/main/resources/define/app-euleros.yml), [Fedora CoreOS](https://raw.githubusercontent.com/apache/hertzbeat/master/manager/src/main/resources/define/app-coreos.yml),
|
||||
[OpenSUSE](https://raw.githubusercontent.com/apache/hertzbeat/master/manager/src/main/resources/define/app-opensuse.yml), [Rocky Linux](https://raw.githubusercontent.com/apache/hertzbeat/master/manager/src/main/resources/define/app-rockylinux.yml),
|
||||
[Red Hat](https://raw.githubusercontent.com/apache/hertzbeat/master/manager/src/main/resources/define/app-redhat.yml), [FreeBSD](https://raw.githubusercontent.com/apache/hertzbeat/master/manager/src/main/resources/define/app-freebsd.yml),
|
||||
[AlmaLinux](https://raw.githubusercontent.com/apache/hertzbeat/master/manager/src/main/resources/define/app-almalinux.yml), [Debian Linux](https://raw.githubusercontent.com/apache/hertzbeat/master/manager/src/main/resources/define/app-debian.yml)
|
||||
- [Tomcat](https://raw.githubusercontent.com/apache/hertzbeat/master/manager/src/main/resources/define/app-tomcat.yml), [Nacos](https://raw.githubusercontent.com/apache/hertzbeat/master/manager/src/main/resources/define/app-nacos.yml),
|
||||
[Zookeeper](https://raw.githubusercontent.com/apache/hertzbeat/master/manager/src/main/resources/define/app-zookeeper.yml), [RabbitMQ](https://raw.githubusercontent.com/apache/hertzbeat/master/manager/src/main/resources/define/app-rabbitmq.yml),
|
||||
[Flink](https://raw.githubusercontent.com/apache/hertzbeat/master/manager/src/main/resources/define/app-flink.yml), [Kafka](https://raw.githubusercontent.com/apache/hertzbeat/master/manager/src/main/resources/define/app-kafka.yml),
|
||||
[ShenYu](https://raw.githubusercontent.com/apache/hertzbeat/master/manager/src/main/resources/define/app-shenyu.yml), [DynamicTp](https://raw.githubusercontent.com/apache/hertzbeat/master/manager/src/main/resources/define/app-dynamic_tp.yml),
|
||||
[Jetty](https://raw.githubusercontent.com/apache/hertzbeat/master/manager/src/main/resources/define/app-jetty.yml), [ActiveMQ](https://raw.githubusercontent.com/apache/hertzbeat/master/manager/src/main/resources/define/app-activemq.yml),
|
||||
[Spring Gateway](https://raw.githubusercontent.com/apache/hertzbeat/master/manager/src/main/resources/define/app-spring_gateway.yml), [EMQX MQTT](https://raw.githubusercontent.com/apache/hertzbeat/master/manager/src/main/resources/define/app-emqx.yml),
|
||||
[AirFlow](https://raw.githubusercontent.com/apache/hertzbeat/master/manager/src/main/resources/define/app-airflow.yml), [Hive](https://raw.githubusercontent.com/apache/hertzbeat/master/manager/src/main/resources/define/app-hive.yml),
|
||||
[Spark](https://raw.githubusercontent.com/apache/hertzbeat/master/manager/src/main/resources/define/app-spark.yml), [Hadoop](https://raw.githubusercontent.com/apache/hertzbeat/master/manager/src/main/resources/define/app-hadoop.yml)
|
||||
- [Kubernetes](https://raw.githubusercontent.com/apache/hertzbeat/master/manager/src/main/resources/define/app-kubernetes.yml), [Docker](https://raw.githubusercontent.com/apache/hertzbeat/master/manager/src/main/resources/define/app-docker.yml)
|
||||
- [CiscoSwitch](https://raw.githubusercontent.com/apache/hertzbeat/master/manager/src/main/resources/define/app-cisco_switch.yml), [HpeSwitch](https://raw.githubusercontent.com/apache/hertzbeat/master/manager/src/main/resources/define/app-hpe_switch.yml),
|
||||
[HuaweiSwitch](https://raw.githubusercontent.com/apache/hertzbeat/master/manager/src/main/resources/define/app-huawei_switch.yml), [TpLinkSwitch](https://raw.githubusercontent.com/apache/hertzbeat/master/manager/src/main/resources/define/app-tplink_switch.yml),
|
||||
[H3cSwitch](https://raw.githubusercontent.com/apache/hertzbeat/master/manager/src/main/resources/define/app-h3c_switch.yml)
|
||||
- 和更多自定义监控模版。
|
||||
- 通知支持 `Discord` `Slack` `Telegram` `邮件` `钉钉` `微信` `飞书` `短信` `Webhook` `Server酱`。
|
||||
|
||||
@@ -159,7 +159,7 @@
|
||||
##### 方式三:本地代码启动
|
||||
|
||||
1. 此为前后端分离项目,本地代码调试需要分别启动后端工程 `manager` 和前端工程 `web-app`
|
||||
2. 后端:需要 `maven3+`, `java17` 和 `lombok` 环境,修改 `YML` 配置信息,添加JVM参数`--add-opens=java.base/java.nio=org.apache.arrow.memory.core,ALL-UNNAMED`后启动 `manager` 服务即可。
|
||||
2. 后端:需要 `maven3+`, `java17` 和 `lombok` 环境,修改 `YML` 配置信息并启动 `manager` 服务
|
||||
3. 前端:需要 `nodejs npm angular-cli`环境,待本地后端启动后,在 `web-app` 目录下启动 `ng serve --open`
|
||||
4. 浏览器访问 `http://localhost:4200` 即可开始,默认账号密码 `admin/hertzbeat`
|
||||
|
||||
@@ -474,41 +474,6 @@ Thanks these wonderful people, welcome to join us:
|
||||
<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>
|
||||
<tr>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/lctking"><img src="https://avatars.githubusercontent.com/u/168249998?v=4?s=100" width="100px;" alt="nullwli"/><br /><sub><b>nullwli</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=lctking" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://simonsigre.com/"><img src="https://avatars.githubusercontent.com/u/14932913?v=4?s=100" width="100px;" alt="Simon Sigré"/><br /><sub><b>Simon Sigré</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=simonsigre" title="Documentation">📖</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="http://www.ponfee.cn/"><img src="https://avatars.githubusercontent.com/u/46117331?v=4?s=100" width="100px;" alt="ponfee"/><br /><sub><b>ponfee</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=ponfee" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/Vedant7789"><img src="https://avatars.githubusercontent.com/u/147625492?v=4?s=100" width="100px;" alt="Vedant7789"/><br /><sub><b>Vedant7789</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=Vedant7789" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/Craaaaazy77"><img src="https://avatars.githubusercontent.com/u/23025522?v=4?s=100" width="100px;" alt="Craaaaazy77"/><br /><sub><b>Craaaaazy77</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=Craaaaazy77" title="Documentation">📖</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/Suvrat1629"><img src="https://avatars.githubusercontent.com/u/140749446?v=4?s=100" width="100px;" alt="Suvrat1629"/><br /><sub><b>Suvrat1629</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=Suvrat1629" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="http://ghyghoo8.github.io/"><img src="https://avatars.githubusercontent.com/u/363129?v=4?s=100" width="100px;" alt="ghy"/><br /><sub><b>ghy</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=ghyghoo8" title="Code">💻</a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/helei1030"><img src="https://avatars.githubusercontent.com/u/11839080?v=4?s=100" width="100px;" alt="helei1030"/><br /><sub><b>helei1030</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=helei1030" title="Documentation">📖</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://medium.com/@pjfanning"><img src="https://avatars.githubusercontent.com/u/11783444?v=4?s=100" width="100px;" alt="PJ Fanning"/><br /><sub><b>PJ Fanning</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=pjfanning" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/MonsterChenzhuo"><img src="https://avatars.githubusercontent.com/u/60029759?v=4?s=100" width="100px;" alt="monster"/><br /><sub><b>monster</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=MonsterChenzhuo" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/MasamiYui"><img src="https://avatars.githubusercontent.com/u/22274133?v=4?s=100" width="100px;" alt="Sherlock Yin"/><br /><sub><b>Sherlock Yin</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=MasamiYui" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/wanhao23"><img src="https://avatars.githubusercontent.com/u/29560961?v=4?s=100" width="100px;" alt="wanhao"/><br /><sub><b>wanhao</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=wanhao23" title="Code">💻</a> <a href="https://github.com/apache/hertzbeat/commits?author=wanhao23" title="Documentation">📖</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/jonasHanhan"><img src="https://avatars.githubusercontent.com/u/130035609?v=4?s=100" width="100px;" alt="jonasHanhan"/><br /><sub><b>jonasHanhan</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=jonasHanhan" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/NikhilMurugesan"><img src="https://avatars.githubusercontent.com/u/49281792?v=4?s=100" width="100px;" alt="NikhilMurugesan"/><br /><sub><b>NikhilMurugesan</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=NikhilMurugesan" title="Code">💻</a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/myangle1120"><img src="https://avatars.githubusercontent.com/u/19237013?v=4?s=100" width="100px;" alt="myangle1120"/><br /><sub><b>myangle1120</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=myangle1120" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/yasminvo"><img src="https://avatars.githubusercontent.com/u/107528848?v=4?s=100" width="100px;" alt="yasminvo"/><br /><sub><b>yasminvo</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=yasminvo" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/notbugggg"><img src="https://avatars.githubusercontent.com/u/147966331?v=4?s=100" width="100px;" alt="不关银渐层的事哦"/><br /><sub><b>不关银渐层的事哦</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=notbugggg" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/yyahang"><img src="https://avatars.githubusercontent.com/u/90464876?v=4?s=100" width="100px;" alt="yyahang"/><br /><sub><b>yyahang</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=yyahang" title="Code">💻</a></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
@@ -536,7 +501,7 @@ Thanks these wonderful people, welcome to join us:
|
||||
|
||||
[Reddit Community](https://www.reddit.com/r/hertzbeat/)
|
||||
|
||||
[Follow Us Twitter](https://x.com/hertzbeat1024)
|
||||
[Follow Us Twitter](https://twitter.com/hertzbeat1024)
|
||||
|
||||
[Subscribe YouTube](https://www.youtube.com/channel/UCri75zfWX0GHqJFPENEbLow)
|
||||
|
||||
|
||||
+6
-9
@@ -1,9 +1,12 @@
|
||||
# Security Policy
|
||||
|
||||
Apache HertzBeat follows the [ASF vulnerability handling process](https://apache.org/security/#vulnerability-handling)
|
||||
**[Version Releases](https://github.com/apache/hertzbeat/releases)**
|
||||
|
||||
## 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: |
|
||||
@@ -11,12 +14,6 @@ Apache HertzBeat follows the [ASF vulnerability handling process](https://apache
|
||||
|
||||
## Reporting a Vulnerability
|
||||
|
||||
Please do not file GitHub issues for security vulnerabilities as they are public!
|
||||
Use this section to tell people how to report a vulnerability.
|
||||
|
||||
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/)
|
||||
Please report vulnerability disclosures to `security@apache.org`.
|
||||
|
||||
@@ -32,19 +32,9 @@
|
||||
<!-- common -->
|
||||
<dependency>
|
||||
<groupId>org.apache.hertzbeat</groupId>
|
||||
<artifactId>hertzbeat-base</artifactId>
|
||||
<artifactId>hertzbeat-common</artifactId>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<!-- plugin -->
|
||||
<dependency>
|
||||
<groupId>org.apache.hertzbeat</groupId>
|
||||
<artifactId>hertzbeat-plugin</artifactId>
|
||||
</dependency>
|
||||
<!-- warehouse -->
|
||||
<dependency>
|
||||
<groupId>org.apache.hertzbeat</groupId>
|
||||
<artifactId>hertzbeat-warehouse</artifactId>
|
||||
</dependency>
|
||||
<!-- spring -->
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
@@ -60,21 +50,6 @@
|
||||
<artifactId>spring-boot-configuration-processor</artifactId>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
<!-- email -->
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-mail</artifactId>
|
||||
</dependency>
|
||||
<!-- freemarker -->
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-freemarker</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>net.sourceforge.nekohtml</groupId>
|
||||
<artifactId>nekohtml</artifactId>
|
||||
<version>${nekohtml.version}</version>
|
||||
</dependency>
|
||||
<!-- kafka -->
|
||||
<dependency>
|
||||
<groupId>org.apache.kafka</groupId>
|
||||
@@ -98,25 +73,6 @@
|
||||
<version>${easy-poi.version}</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.huaweicloud.sdk</groupId>
|
||||
<artifactId>huaweicloud-sdk-smn</artifactId>
|
||||
<version>${huawei.sdk.version}</version>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<groupId>org.openeuler</groupId>
|
||||
<artifactId>bgmprovider</artifactId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.arrow</groupId>
|
||||
<artifactId>arrow-vector</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.arrow</groupId>
|
||||
<artifactId>arrow-memory-netty</artifactId>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
</project>
|
||||
-18
@@ -79,11 +79,6 @@ public class AlerterProperties {
|
||||
*/
|
||||
private EntranceProperties entrance;
|
||||
|
||||
/**
|
||||
* Inhibit configuration properties
|
||||
*/
|
||||
private InhibitProperties inhibit;
|
||||
|
||||
/**
|
||||
* Data entry configuration properties
|
||||
*/
|
||||
@@ -110,17 +105,4 @@ public class AlerterProperties {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Inhibit configuration properties
|
||||
*/
|
||||
@Getter
|
||||
@Setter
|
||||
public static class InhibitProperties {
|
||||
|
||||
/**
|
||||
* inhibit rule cache ttl, default 4h
|
||||
*/
|
||||
private long ttl = 4 * 60 * 60 * 1000L;
|
||||
}
|
||||
|
||||
}
|
||||
+2
-2
@@ -44,7 +44,7 @@ public class AlerterWorkerPool {
|
||||
private void initWorkExecutor() {
|
||||
ThreadFactory threadFactory = new ThreadFactoryBuilder()
|
||||
.setUncaughtExceptionHandler((thread, throwable) -> {
|
||||
log.error("Alerter workerExecutor has uncaughtException.");
|
||||
log.error("workerExecutor has uncaughtException.");
|
||||
log.error(throwable.getMessage(), throwable);
|
||||
})
|
||||
.setDaemon(true)
|
||||
@@ -62,7 +62,7 @@ public class AlerterWorkerPool {
|
||||
private void initNotifyExecutor() {
|
||||
ThreadFactory threadFactory = new ThreadFactoryBuilder()
|
||||
.setUncaughtExceptionHandler((thread, throwable) -> {
|
||||
log.error("Alerter notifyExecutor has uncaughtException.");
|
||||
log.error("notifyExecutor has uncaughtException.");
|
||||
log.error(throwable.getMessage(), throwable);
|
||||
})
|
||||
.setDaemon(true)
|
||||
@@ -0,0 +1,483 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.apache.hertzbeat.alert.calculate;
|
||||
|
||||
import static org.apache.hertzbeat.common.constants.CommonConstants.ALERT_STATUS_CODE_NOT_REACH;
|
||||
import static org.apache.hertzbeat.common.constants.CommonConstants.ALERT_STATUS_CODE_PENDING;
|
||||
import static org.apache.hertzbeat.common.constants.CommonConstants.ALERT_STATUS_CODE_SOLVED;
|
||||
import static org.apache.hertzbeat.common.constants.CommonConstants.TAG_CODE;
|
||||
import static org.apache.hertzbeat.common.constants.CommonConstants.TAG_METRIC;
|
||||
import static org.apache.hertzbeat.common.constants.CommonConstants.TAG_METRICS;
|
||||
import static org.apache.hertzbeat.common.constants.CommonConstants.TAG_MONITOR_APP;
|
||||
import static org.apache.hertzbeat.common.constants.CommonConstants.TAG_MONITOR_ID;
|
||||
import static org.apache.hertzbeat.common.constants.CommonConstants.TAG_MONITOR_NAME;
|
||||
import jakarta.persistence.criteria.Predicate;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.ResourceBundle;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.stream.Collectors;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.jexl3.JexlException;
|
||||
import org.apache.commons.jexl3.JexlExpression;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.hertzbeat.alert.AlerterWorkerPool;
|
||||
import org.apache.hertzbeat.alert.dao.AlertMonitorDao;
|
||||
import org.apache.hertzbeat.alert.reduce.AlarmCommonReduce;
|
||||
import org.apache.hertzbeat.alert.service.AlertDefineService;
|
||||
import org.apache.hertzbeat.alert.service.AlertService;
|
||||
import org.apache.hertzbeat.alert.util.AlertTemplateUtil;
|
||||
import org.apache.hertzbeat.common.constants.CommonConstants;
|
||||
import org.apache.hertzbeat.common.entity.alerter.Alert;
|
||||
import org.apache.hertzbeat.common.entity.alerter.AlertDefine;
|
||||
import org.apache.hertzbeat.common.entity.manager.Monitor;
|
||||
import org.apache.hertzbeat.common.entity.manager.TagItem;
|
||||
import org.apache.hertzbeat.common.entity.message.CollectRep;
|
||||
import org.apache.hertzbeat.common.queue.CommonDataQueue;
|
||||
import org.apache.hertzbeat.common.support.event.MonitorDeletedEvent;
|
||||
import org.apache.hertzbeat.common.support.event.SystemConfigChangeEvent;
|
||||
import org.apache.hertzbeat.common.util.CommonUtil;
|
||||
import org.apache.hertzbeat.common.util.JexlExpressionRunner;
|
||||
import org.apache.hertzbeat.common.util.ResourceBundleUtil;
|
||||
import org.springframework.context.event.EventListener;
|
||||
import org.springframework.data.jpa.domain.Specification;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
|
||||
/**
|
||||
* Calculate alarms based on the alarm definition rules and collected data
|
||||
*/
|
||||
@Component
|
||||
@Slf4j
|
||||
public class CalculateAlarm {
|
||||
|
||||
private static final String SYSTEM_VALUE_ROW_COUNT = "system_value_row_count";
|
||||
|
||||
private static final int CALCULATE_THREADS = 3;
|
||||
|
||||
/**
|
||||
* The alarm in the process is triggered
|
||||
* key - monitorId+alertDefineId+tags | The alarm is a common threshold alarm
|
||||
* key - monitorId | Indicates the monitoring status availability reachability alarm
|
||||
*/
|
||||
private final Map<String, Alert> triggeredAlertMap;
|
||||
/**
|
||||
* The not recover alert
|
||||
* key - monitorId + alertDefineId + tags
|
||||
*/
|
||||
private final Map<String, Alert> notRecoveredAlertMap;
|
||||
private final AlerterWorkerPool workerPool;
|
||||
private final CommonDataQueue dataQueue;
|
||||
private final AlertDefineService alertDefineService;
|
||||
private final AlarmCommonReduce alarmCommonReduce;
|
||||
private ResourceBundle bundle;
|
||||
private final AlertService alertService;
|
||||
|
||||
public CalculateAlarm(AlerterWorkerPool workerPool, CommonDataQueue dataQueue,
|
||||
AlertDefineService alertDefineService, AlertMonitorDao monitorDao,
|
||||
AlarmCommonReduce alarmCommonReduce, AlertService alertService) {
|
||||
this.workerPool = workerPool;
|
||||
this.dataQueue = dataQueue;
|
||||
this.alarmCommonReduce = alarmCommonReduce;
|
||||
this.alertDefineService = alertDefineService;
|
||||
this.alertService = alertService;
|
||||
this.bundle = ResourceBundleUtil.getBundle("alerter");
|
||||
this.triggeredAlertMap = new ConcurrentHashMap<>(16);
|
||||
this.notRecoveredAlertMap = new ConcurrentHashMap<>(16);
|
||||
// Initialize stateAlertMap
|
||||
List<Monitor> monitors = monitorDao.findMonitorsByStatus(CommonConstants.MONITOR_DOWN_CODE);
|
||||
if (monitors != null) {
|
||||
for (Monitor monitor : monitors) {
|
||||
HashMap<String, String> tags = new HashMap<>(8);
|
||||
tags.put(TAG_MONITOR_ID, String.valueOf(monitor.getId()));
|
||||
tags.put(TAG_MONITOR_NAME, monitor.getName());
|
||||
tags.put(TAG_MONITOR_APP, monitor.getApp());
|
||||
this.notRecoveredAlertMap.put(monitor.getId() + CommonConstants.AVAILABILITY,
|
||||
Alert.builder().tags(tags).target(CommonConstants.AVAILABILITY).status(ALERT_STATUS_CODE_PENDING).build());
|
||||
}
|
||||
}
|
||||
startCalculate();
|
||||
}
|
||||
|
||||
private void startCalculate() {
|
||||
Runnable runnable = () -> {
|
||||
while (!Thread.currentThread().isInterrupted()) {
|
||||
try {
|
||||
CollectRep.MetricsData metricsData = dataQueue.pollMetricsDataToAlerter();
|
||||
if (metricsData != null) {
|
||||
calculate(metricsData);
|
||||
}
|
||||
} catch (InterruptedException ignored) {
|
||||
Thread.currentThread().interrupt();
|
||||
} catch (Exception e) {
|
||||
log.error("calculate alarm error: {}.", e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
};
|
||||
for (int i = 0; i < CALCULATE_THREADS; i++) {
|
||||
workerPool.executeJob(runnable);
|
||||
}
|
||||
}
|
||||
|
||||
private void calculate(CollectRep.MetricsData metricsData) {
|
||||
long currentTimeMilli = System.currentTimeMillis();
|
||||
long monitorId = metricsData.getId();
|
||||
String app = metricsData.getApp();
|
||||
if (app.startsWith(CommonConstants.PROMETHEUS_APP_PREFIX)) {
|
||||
app = CommonConstants.PROMETHEUS;
|
||||
}
|
||||
String metrics = metricsData.getMetrics();
|
||||
// If the metrics whose scheduling priority is 0 has the status of collecting response data UN_REACHABLE/UN_CONNECTABLE,
|
||||
// the highest severity alarm is generated to monitor the status change
|
||||
if (metricsData.getPriority() == 0) {
|
||||
handlerAvailableMetrics(monitorId, app, metricsData);
|
||||
}
|
||||
// Query the alarm definitions associated with the metrics of the monitoring type
|
||||
// field - define[]
|
||||
Map<String, List<AlertDefine>> defineMap = alertDefineService.getMonitorBindAlertDefines(monitorId, app, metrics);
|
||||
if (defineMap.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
List<CollectRep.Field> fields = metricsData.getFieldsList();
|
||||
Map<String, Object> fieldValueMap = new HashMap<>(8);
|
||||
int valueRowCount = metricsData.getValuesCount();
|
||||
for (Map.Entry<String, List<AlertDefine>> entry : defineMap.entrySet()) {
|
||||
List<AlertDefine> defines = entry.getValue();
|
||||
for (AlertDefine define : defines) {
|
||||
final String expr = define.getExpr();
|
||||
if (StringUtils.isBlank(expr)) {
|
||||
continue;
|
||||
}
|
||||
if (expr.contains(SYSTEM_VALUE_ROW_COUNT) && metricsData.getValuesCount() == 0) {
|
||||
fieldValueMap.put(SYSTEM_VALUE_ROW_COUNT, valueRowCount);
|
||||
try {
|
||||
boolean match = execAlertExpression(fieldValueMap, expr);
|
||||
try {
|
||||
if (match) {
|
||||
// If the threshold rule matches, the number of times the threshold has been triggered is determined and an alarm is triggered
|
||||
afterThresholdRuleMatch(currentTimeMilli, monitorId, app, metrics, "", fieldValueMap, define);
|
||||
// if the threshold is triggered, ignore other data rows
|
||||
continue;
|
||||
} else {
|
||||
String alarmKey = String.valueOf(monitorId) + define.getId();
|
||||
triggeredAlertMap.remove(alarmKey);
|
||||
if (define.isRecoverNotice()) {
|
||||
handleRecoveredAlert(currentTimeMilli, define, expr, alarmKey);
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.error(e.getMessage(), e);
|
||||
}
|
||||
} catch (Exception ignored) {}
|
||||
}
|
||||
for (CollectRep.ValueRow valueRow : metricsData.getValuesList()) {
|
||||
|
||||
if (CollectionUtils.isEmpty(valueRow.getColumnsList())) {
|
||||
continue;
|
||||
}
|
||||
fieldValueMap.clear();
|
||||
fieldValueMap.put(SYSTEM_VALUE_ROW_COUNT, valueRowCount);
|
||||
StringBuilder tagBuilder = new StringBuilder();
|
||||
for (int index = 0; index < valueRow.getColumnsList().size(); index++) {
|
||||
String valueStr = valueRow.getColumns(index);
|
||||
if (CommonConstants.NULL_VALUE.equals(valueStr)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
final CollectRep.Field field = fields.get(index);
|
||||
final int fieldType = field.getType();
|
||||
|
||||
if (fieldType == CommonConstants.TYPE_NUMBER) {
|
||||
final Double doubleValue;
|
||||
if ((doubleValue = CommonUtil.parseStrDouble(valueStr)) != null) {
|
||||
fieldValueMap.put(field.getName(), doubleValue);
|
||||
}
|
||||
} else if (fieldType == CommonConstants.TYPE_TIME) {
|
||||
final Integer integerValue;
|
||||
if ((integerValue = CommonUtil.parseStrInteger(valueStr)) != null) {
|
||||
fieldValueMap.put(field.getName(), integerValue);
|
||||
}
|
||||
} else {
|
||||
if (StringUtils.isNotEmpty(valueStr)) {
|
||||
fieldValueMap.put(field.getName(), valueStr);
|
||||
}
|
||||
}
|
||||
|
||||
if (field.getLabel()) {
|
||||
tagBuilder.append("-").append(valueStr);
|
||||
}
|
||||
}
|
||||
try {
|
||||
boolean match = execAlertExpression(fieldValueMap, expr);
|
||||
try {
|
||||
if (match) {
|
||||
// If the threshold rule matches, the number of times the threshold has been triggered is determined and an alarm is triggered
|
||||
afterThresholdRuleMatch(currentTimeMilli, monitorId, app, metrics, tagBuilder.toString(), fieldValueMap, define);
|
||||
} else {
|
||||
String alarmKey = String.valueOf(monitorId) + define.getId() + tagBuilder;
|
||||
triggeredAlertMap.remove(alarmKey);
|
||||
if (define.isRecoverNotice()) {
|
||||
handleRecoveredAlert(currentTimeMilli, define, expr, alarmKey);
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.error(e.getMessage(), e);
|
||||
}
|
||||
} catch (Exception ignored) {}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void handleRecoveredAlert(long currentTimeMilli, AlertDefine define, String expr, String alarmKey) {
|
||||
Alert notResolvedAlert = notRecoveredAlertMap.remove(alarmKey);
|
||||
if (notResolvedAlert != null) {
|
||||
// Sending an alarm Restore
|
||||
Map<String, String> tags = notResolvedAlert.getTags();
|
||||
String content = this.bundle.getString("alerter.alarm.recover") + " : " + expr;
|
||||
Alert resumeAlert = Alert.builder()
|
||||
.tags(tags)
|
||||
.target(define.getApp() + "." + define.getMetric() + "." + define.getField())
|
||||
.content(content)
|
||||
.priority(CommonConstants.ALERT_PRIORITY_CODE_WARNING)
|
||||
.status(CommonConstants.ALERT_STATUS_CODE_RESTORED)
|
||||
.firstAlarmTime(currentTimeMilli)
|
||||
.lastAlarmTime(notResolvedAlert.getLastAlarmTime())
|
||||
.triggerTimes(1)
|
||||
.build();
|
||||
alarmCommonReduce.reduceAndSendAlarm(resumeAlert);
|
||||
}
|
||||
}
|
||||
|
||||
private void afterThresholdRuleMatch(long currentTimeMilli, long monitorId, String app, String metrics, String tagStr,
|
||||
Map<String, Object> fieldValueMap, AlertDefine define) {
|
||||
String alarmKey = String.valueOf(monitorId) + define.getId() + tagStr;
|
||||
Alert triggeredAlert = triggeredAlertMap.get(alarmKey);
|
||||
if (triggeredAlert != null) {
|
||||
int times = triggeredAlert.getTriggerTimes() + 1;
|
||||
triggeredAlert.setTriggerTimes(times);
|
||||
triggeredAlert.setFirstAlarmTime(currentTimeMilli);
|
||||
triggeredAlert.setLastAlarmTime(currentTimeMilli);
|
||||
int defineTimes = define.getTimes() == null ? 1 : define.getTimes();
|
||||
if (times >= defineTimes) {
|
||||
triggeredAlert.setStatus(ALERT_STATUS_CODE_PENDING);
|
||||
triggeredAlertMap.remove(alarmKey);
|
||||
notRecoveredAlertMap.put(alarmKey, triggeredAlert);
|
||||
alarmCommonReduce.reduceAndSendAlarm(triggeredAlert.clone());
|
||||
}
|
||||
} else {
|
||||
fieldValueMap.put(TAG_MONITOR_APP, app);
|
||||
fieldValueMap.put(TAG_METRICS, metrics);
|
||||
fieldValueMap.put(TAG_METRIC, define.getField());
|
||||
Map<String, String> tags = new HashMap<>(8);
|
||||
tags.put(TAG_MONITOR_ID, String.valueOf(monitorId));
|
||||
tags.put(TAG_MONITOR_APP, app);
|
||||
tags.put(CommonConstants.TAG_THRESHOLD_ID, String.valueOf(define.getId()));
|
||||
if (!CollectionUtils.isEmpty(define.getTags())) {
|
||||
for (TagItem tagItem : define.getTags()) {
|
||||
fieldValueMap.put(tagItem.getName(), tagItem.getValue());
|
||||
tags.put(tagItem.getName(), tagItem.getValue());
|
||||
}
|
||||
}
|
||||
Alert alert = Alert.builder()
|
||||
.tags(tags)
|
||||
.priority(define.getPriority())
|
||||
.status(ALERT_STATUS_CODE_NOT_REACH)
|
||||
.target(app + "." + metrics + "." + define.getField())
|
||||
.triggerTimes(1)
|
||||
.firstAlarmTime(currentTimeMilli)
|
||||
.lastAlarmTime(currentTimeMilli)
|
||||
// Keyword matching and substitution in the template
|
||||
.content(AlertTemplateUtil.render(define.getTemplate(), fieldValueMap))
|
||||
.build();
|
||||
int defineTimes = define.getTimes() == null ? 1 : define.getTimes();
|
||||
if (1 >= defineTimes) {
|
||||
alert.setStatus(ALERT_STATUS_CODE_PENDING);
|
||||
notRecoveredAlertMap.put(alarmKey, alert);
|
||||
alarmCommonReduce.reduceAndSendAlarm(alert.clone());
|
||||
} else {
|
||||
triggeredAlertMap.put(alarmKey, alert);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private boolean execAlertExpression(Map<String, Object> fieldValueMap, String expr) {
|
||||
Boolean match;
|
||||
JexlExpression expression;
|
||||
try {
|
||||
expression = JexlExpressionRunner.compile(expr);
|
||||
} catch (JexlException jexlException) {
|
||||
log.error("Alarm Rule: {} Compile Error: {}.", expr, jexlException.getMessage());
|
||||
throw jexlException;
|
||||
} catch (Exception e) {
|
||||
log.error("Alarm Rule: {} Unknown Error: {}.", expr, e.getMessage());
|
||||
throw e;
|
||||
}
|
||||
|
||||
try {
|
||||
match = (Boolean) JexlExpressionRunner.evaluate(expression, fieldValueMap);
|
||||
} catch (JexlException jexlException) {
|
||||
log.error("Alarm Rule: {} Run Error: {}.", expr, jexlException.getMessage());
|
||||
throw jexlException;
|
||||
} catch (Exception e) {
|
||||
log.error("Alarm Rule: {} Unknown Error: {}.", expr, e.getMessage());
|
||||
throw e;
|
||||
}
|
||||
return match != null && match;
|
||||
}
|
||||
|
||||
private void handlerAvailableMetrics(long monitorId, String app, CollectRep.MetricsData metricsData) {
|
||||
if (metricsData.getCode() == CollectRep.Code.TIMEOUT) {
|
||||
return;
|
||||
}
|
||||
// TODO CACHE getMonitorBindAlertAvaDefine
|
||||
AlertDefine avaAlertDefine = alertDefineService.getMonitorBindAlertAvaDefine(monitorId, app, CommonConstants.AVAILABILITY);
|
||||
if (avaAlertDefine == null) {
|
||||
return;
|
||||
}
|
||||
long currentTimeMill = System.currentTimeMillis();
|
||||
if (metricsData.getCode() != CollectRep.Code.SUCCESS) {
|
||||
Alert preAlert = triggeredAlertMap.get(String.valueOf(monitorId));
|
||||
Map<String, String> tags = new HashMap<>(6);
|
||||
tags.put(TAG_MONITOR_ID, String.valueOf(monitorId));
|
||||
tags.put(TAG_MONITOR_APP, app);
|
||||
tags.put(CommonConstants.TAG_THRESHOLD_ID, String.valueOf(avaAlertDefine.getId()));
|
||||
tags.put(TAG_METRICS, CommonConstants.AVAILABILITY);
|
||||
tags.put(TAG_CODE, metricsData.getCode().name());
|
||||
Map<String, Object> valueMap = tags.entrySet().stream()
|
||||
.collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
|
||||
|
||||
if (!CollectionUtils.isEmpty(avaAlertDefine.getTags())) {
|
||||
for (TagItem tagItem : avaAlertDefine.getTags()) {
|
||||
valueMap.put(tagItem.getName(), tagItem.getValue());
|
||||
tags.put(tagItem.getName(), tagItem.getValue());
|
||||
}
|
||||
}
|
||||
if (preAlert == null) {
|
||||
Alert.AlertBuilder alertBuilder = Alert.builder()
|
||||
.tags(tags)
|
||||
.priority(avaAlertDefine.getPriority())
|
||||
.status(ALERT_STATUS_CODE_NOT_REACH)
|
||||
.target(CommonConstants.AVAILABILITY)
|
||||
.content(AlertTemplateUtil.render(avaAlertDefine.getTemplate(), valueMap))
|
||||
.firstAlarmTime(currentTimeMill)
|
||||
.lastAlarmTime(currentTimeMill)
|
||||
.triggerTimes(1);
|
||||
if (avaAlertDefine.getTimes() == null || avaAlertDefine.getTimes() <= 1) {
|
||||
String notResolvedAlertKey = monitorId + CommonConstants.AVAILABILITY;
|
||||
alertBuilder.status(ALERT_STATUS_CODE_PENDING);
|
||||
notRecoveredAlertMap.put(notResolvedAlertKey, alertBuilder.build());
|
||||
alarmCommonReduce.reduceAndSendAlarm(alertBuilder.build());
|
||||
} else {
|
||||
triggeredAlertMap.put(String.valueOf(monitorId), alertBuilder.build());
|
||||
}
|
||||
} else {
|
||||
int times = preAlert.getTriggerTimes() + 1;
|
||||
preAlert.setTriggerTimes(times);
|
||||
preAlert.setFirstAlarmTime(currentTimeMill);
|
||||
preAlert.setLastAlarmTime(currentTimeMill);
|
||||
int defineTimes = avaAlertDefine.getTimes() == null ? 1 : avaAlertDefine.getTimes();
|
||||
if (times >= defineTimes) {
|
||||
preAlert.setStatus(ALERT_STATUS_CODE_PENDING);
|
||||
String notResolvedAlertKey = monitorId + CommonConstants.AVAILABILITY;
|
||||
notRecoveredAlertMap.put(notResolvedAlertKey, preAlert.clone());
|
||||
alarmCommonReduce.reduceAndSendAlarm(preAlert.clone());
|
||||
triggeredAlertMap.remove(String.valueOf(monitorId));
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// Check whether an availability or unreachable alarm is generated before the association monitoring
|
||||
// and send a clear alarm to clear the monitoring status
|
||||
triggeredAlertMap.remove(String.valueOf(monitorId));
|
||||
String notResolvedAlertKey = monitorId + CommonConstants.AVAILABILITY;
|
||||
Alert notResolvedAlert = notRecoveredAlertMap.remove(notResolvedAlertKey);
|
||||
if (notResolvedAlert != null) {
|
||||
// Sending an alarm Restore
|
||||
Map<String, String> tags = notResolvedAlert.getTags();
|
||||
if (!avaAlertDefine.isRecoverNotice()) {
|
||||
tags.put(CommonConstants.IGNORE, CommonConstants.IGNORE);
|
||||
}
|
||||
String content = this.bundle.getString("alerter.availability.recover");
|
||||
Alert resumeAlert = Alert.builder()
|
||||
.tags(tags)
|
||||
.target(CommonConstants.AVAILABILITY)
|
||||
.content(content)
|
||||
.priority(CommonConstants.ALERT_PRIORITY_CODE_WARNING)
|
||||
.status(CommonConstants.ALERT_STATUS_CODE_RESTORED)
|
||||
.firstAlarmTime(currentTimeMill)
|
||||
.lastAlarmTime(notResolvedAlert.getLastAlarmTime())
|
||||
.triggerTimes(1)
|
||||
.build();
|
||||
alarmCommonReduce.reduceAndSendAlarm(resumeAlert);
|
||||
Runnable updateStatusJob = () -> {
|
||||
// todo update pre all type alarm status
|
||||
updateAvailabilityAlertStatus(monitorId, resumeAlert);
|
||||
};
|
||||
workerPool.executeJob(updateStatusJob);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void updateAvailabilityAlertStatus(long monitorId, Alert restoreAlert) {
|
||||
List<Alert> availabilityAlerts = queryAvailabilityAlerts(monitorId, restoreAlert);
|
||||
availabilityAlerts.stream().parallel().forEach(alert -> {
|
||||
log.info("updating alert status solved id: {}", alert.getId());
|
||||
alertService.editAlertStatus(ALERT_STATUS_CODE_SOLVED, List.of(alert.getId()));
|
||||
});
|
||||
}
|
||||
|
||||
private List<Alert> queryAvailabilityAlerts(long monitorId, Alert restoreAlert) {
|
||||
//create query condition
|
||||
Specification<Alert> specification = (root, query, criteriaBuilder) -> {
|
||||
List<Predicate> andList = new ArrayList<>();
|
||||
|
||||
Predicate predicateTags = criteriaBuilder.like(root.get("tags").as(String.class), "%" + monitorId + "%");
|
||||
andList.add(predicateTags);
|
||||
|
||||
Predicate predicatePriority = criteriaBuilder.equal(root.get("priority"), CommonConstants.ALERT_PRIORITY_CODE_EMERGENCY);
|
||||
andList.add(predicatePriority);
|
||||
|
||||
Predicate predicateStatus = criteriaBuilder.equal(root.get("status"), ALERT_STATUS_CODE_PENDING);
|
||||
andList.add(predicateStatus);
|
||||
|
||||
Predicate predicateAlertTime = criteriaBuilder.lessThanOrEqualTo(root.get("lastAlarmTime"), restoreAlert.getLastAlarmTime());
|
||||
andList.add(predicateAlertTime);
|
||||
|
||||
Predicate[] predicates = new Predicate[andList.size()];
|
||||
return criteriaBuilder.and(andList.toArray(predicates));
|
||||
};
|
||||
|
||||
//query results
|
||||
return alertService.getAlerts(specification);
|
||||
}
|
||||
|
||||
@EventListener(SystemConfigChangeEvent.class)
|
||||
public void onSystemConfigChangeEvent(SystemConfigChangeEvent event) {
|
||||
log.info("calculate alarm receive system config change event: {}.", event.getSource());
|
||||
this.bundle = ResourceBundleUtil.getBundle("alerter");
|
||||
}
|
||||
|
||||
@EventListener(MonitorDeletedEvent.class)
|
||||
public void onMonitorDeletedEvent(MonitorDeletedEvent event) {
|
||||
log.info("calculate alarm receive monitor {} has been deleted.", event.getMonitorId());
|
||||
this.triggeredAlertMap.remove(String.valueOf(event.getMonitorId()));
|
||||
}
|
||||
|
||||
}
|
||||
+20
-20
@@ -24,8 +24,8 @@ 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.AlertGroupConvergeService;
|
||||
import org.apache.hertzbeat.common.entity.alerter.AlertGroupConverge;
|
||||
import org.apache.hertzbeat.alert.service.AlertConvergeService;
|
||||
import org.apache.hertzbeat.common.entity.alerter.AlertConverge;
|
||||
import org.apache.hertzbeat.common.entity.dto.Message;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
@@ -42,38 +42,38 @@ import org.springframework.web.bind.annotation.RestController;
|
||||
*/
|
||||
@Tag(name = "Alert Converge API")
|
||||
@RestController
|
||||
@RequestMapping(path = "/api/alert/group", produces = {APPLICATION_JSON_VALUE})
|
||||
public class AlertGroupConvergeController {
|
||||
@RequestMapping(path = "/api/alert/converge", produces = {APPLICATION_JSON_VALUE})
|
||||
public class AlertConvergeController {
|
||||
|
||||
@Autowired
|
||||
private AlertGroupConvergeService alertGroupConvergeService;
|
||||
private AlertConvergeService alertConvergeService;
|
||||
|
||||
@PostMapping
|
||||
@Operation(summary = "New Alarm Group Converge", description = "Added an alarm Group Converge")
|
||||
public ResponseEntity<Message<Void>> addNewAlertGroupConverge(@Valid @RequestBody AlertGroupConverge alertGroupConverge) {
|
||||
alertGroupConvergeService.validate(alertGroupConverge, false);
|
||||
alertGroupConvergeService.addAlertGroupConverge(alertGroupConverge);
|
||||
@Operation(summary = "New Alarm Converge", description = "Added an alarm Converge")
|
||||
public ResponseEntity<Message<Void>> addNewAlertConverge(@Valid @RequestBody AlertConverge alertConverge) {
|
||||
alertConvergeService.validate(alertConverge, false);
|
||||
alertConvergeService.addAlertConverge(alertConverge);
|
||||
return ResponseEntity.ok(Message.success("Add success"));
|
||||
}
|
||||
|
||||
@PutMapping
|
||||
@Operation(summary = "Modifying an Alarm Group Converge", description = "Modify an existing alarm Group Converge")
|
||||
public ResponseEntity<Message<Void>> modifyAlertGroupConverge(@Valid @RequestBody AlertGroupConverge alertGroupConverge) {
|
||||
alertGroupConvergeService.validate(alertGroupConverge, true);
|
||||
alertGroupConvergeService.modifyAlertGroupConverge(alertGroupConverge);
|
||||
@Operation(summary = "Modifying an Alarm Converge", description = "Modify an existing alarm Converge")
|
||||
public ResponseEntity<Message<Void>> modifyAlertConverge(@Valid @RequestBody AlertConverge alertConverge) {
|
||||
alertConvergeService.validate(alertConverge, true);
|
||||
alertConvergeService.modifyAlertConverge(alertConverge);
|
||||
return ResponseEntity.ok(Message.success("Modify success"));
|
||||
}
|
||||
|
||||
@GetMapping(path = "/{id}")
|
||||
@Operation(summary = "Querying Alarm Group Converge",
|
||||
description = "You can obtain alarm Group Converge information based on the alarm Converge ID")
|
||||
public ResponseEntity<Message<AlertGroupConverge>> getAlertGroupConverge(
|
||||
@Operation(summary = "Querying Alarm Converge",
|
||||
description = "You can obtain alarm Converge information based on the alarm Converge ID")
|
||||
public ResponseEntity<Message<AlertConverge>> getAlertConverge(
|
||||
@Parameter(description = "Alarm Converge ID", example = "6565463543") @PathVariable("id") long id) {
|
||||
AlertGroupConverge alertGroupConverge = alertGroupConvergeService.getAlertGroupConverge(id);
|
||||
AlertConverge alertConverge = alertConvergeService.getAlertConverge(id);
|
||||
|
||||
return Objects.isNull(alertGroupConverge)
|
||||
? ResponseEntity.ok(Message.fail(MONITOR_NOT_EXIST_CODE, "Alert Group Converge not exist."))
|
||||
: ResponseEntity.ok(Message.success(alertGroupConverge));
|
||||
return Objects.isNull(alertConverge)
|
||||
? ResponseEntity.ok(Message.fail(MONITOR_NOT_EXIST_CODE, "AlertConverge not exist."))
|
||||
: ResponseEntity.ok(Message.success(alertConverge));
|
||||
}
|
||||
|
||||
}
|
||||
+13
-13
@@ -23,8 +23,8 @@ import io.swagger.v3.oas.annotations.Parameter;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import org.apache.hertzbeat.alert.service.AlertGroupConvergeService;
|
||||
import org.apache.hertzbeat.common.entity.alerter.AlertGroupConverge;
|
||||
import org.apache.hertzbeat.alert.service.AlertConvergeService;
|
||||
import org.apache.hertzbeat.common.entity.alerter.AlertConverge;
|
||||
import org.apache.hertzbeat.common.entity.dto.Message;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.data.domain.Page;
|
||||
@@ -40,34 +40,34 @@ import org.springframework.web.bind.annotation.RestController;
|
||||
*/
|
||||
@Tag(name = "Alert Converge Batch API")
|
||||
@RestController
|
||||
@RequestMapping(path = "/api/alert/groups", produces = {APPLICATION_JSON_VALUE})
|
||||
public class AlertGroupConvergesController {
|
||||
@RequestMapping(path = "/api/alert/converges", produces = {APPLICATION_JSON_VALUE})
|
||||
public class AlertConvergesController {
|
||||
|
||||
@Autowired
|
||||
private AlertGroupConvergeService alertGroupConvergeService;
|
||||
private AlertConvergeService alertConvergeService;
|
||||
|
||||
@GetMapping
|
||||
@Operation(summary = "Query the alarm group converge list",
|
||||
description = "You can obtain the list of alarm group group converge by querying filter items")
|
||||
public ResponseEntity<Message<Page<AlertGroupConverge>>> getAlertGroupConverges(
|
||||
@Operation(summary = "Query the alarm converge list",
|
||||
description = "You can obtain the list of alarm converge by querying filter items")
|
||||
public ResponseEntity<Message<Page<AlertConverge>>> getAlertConverges(
|
||||
@Parameter(description = "Alarm Converge ID", example = "6565463543") @RequestParam(required = false) List<Long> ids,
|
||||
@Parameter(description = "Search Name", example = "x") @RequestParam(required = false) String search,
|
||||
@Parameter(description = "Sort field, default id", example = "id") @RequestParam(defaultValue = "id") String sort,
|
||||
@Parameter(description = "Sort mode: asc: ascending, desc: descending", example = "desc") @RequestParam(defaultValue = "desc") String order,
|
||||
@Parameter(description = "List current page", example = "0") @RequestParam(defaultValue = "0") int pageIndex,
|
||||
@Parameter(description = "Number of list pages", example = "8") @RequestParam(defaultValue = "8") int pageSize) {
|
||||
Page<AlertGroupConverge> alertGroupConvergePage = alertGroupConvergeService.getAlertGroupConverges(ids, search, sort, order, pageIndex, pageSize);
|
||||
return ResponseEntity.ok(Message.success(alertGroupConvergePage));
|
||||
Page<AlertConverge> alertConvergePage = alertConvergeService.getAlertConverges(ids, search, sort, order, pageIndex, pageSize);
|
||||
return ResponseEntity.ok(Message.success(alertConvergePage));
|
||||
}
|
||||
|
||||
@DeleteMapping
|
||||
@Operation(summary = "Delete alarm group converge in batches",
|
||||
description = "Delete alarm group converge in batches based on the alarm group converge ID list")
|
||||
@Operation(summary = "Delete alarm converge in batches",
|
||||
description = "Delete alarm converge in batches based on the alarm converge ID list")
|
||||
public ResponseEntity<Message<Void>> deleteAlertDefines(
|
||||
@Parameter(description = "Alarm Converge IDs", example = "6565463543") @RequestParam(required = false) List<Long> ids
|
||||
) {
|
||||
if (ids != null && !ids.isEmpty()) {
|
||||
alertGroupConvergeService.deleteAlertGroupConverges(new HashSet<>(ids));
|
||||
alertConvergeService.deleteAlertConverges(new HashSet<>(ids));
|
||||
}
|
||||
return ResponseEntity.ok(Message.success());
|
||||
}
|
||||
+23
@@ -23,9 +23,12 @@ import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.Parameter;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import jakarta.validation.Valid;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.stream.Collectors;
|
||||
import org.apache.hertzbeat.alert.service.AlertDefineService;
|
||||
import org.apache.hertzbeat.common.entity.alerter.AlertDefine;
|
||||
import org.apache.hertzbeat.common.entity.alerter.AlertDefineMonitorBind;
|
||||
import org.apache.hertzbeat.common.entity.dto.Message;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
@@ -90,4 +93,24 @@ public class AlertDefineController {
|
||||
return ResponseEntity.ok(Message.success("Delete success"));
|
||||
}
|
||||
|
||||
@PostMapping(path = "/{alertDefineId}/monitors")
|
||||
@Operation(summary = "Application alarm definition is associated with monitoring",
|
||||
description = "Applies the association between specified alarm definitions and monitoring")
|
||||
public ResponseEntity<Message<Void>> applyAlertDefineMonitorsBind(
|
||||
@Parameter(description = "Alarm Definition ID", example = "6565463543") @PathVariable("alertDefineId") long alertDefineId,
|
||||
@RequestBody List<AlertDefineMonitorBind> alertDefineMonitorBinds) {
|
||||
alertDefineService.applyBindAlertDefineMonitors(alertDefineId, alertDefineMonitorBinds);
|
||||
return ResponseEntity.ok(Message.success("Apply success"));
|
||||
}
|
||||
|
||||
@GetMapping(path = "/{alertDefineId}/monitors")
|
||||
@Operation(summary = "Application alarm definition is associated with monitoring",
|
||||
description = "Applies the association between specified alarm definitions and monitoring")
|
||||
public ResponseEntity<Message<List<AlertDefineMonitorBind>>> getAlertDefineMonitorsBind(
|
||||
@Parameter(description = "Alarm Definition ID", example = "6565463543") @PathVariable("alertDefineId") long alertDefineId) {
|
||||
List<AlertDefineMonitorBind> defineBinds = alertDefineService.getBindAlertDefineMonitors(alertDefineId);
|
||||
defineBinds = defineBinds.stream().filter(item -> item.getMonitor() != null).collect(Collectors.toList());
|
||||
return ResponseEntity.ok(Message.success(defineBinds));
|
||||
}
|
||||
|
||||
}
|
||||
+2
-1
@@ -55,11 +55,12 @@ public class AlertDefinesController {
|
||||
public ResponseEntity<Message<Page<AlertDefine>>> getAlertDefines(
|
||||
@Parameter(description = "Alarm Definition ID", example = "6565463543") @RequestParam(required = false) List<Long> ids,
|
||||
@Parameter(description = "Search-Target Expr Template", example = "x") @RequestParam(required = false) String search,
|
||||
@Parameter(description = "Alarm Definition Severity", example = "6565463543") @RequestParam(required = false) Byte priority,
|
||||
@Parameter(description = "Sort field, default id", example = "id") @RequestParam(defaultValue = "id") String sort,
|
||||
@Parameter(description = "Sort mode: asc: ascending, desc: descending", example = "desc") @RequestParam(defaultValue = "desc") String order,
|
||||
@Parameter(description = "List current page", example = "0") @RequestParam(defaultValue = "0") int pageIndex,
|
||||
@Parameter(description = "Number of list pages", example = "8") @RequestParam(defaultValue = "8") int pageSize) {
|
||||
Page<AlertDefine> alertDefinePage = alertDefineService.getAlertDefines(ids, search, sort, order, pageIndex, pageSize);
|
||||
Page<AlertDefine> alertDefinePage = alertDefineService.getAlertDefines(ids, search, priority, sort, order, pageIndex, pageSize);
|
||||
return ResponseEntity.ok(Message.success(alertDefinePage));
|
||||
}
|
||||
|
||||
+63
@@ -0,0 +1,63 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.apache.hertzbeat.alert.controller;
|
||||
|
||||
import static org.springframework.http.MediaType.APPLICATION_JSON_VALUE;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.hertzbeat.alert.dto.GeneralCloudAlertReport;
|
||||
import org.apache.hertzbeat.alert.service.AlertService;
|
||||
import org.apache.hertzbeat.common.entity.dto.Message;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.web.bind.annotation.PathVariable;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
/**
|
||||
* Extern Alarm Manage API
|
||||
*/
|
||||
@Tag(name = "Extern Alarm Manage API")
|
||||
@RestController
|
||||
@RequestMapping(path = "/api/alerts/report", produces = {APPLICATION_JSON_VALUE})
|
||||
@Slf4j
|
||||
public class AlertReportController {
|
||||
|
||||
@Autowired
|
||||
private AlertService alertService;
|
||||
|
||||
@PostMapping("/{cloud}")
|
||||
@Operation(summary = "Interface for reporting external alarm information of cloud service")
|
||||
public ResponseEntity<Message<Void>> addNewAlertReportFromCloud(@PathVariable("cloud") String cloudServiceName,
|
||||
@RequestBody String alertReport) {
|
||||
alertService.addNewAlertReportFromCloud(cloudServiceName, alertReport);
|
||||
return ResponseEntity.ok(Message.success("Add report success"));
|
||||
}
|
||||
|
||||
@PostMapping
|
||||
@Operation(summary = "Interface for reporting external and general alarm information",
|
||||
description = "The interface is used to report external and general alarm information")
|
||||
public ResponseEntity<Message<Void>> addNewAlertReport(@RequestBody GeneralCloudAlertReport alertReport) {
|
||||
alertReport.refreshAlertTime();
|
||||
alertService.addNewAlertReport(alertReport);
|
||||
return ResponseEntity.ok(Message.success("Add report success"));
|
||||
}
|
||||
}
|
||||
+25
-28
@@ -25,8 +25,7 @@ import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import org.apache.hertzbeat.alert.dto.AlertSummary;
|
||||
import org.apache.hertzbeat.alert.service.AlertService;
|
||||
import org.apache.hertzbeat.common.entity.alerter.GroupAlert;
|
||||
import org.apache.hertzbeat.common.entity.alerter.SingleAlert;
|
||||
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;
|
||||
@@ -51,49 +50,47 @@ public class AlertsController {
|
||||
private AlertService alertService;
|
||||
|
||||
@GetMapping
|
||||
@Operation(summary = "Query Alarms")
|
||||
public ResponseEntity<Message<Page<SingleAlert>>> getAlerts(
|
||||
@Parameter(description = "Alarm Status", example = "resolved") @RequestParam(required = false) String status,
|
||||
@Parameter(description = "Alarm content fuzzy query", example = "linux") @RequestParam(required = false) String search,
|
||||
@Parameter(description = "Sort field, default id", example = "name") @RequestParam(defaultValue = "gmtUpdate") String sort,
|
||||
@Operation(summary = "Get a list of alarm information based on query filter items", description = "according to the query filter items to obtain a list of alarm information")
|
||||
public ResponseEntity<Message<Page<Alert>>> getAlerts(
|
||||
@Parameter(description = "Alarm ID List", example = "6565466456") @RequestParam(required = false) List<Long> ids,
|
||||
@Parameter(description = "Alarm monitor object ID", example = "6565463543") @RequestParam(required = false) Long monitorId,
|
||||
@Parameter(description = "Alarm level", example = "6565463543") @RequestParam(required = false) Byte priority,
|
||||
@Parameter(description = "Alarm Status", example = "6565463543") @RequestParam(required = false) Byte status,
|
||||
@Parameter(description = "Alarm content fuzzy query", example = "linux") @RequestParam(required = false) String content,
|
||||
@Parameter(description = "Sort field, default id", example = "name") @RequestParam(defaultValue = "id") String sort,
|
||||
@Parameter(description = "Sort Type", example = "desc") @RequestParam(defaultValue = "desc") String order,
|
||||
@Parameter(description = "List current page", example = "0") @RequestParam(defaultValue = "0") int pageIndex,
|
||||
@Parameter(description = "Number of list pagination", example = "8") @RequestParam(defaultValue = "8") int pageSize) {
|
||||
Page<SingleAlert> alertPage = alertService.getSingleAlerts(status, search, sort, order, pageIndex, pageSize);
|
||||
Page<Alert> alertPage = alertService.getAlerts(ids, monitorId, priority, status, content, sort, order, pageIndex, pageSize);
|
||||
return ResponseEntity.ok(Message.success(alertPage));
|
||||
}
|
||||
|
||||
@GetMapping("/group")
|
||||
@Operation(summary = "Query Group Alarms")
|
||||
public ResponseEntity<Message<Page<GroupAlert>>> getGroupAlerts(
|
||||
@Parameter(description = "Alarm Status", example = "resolved") @RequestParam(required = false) String status,
|
||||
@Parameter(description = "Alarm content fuzzy query", example = "linux") @RequestParam(required = false) String search,
|
||||
@Parameter(description = "Sort field, default id", example = "name") @RequestParam(defaultValue = "gmtUpdate") String sort,
|
||||
@Parameter(description = "Sort Type", example = "desc") @RequestParam(defaultValue = "desc") String order,
|
||||
@Parameter(description = "List current page", example = "0") @RequestParam(defaultValue = "0") int pageIndex,
|
||||
@Parameter(description = "Number of list pagination", example = "8") @RequestParam(defaultValue = "8") int pageSize) {
|
||||
Page<GroupAlert> alertPage = alertService.getGroupAlerts(status, search, sort, order, pageIndex, pageSize);
|
||||
return ResponseEntity.ok(Message.success(alertPage));
|
||||
}
|
||||
|
||||
@DeleteMapping("/group")
|
||||
@Operation(summary = "Delete group alarms in batches", description = "according to the alarm ID list to delete the alarm information in batches")
|
||||
@DeleteMapping
|
||||
@Operation(summary = "Delete alarms in batches", description = "according to the alarm ID list to delete the alarm information in batches")
|
||||
public ResponseEntity<Message<Void>> deleteAlerts(
|
||||
@Parameter(description = "Alarm List ID", example = "6565463543") @RequestParam(required = false) List<Long> ids) {
|
||||
if (ids != null && !ids.isEmpty()) {
|
||||
alertService.deleteGroupAlerts(new HashSet<>(ids));
|
||||
alertService.deleteAlerts(new HashSet<>(ids));
|
||||
}
|
||||
Message<Void> message = Message.success();
|
||||
return ResponseEntity.ok(message);
|
||||
}
|
||||
|
||||
@PutMapping(path = "/group/status/{status}")
|
||||
@Operation(summary = "Batch modify alarm status, set firing or resolved", description = "Batch modify alarm status, set firing or resolved")
|
||||
@DeleteMapping("/clear")
|
||||
@Operation(summary = "Delete alarms in batches", description = "delete all alarm information")
|
||||
public ResponseEntity<Message<Void>> clearAllAlerts() {
|
||||
alertService.clearAlerts();
|
||||
Message<Void> message = Message.success();
|
||||
return ResponseEntity.ok(message);
|
||||
}
|
||||
|
||||
@PutMapping(path = "/status/{status}")
|
||||
@Operation(summary = "Batch modify alarm status, set read and unread", description = "Batch modify alarm status, set read and unread")
|
||||
public ResponseEntity<Message<Void>> applyAlertDefinesStatus(
|
||||
@Parameter(description = "Alarm status value", example = "resolved") @PathVariable String status,
|
||||
@Parameter(description = "Alarm status value", example = "0") @PathVariable Byte status,
|
||||
@Parameter(description = "Alarm List IDS", example = "6565463543") @RequestParam(required = false) List<Long> ids) {
|
||||
if (ids != null && status != null && !ids.isEmpty()) {
|
||||
alertService.editGroupAlertStatus(status, ids);
|
||||
alertService.editAlertStatus(status, ids);
|
||||
}
|
||||
Message<Void> message = Message.success();
|
||||
return ResponseEntity.ok(message);
|
||||
+6
-14
@@ -17,29 +17,21 @@
|
||||
|
||||
package org.apache.hertzbeat.alert.dao;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import org.apache.hertzbeat.common.entity.alerter.AlertInhibit;
|
||||
import org.apache.hertzbeat.common.entity.alerter.AlertConverge;
|
||||
import org.springframework.data.jpa.repository.JpaRepository;
|
||||
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
|
||||
import org.springframework.data.jpa.repository.Modifying;
|
||||
|
||||
/**
|
||||
* AlertInhibit Dao
|
||||
* AlertConverge Dao
|
||||
*/
|
||||
public interface AlertInhibitDao extends JpaRepository<AlertInhibit, Long>, JpaSpecificationExecutor<AlertInhibit> {
|
||||
public interface AlertConvergeDao extends JpaRepository<AlertConverge, Long>, JpaSpecificationExecutor<AlertConverge> {
|
||||
|
||||
/**
|
||||
* Delete alarm inhibit based on the ID list
|
||||
*
|
||||
* @param ids alert inhibit id list
|
||||
* Delete alarm converge based on the ID list
|
||||
* @param convergeIds alert converge id list
|
||||
*/
|
||||
@Modifying
|
||||
void deleteAlertInhibitsByIdIn(Set<Long> ids);
|
||||
|
||||
/**
|
||||
* Query the enable true alarm inhibit list
|
||||
* @return alarm inhibit list
|
||||
*/
|
||||
List<AlertInhibit> findAlertInhibitsByEnableIsTrue();
|
||||
void deleteAlertConvergesByIdIn(Set<Long> convergeIds);
|
||||
}
|
||||
+14
-21
@@ -17,9 +17,10 @@
|
||||
|
||||
package org.apache.hertzbeat.alert.dao;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import org.apache.hertzbeat.common.entity.alerter.GroupAlert;
|
||||
import java.util.Set;
|
||||
import org.apache.hertzbeat.alert.dto.AlertPriorityNum;
|
||||
import org.apache.hertzbeat.common.entity.alerter.Alert;
|
||||
import org.springframework.data.jpa.repository.JpaRepository;
|
||||
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
|
||||
import org.springframework.data.jpa.repository.Modifying;
|
||||
@@ -27,37 +28,29 @@ import org.springframework.data.jpa.repository.Query;
|
||||
import org.springframework.data.repository.query.Param;
|
||||
|
||||
/**
|
||||
* Group Alert Database Operations
|
||||
* Alert Database Operations
|
||||
*/
|
||||
public interface GroupAlertDao extends JpaRepository<GroupAlert, Long>, JpaSpecificationExecutor<GroupAlert> {
|
||||
|
||||
/**
|
||||
* Query alert group by groupKey
|
||||
* @param groupKey group key identifier
|
||||
* @return alert group
|
||||
*/
|
||||
GroupAlert findByGroupKey(String groupKey);
|
||||
public interface AlertDao extends JpaRepository<Alert, Long>, JpaSpecificationExecutor<Alert> {
|
||||
|
||||
/**
|
||||
* Delete alerts based on ID list
|
||||
* @param ids Alert ID List
|
||||
* @param alertIds Alert ID List
|
||||
*/
|
||||
@Modifying
|
||||
void deleteGroupAlertsByIdIn(HashSet<Long> ids);
|
||||
void deleteAlertsByIdIn(Set<Long> alertIds);
|
||||
|
||||
/**
|
||||
* Updates the alarm status based on the alarm ID-status value
|
||||
* @param status status value
|
||||
* @param ids alarm ids
|
||||
* @param ids alarm ids
|
||||
*/
|
||||
@Modifying
|
||||
@Query("update GroupAlert set status = :status where id in :ids")
|
||||
void updateGroupAlertsStatus(@Param(value = "status") String status, @Param(value = "ids") List<Long> ids);
|
||||
@Query("update Alert set status = :status where id in :ids")
|
||||
void updateAlertsStatus(@Param(value = "status") Byte status, @Param(value = "ids") List<Long> ids);
|
||||
|
||||
/**
|
||||
* find group alerts by id list
|
||||
* @param ids ids
|
||||
* @return group alerts
|
||||
* Query the number of unhandled alarms of each alarm severity
|
||||
* @return List of alerts num
|
||||
*/
|
||||
List<GroupAlert> findGroupAlertsByIdIn(HashSet<Long> ids);
|
||||
@Query("select new org.apache.hertzbeat.alert.dto.AlertPriorityNum(mo.priority, count(mo.id)) from Alert mo where mo.status = 0 group by mo.priority")
|
||||
List<AlertPriorityNum> findAlertPriorityNum();
|
||||
}
|
||||
+24
-8
@@ -18,11 +18,12 @@
|
||||
package org.apache.hertzbeat.alert.dao;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.Set;
|
||||
import org.apache.hertzbeat.common.entity.alerter.AlertDefine;
|
||||
import org.springframework.data.jpa.repository.JpaRepository;
|
||||
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
|
||||
import org.springframework.data.jpa.repository.Query;
|
||||
import org.springframework.data.repository.query.Param;
|
||||
|
||||
/**
|
||||
* AlertDefine Dao
|
||||
@@ -36,16 +37,31 @@ public interface AlertDefineDao extends JpaRepository<AlertDefine, Long>, JpaSpe
|
||||
void deleteAlertDefinesByIdIn(Set<Long> alertDefineIds);
|
||||
|
||||
/**
|
||||
* Query the alarm define by type
|
||||
* @param type alarm type
|
||||
* Query the default alarm thresholds based on the monitoring metrics type
|
||||
* @param app monitoring type
|
||||
* @param metric metrics
|
||||
* @return alarm defines
|
||||
*/
|
||||
List<AlertDefine> findAlertDefinesByTypeAndEnableTrue(String type);
|
||||
List<AlertDefine> queryAlertDefinesByAppAndMetricAndPresetTrueAndEnableTrue(String app, String metric);
|
||||
|
||||
/**
|
||||
* Query the alarm define by name
|
||||
* @param name alarm name
|
||||
* @return alarm define
|
||||
* Query app metric alert define
|
||||
* @param app app
|
||||
* @param metric metric
|
||||
* @return alert define
|
||||
*/
|
||||
Optional<AlertDefine> findAlertDefineByName(String name);
|
||||
List<AlertDefine> queryAlertDefineByAppAndMetric(String app, String metric);
|
||||
|
||||
/**
|
||||
* Query the alarm definition list associated with the monitoring ID
|
||||
* @param monitorId monitor id
|
||||
* @param app monitor type
|
||||
* @param metrics metrics
|
||||
* @return Alarm Definition List
|
||||
*/
|
||||
@Query("select define from AlertDefine define join AlertDefineMonitorBind bind on bind.alertDefineId = define.id "
|
||||
+ "where bind.monitorId = :monitorId and define.app = :app and define.metric = :metrics and define.enable = true and define.preset = false")
|
||||
List<AlertDefine> queryAlertDefinesByMonitor(@Param(value = "monitorId") Long monitorId,
|
||||
@Param(value = "app") String app,
|
||||
@Param(value = "metrics") String metrics);
|
||||
}
|
||||
+7
-8
@@ -18,8 +18,8 @@
|
||||
package org.apache.hertzbeat.alert.dao;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import org.apache.hertzbeat.common.entity.manager.Monitor;
|
||||
import org.apache.hertzbeat.common.entity.manager.Tag;
|
||||
import org.springframework.data.jpa.repository.JpaRepository;
|
||||
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
|
||||
import org.springframework.data.jpa.repository.Query;
|
||||
@@ -36,13 +36,12 @@ public interface AlertMonitorDao extends JpaRepository<Monitor, Long>, JpaSpecif
|
||||
* @return Monitor the list
|
||||
*/
|
||||
List<Monitor> findMonitorsByStatus(Byte status);
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Query the monitoring
|
||||
* @param id id
|
||||
* @return monitor
|
||||
* find monitor bind tags by monitorId
|
||||
* @param monitorId monitorId
|
||||
* @return bind tags
|
||||
*/
|
||||
@Query("select monitor from Monitor monitor where monitor.id = :id")
|
||||
Optional<Monitor> findMonitorById(@Param(value = "id") Long id);
|
||||
@Query("select tag from Tag tag join TagMonitorBind bind on bind.tagId = tag.id where bind.monitorId = :monitorId")
|
||||
List<Tag> findMonitorIdBindTags(@Param(value = "monitorId") Long monitorId);
|
||||
}
|
||||
-7
@@ -17,7 +17,6 @@
|
||||
|
||||
package org.apache.hertzbeat.alert.dao;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import org.apache.hertzbeat.common.entity.alerter.AlertSilence;
|
||||
import org.springframework.data.jpa.repository.JpaRepository;
|
||||
@@ -36,10 +35,4 @@ public interface AlertSilenceDao extends JpaRepository<AlertSilence, Long>, JpaS
|
||||
*/
|
||||
@Modifying
|
||||
void deleteAlertSilencesByIdIn(Set<Long> silenceIds);
|
||||
|
||||
/**
|
||||
* find enabled alert silence
|
||||
* @return enabled alert silence list
|
||||
*/
|
||||
List<AlertSilence> findAlertSilencesByEnableTrue();
|
||||
}
|
||||
+18
-13
@@ -21,8 +21,9 @@ 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.Map;
|
||||
import java.util.List;
|
||||
import lombok.Data;
|
||||
import org.apache.hertzbeat.common.entity.manager.TagItem;
|
||||
|
||||
/**
|
||||
* Data transfer object for alert configuration
|
||||
@@ -33,22 +34,26 @@ import lombok.Data;
|
||||
@JsonIgnoreProperties(ignoreUnknown = true)
|
||||
@ExcelTarget(value = "AlertDefineDTO")
|
||||
public class AlertDefineDTO {
|
||||
@Excel(name = "Name")
|
||||
private String name;
|
||||
@Excel(name = "Type")
|
||||
private String type;
|
||||
@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 = "Period")
|
||||
private Integer period;
|
||||
@Excel(name = "Priority")
|
||||
private Byte priority;
|
||||
@Excel(name = "Times")
|
||||
private Integer times;
|
||||
@Excel(name = "Labels")
|
||||
private Map<String, String> labels;
|
||||
@Excel(name = "Annotations")
|
||||
private Map<String, String> annotations;
|
||||
@Excel(name = "Template")
|
||||
private String template;
|
||||
@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;
|
||||
}
|
||||
@@ -0,0 +1,78 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.apache.hertzbeat.alert.dto;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonIgnore;
|
||||
import java.util.Map;
|
||||
import org.apache.hertzbeat.common.entity.dto.AlertReport;
|
||||
|
||||
/**
|
||||
* Abstract parent of cloud service alarm information
|
||||
* {@link AlertReport} - The method corresponds to the parameter of this class one by one. For details about the method, see this class
|
||||
*/
|
||||
public abstract class CloudAlertReportAbstract {
|
||||
|
||||
/**
|
||||
* This parameter specifies the alarm name when a cloud alarm is converted to an internal alarm
|
||||
*/
|
||||
@JsonIgnore
|
||||
public abstract String getAlertName();
|
||||
|
||||
/**
|
||||
* Interval when a cloud alarm is converted to an internal alarm
|
||||
*/
|
||||
@JsonIgnore
|
||||
public abstract Integer getAlertDuration();
|
||||
|
||||
/**
|
||||
* Specifies the alarm time when a cloud alarm is converted to an internal alarm
|
||||
*/
|
||||
@JsonIgnore
|
||||
public abstract long getAlertTime();
|
||||
|
||||
/**
|
||||
* Severity of an alarm when a cloud alarm is converted to an internal alarm
|
||||
*/
|
||||
@JsonIgnore
|
||||
public abstract Integer getPriority();
|
||||
|
||||
/**
|
||||
* This parameter specifies the alarm type when a cloud alarm is converted to an internal alarm
|
||||
*/
|
||||
@JsonIgnore
|
||||
public abstract Integer getReportType();
|
||||
|
||||
/**
|
||||
* Alarm label information about a cloud alarm that is converted to an internal alarm
|
||||
*/
|
||||
@JsonIgnore
|
||||
public abstract Map<String, String> getLabels();
|
||||
|
||||
/**
|
||||
* Alarm labels when a cloud alarm is converted to an internal alarm
|
||||
*/
|
||||
@JsonIgnore
|
||||
public abstract Map<String, String> getAnnotations();
|
||||
|
||||
/**
|
||||
* This topic describes the alarm content when a cloud alarm is converted to an internal alarm
|
||||
*/
|
||||
@JsonIgnore
|
||||
public abstract String getContent();
|
||||
|
||||
}
|
||||
@@ -0,0 +1,79 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.apache.hertzbeat.alert.dto;
|
||||
|
||||
import java.util.Optional;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.NoArgsConstructor;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.hertzbeat.alert.util.DateUtil;
|
||||
import org.apache.hertzbeat.common.entity.dto.AlertReport;
|
||||
|
||||
/**
|
||||
* Generic cloud alarm entity class
|
||||
*/
|
||||
@Data
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
public class GeneralCloudAlertReport extends AlertReport {
|
||||
|
||||
/**
|
||||
* Alarm date and time
|
||||
*/
|
||||
private String alertDateTime;
|
||||
|
||||
/**
|
||||
* DATE TIME FORMAT
|
||||
*/
|
||||
private String dateTimeFormat;
|
||||
|
||||
/**
|
||||
* You can refresh the timestamp of the alarm time with enhanced properties
|
||||
*/
|
||||
public void refreshAlertTime() {
|
||||
if (getAlertTime() != 0L) {
|
||||
return;
|
||||
}
|
||||
if (StringUtils.isNotBlank(alertDateTime)) {
|
||||
Long timeStamp = null;
|
||||
if (StringUtils.isNotBlank(dateTimeFormat)) {
|
||||
Optional<Long> tsf = DateUtil.getTimeStampFromFormat(alertDateTime, dateTimeFormat);
|
||||
boolean present = tsf.isPresent();
|
||||
if (present) {
|
||||
timeStamp = tsf.get();
|
||||
}
|
||||
}
|
||||
if (timeStamp == null) {
|
||||
Optional<Long> tsf = DateUtil.getTimeStampFromSomeFormats(alertDateTime);
|
||||
boolean present = tsf.isPresent();
|
||||
if (present) {
|
||||
timeStamp = tsf.get();
|
||||
}
|
||||
}
|
||||
if (timeStamp != null) {
|
||||
setAlertTime(timeStamp);
|
||||
return;
|
||||
}
|
||||
}
|
||||
throw new RuntimeException("parse alarm time error");
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,227 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.apache.hertzbeat.alert.dto;
|
||||
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
import java.io.Serializable;
|
||||
import java.util.Map;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Builder;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.NoArgsConstructor;
|
||||
import org.apache.hertzbeat.alert.util.DateUtil;
|
||||
|
||||
/**
|
||||
*
|
||||
* Tencent cloud alarm entity class
|
||||
*/
|
||||
@Data
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@Builder
|
||||
public class TenCloudAlertReport extends CloudAlertReportAbstract implements Serializable {
|
||||
@JsonProperty("sessionID")
|
||||
private String sessionId;
|
||||
private String alarmStatus;
|
||||
private String alarmType;
|
||||
private AlarmObjInfo alarmObjInfo;
|
||||
private AlarmPolicyInfo alarmPolicyInfo;
|
||||
private String firstOccurTime;
|
||||
private int durationTime;
|
||||
private String recoverTime;
|
||||
|
||||
/**
|
||||
* Alarm Object information
|
||||
*/
|
||||
@Data
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
public static class AlarmObjInfo {
|
||||
private String region;
|
||||
private String namespace;
|
||||
@JsonProperty("appID")
|
||||
private String appId;
|
||||
private String uin;
|
||||
private Dimensions dimensions;
|
||||
}
|
||||
|
||||
/**
|
||||
* Uniform Resource ID information
|
||||
*/
|
||||
@Data
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
public static class Dimensions {
|
||||
@JsonProperty("unInstanceID")
|
||||
private String unInstanceId;
|
||||
@JsonProperty("objID")
|
||||
private String objId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Alarm policy information
|
||||
*/
|
||||
@Data
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
public static class AlarmPolicyInfo {
|
||||
@JsonProperty("policyID")
|
||||
private String policyId;
|
||||
private String policyType;
|
||||
private String policyName;
|
||||
@JsonProperty("policyTypeCName")
|
||||
private String policyTypeCname;
|
||||
private Conditions conditions;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parameters of indicator alarms
|
||||
*/
|
||||
@Data
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
public static class Conditions {
|
||||
// alarm metrics parameters
|
||||
private String metricName;
|
||||
private String metricShowName;
|
||||
private String calcType;
|
||||
private String calcValue;
|
||||
private String calcUnit;
|
||||
private String currentValue;
|
||||
private String historyValue;
|
||||
private String unit;
|
||||
private String period;
|
||||
private String periodNum;
|
||||
private String alarmNotifyType;
|
||||
private long alarmNotifyPeriod;
|
||||
|
||||
// alarm event parameters
|
||||
private String productName;
|
||||
private String productShowName;
|
||||
private String eventName;
|
||||
private String eventShowName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getAlertName() {
|
||||
return "TenCloud|腾讯云";
|
||||
}
|
||||
|
||||
@Override
|
||||
public Integer getAlertDuration() {
|
||||
return this.durationTime;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getAlertTime() {
|
||||
|
||||
return DateUtil.getTimeStampFromFormat(getFirstOccurTime(), "yyyy-MM-dd HH:mm:ss")
|
||||
.orElse(0L);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Integer getPriority() {
|
||||
return 1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Integer getReportType() {
|
||||
return 1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, String> getLabels() {
|
||||
return Map.of("app", "TenCloud");
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, String> getAnnotations() {
|
||||
return Map.of("app", "TenCloud");
|
||||
}
|
||||
|
||||
/**
|
||||
* Transaction alarm
|
||||
*/
|
||||
private static final String EVENT = "event";
|
||||
|
||||
/**
|
||||
* Indicator alarm
|
||||
*/
|
||||
private static final String METRIC = "metric";
|
||||
|
||||
/**
|
||||
* If the following alarm types increase, the entity class can be divided into a parent class and multiple subclasses, and then the method can be implemented in the subclass
|
||||
* Since there are only two, it will not be split for the time being
|
||||
*/
|
||||
@Override
|
||||
public String getContent() {
|
||||
StringBuilder contentBuilder = new StringBuilder();
|
||||
// Check Type.
|
||||
if (EVENT.equals(getAlarmType())) {
|
||||
contentBuilder
|
||||
.append("[")
|
||||
.append("告警状态 | ")
|
||||
.append("0".equals(alarmStatus) ? "恢复" : "告警")
|
||||
.append("]\n")
|
||||
.append("[")
|
||||
.append("告警对象信息 | ")
|
||||
.append(getAlarmObjInfo().getRegion() == null ? "" : "region:" + getAlarmObjInfo().getRegion())
|
||||
.append(";").append("appId:").append(getAlarmObjInfo().getAppId())
|
||||
.append(";").append("uni:").append(getAlarmObjInfo().getUin())
|
||||
.append(";").append("unInstanceId:").append(getAlarmObjInfo().getDimensions().getUnInstanceId())
|
||||
.append("]\n")
|
||||
.append("[")
|
||||
.append("告警策略组信息 | ")
|
||||
.append("名称:").append(getAlarmPolicyInfo().getPolicyName())
|
||||
.append(";")
|
||||
.append("策略类型展示名称:").append(getAlarmPolicyInfo().getConditions().getProductName())
|
||||
.append(",").append(getAlarmPolicyInfo().getConditions().getProductShowName())
|
||||
.append(";")
|
||||
.append("事件告警名称:").append(getAlarmPolicyInfo().getConditions().getEventName())
|
||||
.append(",").append(getAlarmPolicyInfo().getConditions().getEventShowName())
|
||||
.append("]");
|
||||
} else if (METRIC.equals(getAlarmType())) {
|
||||
contentBuilder
|
||||
.append("[")
|
||||
.append("告警对象:")
|
||||
.append(getAlarmObjInfo().getRegion() == null ? "" : getAlarmObjInfo().getRegion())
|
||||
.append(getAlarmObjInfo().getRegion() == null ? "" : "|")
|
||||
.append(getAlarmObjInfo().getNamespace())
|
||||
.append("]")
|
||||
.append("[")
|
||||
.append("告警内容:")
|
||||
.append(getAlarmPolicyInfo().getPolicyTypeCname()).append("|")
|
||||
.append(getAlarmPolicyInfo().getConditions().getMetricShowName()).append("|")
|
||||
.append(getAlarmPolicyInfo().getConditions().getMetricName())
|
||||
.append(getAlarmPolicyInfo().getConditions().getCalcType())
|
||||
.append(getAlarmPolicyInfo().getConditions().getCalcValue())
|
||||
.append(getAlarmPolicyInfo().getConditions().getCalcUnit())
|
||||
.append("]")
|
||||
.append("[")
|
||||
.append("当前数据")
|
||||
.append(getAlarmPolicyInfo().getConditions().getCurrentValue())
|
||||
.append(getAlarmPolicyInfo().getConditions().getCalcUnit())
|
||||
.append("]");
|
||||
}
|
||||
return contentBuilder.toString();
|
||||
}
|
||||
|
||||
}
|
||||
+19
-16
@@ -15,35 +15,38 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.apache.hertzbeat.common.constants;
|
||||
|
||||
package org.apache.hertzbeat.alert.enums;
|
||||
|
||||
import java.util.Arrays;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
import lombok.ToString;
|
||||
import org.apache.hertzbeat.alert.dto.CloudAlertReportAbstract;
|
||||
import org.apache.hertzbeat.alert.dto.TenCloudAlertReport;
|
||||
|
||||
/**
|
||||
* Import/Export task status
|
||||
* Cloud server alarm enum
|
||||
*/
|
||||
@Getter
|
||||
@AllArgsConstructor
|
||||
@ToString
|
||||
public enum ImportTaskStatusEnum {
|
||||
@Getter
|
||||
public enum CloudServiceAlarmInformationEnum {
|
||||
|
||||
TencentCloud("tencloud", TenCloudAlertReport.class);
|
||||
|
||||
/**
|
||||
* In progress
|
||||
* cloud service name
|
||||
*/
|
||||
IN_PROGRESS("IN_PROGRESS"),
|
||||
private final String cloudServiceName;
|
||||
|
||||
/**
|
||||
* Completed
|
||||
* cloud service body
|
||||
*/
|
||||
COMPLETED("COMPLETED"),
|
||||
private final Class<? extends CloudAlertReportAbstract> cloudServiceAlarmInformationEntity;
|
||||
|
||||
/**
|
||||
* Failed
|
||||
*/
|
||||
FAILED("FAILED");
|
||||
public static CloudServiceAlarmInformationEnum getEnumFromCloudServiceName(String name) {
|
||||
return Arrays.stream(CloudServiceAlarmInformationEnum.values())
|
||||
.filter(cloudService -> cloudService.cloudServiceName.equals(name))
|
||||
.findFirst()
|
||||
.orElse(null);
|
||||
}
|
||||
|
||||
private final String value;
|
||||
}
|
||||
@@ -0,0 +1,73 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.apache.hertzbeat.alert.reduce;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.hertzbeat.alert.dao.AlertMonitorDao;
|
||||
import org.apache.hertzbeat.common.constants.CommonConstants;
|
||||
import org.apache.hertzbeat.common.entity.alerter.Alert;
|
||||
import org.apache.hertzbeat.common.entity.manager.Tag;
|
||||
import org.apache.hertzbeat.common.queue.CommonDataQueue;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
/**
|
||||
* reduce alarm and send alert data
|
||||
*/
|
||||
@Service
|
||||
@RequiredArgsConstructor
|
||||
@Slf4j
|
||||
public class AlarmCommonReduce {
|
||||
|
||||
private final AlarmSilenceReduce alarmSilenceReduce;
|
||||
|
||||
private final AlarmConvergeReduce alarmConvergeReduce;
|
||||
|
||||
private final CommonDataQueue dataQueue;
|
||||
|
||||
private final AlertMonitorDao alertMonitorDao;
|
||||
|
||||
public void reduceAndSendAlarm(Alert alert) {
|
||||
alert.setTimes(1);
|
||||
Map<String, String> tags = alert.getTags();
|
||||
if (tags == null) {
|
||||
tags = new HashMap<>(8);
|
||||
alert.setTags(tags);
|
||||
}
|
||||
String monitorIdStr = tags.get(CommonConstants.TAG_MONITOR_ID);
|
||||
if (monitorIdStr == null) {
|
||||
log.debug("receiver extern alarm message: {}", alert);
|
||||
} else {
|
||||
long monitorId = Long.parseLong(monitorIdStr);
|
||||
List<Tag> tagList = alertMonitorDao.findMonitorIdBindTags(monitorId);
|
||||
for (Tag tag : tagList) {
|
||||
if (!tags.containsKey(tag.getName())) {
|
||||
tags.put(tag.getName(), tag.getTagValue());
|
||||
}
|
||||
}
|
||||
}
|
||||
// converge -> silence
|
||||
if (alarmConvergeReduce.filterConverge(alert) && alarmSilenceReduce.filterSilence(alert)) {
|
||||
dataQueue.sendAlertsData(alert);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,168 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.apache.hertzbeat.alert.reduce;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import org.apache.hertzbeat.alert.dao.AlertConvergeDao;
|
||||
import org.apache.hertzbeat.common.cache.CacheFactory;
|
||||
import org.apache.hertzbeat.common.cache.CommonCacheService;
|
||||
import org.apache.hertzbeat.common.constants.CommonConstants;
|
||||
import org.apache.hertzbeat.common.entity.alerter.Alert;
|
||||
import org.apache.hertzbeat.common.entity.alerter.AlertConverge;
|
||||
import org.apache.hertzbeat.common.entity.manager.TagItem;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
/**
|
||||
* alarm converge
|
||||
*/
|
||||
@Service
|
||||
public class AlarmConvergeReduce {
|
||||
|
||||
private final AlertConvergeDao alertConvergeDao;
|
||||
|
||||
private final Map<Integer, Alert> converageAlertMap;
|
||||
|
||||
public AlarmConvergeReduce(AlertConvergeDao alertConvergeDao) {
|
||||
this.alertConvergeDao = alertConvergeDao;
|
||||
this.converageAlertMap = new ConcurrentHashMap<>(16);
|
||||
}
|
||||
|
||||
/**
|
||||
* currentAlert converge filter data
|
||||
*
|
||||
* @param currentAlert currentAlert
|
||||
* @return true when not filter
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public boolean filterConverge(Alert currentAlert) {
|
||||
// ignore monitor status auto recover notice
|
||||
if ((currentAlert.getTags() != null && currentAlert.getTags().containsKey(CommonConstants.IGNORE))
|
||||
|| currentAlert.getStatus() == CommonConstants.ALERT_STATUS_CODE_RESTORED) {
|
||||
// restored alert
|
||||
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 = generateAlertHash(CommonConstants.ALERT_PRIORITY_CODE_EMERGENCY, tags);
|
||||
converageAlertMap.remove(alertHash);
|
||||
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) {
|
||||
alertConvergeList = alertConvergeDao.findAll();
|
||||
// matchAll is in the last
|
||||
alertConvergeList.sort((item1, item2) -> {
|
||||
if (item1.isMatchAll()) {
|
||||
return 1;
|
||||
} else if (item2.isMatchAll()) {
|
||||
return -1;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
});
|
||||
convergeCache.put(CommonConstants.CACHE_ALERT_CONVERGE, alertConvergeList);
|
||||
}
|
||||
for (AlertConverge alertConverge : alertConvergeList) {
|
||||
if (!alertConverge.isEnable()) {
|
||||
continue;
|
||||
}
|
||||
boolean match = alertConverge.isMatchAll();
|
||||
if (!match) {
|
||||
List<TagItem> tags = alertConverge.getTags();
|
||||
if (currentAlert.getTags() != null && !currentAlert.getTags().isEmpty()) {
|
||||
Map<String, String> alertTagMap = currentAlert.getTags();
|
||||
match = tags.stream().anyMatch(item -> {
|
||||
if (alertTagMap.containsKey(item.getName())) {
|
||||
String tagValue = alertTagMap.get(item.getName());
|
||||
if (tagValue == null && item.getValue() == null) {
|
||||
return true;
|
||||
} else {
|
||||
return tagValue != null && tagValue.equals(item.getValue());
|
||||
}
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
});
|
||||
} else {
|
||||
match = true;
|
||||
}
|
||||
if (match && alertConverge.getPriorities() != null && !alertConverge.getPriorities().isEmpty()) {
|
||||
match = alertConverge.getPriorities().stream().anyMatch(item -> item != null && item == currentAlert.getPriority());
|
||||
}
|
||||
}
|
||||
if (match) {
|
||||
long evalInterval = alertConverge.getEvalInterval() * 1000L;
|
||||
long now = System.currentTimeMillis();
|
||||
if (evalInterval <= 0) {
|
||||
return true;
|
||||
}
|
||||
int alertHash = generateAlertHash(currentAlert.getPriority(), currentAlert.getTags());
|
||||
Alert preAlert = converageAlertMap.get(alertHash);
|
||||
if (preAlert == null) {
|
||||
currentAlert.setTimes(1);
|
||||
currentAlert.setFirstAlarmTime(now);
|
||||
currentAlert.setLastAlarmTime(now);
|
||||
converageAlertMap.put(alertHash, currentAlert.clone());
|
||||
return true;
|
||||
} else {
|
||||
if (now - preAlert.getFirstAlarmTime() < evalInterval) {
|
||||
preAlert.setTimes(preAlert.getTimes() + 1);
|
||||
preAlert.setLastAlarmTime(now);
|
||||
return false;
|
||||
} else {
|
||||
currentAlert.setTimes(preAlert.getTimes());
|
||||
if (preAlert.getTimes() == 1) {
|
||||
currentAlert.setFirstAlarmTime(now);
|
||||
} else {
|
||||
currentAlert.setFirstAlarmTime(preAlert.getFirstAlarmTime());
|
||||
}
|
||||
currentAlert.setLastAlarmTime(now);
|
||||
preAlert.setFirstAlarmTime(now);
|
||||
preAlert.setLastAlarmTime(now);
|
||||
preAlert.setTimes(1);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
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]));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,125 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.apache.hertzbeat.alert.reduce;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.apache.hertzbeat.alert.dao.AlertSilenceDao;
|
||||
import org.apache.hertzbeat.common.cache.CacheFactory;
|
||||
import org.apache.hertzbeat.common.cache.CommonCacheService;
|
||||
import org.apache.hertzbeat.common.constants.CommonConstants;
|
||||
import org.apache.hertzbeat.common.entity.alerter.Alert;
|
||||
import org.apache.hertzbeat.common.entity.alerter.AlertSilence;
|
||||
import org.apache.hertzbeat.common.entity.manager.TagItem;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
/**
|
||||
* silence alarm
|
||||
*/
|
||||
@Service
|
||||
@RequiredArgsConstructor
|
||||
public class AlarmSilenceReduce {
|
||||
|
||||
private final AlertSilenceDao alertSilenceDao;
|
||||
|
||||
/**
|
||||
* alert silence filter data
|
||||
* @param alert alert
|
||||
* @return true when not filter
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public boolean filterSilence(Alert alert) {
|
||||
CommonCacheService<String, Object> silenceCache = CacheFactory.getAlertSilenceCache();
|
||||
List<AlertSilence> alertSilenceList = (List<AlertSilence>) silenceCache.get(CommonConstants.CACHE_ALERT_SILENCE);
|
||||
if (alertSilenceList == null) {
|
||||
alertSilenceList = alertSilenceDao.findAll();
|
||||
silenceCache.put(CommonConstants.CACHE_ALERT_SILENCE, alertSilenceList);
|
||||
}
|
||||
for (AlertSilence alertSilence : alertSilenceList) {
|
||||
if (!alertSilence.isEnable()) {
|
||||
continue;
|
||||
}
|
||||
// if match the silence rule, return
|
||||
boolean match = alertSilence.isMatchAll();
|
||||
if (!match) {
|
||||
List<TagItem> tags = alertSilence.getTags();
|
||||
if (alert.getTags() != null && !alert.getTags().isEmpty()) {
|
||||
Map<String, String> alertTagMap = alert.getTags();
|
||||
match = tags.stream().anyMatch(item -> {
|
||||
if (alertTagMap.containsKey(item.getName())) {
|
||||
String tagValue = alertTagMap.get(item.getName());
|
||||
if (tagValue == null && item.getValue() == null) {
|
||||
return true;
|
||||
} else {
|
||||
return tagValue != null && tagValue.equals(item.getValue());
|
||||
}
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
});
|
||||
} else {
|
||||
match = true;
|
||||
}
|
||||
if (match && alertSilence.getPriorities() != null && !alertSilence.getPriorities().isEmpty()) {
|
||||
match = alertSilence.getPriorities().stream().anyMatch(item -> item != null && item == alert.getPriority());
|
||||
}
|
||||
}
|
||||
if (match) {
|
||||
if (alertSilence.getType() == 0) {
|
||||
// once time
|
||||
return checkAndSave(LocalDateTime.now(), alertSilence);
|
||||
} else if (alertSilence.getType() == 1) {
|
||||
// cyc time
|
||||
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) {
|
||||
return checkAndSave(LocalDateTime.now(), alertSilence);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
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;
|
||||
}
|
||||
}
|
||||
+18
-18
@@ -19,50 +19,50 @@ package org.apache.hertzbeat.alert.service;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import org.apache.hertzbeat.common.entity.alerter.AlertGroupConverge;
|
||||
import org.apache.hertzbeat.common.entity.alerter.AlertConverge;
|
||||
import org.springframework.data.domain.Page;
|
||||
|
||||
/**
|
||||
* management interface service for alert converge
|
||||
*/
|
||||
public interface AlertGroupConvergeService {
|
||||
public interface AlertConvergeService {
|
||||
/**
|
||||
* Verify the correctness of the request data parameters
|
||||
* @param alertGroupConverge AlertGroupConverge
|
||||
* @param alertConverge AlertConverge
|
||||
* @param isModify whether modify
|
||||
* @throws IllegalArgumentException A checksum parameter error is thrown
|
||||
*/
|
||||
void validate(AlertGroupConverge alertGroupConverge, boolean isModify) throws IllegalArgumentException;
|
||||
void validate(AlertConverge alertConverge, boolean isModify) throws IllegalArgumentException;
|
||||
|
||||
/**
|
||||
* New AlertGroupConverge
|
||||
* @param alertGroupConverge AlertGroupConverge Entity
|
||||
* New AlertConverge
|
||||
* @param alertConverge AlertConverge Entity
|
||||
* @throws RuntimeException Added procedure exception throwing
|
||||
*/
|
||||
void addAlertGroupConverge(AlertGroupConverge alertGroupConverge) throws RuntimeException;
|
||||
void addAlertConverge(AlertConverge alertConverge) throws RuntimeException;
|
||||
|
||||
/**
|
||||
* Modifying an AlertGroupConverge
|
||||
* @param alertGroupConverge Alarm definition Entity
|
||||
* Modifying an AlertConverge
|
||||
* @param alertConverge Alarm definition Entity
|
||||
* @throws RuntimeException Exception thrown during modification
|
||||
*/
|
||||
void modifyAlertGroupConverge(AlertGroupConverge alertGroupConverge) throws RuntimeException;
|
||||
void modifyAlertConverge(AlertConverge alertConverge) throws RuntimeException;
|
||||
|
||||
/**
|
||||
* Obtain AlertGroupConverge information
|
||||
* @param convergeId AlertGroupConverge ID
|
||||
* @return AlertGroupConverge
|
||||
* Obtain AlertConverge information
|
||||
* @param convergeId AlertConverge ID
|
||||
* @return AlertConverge
|
||||
* @throws RuntimeException An exception was thrown during the query
|
||||
*/
|
||||
AlertGroupConverge getAlertGroupConverge(long convergeId) throws RuntimeException;
|
||||
AlertConverge getAlertConverge(long convergeId) throws RuntimeException;
|
||||
|
||||
|
||||
/**
|
||||
* Delete AlertGroupConverge in batches
|
||||
* @param convergeIds AlertGroupConverge IDs
|
||||
* Delete AlertConverge in batches
|
||||
* @param convergeIds AlertConverge IDs
|
||||
* @throws RuntimeException Exception thrown during deletion
|
||||
*/
|
||||
void deleteAlertGroupConverges(Set<Long> convergeIds) throws RuntimeException;
|
||||
void deleteAlertConverges(Set<Long> convergeIds) throws RuntimeException;
|
||||
|
||||
/**
|
||||
* Dynamic conditional query
|
||||
@@ -74,5 +74,5 @@ public interface AlertGroupConvergeService {
|
||||
* @param pageSize Number of list pages
|
||||
* @return The query results
|
||||
*/
|
||||
Page<AlertGroupConverge> getAlertGroupConverges(List<Long> convergeIds, String search, String sort, String order, int pageIndex, int pageSize);
|
||||
Page<AlertConverge> getAlertConverges(List<Long> convergeIds, String search, String sort, String order, int pageIndex, int pageSize);
|
||||
}
|
||||
+47
-9
@@ -19,9 +19,13 @@ package org.apache.hertzbeat.alert.service;
|
||||
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import org.apache.hertzbeat.common.entity.alerter.AlertDefine;
|
||||
import org.apache.hertzbeat.common.entity.alerter.AlertDefineMonitorBind;
|
||||
import org.springframework.data.domain.Page;
|
||||
import org.springframework.data.domain.PageRequest;
|
||||
import org.springframework.data.jpa.domain.Specification;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
/**
|
||||
@@ -73,18 +77,59 @@ public interface AlertDefineService {
|
||||
* @throws RuntimeException Exception thrown during deletion
|
||||
*/
|
||||
void deleteAlertDefines(Set<Long> alertIds) throws RuntimeException;
|
||||
|
||||
|
||||
/**
|
||||
* Dynamic conditional query
|
||||
* @param specification Query conditions
|
||||
* @param pageRequest Paging parameters
|
||||
* @return The query results
|
||||
*/
|
||||
Page<AlertDefine> getMonitorBindAlertDefines(Specification<AlertDefine> specification, PageRequest pageRequest);
|
||||
|
||||
/**
|
||||
* Association between application alarm schedule and monitoring
|
||||
* @param alertId Alarm Definition ID
|
||||
* @param alertDefineBinds correlation
|
||||
*/
|
||||
void applyBindAlertDefineMonitors(Long alertId, List<AlertDefineMonitorBind> alertDefineBinds);
|
||||
|
||||
/**
|
||||
* Query the alarm definitions that match the specified metrics associated with the monitoring ID
|
||||
* @param monitorId Monitor the ID
|
||||
* @param app Monitoring type
|
||||
* @param metrics metrics
|
||||
* @return field - define[]
|
||||
*/
|
||||
Map<String, List<AlertDefine>> getMonitorBindAlertDefines(long monitorId, String app, String metrics);
|
||||
|
||||
/**
|
||||
* Query the alarm definitions that match the specified metrics associated with the monitoring ID
|
||||
* @param monitorId Monitor the ID
|
||||
* @param app Monitoring type
|
||||
* @param metrics metrics
|
||||
* @return field - define[]
|
||||
*/
|
||||
AlertDefine getMonitorBindAlertAvaDefine(long monitorId, String app, String metrics);
|
||||
|
||||
/**
|
||||
* Dynamic conditional query
|
||||
* @param 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(List<Long> defineIds, String search, String sort, String order, int pageIndex, int pageSize);
|
||||
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
|
||||
* @param alertDefineId Alarm Definition ID
|
||||
* @return Associated information about the monitoring list
|
||||
*/
|
||||
List<AlertDefineMonitorBind> getBindAlertDefineMonitors(long alertDefineId);
|
||||
|
||||
/**
|
||||
* Export file configuration of specified type based on ID list and export file type
|
||||
@@ -101,11 +146,4 @@ public interface AlertDefineService {
|
||||
* @throws Exception An exception was thrown during the importConfig
|
||||
*/
|
||||
void importConfig(MultipartFile file) throws Exception;
|
||||
|
||||
/**
|
||||
* Get the real-time alarm definition list
|
||||
* @return Real-time alarm definition list
|
||||
*/
|
||||
List<AlertDefine> getRealTimeAlertDefines();
|
||||
|
||||
}
|
||||
+41
-29
@@ -20,9 +20,10 @@ package org.apache.hertzbeat.alert.service;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import org.apache.hertzbeat.alert.dto.AlertSummary;
|
||||
import org.apache.hertzbeat.common.entity.alerter.GroupAlert;
|
||||
import org.apache.hertzbeat.common.entity.alerter.SingleAlert;
|
||||
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.jpa.domain.Specification;
|
||||
|
||||
/**
|
||||
* Alarm information management interface
|
||||
@@ -30,57 +31,68 @@ import org.springframework.data.domain.Page;
|
||||
public interface AlertService {
|
||||
|
||||
/**
|
||||
* get and query single alerts
|
||||
* @param status status
|
||||
* @param search search
|
||||
* @param sort sort
|
||||
* @param order order
|
||||
* @param pageIndex pageIndex
|
||||
* @param pageSize pageSize
|
||||
* @return single alerts
|
||||
* Add alarm record
|
||||
* @param alert Alert entity
|
||||
* @throws RuntimeException Add process exception throw
|
||||
*/
|
||||
Page<SingleAlert> getSingleAlerts(String status, String search, String sort, String order, int pageIndex, int pageSize);
|
||||
|
||||
void addAlert(Alert alert) throws RuntimeException;
|
||||
|
||||
/**
|
||||
* Dynamic conditional query
|
||||
* @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<GroupAlert> getGroupAlerts(String status, String search, String sort, String order, int pageIndex, int pageSize);
|
||||
Page<Alert> getAlerts(List<Long> alarmIds, Long monitorId, Byte priority, Byte status, String content, String sort, String order, int pageIndex, int pageSize);
|
||||
|
||||
/**
|
||||
* delete the group alarm according to the alarm ID
|
||||
* @param ids Alarm ID List
|
||||
* Delete alarms in batches according to the alarm ID list
|
||||
* @param ids Alarm ID List
|
||||
*/
|
||||
void deleteGroupAlerts(HashSet<Long> ids);
|
||||
void deleteAlerts(HashSet<Long> ids);
|
||||
|
||||
/**
|
||||
* delete the single alarm according to the alarm ID
|
||||
* @param ids Alarm ID List
|
||||
* Clear all alerts
|
||||
*/
|
||||
void deleteSingleAlerts(HashSet<Long> ids);
|
||||
void clearAlerts();
|
||||
|
||||
/**
|
||||
* Update the alarm status according to the alarm ID-status value
|
||||
* @param status Alarm status to be modified
|
||||
* @param ids Alarm ID List to be modified
|
||||
* @param status Alarm status to be modified
|
||||
* @param ids Alarm ID List to be modified
|
||||
*/
|
||||
void editGroupAlertStatus(String status, List<Long> ids);
|
||||
void editAlertStatus(Byte status, List<Long> ids);
|
||||
|
||||
/**
|
||||
* Update the alarm status according to the alarm ID-status value
|
||||
* @param status Alarm status to be modified
|
||||
* @param ids Alarm ID List to be modified
|
||||
*/
|
||||
void editSingleAlertStatus(String status, List<Long> ids);
|
||||
|
||||
/**
|
||||
* Get alarm statistics information
|
||||
* @return Alarm statistics information
|
||||
*/
|
||||
AlertSummary getAlertsSummary();
|
||||
|
||||
/**
|
||||
* A third party reports an alarm
|
||||
* @param alertReport The alarm information
|
||||
*/
|
||||
void addNewAlertReport(AlertReport alertReport);
|
||||
|
||||
/**
|
||||
* 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
|
||||
* @return search result
|
||||
*/
|
||||
List<Alert> getAlerts(Specification<Alert> specification);
|
||||
}
|
||||
+26
-27
@@ -23,10 +23,12 @@ import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.hertzbeat.alert.dao.AlertGroupConvergeDao;
|
||||
import org.apache.hertzbeat.alert.reduce.AlarmGroupReduce;
|
||||
import org.apache.hertzbeat.alert.service.AlertGroupConvergeService;
|
||||
import org.apache.hertzbeat.common.entity.alerter.AlertGroupConverge;
|
||||
import org.apache.hertzbeat.alert.dao.AlertConvergeDao;
|
||||
import org.apache.hertzbeat.alert.service.AlertConvergeService;
|
||||
import org.apache.hertzbeat.common.cache.CacheFactory;
|
||||
import org.apache.hertzbeat.common.cache.CommonCacheService;
|
||||
import org.apache.hertzbeat.common.constants.CommonConstants;
|
||||
import org.apache.hertzbeat.common.entity.alerter.AlertConverge;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.data.domain.Page;
|
||||
import org.springframework.data.domain.PageRequest;
|
||||
@@ -42,45 +44,42 @@ import org.springframework.util.StringUtils;
|
||||
@Service
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
@Slf4j
|
||||
public class AlertGroupConvergeServiceImpl implements AlertGroupConvergeService {
|
||||
public class AlertConvergeServiceImpl implements AlertConvergeService {
|
||||
|
||||
@Autowired
|
||||
private AlertGroupConvergeDao alertGroupConvergeDao;
|
||||
|
||||
@Autowired
|
||||
private AlarmGroupReduce alarmGroupReduce;
|
||||
private AlertConvergeDao alertConvergeDao;
|
||||
|
||||
@Override
|
||||
public void validate(AlertGroupConverge alertGroupConverge, boolean isModify) throws IllegalArgumentException {
|
||||
public void validate(AlertConverge alertConverge, boolean isModify) throws IllegalArgumentException {
|
||||
// todo
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addAlertGroupConverge(AlertGroupConverge alertGroupConverge) throws RuntimeException {
|
||||
alertGroupConvergeDao.save(alertGroupConverge);
|
||||
refreshAlertGroupConvergesCache();
|
||||
public void addAlertConverge(AlertConverge alertConverge) throws RuntimeException {
|
||||
alertConvergeDao.save(alertConverge);
|
||||
clearAlertConvergesCache();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void modifyAlertGroupConverge(AlertGroupConverge alertGroupConverge) throws RuntimeException {
|
||||
alertGroupConvergeDao.save(alertGroupConverge);
|
||||
refreshAlertGroupConvergesCache();
|
||||
public void modifyAlertConverge(AlertConverge alertConverge) throws RuntimeException {
|
||||
alertConvergeDao.save(alertConverge);
|
||||
clearAlertConvergesCache();
|
||||
}
|
||||
|
||||
@Override
|
||||
public AlertGroupConverge getAlertGroupConverge(long convergeId) throws RuntimeException {
|
||||
return alertGroupConvergeDao.findById(convergeId).orElse(null);
|
||||
public AlertConverge getAlertConverge(long convergeId) throws RuntimeException {
|
||||
return alertConvergeDao.findById(convergeId).orElse(null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deleteAlertGroupConverges(Set<Long> convergeIds) throws RuntimeException {
|
||||
alertGroupConvergeDao.deleteAlertGroupConvergesByIdIn(convergeIds);
|
||||
refreshAlertGroupConvergesCache();
|
||||
public void deleteAlertConverges(Set<Long> convergeIds) throws RuntimeException {
|
||||
alertConvergeDao.deleteAlertConvergesByIdIn(convergeIds);
|
||||
clearAlertConvergesCache();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Page<AlertGroupConverge> getAlertGroupConverges(List<Long> convergeIds, String search, String sort, String order, int pageIndex, int pageSize) {
|
||||
Specification<AlertGroupConverge> specification = (root, query, criteriaBuilder) -> {
|
||||
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"));
|
||||
@@ -103,11 +102,11 @@ public class AlertGroupConvergeServiceImpl implements AlertGroupConvergeService
|
||||
};
|
||||
Sort sortExp = Sort.by(new Sort.Order(Sort.Direction.fromString(order), sort));
|
||||
PageRequest pageRequest = PageRequest.of(pageIndex, pageSize, sortExp);
|
||||
return alertGroupConvergeDao.findAll(specification, pageRequest);
|
||||
return alertConvergeDao.findAll(specification, pageRequest);
|
||||
}
|
||||
|
||||
private void refreshAlertGroupConvergesCache() {
|
||||
List<AlertGroupConverge> alertGroupConverges = alertGroupConvergeDao.findAlertGroupConvergesByEnableIsTrue();
|
||||
alarmGroupReduce.refreshGroupDefines(alertGroupConverges);
|
||||
private void clearAlertConvergesCache() {
|
||||
CommonCacheService<String, Object> convergeCache = CacheFactory.getAlertConvergeCache();
|
||||
convergeCache.remove(CommonConstants.CACHE_ALERT_CONVERGE);
|
||||
}
|
||||
}
|
||||
+58
-57
@@ -25,17 +25,17 @@ import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
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;
|
||||
@@ -97,6 +97,15 @@ public class AlertDefineExcelImExportServiceImpl extends AlertDefineAbstractImEx
|
||||
}
|
||||
}
|
||||
|
||||
private List<TagItem> extractTagDataFromRow(Cell cell) {
|
||||
String jsonStr = getCellValueAsString(cell);
|
||||
if (StringUtils.hasText(jsonStr)) {
|
||||
return JsonUtil.fromJson(jsonStr, new TypeReference<>() {
|
||||
});
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
private String getCellValueAsString(Cell cell) {
|
||||
if (cell == null) {
|
||||
@@ -144,17 +153,18 @@ public class AlertDefineExcelImExportServiceImpl extends AlertDefineAbstractImEx
|
||||
|
||||
|
||||
private AlertDefineDTO extractAlertDefineDataFromRow(Row row) {
|
||||
TypeReference<Map<String, String>> typeReference = new TypeReference<>() {};
|
||||
AlertDefineDTO alertDefineDTO = new AlertDefineDTO();
|
||||
alertDefineDTO.setName(getCellValueAsString(row.getCell(0)));
|
||||
alertDefineDTO.setType(getCellValueAsString(row.getCell(1)));
|
||||
alertDefineDTO.setExpr(getCellValueAsString(row.getCell(2)));
|
||||
alertDefineDTO.setPeriod(getCellValueAsInteger(row.getCell(3)));
|
||||
alertDefineDTO.setTimes(getCellValueAsInteger(row.getCell(4)));
|
||||
alertDefineDTO.setLabels(JsonUtil.fromJson(getCellValueAsString(row.getCell(5)), typeReference));
|
||||
alertDefineDTO.setAnnotations(JsonUtil.fromJson(getCellValueAsString(row.getCell(6)), typeReference));
|
||||
alertDefineDTO.setTemplate(getCellValueAsString(row.getCell(7)));
|
||||
alertDefineDTO.setApp(getCellValueAsString(row.getCell(0)));
|
||||
alertDefineDTO.setMetric(getCellValueAsString(row.getCell(1)));
|
||||
alertDefineDTO.setField(getCellValueAsString(row.getCell(2)));
|
||||
alertDefineDTO.setPreset(getCellValueAsBoolean(row.getCell(3)));
|
||||
alertDefineDTO.setExpr(getCellValueAsString(row.getCell(4)));
|
||||
alertDefineDTO.setPriority(getCellValueAsByte(row.getCell(5)));
|
||||
alertDefineDTO.setTimes(getCellValueAsInteger(row.getCell(6)));
|
||||
alertDefineDTO.setTags(extractTagDataFromRow(row.getCell(7)));
|
||||
alertDefineDTO.setEnable(getCellValueAsBoolean(row.getCell(8)));
|
||||
alertDefineDTO.setRecoverNotice(getCellValueAsBoolean(row.getCell(9)));
|
||||
alertDefineDTO.setTemplate(getCellValueAsString(row.getCell(10)));
|
||||
return alertDefineDTO;
|
||||
}
|
||||
|
||||
@@ -168,31 +178,11 @@ public class AlertDefineExcelImExportServiceImpl extends AlertDefineAbstractImEx
|
||||
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(2, 40 * 256);
|
||||
sheet.setColumnWidth(5, 40 * 256);
|
||||
sheet.setColumnWidth(6, 40 * 256);
|
||||
sheet.setColumnWidth(7, 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 = {"Name", "Type", "Expr", "Period", "Times", "Labels", "Annotations", "Template", "Enable"};
|
||||
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;
|
||||
@@ -200,33 +190,44 @@ public class AlertDefineExcelImExportServiceImpl extends AlertDefineAbstractImEx
|
||||
AlertDefineDTO alertDefineDTO = alertDefine.getAlertDefine();
|
||||
Row row = sheet.createRow(rowIndex++);
|
||||
// Threshold rule information only needs to be written once
|
||||
Cell nameCell = row.createCell(0);
|
||||
nameCell.setCellValue(alertDefineDTO.getName());
|
||||
nameCell.setCellStyle(cellStyle);
|
||||
Cell typeCell = row.createCell(1);
|
||||
typeCell.setCellValue(alertDefineDTO.getType());
|
||||
typeCell.setCellStyle(cellStyle);
|
||||
Cell exprCell = row.createCell(2);
|
||||
Cell appCell = row.createCell(0);
|
||||
appCell.setCellValue(alertDefineDTO.getApp());
|
||||
appCell.setCellStyle(cellStyle);
|
||||
Cell metricCell = row.createCell(1);
|
||||
metricCell.setCellValue(alertDefineDTO.getMetric());
|
||||
metricCell.setCellStyle(cellStyle);
|
||||
Cell fieldCell = row.createCell(2);
|
||||
fieldCell.setCellValue(alertDefineDTO.getField());
|
||||
fieldCell.setCellStyle(cellStyle);
|
||||
Cell presetCell = row.createCell(3);
|
||||
presetCell.setCellValue(alertDefineDTO.getPreset() != null
|
||||
&& alertDefineDTO.getPreset());
|
||||
presetCell.setCellStyle(cellStyle);
|
||||
Cell exprCell = row.createCell(4);
|
||||
exprCell.setCellValue(alertDefineDTO.getExpr());
|
||||
exprCell.setCellStyle(cellStyle);
|
||||
Cell periodCell = row.createCell(3);
|
||||
periodCell.setCellValue(alertDefineDTO.getPeriod());
|
||||
periodCell.setCellStyle(cellStyle);
|
||||
Cell timesCell = row.createCell(4);
|
||||
Cell priorityCell = row.createCell(5);
|
||||
priorityCell.setCellValue(alertDefineDTO.getPriority());
|
||||
priorityCell.setCellStyle(cellStyle);
|
||||
Cell timesCell = row.createCell(6);
|
||||
timesCell.setCellValue(alertDefineDTO.getTimes());
|
||||
timesCell.setCellStyle(cellStyle);
|
||||
Cell labelsCell = row.createCell(5);
|
||||
labelsCell.setCellValue(JsonUtil.toJson(alertDefineDTO.getLabels()));
|
||||
labelsCell.setCellStyle(cellStyle);
|
||||
Cell annoCell = row.createCell(6);
|
||||
annoCell.setCellValue(JsonUtil.toJson(alertDefineDTO.getAnnotations()));
|
||||
annoCell.setCellStyle(cellStyle);
|
||||
Cell templateCell = row.createCell(7);
|
||||
templateCell.setCellValue(alertDefineDTO.getTemplate());
|
||||
templateCell.setCellStyle(cellStyle);
|
||||
Cell tagCell = row.createCell(7);
|
||||
// get tags
|
||||
List<TagItem> tagList = alertDefineDTO.getTags();
|
||||
String tagValue = tagList == null || tagList.isEmpty() ? "" : JsonUtil.toJson(tagList);
|
||||
tagCell.setCellValue(tagValue);
|
||||
tagCell.setCellStyle(cellStyle);
|
||||
Cell enableCell = row.createCell(8);
|
||||
enableCell.setCellValue(alertDefineDTO.getEnable());
|
||||
enableCell.setCellValue(alertDefineDTO.getEnable() != null
|
||||
&& alertDefineDTO.getEnable());
|
||||
enableCell.setCellStyle(cellStyle);
|
||||
Cell recoverNoticeCell = row.createCell(9);
|
||||
recoverNoticeCell.setCellValue(alertDefineDTO.getRecoverNotice() != null
|
||||
&& alertDefineDTO.getRecoverNotice());
|
||||
recoverNoticeCell.setCellStyle(cellStyle);
|
||||
Cell templateCell = row.createCell(10);
|
||||
templateCell.setCellValue(alertDefineDTO.getTemplate());
|
||||
recoverNoticeCell.setCellStyle(cellStyle);
|
||||
}
|
||||
workbook.write(os);
|
||||
os.close();
|
||||
+85
-43
@@ -17,7 +17,6 @@
|
||||
|
||||
package org.apache.hertzbeat.alert.service.impl;
|
||||
|
||||
import static org.apache.hertzbeat.common.constants.CommonConstants.ALERT_THRESHOLD_TYPE_REALTIME;
|
||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||
import com.fasterxml.jackson.core.type.TypeReference;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
@@ -25,14 +24,16 @@ 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.calculate.PeriodicAlertRuleScheduler;
|
||||
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.cache.CacheFactory;
|
||||
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;
|
||||
@@ -52,11 +53,14 @@ 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;
|
||||
|
||||
/**
|
||||
* Alarm definition management interface implementation
|
||||
@@ -68,9 +72,12 @@ public class AlertDefineServiceImpl implements AlertDefineService {
|
||||
|
||||
@Autowired
|
||||
private AlertDefineDao alertDefineDao;
|
||||
|
||||
|
||||
@Autowired
|
||||
private PeriodicAlertRuleScheduler periodicAlertRuleScheduler;
|
||||
private AlertDefineBindDao alertDefineBindDao;
|
||||
|
||||
@Autowired
|
||||
private AlertMonitorDao alertMonitorDao;
|
||||
|
||||
private final Map<String, AlertDefineImExportService> alertDefineImExportServiceMap = new HashMap<>();
|
||||
|
||||
@@ -82,43 +89,29 @@ public class AlertDefineServiceImpl implements AlertDefineService {
|
||||
|
||||
@Override
|
||||
public void validate(AlertDefine alertDefine, boolean isModify) throws IllegalArgumentException {
|
||||
// todo
|
||||
if (StringUtils.hasText(alertDefine.getExpr())) {
|
||||
if (ALERT_THRESHOLD_TYPE_REALTIME.equals(alertDefine.getType())) {
|
||||
try {
|
||||
JexlExpressionRunner.compile(alertDefine.getExpr());
|
||||
} catch (Exception e) {
|
||||
throw new IllegalArgumentException("alert expr error: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
// the name of the alarm rule is unique
|
||||
Optional<AlertDefine> optional = alertDefineDao.findAlertDefineByName(alertDefine.getName());
|
||||
if (optional.isPresent()) {
|
||||
if (!isModify || !optional.get().getId().equals(alertDefine.getId())) {
|
||||
throw new IllegalArgumentException("alert name already exists");
|
||||
try {
|
||||
JexlExpressionRunner.compile(alertDefine.getExpr());
|
||||
} catch (Exception e) {
|
||||
throw new IllegalArgumentException("alert expr error: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addAlertDefine(AlertDefine alertDefine) throws RuntimeException {
|
||||
alertDefine = alertDefineDao.save(alertDefine);
|
||||
periodicAlertRuleScheduler.updateSchedule(alertDefine);
|
||||
CacheFactory.clearAlertDefineCache();
|
||||
alertDefineDao.save(alertDefine);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void modifyAlertDefine(AlertDefine alertDefine) throws RuntimeException {
|
||||
alertDefineDao.save(alertDefine);
|
||||
periodicAlertRuleScheduler.updateSchedule(alertDefine);
|
||||
CacheFactory.clearAlertDefineCache();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deleteAlertDefine(long alertId) throws RuntimeException {
|
||||
alertDefineDao.deleteById(alertId);
|
||||
periodicAlertRuleScheduler.cancelSchedule(alertId);
|
||||
CacheFactory.clearAlertDefineCache();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -130,14 +123,47 @@ public class AlertDefineServiceImpl implements AlertDefineService {
|
||||
@Override
|
||||
public void deleteAlertDefines(Set<Long> alertIds) throws RuntimeException {
|
||||
alertDefineDao.deleteAlertDefinesByIdIn(alertIds);
|
||||
for (Long alertId : alertIds) {
|
||||
periodicAlertRuleScheduler.cancelSchedule(alertId);
|
||||
}
|
||||
CacheFactory.clearAlertDefineCache();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Page<AlertDefine> getAlertDefines(List<Long> defineIds, String search, String sort, String order, int pageIndex, int pageSize) {
|
||||
public Page<AlertDefine> getMonitorBindAlertDefines(Specification<AlertDefine> specification, PageRequest pageRequest) {
|
||||
return alertDefineDao.findAll(specification, pageRequest);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void applyBindAlertDefineMonitors(Long alertId, List<AlertDefineMonitorBind> alertDefineBinds) {
|
||||
// todo checks whether the alarm definition and monitoring exist
|
||||
if (!alertDefineBindDao.existsById(alertId)){
|
||||
alertDefineBindDao.deleteAlertDefineBindsByAlertDefineIdEquals(alertId);
|
||||
}
|
||||
// Delete all associations of this alarm
|
||||
alertDefineBindDao.deleteAlertDefineBindsByAlertDefineIdEquals(alertId);
|
||||
// Save the associated
|
||||
alertDefineBindDao.saveAll(alertDefineBinds);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, List<AlertDefine>> getMonitorBindAlertDefines(long monitorId, String app, String metrics) {
|
||||
List<AlertDefine> defines = alertDefineDao.queryAlertDefinesByMonitor(monitorId, app, metrics);
|
||||
List<AlertDefine> defaultDefines = alertDefineDao.queryAlertDefinesByAppAndMetricAndPresetTrueAndEnableTrue(app, metrics);
|
||||
defines.addAll(defaultDefines);
|
||||
Set<AlertDefine> defineSet = defines.stream().filter(item -> item.getField() != null).collect(Collectors.toSet());
|
||||
// The alarm thresholds are defined in ascending order of the alarm severity from 0 to 3.
|
||||
// The lower the number, the higher the alarm is. That is, the alarm is calculated from the highest alarm threshold
|
||||
return defineSet.stream().sorted(Comparator.comparing(AlertDefine::getPriority))
|
||||
.collect(Collectors.groupingBy(AlertDefine::getField));
|
||||
}
|
||||
|
||||
@Override
|
||||
public AlertDefine getMonitorBindAlertAvaDefine(long monitorId, String app, String metrics) {
|
||||
List<AlertDefine> defines = alertDefineDao.queryAlertDefinesByMonitor(monitorId, app, metrics);
|
||||
List<AlertDefine> defaultDefines = alertDefineDao.queryAlertDefinesByAppAndMetricAndPresetTrueAndEnableTrue(app, metrics);
|
||||
defines.addAll(defaultDefines);
|
||||
return defines.stream().findFirst().orElse(null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Page<AlertDefine> getAlertDefines(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();
|
||||
@@ -164,10 +190,10 @@ public class AlertDefineServiceImpl implements AlertDefineService {
|
||||
for (String searchContent : finalSearchList) {
|
||||
searchContent = searchContent.toLowerCase();
|
||||
Predicate predicate = criteriaBuilder.or(
|
||||
criteriaBuilder.like(criteriaBuilder.lower(root.get("name")), "%" + searchContent + "%"),
|
||||
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("labels")), "%" + searchContent + "%"),
|
||||
criteriaBuilder.like(criteriaBuilder.lower(root.get("annotations")), "%" + searchContent + "%"),
|
||||
criteriaBuilder.like(criteriaBuilder.lower(root.get("template")), "%" + searchContent + "%")
|
||||
);
|
||||
searchPredicates.add(predicate);
|
||||
@@ -175,6 +201,10 @@ public class AlertDefineServiceImpl implements AlertDefineService {
|
||||
// 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));
|
||||
};
|
||||
@@ -183,6 +213,28 @@ public class AlertDefineServiceImpl implements AlertDefineService {
|
||||
return alertDefineDao.findAll(specification, pageRequest);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<AlertDefineMonitorBind> getBindAlertDefineMonitors(long 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
|
||||
public void export(List<Long> ids, String type, HttpServletResponse res) throws Exception {
|
||||
var imExportService = alertDefineImExportServiceMap.get(type);
|
||||
@@ -208,14 +260,4 @@ public class AlertDefineServiceImpl implements AlertDefineService {
|
||||
var imExportService = alertDefineImExportServiceMap.get(type);
|
||||
imExportService.importConfig(file.getInputStream());
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<AlertDefine> getRealTimeAlertDefines() {
|
||||
List<AlertDefine> alertDefines = CacheFactory.getAlertDefineCache();
|
||||
if (alertDefines == null) {
|
||||
alertDefines = alertDefineDao.findAlertDefinesByTypeAndEnableTrue(ALERT_THRESHOLD_TYPE_REALTIME);
|
||||
CacheFactory.setAlertDefineCache(alertDefines);
|
||||
}
|
||||
return alertDefines;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,236 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.apache.hertzbeat.alert.service.impl;
|
||||
|
||||
import jakarta.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.Date;
|
||||
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;
|
||||
|
||||
/**
|
||||
* Realization of Alarm Information Service
|
||||
*/
|
||||
@Service
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
@Slf4j
|
||||
public class AlertServiceImpl implements AlertService {
|
||||
|
||||
@Autowired
|
||||
private AlertDao alertDao;
|
||||
|
||||
@Autowired
|
||||
private AlarmCommonReduce alarmCommonReduce;
|
||||
|
||||
@Override
|
||||
public void addAlert(Alert alert) throws RuntimeException {
|
||||
alertDao.save(alert);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Page<Alert> getAlerts(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);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deleteAlerts(HashSet<Long> ids) {
|
||||
alertDao.deleteAlertsByIdIn(ids);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clearAlerts() {
|
||||
alertDao.deleteAll();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void editAlertStatus(Byte status, List<Long> ids) {
|
||||
alertDao.updateAlertsStatus(status, ids);
|
||||
}
|
||||
|
||||
@Override
|
||||
public AlertSummary getAlertsSummary() {
|
||||
AlertSummary alertSummary = new AlertSummary();
|
||||
// Statistics on the alarm information in the alarm state
|
||||
List<AlertPriorityNum> priorityNums = alertDao.findAlertPriorityNum();
|
||||
if (priorityNums != null) {
|
||||
for (AlertPriorityNum priorityNum : priorityNums) {
|
||||
switch (priorityNum.getPriority()) {
|
||||
case CommonConstants
|
||||
.ALERT_PRIORITY_CODE_WARNING -> alertSummary.setPriorityWarningNum(priorityNum.getNum());
|
||||
case CommonConstants.ALERT_PRIORITY_CODE_CRITICAL -> alertSummary.setPriorityCriticalNum(priorityNum.getNum());
|
||||
case CommonConstants.ALERT_PRIORITY_CODE_EMERGENCY -> alertSummary.setPriorityEmergencyNum(priorityNum.getNum());
|
||||
default -> {}
|
||||
}
|
||||
}
|
||||
}
|
||||
long total = alertDao.count();
|
||||
alertSummary.setTotal(total);
|
||||
long dealNum = total - alertSummary.getPriorityCriticalNum()
|
||||
- alertSummary.getPriorityEmergencyNum() - alertSummary.getPriorityWarningNum();
|
||||
alertSummary.setDealNum(dealNum);
|
||||
try {
|
||||
if (total == 0) {
|
||||
alertSummary.setRate(100);
|
||||
} else {
|
||||
float rate = BigDecimal.valueOf(100 * (float) dealNum / total)
|
||||
.setScale(2, RoundingMode.HALF_UP)
|
||||
.floatValue();
|
||||
alertSummary.setRate(rate);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.error(e.getMessage(), e);
|
||||
}
|
||||
return alertSummary;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addNewAlertReport(AlertReport alertReport) {
|
||||
alarmCommonReduce.reduceAndSendAlarm(buildAlertData(alertReport));
|
||||
}
|
||||
|
||||
@Override
|
||||
public 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(new Date().getTime())
|
||||
.priority(1)
|
||||
.reportType(1)
|
||||
.build();
|
||||
}
|
||||
Optional.ofNullable(alert).ifPresent(this::addNewAlertReport);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Alert> getAlerts(Specification<Alert> specification) {
|
||||
|
||||
return alertDao.findAll(specification);
|
||||
}
|
||||
|
||||
/**
|
||||
* The external alarm information is converted to Alert
|
||||
* @param alertReport alarm body
|
||||
* @return Alert entity
|
||||
*/
|
||||
private Alert buildAlertData(AlertReport alertReport){
|
||||
Map<String, String> annotations = alertReport.getAnnotations();
|
||||
StringBuilder sb = new StringBuilder();
|
||||
if (alertReport.getContent() == null || alertReport.getContent().length() <= 0){
|
||||
StringBuilder finalSb = sb;
|
||||
annotations.forEach((k, v) -> finalSb.append(k).append(":").append(v).append("\n"));
|
||||
} else {
|
||||
sb = new StringBuilder(alertReport.getContent());
|
||||
}
|
||||
LocalDateTime dateTime = LocalDateTime.ofInstant(Instant.ofEpochMilli(alertReport.getAlertTime()),
|
||||
ZoneId.systemDefault());
|
||||
return Alert.builder()
|
||||
.content("Alert Center\n" + sb)
|
||||
.priority(alertReport.getPriority().byteValue())
|
||||
.status(CommonConstants.ALERT_STATUS_CODE_PENDING)
|
||||
.tags(alertReport.getLabels())
|
||||
.target(alertReport.getAlertName())
|
||||
.triggerTimes(1)
|
||||
.firstAlarmTime(alertReport.getAlertTime())
|
||||
.lastAlarmTime(alertReport.getAlertTime())
|
||||
.gmtCreate(dateTime)
|
||||
.gmtUpdate(dateTime)
|
||||
.build();
|
||||
}
|
||||
}
|
||||
+4
-1
@@ -27,6 +27,8 @@ import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.hertzbeat.alert.dao.AlertSilenceDao;
|
||||
import org.apache.hertzbeat.alert.service.AlertSilenceService;
|
||||
import org.apache.hertzbeat.common.cache.CacheFactory;
|
||||
import org.apache.hertzbeat.common.cache.CommonCacheService;
|
||||
import org.apache.hertzbeat.common.constants.CommonConstants;
|
||||
import org.apache.hertzbeat.common.entity.alerter.AlertSilence;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.data.domain.Page;
|
||||
@@ -109,6 +111,7 @@ public class AlertSilenceServiceImpl implements AlertSilenceService {
|
||||
}
|
||||
|
||||
private void clearAlertSilencesCache() {
|
||||
CacheFactory.clearAlertSilenceCache();
|
||||
CommonCacheService<String, Object> silenceCache = CacheFactory.getAlertSilenceCache();
|
||||
silenceCache.remove(CommonConstants.CACHE_ALERT_SILENCE);
|
||||
}
|
||||
}
|
||||
+31
-30
@@ -27,10 +27,9 @@ import static org.springframework.test.web.servlet.request.MockMvcRequestBuilder
|
||||
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.AlertGroupConvergeService;
|
||||
import org.apache.hertzbeat.alert.service.AlertConvergeService;
|
||||
import org.apache.hertzbeat.common.constants.CommonConstants;
|
||||
import org.apache.hertzbeat.common.entity.alerter.AlertGroupConverge;
|
||||
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;
|
||||
@@ -42,27 +41,28 @@ import org.springframework.http.MediaType;
|
||||
import org.springframework.test.web.servlet.MockMvc;
|
||||
|
||||
/**
|
||||
* test case for {@link AlertGroupConvergeController}
|
||||
* test case for {@link AlertConvergeController}
|
||||
*/
|
||||
|
||||
@ExtendWith(MockitoExtension.class)
|
||||
public class AlertGroupConvergeControllerTest {
|
||||
public class AlertConvergeControllerTest {
|
||||
|
||||
private MockMvc mockMvc;
|
||||
|
||||
@Mock
|
||||
private AlertGroupConvergeService alertGroupConvergeService;
|
||||
private AlertConvergeService alertConvergeService;
|
||||
|
||||
private AlertGroupConverge alertGroupConverge;
|
||||
private AlertConverge alertConverge;
|
||||
|
||||
@InjectMocks
|
||||
private AlertGroupConvergeController alertGroupConvergeController;
|
||||
private AlertConvergeController alertConvergeController;
|
||||
|
||||
@BeforeEach
|
||||
void setUp() {
|
||||
|
||||
this.mockMvc = standaloneSetup(alertGroupConvergeController).build();
|
||||
this.mockMvc = standaloneSetup(alertConvergeController).build();
|
||||
|
||||
alertGroupConverge = AlertGroupConverge.builder()
|
||||
alertConverge = AlertConverge.builder()
|
||||
.name("test")
|
||||
.creator("admin")
|
||||
.modifier("admin")
|
||||
@@ -71,53 +71,54 @@ public class AlertGroupConvergeControllerTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
void testAddNewAlertGroupConverge() throws Exception {
|
||||
void testAddNewAlertConverge() throws Exception {
|
||||
|
||||
doNothing().when(alertGroupConvergeService).validate(any(AlertGroupConverge.class), eq(false));
|
||||
doNothing().when(alertGroupConvergeService).addAlertGroupConverge(any(AlertGroupConverge.class));
|
||||
doNothing().when(alertConvergeService).validate(any(AlertConverge.class), eq(false));
|
||||
doNothing().when(alertConvergeService).addAlertConverge(any(AlertConverge.class));
|
||||
|
||||
mockMvc.perform(post("/api/alert/group")
|
||||
mockMvc.perform(post("/api/alert/converge")
|
||||
.contentType(MediaType.APPLICATION_JSON)
|
||||
.content(JsonUtil.toJson(alertGroupConverge)))
|
||||
.andExpect(status().isOk())
|
||||
.content(JsonUtil.toJson(alertConverge))
|
||||
).andExpect(status().isOk())
|
||||
.andExpect(jsonPath("$.code").value((int) CommonConstants.SUCCESS_CODE))
|
||||
.andExpect(jsonPath("$.msg").value("Add success"));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testModifyAlertGroupConverge() throws Exception {
|
||||
void testModifyAlertConverge() throws Exception {
|
||||
|
||||
doNothing().when(alertGroupConvergeService).validate(any(AlertGroupConverge.class), eq(true));
|
||||
doNothing().when(alertGroupConvergeService).modifyAlertGroupConverge(any(AlertGroupConverge.class));
|
||||
doNothing().when(alertConvergeService).validate(any(AlertConverge.class), eq(true));
|
||||
doNothing().when(alertConvergeService).modifyAlertConverge(any(AlertConverge.class));
|
||||
|
||||
mockMvc.perform(put("/api/alert/group")
|
||||
mockMvc.perform(put("/api/alert/converge")
|
||||
.contentType(MediaType.APPLICATION_JSON)
|
||||
.content(JsonUtil.toJson(alertGroupConverge)))
|
||||
.andExpect(status().isOk())
|
||||
.content(JsonUtil.toJson(alertConverge))
|
||||
).andExpect(status().isOk())
|
||||
.andExpect(jsonPath("$.code").value((int) CommonConstants.SUCCESS_CODE))
|
||||
.andExpect(jsonPath("$.msg").value("Modify success"));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testGetAlertGroupConvergeExists() throws Exception {
|
||||
void testGetAlertConvergeExists() throws Exception {
|
||||
|
||||
when(alertGroupConvergeService.getAlertGroupConverge(1L)).thenReturn(alertGroupConverge);
|
||||
when(alertConvergeService.getAlertConverge(1L)).thenReturn(alertConverge);
|
||||
|
||||
mockMvc.perform(get("/api/alert/group/{id}", 1L)
|
||||
mockMvc.perform(get("/api/alert/converge/{id}", 1L)
|
||||
.accept(MediaType.APPLICATION_JSON))
|
||||
.andExpect(status().isOk())
|
||||
.andExpect(jsonPath("$.data.id").value(alertGroupConverge.getId()));
|
||||
.andExpect(jsonPath("$.data.id").value(alertConverge.getId()));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testGetAlertGroupConvergeNotExists() throws Exception {
|
||||
void testGetAlertConvergeNotExists() throws Exception {
|
||||
|
||||
when(alertGroupConvergeService.getAlertGroupConverge(1L)).thenReturn(null);
|
||||
when(alertConvergeService.getAlertConverge(1L)).thenReturn(null);
|
||||
|
||||
mockMvc.perform(get("/api/alert/group/{id}", 1L)
|
||||
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("Alert Group Converge not exist."));
|
||||
.andExpect(jsonPath("$.msg").value("AlertConverge not exist."));
|
||||
}
|
||||
|
||||
}
|
||||
+21
-21
@@ -29,9 +29,9 @@ import static org.springframework.test.web.servlet.setup.MockMvcBuilders.standal
|
||||
import java.util.Arrays;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import org.apache.hertzbeat.alert.service.AlertGroupConvergeService;
|
||||
import org.apache.hertzbeat.alert.service.AlertConvergeService;
|
||||
import org.apache.hertzbeat.common.constants.CommonConstants;
|
||||
import org.apache.hertzbeat.common.entity.alerter.AlertGroupConverge;
|
||||
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;
|
||||
@@ -47,59 +47,58 @@ import org.springframework.test.web.servlet.MockMvc;
|
||||
|
||||
|
||||
/**
|
||||
* test case for {@link AlertGroupConvergesController}
|
||||
* test case for {@link AlertConvergesController}
|
||||
*/
|
||||
|
||||
@ExtendWith(MockitoExtension.class)
|
||||
class AlertGroupConvergesControllerTest {
|
||||
class AlertConvergesControllerTest {
|
||||
|
||||
private MockMvc mockMvc;
|
||||
|
||||
@Mock
|
||||
private AlertGroupConvergeService alertGroupConvergeService;
|
||||
private AlertConvergeService alertConvergeService;
|
||||
|
||||
@InjectMocks
|
||||
private AlertGroupConvergesController alertGroupConvergesController;
|
||||
private AlertConvergesController alertConvergesController;
|
||||
|
||||
private List<AlertGroupConverge> alertGroupConvergeList;
|
||||
private List<AlertConverge> alertConvergeList;
|
||||
|
||||
@BeforeEach
|
||||
void setUp() {
|
||||
|
||||
this.mockMvc = standaloneSetup(alertGroupConvergesController).build();
|
||||
this.mockMvc = standaloneSetup(alertConvergesController).build();
|
||||
|
||||
AlertGroupConverge alertGroupConverge1 = AlertGroupConverge.builder()
|
||||
AlertConverge alertConverge1 = AlertConverge.builder()
|
||||
.name("Converge1")
|
||||
.id(1L)
|
||||
.build();
|
||||
|
||||
AlertGroupConverge alertGroupConverge2 = AlertGroupConverge.builder()
|
||||
AlertConverge alertConverge2 = AlertConverge.builder()
|
||||
.name("Converge2")
|
||||
.id(2L)
|
||||
.build();
|
||||
|
||||
alertGroupConvergeList = Arrays.asList(alertGroupConverge1, alertGroupConverge2);
|
||||
alertConvergeList = Arrays.asList(alertConverge1, alertConverge2);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testGetAlertGroupConverges() throws Exception {
|
||||
void testGetAlertConverges() throws Exception {
|
||||
|
||||
Page<AlertGroupConverge> alertGroupConvergePage = new PageImpl<>(
|
||||
alertGroupConvergeList,
|
||||
Page<AlertConverge> alertConvergePage = new PageImpl<>(
|
||||
alertConvergeList,
|
||||
PageRequest.of(0, 8, Sort.by("id").descending()),
|
||||
alertGroupConvergeList.size()
|
||||
alertConvergeList.size()
|
||||
);
|
||||
|
||||
when(alertGroupConvergeService.getAlertGroupConverges(null, null, "id", "desc", 0, 8)).thenReturn(alertGroupConvergePage);
|
||||
when(alertConvergeService.getAlertConverges(null, null, "id", "desc", 0, 8)).thenReturn(alertConvergePage);
|
||||
|
||||
mockMvc.perform(get("/api/alert/groups")
|
||||
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("$.code").value((int) CommonConstants.SUCCESS_CODE))
|
||||
.andExpect(jsonPath("$.data.content[0].id").value(1))
|
||||
.andExpect(jsonPath("$.data.content[0].name").value("Converge1"))
|
||||
.andExpect(jsonPath("$.data.content[1].id").value(2))
|
||||
@@ -109,12 +108,13 @@ class AlertGroupConvergesControllerTest {
|
||||
@Test
|
||||
void testDeleteAlertDefines() throws Exception {
|
||||
|
||||
doNothing().when(alertGroupConvergeService).deleteAlertGroupConverges(eq(new HashSet<>(Arrays.asList(1L, 2L))));
|
||||
doNothing().when(alertConvergeService).deleteAlertConverges(eq(new HashSet<>(Arrays.asList(1L, 2L))));
|
||||
|
||||
mockMvc.perform(delete("/api/alert/groups")
|
||||
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));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+32
-1
@@ -64,8 +64,12 @@ class AlertDefineControllerTest {
|
||||
|
||||
this.alertDefine = AlertDefine.builder()
|
||||
.id(1L)
|
||||
.name("alertDefine")
|
||||
.app("app")
|
||||
.metric("test")
|
||||
.field("test")
|
||||
.preset(false)
|
||||
.expr("1 > 0")
|
||||
.priority((byte) 1)
|
||||
.times(1)
|
||||
.template("template")
|
||||
.creator("tom")
|
||||
@@ -121,6 +125,9 @@ class AlertDefineControllerTest {
|
||||
.andExpect(status().isOk())
|
||||
.andExpect(jsonPath("$.code").value((int) CommonConstants.SUCCESS_CODE))
|
||||
.andExpect(jsonPath("$.data.id").value(alertDefine.getId()))
|
||||
.andExpect(jsonPath("$.data.app").value(alertDefine.getApp()))
|
||||
.andExpect(jsonPath("$.data.metric").value(alertDefine.getMetric()))
|
||||
.andExpect(jsonPath("$.data.field").value(alertDefine.getField()))
|
||||
.andExpect(jsonPath("$.data.expr").value(alertDefine.getExpr()))
|
||||
.andExpect(jsonPath("$.data.template").value(alertDefine.getTemplate()))
|
||||
.andExpect(jsonPath("$.data.gmtCreate").value(alertDefine.getGmtCreate()))
|
||||
@@ -137,4 +144,28 @@ class AlertDefineControllerTest {
|
||||
.andExpect(jsonPath("$.code").value((int) CommonConstants.SUCCESS_CODE))
|
||||
.andReturn();
|
||||
}
|
||||
|
||||
@Test
|
||||
void applyAlertDefineMonitorsBind() throws Exception {
|
||||
mockMvc.perform(MockMvcRequestBuilders.post("/api/alert/define/" + this.alertDefine.getId() + "/monitors")
|
||||
.contentType(MediaType.APPLICATION_JSON)
|
||||
.content(JsonUtil.toJson(this.alertDefineMonitorBinds)))
|
||||
.andExpect(status().isOk())
|
||||
.andExpect(jsonPath("$.code").value((int) CommonConstants.SUCCESS_CODE))
|
||||
.andReturn();
|
||||
}
|
||||
|
||||
@Test
|
||||
void getAlertDefineMonitorsBind() throws Exception {
|
||||
Mockito.when(alertDefineService.getBindAlertDefineMonitors(this.alertDefine.getId()))
|
||||
.thenReturn(this.alertDefineMonitorBinds);
|
||||
|
||||
mockMvc.perform(MockMvcRequestBuilders.get("/api/alert/define/" + this.alertDefine.getId() + "/monitors")
|
||||
.contentType(MediaType.APPLICATION_JSON))
|
||||
.andExpect(status().isOk())
|
||||
.andExpect(jsonPath("$.code").value((int) CommonConstants.SUCCESS_CODE))
|
||||
.andExpect(jsonPath("$.data[0].id").value(alertDefineMonitorBinds.get(0).getId()))
|
||||
.andExpect(jsonPath("$.data[0].monitor.id").value(alertDefineMonitorBinds.get(0).getMonitor().getId()))
|
||||
.andReturn();
|
||||
}
|
||||
}
|
||||
+24
-17
@@ -19,8 +19,10 @@ package org.apache.hertzbeat.alert.controller;
|
||||
|
||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
|
||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
@@ -90,7 +92,8 @@ class AlertDefinesControllerTest {
|
||||
pageRequest = PageRequest.of((Integer) content.get("pageIndex"), (Integer) content.get("pageSize"), sortExp);
|
||||
}
|
||||
|
||||
@Test
|
||||
// @Test
|
||||
// todo: fix this test
|
||||
void getAlertDefines() throws Exception {
|
||||
|
||||
// Test the correctness of the mock
|
||||
@@ -107,28 +110,32 @@ class AlertDefinesControllerTest {
|
||||
// return false;
|
||||
// }
|
||||
// }))).thenReturn(new PageImpl<AlertDefine>(new ArrayList<AlertDefine>()));
|
||||
AlertDefine define = AlertDefine.builder().id(9L).expr("x").times(1).build();
|
||||
PageRequest pageRequest = PageRequest.of(pageIndex, pageSize, Sort.by(Sort.Order.asc(sort)));
|
||||
Mockito.when(alertDefineService.getAlertDefines(
|
||||
Mockito.eq(ids),
|
||||
Mockito.isNull(),
|
||||
Mockito.eq(sort),
|
||||
Mockito.eq(order),
|
||||
Mockito.eq(pageIndex),
|
||||
Mockito.eq(pageSize)
|
||||
)).thenReturn(new PageImpl<>(Collections.singletonList(define), pageRequest, 1));
|
||||
AlertDefine define = AlertDefine.builder().id(9L).app("linux").metric("disk").field("usage").expr("x").times(1).tags(new LinkedList<>()).build();
|
||||
Mockito.when(alertDefineService.getAlertDefines(null, null, null, "id", "desc", 1, 10)).thenReturn(new PageImpl<>(Collections.singletonList(define)));
|
||||
|
||||
mockMvc.perform(MockMvcRequestBuilders.get("/api/alert/defines")
|
||||
mockMvc.perform(MockMvcRequestBuilders.get(
|
||||
"/api/alert/defines")
|
||||
.param("ids", ids.toString().substring(1, ids.toString().length() - 1))
|
||||
.param("priority", priority.toString())
|
||||
.param("sort", sort)
|
||||
.param("order", order)
|
||||
.param("pageIndex", String.valueOf(pageIndex))
|
||||
.param("pageSize", String.valueOf(pageSize)))
|
||||
.param("pageIndex", pageIndex.toString())
|
||||
.param("pageSize", pageSize.toString()))
|
||||
.andExpect(status().isOk())
|
||||
.andExpect(jsonPath("$.code").value((int) CommonConstants.SUCCESS_CODE))
|
||||
.andExpect(jsonPath("$.data.content[0].id").value(9))
|
||||
.andExpect(jsonPath("$.data.content[0].expr").value("x"))
|
||||
.andExpect(jsonPath("$.data.content[0].times").value(1))
|
||||
.andExpect(jsonPath("$.data.content").value(new ArrayList<>()))
|
||||
.andExpect(jsonPath("$.data.pageable").value("INSTANCE"))
|
||||
.andExpect(jsonPath("$.data.totalPages").value(1))
|
||||
.andExpect(jsonPath("$.data.totalElements").value(0))
|
||||
.andExpect(jsonPath("$.data.last").value(true))
|
||||
.andExpect(jsonPath("$.data.number").value(0))
|
||||
.andExpect(jsonPath("$.data.size").value(0))
|
||||
.andExpect(jsonPath("$.data.first").value(true))
|
||||
.andExpect(jsonPath("$.data.numberOfElements").value(0))
|
||||
.andExpect(jsonPath("$.data.empty").value(true))
|
||||
.andExpect(jsonPath("$.data.sort.empty").value(true))
|
||||
.andExpect(jsonPath("$.data.sort.sorted").value(false))
|
||||
.andExpect(jsonPath("$.data.sort.unsorted").value(true))
|
||||
.andReturn();
|
||||
}
|
||||
|
||||
+17
-32
@@ -17,19 +17,15 @@
|
||||
|
||||
package org.apache.hertzbeat.alert.controller;
|
||||
|
||||
import static org.mockito.ArgumentMatchers.anyString;
|
||||
import static org.mockito.Mockito.doNothing;
|
||||
import static org.mockito.Mockito.when;
|
||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content;
|
||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
|
||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
|
||||
import java.util.HashMap;
|
||||
import org.apache.hertzbeat.alert.dto.TencentCloudExternAlert;
|
||||
import org.apache.hertzbeat.alert.service.ExternAlertService;
|
||||
import org.apache.hertzbeat.alert.dto.GeneralCloudAlertReport;
|
||||
import org.apache.hertzbeat.alert.dto.TenCloudAlertReport;
|
||||
import org.apache.hertzbeat.alert.service.AlertService;
|
||||
import org.apache.hertzbeat.common.constants.CommonConstants;
|
||||
import org.apache.hertzbeat.common.entity.alerter.SingleAlert;
|
||||
import org.apache.hertzbeat.common.util.JsonUtil;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Disabled;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
import org.mockito.InjectMocks;
|
||||
@@ -40,18 +36,16 @@ import org.springframework.test.web.servlet.MockMvc;
|
||||
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
|
||||
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
|
||||
|
||||
|
||||
/**
|
||||
* unit test for {@link AlertReportController }
|
||||
*/
|
||||
@Disabled
|
||||
@ExtendWith(MockitoExtension.class)
|
||||
class AlertReportControllerTest {
|
||||
|
||||
private MockMvc mockMvc;
|
||||
|
||||
@Mock
|
||||
private ExternAlertService externAlertService;
|
||||
private AlertService alertService;
|
||||
|
||||
@InjectMocks
|
||||
private AlertReportController alertReportController;
|
||||
@@ -63,17 +57,17 @@ class AlertReportControllerTest {
|
||||
|
||||
@Test
|
||||
void addNewAlertReportTencent() throws Exception {
|
||||
TencentCloudExternAlert.Dimensions dimensions = new TencentCloudExternAlert.Dimensions();
|
||||
TenCloudAlertReport.Dimensions dimensions = new TenCloudAlertReport.Dimensions();
|
||||
dimensions.setUnInstanceId("3333");
|
||||
|
||||
TencentCloudExternAlert.AlarmObjInfo alarmObjInfo = new TencentCloudExternAlert.AlarmObjInfo();
|
||||
TenCloudAlertReport.AlarmObjInfo alarmObjInfo = new TenCloudAlertReport.AlarmObjInfo();
|
||||
alarmObjInfo.setRegion("Guangzhou");
|
||||
alarmObjInfo.setNamespace("Guangzhou1");
|
||||
alarmObjInfo.setAppId("1111");
|
||||
alarmObjInfo.setUin("2222");
|
||||
alarmObjInfo.setDimensions(dimensions);
|
||||
|
||||
TencentCloudExternAlert.Conditions conditions = new TencentCloudExternAlert.Conditions();
|
||||
TenCloudAlertReport.Conditions conditions = new TenCloudAlertReport.Conditions();
|
||||
conditions.setMetricName("xx");
|
||||
conditions.setMetricShowName("xxx");
|
||||
conditions.setCalcType("a");
|
||||
@@ -86,12 +80,12 @@ class AlertReportControllerTest {
|
||||
conditions.setEventName("CVS");
|
||||
conditions.setEventShowName("Core error");
|
||||
|
||||
TencentCloudExternAlert.AlarmPolicyInfo alarmPolicyInfo = new TencentCloudExternAlert.AlarmPolicyInfo();
|
||||
TenCloudAlertReport.AlarmPolicyInfo alarmPolicyInfo = new TenCloudAlertReport.AlarmPolicyInfo();
|
||||
alarmPolicyInfo.setPolicyTypeCname("x");
|
||||
alarmPolicyInfo.setPolicyName("Test1");
|
||||
alarmPolicyInfo.setConditions(conditions);
|
||||
|
||||
TencentCloudExternAlert report = TencentCloudExternAlert.builder()
|
||||
TenCloudAlertReport report = TenCloudAlertReport.builder()
|
||||
.sessionId("123")
|
||||
.alarmStatus("1")
|
||||
.alarmType("event")
|
||||
@@ -100,40 +94,31 @@ class AlertReportControllerTest {
|
||||
.alarmObjInfo(alarmObjInfo)
|
||||
.alarmPolicyInfo(alarmPolicyInfo)
|
||||
.build();
|
||||
when(externAlertService.supportSource()).thenReturn("tencent");
|
||||
doNothing().when(externAlertService).addExternAlert(anyString());
|
||||
mockMvc.perform(
|
||||
MockMvcRequestBuilders
|
||||
.post("/api/alerts/report/tencent")
|
||||
.post("/api/alerts/report/tencloud")
|
||||
.contentType(MediaType.APPLICATION_JSON)
|
||||
.content(JsonUtil.toJson(report))
|
||||
)
|
||||
.andExpect(status().isOk())
|
||||
.andExpect(jsonPath("$.code").value((int) CommonConstants.SUCCESS_CODE))
|
||||
.andExpect(content().json("{\"data\":null,\"msg\":\"Add report success\",\"code\":0}"))
|
||||
.andReturn();
|
||||
}
|
||||
|
||||
@Test
|
||||
void addNewAlertReport() throws Exception {
|
||||
SingleAlert singleAlert = SingleAlert.builder()
|
||||
.fingerprint("fingerprint")
|
||||
.labels(new HashMap<>())
|
||||
.annotations(new HashMap<>())
|
||||
.content("content")
|
||||
.status("firing")
|
||||
.triggerTimes(1)
|
||||
.startAt(1734005477630L)
|
||||
.activeAt(1734005477630L)
|
||||
.build();
|
||||
when(externAlertService.supportSource()).thenReturn("default");
|
||||
doNothing().when(externAlertService).addExternAlert(anyString());
|
||||
GeneralCloudAlertReport generalCloudAlertReport = new GeneralCloudAlertReport();
|
||||
generalCloudAlertReport.setAlertDateTime("2023-02-22T07:27:15.404000000Z");
|
||||
|
||||
mockMvc.perform(MockMvcRequestBuilders
|
||||
.post("/api/alerts/report")
|
||||
.contentType(MediaType.APPLICATION_JSON)
|
||||
.content(JsonUtil.toJson(singleAlert))
|
||||
.content(JsonUtil.toJson(generalCloudAlertReport))
|
||||
)
|
||||
.andExpect(status().isOk())
|
||||
.andExpect(jsonPath("$.code").value((int) CommonConstants.SUCCESS_CODE))
|
||||
.andExpect(content().json("{\"data\":null,\"msg\":\"Add report success\",\"code\":0}"))
|
||||
.andReturn();
|
||||
}
|
||||
}
|
||||
+29
-12
@@ -27,7 +27,7 @@ import java.util.stream.LongStream;
|
||||
import org.apache.hertzbeat.alert.dto.AlertSummary;
|
||||
import org.apache.hertzbeat.alert.service.AlertService;
|
||||
import org.apache.hertzbeat.common.constants.CommonConstants;
|
||||
import org.apache.hertzbeat.common.entity.alerter.GroupAlert;
|
||||
import org.apache.hertzbeat.common.entity.alerter.Alert;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
@@ -71,23 +71,28 @@ class AlertsControllerTest {
|
||||
void getAlerts() throws Exception {
|
||||
String sortField = "id";
|
||||
String orderType = "desc";
|
||||
String status = "firing";
|
||||
Byte priority = 1;
|
||||
Byte status = 1;
|
||||
Long monitorId = 1L;
|
||||
String content = "test";
|
||||
int pageIndex = 0;
|
||||
int pageSize = 10;
|
||||
|
||||
Page<GroupAlert> alertPage = new PageImpl<>(
|
||||
Collections.singletonList(GroupAlert.builder().build()),
|
||||
Page<Alert> alertPage = new PageImpl<>(
|
||||
Collections.singletonList(Alert.builder().build()),
|
||||
PageRequest.of(pageIndex, pageSize, Sort.by(sortField).descending()),
|
||||
ids.size()
|
||||
);
|
||||
Mockito.when(alertService.getGroupAlerts(status, content, sortField, orderType, pageIndex, pageSize))
|
||||
Mockito.when(alertService.getAlerts(ids, monitorId, priority, status, content, sortField, orderType, pageIndex, pageSize))
|
||||
.thenReturn(alertPage);
|
||||
|
||||
mockMvc.perform(MockMvcRequestBuilders
|
||||
.get("/api/alerts/group")
|
||||
.param("status", status)
|
||||
.param("search", content)
|
||||
.get("/api/alerts")
|
||||
.param("ids", ids.stream().map(String::valueOf).collect(Collectors.joining(",")))
|
||||
.param("monitorId", String.valueOf(monitorId))
|
||||
.param("priority", String.valueOf(priority))
|
||||
.param("status", String.valueOf(status))
|
||||
.param("content", content)
|
||||
.param("sort", sortField)
|
||||
.param("order", orderType)
|
||||
.param("pageIndex", String.valueOf(pageIndex))
|
||||
@@ -100,10 +105,10 @@ class AlertsControllerTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
void deleteGroupAlerts() throws Exception {
|
||||
void deleteAlerts() throws Exception {
|
||||
mockMvc.perform(
|
||||
MockMvcRequestBuilders
|
||||
.delete("/api/alerts/group")
|
||||
.delete("/api/alerts")
|
||||
.param("ids", ids.stream().map(String::valueOf).collect(Collectors.joining(",")))
|
||||
)
|
||||
.andExpect(status().isOk())
|
||||
@@ -113,10 +118,22 @@ class AlertsControllerTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
void applyGroupAlertStatus() throws Exception {
|
||||
void clearAllAlerts() throws Exception {
|
||||
mockMvc.perform(
|
||||
MockMvcRequestBuilders
|
||||
.put("/api/alerts/group/status/resolved")
|
||||
.delete("/api/alerts/clear")
|
||||
)
|
||||
.andExpect(status().isOk())
|
||||
.andExpect(jsonPath("$.code").value((int) CommonConstants.SUCCESS_CODE))
|
||||
.andExpect(content().json("{\"data\":null,\"msg\":null,\"code\":0}"))
|
||||
.andReturn();
|
||||
}
|
||||
|
||||
@Test
|
||||
void applyAlertDefinesStatus() throws Exception {
|
||||
mockMvc.perform(
|
||||
MockMvcRequestBuilders
|
||||
.put("/api/alerts/status/1")
|
||||
.param("ids", ids.stream().map(String::valueOf).collect(Collectors.joining(",")))
|
||||
)
|
||||
.andExpect(status().isOk())
|
||||
@@ -0,0 +1,134 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.apache.hertzbeat.alert.reduce;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.ArgumentMatchers.anyLong;
|
||||
import static org.mockito.Mockito.doReturn;
|
||||
import static org.mockito.Mockito.never;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import org.apache.hertzbeat.alert.dao.AlertMonitorDao;
|
||||
import org.apache.hertzbeat.common.constants.CommonConstants;
|
||||
import org.apache.hertzbeat.common.entity.alerter.Alert;
|
||||
import org.apache.hertzbeat.common.entity.manager.Tag;
|
||||
import org.apache.hertzbeat.common.queue.CommonDataQueue;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.junit.jupiter.MockitoExtension;
|
||||
|
||||
/**
|
||||
* test case for {@link AlarmCommonReduce}
|
||||
*/
|
||||
|
||||
@ExtendWith(MockitoExtension.class)
|
||||
class AlarmCommonReduceTest {
|
||||
|
||||
@Mock
|
||||
private AlarmSilenceReduce alarmSilenceReduce;
|
||||
|
||||
@Mock
|
||||
private AlarmConvergeReduce alarmConvergeReduce;
|
||||
|
||||
@Mock
|
||||
private CommonDataQueue dataQueue;
|
||||
|
||||
@Mock
|
||||
private AlertMonitorDao alertMonitorDao;
|
||||
|
||||
private AlarmCommonReduce alarmCommonReduce;
|
||||
|
||||
private Alert testAlert;
|
||||
|
||||
@BeforeEach
|
||||
void setUp() {
|
||||
|
||||
testAlert = Alert.builder().build();
|
||||
alarmCommonReduce = new AlarmCommonReduce(
|
||||
alarmSilenceReduce,
|
||||
alarmConvergeReduce,
|
||||
dataQueue,
|
||||
alertMonitorDao
|
||||
);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testReduceAndSendAlarmNoMonitorId() {
|
||||
|
||||
when(alarmConvergeReduce.filterConverge(testAlert)).thenReturn(true);
|
||||
when(alarmSilenceReduce.filterSilence(testAlert)).thenReturn(true);
|
||||
|
||||
alarmCommonReduce.reduceAndSendAlarm(testAlert);
|
||||
|
||||
verify(dataQueue).sendAlertsData(testAlert);
|
||||
verify(alertMonitorDao, never()).findMonitorIdBindTags(anyLong());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testReduceAndSendAlarmWithMonitorId() {
|
||||
|
||||
Map<String, String> tags = new HashMap<>();
|
||||
tags.put(CommonConstants.TAG_MONITOR_ID, "123");
|
||||
testAlert.setTags(tags);
|
||||
|
||||
doReturn(Collections.singletonList(
|
||||
Tag.builder()
|
||||
.name("newTag")
|
||||
.tagValue("tagValue")
|
||||
.build())
|
||||
).when(alertMonitorDao).findMonitorIdBindTags(123L);
|
||||
when(alarmConvergeReduce.filterConverge(testAlert)).thenReturn(true);
|
||||
when(alarmSilenceReduce.filterSilence(testAlert)).thenReturn(true);
|
||||
|
||||
alarmCommonReduce.reduceAndSendAlarm(testAlert);
|
||||
|
||||
assertTrue(testAlert.getTags().containsKey("newTag"));
|
||||
assertEquals("tagValue", testAlert.getTags().get("newTag"));
|
||||
verify(dataQueue).sendAlertsData(testAlert);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testReduceAndSendAlarmConvergeFilterFail() {
|
||||
|
||||
when(alarmConvergeReduce.filterConverge(testAlert)).thenReturn(false);
|
||||
|
||||
alarmCommonReduce.reduceAndSendAlarm(testAlert);
|
||||
|
||||
verify(dataQueue, never()).sendAlertsData(testAlert);
|
||||
verify(alarmSilenceReduce, never()).filterSilence(any(Alert.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testReduceAndSendAlarmSilenceFilterFail() {
|
||||
|
||||
when(alarmConvergeReduce.filterConverge(testAlert)).thenReturn(true);
|
||||
when(alarmSilenceReduce.filterSilence(testAlert)).thenReturn(false);
|
||||
|
||||
alarmCommonReduce.reduceAndSendAlarm(testAlert);
|
||||
|
||||
verify(dataQueue, never()).sendAlertsData(testAlert);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,112 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.apache.hertzbeat.alert.reduce;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
import static org.mockito.Mockito.mockStatic;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import org.apache.hertzbeat.alert.dao.AlertConvergeDao;
|
||||
import org.apache.hertzbeat.common.cache.CacheFactory;
|
||||
import org.apache.hertzbeat.common.cache.CommonCacheService;
|
||||
import org.apache.hertzbeat.common.constants.CommonConstants;
|
||||
import org.apache.hertzbeat.common.entity.alerter.Alert;
|
||||
import org.junit.jupiter.api.AfterEach;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.MockedStatic;
|
||||
import org.mockito.junit.jupiter.MockitoExtension;
|
||||
|
||||
/**
|
||||
* test case for {@link AlarmConvergeReduce}
|
||||
*/
|
||||
|
||||
@ExtendWith(MockitoExtension.class)
|
||||
class AlarmConvergeReduceTest {
|
||||
|
||||
@Mock
|
||||
private AlertConvergeDao alertConvergeDao;
|
||||
|
||||
@Mock
|
||||
private CommonCacheService<String, Object> convergeCache;
|
||||
|
||||
private AlarmConvergeReduce alarmConvergeReduce;
|
||||
|
||||
private Alert testAlert;
|
||||
|
||||
private MockedStatic<CacheFactory> cacheFactoryMockedStatic;
|
||||
|
||||
@BeforeEach
|
||||
void setUp() {
|
||||
|
||||
testAlert = Alert.builder()
|
||||
.tags(new HashMap<>())
|
||||
.status(CommonConstants.ALERT_STATUS_CODE_SOLVED)
|
||||
.build();
|
||||
|
||||
cacheFactoryMockedStatic = mockStatic(CacheFactory.class);
|
||||
cacheFactoryMockedStatic.when(CacheFactory::getAlertConvergeCache).thenReturn(convergeCache);
|
||||
|
||||
alarmConvergeReduce = new AlarmConvergeReduce(alertConvergeDao);
|
||||
}
|
||||
|
||||
@AfterEach
|
||||
void tearDown() {
|
||||
|
||||
if (cacheFactoryMockedStatic != null) {
|
||||
cacheFactoryMockedStatic.close();
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
void testFilterConverge_RestoredAlert() {
|
||||
|
||||
testAlert.setStatus(CommonConstants.ALERT_STATUS_CODE_RESTORED);
|
||||
boolean result = alarmConvergeReduce.filterConverge(testAlert);
|
||||
|
||||
assertTrue(result);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testFilterConverge_IgnoreTag() {
|
||||
|
||||
testAlert.getTags().put(CommonConstants.IGNORE, "true");
|
||||
boolean result = alarmConvergeReduce.filterConverge(testAlert);
|
||||
|
||||
assertTrue(result);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testFilterConvergeNoConverge() {
|
||||
|
||||
when(convergeCache.get(CommonConstants.CACHE_ALERT_CONVERGE)).thenReturn(null);
|
||||
when(alertConvergeDao.findAll()).thenReturn(Collections.emptyList());
|
||||
|
||||
boolean result = alarmConvergeReduce.filterConverge(testAlert);
|
||||
|
||||
assertTrue(result);
|
||||
verify(convergeCache).get(CommonConstants.CACHE_ALERT_CONVERGE);
|
||||
verify(alertConvergeDao).findAll();
|
||||
verify(convergeCache).put(CommonConstants.CACHE_ALERT_CONVERGE, Collections.emptyList());
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,186 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.apache.hertzbeat.alert.reduce;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertFalse;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.ArgumentMatchers.eq;
|
||||
import static org.mockito.Mockito.doReturn;
|
||||
import static org.mockito.Mockito.mockStatic;
|
||||
import static org.mockito.Mockito.never;
|
||||
import static org.mockito.Mockito.times;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.ZoneId;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import org.apache.hertzbeat.alert.dao.AlertSilenceDao;
|
||||
import org.apache.hertzbeat.common.cache.CacheFactory;
|
||||
import org.apache.hertzbeat.common.cache.CommonCacheService;
|
||||
import org.apache.hertzbeat.common.constants.CommonConstants;
|
||||
import org.apache.hertzbeat.common.entity.alerter.Alert;
|
||||
import org.apache.hertzbeat.common.entity.alerter.AlertSilence;
|
||||
import org.apache.hertzbeat.common.entity.manager.TagItem;
|
||||
import org.junit.jupiter.api.AfterEach;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.MockedStatic;
|
||||
import org.mockito.MockitoAnnotations;
|
||||
|
||||
/**
|
||||
* test case for {@link AlarmSilenceReduce}
|
||||
*/
|
||||
|
||||
class AlarmSilenceReduceTest {
|
||||
|
||||
@Mock
|
||||
private AlertSilenceDao alertSilenceDao;
|
||||
|
||||
@Mock
|
||||
private CommonCacheService<String, Object> silenceCache;
|
||||
|
||||
private AlarmSilenceReduce alarmSilenceReduce;
|
||||
|
||||
private MockedStatic<CacheFactory> cacheFactoryMockedStatic;
|
||||
|
||||
@BeforeEach
|
||||
void setUp() {
|
||||
|
||||
MockitoAnnotations.openMocks(this);
|
||||
|
||||
cacheFactoryMockedStatic = mockStatic(CacheFactory.class);
|
||||
cacheFactoryMockedStatic.when(CacheFactory::getAlertSilenceCache).thenReturn(silenceCache);
|
||||
|
||||
// inject dao object.
|
||||
alarmSilenceReduce = new AlarmSilenceReduce(alertSilenceDao);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testFilterSilenceNull() {
|
||||
|
||||
// when cache get result is null, exec db logic.
|
||||
when(silenceCache.get(CommonConstants.CACHE_ALERT_SILENCE)).thenReturn(null);
|
||||
doReturn(Collections.emptyList()).when(alertSilenceDao).findAll();
|
||||
|
||||
Alert alert = Alert.builder()
|
||||
.tags(new HashMap<>())
|
||||
.priority((byte) 1)
|
||||
.build();
|
||||
|
||||
boolean result = alarmSilenceReduce.filterSilence(alert);
|
||||
|
||||
assertTrue(result);
|
||||
verify(alertSilenceDao, times(1)).findAll();
|
||||
verify(silenceCache, times(1)).put(eq(CommonConstants.CACHE_ALERT_SILENCE), any());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testFilterSilenceOnce() {
|
||||
|
||||
AlertSilence alertSilence = AlertSilence.builder()
|
||||
.enable(Boolean.TRUE)
|
||||
.matchAll(Boolean.TRUE)
|
||||
.type((byte) 0)
|
||||
.periodEnd(LocalDateTime.now().atZone(ZoneId.systemDefault()).plusHours(1))
|
||||
.periodStart(LocalDateTime.now().atZone(ZoneId.systemDefault()).minusHours(1))
|
||||
.times(0)
|
||||
.build();
|
||||
|
||||
when(silenceCache.get(CommonConstants.CACHE_ALERT_SILENCE)).thenReturn(Collections.singletonList(alertSilence));
|
||||
doReturn(alertSilence).when(alertSilenceDao).save(alertSilence);
|
||||
|
||||
Alert alert = Alert.builder()
|
||||
.tags(new HashMap<>())
|
||||
.priority((byte) 1)
|
||||
.build();
|
||||
|
||||
boolean result = alarmSilenceReduce.filterSilence(alert);
|
||||
|
||||
assertFalse(result);
|
||||
verify(alertSilenceDao, times(1)).save(alertSilence);
|
||||
assertEquals(1, alertSilence.getTimes());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testFilterSilenceCyc() {
|
||||
|
||||
AlertSilence alertSilence = AlertSilence.builder()
|
||||
.enable(Boolean.TRUE)
|
||||
.matchAll(Boolean.TRUE)
|
||||
.type((byte) 1) // cyc time
|
||||
.periodEnd(LocalDateTime.now().atZone(ZoneId.systemDefault()).plusHours(1))
|
||||
.periodStart(LocalDateTime.now().atZone(ZoneId.systemDefault()).minusHours(1))
|
||||
.times(0)
|
||||
.days(Collections.singletonList((byte) LocalDateTime.now().getDayOfWeek().getValue()))
|
||||
.build();
|
||||
|
||||
when(silenceCache.get(CommonConstants.CACHE_ALERT_SILENCE)).thenReturn(Collections.singletonList(alertSilence));
|
||||
doReturn(alertSilence).when(alertSilenceDao).save(alertSilence);
|
||||
|
||||
Alert alert = Alert.builder()
|
||||
.tags(new HashMap<>())
|
||||
.priority((byte) 1)
|
||||
.build();
|
||||
|
||||
boolean result = alarmSilenceReduce.filterSilence(alert);
|
||||
|
||||
assertFalse(result);
|
||||
verify(alertSilenceDao, times(1)).save(alertSilence);
|
||||
assertEquals(1, alertSilence.getTimes());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testFilterSilenceNoMatch() {
|
||||
|
||||
AlertSilence alertSilence = AlertSilence.builder()
|
||||
.enable(Boolean.TRUE)
|
||||
.matchAll(Boolean.TRUE)
|
||||
.type((byte) 0)
|
||||
.tags(Collections.singletonList(new TagItem("non-matching-tag", "value")))
|
||||
.periodEnd(LocalDateTime.now().atZone(ZoneId.systemDefault()).minusHours(1))
|
||||
.periodStart(LocalDateTime.now().atZone(ZoneId.systemDefault()).plusHours(1))
|
||||
.times(0)
|
||||
.build();
|
||||
|
||||
when(silenceCache.get(CommonConstants.CACHE_ALERT_SILENCE)).thenReturn(Collections.singletonList(alertSilence));
|
||||
doReturn(alertSilence).when(alertSilenceDao).save(alertSilence);
|
||||
|
||||
Alert alert = Alert.builder()
|
||||
.tags(new HashMap<>())
|
||||
.priority((byte) 1)
|
||||
.build();
|
||||
|
||||
boolean result = alarmSilenceReduce.filterSilence(alert);
|
||||
|
||||
assertTrue(result);
|
||||
verify(alertSilenceDao, never()).save(any());
|
||||
}
|
||||
|
||||
@AfterEach
|
||||
public void tearDown() {
|
||||
|
||||
if (cacheFactoryMockedStatic != null) {
|
||||
cacheFactoryMockedStatic.close();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
+112
@@ -0,0 +1,112 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.apache.hertzbeat.alert.service;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.Mockito.times;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
import java.util.Collections;
|
||||
import java.util.Optional;
|
||||
import java.util.Set;
|
||||
import org.apache.hertzbeat.alert.dao.AlertConvergeDao;
|
||||
import org.apache.hertzbeat.alert.service.impl.AlertConvergeServiceImpl;
|
||||
import org.apache.hertzbeat.common.entity.alerter.AlertConverge;
|
||||
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.Pageable;
|
||||
import org.springframework.data.jpa.domain.Specification;
|
||||
|
||||
/**
|
||||
* test case for {@link org.apache.hertzbeat.alert.service.impl.AlertConvergeServiceImpl}
|
||||
*/
|
||||
|
||||
@ExtendWith(MockitoExtension.class)
|
||||
class AlertConvergeServiceTest {
|
||||
|
||||
@Mock
|
||||
private AlertConvergeDao alertConvergeDao;
|
||||
|
||||
@InjectMocks
|
||||
private AlertConvergeServiceImpl alertConvergeService;
|
||||
|
||||
@Test
|
||||
public void testAddAlertConverge() {
|
||||
|
||||
AlertConverge alertConverge = new AlertConverge();
|
||||
alertConvergeService.addAlertConverge(alertConverge);
|
||||
|
||||
verify(alertConvergeDao, times(1)).save(alertConverge);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testModifyAlertConverge() {
|
||||
|
||||
AlertConverge alertConverge = new AlertConverge();
|
||||
alertConvergeService.modifyAlertConverge(alertConverge);
|
||||
|
||||
verify(alertConvergeDao, times(1)).save(alertConverge);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetAlertConverge() {
|
||||
|
||||
long convergeId = 1L;
|
||||
AlertConverge alertConverge = new AlertConverge();
|
||||
when(alertConvergeDao.findById(convergeId)).thenReturn(Optional.of(alertConverge));
|
||||
AlertConverge result = alertConvergeService.getAlertConverge(convergeId);
|
||||
|
||||
verify(alertConvergeDao, times(1)).findById(convergeId);
|
||||
assertEquals(alertConverge, result);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDeleteAlertConverges() {
|
||||
|
||||
Set<Long> convergeIds = Set.of(1L, 2L, 3L);
|
||||
alertConvergeService.deleteAlertConverges(convergeIds);
|
||||
|
||||
verify(alertConvergeDao, times(1)).deleteAlertConvergesByIdIn(convergeIds);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetAlertConverges() {
|
||||
|
||||
Page<AlertConverge> page = new PageImpl<>(Collections.emptyList());
|
||||
when(alertConvergeDao.findAll(
|
||||
any(Specification.class),
|
||||
any(Pageable.class))
|
||||
).thenReturn(page);
|
||||
|
||||
Page<AlertConverge> result = alertConvergeService.getAlertConverges(null, null, "id", "desc", 1, 10);
|
||||
|
||||
verify(alertConvergeDao, times(1)).findAll(
|
||||
any(Specification.class),
|
||||
any(PageRequest.class)
|
||||
);
|
||||
assertEquals(page, result);
|
||||
}
|
||||
|
||||
}
|
||||
+45
-39
@@ -24,12 +24,10 @@ import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.apache.hertzbeat.alert.dto.AlertDefineDTO;
|
||||
import org.apache.hertzbeat.alert.dto.ExportAlertDefineDTO;
|
||||
import org.apache.hertzbeat.alert.service.impl.AlertDefineExcelImExportServiceImpl;
|
||||
import org.apache.hertzbeat.common.util.JsonUtil;
|
||||
import org.apache.hertzbeat.common.entity.manager.TagItem;
|
||||
import org.apache.hertzbeat.common.util.export.ExcelExportUtils;
|
||||
import org.apache.poi.ss.usermodel.Row;
|
||||
import org.apache.poi.ss.usermodel.Sheet;
|
||||
@@ -44,6 +42,7 @@ import org.mockito.junit.jupiter.MockitoExtension;
|
||||
/**
|
||||
* test case for {@link AlertDefineExcelImExportServiceImpl}
|
||||
*/
|
||||
|
||||
@ExtendWith(MockitoExtension.class)
|
||||
public class AlertDefineExcelImExportServiceTest {
|
||||
|
||||
@@ -62,13 +61,15 @@ public class AlertDefineExcelImExportServiceTest {
|
||||
Row row = initialSheet.createRow(1);
|
||||
row.createCell(0).setCellValue("app1");
|
||||
row.createCell(1).setCellValue("metric1");
|
||||
row.createCell(2).setCellValue("expr1");
|
||||
row.createCell(3).setCellValue(10);
|
||||
row.createCell(4).setCellValue(1);
|
||||
row.createCell(5).setCellValue(JsonUtil.toJson(Map.of("key", "value")));
|
||||
row.createCell(6).setCellValue(JsonUtil.toJson(Map.of("key", "value")));
|
||||
row.createCell(7).setCellValue("template1");
|
||||
row.createCell(2).setCellValue("field1");
|
||||
row.createCell(3).setCellValue(true);
|
||||
row.createCell(4).setCellValue("expr1");
|
||||
row.createCell(5).setCellValue(1);
|
||||
row.createCell(6).setCellValue(10);
|
||||
row.createCell(7).setCellValue("[{\"name\":\"tag1\",\"value\":\"value1\"}]");
|
||||
row.createCell(8).setCellValue(true);
|
||||
row.createCell(9).setCellValue(true);
|
||||
row.createCell(10).setCellValue("template1");
|
||||
|
||||
ByteArrayInputStream inputStream = new ByteArrayInputStream(toByteArray(initialWorkbook));
|
||||
|
||||
@@ -84,15 +85,18 @@ public class AlertDefineExcelImExportServiceTest {
|
||||
|
||||
assertEquals(1, result.size());
|
||||
AlertDefineDTO alertDefineDTO = result.get(0).getAlertDefine();
|
||||
assertEquals("app1", alertDefineDTO.getName());
|
||||
assertEquals("metric1", alertDefineDTO.getType());
|
||||
assertEquals("app1", alertDefineDTO.getApp());
|
||||
assertEquals("metric1", alertDefineDTO.getMetric());
|
||||
assertEquals("field1", alertDefineDTO.getField());
|
||||
assertTrue(alertDefineDTO.getPreset());
|
||||
assertEquals("expr1", alertDefineDTO.getExpr());
|
||||
assertEquals(10, alertDefineDTO.getPeriod());
|
||||
assertEquals(1, alertDefineDTO.getTimes());
|
||||
assertEquals(Map.of("key", "value"), alertDefineDTO.getLabels());
|
||||
assertEquals(Map.of("key", "value"), alertDefineDTO.getAnnotations());
|
||||
assertEquals("template1", alertDefineDTO.getTemplate());
|
||||
assertEquals(10, alertDefineDTO.getTimes());
|
||||
assertEquals(1, alertDefineDTO.getTags().size());
|
||||
assertEquals("tag1", alertDefineDTO.getTags().get(0).getName());
|
||||
assertEquals("value1", alertDefineDTO.getTags().get(0).getValue());
|
||||
assertTrue(alertDefineDTO.getEnable());
|
||||
assertTrue(alertDefineDTO.getRecoverNotice());
|
||||
assertEquals("template1", alertDefineDTO.getTemplate());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -102,15 +106,22 @@ public class AlertDefineExcelImExportServiceTest {
|
||||
List<ExportAlertDefineDTO> exportAlertDefineList = new ArrayList<>();
|
||||
ExportAlertDefineDTO exportAlertDefineDTO = new ExportAlertDefineDTO();
|
||||
AlertDefineDTO alertDefineDTO = new AlertDefineDTO();
|
||||
alertDefineDTO.setName("app1");
|
||||
alertDefineDTO.setType("metric1");
|
||||
alertDefineDTO.setApp("app1");
|
||||
alertDefineDTO.setMetric("metric1");
|
||||
alertDefineDTO.setField("field1");
|
||||
alertDefineDTO.setPreset(true);
|
||||
alertDefineDTO.setExpr("expr1");
|
||||
alertDefineDTO.setPeriod(10);
|
||||
alertDefineDTO.setTimes(1);
|
||||
alertDefineDTO.setLabels(Map.of("key", "value"));
|
||||
alertDefineDTO.setAnnotations(Map.of("key", "value"));
|
||||
alertDefineDTO.setTemplate("template1");
|
||||
alertDefineDTO.setPriority((byte) 1);
|
||||
alertDefineDTO.setTimes(10);
|
||||
List<TagItem> tags = new ArrayList<>();
|
||||
TagItem tagItem = new TagItem();
|
||||
tagItem.setName("tag1");
|
||||
tagItem.setValue("value1");
|
||||
tags.add(tagItem);
|
||||
alertDefineDTO.setTags(tags);
|
||||
alertDefineDTO.setEnable(true);
|
||||
alertDefineDTO.setRecoverNotice(true);
|
||||
alertDefineDTO.setTemplate("template1");
|
||||
exportAlertDefineDTO.setAlertDefine(alertDefineDTO);
|
||||
exportAlertDefineList.add(exportAlertDefineDTO);
|
||||
|
||||
@@ -120,26 +131,21 @@ public class AlertDefineExcelImExportServiceTest {
|
||||
try (Workbook resultWorkbook = WorkbookFactory.create(new ByteArrayInputStream(outputStream.toByteArray()))) {
|
||||
Sheet resultSheet = resultWorkbook.getSheetAt(0);
|
||||
Row headerRow = resultSheet.getRow(0);
|
||||
assertEquals("Name", headerRow.getCell(0).getStringCellValue());
|
||||
assertEquals("Type", headerRow.getCell(1).getStringCellValue());
|
||||
assertEquals("Expr", headerRow.getCell(2).getStringCellValue());
|
||||
assertEquals("Period", headerRow.getCell(3).getStringCellValue());
|
||||
assertEquals("Times", headerRow.getCell(4).getStringCellValue());
|
||||
assertEquals("Labels", headerRow.getCell(5).getStringCellValue());
|
||||
assertEquals("Annotations", headerRow.getCell(6).getStringCellValue());
|
||||
assertEquals("Template", headerRow.getCell(7).getStringCellValue());
|
||||
assertEquals("Enable", headerRow.getCell(8).getStringCellValue());
|
||||
assertEquals("app", headerRow.getCell(0).getStringCellValue());
|
||||
assertEquals("metric", headerRow.getCell(1).getStringCellValue());
|
||||
|
||||
Row dataRow = resultSheet.getRow(1);
|
||||
assertEquals("app1", dataRow.getCell(0).getStringCellValue());
|
||||
assertEquals("metric1", dataRow.getCell(1).getStringCellValue());
|
||||
assertEquals("expr1", dataRow.getCell(2).getStringCellValue());
|
||||
assertEquals(10, (int) dataRow.getCell(3).getNumericCellValue());
|
||||
assertEquals(1, (int) dataRow.getCell(4).getNumericCellValue());
|
||||
assertEquals(JsonUtil.toJson(Map.of("key", "value")), dataRow.getCell(5).getStringCellValue());
|
||||
assertEquals(JsonUtil.toJson(Map.of("key", "value")), dataRow.getCell(6).getStringCellValue());
|
||||
assertEquals("template1", dataRow.getCell(7).getStringCellValue());
|
||||
assertEquals("field1", dataRow.getCell(2).getStringCellValue());
|
||||
assertTrue(dataRow.getCell(3).getBooleanCellValue());
|
||||
assertEquals("expr1", dataRow.getCell(4).getStringCellValue());
|
||||
assertEquals(1, (int) dataRow.getCell(5).getNumericCellValue());
|
||||
assertEquals(10, (int) dataRow.getCell(6).getNumericCellValue());
|
||||
assertEquals("[{\"name\":\"tag1\",\"value\":\"value1\"}]", dataRow.getCell(7).getStringCellValue());
|
||||
assertTrue(dataRow.getCell(8).getBooleanCellValue());
|
||||
assertTrue(dataRow.getCell(9).getBooleanCellValue());
|
||||
assertEquals("template1", dataRow.getCell(10).getStringCellValue());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -152,4 +158,4 @@ public class AlertDefineExcelImExportServiceTest {
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
+12
-9
@@ -33,7 +33,6 @@ import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.List;
|
||||
import org.apache.hertzbeat.alert.dto.AlertDefineDTO;
|
||||
import org.apache.hertzbeat.alert.dto.ExportAlertDefineDTO;
|
||||
@@ -59,9 +58,9 @@ class AlertDefineJsonImExportServiceTest {
|
||||
private AlertDefineJsonImExportServiceImpl service;
|
||||
|
||||
@SuppressWarnings("checkstyle:OperatorWrap")
|
||||
private static final String JSON_DATA = "[{\"alertDefine\":{\"name\":\"App1\",\"type\":\"realtime\"," +
|
||||
"\"expr\":\"Expr1\",\"period\":3000,\"times\":3," +
|
||||
"\"enable\":true,\"template\":\"Template1\"}}]";
|
||||
private static final String JSON_DATA = "[{\"alertDefine\":{\"app\":\"App1\",\"metric\":\"Metric1\"," +
|
||||
"\"field\":\"Field1\",\"preset\":true,\"expr\":\"Expr1\",\"priority\":1,\"times\":1,\"tags\":[]," +
|
||||
"\"enable\":true,\"recoverNotice\":true,\"template\":\"Template1\"}}]";
|
||||
|
||||
private InputStream inputStream;
|
||||
private List<ExportAlertDefineDTO> alertDefineList;
|
||||
@@ -69,15 +68,19 @@ class AlertDefineJsonImExportServiceTest {
|
||||
@BeforeEach
|
||||
public void setup() {
|
||||
|
||||
inputStream = new ByteArrayInputStream(JSON_DATA.getBytes(StandardCharsets.UTF_8));
|
||||
inputStream = new ByteArrayInputStream(JSON_DATA.getBytes());
|
||||
|
||||
AlertDefineDTO alertDefine = new AlertDefineDTO();
|
||||
alertDefine.setName("App1");
|
||||
alertDefine.setType("realtime");
|
||||
alertDefine.setApp("App1");
|
||||
alertDefine.setMetric("Metric1");
|
||||
alertDefine.setField("Field1");
|
||||
alertDefine.setPreset(true);
|
||||
alertDefine.setExpr("Expr1");
|
||||
alertDefine.setPeriod(3000);
|
||||
alertDefine.setTimes(3);
|
||||
alertDefine.setPriority((byte) 1);
|
||||
alertDefine.setTimes(1);
|
||||
alertDefine.setTags(List.of());
|
||||
alertDefine.setEnable(true);
|
||||
alertDefine.setRecoverNotice(true);
|
||||
alertDefine.setTemplate("Template1");
|
||||
|
||||
ExportAlertDefineDTO exportAlertDefine = new ExportAlertDefineDTO();
|
||||
+64
-5
@@ -23,17 +23,22 @@ import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||
import static org.mockito.Mockito.any;
|
||||
import static org.mockito.Mockito.anySet;
|
||||
import static org.mockito.Mockito.doNothing;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.reset;
|
||||
import static org.mockito.Mockito.times;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import org.apache.hertzbeat.alert.calculate.PeriodicAlertRuleScheduler;
|
||||
import org.apache.hertzbeat.alert.dao.AlertDefineBindDao;
|
||||
import org.apache.hertzbeat.alert.dao.AlertDefineDao;
|
||||
import org.apache.hertzbeat.alert.service.impl.AlertDefineServiceImpl;
|
||||
import org.apache.hertzbeat.common.entity.alerter.AlertDefine;
|
||||
import org.apache.hertzbeat.common.entity.alerter.AlertDefineMonitorBind;
|
||||
import org.apache.hertzbeat.common.entity.manager.Monitor;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
@@ -53,11 +58,13 @@ class AlertDefineServiceTest {
|
||||
|
||||
private AlertDefine alertDefine;
|
||||
|
||||
private List<AlertDefineMonitorBind> alertDefineMonitorBinds;
|
||||
|
||||
@Mock
|
||||
private AlertDefineDao alertDefineDao;
|
||||
|
||||
|
||||
@Mock
|
||||
private PeriodicAlertRuleScheduler periodicAlertRuleScheduler;
|
||||
private AlertDefineBindDao alertDefineBindDao;
|
||||
|
||||
@Mock
|
||||
private List<AlertDefineImExportService> alertDefineImExportServiceList;
|
||||
@@ -68,16 +75,37 @@ class AlertDefineServiceTest {
|
||||
@BeforeEach
|
||||
void setUp() {
|
||||
ReflectionTestUtils.setField(this.alertDefineService, "alertDefineDao", alertDefineDao);
|
||||
ReflectionTestUtils.setField(this.alertDefineService, "periodicAlertRuleScheduler", periodicAlertRuleScheduler);
|
||||
ReflectionTestUtils.setField(this.alertDefineService, "alertDefineBindDao", alertDefineBindDao);
|
||||
|
||||
this.alertDefine = AlertDefine.builder()
|
||||
.id(1L)
|
||||
.app("app")
|
||||
.metric("test")
|
||||
.field("test")
|
||||
.preset(false)
|
||||
.expr("1 > 0")
|
||||
.priority((byte) 1)
|
||||
.times(1)
|
||||
.template("template")
|
||||
.creator("tom")
|
||||
.modifier("tom")
|
||||
.build();
|
||||
|
||||
this.alertDefineMonitorBinds = Collections.singletonList(
|
||||
AlertDefineMonitorBind.builder()
|
||||
.id(1L)
|
||||
.alertDefineId(this.alertDefine.getId())
|
||||
.monitorId(1L)
|
||||
.monitor(
|
||||
Monitor.builder()
|
||||
.id(1L)
|
||||
.app("app")
|
||||
.host("localhost")
|
||||
.name("monitor")
|
||||
.build()
|
||||
)
|
||||
.build()
|
||||
);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -125,10 +153,41 @@ class AlertDefineServiceTest {
|
||||
assertDoesNotThrow(() -> alertDefineService.deleteAlertDefines(new HashSet<>(1)));
|
||||
}
|
||||
|
||||
@Test
|
||||
void getMonitorBindAlertDefines() {
|
||||
Specification<AlertDefine> specification = mock(Specification.class);
|
||||
when(alertDefineDao.findAll(specification, PageRequest.of(1, 1))).thenReturn(Page.empty());
|
||||
assertNotNull(alertDefineService.getMonitorBindAlertDefines(specification, PageRequest.of(1, 1)));
|
||||
}
|
||||
|
||||
@Test
|
||||
void applyBindAlertDefineMonitors() {
|
||||
long id = 1L;
|
||||
doNothing().when(alertDefineBindDao).deleteAlertDefineBindsByAlertDefineIdEquals(id);
|
||||
when(alertDefineBindDao.saveAll(alertDefineMonitorBinds)).thenReturn(alertDefineMonitorBinds);
|
||||
assertDoesNotThrow(() -> alertDefineService.applyBindAlertDefineMonitors(id, alertDefineMonitorBinds));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testGetMonitorBindAlertDefines() {
|
||||
List<AlertDefine> alertDefineList = new ArrayList<>();
|
||||
alertDefineList.add(this.alertDefine);
|
||||
when(alertDefineDao.queryAlertDefinesByMonitor(1L, "app", "test")).thenReturn(alertDefineList);
|
||||
when(alertDefineDao.queryAlertDefinesByAppAndMetricAndPresetTrueAndEnableTrue("app", "test")).thenReturn(alertDefineList);
|
||||
assertNotNull(alertDefineService.getMonitorBindAlertDefines(1L, "app", "test"));
|
||||
}
|
||||
|
||||
@Test
|
||||
void getAlertDefines() {
|
||||
when(alertDefineDao.findAll(any(Specification.class), any(PageRequest.class))).thenReturn(Page.empty());
|
||||
assertNotNull(alertDefineService.getAlertDefines(null, null, "id", "desc", 1, 10));
|
||||
assertNotNull(alertDefineService.getAlertDefines(null, null, null, "id", "desc", 1, 10));
|
||||
verify(alertDefineDao, times(1)).findAll(any(Specification.class), any(PageRequest.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
void getBindAlertDefineMonitors() {
|
||||
long id = 1L;
|
||||
when(alertDefineBindDao.getAlertDefineBindsByAlertDefineIdEquals(id)).thenReturn(alertDefineMonitorBinds);
|
||||
assertDoesNotThrow(() -> alertDefineService.getBindAlertDefineMonitors(id));
|
||||
}
|
||||
}
|
||||
+20
-12
@@ -47,7 +47,8 @@ import org.yaml.snakeyaml.Yaml;
|
||||
|
||||
/**
|
||||
* test case for {@link AlertDefineYamlImExportServiceImpl}
|
||||
*/
|
||||
*/
|
||||
|
||||
@ExtendWith(MockitoExtension.class)
|
||||
class AlertDefineYamlImExportServiceTest {
|
||||
|
||||
@@ -57,12 +58,16 @@ class AlertDefineYamlImExportServiceTest {
|
||||
private static final String YAML_DATA =
|
||||
"""
|
||||
- alertDefine:
|
||||
name: App1
|
||||
type: realtime
|
||||
app: App1
|
||||
metric: Metric1
|
||||
field: Field1
|
||||
preset: true
|
||||
expr: Expr1
|
||||
period: 3000
|
||||
times: 3
|
||||
priority: 1
|
||||
times: 1
|
||||
tags: []
|
||||
enable: true
|
||||
recoverNotice: true
|
||||
template: Template1
|
||||
""";
|
||||
|
||||
@@ -75,12 +80,16 @@ class AlertDefineYamlImExportServiceTest {
|
||||
inputStream = new ByteArrayInputStream(YAML_DATA.getBytes(StandardCharsets.UTF_8));
|
||||
|
||||
AlertDefineDTO alertDefine = new AlertDefineDTO();
|
||||
alertDefine.setName("App1");
|
||||
alertDefine.setType("realtime");
|
||||
alertDefine.setPeriod(3000);
|
||||
alertDefine.setTimes(3);
|
||||
alertDefine.setApp("App1");
|
||||
alertDefine.setMetric("Metric1");
|
||||
alertDefine.setField("Field1");
|
||||
alertDefine.setPreset(true);
|
||||
alertDefine.setExpr("Expr1");
|
||||
alertDefine.setPriority((byte) 1);
|
||||
alertDefine.setTimes(1);
|
||||
alertDefine.setTags(List.of());
|
||||
alertDefine.setEnable(true);
|
||||
alertDefine.setRecoverNotice(true);
|
||||
alertDefine.setTemplate("Template1");
|
||||
|
||||
ExportAlertDefineDTO exportAlertDefine = new ExportAlertDefineDTO();
|
||||
@@ -132,9 +141,8 @@ class AlertDefineYamlImExportServiceTest {
|
||||
service.writeOs(alertDefineList, outputStream);
|
||||
String yamlOutput = outputStream.toString(StandardCharsets.UTF_8);
|
||||
|
||||
assertTrue(yamlOutput.contains("name: App1"));
|
||||
assertTrue(yamlOutput.contains("type: realtime"));
|
||||
assertTrue(yamlOutput.contains("expr: Expr1"));
|
||||
assertTrue(yamlOutput.contains("app: App1"));
|
||||
assertTrue(yamlOutput.contains("metric: Metric1"));
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -0,0 +1,139 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.apache.hertzbeat.alert.service;
|
||||
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
|
||||
import static org.junit.jupiter.api.Assertions.assertNotNull;
|
||||
import static org.mockito.Mockito.any;
|
||||
import static org.mockito.Mockito.reset;
|
||||
import static org.mockito.Mockito.times;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import org.apache.hertzbeat.alert.dao.AlertDao;
|
||||
import org.apache.hertzbeat.alert.dto.AlertPriorityNum;
|
||||
import org.apache.hertzbeat.alert.dto.TenCloudAlertReport;
|
||||
import org.apache.hertzbeat.alert.reduce.AlarmCommonReduce;
|
||||
import org.apache.hertzbeat.alert.service.impl.AlertServiceImpl;
|
||||
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.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;
|
||||
|
||||
/**
|
||||
* Test case for {@link AlertService}
|
||||
*/
|
||||
@ExtendWith(MockitoExtension.class)
|
||||
class AlertServiceTest {
|
||||
@Mock
|
||||
private AlertDao alertDao;
|
||||
|
||||
@Mock
|
||||
private AlarmCommonReduce alarmCommonReduce;
|
||||
|
||||
@InjectMocks
|
||||
private AlertServiceImpl alertService;
|
||||
|
||||
@BeforeEach
|
||||
void setUp() {
|
||||
}
|
||||
|
||||
@Test
|
||||
void addAlert() {
|
||||
Alert alert = new Alert();
|
||||
assertDoesNotThrow(() -> alertService.addAlert(alert));
|
||||
verify(alertDao, times(1)).save(alert);
|
||||
}
|
||||
|
||||
@Test
|
||||
void getAlerts() {
|
||||
// todo
|
||||
}
|
||||
|
||||
@Test
|
||||
void deleteAlerts() {
|
||||
HashSet<Long> ids = new HashSet<>();
|
||||
ids.add(1L);
|
||||
ids.add(2L);
|
||||
assertDoesNotThrow(() -> alertService.deleteAlerts(ids));
|
||||
verify(alertDao, times(1)).deleteAlertsByIdIn(ids);
|
||||
}
|
||||
|
||||
@Test
|
||||
void clearAlerts() {
|
||||
assertDoesNotThrow(() -> alertService.clearAlerts());
|
||||
verify(alertDao, times(1)).deleteAll();
|
||||
}
|
||||
|
||||
@Test
|
||||
void editAlertStatus() {
|
||||
Byte status = 0;
|
||||
List<Long> ids = List.of(1L, 2L, 3L);
|
||||
assertDoesNotThrow(() -> alertService.editAlertStatus(status, ids));
|
||||
verify(alertDao, times(1)).updateAlertsStatus(status, ids);
|
||||
}
|
||||
|
||||
@Test
|
||||
void getAlertsSummary() {
|
||||
List<AlertPriorityNum> priorityNums = new ArrayList<>();
|
||||
priorityNums.add(new AlertPriorityNum((byte) 1, 100));
|
||||
when(alertDao.findAlertPriorityNum()).thenReturn(priorityNums);
|
||||
|
||||
assertDoesNotThrow(() -> alertService.getAlertsSummary());
|
||||
verify(alertDao, times(1)).findAlertPriorityNum();
|
||||
verify(alertDao, times(1)).count();
|
||||
|
||||
assertNotNull(alertService.getAlertsSummary());
|
||||
}
|
||||
|
||||
@Test
|
||||
void addNewAlertReport() {
|
||||
AlertReport alertReport = AlertReport.builder()
|
||||
.annotations(new HashMap<>())
|
||||
.priority(0)
|
||||
.alertTime(System.currentTimeMillis())
|
||||
.build();
|
||||
assertDoesNotThrow(() -> alertService.addNewAlertReport(alertReport));
|
||||
verify(alarmCommonReduce, times(1)).reduceAndSendAlarm(any(Alert.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
void addNewAlertReportFromCloud() {
|
||||
TenCloudAlertReport alertReport = TenCloudAlertReport.builder()
|
||||
.firstOccurTime("2024-08-01 11:30:00")
|
||||
.durationTime(100)
|
||||
.build();
|
||||
String reportJson = JsonUtil.toJson(alertReport);
|
||||
assertDoesNotThrow(() -> alertService.addNewAlertReportFromCloud("tencloud", reportJson));
|
||||
verify(alarmCommonReduce, times(1)).reduceAndSendAlarm(any(Alert.class));
|
||||
|
||||
alertService.addNewAlertReportFromCloud("alicloud", reportJson);
|
||||
reset(alarmCommonReduce);
|
||||
verify(alarmCommonReduce, times(0)).reduceAndSendAlarm(any(Alert.class));
|
||||
|
||||
}
|
||||
}
|
||||
+1
-17
@@ -33,7 +33,6 @@
|
||||
<maven.compiler.source>17</maven.compiler.source>
|
||||
<maven.compiler.target>17</maven.compiler.target>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
<mqtt.version>1.3.3</mqtt.version>
|
||||
</properties>
|
||||
|
||||
<dependencies>
|
||||
@@ -142,22 +141,7 @@
|
||||
<dependency>
|
||||
<groupId>com.hivemq</groupId>
|
||||
<artifactId>hivemq-mqtt-client</artifactId>
|
||||
<version>${mqtt.version}</version>
|
||||
</dependency>
|
||||
<!--plc-->
|
||||
<dependency>
|
||||
<groupId>org.apache.plc4x</groupId>
|
||||
<artifactId>plc4j-api</artifactId>
|
||||
<version>0.12.0</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.plc4x</groupId>
|
||||
<artifactId>plc4j-driver-modbus</artifactId>
|
||||
<version>0.12.0</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.sshd</groupId>
|
||||
<artifactId>sshd-sftp</artifactId>
|
||||
<version>1.3.3</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</project>
|
||||
+65
-108
@@ -26,25 +26,19 @@ import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.Optional;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.hertzbeat.collector.collect.AbstractCollect;
|
||||
import org.apache.hertzbeat.collector.collect.common.cache.AbstractConnection;
|
||||
import org.apache.hertzbeat.collector.collect.common.cache.CacheIdentifier;
|
||||
import org.apache.hertzbeat.collector.collect.common.cache.GlobalConnectionCache;
|
||||
import org.apache.hertzbeat.collector.collect.common.cache.ConnectionCommonCache;
|
||||
import org.apache.hertzbeat.collector.collect.common.cache.JdbcConnect;
|
||||
import org.apache.hertzbeat.collector.collect.common.ssh.SshTunnelHelper;
|
||||
import org.apache.hertzbeat.collector.constants.CollectorConstants;
|
||||
import org.apache.hertzbeat.collector.dispatch.DispatchConstants;
|
||||
import org.apache.hertzbeat.collector.util.CollectUtil;
|
||||
import org.apache.hertzbeat.common.constants.CommonConstants;
|
||||
import org.apache.hertzbeat.common.entity.job.Metrics;
|
||||
import org.apache.hertzbeat.common.entity.job.SshTunnel;
|
||||
import org.apache.hertzbeat.common.entity.job.protocol.JdbcProtocol;
|
||||
import org.apache.hertzbeat.common.entity.message.CollectRep;
|
||||
import org.apache.hertzbeat.common.util.CommonUtil;
|
||||
import org.apache.sshd.common.SshException;
|
||||
import org.apache.sshd.common.channel.exception.SshChannelOpenException;
|
||||
import org.postgresql.util.PSQLException;
|
||||
import org.springframework.core.io.FileSystemResource;
|
||||
import org.springframework.jdbc.datasource.init.ScriptUtils;
|
||||
@@ -60,11 +54,14 @@ public class JdbcCommonCollect extends AbstractCollect {
|
||||
private static final String QUERY_TYPE_MULTI_ROW = "multiRow";
|
||||
private static final String QUERY_TYPE_COLUMNS = "columns";
|
||||
private static final String RUN_SCRIPT = "runScript";
|
||||
|
||||
|
||||
private static final String[] VULNERABLE_KEYWORDS = {"allowLoadLocalInfile", "allowLoadLocalInfileInPath", "useLocalInfile"};
|
||||
|
||||
private final GlobalConnectionCache connectionCommonCache = GlobalConnectionCache.getInstance();
|
||||
private final ConnectionCommonCache<CacheIdentifier, JdbcConnect> connectionCommonCache;
|
||||
|
||||
public JdbcCommonCollect(){
|
||||
connectionCommonCache = new ConnectionCommonCache<>();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void preCheck(Metrics metrics) throws IllegalArgumentException {
|
||||
@@ -78,29 +75,18 @@ public class JdbcCommonCollect extends AbstractCollect {
|
||||
}
|
||||
}
|
||||
}
|
||||
SshTunnelHelper.checkTunnelParam(metrics.getJdbc().getSshTunnel());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void collect(CollectRep.MetricsData.Builder builder, Metrics metrics) {
|
||||
public void collect(CollectRep.MetricsData.Builder builder, long monitorId, String app, Metrics metrics) {
|
||||
long startTime = System.currentTimeMillis();
|
||||
JdbcProtocol jdbcProtocol = metrics.getJdbc();
|
||||
SshTunnel sshTunnel = jdbcProtocol.getSshTunnel();
|
||||
|
||||
String databaseUrl = constructDatabaseUrl(jdbcProtocol);
|
||||
int timeout = CollectUtil.getTimeout(jdbcProtocol.getTimeout());
|
||||
boolean reuseConnection = Boolean.parseBoolean(jdbcProtocol.getReuseConnection());
|
||||
Statement statement = null;
|
||||
String databaseUrl;
|
||||
try {
|
||||
if (sshTunnel != null && Boolean.parseBoolean(sshTunnel.getEnable())) {
|
||||
int localPort = SshTunnelHelper.localPortForward(sshTunnel, jdbcProtocol.getHost(), jdbcProtocol.getPort());
|
||||
databaseUrl = constructDatabaseUrl(jdbcProtocol, "localhost", String.valueOf(localPort));
|
||||
} else {
|
||||
databaseUrl = constructDatabaseUrl(jdbcProtocol, jdbcProtocol.getHost(), jdbcProtocol.getPort());
|
||||
}
|
||||
|
||||
statement = getConnection(jdbcProtocol.getUsername(),
|
||||
jdbcProtocol.getPassword(), databaseUrl, timeout, reuseConnection);
|
||||
jdbcProtocol.getPassword(), databaseUrl, timeout);
|
||||
switch (jdbcProtocol.getQueryType()) {
|
||||
case QUERY_TYPE_ONE_ROW -> queryOneRow(statement, jdbcProtocol.getSql(), metrics.getAliasFields(), builder, startTime);
|
||||
case QUERY_TYPE_MULTI_ROW -> queryMultiRow(statement, jdbcProtocol.getSql(), metrics.getAliasFields(), builder, startTime);
|
||||
@@ -128,14 +114,6 @@ public class JdbcCommonCollect extends AbstractCollect {
|
||||
log.warn("Jdbc sql error: {}, code: {}.", sqlException.getMessage(), sqlException.getErrorCode());
|
||||
builder.setCode(CollectRep.Code.FAIL);
|
||||
builder.setMsg("Query Error: " + sqlException.getMessage() + " Code: " + sqlException.getErrorCode());
|
||||
} catch (SshException sshException) {
|
||||
Throwable throwable = sshException.getCause();
|
||||
if (throwable instanceof SshChannelOpenException) {
|
||||
log.warn("[Jdbc collect] Remote ssh server no more session channel, please increase sshd_config MaxSessions.");
|
||||
}
|
||||
String errorMsg = CommonUtil.getMessageFromThrowable(sshException);
|
||||
builder.setCode(CollectRep.Code.UN_CONNECTABLE);
|
||||
builder.setMsg("Peer ssh connection failed: " + errorMsg);
|
||||
} catch (Exception e) {
|
||||
String errorMessage = CommonUtil.getMessageFromThrowable(e);
|
||||
log.error("Jdbc error: {}.", errorMessage, e);
|
||||
@@ -143,20 +121,11 @@ public class JdbcCommonCollect extends AbstractCollect {
|
||||
builder.setMsg("Query Error: " + errorMessage);
|
||||
} finally {
|
||||
if (statement != null) {
|
||||
Connection connection = null;
|
||||
try {
|
||||
connection = statement.getConnection();
|
||||
statement.close();
|
||||
} catch (Exception e) {
|
||||
log.error("Jdbc close statement error: {}", e.getMessage());
|
||||
}
|
||||
try {
|
||||
if (!reuseConnection && connection != null) {
|
||||
connection.close();
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.error("Jdbc close connection error: {}", e.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -167,53 +136,48 @@ public class JdbcCommonCollect extends AbstractCollect {
|
||||
}
|
||||
|
||||
|
||||
private Statement getConnection(String username, String password, String url, Integer timeout, boolean reuseConnection) throws Exception {
|
||||
private Statement getConnection(String username, String password, String url, Integer timeout) throws Exception {
|
||||
CacheIdentifier identifier = CacheIdentifier.builder()
|
||||
.ip(url)
|
||||
.username(username).password(password).build();
|
||||
Optional<JdbcConnect> cacheOption = connectionCommonCache.getCache(identifier, true);
|
||||
Statement statement = null;
|
||||
if (reuseConnection) {
|
||||
Optional<AbstractConnection<?>> cacheOption = connectionCommonCache.getCache(identifier, true);
|
||||
if (cacheOption.isPresent()) {
|
||||
JdbcConnect jdbcConnect = (JdbcConnect) cacheOption.get();
|
||||
if (cacheOption.isPresent()) {
|
||||
JdbcConnect jdbcConnect = cacheOption.get();
|
||||
try {
|
||||
statement = jdbcConnect.getConnection().createStatement();
|
||||
// set query timeout
|
||||
int timeoutSecond = timeout / 1000;
|
||||
timeoutSecond = timeoutSecond <= 0 ? 1 : timeoutSecond;
|
||||
statement.setQueryTimeout(timeoutSecond);
|
||||
// set query max row number
|
||||
statement.setMaxRows(1000);
|
||||
} catch (Exception e) {
|
||||
log.info("The jdbc connect from cache, create statement error: {}", e.getMessage());
|
||||
try {
|
||||
statement = jdbcConnect.getConnection().createStatement();
|
||||
// set query timeout
|
||||
int timeoutSecond = timeout / 1000;
|
||||
timeoutSecond = timeoutSecond <= 0 ? 1 : timeoutSecond;
|
||||
statement.setQueryTimeout(timeoutSecond);
|
||||
// set query max row number
|
||||
statement.setMaxRows(1000);
|
||||
} catch (Exception e) {
|
||||
log.info("The jdbc connect from cache, create statement error: {}", e.getMessage());
|
||||
try {
|
||||
if (statement != null) {
|
||||
statement.close();
|
||||
}
|
||||
jdbcConnect.close();
|
||||
} catch (Exception e2) {
|
||||
log.error(e2.getMessage());
|
||||
if (statement != null) {
|
||||
statement.close();
|
||||
}
|
||||
statement = null;
|
||||
connectionCommonCache.removeCache(identifier);
|
||||
jdbcConnect.close();
|
||||
} catch (Exception e2) {
|
||||
log.error(e2.getMessage());
|
||||
}
|
||||
statement = null;
|
||||
connectionCommonCache.removeCache(identifier);
|
||||
}
|
||||
if (statement != null) {
|
||||
return statement;
|
||||
}
|
||||
}
|
||||
if (statement != null) {
|
||||
return statement;
|
||||
}
|
||||
// renew connection when failed
|
||||
Connection connection = DriverManager.getConnection(url, username, password);
|
||||
connection.setReadOnly(true);
|
||||
statement = connection.createStatement();
|
||||
int timeoutSecond = timeout / 1000;
|
||||
timeoutSecond = timeoutSecond <= 0 ? 1 : timeoutSecond;
|
||||
statement.setQueryTimeout(timeoutSecond);
|
||||
statement.setMaxRows(1000);
|
||||
if (reuseConnection) {
|
||||
JdbcConnect jdbcConnect = new JdbcConnect(connection);
|
||||
connectionCommonCache.addCache(identifier, jdbcConnect);
|
||||
}
|
||||
JdbcConnect jdbcConnect = new JdbcConnect(connection);
|
||||
connectionCommonCache.addCache(identifier, jdbcConnect);
|
||||
return statement;
|
||||
}
|
||||
|
||||
@@ -222,14 +186,13 @@ public class JdbcCommonCollect extends AbstractCollect {
|
||||
* eg:
|
||||
* query metrics:one tow three four
|
||||
* query sql:select one, tow, three, four from book limit 1;
|
||||
*
|
||||
* @param statement statement
|
||||
* @param sql sql
|
||||
* @param columns query metrics field list
|
||||
* @param sql sql
|
||||
* @param columns query metrics field list
|
||||
* @throws Exception when error happen
|
||||
*/
|
||||
private void queryOneRow(Statement statement, String sql, List<String> columns,
|
||||
CollectRep.MetricsData.Builder builder, long startTime) throws Exception {
|
||||
CollectRep.MetricsData.Builder builder, long startTime) throws Exception {
|
||||
statement.setMaxRows(1);
|
||||
try (ResultSet resultSet = statement.executeQuery(sql)) {
|
||||
if (resultSet.next()) {
|
||||
@@ -237,14 +200,14 @@ public class JdbcCommonCollect extends AbstractCollect {
|
||||
for (String column : columns) {
|
||||
if (CollectorConstants.RESPONSE_TIME.equals(column)) {
|
||||
long time = System.currentTimeMillis() - startTime;
|
||||
valueRowBuilder.addColumn(String.valueOf(time));
|
||||
valueRowBuilder.addColumns(String.valueOf(time));
|
||||
} else {
|
||||
String value = resultSet.getString(column);
|
||||
value = value == null ? CommonConstants.NULL_VALUE : value;
|
||||
valueRowBuilder.addColumn(value);
|
||||
valueRowBuilder.addColumns(value);
|
||||
}
|
||||
}
|
||||
builder.addValueRow(valueRowBuilder.build());
|
||||
builder.addValues(valueRowBuilder.build());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -254,15 +217,14 @@ public class JdbcCommonCollect extends AbstractCollect {
|
||||
* eg:
|
||||
* query metrics:one two three four
|
||||
* query sql:select key, value from book; the key is the query metrics fields
|
||||
* select key, value from book;
|
||||
* select key, value from book;
|
||||
* one - value1
|
||||
* two - value2
|
||||
* three - value3
|
||||
* four - value4
|
||||
*
|
||||
* @param statement statement
|
||||
* @param sql sql
|
||||
* @param columns query metrics field list
|
||||
* @param sql sql
|
||||
* @param columns query metrics field list
|
||||
* @throws Exception when error happen
|
||||
*/
|
||||
private void queryOneRowByMatchTwoColumns(Statement statement, String sql, List<String> columns,
|
||||
@@ -278,14 +240,14 @@ public class JdbcCommonCollect extends AbstractCollect {
|
||||
for (String column : columns) {
|
||||
if (CollectorConstants.RESPONSE_TIME.equals(column)) {
|
||||
long time = System.currentTimeMillis() - startTime;
|
||||
valueRowBuilder.addColumn(String.valueOf(time));
|
||||
valueRowBuilder.addColumns(String.valueOf(time));
|
||||
} else {
|
||||
String value = values.get(column.toLowerCase());
|
||||
value = value == null ? CommonConstants.NULL_VALUE : value;
|
||||
valueRowBuilder.addColumn(value);
|
||||
valueRowBuilder.addColumns(value);
|
||||
}
|
||||
}
|
||||
builder.addValueRow(valueRowBuilder.build());
|
||||
builder.addValues(valueRowBuilder.build());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -295,10 +257,9 @@ public class JdbcCommonCollect extends AbstractCollect {
|
||||
* query metrics:one tow three four
|
||||
* query sql:select one, tow, three, four from book;
|
||||
* and return multi row record mapping with the metrics
|
||||
*
|
||||
* @param statement statement
|
||||
* @param sql sql
|
||||
* @param columns query metrics field list
|
||||
* @param sql sql
|
||||
* @param columns query metrics field list
|
||||
* @throws Exception when error happen
|
||||
*/
|
||||
private void queryMultiRow(Statement statement, String sql, List<String> columns,
|
||||
@@ -309,54 +270,50 @@ public class JdbcCommonCollect extends AbstractCollect {
|
||||
for (String column : columns) {
|
||||
if (CollectorConstants.RESPONSE_TIME.equals(column)) {
|
||||
long time = System.currentTimeMillis() - startTime;
|
||||
valueRowBuilder.addColumn(String.valueOf(time));
|
||||
valueRowBuilder.addColumns(String.valueOf(time));
|
||||
} else {
|
||||
String value = resultSet.getString(column);
|
||||
value = value == null ? CommonConstants.NULL_VALUE : value;
|
||||
valueRowBuilder.addColumn(value);
|
||||
valueRowBuilder.addColumns(value);
|
||||
}
|
||||
}
|
||||
builder.addValueRow(valueRowBuilder.build());
|
||||
builder.addValues(valueRowBuilder.build());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* construct jdbc url due the jdbc protocol
|
||||
*
|
||||
* @param jdbcProtocol jdbc
|
||||
* @return URL
|
||||
*/
|
||||
private String constructDatabaseUrl(JdbcProtocol jdbcProtocol, String host, String port) {
|
||||
private String constructDatabaseUrl(JdbcProtocol jdbcProtocol) {
|
||||
if (Objects.nonNull(jdbcProtocol.getUrl())
|
||||
&& !Objects.equals("", jdbcProtocol.getUrl())
|
||||
&& jdbcProtocol.getUrl().startsWith("jdbc")) {
|
||||
// convert the URL to lowercase for case-insensitive checking
|
||||
String url = jdbcProtocol.getUrl().toLowerCase();
|
||||
// check whether the parameter is valid
|
||||
if (url.contains("create trigger") || url.contains("create alias") || url.contains("runscript from")
|
||||
|| url.contains("allowloadlocalinfile") || url.contains("allowloadlocalinfileinpath")
|
||||
|| url.contains("uselocalinfile") || url.contains("autodeserialize") || url.contains("detectcustomcollations")
|
||||
|| url.contains("serverstatusdiffinterceptor")) {
|
||||
throw new IllegalArgumentException("Invalid JDBC URL: contains malicious characters.");
|
||||
}
|
||||
// when has config jdbc url, use it
|
||||
return jdbcProtocol.getUrl();
|
||||
}
|
||||
return switch (jdbcProtocol.getPlatform()) {
|
||||
case "mysql", "mariadb" -> "jdbc:mysql://" + host + ":" + port
|
||||
case "mysql", "mariadb" ->
|
||||
"jdbc:mysql://" + jdbcProtocol.getHost() + ":" + jdbcProtocol.getPort()
|
||||
+ "/" + (jdbcProtocol.getDatabase() == null ? "" : jdbcProtocol.getDatabase())
|
||||
+ "?useUnicode=true&characterEncoding=utf-8&useSSL=false";
|
||||
case "postgresql" -> "jdbc:postgresql://" + host + ":" + port
|
||||
case "postgresql" ->
|
||||
"jdbc:postgresql://" + jdbcProtocol.getHost() + ":" + jdbcProtocol.getPort()
|
||||
+ "/" + (jdbcProtocol.getDatabase() == null ? "" : jdbcProtocol.getDatabase());
|
||||
case "clickhouse" -> "jdbc:clickhouse://" + host + ":" + port
|
||||
case "clickhouse" ->
|
||||
"jdbc:clickhouse://" + jdbcProtocol.getHost() + ":" + jdbcProtocol.getPort()
|
||||
+ "/" + (jdbcProtocol.getDatabase() == null ? "" : jdbcProtocol.getDatabase());
|
||||
case "sqlserver" -> "jdbc:sqlserver://" + host + ":" + port
|
||||
case "sqlserver" ->
|
||||
"jdbc:sqlserver://" + jdbcProtocol.getHost() + ":" + jdbcProtocol.getPort()
|
||||
+ ";" + (jdbcProtocol.getDatabase() == null ? "" : "DatabaseName=" + jdbcProtocol.getDatabase())
|
||||
+ ";trustServerCertificate=true;";
|
||||
case "oracle" -> "jdbc:oracle:thin:@" + host + ":" + port
|
||||
case "oracle" ->
|
||||
"jdbc:oracle:thin:@" + jdbcProtocol.getHost() + ":" + jdbcProtocol.getPort()
|
||||
+ "/" + (jdbcProtocol.getDatabase() == null ? "" : jdbcProtocol.getDatabase());
|
||||
case "dm" -> "jdbc:dm://" + host + ":" + port;
|
||||
case "dm" ->
|
||||
"jdbc:dm://" + jdbcProtocol.getHost() + ":" + jdbcProtocol.getPort();
|
||||
default -> throw new IllegalArgumentException("Not support database platform: " + jdbcProtocol.getPlatform());
|
||||
};
|
||||
}
|
||||
+4
-4
@@ -103,7 +103,7 @@ public class DnsCollectImpl extends AbstractCollect {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void collect(CollectRep.MetricsData.Builder builder, Metrics metrics) {
|
||||
public void collect(CollectRep.MetricsData.Builder builder, long monitorId, String app, Metrics metrics) {
|
||||
|
||||
DnsResolveResult dnsResolveResult;
|
||||
try {
|
||||
@@ -127,18 +127,18 @@ public class DnsCollectImpl extends AbstractCollect {
|
||||
if (StringUtils.equals(HEADER, metrics.getName())) {
|
||||
// add header columns
|
||||
Map<String, String> headerInfo = dnsResolveResult.getHeaderInfo();
|
||||
metrics.getAliasFields().forEach(field -> valueRowBuilder.addColumn(headerInfo.getOrDefault(field, CommonConstants.NULL_VALUE)));
|
||||
metrics.getAliasFields().forEach(field -> valueRowBuilder.addColumns(headerInfo.getOrDefault(field, CommonConstants.NULL_VALUE)));
|
||||
} else {
|
||||
// add question/answer/authority/additional columns
|
||||
List<String> currentMetricsResolveResultList = dnsResolveResult.getList(metrics.getName());
|
||||
for (int index = 0; index < metrics.getAliasFields().size(); index++) {
|
||||
valueRowBuilder.addColumn(index >= currentMetricsResolveResultList.size()
|
||||
valueRowBuilder.addColumns(index >= currentMetricsResolveResultList.size()
|
||||
? CommonConstants.NULL_VALUE
|
||||
: currentMetricsResolveResultList.get(index));
|
||||
}
|
||||
}
|
||||
|
||||
builder.addValueRow(valueRowBuilder.build());
|
||||
builder.addValues(valueRowBuilder.build());
|
||||
}
|
||||
|
||||
@Override
|
||||
+27
-105
@@ -17,11 +17,9 @@
|
||||
|
||||
package org.apache.hertzbeat.collector.collect.ftp;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.net.ftp.FTPClient;
|
||||
import org.apache.hertzbeat.collector.collect.AbstractCollect;
|
||||
@@ -31,10 +29,6 @@ import org.apache.hertzbeat.common.entity.job.Metrics;
|
||||
import org.apache.hertzbeat.common.entity.job.protocol.FtpProtocol;
|
||||
import org.apache.hertzbeat.common.entity.message.CollectRep;
|
||||
import org.apache.hertzbeat.common.util.CommonUtil;
|
||||
import org.apache.sshd.client.SshClient;
|
||||
import org.apache.sshd.client.session.ClientSession;
|
||||
import org.apache.sshd.sftp.client.SftpClient;
|
||||
import org.apache.sshd.sftp.client.SftpClientFactory;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
@@ -62,14 +56,33 @@ public class FtpCollectImpl extends AbstractCollect {
|
||||
Assert.hasText(ftpProtocol.getTimeout(), "Ftp Protocol timeout is required.");
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void collect(CollectRep.MetricsData.Builder builder, Metrics metrics) {
|
||||
boolean ssl = Boolean.parseBoolean(metrics.getFtp().getSsl());
|
||||
if (ssl){
|
||||
handleSftpCollect(builder, metrics);
|
||||
} else {
|
||||
handleFtpCollect(builder, metrics);
|
||||
public void collect(CollectRep.MetricsData.Builder builder, long monitorId, String app, Metrics metrics) {
|
||||
FTPClient ftpClient = new FTPClient();
|
||||
FtpProtocol ftpProtocol = metrics.getFtp();
|
||||
// Set timeout
|
||||
ftpClient.setControlKeepAliveReplyTimeout(Integer.parseInt(ftpProtocol.getTimeout()));
|
||||
|
||||
// Collect data to load in CollectRep.ValueRow.Builder's object
|
||||
CollectRep.ValueRow.Builder valueRowBuilder = CollectRep.ValueRow.newBuilder();
|
||||
Map<String, String> valueMap;
|
||||
try {
|
||||
valueMap = collectValue(ftpClient, ftpProtocol);
|
||||
metrics.getAliasFields().forEach(it -> {
|
||||
if (valueMap.containsKey(it)) {
|
||||
String fieldValue = valueMap.get(it);
|
||||
valueRowBuilder.addColumns(Objects.requireNonNullElse(fieldValue, CommonConstants.NULL_VALUE));
|
||||
} else {
|
||||
valueRowBuilder.addColumns(CommonConstants.NULL_VALUE);
|
||||
}
|
||||
});
|
||||
} catch (Exception e) {
|
||||
builder.setCode(CollectRep.Code.UN_CONNECTABLE);
|
||||
builder.setMsg(e.getMessage());
|
||||
return;
|
||||
}
|
||||
builder.addValues(valueRowBuilder.build());
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -100,23 +113,8 @@ public class FtpCollectImpl extends AbstractCollect {
|
||||
};
|
||||
}
|
||||
|
||||
private Map<String, String> collectValue(SftpClient sftpClient, FtpProtocol ftpProtocol) {
|
||||
boolean isActive;
|
||||
String responseTime;
|
||||
try {
|
||||
long startTime = System.currentTimeMillis();
|
||||
sftpClient.stat(ftpProtocol.getDirection());
|
||||
isActive = true;
|
||||
long endTime = System.currentTimeMillis();
|
||||
responseTime = String.valueOf(endTime - startTime);
|
||||
} catch (IOException e) {
|
||||
throw new IllegalArgumentException("[SFTPClient] error: {}" + CommonUtil.getMessageFromThrowable(e), e);
|
||||
}
|
||||
return Map.of("isActive", Boolean.toString(isActive), "responseTime", responseTime);
|
||||
}
|
||||
|
||||
/**
|
||||
* ftp login
|
||||
* login
|
||||
*/
|
||||
private void login(FTPClient ftpClient, FtpProtocol ftpProtocol) {
|
||||
try {
|
||||
@@ -149,84 +147,8 @@ public class FtpCollectImpl extends AbstractCollect {
|
||||
}
|
||||
}
|
||||
|
||||
private ClientSession connect(SshClient client, FtpProtocol ftpProtocol) {
|
||||
client.start();
|
||||
try {
|
||||
ClientSession session = client.connect(ftpProtocol.getUsername(), ftpProtocol.getHost(), Integer.parseInt(ftpProtocol.getPort()))
|
||||
.verify(Integer.parseInt(ftpProtocol.getTimeout()))
|
||||
.getSession();
|
||||
session.addPasswordIdentity(ftpProtocol.getPassword());
|
||||
session.auth().verify(Integer.parseInt(ftpProtocol.getTimeout()));
|
||||
return session;
|
||||
} catch (Exception e) {
|
||||
throw new IllegalArgumentException("[sftp connection] error: {}" + CommonUtil.getMessageFromThrowable(e), e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String supportProtocol() {
|
||||
return DispatchConstants.PROTOCOL_FTP;
|
||||
}
|
||||
|
||||
private void handleFtpCollect(CollectRep.MetricsData.Builder builder, Metrics metrics) {
|
||||
FTPClient ftpClient = new FTPClient();
|
||||
FtpProtocol ftpProtocol = metrics.getFtp();
|
||||
// Set timeout
|
||||
ftpClient.setControlKeepAliveReplyTimeout(Integer.parseInt(ftpProtocol.getTimeout()));
|
||||
|
||||
// Collect data to load in CollectRep.ValueRow.Builder's object
|
||||
CollectRep.ValueRow.Builder valueRowBuilder = CollectRep.ValueRow.newBuilder();
|
||||
Map<String, String> valueMap;
|
||||
try {
|
||||
valueMap = collectValue(ftpClient, ftpProtocol);
|
||||
metrics.getAliasFields().forEach(it -> {
|
||||
if (valueMap.containsKey(it)) {
|
||||
String fieldValue = valueMap.get(it);
|
||||
valueRowBuilder.addColumn(Objects.requireNonNullElse(fieldValue, CommonConstants.NULL_VALUE));
|
||||
} else {
|
||||
valueRowBuilder.addColumn(CommonConstants.NULL_VALUE);
|
||||
}
|
||||
});
|
||||
} catch (Exception e) {
|
||||
builder.setCode(CollectRep.Code.UN_CONNECTABLE);
|
||||
builder.setMsg(e.getMessage());
|
||||
return;
|
||||
}
|
||||
builder.addValueRow(valueRowBuilder.build());
|
||||
}
|
||||
|
||||
private void handleSftpCollect(CollectRep.MetricsData.Builder builder, Metrics metrics) {
|
||||
FtpProtocol ftpProtocol = metrics.getFtp();
|
||||
ClientSession session = null;
|
||||
SftpClient sftpClient = null;
|
||||
SshClient client = null;
|
||||
try {
|
||||
client = SshClient.setUpDefaultClient();
|
||||
session = connect(client, ftpProtocol);
|
||||
sftpClient = SftpClientFactory.instance().createSftpClient(session);
|
||||
Map<String, String> valueMap = collectValue(sftpClient, ftpProtocol);
|
||||
CollectRep.ValueRow.Builder valueRowBuilder = CollectRep.ValueRow.newBuilder();
|
||||
metrics.getAliasFields().forEach(it ->
|
||||
valueRowBuilder.addColumn(valueMap.getOrDefault(it, CommonConstants.NULL_VALUE))
|
||||
);
|
||||
builder.addValueRow(valueRowBuilder.build());
|
||||
} catch (Exception e) {
|
||||
builder.setCode(CollectRep.Code.UN_CONNECTABLE);
|
||||
builder.setMsg(e.getMessage());
|
||||
} finally {
|
||||
try {
|
||||
if (sftpClient != null && sftpClient.isOpen()){
|
||||
sftpClient.close();
|
||||
}
|
||||
if (session != null && session.isOpen()){
|
||||
session.close();
|
||||
}
|
||||
if (client != null && client.isOpen()){
|
||||
client.close();
|
||||
}
|
||||
} catch (Exception e){
|
||||
log.error("[SFTPClient] error while closing: {}", CommonUtil.getMessageFromThrowable(e), e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+60
-64
@@ -22,9 +22,9 @@ import com.google.gson.JsonArray;
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonObject;
|
||||
import com.google.gson.JsonParser;
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InterruptedIOException;
|
||||
import java.io.StringReader;
|
||||
import java.net.ConnectException;
|
||||
import java.net.UnknownHostException;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
@@ -41,6 +41,7 @@ import javax.net.ssl.SSLException;
|
||||
import javax.xml.parsers.DocumentBuilder;
|
||||
import javax.xml.parsers.DocumentBuilderFactory;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.net.util.Base64;
|
||||
import org.apache.hertzbeat.collector.collect.AbstractCollect;
|
||||
import org.apache.hertzbeat.collector.collect.common.http.CommonHttpClient;
|
||||
import org.apache.hertzbeat.collector.collect.http.promethus.AbstractPrometheusParse;
|
||||
@@ -58,7 +59,6 @@ import org.apache.hertzbeat.common.constants.SignConstants;
|
||||
import org.apache.hertzbeat.common.entity.job.Metrics;
|
||||
import org.apache.hertzbeat.common.entity.job.protocol.HttpProtocol;
|
||||
import org.apache.hertzbeat.common.entity.message.CollectRep;
|
||||
import org.apache.hertzbeat.common.util.Base64Util;
|
||||
import org.apache.hertzbeat.common.util.CommonUtil;
|
||||
import org.apache.hertzbeat.common.util.IpDomainUtil;
|
||||
import org.apache.http.Header;
|
||||
@@ -86,7 +86,6 @@ import org.springframework.http.HttpMethod;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
import org.springframework.util.StringUtils;
|
||||
import org.xml.sax.InputSource;
|
||||
import org.w3c.dom.Document;
|
||||
import org.w3c.dom.Node;
|
||||
import org.w3c.dom.NodeList;
|
||||
@@ -109,7 +108,8 @@ public class HttpCollectImpl extends AbstractCollect {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void collect(CollectRep.MetricsData.Builder builder, Metrics metrics) {
|
||||
public void collect(CollectRep.MetricsData.Builder builder,
|
||||
long monitorId, String app, Metrics metrics) {
|
||||
long startTime = System.currentTimeMillis();
|
||||
|
||||
HttpProtocol httpProtocol = metrics.getHttp();
|
||||
@@ -153,11 +153,9 @@ public class HttpCollectImpl extends AbstractCollect {
|
||||
case DispatchConstants.PARSE_XML_PATH ->
|
||||
parseResponseByXmlPath(resp, metrics.getAliasFields(), metrics.getHttp(), builder);
|
||||
case DispatchConstants.PARSE_WEBSITE ->
|
||||
parseResponseByWebsite(resp, metrics, metrics.getHttp(), builder, responseTime);
|
||||
parseResponseByWebsite(resp, metrics, metrics.getHttp(), builder, responseTime, response);
|
||||
case DispatchConstants.PARSE_SITE_MAP ->
|
||||
parseResponseBySiteMap(resp, metrics.getAliasFields(), builder);
|
||||
case DispatchConstants.PARSE_HEADER ->
|
||||
parseResponseByHeader(builder, metrics.getAliasFields(), response);
|
||||
default ->
|
||||
parseResponseByDefault(resp, metrics.getAliasFields(), metrics.getHttp(), builder, responseTime);
|
||||
}
|
||||
@@ -198,46 +196,48 @@ public class HttpCollectImpl extends AbstractCollect {
|
||||
}
|
||||
}
|
||||
|
||||
private void parseResponseByHeader(CollectRep.MetricsData.Builder builder, List<String> aliases, CloseableHttpResponse response) {
|
||||
CollectRep.ValueRow.Builder valueRowBuilder = CollectRep.ValueRow.newBuilder();
|
||||
for (String alias : aliases) {
|
||||
if (!StringUtils.hasText(alias)) {
|
||||
valueRowBuilder.addColumn(CommonConstants.NULL_VALUE);
|
||||
continue;
|
||||
}
|
||||
final Header firstHeader = response.getFirstHeader(alias);
|
||||
if (Objects.isNull(firstHeader)) {
|
||||
valueRowBuilder.addColumn(CommonConstants.NULL_VALUE);
|
||||
continue;
|
||||
}
|
||||
|
||||
valueRowBuilder.addColumn(firstHeader.getValue());
|
||||
}
|
||||
builder.addValueRow(valueRowBuilder.build());
|
||||
}
|
||||
|
||||
@Override
|
||||
public String supportProtocol() {
|
||||
return DispatchConstants.PROTOCOL_HTTP;
|
||||
}
|
||||
|
||||
private void parseResponseByWebsite(String resp, Metrics metrics, HttpProtocol http,
|
||||
CollectRep.MetricsData.Builder builder, Long responseTime) {
|
||||
CollectRep.MetricsData.Builder builder, Long responseTime,
|
||||
CloseableHttpResponse response) {
|
||||
CollectRep.ValueRow.Builder valueRowBuilder = CollectRep.ValueRow.newBuilder();
|
||||
int keywordNum = CollectUtil.countMatchKeyword(resp, http.getKeyword());
|
||||
for (String alias : metrics.getAliasFields()) {
|
||||
addColumnForSummary(responseTime, valueRowBuilder, keywordNum, alias);
|
||||
if ("summary".equalsIgnoreCase(metrics.getName())) {
|
||||
addColumnForSummary(responseTime, valueRowBuilder, keywordNum, alias);
|
||||
} else if ("header".equalsIgnoreCase(metrics.getName())) {
|
||||
addColumnFromHeader(valueRowBuilder, alias, response);
|
||||
}
|
||||
}
|
||||
builder.addValueRow(valueRowBuilder.build());
|
||||
builder.addValues(valueRowBuilder.build());
|
||||
}
|
||||
|
||||
private void addColumnFromHeader(CollectRep.ValueRow.Builder valueRowBuilder, String alias, CloseableHttpResponse response) {
|
||||
if (!StringUtils.hasText(alias)) {
|
||||
valueRowBuilder.addColumns(CommonConstants.NULL_VALUE);
|
||||
return;
|
||||
}
|
||||
|
||||
final Header firstHeader = response.getFirstHeader(alias);
|
||||
if (Objects.isNull(firstHeader)) {
|
||||
valueRowBuilder.addColumns(CommonConstants.NULL_VALUE);
|
||||
return;
|
||||
}
|
||||
|
||||
valueRowBuilder.addColumns(firstHeader.getValue());
|
||||
}
|
||||
|
||||
private void addColumnForSummary(Long responseTime, CollectRep.ValueRow.Builder valueRowBuilder, int keywordNum, String alias) {
|
||||
if (NetworkConstants.RESPONSE_TIME.equalsIgnoreCase(alias)) {
|
||||
valueRowBuilder.addColumn(responseTime.toString());
|
||||
valueRowBuilder.addColumns(responseTime.toString());
|
||||
} else if (CollectorConstants.KEYWORD.equalsIgnoreCase(alias)) {
|
||||
valueRowBuilder.addColumn(Integer.toString(keywordNum));
|
||||
valueRowBuilder.addColumns(Integer.toString(keywordNum));
|
||||
} else {
|
||||
valueRowBuilder.addColumn(CommonConstants.NULL_VALUE);
|
||||
valueRowBuilder.addColumns(CommonConstants.NULL_VALUE);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -247,11 +247,8 @@ public class HttpCollectImpl extends AbstractCollect {
|
||||
boolean isXmlFormat = true;
|
||||
try {
|
||||
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
|
||||
// see https://cheatsheetseries.owasp.org/cheatsheets/XML_External_Entity_Prevention_Cheat_Sheet.html
|
||||
dbf.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true);
|
||||
dbf.setXIncludeAware(false);
|
||||
DocumentBuilder db = dbf.newDocumentBuilder();
|
||||
Document document = db.parse(new InputSource(new StringReader(resp)));
|
||||
Document document = db.parse(new ByteArrayInputStream(resp.getBytes(StandardCharsets.UTF_8)));
|
||||
NodeList urlList = document.getElementsByTagName("url");
|
||||
for (int i = 0; i < urlList.getLength(); i++) {
|
||||
Node urlNode = urlList.item(i);
|
||||
@@ -289,10 +286,9 @@ public class HttpCollectImpl extends AbstractCollect {
|
||||
long startTime = System.currentTimeMillis();
|
||||
try {
|
||||
HttpGet httpGet = new HttpGet(siteUrl);
|
||||
try (CloseableHttpResponse response = CommonHttpClient.getHttpClient().execute(httpGet)) {
|
||||
statusCode = response.getStatusLine().getStatusCode();
|
||||
EntityUtils.consume(response.getEntity());
|
||||
}
|
||||
CloseableHttpResponse response = CommonHttpClient.getHttpClient().execute(httpGet);
|
||||
statusCode = response.getStatusLine().getStatusCode();
|
||||
EntityUtils.consume(response.getEntity());
|
||||
} catch (ClientProtocolException e1) {
|
||||
if (e1.getCause() != null) {
|
||||
errorMsg = e1.getCause().getMessage();
|
||||
@@ -312,19 +308,19 @@ public class HttpCollectImpl extends AbstractCollect {
|
||||
CollectRep.ValueRow.Builder valueRowBuilder = CollectRep.ValueRow.newBuilder();
|
||||
for (String alias : aliasFields) {
|
||||
if (NetworkConstants.URL.equalsIgnoreCase(alias)) {
|
||||
valueRowBuilder.addColumn(siteUrl);
|
||||
valueRowBuilder.addColumns(siteUrl);
|
||||
} else if (NetworkConstants.STATUS_CODE.equalsIgnoreCase(alias)) {
|
||||
valueRowBuilder.addColumn(statusCode == null
|
||||
valueRowBuilder.addColumns(statusCode == null
|
||||
? CommonConstants.NULL_VALUE : String.valueOf(statusCode));
|
||||
} else if (NetworkConstants.RESPONSE_TIME.equalsIgnoreCase(alias)) {
|
||||
valueRowBuilder.addColumn(String.valueOf(responseTime));
|
||||
valueRowBuilder.addColumns(String.valueOf(responseTime));
|
||||
} else if (NetworkConstants.ERROR_MSG.equalsIgnoreCase(alias)) {
|
||||
valueRowBuilder.addColumn(errorMsg);
|
||||
valueRowBuilder.addColumns(errorMsg);
|
||||
} else {
|
||||
valueRowBuilder.addColumn(CommonConstants.NULL_VALUE);
|
||||
valueRowBuilder.addColumns(CommonConstants.NULL_VALUE);
|
||||
}
|
||||
}
|
||||
builder.addValueRow(valueRowBuilder.build());
|
||||
builder.addValues(valueRowBuilder.build());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -348,34 +344,34 @@ public class HttpCollectImpl extends AbstractCollect {
|
||||
for (String alias : aliasFields) {
|
||||
Object value = stringMap.get(alias);
|
||||
if (value != null) {
|
||||
valueRowBuilder.addColumn(String.valueOf(value));
|
||||
valueRowBuilder.addColumns(String.valueOf(value));
|
||||
} else {
|
||||
if (alias.startsWith("$.")) {
|
||||
List<Object> subResults = JsonPathParser.parseContentWithJsonPath(resp, http.getParseScript() + alias.substring(1));
|
||||
if (subResults != null && subResults.size() > i) {
|
||||
Object resultValue = subResults.get(i);
|
||||
valueRowBuilder.addColumn(resultValue == null ? CommonConstants.NULL_VALUE : String.valueOf(resultValue));
|
||||
valueRowBuilder.addColumns(resultValue == null ? CommonConstants.NULL_VALUE : String.valueOf(resultValue));
|
||||
} else {
|
||||
valueRowBuilder.addColumn(CommonConstants.NULL_VALUE);
|
||||
valueRowBuilder.addColumns(CommonConstants.NULL_VALUE);
|
||||
}
|
||||
} else {
|
||||
addColumnForSummary(responseTime, valueRowBuilder, keywordNum, alias);
|
||||
}
|
||||
}
|
||||
}
|
||||
builder.addValueRow(valueRowBuilder.build());
|
||||
builder.addValues(valueRowBuilder.build());
|
||||
} else if (objectValue instanceof String stringValue) {
|
||||
CollectRep.ValueRow.Builder valueRowBuilder = CollectRep.ValueRow.newBuilder();
|
||||
for (String alias : aliasFields) {
|
||||
if (NetworkConstants.RESPONSE_TIME.equalsIgnoreCase(alias)) {
|
||||
valueRowBuilder.addColumn(responseTime.toString());
|
||||
valueRowBuilder.addColumns(responseTime.toString());
|
||||
} else if (CollectorConstants.KEYWORD.equalsIgnoreCase(alias)) {
|
||||
valueRowBuilder.addColumn(Integer.toString(keywordNum));
|
||||
valueRowBuilder.addColumns(Integer.toString(keywordNum));
|
||||
} else {
|
||||
valueRowBuilder.addColumn(stringValue);
|
||||
valueRowBuilder.addColumns(stringValue);
|
||||
}
|
||||
}
|
||||
builder.addValueRow(valueRowBuilder.build());
|
||||
builder.addValues(valueRowBuilder.build());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -404,24 +400,24 @@ public class HttpCollectImpl extends AbstractCollect {
|
||||
for (String aliasField : aliasFields) {
|
||||
if ("value".equals(aliasField)) {
|
||||
if (metric.getCounter() != null) {
|
||||
valueRowBuilder.addColumn(String.valueOf(metric.getCounter().getValue()));
|
||||
valueRowBuilder.addColumns(String.valueOf(metric.getCounter().getValue()));
|
||||
} else if (metric.getGauge() != null) {
|
||||
valueRowBuilder.addColumn(String.valueOf(metric.getGauge().getValue()));
|
||||
valueRowBuilder.addColumns(String.valueOf(metric.getGauge().getValue()));
|
||||
} else if (metric.getUntyped() != null) {
|
||||
valueRowBuilder.addColumn(String.valueOf(metric.getUntyped().getValue()));
|
||||
valueRowBuilder.addColumns(String.valueOf(metric.getUntyped().getValue()));
|
||||
} else if (metric.getInfo() != null) {
|
||||
valueRowBuilder.addColumn(String.valueOf(metric.getInfo().getValue()));
|
||||
valueRowBuilder.addColumns(String.valueOf(metric.getInfo().getValue()));
|
||||
} else if (metric.getSummary() != null) {
|
||||
valueRowBuilder.addColumn(String.valueOf(metric.getSummary().getValue()));
|
||||
valueRowBuilder.addColumns(String.valueOf(metric.getSummary().getValue()));
|
||||
} else if (metric.getHistogram() != null) {
|
||||
valueRowBuilder.addColumn(String.valueOf(metric.getHistogram().getValue()));
|
||||
valueRowBuilder.addColumns(String.valueOf(metric.getHistogram().getValue()));
|
||||
}
|
||||
} else {
|
||||
String columnValue = labelMap.get(aliasField);
|
||||
valueRowBuilder.addColumn(columnValue == null ? CommonConstants.NULL_VALUE : columnValue);
|
||||
valueRowBuilder.addColumns(columnValue == null ? CommonConstants.NULL_VALUE : columnValue);
|
||||
}
|
||||
}
|
||||
builder.addValueRow(valueRowBuilder.build());
|
||||
builder.addValues(valueRowBuilder.build());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -448,12 +444,12 @@ public class HttpCollectImpl extends AbstractCollect {
|
||||
JsonElement valueElement = object.get(alias);
|
||||
if (valueElement != null) {
|
||||
String value = valueElement.getAsString();
|
||||
valueRowBuilder.addColumn(value);
|
||||
valueRowBuilder.addColumns(value);
|
||||
} else {
|
||||
addColumnForSummary(responseTime, valueRowBuilder, keywordNum, alias);
|
||||
}
|
||||
}
|
||||
builder.addValueRow(valueRowBuilder.build());
|
||||
builder.addValues(valueRowBuilder.build());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -549,7 +545,7 @@ public class HttpCollectImpl extends AbstractCollect {
|
||||
if (StringUtils.hasText(authorization.getBasicAuthUsername())
|
||||
&& StringUtils.hasText(authorization.getBasicAuthPassword())) {
|
||||
String authStr = authorization.getBasicAuthUsername() + SignConstants.DOUBLE_MARK + authorization.getBasicAuthPassword();
|
||||
String encodedAuth = Base64Util.encode(authStr);
|
||||
String encodedAuth = new String(Base64.encodeBase64(authStr.getBytes(StandardCharsets.UTF_8)), StandardCharsets.UTF_8);
|
||||
requestBuilder.addHeader(HttpHeaders.AUTHORIZATION, DispatchConstants.BASIC + SignConstants.BLANK + encodedAuth);
|
||||
}
|
||||
}
|
||||
+10
-10
@@ -68,7 +68,7 @@ public class SslCertificateCollectImpl extends AbstractCollect {
|
||||
|
||||
@Override
|
||||
public void collect(CollectRep.MetricsData.Builder builder,
|
||||
Metrics metrics) {
|
||||
long monitorId, String app, Metrics metrics) {
|
||||
long startTime = System.currentTimeMillis();
|
||||
|
||||
HttpProtocol httpProtocol = metrics.getHttp();
|
||||
@@ -111,24 +111,24 @@ public class SslCertificateCollectImpl extends AbstractCollect {
|
||||
CollectRep.ValueRow.Builder valueRowBuilder = CollectRep.ValueRow.newBuilder();
|
||||
for (String alias : metrics.getAliasFields()) {
|
||||
if (CollectorConstants.RESPONSE_TIME.equalsIgnoreCase(alias)) {
|
||||
valueRowBuilder.addColumn(Long.toString(responseTime));
|
||||
valueRowBuilder.addColumns(Long.toString(responseTime));
|
||||
} else if (NAME_SUBJECT.equalsIgnoreCase(alias)) {
|
||||
valueRowBuilder.addColumn(x509Certificate.getSubjectX500Principal().getName());
|
||||
valueRowBuilder.addColumns(x509Certificate.getSubjectX500Principal().getName());
|
||||
} else if (NAME_EXPIRED.equalsIgnoreCase(alias)) {
|
||||
valueRowBuilder.addColumn(Boolean.toString(expired));
|
||||
valueRowBuilder.addColumns(Boolean.toString(expired));
|
||||
} else if (NAME_START_TIME.equalsIgnoreCase(alias)) {
|
||||
valueRowBuilder.addColumn(x509Certificate.getNotBefore().toLocaleString());
|
||||
valueRowBuilder.addColumns(x509Certificate.getNotBefore().toLocaleString());
|
||||
} else if (NAME_START_TIMESTAMP.equalsIgnoreCase(alias)) {
|
||||
valueRowBuilder.addColumn(String.valueOf(x509Certificate.getNotBefore().getTime()));
|
||||
valueRowBuilder.addColumns(String.valueOf(x509Certificate.getNotBefore().getTime()));
|
||||
} else if (NAME_END_TIME.equalsIgnoreCase(alias)) {
|
||||
valueRowBuilder.addColumn(x509Certificate.getNotAfter().toLocaleString());
|
||||
valueRowBuilder.addColumns(x509Certificate.getNotAfter().toLocaleString());
|
||||
} else if (NAME_END_TIMESTAMP.equalsIgnoreCase(alias)) {
|
||||
valueRowBuilder.addColumn(String.valueOf(x509Certificate.getNotAfter().getTime()));
|
||||
valueRowBuilder.addColumns(String.valueOf(x509Certificate.getNotAfter().getTime()));
|
||||
} else {
|
||||
valueRowBuilder.addColumn(CommonConstants.NULL_VALUE);
|
||||
valueRowBuilder.addColumns(CommonConstants.NULL_VALUE);
|
||||
}
|
||||
}
|
||||
builder.addValueRow(valueRowBuilder.build());
|
||||
builder.addValues(valueRowBuilder.build());
|
||||
}
|
||||
} catch (SSLPeerUnverifiedException e1) {
|
||||
String errorMsg = "Ssl certificate does not exist.";
|
||||
+1
-1
@@ -39,6 +39,6 @@ public class PrometheusLastParser extends AbstractPrometheusParse {
|
||||
@Override
|
||||
public void parse(String resp, List<String> aliasFields, HttpProtocol http, CollectRep.MetricsData.Builder builder) {
|
||||
CollectRep.ValueRow.Builder valueRowBuilder = CollectRep.ValueRow.newBuilder();
|
||||
aliasFields.forEach(aliasField -> valueRowBuilder.addColumn(CommonConstants.NULL_VALUE));
|
||||
aliasFields.forEach(aliasField -> valueRowBuilder.addColumns(CommonConstants.NULL_VALUE));
|
||||
}
|
||||
}
|
||||
+7
-7
@@ -63,35 +63,35 @@ public class PrometheusMatrixParser extends AbstractPrometheusParse {
|
||||
if (!CollectUtil.assertPromRequireField(aliasField)) {
|
||||
JsonElement jsonElement = r.getMetric().get(aliasField);
|
||||
if (jsonElement != null) {
|
||||
valueRowBuilder.addColumn(jsonElement.getAsString());
|
||||
valueRowBuilder.addColumns(jsonElement.getAsString());
|
||||
} else {
|
||||
valueRowBuilder.addColumn(CommonConstants.NULL_VALUE);
|
||||
valueRowBuilder.addColumns(CommonConstants.NULL_VALUE);
|
||||
}
|
||||
} else {
|
||||
if (CommonConstants.PROM_TIME.equals(aliasField)) {
|
||||
for (Object o : value) {
|
||||
if (o instanceof Double time) {
|
||||
valueRowBuilder.addColumn(String.valueOf(BigDecimal.valueOf(time * 1000)));
|
||||
valueRowBuilder.addColumns(String.valueOf(BigDecimal.valueOf(time * 1000)));
|
||||
setTimeFlag = true;
|
||||
}
|
||||
}
|
||||
if (!setTimeFlag) {
|
||||
valueRowBuilder.addColumn(CommonConstants.NULL_VALUE);
|
||||
valueRowBuilder.addColumns(CommonConstants.NULL_VALUE);
|
||||
}
|
||||
} else {
|
||||
for (Object o : value) {
|
||||
if (o instanceof String str) {
|
||||
valueRowBuilder.addColumn(str);
|
||||
valueRowBuilder.addColumns(str);
|
||||
setValueFlag = true;
|
||||
}
|
||||
}
|
||||
if (!setValueFlag) {
|
||||
valueRowBuilder.addColumn(CommonConstants.NULL_VALUE);
|
||||
valueRowBuilder.addColumns(CommonConstants.NULL_VALUE);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
builder.addValueRow(valueRowBuilder.build());
|
||||
builder.addValues(valueRowBuilder);
|
||||
}
|
||||
|
||||
}
|
||||
+7
-7
@@ -62,35 +62,35 @@ public class PrometheusVectorParser extends AbstractPrometheusParse {
|
||||
if (!CollectUtil.assertPromRequireField(aliasField)) {
|
||||
JsonElement jsonElement = r.getMetric().get(aliasField);
|
||||
if (jsonElement != null) {
|
||||
valueRowBuilder.addColumn(jsonElement.getAsString());
|
||||
valueRowBuilder.addColumns(jsonElement.getAsString());
|
||||
} else {
|
||||
valueRowBuilder.addColumn(CommonConstants.NULL_VALUE);
|
||||
valueRowBuilder.addColumns(CommonConstants.NULL_VALUE);
|
||||
}
|
||||
} else {
|
||||
if (CommonConstants.PROM_TIME.equals(aliasField)) {
|
||||
for (Object o : r.getValue()) {
|
||||
if (o instanceof Double time) {
|
||||
valueRowBuilder.addColumn(String.valueOf(BigDecimal.valueOf(time * 1000)));
|
||||
valueRowBuilder.addColumns(String.valueOf(BigDecimal.valueOf(time * 1000)));
|
||||
setTimeFlag = true;
|
||||
}
|
||||
}
|
||||
if (!setTimeFlag) {
|
||||
valueRowBuilder.addColumn(CommonConstants.NULL_VALUE);
|
||||
valueRowBuilder.addColumns(CommonConstants.NULL_VALUE);
|
||||
}
|
||||
} else {
|
||||
for (Object o : r.getValue()) {
|
||||
if (o instanceof String str) {
|
||||
valueRowBuilder.addColumn(str);
|
||||
valueRowBuilder.addColumns(str);
|
||||
setValueFlag = true;
|
||||
}
|
||||
}
|
||||
if (!setValueFlag) {
|
||||
valueRowBuilder.addColumn(CommonConstants.NULL_VALUE);
|
||||
valueRowBuilder.addColumns(CommonConstants.NULL_VALUE);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
builder.addValueRow(valueRowBuilder.build());
|
||||
builder.addValues(valueRowBuilder);
|
||||
}
|
||||
}
|
||||
}
|
||||
+2
-1
@@ -17,6 +17,7 @@
|
||||
|
||||
package org.apache.hertzbeat.collector.collect.http.promethus.exporter;
|
||||
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
@@ -418,7 +419,7 @@ public class ExporterParser {
|
||||
* @return true/false
|
||||
*/
|
||||
private boolean isValidLabelValue(String s) {
|
||||
return s != null;
|
||||
return s != null && s.equals(new String(s.getBytes(StandardCharsets.UTF_8)));
|
||||
}
|
||||
|
||||
private boolean isSum(String s) {
|
||||
+22
-18
@@ -17,7 +17,7 @@
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
package org.apache.hertzbeat.collector.collect.registry;
|
||||
package org.apache.hertzbeat.collector.collect.httpsd;
|
||||
|
||||
import com.ecwid.consul.transport.TransportException;
|
||||
import com.google.common.annotations.VisibleForTesting;
|
||||
@@ -27,22 +27,22 @@ import lombok.Setter;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.hertzbeat.collector.collect.AbstractCollect;
|
||||
import org.apache.hertzbeat.collector.collect.registry.discovery.DiscoveryClient;
|
||||
import org.apache.hertzbeat.collector.collect.registry.discovery.DiscoveryClientManagement;
|
||||
import org.apache.hertzbeat.collector.collect.registry.discovery.entity.ServerInfo;
|
||||
import org.apache.hertzbeat.collector.collect.httpsd.discovery.DiscoveryClient;
|
||||
import org.apache.hertzbeat.collector.collect.httpsd.discovery.DiscoveryClientManagement;
|
||||
import org.apache.hertzbeat.collector.collect.httpsd.discovery.entity.ServerInfo;
|
||||
import org.apache.hertzbeat.collector.constants.CollectorConstants;
|
||||
import org.apache.hertzbeat.collector.dispatch.DispatchConstants;
|
||||
import org.apache.hertzbeat.common.constants.CommonConstants;
|
||||
import org.apache.hertzbeat.common.entity.job.Metrics;
|
||||
import org.apache.hertzbeat.common.entity.job.protocol.RegistryProtocol;
|
||||
import org.apache.hertzbeat.common.entity.job.protocol.HttpsdProtocol;
|
||||
import org.apache.hertzbeat.common.entity.message.CollectRep;
|
||||
import org.apache.hertzbeat.common.util.CommonUtil;
|
||||
|
||||
/**
|
||||
* registry protocol collection implementation
|
||||
* http_sd protocol collection implementation
|
||||
*/
|
||||
@Slf4j
|
||||
public class RegistryImpl extends AbstractCollect {
|
||||
public class HttpsdImpl extends AbstractCollect {
|
||||
private static final String SERVER = "server";
|
||||
|
||||
@Setter
|
||||
@@ -51,17 +51,17 @@ public class RegistryImpl extends AbstractCollect {
|
||||
|
||||
@Override
|
||||
public void preCheck(Metrics metrics) throws IllegalArgumentException {
|
||||
RegistryProtocol registryProtocol = metrics.getRegistry();
|
||||
if (Objects.isNull(registryProtocol) || registryProtocol.isInvalid()){
|
||||
throw new IllegalArgumentException("registry collect must have a valid registry protocol param! ");
|
||||
HttpsdProtocol httpsdProtocol = metrics.getHttpsd();
|
||||
if (Objects.isNull(httpsdProtocol) || httpsdProtocol.isInvalid()){
|
||||
throw new IllegalArgumentException("http_sd collect must have a valid http_sd protocol param! ");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void collect(CollectRep.MetricsData.Builder builder, Metrics metrics) {
|
||||
RegistryProtocol registryProtocol = metrics.getRegistry();
|
||||
public void collect(CollectRep.MetricsData.Builder builder, long monitorId, String app, Metrics metrics) {
|
||||
HttpsdProtocol httpsdProtocol = metrics.getHttpsd();
|
||||
|
||||
try (DiscoveryClient discoveryClient = discoveryClientManagement.getClient(registryProtocol)) {
|
||||
try (DiscoveryClient discoveryClient = discoveryClientManagement.getClient(httpsdProtocol)) {
|
||||
collectMetrics(builder, metrics, discoveryClient);
|
||||
} catch (TransportException e1) {
|
||||
String errorMsg = "Consul " + CommonUtil.getMessageFromThrowable(e1);
|
||||
@@ -84,26 +84,30 @@ public class RegistryImpl extends AbstractCollect {
|
||||
ServerInfo serverInfo = discoveryClient.getServerInfo();
|
||||
metrics.getAliasFields().forEach(fieldName -> {
|
||||
if (StringUtils.equalsAnyIgnoreCase(CollectorConstants.RESPONSE_TIME, fieldName)) {
|
||||
valueRowBuilder.addColumn(String.valueOf(System.currentTimeMillis() - beginTime));
|
||||
valueRowBuilder.addColumns(String.valueOf(System.currentTimeMillis() - beginTime));
|
||||
} else {
|
||||
addColumnIfMatched(fieldName, serverInfo, valueRowBuilder);
|
||||
}
|
||||
});
|
||||
|
||||
builder.addValueRow(valueRowBuilder.build());
|
||||
builder.addValues(valueRowBuilder.build());
|
||||
} else {
|
||||
// Service instances monitor
|
||||
discoveryClient.getServices().forEach(serviceInstance -> {
|
||||
CollectRep.ValueRow.Builder valueRowBuilder = CollectRep.ValueRow.newBuilder();
|
||||
metrics.getAliasFields().forEach(fieldName -> addColumnIfMatched(fieldName, serviceInstance, valueRowBuilder));
|
||||
builder.addValueRow(valueRowBuilder.build());
|
||||
builder.addValues(valueRowBuilder.build());
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String supportProtocol() {
|
||||
return DispatchConstants.PROTOCOL_REGISTRY;
|
||||
return DispatchConstants.PROTOCOL_HTTP_SD;
|
||||
}
|
||||
|
||||
private boolean checkParamsFailed(HttpsdProtocol httpsd) {
|
||||
return Objects.isNull(httpsd) || httpsd.isInvalid();
|
||||
}
|
||||
|
||||
private void addColumnIfMatched(String fieldName, Object sourceObj, CollectRep.ValueRow.Builder valueRowBuilder) {
|
||||
@@ -116,7 +120,7 @@ public class RegistryImpl extends AbstractCollect {
|
||||
log.warn("No such field for {}", fieldName);
|
||||
}
|
||||
|
||||
valueRowBuilder.addColumn(StringUtils.isBlank(columnValue)
|
||||
valueRowBuilder.addColumns(StringUtils.isBlank(columnValue)
|
||||
? CommonConstants.NULL_VALUE
|
||||
: columnValue);
|
||||
}
|
||||
+1
-1
@@ -17,7 +17,7 @@
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
package org.apache.hertzbeat.collector.collect.registry.constant;
|
||||
package org.apache.hertzbeat.collector.collect.httpsd.constant;
|
||||
|
||||
/**
|
||||
* Discovery client instance status.
|
||||
+1
-1
@@ -17,7 +17,7 @@
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
package org.apache.hertzbeat.collector.collect.registry.constant;
|
||||
package org.apache.hertzbeat.collector.collect.httpsd.constant;
|
||||
|
||||
import java.util.Arrays;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
+7
-7
@@ -17,13 +17,13 @@
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
package org.apache.hertzbeat.collector.collect.registry.discovery;
|
||||
package org.apache.hertzbeat.collector.collect.httpsd.discovery;
|
||||
|
||||
import java.util.List;
|
||||
import org.apache.hertzbeat.collector.collect.registry.discovery.entity.ConnectConfig;
|
||||
import org.apache.hertzbeat.collector.collect.registry.discovery.entity.ServerInfo;
|
||||
import org.apache.hertzbeat.collector.collect.registry.discovery.entity.ServiceInstance;
|
||||
import org.apache.hertzbeat.common.entity.job.protocol.RegistryProtocol;
|
||||
import org.apache.hertzbeat.collector.collect.httpsd.discovery.entity.ConnectConfig;
|
||||
import org.apache.hertzbeat.collector.collect.httpsd.discovery.entity.ServerInfo;
|
||||
import org.apache.hertzbeat.collector.collect.httpsd.discovery.entity.ServiceInstance;
|
||||
import org.apache.hertzbeat.common.entity.job.protocol.HttpsdProtocol;
|
||||
|
||||
/**
|
||||
* DiscoveryClient interface.
|
||||
@@ -32,10 +32,10 @@ public interface DiscoveryClient extends AutoCloseable {
|
||||
|
||||
/**
|
||||
* Build connect config.
|
||||
* @param registryProtocol registry protocol.
|
||||
* @param httpsdProtocol httpsd protocol.
|
||||
* @return connect config object.
|
||||
*/
|
||||
ConnectConfig buildConnectConfig(RegistryProtocol registryProtocol);
|
||||
ConnectConfig buildConnectConfig(HttpsdProtocol httpsdProtocol);
|
||||
|
||||
/**
|
||||
* Initialize client.
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user