mirror of
https://github.com/dromara/hertzbeat.git
synced 2026-09-17 18:19:02 +00:00
Compare commits
86
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
af5e4b0049 | ||
|
|
5402437eac | ||
|
|
9fb3f39eb1 | ||
|
|
2430448089 | ||
|
|
993de3d504 | ||
|
|
955ecd2128 | ||
|
|
96e5402c09 | ||
|
|
0a6e8147e8 | ||
|
|
7779056983 | ||
|
|
ca3348adf2 | ||
|
|
dc822f50e8 | ||
|
|
896adb76a2 | ||
|
|
2a49fa5774 | ||
|
|
2259d51cae | ||
|
|
e9e49cfbc5 | ||
|
|
3eba906491 | ||
|
|
6645c5d4b2 | ||
|
|
88fb007ef0 | ||
|
|
4892ef101f | ||
|
|
d0b7e38537 | ||
|
|
096153b3a4 | ||
|
|
b313db36c6 | ||
|
|
ce61c7d456 | ||
|
|
47298033dc | ||
|
|
f05e91247a | ||
|
|
1592c93d25 | ||
|
|
46d609a95e | ||
|
|
f17fb02441 | ||
|
|
e6cc71ed56 | ||
|
|
e2a9160e59 | ||
|
|
7ebeee2c1f | ||
|
|
ccfc8dc8ce | ||
|
|
ca9db17241 | ||
|
|
7a40bdee12 | ||
|
|
5db20d33f4 | ||
|
|
896869c611 | ||
|
|
32ce88b2c0 | ||
|
|
2288d8e900 | ||
|
|
dbb81d44ff | ||
|
|
320766a48e | ||
|
|
efb2ac02df | ||
|
|
06c939c810 | ||
|
|
e56823b240 | ||
|
|
3b18d1ddaf | ||
|
|
d44fe43eb0 | ||
|
|
a221ddfba2 | ||
|
|
8e31a3147b | ||
|
|
d2f9a56fe7 | ||
|
|
a0b41dc7bb | ||
|
|
3f572a1ddc | ||
|
|
767deccee5 | ||
|
|
9221e2f6c1 | ||
|
|
0a36b3df90 | ||
|
|
f3202133d8 | ||
|
|
6ee458c521 | ||
|
|
cbc1caf4ac | ||
|
|
86db630fc7 | ||
|
|
145c4d1d5e | ||
|
|
0217cbb7f9 | ||
|
|
9f5df95f29 | ||
|
|
0f955019bf | ||
|
|
129b6282d3 | ||
|
|
36c5d8f518 | ||
|
|
de8a473e24 | ||
|
|
ffc4641dc9 | ||
|
|
d0cb9f8bf3 | ||
|
|
0d4ff33f19 | ||
|
|
86f40e5e15 | ||
|
|
dbbbc045d4 | ||
|
|
b0fdd5e11d | ||
|
|
9c5ea20b15 | ||
|
|
7a74f80906 | ||
|
|
ee32a890eb | ||
|
|
ec1c04194b | ||
|
|
55d8dfdede | ||
|
|
918073dca7 | ||
|
|
2defaecd93 | ||
|
|
641ba47f4c | ||
|
|
ccbc2151ae | ||
|
|
1cb919a301 | ||
|
|
7351a03c81 | ||
|
|
26c3a802d1 | ||
|
|
47dbe2fd2a | ||
|
|
f4943e9d89 | ||
|
|
1f6614d1a1 | ||
|
|
4a96c02b9a |
@@ -0,0 +1,53 @@
|
||||
# Licensed to the Apache Software Foundation (ASF) under one
|
||||
# or more contributor license agreements. See the NOTICE file
|
||||
# distributed with this work for additional information
|
||||
# regarding copyright ownership. The ASF licenses this file
|
||||
# to you under the Apache License, Version 2.0 (the
|
||||
# "License"); you may not use this file except in compliance
|
||||
# with the License. You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing,
|
||||
# software distributed under the License is distributed on an
|
||||
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
# KIND, either express or implied. See the License for the
|
||||
# specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
# This workflow will build a Java project with Maven
|
||||
# For more information see: https://help.github.com/actions/language-and-framework-guides/building-and-testing-java-with-maven
|
||||
|
||||
name: Monitor E2E Test
|
||||
|
||||
|
||||
on:
|
||||
schedule:
|
||||
# trigger at 01:00 everyday
|
||||
- cron: '0 1 * * *'
|
||||
push:
|
||||
branches: [ action* ]
|
||||
jobs:
|
||||
check-license-header:
|
||||
name: Monitor E2E Test
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 10
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: ./script/ci/github-actions/setup-deps
|
||||
- name: Build with Maven
|
||||
run: mvn clean -B package -Prelease -Dmaven.test.skip=true --file pom.xml
|
||||
- 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 K8s Monitor E2E Test
|
||||
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/k8s
|
||||
sudo docker-compose version
|
||||
sudo docker-compose up --exit-code-from testing --remove-orphans
|
||||
+2
-1
@@ -6,13 +6,14 @@ Thumbs.db
|
||||
build/
|
||||
out/
|
||||
micronaut-cli.yml
|
||||
.mvn/
|
||||
*.log
|
||||
package-lock.json
|
||||
*.zip
|
||||
jdk/
|
||||
data/
|
||||
|
||||
!/e2e/**/data/
|
||||
|
||||
### STS ###
|
||||
.apt_generated
|
||||
.classpath
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
// limitations under the License.
|
||||
//
|
||||
{
|
||||
"globs": ["home/**/*.md"],
|
||||
"config": {
|
||||
"default": true,
|
||||
"MD001": true,
|
||||
@@ -39,9 +40,9 @@
|
||||
"MD047": true,
|
||||
"MD052": true
|
||||
},
|
||||
"ignore": [
|
||||
"node_modules/",
|
||||
"target/",
|
||||
"dist/"
|
||||
"ignores": [
|
||||
"**/node_modules/**",
|
||||
"**/target/**",
|
||||
"**/dist/**"
|
||||
]
|
||||
}
|
||||
|
||||
+17
@@ -0,0 +1,17 @@
|
||||
# Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
# contributor license agreements. See the NOTICE file distributed with
|
||||
# this work for additional information regarding copyright ownership.
|
||||
# The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
# (the "License"); you may not use this file except in compliance with
|
||||
# the License. You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
wrapperVersion=3.3.2
|
||||
distributionType=only-script
|
||||
distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.9.9/apache-maven-3.9.9-bin.zip
|
||||
@@ -4,9 +4,10 @@
|
||||
</a>
|
||||
</p>
|
||||
|
||||
<h4 align="center">
|
||||
<a href="README.md">English Document</a> | <a href="README_CN.md">中文文档</a>
|
||||
</h4>
|
||||
<p align="center">
|
||||
<b>Readme</b>:
|
||||
<b><a href="README.md">English</a></b> | <a href="README_CN.md">中文</a> | <a href="README_JP.md">日本語</a>
|
||||
</p>
|
||||
|
||||
> A real-time monitoring system with agentless, performance cluster, prometheus-compatible, custom monitoring and status page building capabilities.
|
||||
|
||||
@@ -19,6 +20,7 @@
|
||||
[](https://artifacthub.io/packages/search?repo=hertzbeat)
|
||||
[](https://www.youtube.com/channel/UCri75zfWX0GHqJFPENEbLow)
|
||||
[](https://gitpod.io/#https://github.com/apache/hertzbeat)
|
||||
[](https://deepwiki.com/apache/hertzbeat)
|
||||
|
||||
**Home: [hertzbeat.apache.org](https://hertzbeat.apache.org)**
|
||||
**Email: <a href="mailto:dev-subscribe@hertzbeat.apache.org">Mail to `dev-subscribe@hertzbeat.apache.org`</a> to subscribe mailing lists**
|
||||
|
||||
+4
-3
@@ -4,9 +4,10 @@
|
||||
</a>
|
||||
</p>
|
||||
|
||||
<h4 align="center">
|
||||
<a href="README_CN.md">中文文档</a> | <a href="README.md">English Document</a>
|
||||
</h4>
|
||||
<p align="center">
|
||||
<b>Readme</b>:
|
||||
<a href="README.md">English</a> | <b><a href="README_CN.md">中文</a></b> | <a href="README_JP.md">日本語</a>
|
||||
</p>
|
||||
|
||||
> 实时监控系统,无需 Agent,性能集群,兼容 Prometheus,自定义监控和状态页构建能力。
|
||||
|
||||
|
||||
+578
@@ -0,0 +1,578 @@
|
||||
<p align="center">
|
||||
<a href="https://hertzbeat.apache.org">
|
||||
<img alt="hertzbeat" src="/home/static/img/hertzbeat-brand.svg" width="260">
|
||||
</a>
|
||||
</p>
|
||||
|
||||
<p align="center">
|
||||
<b>Readme</b>:
|
||||
<a href="README.md">English</a> | <a href="README_CN.md">中文</a> | <b><a href="README_JP.md">日本語</a></b>
|
||||
</p>
|
||||
|
||||
> オープンソースのリアルタイム監視システム、エージェントレス、クラスタ対応、Prometheus互換、カスタムおよびステータスページ付き。
|
||||
|
||||
[](https://discord.gg/Fb6M73htGr)
|
||||
[](https://www.reddit.com/r/hertzbeat/)
|
||||
[](https://x.com/hertzbeat1024)
|
||||
[](https://www.bestpractices.dev/projects/8139)
|
||||
[](https://app.codecov.io/gh/apache/hertzbeat)
|
||||
[](https://hub.docker.com/r/apache/hertzbeat)
|
||||
[](https://artifacthub.io/packages/search?repo=hertzbeat)
|
||||
[](https://www.youtube.com/channel/UCri75zfWX0GHqJFPENEbLow)
|
||||
[](https://gitpod.io/#https://github.com/apache/hertzbeat)
|
||||
|
||||
|
||||
**公式サイト: [hertzbeat.apache.org](https://hertzbeat.apache.org)**
|
||||
**メール:** メーリングリストに登録するために、<a href="mailto:dev-subscribe@hertzbeat.apache.org">dev-subscribe@hertzbeat.apache.org</a>にメールを送ってください。
|
||||
|
||||
|
||||
## 🎡 <font color="green">紹介</font>
|
||||
|
||||
[Apache HertzBeat](https://github.com/apache/hertzbeat) (incubating)はオープンソースのリアルタイム監視システム、エージェントレス、クラスタ対応、Prometheus互換、カスタムおよびステータスページ付き。
|
||||
|
||||
### 特性
|
||||
|
||||
- **モニター・アラーム・通知** を一体化し、Web、データベース、キャッシュ、OS、ミドルウェア、クラウドネイティブ、ネットワークなどをサポート。
|
||||
- 使いやすさを重視し、マウスのクリックだけで完全なWebベースの操作が可能。
|
||||
- `Http、Jmx、Ssh、Snmp、jdbc、Prometheus`などのプロトコルを設定可能にし、テンプレート`YML`ファイルをオンラインで設定するだけで、あらゆるメトリクスを収集できるようにします。HertzBeatでオンライン設定するだけで、`K8S`や`Docker`のような新しい監視タイプに素早く対応できることを想像してみてください。
|
||||
- `Prometheus`のエコシステム互換、Prometheusが監視できるものを、全てオンライン設定によって監視することができます。
|
||||
- 高性能で、コレクタークラスタ、マルチアイソレートネットワーク、クラウドエッジをサポート。
|
||||
- 柔軟なアラーム閾値ルールで、メール、discord、slack、telegramなどを通じてタイムリーに通知。
|
||||
- 強力なステータスページを簡単に構築し、リアルタイムのステータスをユーザーと共有。
|
||||
|
||||
|
||||
> `HertzBeat`の強力なカスタマイズ、多種類のサポート、高性能および容易な拡張性は、ユーザーが迅速に独自の監視システムを構築するのを支援することを目的としています。
|
||||
|
||||
----
|
||||
|
||||

|
||||
|
||||

|
||||
|
||||

|
||||
|
||||
----
|
||||
|
||||
## 🥐 モジュール
|
||||
|
||||

|
||||
|
||||
## ⛄ 利用可能
|
||||
|
||||
> `mysql`、`Java仮想マシン`、`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)
|
||||
- その他、カスタマイズされたモニターテンプレート。
|
||||
- 通知利用可能 `Discord` `Slack` `Telegram` `Email` `Dingtalk` `WeChat` `FeiShu` `Webhook` `SMS` `ServerChan`。
|
||||
|
||||
## 🐕 クイックスタート
|
||||
|
||||
- HertzBeat をローカルに展開する場合は、以下のデプロイメントドキュメントを参照してください。
|
||||
|
||||
### 🍞 HertzBeatのインストール
|
||||
> HertzBeatは、ソースコードのインストールとブート、Dockerコンテナの実行とインストールパッケージによるインストールとデプロイをサポートし、CPUアーキテクチャはx86/arm64をサポートします。
|
||||
|
||||
##### 方式1:Docker
|
||||
|
||||
1. `docker` で以下の指令を実行します:
|
||||
|
||||
```shell
|
||||
docker run -d -p 1157:1157 -p 1158:1158 --name hertzbeat apache/hertzbeat
|
||||
```
|
||||
|
||||
2. スタート:`http://localhost:4200`にアクセスします。デフォルトのアカウントとパスワード:`admin/hertzbeat`。
|
||||
|
||||
3. コレクタークラスタのデプロイメント(オプション)
|
||||
|
||||
```shell
|
||||
docker run -d -e IDENTITY=custom-collector-name -e MANAGER_HOST=127.0.0.1 -e MANAGER_PORT=1158 --name hertzbeat-collector apache/hertzbeat-collector
|
||||
```
|
||||
|
||||
- `-e IDENTITY=custom-collector-name` :コレクターのユニーク ID。
|
||||
- `-e MODE=public` :実行モード(パブリッククラスタまたはプライベートクラウドエッジ)。
|
||||
- `-e MANAGER_HOST=127.0.0.1` :メインhertzbeatサーバーのIP。
|
||||
- `-e MANAGER_PORT=1158` :メインhertzbeatサーバポート。
|
||||
|
||||
|
||||
詳細ステップ [通过 Docker 方式安装 HertzBeat](https://hertzbeat.apache.org/docs/start/docker-deploy)
|
||||
|
||||
##### 方式2:インストールパッケージ
|
||||
|
||||
1. リリースパッケージをダウンロード `hertzbeat-xx.tar.gz` [Download](https://hertzbeat.apache.org/docs/download)
|
||||
2. HertzBeatのymlファイルを設定 `hertzbeat/config/application.yml` (オプション)
|
||||
3. コマンド`$ ./bin/startup.sh`または`bin/startup.bat`を実行
|
||||
4. スタート:`http://localhost:4200`にアクセスします。デフォルトのアカウントとパスワード:`admin/hertzbeat`
|
||||
5. コレクタークラスタのデプロイメント(オプション)
|
||||
- コレクターパッケージを別のホストにダウンロード `hertzbeat-collector-xx.tar.gz` [Download](https://hertzbeat.apache.org/docs/download)
|
||||
- コレクターのymlファイルを設定 `hertzbeat-collector/config/application.yml`
|
||||
```yaml
|
||||
collector:
|
||||
dispatch:
|
||||
entrance:
|
||||
netty:
|
||||
enabled: true
|
||||
identity: ${IDENTITY:}
|
||||
mode: ${MODE:public}
|
||||
manager-host: ${MANAGER_HOST:127.0.0.1}
|
||||
manager-port: ${MANAGER_PORT:1158}
|
||||
```
|
||||
- `identity: ${IDENTITY:}`:コレクターのユニークID。
|
||||
- `mode: ${MODE:public}`:実行モード(パブリッククラスタまたはプライベートクラウドエッジ)。
|
||||
- `manager-host: ${MANAGER_HOST:127.0.0.1}`:メインhertzbeatサーバーのIP。
|
||||
- `manager-port: ${MANAGER_PORT:1158}`:メインhertzbeatサーバポート。
|
||||
- コマンド`$ ./bin/startup.sh`または`bin/startup.bat`を実行。
|
||||
- `http://localhost:1157`にアクセスし、登録された新しいコレクターを見ることがでます。
|
||||
|
||||
詳細ステップ [通过安装包安装HertzBeat](https://hertzbeat.apache.org/docs/start/package-deploy)
|
||||
|
||||
##### 方式3:ローカルの実行
|
||||
|
||||
1. ローカルの実行には、バックエンドのプロジェクト`manager`とフロントエンドのプロジェクト`web-app`を起動する必要があります。
|
||||
2. バックエンド:`maven3+`、`java17`と`lombok`の環境は必要です。`YML` 設定を修正し、Java仮想マシンパラメータに`--add-opens=java.base/java.nio=org.apache.arrow.memory.core,ALL-UNNAMED` を追加し、`manager` を起動します。
|
||||
3. フロントエンド:`nodejs npm angular-cli`の環境は必要です。ローカルのバックエンドが立ち上がったら、`web-app` ディレクトリで `ng serve --open` というコマンドを実行します。
|
||||
4. スタート:`http://localhost:4200`にアクセスします。デフォルトのアカウントとパスワード:`admin/hertzbeat`。
|
||||
|
||||
詳細ステップ [貢献ガイド](CONTRIBUTING.md)
|
||||
|
||||
##### 方式4:Docker-Compose
|
||||
|
||||
[Docker-Compose 部署脚本](script/docker-compose)でpostgresql/mysqlデータベース、victoria-metrics、iotdb、またはtdengine時系列データベースとHertzbeat一括デプロイ。
|
||||
|
||||
詳細ステップ [通过 Docker-Compose 安装 HertzBeat](script/docker-compose/README.md)
|
||||
|
||||
##### 方式5:Kubernetes Helm Charts
|
||||
|
||||
Helm ChartでHertzBeatクラスタコンポーネントをKubernetesクラスタに一括デプロイ。
|
||||
|
||||
詳細ステップ [Artifact Hub](https://artifacthub.io/packages/helm/hertzbeat/hertzbeat)
|
||||
|
||||
**HAVE FUN**
|
||||
|
||||
## ✨ Contributors
|
||||
|
||||
Thanks these wonderful people, welcome to join us:
|
||||
[貢献ガイド](CONTRIBUTING.md)
|
||||
|
||||
<!-- ALL-CONTRIBUTORS-LIST:START - Do not remove or modify this section -->
|
||||
<!-- prettier-ignore-start -->
|
||||
<!-- markdownlint-disable -->
|
||||
<table>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/tomsun28"><img src="https://avatars.githubusercontent.com/u/24788200?v=4?s=100" width="100px;" alt="tomsun28"/><br /><sub><b>tomsun28</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=tomsun28" title="Code">💻</a> <a href="https://github.com/apache/hertzbeat/commits?author=tomsun28" title="Documentation">📖</a> <a href="#design-tomsun28" title="Design">🎨</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/wang1027-wqh"><img src="https://avatars.githubusercontent.com/u/71161318?v=4?s=100" width="100px;" alt="会编程的王学长"/><br /><sub><b>会编程的王学长</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=wang1027-wqh" title="Code">💻</a> <a href="https://github.com/apache/hertzbeat/commits?author=wang1027-wqh" title="Documentation">📖</a> <a href="#design-wang1027-wqh" title="Design">🎨</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://www.maxkey.top/"><img src="https://avatars.githubusercontent.com/u/1563377?v=4?s=100" width="100px;" alt="MaxKey"/><br /><sub><b>MaxKey</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=shimingxy" title="Code">💻</a> <a href="#design-shimingxy" title="Design">🎨</a> <a href="#ideas-shimingxy" title="Ideas, Planning, & Feedback">🤔</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://blog.gcdd.top/"><img src="https://avatars.githubusercontent.com/u/26523525?v=4?s=100" width="100px;" alt="观沧海"/><br /><sub><b>观沧海</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=gcdd1993" title="Code">💻</a> <a href="#design-gcdd1993" title="Design">🎨</a> <a href="https://github.com/apache/hertzbeat/issues?q=author%3Agcdd1993" title="Bug reports">🐛</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/a25017012"><img src="https://avatars.githubusercontent.com/u/32265356?v=4?s=100" width="100px;" alt="yuye"/><br /><sub><b>yuye</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=a25017012" title="Code">💻</a> <a href="https://github.com/apache/hertzbeat/commits?author=a25017012" title="Documentation">📖</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/jx10086"><img src="https://avatars.githubusercontent.com/u/5323228?v=4?s=100" width="100px;" alt="jx10086"/><br /><sub><b>jx10086</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=jx10086" title="Code">💻</a> <a href="https://github.com/apache/hertzbeat/issues?q=author%3Ajx10086" title="Bug reports">🐛</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/winnerTimer"><img src="https://avatars.githubusercontent.com/u/76024658?v=4?s=100" width="100px;" alt="winnerTimer"/><br /><sub><b>winnerTimer</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=winnerTimer" title="Code">💻</a> <a href="https://github.com/apache/hertzbeat/issues?q=author%3AwinnerTimer" title="Bug reports">🐛</a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/goo-kits"><img src="https://avatars.githubusercontent.com/u/13163673?v=4?s=100" width="100px;" alt="goo-kits"/><br /><sub><b>goo-kits</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=goo-kits" title="Code">💻</a> <a href="https://github.com/apache/hertzbeat/issues?q=author%3Agoo-kits" title="Bug reports">🐛</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/brave4Time"><img src="https://avatars.githubusercontent.com/u/105094014?v=4?s=100" width="100px;" alt="brave4Time"/><br /><sub><b>brave4Time</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=brave4Time" title="Code">💻</a> <a href="https://github.com/apache/hertzbeat/issues?q=author%3Abrave4Time" title="Bug reports">🐛</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/walkerlee-lab"><img src="https://avatars.githubusercontent.com/u/8426753?v=4?s=100" width="100px;" alt="WalkerLee"/><br /><sub><b>WalkerLee</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=walkerlee-lab" title="Code">💻</a> <a href="https://github.com/apache/hertzbeat/issues?q=author%3Awalkerlee-lab" title="Bug reports">🐛</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/fullofjoy"><img src="https://avatars.githubusercontent.com/u/30247571?v=4?s=100" width="100px;" alt="jianghang"/><br /><sub><b>jianghang</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=fullofjoy" title="Code">💻</a> <a href="https://github.com/apache/hertzbeat/issues?q=author%3Afullofjoy" title="Bug reports">🐛</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/ChineseTony"><img src="https://avatars.githubusercontent.com/u/24618786?v=4?s=100" width="100px;" alt="ChineseTony"/><br /><sub><b>ChineseTony</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=ChineseTony" title="Code">💻</a> <a href="https://github.com/apache/hertzbeat/issues?q=author%3AChineseTony" title="Bug reports">🐛</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/wyt199905"><img src="https://avatars.githubusercontent.com/u/85098809?v=4?s=100" width="100px;" alt="wyt199905"/><br /><sub><b>wyt199905</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=wyt199905" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/weifuqing"><img src="https://avatars.githubusercontent.com/u/13931013?v=4?s=100" width="100px;" alt="卫傅庆"/><br /><sub><b>卫傅庆</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=weifuqing" title="Code">💻</a> <a href="https://github.com/apache/hertzbeat/issues?q=author%3Aweifuqing" title="Bug reports">🐛</a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/zklmcookle"><img src="https://avatars.githubusercontent.com/u/107192352?v=4?s=100" width="100px;" alt="zklmcookle"/><br /><sub><b>zklmcookle</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=zklmcookle" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/DevilX5"><img src="https://avatars.githubusercontent.com/u/13269921?v=4?s=100" width="100px;" alt="DevilX5"/><br /><sub><b>DevilX5</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=DevilX5" title="Documentation">📖</a> <a href="https://github.com/apache/hertzbeat/commits?author=DevilX5" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/djzeng"><img src="https://avatars.githubusercontent.com/u/14074864?v=4?s=100" width="100px;" alt="tea"/><br /><sub><b>tea</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=djzeng" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/yangshihui"><img src="https://avatars.githubusercontent.com/u/28550208?v=4?s=100" width="100px;" alt="yangshihui"/><br /><sub><b>yangshihui</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=yangshihui" title="Code">💻</a> <a href="https://github.com/apache/hertzbeat/issues?q=author%3Ayangshihui" title="Bug reports">🐛</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/DreamGirl524"><img src="https://avatars.githubusercontent.com/u/81132838?v=4?s=100" width="100px;" alt="DreamGirl524"/><br /><sub><b>DreamGirl524</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=DreamGirl524" title="Code">💻</a> <a href="https://github.com/apache/hertzbeat/commits?author=DreamGirl524" title="Documentation">📖</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/gzwlly"><img src="https://avatars.githubusercontent.com/u/83171907?v=4?s=100" width="100px;" alt="gzwlly"/><br /><sub><b>gzwlly</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=gzwlly" title="Documentation">📖</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/cuipiheqiuqiu"><img src="https://avatars.githubusercontent.com/u/76642201?v=4?s=100" width="100px;" alt="cuipiheqiuqiu"/><br /><sub><b>cuipiheqiuqiu</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=cuipiheqiuqiu" title="Code">💻</a> <a href="https://github.com/apache/hertzbeat/commits?author=cuipiheqiuqiu" title="Tests">⚠️</a> <a href="#design-cuipiheqiuqiu" title="Design">🎨</a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/oyiyou"><img src="https://avatars.githubusercontent.com/u/39228891?v=4?s=100" width="100px;" alt="lambert"/><br /><sub><b>lambert</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=oyiyou" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="http://mroldx.xyz/"><img src="https://avatars.githubusercontent.com/u/34847828?v=4?s=100" width="100px;" alt="mroldx"/><br /><sub><b>mroldx</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=mroldx" title="Documentation">📖</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/woshiniusange"><img src="https://avatars.githubusercontent.com/u/91513022?v=4?s=100" width="100px;" alt="woshiniusange"/><br /><sub><b>woshiniusange</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=woshiniusange" title="Documentation">📖</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://vampireachao.github.io/"><img src="https://avatars.githubusercontent.com/u/52746628?v=4?s=100" width="100px;" alt="VampireAchao"/><br /><sub><b>VampireAchao</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=VampireAchao" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/Ceilzcx"><img src="https://avatars.githubusercontent.com/u/48920254?v=4?s=100" width="100px;" alt="zcx"/><br /><sub><b>zcx</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=Ceilzcx" title="Code">💻</a> <a href="https://github.com/apache/hertzbeat/issues?q=author%3ACeilzcx" title="Bug reports">🐛</a> <a href="#design-Ceilzcx" title="Design">🎨</a> <a href="https://github.com/apache/hertzbeat/commits?author=Ceilzcx" title="Tests">⚠️</a> <a href="#blog-Ceilzcx" title="Blogposts">📝</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/CharlieXCL"><img src="https://avatars.githubusercontent.com/u/91540487?v=4?s=100" width="100px;" alt="CharlieXCL"/><br /><sub><b>CharlieXCL</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=CharlieXCL" title="Documentation">📖</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/Privauto"><img src="https://avatars.githubusercontent.com/u/36581456?v=4?s=100" width="100px;" alt="Privauto"/><br /><sub><b>Privauto</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=Privauto" title="Code">💻</a> <a href="https://github.com/apache/hertzbeat/commits?author=Privauto" title="Documentation">📖</a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/emrys-he"><img src="https://avatars.githubusercontent.com/u/5848915?v=4?s=100" width="100px;" alt="emrys"/><br /><sub><b>emrys</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=emrys-he" title="Documentation">📖</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/SxLiuYu"><img src="https://avatars.githubusercontent.com/u/95198625?v=4?s=100" width="100px;" alt="SxLiuYu"/><br /><sub><b>SxLiuYu</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/issues?q=author%3ASxLiuYu" title="Bug reports">🐛</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://allcontributors.org"><img src="https://avatars.githubusercontent.com/u/46410174?v=4?s=100" width="100px;" alt="All Contributors"/><br /><sub><b>All Contributors</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=all-contributors" title="Documentation">📖</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/gxc-myh"><img src="https://avatars.githubusercontent.com/u/85919258?v=4?s=100" width="100px;" alt="铁甲小宝"/><br /><sub><b>铁甲小宝</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=gxc-myh" title="Code">💻</a> <a href="https://github.com/apache/hertzbeat/commits?author=gxc-myh" title="Documentation">📖</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/click33"><img src="https://avatars.githubusercontent.com/u/36243476?v=4?s=100" width="100px;" alt="click33"/><br /><sub><b>click33</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=click33" title="Documentation">📖</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://jpom.io/"><img src="https://avatars.githubusercontent.com/u/16408873?v=4?s=100" width="100px;" alt="蒋小小"/><br /><sub><b>蒋小小</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=bwcx-jzy" title="Documentation">📖</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://www.zhihu.com/people/kevinbauer"><img src="https://avatars.githubusercontent.com/u/28581579?v=4?s=100" width="100px;" alt="Kevin Huang"/><br /><sub><b>Kevin Huang</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=kevinhuangwl" title="Documentation">📖</a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/TJxiaobao"><img src="https://avatars.githubusercontent.com/u/85919258?v=4?s=100" width="100px;" alt="铁甲小宝"/><br /><sub><b>铁甲小宝</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/issues?q=author%3ATJxiaobao" title="Bug reports">🐛</a> <a href="https://github.com/apache/hertzbeat/commits?author=TJxiaobao" title="Code">💻</a> <a href="https://github.com/apache/hertzbeat/commits?author=TJxiaobao" title="Documentation">📖</a> <a href="https://github.com/apache/hertzbeat/commits?author=TJxiaobao" title="Tests">⚠️</a> <a href="#design-TJxiaobao" title="Design">🎨</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/Jack-123-power"><img src="https://avatars.githubusercontent.com/u/84333501?v=4?s=100" width="100px;" alt="Captain Jack"/><br /><sub><b>Captain Jack</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=Jack-123-power" title="Documentation">📖</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/haibo-duan"><img src="https://avatars.githubusercontent.com/u/7974845?v=4?s=100" width="100px;" alt="haibo.duan"/><br /><sub><b>haibo.duan</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=haibo-duan" title="Tests">⚠️</a> <a href="https://github.com/apache/hertzbeat/commits?author=haibo-duan" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/assassinfym"><img src="https://avatars.githubusercontent.com/u/15188754?v=4?s=100" width="100px;" alt="assassin"/><br /><sub><b>assassin</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/issues?q=author%3Aassassinfym" title="Bug reports">🐛</a> <a href="https://github.com/apache/hertzbeat/commits?author=assassinfym" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/csyshu"><img src="https://avatars.githubusercontent.com/u/46591658?v=4?s=100" width="100px;" alt="Reverse wind"/><br /><sub><b>Reverse wind</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=csyshu" title="Tests">⚠️</a> <a href="https://github.com/apache/hertzbeat/commits?author=csyshu" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/luxx-lq"><img src="https://avatars.githubusercontent.com/u/58515565?v=4?s=100" width="100px;" alt="luxx"/><br /><sub><b>luxx</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=luxx-lq" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://bandism.net/"><img src="https://avatars.githubusercontent.com/u/22633385?v=4?s=100" width="100px;" alt="Ikko Ashimine"/><br /><sub><b>Ikko Ashimine</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=eltociear" title="Documentation">📖</a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/zenan08"><img src="https://avatars.githubusercontent.com/u/80514991?v=4?s=100" width="100px;" alt="leizenan"/><br /><sub><b>leizenan</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=zenan08" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/BKing2020"><img src="https://avatars.githubusercontent.com/u/28869121?v=4?s=100" width="100px;" alt="BKing"/><br /><sub><b>BKing</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=BKing2020" title="Documentation">📖</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/xingshuaiLi"><img src="https://avatars.githubusercontent.com/u/119487588?v=4?s=100" width="100px;" alt="xingshuaiLi"/><br /><sub><b>xingshuaiLi</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=xingshuaiLi" title="Documentation">📖</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/wangke6666"><img src="https://avatars.githubusercontent.com/u/113656595?v=4?s=100" width="100px;" alt="wangke6666"/><br /><sub><b>wangke6666</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=wangke6666" title="Documentation">📖</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/LWBobo"><img src="https://avatars.githubusercontent.com/u/50368698?v=4?s=100" width="100px;" alt="刺猬"/><br /><sub><b>刺猬</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/issues?q=author%3ALWBobo" title="Bug reports">🐛</a> <a href="https://github.com/apache/hertzbeat/commits?author=LWBobo" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="http://www.zanglikun.com"><img src="https://avatars.githubusercontent.com/u/61591648?v=4?s=100" width="100px;" alt="Haste"/><br /><sub><b>Haste</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=zanglikun" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/SuitSmile"><img src="https://avatars.githubusercontent.com/u/38679717?v=4?s=100" width="100px;" alt="zhongshi.yi"/><br /><sub><b>zhongshi.yi</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=SuitSmile" title="Documentation">📖</a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://www.smallq.cn"><img src="https://avatars.githubusercontent.com/u/39754275?v=4?s=100" width="100px;" alt="Qi Zhang"/><br /><sub><b>Qi Zhang</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=zzzhangqi" title="Documentation">📖</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/MrAndyMing"><img src="https://avatars.githubusercontent.com/u/49541483?v=4?s=100" width="100px;" alt="MrAndyMing"/><br /><sub><b>MrAndyMing</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=MrAndyMing" title="Documentation">📖</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://idongliming.github.io/"><img src="https://avatars.githubusercontent.com/u/31564353?v=4?s=100" width="100px;" alt="idongliming"/><br /><sub><b>idongliming</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=idongliming" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://earthjasonlin.github.io"><img src="https://avatars.githubusercontent.com/u/83632110?v=4?s=100" width="100px;" alt="Zichao Lin"/><br /><sub><b>Zichao Lin</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=earthjasonlin" title="Code">💻</a> <a href="https://github.com/apache/hertzbeat/commits?author=earthjasonlin" title="Documentation">📖</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="http://blog.liudonghua.com"><img src="https://avatars.githubusercontent.com/u/2276718?v=4?s=100" width="100px;" alt="liudonghua"/><br /><sub><b>liudonghua</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=liudonghua123" title="Code">💻</a> <a href="#ideas-liudonghua123" title="Ideas, Planning, & Feedback">🤔</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/orangeyts"><img src="https://avatars.githubusercontent.com/u/4250869?v=4?s=100" width="100px;" alt="Jerry"/><br /><sub><b>Jerry</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=orangeyts" title="Code">💻</a> <a href="https://github.com/apache/hertzbeat/commits?author=orangeyts" title="Tests">⚠️</a> <a href="#ideas-orangeyts" title="Ideas, Planning, & Feedback">🤔</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://dynamictp.cn"><img src="https://avatars.githubusercontent.com/u/13051908?v=4?s=100" width="100px;" alt="yanhom"/><br /><sub><b>yanhom</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=yanhom1314" title="Documentation">📖</a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://www.jianshu.com/u/a8f822c04f67"><img src="https://avatars.githubusercontent.com/u/18587688?v=4?s=100" width="100px;" alt="fsl"/><br /><sub><b>fsl</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=fengshunli" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/xttttv"><img src="https://avatars.githubusercontent.com/u/116323904?v=4?s=100" width="100px;" alt="xttttv"/><br /><sub><b>xttttv</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=xttttv" title="Documentation">📖</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/NavinKumarBarnwal"><img src="https://avatars.githubusercontent.com/u/44504274?v=4?s=100" width="100px;" alt="NavinKumarBarnwal"/><br /><sub><b>NavinKumarBarnwal</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=NavinKumarBarnwal" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/z641205699"><img src="https://avatars.githubusercontent.com/u/45276423?v=4?s=100" width="100px;" alt="Zakkary"/><br /><sub><b>Zakkary</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=z641205699" title="Documentation">📖</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/898349230"><img src="https://avatars.githubusercontent.com/u/21972532?v=4?s=100" width="100px;" alt="sunxinbo"/><br /><sub><b>sunxinbo</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=898349230" title="Code">💻</a> <a href="https://github.com/apache/hertzbeat/commits?author=898349230" title="Tests">⚠️</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/ldzbook"><img src="https://avatars.githubusercontent.com/u/13903790?v=4?s=100" width="100px;" alt="ldzbook"/><br /><sub><b>ldzbook</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=ldzbook" title="Documentation">📖</a> <a href="https://github.com/apache/hertzbeat/issues?q=author%3Aldzbook" title="Bug reports">🐛</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/SurryChen"><img src="https://avatars.githubusercontent.com/u/91116490?v=4?s=100" width="100px;" alt="余与雨"/><br /><sub><b>余与雨</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=SurryChen" title="Code">💻</a> <a href="https://github.com/apache/hertzbeat/commits?author=SurryChen" title="Tests">⚠️</a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/MysticalDream"><img src="https://avatars.githubusercontent.com/u/78899028?v=4?s=100" width="100px;" alt="MysticalDream"/><br /><sub><b>MysticalDream</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=MysticalDream" title="Code">💻</a> <a href="https://github.com/apache/hertzbeat/commits?author=MysticalDream" title="Tests">⚠️</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/zhouyoulin12"><img src="https://avatars.githubusercontent.com/u/17086633?v=4?s=100" width="100px;" alt="zhouyoulin12"/><br /><sub><b>zhouyoulin12</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=zhouyoulin12" title="Code">💻</a> <a href="https://github.com/apache/hertzbeat/commits?author=zhouyoulin12" title="Tests">⚠️</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/jerjjj"><img src="https://avatars.githubusercontent.com/u/93431283?v=4?s=100" width="100px;" alt="jerjjj"/><br /><sub><b>jerjjj</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=jerjjj" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://wjl110.xyz/"><img src="https://avatars.githubusercontent.com/u/53851034?v=4?s=100" width="100px;" alt="wjl110"/><br /><sub><b>wjl110</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=wjl110" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/ngyhd"><img src="https://avatars.githubusercontent.com/u/29095207?v=4?s=100" width="100px;" alt="Sean"/><br /><sub><b>Sean</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=ngyhd" title="Documentation">📖</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/Daydreamer-ia"><img src="https://avatars.githubusercontent.com/u/83362909?v=4?s=100" width="100px;" alt="chenyiqin"/><br /><sub><b>chenyiqin</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=Daydreamer-ia" title="Code">💻</a> <a href="https://github.com/apache/hertzbeat/commits?author=Daydreamer-ia" title="Tests">⚠️</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/hudongdong129"><img src="https://avatars.githubusercontent.com/u/34374227?v=4?s=100" width="100px;" alt="hudongdong129"/><br /><sub><b>hudongdong129</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=hudongdong129" title="Code">💻</a> <a href="https://github.com/apache/hertzbeat/commits?author=hudongdong129" title="Tests">⚠️</a> <a href="https://github.com/apache/hertzbeat/commits?author=hudongdong129" title="Documentation">📖</a> <a href="#design-hudongdong129" title="Design">🎨</a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/TherChenYang"><img src="https://avatars.githubusercontent.com/u/124348939?v=4?s=100" width="100px;" alt="TherChenYang"/><br /><sub><b>TherChenYang</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=TherChenYang" title="Code">💻</a> <a href="https://github.com/apache/hertzbeat/commits?author=TherChenYang" title="Tests">⚠️</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/HattoriHenzo"><img src="https://avatars.githubusercontent.com/u/5141285?v=4?s=100" width="100px;" alt="HattoriHenzo"/><br /><sub><b>HattoriHenzo</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=HattoriHenzo" title="Code">💻</a> <a href="https://github.com/apache/hertzbeat/commits?author=HattoriHenzo" title="Tests">⚠️</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/ycilry"><img src="https://avatars.githubusercontent.com/u/63967101?v=4?s=100" width="100px;" alt="ycilry"/><br /><sub><b>ycilry</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=ycilry" title="Documentation">📖</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/aoshiguchen"><img src="https://avatars.githubusercontent.com/u/10580997?v=4?s=100" width="100px;" alt="aoshiguchen"/><br /><sub><b>aoshiguchen</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=aoshiguchen" title="Documentation">📖</a> <a href="https://github.com/apache/hertzbeat/commits?author=aoshiguchen" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/caibenxiang"><img src="https://avatars.githubusercontent.com/u/4568241?v=4?s=100" width="100px;" alt="蔡本祥"/><br /><sub><b>蔡本祥</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=caibenxiang" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="http://www.fckeverything.cn:4000/"><img src="https://avatars.githubusercontent.com/u/13827124?v=4?s=100" width="100px;" alt="浮游"/><br /><sub><b>浮游</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=lifefloating" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/Grass-Life"><img src="https://avatars.githubusercontent.com/u/114381513?v=4?s=100" width="100px;" alt="Grass-Life"/><br /><sub><b>Grass-Life</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=Grass-Life" title="Code">💻</a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/xiaohe428"><img src="https://avatars.githubusercontent.com/u/99130317?v=4?s=100" width="100px;" alt="xiaohe428"/><br /><sub><b>xiaohe428</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=xiaohe428" title="Code">💻</a> <a href="https://github.com/apache/hertzbeat/commits?author=xiaohe428" title="Documentation">📖</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/baiban114"><img src="https://avatars.githubusercontent.com/u/59152619?v=4?s=100" width="100px;" alt="TableRow"/><br /><sub><b>TableRow</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=baiban114" title="Documentation">📖</a> <a href="https://github.com/apache/hertzbeat/commits?author=baiban114" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/ByteIDance"><img src="https://avatars.githubusercontent.com/u/100207562?v=4?s=100" width="100px;" alt="ByteIDance"/><br /><sub><b>ByteIDance</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=ByteIDance" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/mangel2002"><img src="https://avatars.githubusercontent.com/u/9348020?v=4?s=100" width="100px;" alt="Jangfe"/><br /><sub><b>Jangfe</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=mangel2002" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/zqr10159"><img src="https://avatars.githubusercontent.com/u/30048352?v=4?s=100" width="100px;" alt="zqr10159"/><br /><sub><b>zqr10159</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=zqr10159" title="Documentation">📖</a> <a href="https://github.com/apache/hertzbeat/commits?author=zqr10159" title="Code">💻</a> <a href="#blog-zqr10159" title="Blogposts">📝</a> <a href="https://github.com/apache/hertzbeat/issues?q=author%3Azqr10159" title="Bug reports">🐛</a> <a href="https://github.com/apache/hertzbeat/commits?author=zqr10159" title="Tests">⚠️</a> <a href="#design-zqr10159" title="Design">🎨</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/vinci-897"><img src="https://avatars.githubusercontent.com/u/55838224?v=4?s=100" width="100px;" alt="vinci"/><br /><sub><b>vinci</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=vinci-897" title="Code">💻</a> <a href="https://github.com/apache/hertzbeat/commits?author=vinci-897" title="Documentation">📖</a> <a href="#design-vinci-897" title="Design">🎨</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/js110"><img src="https://avatars.githubusercontent.com/u/51191863?v=4?s=100" width="100px;" alt="js110"/><br /><sub><b>js110</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=js110" title="Code">💻</a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/JavaLionLi"><img src="https://avatars.githubusercontent.com/u/31852897?v=4?s=100" width="100px;" alt="CrazyLionLi"/><br /><sub><b>CrazyLionLi</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=JavaLionLi" title="Documentation">📖</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="http://www.banmajio.com"><img src="https://avatars.githubusercontent.com/u/53471385?v=4?s=100" width="100px;" alt="banmajio"/><br /><sub><b>banmajio</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=banmajio" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://suder.fun"><img src="https://avatars.githubusercontent.com/u/69955165?v=4?s=100" width="100px;" alt="topsuder"/><br /><sub><b>topsuder</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=topsuder" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/richar2022"><img src="https://avatars.githubusercontent.com/u/129016397?v=4?s=100" width="100px;" alt="richar2022"/><br /><sub><b>richar2022</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=richar2022" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/fcb-xiaobo"><img src="https://avatars.githubusercontent.com/u/60566194?v=4?s=100" width="100px;" alt="fcb-xiaobo"/><br /><sub><b>fcb-xiaobo</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=fcb-xiaobo" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/wenkyzhang"><img src="https://avatars.githubusercontent.com/u/13983669?v=4?s=100" width="100px;" alt="wenkyzhang"/><br /><sub><b>wenkyzhang</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=wenkyzhang" title="Documentation">📖</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/ZangJuxy"><img src="https://avatars.githubusercontent.com/u/71380295?v=4?s=100" width="100px;" alt="ZangJuxy"/><br /><sub><b>ZangJuxy</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=ZangJuxy" title="Documentation">📖</a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/l646505418"><img src="https://avatars.githubusercontent.com/u/50475131?v=4?s=100" width="100px;" alt="l646505418"/><br /><sub><b>l646505418</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=l646505418" title="Code">💻</a> <a href="https://github.com/apache/hertzbeat/issues?q=author%3Al646505418" title="Bug reports">🐛</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="http://www.carpewang.com"><img src="https://avatars.githubusercontent.com/u/78642589?v=4?s=100" width="100px;" alt="Carpe-Wang"/><br /><sub><b>Carpe-Wang</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=Carpe-Wang" title="Code">💻</a> <a href="https://github.com/apache/hertzbeat/issues?q=author%3ACarpe-Wang" title="Bug reports">🐛</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/moshu023"><img src="https://avatars.githubusercontent.com/u/48593205?v=4?s=100" width="100px;" alt="莫枢"/><br /><sub><b>莫枢</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=moshu023" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/huangcanda"><img src="https://avatars.githubusercontent.com/u/4470566?v=4?s=100" width="100px;" alt="huangcanda"/><br /><sub><b>huangcanda</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=huangcanda" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://www.zrkizzy.com"><img src="https://avatars.githubusercontent.com/u/85340613?v=4?s=100" width="100px;" alt="世纪末的架构师"/><br /><sub><b>世纪末的架构师</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=Architect-Java" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/ShuningWan"><img src="https://avatars.githubusercontent.com/u/31086770?v=4?s=100" width="100px;" alt="ShuningWan"/><br /><sub><b>ShuningWan</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=ShuningWan" title="Documentation">📖</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/MrYZhou"><img src="https://avatars.githubusercontent.com/u/44339602?v=4?s=100" width="100px;" alt="MrYZhou"/><br /><sub><b>MrYZhou</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=MrYZhou" title="Documentation">📖</a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/suncqujsj"><img src="https://avatars.githubusercontent.com/u/8012932?v=4?s=100" width="100px;" alt="suncqujsj"/><br /><sub><b>suncqujsj</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=suncqujsj" title="Documentation">📖</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/sunqinbo"><img src="https://avatars.githubusercontent.com/u/1428540?v=4?s=100" width="100px;" alt="sunqinbo"/><br /><sub><b>sunqinbo</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=sunqinbo" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/haoww"><img src="https://avatars.githubusercontent.com/u/32739294?v=4?s=100" width="100px;" alt="haoww"/><br /><sub><b>haoww</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=haoww" title="Documentation">📖</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/i-mayuan"><img src="https://avatars.githubusercontent.com/u/101498477?v=4?s=100" width="100px;" alt="i-mayuan"/><br /><sub><b>i-mayuan</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=i-mayuan" title="Documentation">📖</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/fengruge"><img src="https://avatars.githubusercontent.com/u/85803831?v=4?s=100" width="100px;" alt="fengruge"/><br /><sub><b>fengruge</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=fengruge" title="Documentation">📖</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/aystzh"><img src="https://avatars.githubusercontent.com/u/38125392?v=4?s=100" width="100px;" alt="zhanghuan"/><br /><sub><b>zhanghuan</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=aystzh" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/shenyumin"><img src="https://avatars.githubusercontent.com/u/8438506?v=4?s=100" width="100px;" alt="shenymin"/><br /><sub><b>shenymin</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=shenyumin" title="Code">💻</a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/dhruva1995"><img src="https://avatars.githubusercontent.com/u/12976351?v=4?s=100" width="100px;" alt="Dhruva Chandra"/><br /><sub><b>Dhruva Chandra</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=dhruva1995" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/weiwang988"><img src="https://avatars.githubusercontent.com/u/58241726?v=4?s=100" width="100px;" alt="miss_z"/><br /><sub><b>miss_z</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=weiwang988" title="Documentation">📖</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/wyt990"><img src="https://avatars.githubusercontent.com/u/86013697?v=4?s=100" width="100px;" alt="wyt990"/><br /><sub><b>wyt990</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=wyt990" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/licocon"><img src="https://avatars.githubusercontent.com/u/36863277?v=4?s=100" width="100px;" alt="licocon"/><br /><sub><b>licocon</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=licocon" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/2406450951"><img src="https://avatars.githubusercontent.com/u/48074721?v=4?s=100" width="100px;" alt="Mi Na"/><br /><sub><b>Mi Na</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=2406450951" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/Kylin-Guo"><img src="https://avatars.githubusercontent.com/u/131239856?v=4?s=100" width="100px;" alt="Kylin-Guo"/><br /><sub><b>Kylin-Guo</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=Kylin-Guo" title="Documentation">📖</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/1797899698"><img src="https://avatars.githubusercontent.com/u/40411650?v=4?s=100" width="100px;" alt="Mr灬Dong先生"/><br /><sub><b>Mr灬Dong先生</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=1797899698" title="Code">💻</a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="center" valign="top" width="14.28%"><a href="http://neilblaze.live"><img src="https://avatars.githubusercontent.com/u/48355572?v=4?s=100" width="100px;" alt="Pratyay Banerjee"/><br /><sub><b>Pratyay Banerjee</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=Neilblaze" title="Documentation">📖</a> <a href="https://github.com/apache/hertzbeat/commits?author=Neilblaze" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/yujianzhong520"><img src="https://avatars.githubusercontent.com/u/63705063?v=4?s=100" width="100px;" alt="yujianzhong520"/><br /><sub><b>yujianzhong520</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=yujianzhong520" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://sppan24.github.io/"><img src="https://avatars.githubusercontent.com/u/15795173?v=4?s=100" width="100px;" alt="SPPan"/><br /><sub><b>SPPan</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=sppan24" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/1130600015"><img src="https://avatars.githubusercontent.com/u/67859663?v=4?s=100" width="100px;" alt="ZhangJiashu"/><br /><sub><b>ZhangJiashu</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=1130600015" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/QZmp236478"><img src="https://avatars.githubusercontent.com/u/56623162?v=4?s=100" width="100px;" alt="impress"/><br /><sub><b>impress</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=QZmp236478" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/jx3775250"><img src="https://avatars.githubusercontent.com/u/40455946?v=4?s=100" width="100px;" alt="凌晨一点半"/><br /><sub><b>凌晨一点半</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=jx3775250" title="Documentation">📖</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/eeshaanSA"><img src="https://avatars.githubusercontent.com/u/100678386?v=4?s=100" width="100px;" alt="Eeshaan Sawant"/><br /><sub><b>Eeshaan Sawant</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=eeshaanSA" title="Code">💻</a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/nandofromthebando"><img src="https://avatars.githubusercontent.com/u/87321214?v=4?s=100" width="100px;" alt="nandofromthebando"/><br /><sub><b>nandofromthebando</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=nandofromthebando" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/caiboking"><img src="https://avatars.githubusercontent.com/u/6509883?v=4?s=100" width="100px;" alt="caiboking"/><br /><sub><b>caiboking</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=caiboking" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/baixing99"><img src="https://avatars.githubusercontent.com/u/73473087?v=4?s=100" width="100px;" alt="baixing99"/><br /><sub><b>baixing99</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=baixing99" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/ifrenzyc"><img src="https://avatars.githubusercontent.com/u/543927?v=4?s=100" width="100px;" alt="Yang Chuang"/><br /><sub><b>Yang Chuang</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=ifrenzyc" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/wlin20"><img src="https://avatars.githubusercontent.com/u/20657577?v=4?s=100" width="100px;" alt="wlin20"/><br /><sub><b>wlin20</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=wlin20" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/guojing1983"><img src="https://avatars.githubusercontent.com/u/60596094?v=4?s=100" width="100px;" alt="guojing1983"/><br /><sub><b>guojing1983</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=guojing1983" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/itxxq"><img src="https://avatars.githubusercontent.com/u/46962357?v=4?s=100" width="100px;" alt="moxi"/><br /><sub><b>moxi</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=itxxq" title="Documentation">📖</a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/qq471754603"><img src="https://avatars.githubusercontent.com/u/23146592?v=4?s=100" width="100px;" alt="qq471754603"/><br /><sub><b>qq471754603</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=qq471754603" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/san346596324"><img src="https://avatars.githubusercontent.com/u/30828520?v=4?s=100" width="100px;" alt="渭雨"/><br /><sub><b>渭雨</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=san346596324" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/luoxuanzao"><img src="https://avatars.githubusercontent.com/u/44692579?v=4?s=100" width="100px;" alt="liuxuezhuo"/><br /><sub><b>liuxuezhuo</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=luoxuanzao" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/lisongning"><img src="https://avatars.githubusercontent.com/u/93140178?v=4?s=100" width="100px;" alt="lisongning"/><br /><sub><b>lisongning</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=lisongning" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/YutingNie"><img src="https://avatars.githubusercontent.com/u/104416402?v=4?s=100" width="100px;" alt="YutingNie"/><br /><sub><b>YutingNie</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=YutingNie" title="Code">💻</a> <a href="https://github.com/apache/hertzbeat/commits?author=YutingNie" title="Documentation">📖</a> <a href="#design-YutingNie" title="Design">🎨</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/mikezzb"><img src="https://avatars.githubusercontent.com/u/23418428?v=4?s=100" width="100px;" alt="Mike Zhou"/><br /><sub><b>Mike Zhou</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=mikezzb" title="Code">💻</a> <a href="https://github.com/apache/hertzbeat/commits?author=mikezzb" title="Documentation">📖</a> <a href="#design-mikezzb" title="Design">🎨</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/a-little-fool"><img src="https://avatars.githubusercontent.com/u/105542329?v=4?s=100" width="100px;" alt="小笨蛋"/><br /><sub><b>小笨蛋</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=a-little-fool" title="Code">💻</a> <a href="https://github.com/apache/hertzbeat/commits?author=a-little-fool" title="Documentation">📖</a> <a href="#blog-a-little-fool" title="Blogposts">📝</a> <a href="https://github.com/apache/hertzbeat/issues?q=author%3Aa-little-fool" title="Bug reports">🐛</a> <a href="#design-a-little-fool" title="Design">🎨</a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/littlezhongzer"><img src="https://avatars.githubusercontent.com/u/33685289?v=4?s=100" width="100px;" alt="littlezhongzer"/><br /><sub><b>littlezhongzer</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=littlezhongzer" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/ChenXiangxxxxx"><img src="https://avatars.githubusercontent.com/u/90089594?v=4?s=100" width="100px;" alt="ChenXiangxxxxx"/><br /><sub><b>ChenXiangxxxxx</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=ChenXiangxxxxx" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/Mr-zhou315"><img src="https://avatars.githubusercontent.com/u/10276100?v=4?s=100" width="100px;" alt="Mr.zhou"/><br /><sub><b>Mr.zhou</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=Mr-zhou315" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/XimfengYao"><img src="https://avatars.githubusercontent.com/u/17541537?v=4?s=100" width="100px;" alt="姚贤丰"/><br /><sub><b>姚贤丰</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=XimfengYao" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/LINGLUOJUN"><img src="https://avatars.githubusercontent.com/u/16778977?v=4?s=100" width="100px;" alt="lingluojun"/><br /><sub><b>lingluojun</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=LINGLUOJUN" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="http://www.luelueking.com"><img src="https://avatars.githubusercontent.com/u/93204032?v=4?s=100" width="100px;" alt="1ue"/><br /><sub><b>1ue</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=luelueking" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="http://www.jimmyqiao.top"><img src="https://avatars.githubusercontent.com/u/67301054?v=4?s=100" width="100px;" alt="qyaaaa"/><br /><sub><b>qyaaaa</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=qyaaaa" title="Code">💻</a> <a href="https://github.com/apache/hertzbeat/issues?q=author%3Aqyaaaa" title="Bug reports">🐛</a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://novohit.top"><img src="https://avatars.githubusercontent.com/u/101090395?v=4?s=100" width="100px;" alt="novohit"/><br /><sub><b>novohit</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=novohit" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/rbsrcy"><img src="https://avatars.githubusercontent.com/u/4798540?v=4?s=100" width="100px;" alt="zhuoshangyi"/><br /><sub><b>zhuoshangyi</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=rbsrcy" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/ruanliang-hualun"><img src="https://avatars.githubusercontent.com/u/65543716?v=4?s=100" width="100px;" alt="ruanliang"/><br /><sub><b>ruanliang</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=ruanliang-hualun" title="Documentation">📖</a> <a href="https://github.com/apache/hertzbeat/commits?author=ruanliang-hualun" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/Eden4701"><img src="https://avatars.githubusercontent.com/u/68422437?v=4?s=100" width="100px;" alt="Eden4701"/><br /><sub><b>Eden4701</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=Eden4701" title="Code">💻</a> <a href="https://github.com/apache/hertzbeat/commits?author=Eden4701" title="Documentation">📖</a> <a href="#design-Eden4701" title="Design">🎨</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/XiaTian688"><img src="https://avatars.githubusercontent.com/u/111830921?v=4?s=100" width="100px;" alt="XiaTian688"/><br /><sub><b>XiaTian688</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=XiaTian688" title="Documentation">📖</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/liyin"><img src="https://avatars.githubusercontent.com/u/863169?v=4?s=100" width="100px;" alt="liyinjiang"/><br /><sub><b>liyinjiang</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=liyin" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/jiashu1024"><img src="https://avatars.githubusercontent.com/u/67859663?v=4?s=100" width="100px;" alt="ZhangJiashu"/><br /><sub><b>ZhangJiashu</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=jiashu1024" title="Documentation">📖</a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/1036664317"><img src="https://avatars.githubusercontent.com/u/7696697?v=4?s=100" width="100px;" alt="moghn"/><br /><sub><b>moghn</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=1036664317" title="Documentation">📖</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/xiaoguolong"><img src="https://avatars.githubusercontent.com/u/33684988?v=4?s=100" width="100px;" alt="xiaoguolong"/><br /><sub><b>xiaoguolong</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=xiaoguolong" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/Clownsw"><img src="https://avatars.githubusercontent.com/u/28394742?v=4?s=100" width="100px;" alt="Smliexx"/><br /><sub><b>Smliexx</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=Clownsw" title="Code">💻</a> <a href="https://github.com/apache/hertzbeat/issues?q=author%3AClownsw" title="Bug reports">🐛</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/Calvin979"><img src="https://avatars.githubusercontent.com/u/131688897?v=4?s=100" width="100px;" alt="Naruse"/><br /><sub><b>Naruse</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=Calvin979" title="Documentation">📖</a> <a href="https://github.com/apache/hertzbeat/commits?author=Calvin979" title="Code">💻</a> <a href="#design-Calvin979" title="Design">🎨</a> <a href="https://github.com/apache/hertzbeat/issues?q=author%3ACalvin979" title="Bug reports">🐛</a> <a href="https://github.com/apache/hertzbeat/commits?author=Calvin979" title="Tests">⚠️</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/bbelide2"><img src="https://avatars.githubusercontent.com/u/26840796?v=4?s=100" width="100px;" alt="Bala Sukesh"/><br /><sub><b>Bala Sukesh</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=bbelide2" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/jinyaoMa"><img src="https://avatars.githubusercontent.com/u/25066570?v=4?s=100" width="100px;" alt="Jinyao Ma"/><br /><sub><b>Jinyao Ma</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=jinyaoMa" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://linuxsuren.github.io/open-source-best-practice/"><img src="https://avatars.githubusercontent.com/u/1450685?v=4?s=100" width="100px;" alt="Rick"/><br /><sub><b>Rick</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=LinuxSuRen" title="Code">💻</a> <a href="https://github.com/apache/hertzbeat/commits?author=LinuxSuRen" title="Tests">⚠️</a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/ZY945"><img src="https://avatars.githubusercontent.com/u/74083801?v=4?s=100" width="100px;" alt="东风"/><br /><sub><b>东风</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=ZY945" title="Code">💻</a> <a href="#design-ZY945" title="Design">🎨</a> <a href="https://github.com/apache/hertzbeat/commits?author=ZY945" title="Documentation">📖</a> <a href="https://github.com/apache/hertzbeat/issues?q=author%3AZY945" title="Bug reports">🐛</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/prolevel1"><img src="https://avatars.githubusercontent.com/u/51995525?v=4?s=100" width="100px;" alt="sonam singh"/><br /><sub><b>sonam singh</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=prolevel1" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/ZhangZixuan1994"><img src="https://avatars.githubusercontent.com/u/20011653?v=4?s=100" width="100px;" alt="ZhangZixuan1994"/><br /><sub><b>ZhangZixuan1994</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=ZhangZixuan1994" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/hurenjie1"><img src="https://avatars.githubusercontent.com/u/40120355?v=4?s=100" width="100px;" alt="SHIG"/><br /><sub><b>SHIG</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=hurenjie1" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://tslj1024.github.io/"><img src="https://avatars.githubusercontent.com/u/155222677?v=4?s=100" width="100px;" alt="泰上老菌"/><br /><sub><b>泰上老菌</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=tslj1024" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/ldysdu"><img src="https://avatars.githubusercontent.com/u/15815338?v=4?s=100" width="100px;" alt="ldysdu"/><br /><sub><b>ldysdu</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=ldysdu" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/GEM0816g"><img src="https://avatars.githubusercontent.com/u/85116017?v=4?s=100" width="100px;" alt="梁同学"/><br /><sub><b>梁同学</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=GEM0816g" title="Code">💻</a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/avvCode"><img src="https://avatars.githubusercontent.com/u/113538532?v=4?s=100" width="100px;" alt="avv"/><br /><sub><b>avv</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=avvCode" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/yqxxgh"><img src="https://avatars.githubusercontent.com/u/42080876?v=4?s=100" width="100px;" alt="yqxxgh"/><br /><sub><b>yqxxgh</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=yqxxgh" title="Documentation">📖</a> <a href="https://github.com/apache/hertzbeat/commits?author=yqxxgh" title="Code">💻</a> <a href="https://github.com/apache/hertzbeat/issues?q=author%3Ayqxxgh" title="Bug reports">🐛</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/CharlieShi46"><img src="https://avatars.githubusercontent.com/u/149798885?v=4?s=100" width="100px;" alt="CharlieShi46"/><br /><sub><b>CharlieShi46</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=CharlieShi46" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/Nctllnty"><img src="https://avatars.githubusercontent.com/u/33241818?v=4?s=100" width="100px;" alt="Nctllnty"/><br /><sub><b>Nctllnty</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=Nctllnty" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/Wang-Yonghao"><img src="https://avatars.githubusercontent.com/u/48146606?v=4?s=100" width="100px;" alt="Wang-Yonghao"/><br /><sub><b>Wang-Yonghao</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=Wang-Yonghao" title="Documentation">📖</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://www.yuque.com/dudiao/yy"><img src="https://avatars.githubusercontent.com/u/38355949?v=4?s=100" width="100px;" alt="读钓"/><br /><sub><b>读钓</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=dudiao" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/starmilkxin"><img src="https://avatars.githubusercontent.com/u/55646681?v=4?s=100" width="100px;" alt="Xin"/><br /><sub><b>Xin</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=starmilkxin" title="Code">💻</a> <a href="https://github.com/apache/hertzbeat/issues?q=author%3Astarmilkxin" title="Bug reports">🐛</a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/handy-git"><img src="https://avatars.githubusercontent.com/u/32837980?v=4?s=100" width="100px;" alt="handy"/><br /><sub><b>handy</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=handy-git" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/LiuTianyou"><img src="https://avatars.githubusercontent.com/u/30208283?v=4?s=100" width="100px;" alt="LiuTianyou"/><br /><sub><b>LiuTianyou</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=LiuTianyou" title="Code">💻</a> <a href="https://github.com/apache/hertzbeat/commits?author=LiuTianyou" title="Documentation">📖</a> <a href="https://github.com/apache/hertzbeat/issues?q=author%3ALiuTianyou" title="Bug reports">🐛</a> <a href="https://github.com/apache/hertzbeat/commits?author=LiuTianyou" title="Tests">⚠️</a> <a href="#blog-LiuTianyou" title="Blogposts">📝</a> <a href="#design-LiuTianyou" title="Design">🎨</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/WinterKi1ler"><img src="https://avatars.githubusercontent.com/u/160592092?v=4?s=100" width="100px;" alt="WinterKi1ler"/><br /><sub><b>WinterKi1ler</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=WinterKi1ler" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="http://sharehoo.cn/"><img src="https://avatars.githubusercontent.com/u/45377370?v=4?s=100" width="100px;" alt="miki"/><br /><sub><b>miki</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=miki-hmt" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://codeflex.substack.com/"><img src="https://avatars.githubusercontent.com/u/85513042?v=4?s=100" width="100px;" alt="Keshav Carpenter"/><br /><sub><b>Keshav Carpenter</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=alpha951" title="Code">💻</a> <a href="https://github.com/apache/hertzbeat/commits?author=alpha951" title="Documentation">📖</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/makechoicenow"><img src="https://avatars.githubusercontent.com/u/9911918?v=4?s=100" width="100px;" alt="makechoicenow"/><br /><sub><b>makechoicenow</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=makechoicenow" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/gjjjj0101"><img src="https://avatars.githubusercontent.com/u/71874373?v=4?s=100" width="100px;" alt="Gao Jian"/><br /><sub><b>Gao Jian</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=gjjjj0101" title="Tests">⚠️</a> <a href="https://github.com/apache/hertzbeat/commits?author=gjjjj0101" title="Code">💻</a> <a href="https://github.com/apache/hertzbeat/commits?author=gjjjj0101" title="Documentation">📖</a> <a href="#design-gjjjj0101" title="Design">🎨</a> <a href="https://github.com/apache/hertzbeat/issues?q=author%3Agjjjj0101" title="Bug reports">🐛</a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://jangto.tistory.com/"><img src="https://avatars.githubusercontent.com/u/37864182?v=4?s=100" width="100px;" alt="Hyeon Sung"/><br /><sub><b>Hyeon Sung</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=dukbong" title="Code">💻</a> <a href="https://github.com/apache/hertzbeat/commits?author=dukbong" title="Documentation">📖</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://crossoverjie.top/"><img src="https://avatars.githubusercontent.com/u/15684156?v=4?s=100" width="100px;" alt="crossoverJie"/><br /><sub><b>crossoverJie</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=crossoverJie" title="Code">💻</a> <a href="https://github.com/apache/hertzbeat/commits?author=crossoverJie" title="Documentation">📖</a> <a href="#blog-crossoverJie" title="Blogposts">📝</a> <a href="https://github.com/apache/hertzbeat/commits?author=crossoverJie" title="Tests">⚠️</a> <a href="#design-crossoverJie" title="Design">🎨</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/PeixyJ"><img src="https://avatars.githubusercontent.com/u/45998593?v=4?s=100" width="100px;" alt="PeixyJ"/><br /><sub><b>PeixyJ</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=PeixyJ" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/Hi-Mr-Wind"><img src="https://avatars.githubusercontent.com/u/85803831?v=4?s=100" width="100px;" alt="风如歌"/><br /><sub><b>风如歌</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=Hi-Mr-Wind" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/MananPoojara"><img src="https://avatars.githubusercontent.com/u/104253184?v=4?s=100" width="100px;" alt="Manan Pujara"/><br /><sub><b>Manan Pujara</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=MananPoojara" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/xuziyang"><img src="https://avatars.githubusercontent.com/u/8465969?v=4?s=100" width="100px;" alt="xuziyang"/><br /><sub><b>xuziyang</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=xuziyang" title="Code">💻</a> <a href="https://github.com/apache/hertzbeat/commits?author=xuziyang" title="Documentation">📖</a> <a href="https://github.com/apache/hertzbeat/issues?q=author%3Axuziyang" title="Bug reports">🐛</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/lwqzz"><img src="https://avatars.githubusercontent.com/u/62584513?v=4?s=100" width="100px;" alt="lwqzz"/><br /><sub><b>lwqzz</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=lwqzz" title="Code">💻</a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/YxYL6125"><img src="https://avatars.githubusercontent.com/u/91076160?v=4?s=100" width="100px;" alt="YxYL"/><br /><sub><b>YxYL</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=YxYL6125" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/tomorrowshipyltm"><img src="https://avatars.githubusercontent.com/u/61336903?v=4?s=100" width="100px;" alt="tomorrowshipyltm"/><br /><sub><b>tomorrowshipyltm</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=tomorrowshipyltm" title="Documentation">📖</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/15613060203"><img src="https://avatars.githubusercontent.com/u/41351615?v=4?s=100" width="100px;" alt="栗磊"/><br /><sub><b>栗磊</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=15613060203" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/Alanxtl"><img src="https://avatars.githubusercontent.com/u/25652981?v=4?s=100" width="100px;" alt="Alan"/><br /><sub><b>Alan</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=Alanxtl" title="Documentation">📖</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="http://www.hadoop.wiki/"><img src="https://avatars.githubusercontent.com/u/29418975?v=4?s=100" width="100px;" alt="Jast"/><br /><sub><b>Jast</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=zhangshenghang" title="Code">💻</a> <a href="#ideas-zhangshenghang" title="Ideas, Planning, & Feedback">🤔</a> <a href="https://github.com/apache/hertzbeat/commits?author=zhangshenghang" title="Documentation">📖</a> <a href="#blog-zhangshenghang" title="Blogposts">📝</a> <a href="https://github.com/apache/hertzbeat/issues?q=author%3Azhangshenghang" title="Bug reports">🐛</a> <a href="https://github.com/apache/hertzbeat/commits?author=zhangshenghang" title="Tests">⚠️</a> <a href="#design-zhangshenghang" title="Design">🎨</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/zuobiao-zhou"><img src="https://avatars.githubusercontent.com/u/61108539?v=4?s=100" width="100px;" alt="Zhang Yuxuan"/><br /><sub><b>Zhang Yuxuan</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=zuobiao-zhou" title="Code">💻</a> <a href="https://github.com/apache/hertzbeat/commits?author=zuobiao-zhou" title="Documentation">📖</a> <a href="https://github.com/apache/hertzbeat/issues?q=author%3Azuobiao-zhou" title="Bug reports">🐛</a> <a href="#blog-zuobiao-zhou" title="Blogposts">📝</a> <a href="https://github.com/apache/hertzbeat/commits?author=zuobiao-zhou" title="Tests">⚠️</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/Pzz-2021"><img src="https://avatars.githubusercontent.com/u/118056735?v=4?s=100" width="100px;" alt="P.P."/><br /><sub><b>P.P.</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=Pzz-2021" title="Code">💻</a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/LLP2333"><img src="https://avatars.githubusercontent.com/u/61670545?v=4?s=100" width="100px;" alt="llp2333"/><br /><sub><b>llp2333</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=LLP2333" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/HeartLinked"><img src="https://avatars.githubusercontent.com/u/78212101?v=4?s=100" width="100px;" alt="feiyang li"/><br /><sub><b>feiyang li</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=HeartLinked" title="Documentation">📖</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/Aias00"><img src="https://avatars.githubusercontent.com/u/25810623?v=4?s=100" width="100px;" alt="aias00"/><br /><sub><b>aias00</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=Aias00" title="Code">💻</a> <a href="https://github.com/apache/hertzbeat/commits?author=Aias00" title="Documentation">📖</a> <a href="https://github.com/apache/hertzbeat/issues?q=author%3AAias00" title="Bug reports">🐛</a> <a href="#ideas-Aias00" title="Ideas, Planning, & Feedback">🤔</a> <a href="https://github.com/apache/hertzbeat/commits?author=Aias00" title="Tests">⚠️</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/westboy"><img src="https://avatars.githubusercontent.com/u/6385565?v=4?s=100" width="100px;" alt="Jin"/><br /><sub><b>Jin</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=westboy" title="Documentation">📖</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://blog.csdn.net/qq_52397471"><img src="https://avatars.githubusercontent.com/u/77964041?v=4?s=100" width="100px;" alt="YuLuo"/><br /><sub><b>YuLuo</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=yuluo-yx" title="Code">💻</a> <a href="https://github.com/apache/hertzbeat/issues?q=author%3Ayuluo-yx" title="Bug reports">🐛</a> <a href="https://github.com/apache/hertzbeat/commits?author=yuluo-yx" title="Tests">⚠️</a> <a href="#blog-yuluo-yx" title="Blogposts">📝</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/Yanshuming1"><img src="https://avatars.githubusercontent.com/u/118667222?v=4?s=100" width="100px;" alt="linDong"/><br /><sub><b>linDong</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=Yanshuming1" title="Code">💻</a> <a href="https://github.com/apache/hertzbeat/commits?author=Yanshuming1" title="Documentation">📖</a> <a href="https://github.com/apache/hertzbeat/issues?q=author%3AYanshuming1" title="Bug reports">🐛</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/lwjxy"><img src="https://avatars.githubusercontent.com/u/52726400?v=4?s=100" width="100px;" alt="lwjxy"/><br /><sub><b>lwjxy</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=lwjxy" title="Code">💻</a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://thespica.github.io/"><img src="https://avatars.githubusercontent.com/u/119573640?v=4?s=100" width="100px;" alt="John"/><br /><sub><b>John</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=Thespica" title="Code">💻</a> <a href="https://github.com/apache/hertzbeat/commits?author=Thespica" title="Documentation">📖</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/boatrainlsz"><img src="https://avatars.githubusercontent.com/u/18243785?v=4?s=100" width="100px;" alt="boatrainlsz"/><br /><sub><b>boatrainlsz</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=boatrainlsz" title="Documentation">📖</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://www.yitianyigexiangfa.com/"><img src="https://avatars.githubusercontent.com/u/3973419?v=4?s=100" width="100px;" alt="Bill Lau"/><br /><sub><b>Bill Lau</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=JavaProgrammerLB" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/lw-yang"><img src="https://avatars.githubusercontent.com/u/23456873?v=4?s=100" width="100px;" alt="lwyang"/><br /><sub><b>lwyang</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=lw-yang" title="Documentation">📖</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/xfl12345"><img src="https://avatars.githubusercontent.com/u/17960863?v=4?s=100" width="100px;" alt="xfl12345"/><br /><sub><b>xfl12345</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=xfl12345" title="Documentation">📖</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/yykaue"><img src="https://avatars.githubusercontent.com/u/22905143?v=4?s=100" width="100px;" alt="Limbo"/><br /><sub><b>Limbo</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=yykaue" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/irenhongyan"><img src="https://avatars.githubusercontent.com/u/53438321?v=4?s=100" width="100px;" alt="哈哈哈哈哈哈哈哈哈"/><br /><sub><b>哈哈哈哈哈哈哈哈哈</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=irenhongyan" title="Code">💻</a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/ileonli"><img src="https://avatars.githubusercontent.com/u/45332412?v=4?s=100" width="100px;" alt="Leon Li"/><br /><sub><b>Leon Li</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=ileonli" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="http://fnil.net/"><img src="https://avatars.githubusercontent.com/u/14142?v=4?s=100" width="100px;" alt="dennis zhuang"/><br /><sub><b>dennis zhuang</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=killme2008" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/kerwin612"><img src="https://avatars.githubusercontent.com/u/3371163?v=4?s=100" width="100px;" alt="Kerwin Bryant"/><br /><sub><b>Kerwin Bryant</b></sub></a><br /><a href="#design-kerwin612" title="Design">🎨</a> <a href="https://github.com/apache/hertzbeat/commits?author=kerwin612" title="Code">💻</a> <a href="https://github.com/apache/hertzbeat/commits?author=kerwin612" title="Documentation">📖</a> <a href="https://github.com/apache/hertzbeat/issues?q=author%3Akerwin612" title="Bug reports">🐛</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/ShineDevelopment"><img src="https://avatars.githubusercontent.com/u/59306780?v=4?s=100" width="100px;" alt="daixianglong"/><br /><sub><b>daixianglong</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=ShineDevelopment" title="Documentation">📖</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/mchgood"><img src="https://avatars.githubusercontent.com/u/38482005?v=4?s=100" width="100px;" alt="mchgood"/><br /><sub><b>mchgood</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=mchgood" title="Documentation">📖</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/pwallk"><img src="https://avatars.githubusercontent.com/u/69385076?v=4?s=100" width="100px;" alt="kangli"/><br /><sub><b>kangli</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=pwallk" title="Code">💻</a> <a href="https://github.com/apache/hertzbeat/commits?author=pwallk" title="Documentation">📖</a> <a href="https://github.com/apache/hertzbeat/issues?q=author%3Apwallk" title="Bug reports">🐛</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/cdphantom"><img src="https://avatars.githubusercontent.com/u/12674795?v=4?s=100" width="100px;" alt="cdphantom"/><br /><sub><b>cdphantom</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=cdphantom" title="Code">💻</a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/asd108908382"><img src="https://avatars.githubusercontent.com/u/77717999?v=4?s=100" width="100px;" alt="jiawei.guo"/><br /><sub><b>jiawei.guo</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=asd108908382" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/QBH-insist"><img src="https://avatars.githubusercontent.com/u/39401478?v=4?s=100" width="100px;" alt="QBH-insist"/><br /><sub><b>QBH-insist</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=QBH-insist" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/jiangsh-ui"><img src="https://avatars.githubusercontent.com/u/86990361?v=4?s=100" width="100px;" alt="jiangsh"/><br /><sub><b>jiangsh</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=jiangsh-ui" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/keaifafafa"><img src="https://avatars.githubusercontent.com/u/83876361?v=4?s=100" width="100px;" alt="Keaifa"/><br /><sub><b>Keaifa</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=keaifafafa" title="Code">💻</a> <a href="https://github.com/apache/hertzbeat/issues?q=author%3Akeaifafafa" title="Bug reports">🐛</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/loong95"><img src="https://avatars.githubusercontent.com/u/16333958?v=4?s=100" width="100px;" alt="Loong"/><br /><sub><b>Loong</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=loong95" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/ceekay47"><img src="https://avatars.githubusercontent.com/u/104664857?v=4?s=100" width="100px;" alt="Chandrakant Vankayalapati"/><br /><sub><b>Chandrakant Vankayalapati</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=ceekay47" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/MRgenial"><img src="https://avatars.githubusercontent.com/u/49973336?v=4?s=100" width="100px;" alt="b_mountain"/><br /><sub><b>b_mountain</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=MRgenial" title="Code">💻</a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/TemirlanBasitov"><img src="https://avatars.githubusercontent.com/u/57500808?v=4?s=100" width="100px;" alt="TemirlanBasitov"/><br /><sub><b>TemirlanBasitov</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=TemirlanBasitov" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/wyfvsfy"><img src="https://avatars.githubusercontent.com/u/11973517?v=4?s=100" width="100px;" alt="wyfvsfy"/><br /><sub><b>wyfvsfy</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=wyfvsfy" title="Documentation">📖</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/sherry-peng2333"><img src="https://avatars.githubusercontent.com/u/70619577?v=4?s=100" width="100px;" alt="sherry-peng2333"/><br /><sub><b>sherry-peng2333</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=sherry-peng2333" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/lixiaobaivv"><img src="https://avatars.githubusercontent.com/u/39290771?v=4?s=100" width="100px;" alt="Yzzz"/><br /><sub><b>Yzzz</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=lixiaobaivv" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="http://www.bckf.cn/"><img src="https://avatars.githubusercontent.com/u/13309008?v=4?s=100" width="100px;" alt="puruidong"/><br /><sub><b>puruidong</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=pruidong" title="Documentation">📖</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/shinestare"><img src="https://avatars.githubusercontent.com/u/13570619?v=4?s=100" width="100px;" alt="shinestare"/><br /><sub><b>shinestare</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=shinestare" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/po-168"><img src="https://avatars.githubusercontent.com/u/185745593?v=4?s=100" width="100px;" alt="po-168"/><br /><sub><b>po-168</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=po-168" title="Code">💻</a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/All-The-Best-for"><img src="https://avatars.githubusercontent.com/u/76414672?v=4?s=100" width="100px;" alt="wbs99"/><br /><sub><b>wbs99</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=All-The-Best-for" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/starryCoder"><img src="https://avatars.githubusercontent.com/u/46510059?v=4?s=100" width="100px;" alt="starryCoder"/><br /><sub><b>starryCoder</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=starryCoder" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/hasimmollah"><img src="https://avatars.githubusercontent.com/u/32538599?v=4?s=100" width="100px;" alt="hasimmollah"/><br /><sub><b>hasimmollah</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=hasimmollah" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/ayu-v0"><img src="https://avatars.githubusercontent.com/u/127600988?v=4?s=100" width="100px;" alt="Ayu"/><br /><sub><b>Ayu</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=ayu-v0" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/Rancho-7"><img src="https://avatars.githubusercontent.com/u/59016860?v=4?s=100" width="100px;" alt="Nick Guo"/><br /><sub><b>Nick Guo</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=Rancho-7" title="Documentation">📖</a> <a href="https://github.com/apache/hertzbeat/commits?author=Rancho-7" title="Code">💻</a> <a href="https://github.com/apache/hertzbeat/issues?q=author%3ARancho-7" title="Bug reports">🐛</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/doveLin0818"><img src="https://avatars.githubusercontent.com/u/190927907?v=4?s=100" width="100px;" alt="doveLin"/><br /><sub><b>doveLin</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=doveLin0818" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://zzrl.cc/"><img src="https://avatars.githubusercontent.com/u/91836599?v=4?s=100" width="100px;" alt="yunfan24"/><br /><sub><b>yunfan24</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=yunfan24" title="Code">💻</a> <a href="https://github.com/apache/hertzbeat/commits?author=yunfan24" title="Documentation">📖</a> <a href="https://github.com/apache/hertzbeat/issues?q=author%3Ayunfan24" title="Bug reports">🐛</a> <a href="https://github.com/apache/hertzbeat/commits?author=yunfan24" title="Tests">⚠️</a> <a href="#blog-yunfan24" title="Blogposts">📝</a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/lctking"><img src="https://avatars.githubusercontent.com/u/168249998?v=4?s=100" width="100px;" alt="nullwli"/><br /><sub><b>nullwli</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=lctking" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://simonsigre.com/"><img src="https://avatars.githubusercontent.com/u/14932913?v=4?s=100" width="100px;" alt="Simon Sigré"/><br /><sub><b>Simon Sigré</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=simonsigre" title="Documentation">📖</a> <a href="https://github.com/apache/hertzbeat/commits?author=simonsigre" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="http://www.ponfee.cn/"><img src="https://avatars.githubusercontent.com/u/46117331?v=4?s=100" width="100px;" alt="ponfee"/><br /><sub><b>ponfee</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=ponfee" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/Vedant7789"><img src="https://avatars.githubusercontent.com/u/147625492?v=4?s=100" width="100px;" alt="Vedant7789"/><br /><sub><b>Vedant7789</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=Vedant7789" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/Craaaaazy77"><img src="https://avatars.githubusercontent.com/u/23025522?v=4?s=100" width="100px;" alt="Craaaaazy77"/><br /><sub><b>Craaaaazy77</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=Craaaaazy77" title="Documentation">📖</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/Suvrat1629"><img src="https://avatars.githubusercontent.com/u/140749446?v=4?s=100" width="100px;" alt="Suvrat1629"/><br /><sub><b>Suvrat1629</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=Suvrat1629" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="http://ghyghoo8.github.io/"><img src="https://avatars.githubusercontent.com/u/363129?v=4?s=100" width="100px;" alt="ghy"/><br /><sub><b>ghy</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=ghyghoo8" title="Code">💻</a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/helei1030"><img src="https://avatars.githubusercontent.com/u/11839080?v=4?s=100" width="100px;" alt="helei1030"/><br /><sub><b>helei1030</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=helei1030" title="Documentation">📖</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://medium.com/@pjfanning"><img src="https://avatars.githubusercontent.com/u/11783444?v=4?s=100" width="100px;" alt="PJ Fanning"/><br /><sub><b>PJ Fanning</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=pjfanning" title="Code">💻</a> <a href="https://github.com/apache/hertzbeat/issues?q=author%3Apjfanning" title="Bug reports">🐛</a> <a href="https://github.com/apache/hertzbeat/commits?author=pjfanning" title="Tests">⚠️</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/MonsterChenzhuo"><img src="https://avatars.githubusercontent.com/u/60029759?v=4?s=100" width="100px;" alt="monster"/><br /><sub><b>monster</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=MonsterChenzhuo" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/MasamiYui"><img src="https://avatars.githubusercontent.com/u/22274133?v=4?s=100" width="100px;" alt="Sherlock Yin"/><br /><sub><b>Sherlock Yin</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=MasamiYui" title="Code">💻</a> <a href="https://github.com/apache/hertzbeat/commits?author=MasamiYui" title="Documentation">📖</a> <a href="https://github.com/apache/hertzbeat/issues?q=author%3AMasamiYui" title="Bug reports">🐛</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/wanhao23"><img src="https://avatars.githubusercontent.com/u/29560961?v=4?s=100" width="100px;" alt="wanhao"/><br /><sub><b>wanhao</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=wanhao23" title="Code">💻</a> <a href="https://github.com/apache/hertzbeat/commits?author=wanhao23" title="Documentation">📖</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/jonasHanhan"><img src="https://avatars.githubusercontent.com/u/130035609?v=4?s=100" width="100px;" alt="jonasHanhan"/><br /><sub><b>jonasHanhan</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=jonasHanhan" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/NikhilMurugesan"><img src="https://avatars.githubusercontent.com/u/49281792?v=4?s=100" width="100px;" alt="NikhilMurugesan"/><br /><sub><b>NikhilMurugesan</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=NikhilMurugesan" title="Code">💻</a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/myangle1120"><img src="https://avatars.githubusercontent.com/u/19237013?v=4?s=100" width="100px;" alt="myangle1120"/><br /><sub><b>myangle1120</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=myangle1120" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/yasminvo"><img src="https://avatars.githubusercontent.com/u/107528848?v=4?s=100" width="100px;" alt="yasminvo"/><br /><sub><b>yasminvo</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=yasminvo" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/notbugggg"><img src="https://avatars.githubusercontent.com/u/147966331?v=4?s=100" width="100px;" alt="不关银渐层的事哦"/><br /><sub><b>不关银渐层的事哦</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=notbugggg" title="Code">💻</a> <a href="https://github.com/apache/hertzbeat/issues?q=author%3Anotbugggg" title="Bug reports">🐛</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/yyahang"><img src="https://avatars.githubusercontent.com/u/90464876?v=4?s=100" width="100px;" alt="yyahang"/><br /><sub><b>yyahang</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=yyahang" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/JuJinPark"><img src="https://avatars.githubusercontent.com/u/44892459?v=4?s=100" width="100px;" alt="jujin"/><br /><sub><b>jujin</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=JuJinPark" title="Code">💻</a> <a href="https://github.com/apache/hertzbeat/commits?author=JuJinPark" title="Documentation">📖</a> <a href="#ideas-JuJinPark" title="Ideas, Planning, & Feedback">🤔</a> <a href="#blog-JuJinPark" title="Blogposts">📝</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/LL-LIN"><img src="https://avatars.githubusercontent.com/u/43002118?v=4?s=100" width="100px;" alt="LL-LIN"/><br /><sub><b>LL-LIN</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=LL-LIN" title="Code">💻</a> <a href="https://github.com/apache/hertzbeat/issues?q=author%3ALL-LIN" title="Bug reports">🐛</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://bigcyy.github.io/"><img src="https://avatars.githubusercontent.com/u/73413979?v=4?s=100" width="100px;" alt="Yang Chen"/><br /><sub><b>Yang Chen</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=bigcyy" title="Code">💻</a> <a href="https://github.com/apache/hertzbeat/commits?author=bigcyy" title="Documentation">📖</a> <a href="https://github.com/apache/hertzbeat/issues?q=author%3Abigcyy" title="Bug reports">🐛</a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/sarthakeash"><img src="https://avatars.githubusercontent.com/u/74091160?v=4?s=100" width="100px;" alt="Sarthak Arora"/><br /><sub><b>Sarthak Arora</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=sarthakeash" title="Code">💻</a> <a href="https://github.com/apache/hertzbeat/commits?author=sarthakeash" title="Documentation">📖</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/PengJingzhao"><img src="https://avatars.githubusercontent.com/u/97368949?v=4?s=100" width="100px;" alt="彭镜肇"/><br /><sub><b>彭镜肇</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=PengJingzhao" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/gagaradio"><img src="https://avatars.githubusercontent.com/u/18532370?v=4?s=100" width="100px;" alt="Walter Jia"/><br /><sub><b>Walter Jia</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=gagaradio" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/boyucjz"><img src="https://avatars.githubusercontent.com/u/18730041?v=4?s=100" width="100px;" alt="boyucjz"/><br /><sub><b>boyucjz</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=boyucjz" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/Cyanty"><img src="https://avatars.githubusercontent.com/u/153884653?v=4?s=100" width="100px;" alt="Cyanty"/><br /><sub><b>Cyanty</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=Cyanty" title="Code">💻</a> <a href="https://github.com/apache/hertzbeat/commits?author=Cyanty" title="Documentation">📖</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/KevinLLF"><img src="https://avatars.githubusercontent.com/u/85452733?v=4?s=100" width="100px;" alt="Jay丿167"/><br /><sub><b>Jay丿167</b></sub></a><br /><a href="https://github.com/apache/hertzbeat/commits?author=KevinLLF" title="Code">💻</a></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<!-- markdownlint-restore -->
|
||||
<!-- prettier-ignore-end -->
|
||||
|
||||
<!-- ALL-CONTRIBUTORS-LIST:END -->
|
||||
|
||||
## 💬 コミュニティ交流
|
||||
|
||||
##### チャネル
|
||||
|
||||
[メール](https://lists.apache.org/list.html?dev@hertzbeat.apache.org) : メーリングリストに登録するために、```dev-subscribe@hertzbeat.apache.org```にメールを送ってください。
|
||||
|
||||
[Chat On Discord](https://discord.gg/Fb6M73htGr)
|
||||
|
||||
WeChatグループ : `ahertzbeat` を検索.
|
||||
|
||||
WeChat公式アカウント : `usthecom`を検索.
|
||||
|
||||
[QQグループ](https://jq.qq.com/?_wv=1027&k=Bud9OzdI) : グループ番号 `630061200`
|
||||
|
||||
[Github Discussion](https://github.com/apache/hertzbeat/discussions)
|
||||
|
||||
[Reddit Community](https://www.reddit.com/r/hertzbeat/)
|
||||
|
||||
[Follow Us Twitter](https://x.com/hertzbeat1024)
|
||||
|
||||
[Subscribe YouTube](https://www.youtube.com/channel/UCri75zfWX0GHqJFPENEbLow)
|
||||
|
||||
|
||||
##### Open-Source Project Build From Open-Source
|
||||
|
||||
HertzBeat is built on so many great open source projects, thanks to them!
|
||||
|
||||
- `Java Spring SpringBoot Jpa Maven Assembly Netty Lombok Sureness Protobuf HttpClient Guava SnakeYaml JsonPath ...`
|
||||
- `TypeScript Angular NG-ZORRO NG-ALAIN NodeJs Npm Html Less Echarts Rxjs ZoneJs MonacoEditor SlickCarousel Docusaurus ...`
|
||||
|
||||
|
||||
## Landscape
|
||||
|
||||
<p align="left">
|
||||
<img src="./home/static/img/home/cncf-landscape-left-logo.svg" width="300"> <img src="./home/static/img/home/cncf-right-logo.svg" width="345" />
|
||||
<br /><br />
|
||||
HertzBeat has been included in the <a href="https://landscape.cncf.io/guide?item=observability-and-analysis--monitoring--hertzbeat#observability-and-analysis--monitoring">
|
||||
CNCF Observability And Analysis - Monitoring Landscape.</a>
|
||||
</p>
|
||||
|
||||
## 🛡️ License
|
||||
[`Apache License, Version 2.0`](https://www.apache.org/licenses/LICENSE-2.0.html)
|
||||
@@ -0,0 +1,39 @@
|
||||
# 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
|
||||
|
||||
apiVersion: v1
|
||||
clusters:
|
||||
- cluster:
|
||||
certificate-authority-data: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUJkakNDQVIyZ0F3SUJBZ0lCQURBS0JnZ3Foa2pPUFFRREFqQWpNU0V3SHdZRFZRUUREQmhyTTNNdGMyVnkKZG1WeUxXTmhRREUzTkRVeU5ESTROamd3SGhjTk1qVXdOREl4TVRNME1UQTRXaGNOTXpVd05ERTVNVE0wTVRBNApXakFqTVNFd0h3WURWUVFEREJock0zTXRjMlZ5ZG1WeUxXTmhRREUzTkRVeU5ESTROamd3V1RBVEJnY3Foa2pPClBRSUJCZ2dxaGtqT1BRTUJCd05DQUFUR2U2SW5hQko4RGRiQVdmZTRNM09yS3ZTR1IvWkROS0JJV2lMejZXckcKYmh4Mm5ncHJFQjhRYThEWDZocGRCVkI1RmN3L1hwTXZjRnNCeFh3MThPNkdvMEl3UURBT0JnTlZIUThCQWY4RQpCQU1DQXFRd0R3WURWUjBUQVFIL0JBVXdBd0VCL3pBZEJnTlZIUTRFRmdRVWRXOEFySENLNVQ2OFdJeG1BUnlTCkJFcHJ6N1F3Q2dZSUtvWkl6ajBFQXdJRFJ3QXdSQUlnYlhwYXV0c2RlTlJHNm4zRmhBRkkzbncvWUErYTBBdi8KUE9HZzNhYWRCSDBDSUU5NW4vQW5yOXV2Z0tyczVrakpGKzAwci96SWpFdnQxNmhkOGdabFEzb1IKLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQo=
|
||||
server: https://172.29.0.11:6443
|
||||
name: default
|
||||
contexts:
|
||||
- context:
|
||||
cluster: default
|
||||
user: default
|
||||
name: default
|
||||
current-context: default
|
||||
kind: Config
|
||||
preferences: {}
|
||||
users:
|
||||
- name: default
|
||||
user:
|
||||
client-certificate-data: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUJrVENDQVRlZ0F3SUJBZ0lJZm5OdzUyby9ybDB3Q2dZSUtvWkl6ajBFQXdJd0l6RWhNQjhHQTFVRUF3d1kKYXpOekxXTnNhV1Z1ZEMxallVQXhOelExTWpReU9EWTRNQjRYRFRJMU1EUXlNVEV6TkRFd09Gb1hEVEkyTURReQpNVEV6TkRFd09Gb3dNREVYTUJVR0ExVUVDaE1PYzNsemRHVnRPbTFoYzNSbGNuTXhGVEFUQmdOVkJBTVRESE41CmMzUmxiVHBoWkcxcGJqQlpNQk1HQnlxR1NNNDlBZ0VHQ0NxR1NNNDlBd0VIQTBJQUJHa3UxWDQvRGNMU1h4cXcKSzczdGhMUFd5Y3JCendrL3ZMbzkzMTZ0dXNXRWE4WnNMdytnYk5wWEVOSFNxQk8zdGcrYUFSdGhWakF3OU5GaApZWXNtaTQyalNEQkdNQTRHQTFVZER3RUIvd1FFQXdJRm9EQVRCZ05WSFNVRUREQUtCZ2dyQmdFRkJRY0RBakFmCkJnTlZIU01FR0RBV2dCU1B5dEJrYlFaRmtxSEpOaHlHNjZ1K3ZqbjNhakFLQmdncWhrak9QUVFEQWdOSUFEQkYKQWlFQXZQVC9ENGs2S29tUUxaZjRNMTEvd1psT3QyZkpGTGhIY3EyOHMvUUVLcndDSUZVMWVzTGFFTnRWc2xUeAo0QTFtNkt4eEpUbmdNM0M3UXJ5OUs0Z2hzVDA0Ci0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0KLS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUJkekNDQVIyZ0F3SUJBZ0lCQURBS0JnZ3Foa2pPUFFRREFqQWpNU0V3SHdZRFZRUUREQmhyTTNNdFkyeHAKWlc1MExXTmhRREUzTkRVeU5ESTROamd3SGhjTk1qVXdOREl4TVRNME1UQTRXaGNOTXpVd05ERTVNVE0wTVRBNApXakFqTVNFd0h3WURWUVFEREJock0zTXRZMnhwWlc1MExXTmhRREUzTkRVeU5ESTROamd3V1RBVEJnY3Foa2pPClBRSUJCZ2dxaGtqT1BRTUJCd05DQUFSeENGL2FuNVUvS0xEUk9VUlZxdllWTHFsdWxXaE8rMzJpc1lRU1hlYUgKdnRBWHo3dFE2MkhrazNIdXZudnFmditvQlBKVUlzS3ExTyt6aytLT3JWa2dvMEl3UURBT0JnTlZIUThCQWY4RQpCQU1DQXFRd0R3WURWUjBUQVFIL0JBVXdBd0VCL3pBZEJnTlZIUTRFRmdRVWo4clFaRzBHUlpLaHlUWWNodXVyCnZyNDU5Mm93Q2dZSUtvWkl6ajBFQXdJRFNBQXdSUUlnWmxiRkpoZWwzQiszQ2FyZjUrdE5taDhkWkRUOC9yVDAKR01VVXlBNzlWSUVDSVFDSUQ1NkVQbmtOa0xmZExEZXloclBGWks3VWRTc2x2QWZGN2N4czF1MDBxZz09Ci0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0K
|
||||
client-key-data: LS0tLS1CRUdJTiBFQyBQUklWQVRFIEtFWS0tLS0tCk1IY0NBUUVFSUpMOGJrS1FMbEdZWUE0Ny9Lek9CRm5iZnI0NGQ5VndUWXlPT0dJdnNLOXNvQW9HQ0NxR1NNNDkKQXdFSG9VUURRZ0FFYVM3VmZqOE53dEpmR3JBcnZlMkVzOWJKeXNIUENUKzh1ajNmWHEyNnhZUnJ4bXd2RDZCcwoybGNRMGRLb0U3ZTJENW9CRzJGV01ERDAwV0ZoaXlhTGpRPT0KLS0tLS1FTkQgRUMgUFJJVkFURSBLRVktLS0tLQo=
|
||||
@@ -0,0 +1 @@
|
||||
K10800b7e6b1f6390067e433bd30dff5f925893b60074f8c36f7725bfdce6a45917::server:ca7449eb0dddd8a4bb6e5ca86e2d0cdd
|
||||
@@ -0,0 +1,37 @@
|
||||
{
|
||||
"detected": true,
|
||||
"monitor": {
|
||||
"intervals": 10,
|
||||
"tags": [],
|
||||
"app": "kubernetes",
|
||||
"host": "172.29.0.11",
|
||||
"name": "Brave_Stingray_55yR"
|
||||
},
|
||||
"collector": "",
|
||||
"params": [
|
||||
{
|
||||
"display": true,
|
||||
"field": "host",
|
||||
"type": 1,
|
||||
"paramValue": "172.29.0.11"
|
||||
},
|
||||
{
|
||||
"display": true,
|
||||
"field": "port",
|
||||
"type": 0,
|
||||
"paramValue": 6443
|
||||
},
|
||||
{
|
||||
"display": true,
|
||||
"field": "authType",
|
||||
"type": 1,
|
||||
"paramValue": "Bearer Token"
|
||||
},
|
||||
{
|
||||
"display": true,
|
||||
"field": "token",
|
||||
"type": 1,
|
||||
"paramValue": "#TOKEN#"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,69 @@
|
||||
#!api-testing
|
||||
# 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.
|
||||
|
||||
# yaml-language-server: $schema=https://linuxsuren.github.io/api-testing/api-testing-schema.json
|
||||
name: hertzbeat
|
||||
api: |
|
||||
{{default "http://localhost:1157" (env "SERVER")}}
|
||||
param:
|
||||
monitorHTTP: "{{randAlpha 6}}"
|
||||
monitorSiteMap: "{{randAlpha 6}}"
|
||||
monitorPort: "{{randAlpha 6}}"
|
||||
monitorSSL: "{{randAlpha 6}}"
|
||||
monitorPing: "{{randAlpha 6}}"
|
||||
monitorUDP: "{{randAlpha 6}}"
|
||||
monitorWebsite: "{{randAlpha 6}}"
|
||||
monitorFTP: "{{randAlpha 6}}"
|
||||
tagName: "{{randAlpha 3}}"
|
||||
items:
|
||||
- name: login
|
||||
request:
|
||||
api: /api/account/auth/form
|
||||
method: POST
|
||||
header:
|
||||
Content-type: application/json
|
||||
body: |
|
||||
{
|
||||
"type": 0,
|
||||
"identifier": "admin",
|
||||
"credential": "hertzbeat"
|
||||
}
|
||||
expect:
|
||||
bodyFieldsExpect:
|
||||
code: "0"
|
||||
- name: detectMonitor
|
||||
request:
|
||||
api: /api/monitor/detect
|
||||
method: POST
|
||||
header:
|
||||
Authorization: Bearer {{.login.data.token}}
|
||||
Content-type: application/json
|
||||
bodyFromFile: data/tmp.json
|
||||
expect:
|
||||
statusCode: 200
|
||||
- name: createMonitor
|
||||
request:
|
||||
api: /api/monitor
|
||||
method: POST
|
||||
header:
|
||||
Authorization: Bearer {{.login.data.token}}
|
||||
Content-type: application/json
|
||||
bodyFromFile: data/tmp.json
|
||||
expect:
|
||||
statusCode: 200
|
||||
|
||||
@@ -0,0 +1,123 @@
|
||||
# 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.
|
||||
|
||||
version: '3.8'
|
||||
services:
|
||||
init:
|
||||
image: bitnami/kubectl:latest
|
||||
privileged: true
|
||||
depends_on:
|
||||
k3s:
|
||||
condition: service_healthy
|
||||
entrypoint: /bin/bash
|
||||
networks:
|
||||
k3s_network:
|
||||
ipv4_address: 172.29.0.10
|
||||
volumes:
|
||||
- ./data/config/k3s.yaml:/.kube/config
|
||||
- ./data:/testcase
|
||||
command:
|
||||
- -c
|
||||
- |
|
||||
# Wait for k3s to start
|
||||
until kubectl cluster-info; do sleep 1; done
|
||||
sleep 5
|
||||
# Create serviceaccount and clusterrolebinding
|
||||
kubectl create serviceaccount -n kube-system cluster-admin-sa
|
||||
kubectl create clusterrolebinding -n kube-system cluster-admin-binding --clusterrole=cluster-admin --serviceaccount=kube-system:cluster-admin-sa
|
||||
cd /testcase
|
||||
kubectl create token cluster-admin-sa -n kube-system --duration=24h
|
||||
echo $(sed "s/#TOKEN#/$(echo $(kubectl create token cluster-admin-sa -n kube-system --duration=24h))/g" create_k8s_monitor_data.json)>tmp.json
|
||||
# install metrics server
|
||||
kubectl apply -f https://github.com/kubernetes-sigs/metrics-server/releases/latest/download/components.yaml
|
||||
sleep 30
|
||||
tail -f /dev/null
|
||||
k3s:
|
||||
image: rancher/k3s:v1.31.0-k3s1
|
||||
container_name: k3s
|
||||
privileged: true
|
||||
ports:
|
||||
- "6443:6443"
|
||||
- "80:80"
|
||||
command: server --bind-address 172.29.0.11
|
||||
networks:
|
||||
k3s_network:
|
||||
ipv4_address: 172.29.0.11
|
||||
healthcheck:
|
||||
test: [ "CMD-SHELL",
|
||||
"kubectl cluster-info && echo $(cat /var/lib/rancher/k3s/server/node-token)>node-token.txt" ]
|
||||
interval: 3s
|
||||
retries: 30
|
||||
start_period: 10s
|
||||
timeout: 10s
|
||||
volumes:
|
||||
- ./data/config/k3s.yaml:/etc/rancher/k3s/k3s.yaml
|
||||
- ./data/config/node-token.txt:/node-token.txt
|
||||
testing:
|
||||
image: ghcr.io/linuxsuren/api-testing:v0.0.17
|
||||
environment:
|
||||
SERVER: http://hertzbeat:1157
|
||||
container_name: e2e-testing
|
||||
volumes:
|
||||
- ./data/:/work/data/
|
||||
- ./data/testsuite.yaml:/work/testsuite.yaml
|
||||
command: atest run -p /work/testsuite.yaml --level debug --thread 3
|
||||
networks:
|
||||
k3s_network:
|
||||
ipv4_address: 172.29.0.12
|
||||
depends_on:
|
||||
checker:
|
||||
condition: service_healthy
|
||||
k3s:
|
||||
condition: service_healthy
|
||||
links:
|
||||
- hertzbeat
|
||||
- checker
|
||||
- k3s
|
||||
checker:
|
||||
image: alpine:latest
|
||||
container_name: e2e-checker
|
||||
command: sh -c "apk add --update curl && tail -f /dev/null"
|
||||
healthcheck:
|
||||
test: [ "CMD-SHELL",
|
||||
"curl -s -X POST -H \"Content-Type: application/json\" -d '{\"type\": 0,\"identifier\": \"admin\",\"credential\": \"hertzbeat\"}' http://hertzbeat:1157/api/account/auth/form | grep -q token"
|
||||
]
|
||||
interval: 3s
|
||||
timeout: 60s
|
||||
retries: 10
|
||||
start_period: 10s
|
||||
networks:
|
||||
k3s_network:
|
||||
ipv4_address: 172.29.0.13
|
||||
depends_on:
|
||||
- init
|
||||
hertzbeat:
|
||||
image: apache/hertzbeat:test
|
||||
container_name: e2e-hertzbeat
|
||||
volumes:
|
||||
- ./logs/:/opt/hertzbeat/logs/
|
||||
ports:
|
||||
- "1157:1157"
|
||||
networks:
|
||||
k3s_network:
|
||||
ipv4_address: 172.29.0.14
|
||||
networks:
|
||||
k3s_network:
|
||||
driver: bridge
|
||||
ipam:
|
||||
config:
|
||||
- subnet: 172.29.0.0/16
|
||||
+2
-2
@@ -220,11 +220,11 @@ public class RealTimeAlertCalculator {
|
||||
fingerPrints.putAll(commonFingerPrints);
|
||||
for (int index = 0; index < valueRow.getColumnsList().size(); index++) {
|
||||
String valueStr = valueRow.getColumns(index);
|
||||
final CollectRep.Field field = fields.get(index);
|
||||
if (CommonConstants.NULL_VALUE.equals(valueStr)) {
|
||||
fieldValueMap.put(field.getName(), null);
|
||||
continue;
|
||||
}
|
||||
|
||||
final CollectRep.Field field = fields.get(index);
|
||||
final int fieldType = field.getType();
|
||||
|
||||
if (fieldType == CommonConstants.TYPE_NUMBER) {
|
||||
|
||||
+133
@@ -0,0 +1,133 @@
|
||||
/*
|
||||
* 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 lombok.AllArgsConstructor;
|
||||
import lombok.Builder;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* uptime-kuma alert content entity
|
||||
*/
|
||||
@Data
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
@Builder
|
||||
public class UptimeKumaExternAlert {
|
||||
|
||||
private Heartbeat heartbeat;
|
||||
|
||||
private Monitor monitor;
|
||||
|
||||
private String msg;
|
||||
|
||||
/**
|
||||
* Monitor information
|
||||
*/
|
||||
@Data
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
public static class Heartbeat {
|
||||
@JsonProperty("monitorID")
|
||||
private int monitorId;
|
||||
private int status;
|
||||
private String time;
|
||||
private String msg;
|
||||
private boolean important;
|
||||
private int duration;
|
||||
private String timezone;
|
||||
private String timezoneOffset;
|
||||
private String localDateTime;
|
||||
}
|
||||
|
||||
/**
|
||||
* Monitor information
|
||||
*/
|
||||
@Data
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
public static class Monitor {
|
||||
private int id;
|
||||
private String name;
|
||||
private String description;
|
||||
private String pathName;
|
||||
private String parent;
|
||||
@JsonProperty("childrenIDs")
|
||||
private List<String> childrenIds;
|
||||
private String url;
|
||||
private String method;
|
||||
private String hostname;
|
||||
private String port;
|
||||
@JsonProperty("maxretries")
|
||||
private int maxRetries;
|
||||
private int weight;
|
||||
private boolean active;
|
||||
private boolean forceInactive;
|
||||
private String type;
|
||||
private int timeout;
|
||||
private int interval;
|
||||
private int retryInterval;
|
||||
private int resendInterval;
|
||||
private String keyword;
|
||||
private boolean invertKeyword;
|
||||
private boolean expiryNotification;
|
||||
private boolean ignoreTls;
|
||||
private boolean upsideDown;
|
||||
private int packetSize;
|
||||
@JsonProperty("maxredirects")
|
||||
private int maxRedirects;
|
||||
@JsonProperty("accepted_statuscodes")
|
||||
private List<String> acceptedStatusCodes;
|
||||
private String dnsResolveType;
|
||||
private String dnsResolveServer;
|
||||
private String dnsLastResult;
|
||||
private String dockerContainer;
|
||||
private String dockerHost;
|
||||
private String proxyId;
|
||||
private Map<String, Object> notificationIDList;
|
||||
private List<String> tags;
|
||||
private boolean maintenance;
|
||||
private String mqttTopic;
|
||||
private String mqttSuccessMessage;
|
||||
private String databaseQuery;
|
||||
private String authMethod;
|
||||
private String grpcUrl;
|
||||
private String grpcProtobuf;
|
||||
private String grpcMethod;
|
||||
private String grpcServiceName;
|
||||
private boolean grpcEnableTls;
|
||||
private String radiusCalledStationId;
|
||||
private String radiusCallingStationId;
|
||||
private String game;
|
||||
private boolean gamedigGivenPortOnly;
|
||||
private String httpBodyEncoding;
|
||||
private String jsonPath;
|
||||
private String expectedValue;
|
||||
private String kafkaProducerTopic;
|
||||
private List<String> kafkaProducerBrokers;
|
||||
private boolean kafkaProducerSsl;
|
||||
private boolean kafkaProducerAllowAutoTopicCreation;
|
||||
private String kafkaProducerMessage;
|
||||
private String screenshot;
|
||||
private boolean includeSensitiveData;
|
||||
}
|
||||
}
|
||||
+64
-66
@@ -52,86 +52,84 @@ final class DbAlertStoreHandlerImpl implements AlertStoreHandler {
|
||||
log.error("The Group Alerts is empty, ignore store");
|
||||
return groupAlert;
|
||||
}
|
||||
// 1. Find existing alert group
|
||||
GroupAlert existGroupAlert = groupAlertDao.findByGroupKey(groupAlert.getGroupKey());
|
||||
|
||||
// 2. Process individual alerts
|
||||
// Process individual alerts
|
||||
Set<String> alertFingerprints = new HashSet<>(8);
|
||||
|
||||
List<SingleAlert> originalAlerts = groupAlert.getAlerts();
|
||||
List<SingleAlert> newAlerts = new ArrayList<>();
|
||||
|
||||
|
||||
for (SingleAlert singleAlert : originalAlerts) {
|
||||
SingleAlert existAlert = singleAlertDao.findByFingerprint(singleAlert.getFingerprint());
|
||||
|
||||
if (existAlert != null) {
|
||||
// Update the existing alert with the ID and creation time from the database
|
||||
singleAlert.setId(existAlert.getId());
|
||||
singleAlert.setGmtCreate(existAlert.getGmtCreate());
|
||||
|
||||
// Status transition logic
|
||||
if (CommonConstants.ALERT_STATUS_FIRING.equals(singleAlert.getStatus())) {
|
||||
// If the alert is firing and the existing alert is not resolved, update the start time and trigger times
|
||||
if (!CommonConstants.ALERT_STATUS_RESOLVED.equals(existAlert.getStatus())) {
|
||||
synchronized (singleAlert.getFingerprint().intern()) {
|
||||
SingleAlert existAlert = singleAlertDao.findByFingerprint(singleAlert.getFingerprint());
|
||||
if (existAlert != null) {
|
||||
// Update the existing alert with the ID and creation time from the database
|
||||
singleAlert.setId(existAlert.getId());
|
||||
singleAlert.setGmtCreate(existAlert.getGmtCreate());
|
||||
// Status transition logic
|
||||
if (CommonConstants.ALERT_STATUS_FIRING.equals(singleAlert.getStatus())) {
|
||||
// If the alert is firing and the existing alert is not resolved, update the start time and trigger times
|
||||
if (!CommonConstants.ALERT_STATUS_RESOLVED.equals(existAlert.getStatus())) {
|
||||
singleAlert.setStartAt(existAlert.getStartAt());
|
||||
int triggerTimes = Optional.ofNullable(existAlert.getTriggerTimes()).orElse(1)
|
||||
+ Optional.ofNullable(singleAlert.getTriggerTimes()).orElse(1);
|
||||
singleAlert.setTriggerTimes(triggerTimes);
|
||||
}
|
||||
} else if (CommonConstants.ALERT_STATUS_RESOLVED.equals(singleAlert.getStatus())) {
|
||||
// If the alert is resolved, set the end time (if not already set) and copy other fields from the existing alert
|
||||
if (singleAlert.getEndAt() == null) {
|
||||
singleAlert.setEndAt(System.currentTimeMillis());
|
||||
}
|
||||
singleAlert.setStartAt(existAlert.getStartAt());
|
||||
int triggerTimes = Optional.ofNullable(existAlert.getTriggerTimes()).orElse(1)
|
||||
+ Optional.ofNullable(singleAlert.getTriggerTimes()).orElse(1);
|
||||
singleAlert.setTriggerTimes(triggerTimes);
|
||||
singleAlert.setActiveAt(existAlert.getActiveAt());
|
||||
singleAlert.setTriggerTimes(existAlert.getTriggerTimes());
|
||||
}
|
||||
} else if (CommonConstants.ALERT_STATUS_RESOLVED.equals(singleAlert.getStatus())) {
|
||||
// If the alert is resolved, set the end time (if not already set) and copy other fields from the existing alert
|
||||
if (singleAlert.getEndAt() == null) {
|
||||
singleAlert.setEndAt(System.currentTimeMillis());
|
||||
}
|
||||
singleAlert.setStartAt(existAlert.getStartAt());
|
||||
singleAlert.setActiveAt(existAlert.getActiveAt());
|
||||
singleAlert.setTriggerTimes(existAlert.getTriggerTimes());
|
||||
}
|
||||
SingleAlert savedSingleAlert = singleAlertDao.save(singleAlert);
|
||||
newAlerts.add(savedSingleAlert);
|
||||
alertFingerprints.add(savedSingleAlert.getFingerprint());
|
||||
}
|
||||
SingleAlert savedSingleAlert = singleAlertDao.save(singleAlert);
|
||||
newAlerts.add(savedSingleAlert);
|
||||
alertFingerprints.add(savedSingleAlert.getFingerprint());
|
||||
}
|
||||
groupAlert.setAlerts(newAlerts);
|
||||
// 3. Process resolved alerts
|
||||
if (existGroupAlert != null) {
|
||||
List<String> existFingerprints = existGroupAlert.getAlertFingerprints();
|
||||
if (existFingerprints != null) {
|
||||
alertFingerprints.addAll(existFingerprints);
|
||||
}
|
||||
// Merge group information
|
||||
groupAlert.setId(existGroupAlert.getId());
|
||||
groupAlert.setGmtCreate(existGroupAlert.getGmtCreate());
|
||||
// Merge other historical information to preserve
|
||||
Map<String, String> existCommonLabels = existGroupAlert.getCommonLabels();
|
||||
if (existCommonLabels != null) {
|
||||
Map<String, String> commonLabels = groupAlert.getCommonLabels();
|
||||
if (commonLabels != null) {
|
||||
// filter common label in commonLabels and existCommonLabels
|
||||
commonLabels = commonLabels.entrySet().stream()
|
||||
.filter(entry -> existCommonLabels.containsKey(entry.getKey()))
|
||||
.collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
|
||||
groupAlert.setCommonLabels(commonLabels);
|
||||
// Find existing alert group
|
||||
synchronized (groupAlert.getGroupKey().intern()) {
|
||||
GroupAlert existGroupAlert = groupAlertDao.findByGroupKey(groupAlert.getGroupKey());
|
||||
// Process resolved alerts
|
||||
if (existGroupAlert != null) {
|
||||
List<String> existFingerprints = existGroupAlert.getAlertFingerprints();
|
||||
if (existFingerprints != null) {
|
||||
alertFingerprints.addAll(existFingerprints);
|
||||
}
|
||||
}
|
||||
Map<String, String> existCommonAnnotations = existGroupAlert.getCommonAnnotations();
|
||||
if (existCommonAnnotations != null) {
|
||||
Map<String, String> commonAnnotations = groupAlert.getCommonAnnotations();
|
||||
if (commonAnnotations != null) {
|
||||
// filter common annotation in commonAnnotations and existCommonAnnotations
|
||||
commonAnnotations = commonAnnotations.entrySet().stream()
|
||||
.filter(entry -> existCommonAnnotations.containsKey(entry.getKey()))
|
||||
.collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
|
||||
groupAlert.setCommonAnnotations(commonAnnotations);
|
||||
// Merge group information
|
||||
groupAlert.setId(existGroupAlert.getId());
|
||||
groupAlert.setGmtCreate(existGroupAlert.getGmtCreate());
|
||||
// Merge other historical information to preserve
|
||||
Map<String, String> existCommonLabels = existGroupAlert.getCommonLabels();
|
||||
if (existCommonLabels != null) {
|
||||
Map<String, String> commonLabels = groupAlert.getCommonLabels();
|
||||
if (commonLabels != null) {
|
||||
// filter common label in commonLabels and existCommonLabels
|
||||
commonLabels = commonLabels.entrySet().stream()
|
||||
.filter(entry -> existCommonLabels.containsKey(entry.getKey()))
|
||||
.collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
|
||||
groupAlert.setCommonLabels(commonLabels);
|
||||
}
|
||||
}
|
||||
Map<String, String> existCommonAnnotations = existGroupAlert.getCommonAnnotations();
|
||||
if (existCommonAnnotations != null) {
|
||||
Map<String, String> commonAnnotations = groupAlert.getCommonAnnotations();
|
||||
if (commonAnnotations != null) {
|
||||
// filter common annotation in commonAnnotations and existCommonAnnotations
|
||||
commonAnnotations = commonAnnotations.entrySet().stream()
|
||||
.filter(entry -> existCommonAnnotations.containsKey(entry.getKey()))
|
||||
.collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
|
||||
groupAlert.setCommonAnnotations(commonAnnotations);
|
||||
}
|
||||
}
|
||||
}
|
||||
// Save alert group
|
||||
groupAlert.setAlertFingerprints(alertFingerprints.stream().toList());
|
||||
GroupAlert savedGroupAlert = groupAlertDao.save(groupAlert);
|
||||
savedGroupAlert.setAlerts(groupAlert.getAlerts());
|
||||
return savedGroupAlert;
|
||||
}
|
||||
|
||||
// 4. Save alert group
|
||||
groupAlert.setAlertFingerprints(alertFingerprints.stream().toList());
|
||||
GroupAlert savedGroupAlert = groupAlertDao.save(groupAlert);
|
||||
savedGroupAlert.setAlerts(groupAlert.getAlerts());
|
||||
return savedGroupAlert;
|
||||
}
|
||||
}
|
||||
|
||||
+118
@@ -0,0 +1,118 @@
|
||||
/*
|
||||
* 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 lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.hertzbeat.alert.dto.UptimeKumaExternAlert;
|
||||
import org.apache.hertzbeat.alert.reduce.AlarmCommonReduce;
|
||||
import org.apache.hertzbeat.alert.service.ExternAlertService;
|
||||
import org.apache.hertzbeat.common.constants.CommonConstants;
|
||||
import org.apache.hertzbeat.common.entity.alerter.SingleAlert;
|
||||
import org.apache.hertzbeat.common.util.JsonUtil;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.text.ParseException;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* uptime-kuma external alarm service impl
|
||||
*/
|
||||
@Slf4j
|
||||
@Service
|
||||
public class UptimeKumaExternAlertServiceImpl implements ExternAlertService {
|
||||
|
||||
@Autowired
|
||||
private AlarmCommonReduce alarmCommonReduce;
|
||||
|
||||
@Override
|
||||
public void addExternAlert(String content) {
|
||||
UptimeKumaExternAlert alert = JsonUtil.fromJson(content, UptimeKumaExternAlert.class);
|
||||
if (alert == null) {
|
||||
log.warn("parse extern alert content failed! content: {}", content);
|
||||
return;
|
||||
}
|
||||
SingleAlert singleAlert = new UptimeKumaAlertConverter().convert(alert);
|
||||
alarmCommonReduce.reduceAndSendAlarm(singleAlert);
|
||||
}
|
||||
|
||||
/**
|
||||
* Converter: UptimeKuma alert to SingleAlert
|
||||
*/
|
||||
public static class UptimeKumaAlertConverter {
|
||||
|
||||
/**
|
||||
* Convert UptimeKuma alert to SingleAlert
|
||||
*/
|
||||
public SingleAlert convert(UptimeKumaExternAlert alert) {
|
||||
// build basic info
|
||||
SingleAlert.SingleAlertBuilder builder = SingleAlert.builder()
|
||||
.status(convertStatus(alert.getHeartbeat().getStatus()))
|
||||
.startAt(parseTime(alert.getHeartbeat().getTime()))
|
||||
.activeAt(parseTime(alert.getHeartbeat().getTime()))
|
||||
.triggerTimes(1);
|
||||
|
||||
// build labels
|
||||
Map<String, String> labels = new HashMap<>();
|
||||
labels.put("__source__", "uptime_kuma");
|
||||
labels.put("monitor_id", String.valueOf(alert.getMonitor().getId()));
|
||||
labels.put("monitor_name", alert.getMonitor().getName());
|
||||
|
||||
// build annotations
|
||||
Map<String, String> annotations = new HashMap<>();
|
||||
annotations.put("description", alert.getMonitor().getDescription());
|
||||
annotations.put("message", alert.getHeartbeat().getMsg());
|
||||
annotations.put("important", String.valueOf(alert.getHeartbeat().isImportant()));
|
||||
|
||||
return builder
|
||||
.labels(labels)
|
||||
.annotations(annotations)
|
||||
.content(buildContent(alert))
|
||||
.build();
|
||||
}
|
||||
|
||||
private String buildContent(UptimeKumaExternAlert alert) {
|
||||
return String.format("Monitor [%s] %s: %s",
|
||||
alert.getMonitor().getName(),
|
||||
alert.getMonitor().getDescription(),
|
||||
alert.getHeartbeat().getMsg());
|
||||
}
|
||||
|
||||
private String convertStatus(int status) {
|
||||
// uptime kuma status: 1-up, 0-down, 2-pending
|
||||
return status == 1 ? CommonConstants.ALERT_STATUS_RESOLVED : CommonConstants.ALERT_STATUS_FIRING;
|
||||
}
|
||||
|
||||
private Long parseTime(String timeStr) {
|
||||
try {
|
||||
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
|
||||
return sdf.parse(timeStr).getTime();
|
||||
} catch (ParseException e) {
|
||||
log.error("Failed to parse time: {}", timeStr);
|
||||
throw new IllegalArgumentException("Failed to parse time: " + timeStr, e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String supportSource() {
|
||||
return "uptime-kuma";
|
||||
}
|
||||
}
|
||||
+52
@@ -0,0 +1,52 @@
|
||||
/*
|
||||
* 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 lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.hertzbeat.alert.reduce.AlarmCommonReduce;
|
||||
import org.apache.hertzbeat.alert.service.ExternAlertService;
|
||||
import org.apache.hertzbeat.common.entity.alerter.SingleAlert;
|
||||
import org.apache.hertzbeat.common.util.JsonUtil;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
/**
|
||||
* zabbix external alarm service impl
|
||||
*/
|
||||
@Slf4j
|
||||
@Service
|
||||
public class ZabbixExternAlertServiceImpl implements ExternAlertService {
|
||||
|
||||
@Autowired
|
||||
private AlarmCommonReduce alarmCommonReduce;
|
||||
|
||||
@Override
|
||||
public void addExternAlert(String content) {
|
||||
SingleAlert alert = JsonUtil.fromJson(content, SingleAlert.class);
|
||||
if (alert == null) {
|
||||
log.warn("parse extern alert content failed! content: {}", content);
|
||||
return;
|
||||
}
|
||||
alarmCommonReduce.reduceAndSendAlarm(alert);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String supportSource() {
|
||||
return "zabbix";
|
||||
}
|
||||
}
|
||||
+5
-4
@@ -21,6 +21,7 @@ import java.util.Map;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
/**
|
||||
* Alarm template keyword matching replacement engine tool
|
||||
@@ -38,11 +39,11 @@ public final class AlertTemplateUtil {
|
||||
private static final Pattern PATTERN = Pattern.compile("\\$\\{(\\w+)\\}");
|
||||
|
||||
public static String render(String template, Map<String, Object> replaceData) {
|
||||
if (template == null) {
|
||||
return null;
|
||||
if (!StringUtils.hasText(template)) {
|
||||
return template;
|
||||
}
|
||||
if (replaceData == null) {
|
||||
log.warn("The replaceData is null.");
|
||||
log.warn("The render replace data is null.");
|
||||
return template;
|
||||
}
|
||||
try {
|
||||
@@ -50,7 +51,7 @@ public final class AlertTemplateUtil {
|
||||
StringBuilder builder = new StringBuilder();
|
||||
while (matcher.find()) {
|
||||
Object objectValue = replaceData.getOrDefault(matcher.group(1), "NullValue");
|
||||
String value = objectValue.toString();
|
||||
String value = objectValue != null ? objectValue.toString() : "NullValue";
|
||||
matcher.appendReplacement(builder, Matcher.quoteReplacement(value));
|
||||
}
|
||||
matcher.appendTail(builder);
|
||||
|
||||
+154
@@ -0,0 +1,154 @@
|
||||
/*
|
||||
* 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 org.apache.hertzbeat.alert.reduce.AlarmCommonReduce;
|
||||
import org.apache.hertzbeat.alert.service.DataSourceService;
|
||||
import org.apache.hertzbeat.common.constants.CommonConstants;
|
||||
import org.apache.hertzbeat.common.entity.alerter.AlertDefine;
|
||||
import org.apache.hertzbeat.common.entity.alerter.SingleAlert;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
import org.junit.jupiter.params.ParameterizedTest;
|
||||
import org.junit.jupiter.params.provider.NullAndEmptySource;
|
||||
import org.mockito.ArgumentCaptor;
|
||||
import org.mockito.InjectMocks;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.junit.jupiter.MockitoExtension;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertAll;
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertNotNull;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.ArgumentMatchers.anyString;
|
||||
import static org.mockito.Mockito.reset;
|
||||
import static org.mockito.Mockito.times;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.verifyNoInteractions;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
/**
|
||||
* Test case for {@link PeriodicAlertCalculator}
|
||||
*/
|
||||
@ExtendWith(MockitoExtension.class)
|
||||
class PeriodicAlertCalculatorTest {
|
||||
|
||||
@Mock
|
||||
private DataSourceService dataSourceService;
|
||||
|
||||
@Mock
|
||||
private AlarmCommonReduce alarmCommonReduce;
|
||||
|
||||
@Mock
|
||||
private AlarmCacheManager alarmCacheManager;
|
||||
|
||||
@InjectMocks
|
||||
private PeriodicAlertCalculator periodicAlertCalculator;
|
||||
|
||||
private AlertDefine rule;
|
||||
|
||||
@BeforeEach
|
||||
void setUp() {
|
||||
rule = AlertDefine.builder()
|
||||
.id(1L)
|
||||
.name("high_cpu_usage")
|
||||
.type("periodic")
|
||||
.expr("usage>90")
|
||||
.times(1)
|
||||
.labels(Map.of("team", "test-team", "priority", "P1"))
|
||||
.annotations(Map.of("summary", "High CPU usage detected"))
|
||||
.template("High CPU usage (${__value__}%)")
|
||||
.datasource("PROMETHEUS")
|
||||
.enable(true)
|
||||
.period(300)
|
||||
.build();
|
||||
}
|
||||
|
||||
@Test
|
||||
void testTriggerAlertWhenMatchThreshold() {
|
||||
reset(alarmCacheManager);
|
||||
Map<String, Object> result = new HashMap<>();
|
||||
result.put("__value__", 95.0); // Non-null, matched with threshold
|
||||
result.put("__timestamp__", System.currentTimeMillis());
|
||||
when(dataSourceService.calculate(anyString(), anyString())).thenReturn(List.of(result));
|
||||
when(alarmCacheManager.getPending(anyString())).thenReturn(null);
|
||||
periodicAlertCalculator.calculate(rule);
|
||||
// Verify that putFiring is called
|
||||
ArgumentCaptor<String> idCaptor = ArgumentCaptor.forClass(String.class);
|
||||
ArgumentCaptor<SingleAlert> alertCaptor = ArgumentCaptor.forClass(SingleAlert.class);
|
||||
verify(alarmCacheManager).putFiring(idCaptor.capture(), alertCaptor.capture());
|
||||
// Assertion alarm status and content
|
||||
SingleAlert alert = alertCaptor.getValue();
|
||||
assertAll(() -> assertEquals(CommonConstants.ALERT_STATUS_FIRING, alert.getStatus()),
|
||||
() -> assertEquals("High CPU usage (95.0%)", alert.getContent()));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testNoTriggerAlertWhenNotMatchThreshold() {
|
||||
reset(alarmCacheManager);
|
||||
Map<String, Object> result = new HashMap<>();
|
||||
result.put("__value__", null); // null, not matched with threshold
|
||||
result.put("__timestamp__", System.currentTimeMillis());
|
||||
when(dataSourceService.calculate(anyString(), anyString())).thenReturn(List.of(result));
|
||||
periodicAlertCalculator.calculate(rule);
|
||||
verify(alarmCacheManager, times(0)).putFiring(any(), any());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testResolveFiringAlert() {
|
||||
reset(alarmCacheManager);
|
||||
Map<String, Object> result = new HashMap<>();
|
||||
result.put("__value__", null); // null, not matched with threshold
|
||||
result.put("__timestamp__", System.currentTimeMillis());
|
||||
SingleAlert pendingAlert = SingleAlert.builder()
|
||||
.status(CommonConstants.ALERT_STATUS_FIRING)
|
||||
.triggerTimes(2).startAt(System.currentTimeMillis() - 60000)
|
||||
.activeAt(System.currentTimeMillis() - 30000)
|
||||
.build();
|
||||
when(alarmCacheManager.removeFiring(anyString())).thenReturn(pendingAlert);
|
||||
when(dataSourceService.calculate(anyString(), anyString())).thenReturn(List.of(result));
|
||||
periodicAlertCalculator.calculate(rule);
|
||||
ArgumentCaptor<SingleAlert> resolvedCaptor = ArgumentCaptor.forClass(SingleAlert.class);
|
||||
verify(alarmCommonReduce).reduceAndSendAlarm(resolvedCaptor.capture());
|
||||
SingleAlert resolvedAlert = resolvedCaptor.getValue();
|
||||
assertAll(() -> assertEquals(CommonConstants.ALERT_STATUS_RESOLVED, resolvedAlert.getStatus()),
|
||||
() -> assertNotNull(resolvedAlert.getEndAt()),
|
||||
() -> assertTrue(resolvedAlert.getEndAt() > resolvedAlert.getStartAt()));
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@NullAndEmptySource
|
||||
void testSkipWhenDataSourceResultInvalid(List<Map<String, Object>> results) {
|
||||
when(dataSourceService.calculate(anyString(), anyString())).thenReturn(results);
|
||||
periodicAlertCalculator.calculate(rule);
|
||||
verifyNoInteractions(alarmCacheManager);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testHandleDisabledRule() {
|
||||
rule.setEnable(false);
|
||||
periodicAlertCalculator.calculate(rule);
|
||||
verifyNoInteractions(dataSourceService);
|
||||
}
|
||||
}
|
||||
+4
-1
@@ -57,6 +57,7 @@ class DbAlertStoreHandlerImplTest {
|
||||
public void setUp() {
|
||||
groupAlert = new GroupAlert();
|
||||
singleAlert = new SingleAlert();
|
||||
singleAlert.setFingerprint("test-fingerprint");
|
||||
List<SingleAlert> alerts = new ArrayList<>();
|
||||
alerts.add(singleAlert);
|
||||
groupAlert.setAlerts(alerts);
|
||||
@@ -77,11 +78,13 @@ class DbAlertStoreHandlerImplTest {
|
||||
when(groupAlertDao.findByGroupKey(groupKey)).thenReturn(null);
|
||||
|
||||
SingleAlert savedSingleAlert = new SingleAlert();
|
||||
savedSingleAlert.setFingerprint("test-finger");
|
||||
when(singleAlertDao.save(any(SingleAlert.class))).thenReturn(savedSingleAlert);
|
||||
|
||||
GroupAlert savedGroupAlert = new GroupAlert();
|
||||
savedGroupAlert.setGroupKey(groupKey);
|
||||
when(groupAlertDao.save(any(GroupAlert.class))).thenReturn(savedGroupAlert);
|
||||
|
||||
|
||||
dbAlertStoreHandler.store(groupAlert);
|
||||
|
||||
verify(singleAlertDao).save(any(SingleAlert.class));
|
||||
|
||||
+83
@@ -0,0 +1,83 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.apache.hertzbeat.collector.collect.sd;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.hertzbeat.collector.collect.AbstractCollect;
|
||||
import org.apache.hertzbeat.collector.collect.registry.constant.DiscoveryClientInstance;
|
||||
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.ServiceInstance;
|
||||
import org.apache.hertzbeat.collector.dispatch.DispatchConstants;
|
||||
import org.apache.hertzbeat.common.entity.job.Metrics;
|
||||
import org.apache.hertzbeat.common.entity.job.protocol.ConsulSdProtocol;
|
||||
import org.apache.hertzbeat.common.entity.job.protocol.RegistryProtocol;
|
||||
import org.apache.hertzbeat.common.entity.message.CollectRep;
|
||||
import org.apache.hertzbeat.common.util.CommonUtil;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* consul sd collector
|
||||
*/
|
||||
@Slf4j
|
||||
public class ConsulSdCollectImpl extends AbstractCollect {
|
||||
|
||||
private static final DiscoveryClientManagement discoveryClientManagement = new DiscoveryClientManagement();
|
||||
|
||||
@Override
|
||||
public void preCheck(Metrics metrics) throws IllegalArgumentException {
|
||||
ConsulSdProtocol consulSd = metrics.getConsul_sd();
|
||||
if (consulSd == null || consulSd.isInvalid()) {
|
||||
throw new IllegalArgumentException("Consul Service Discovery params is required.");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void collect(CollectRep.MetricsData.Builder builder, Metrics metrics) {
|
||||
RegistryProtocol registryProtocol = RegistryProtocol.builder()
|
||||
.host(metrics.getConsul_sd().getHost())
|
||||
.port(metrics.getConsul_sd().getPort())
|
||||
.discoveryClientTypeName(DiscoveryClientInstance.CONSUL.name())
|
||||
.build();
|
||||
try (DiscoveryClient client = discoveryClientManagement.getClient(registryProtocol)){
|
||||
List<ServiceInstance> services = client.getServices();
|
||||
if (CollectionUtils.isEmpty(services)) {
|
||||
return;
|
||||
}
|
||||
services.forEach(instance -> {
|
||||
CollectRep.ValueRow.Builder valueRowBuilder = CollectRep.ValueRow.newBuilder();
|
||||
valueRowBuilder.addColumn(instance.getAddress());
|
||||
valueRowBuilder.addColumn(String.valueOf(instance.getPort()));
|
||||
builder.addValueRow(valueRowBuilder.build());
|
||||
});
|
||||
} catch (Exception e) {
|
||||
String errorMsg = CommonUtil.getMessageFromThrowable(e);
|
||||
log.warn("Failed to fetch consul sd... {}", errorMsg);
|
||||
builder.setCode(CollectRep.Code.FAIL);
|
||||
builder.setMsg(errorMsg);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String supportProtocol() {
|
||||
return DispatchConstants.PROTOCOL_CONSUL_SD;
|
||||
}
|
||||
}
|
||||
+181
@@ -0,0 +1,181 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.apache.hertzbeat.collector.collect.sd;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.hertzbeat.collector.collect.AbstractCollect;
|
||||
import org.apache.hertzbeat.collector.dispatch.DispatchConstants;
|
||||
import org.apache.hertzbeat.common.entity.job.Metrics;
|
||||
import org.apache.hertzbeat.common.entity.message.CollectRep;
|
||||
import org.apache.hertzbeat.common.util.CommonUtil;
|
||||
import org.xbill.DNS.AAAARecord;
|
||||
import org.xbill.DNS.ARecord;
|
||||
import org.xbill.DNS.Lookup;
|
||||
import org.xbill.DNS.MXRecord;
|
||||
import org.xbill.DNS.NSRecord;
|
||||
import org.xbill.DNS.Record;
|
||||
import org.xbill.DNS.SRVRecord;
|
||||
import org.xbill.DNS.SimpleResolver;
|
||||
import org.xbill.DNS.TextParseException;
|
||||
import org.xbill.DNS.Type;
|
||||
|
||||
import java.time.Duration;
|
||||
import java.util.Arrays;
|
||||
|
||||
/**
|
||||
* DNS SD collector supporting multiple record types
|
||||
*/
|
||||
@Slf4j
|
||||
public class DnsSdCollectImpl extends AbstractCollect {
|
||||
|
||||
private static final int DEFAULT_TIME_OUT = 3;
|
||||
|
||||
@Override
|
||||
public void preCheck(Metrics metrics) throws IllegalArgumentException {
|
||||
if (metrics.getDns_sd() == null) {
|
||||
throw new IllegalArgumentException("DNS SD configuration cannot be null");
|
||||
}
|
||||
if (metrics.getDns_sd().getHost() == null || metrics.getDns_sd().getHost().isEmpty()) {
|
||||
throw new IllegalArgumentException("DNS host cannot be null or empty");
|
||||
}
|
||||
if (metrics.getDns_sd().getPort() == null || metrics.getDns_sd().getPort().isEmpty()) {
|
||||
throw new IllegalArgumentException("DNS port cannot be null or empty");
|
||||
}
|
||||
if (metrics.getDns_sd().getRecordType() == null || metrics.getDns_sd().getRecordType().isEmpty()) {
|
||||
throw new IllegalArgumentException("DNS record type cannot be null or empty");
|
||||
}
|
||||
if (metrics.getDns_sd().getRecordName() == null || metrics.getDns_sd().getRecordName().isEmpty()) {
|
||||
throw new IllegalArgumentException("DNS record name cannot be null or empty");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void collect(CollectRep.MetricsData.Builder builder, Metrics metrics) {
|
||||
String hostName = metrics.getDns_sd().getHost();
|
||||
int type = Integer.parseInt(metrics.getDns_sd().getRecordType());
|
||||
Type.check(type);
|
||||
String recordName = metrics.getDns_sd().getRecordName();
|
||||
try {
|
||||
Lookup lookup = new Lookup(recordName, type);
|
||||
SimpleResolver resolver = new SimpleResolver(metrics.getDns_sd().getHost());
|
||||
resolver.setPort(Integer.parseInt(metrics.getDns_sd().getPort()));
|
||||
resolver.setTimeout(Duration.ofMillis(DEFAULT_TIME_OUT));
|
||||
lookup.setResolver(resolver);
|
||||
lookup.setCache(null);
|
||||
lookup.run();
|
||||
if (lookup.getResult() != Lookup.SUCCESSFUL) {
|
||||
String msg = String.format("DNS lookup failed for: %s, error: %s", recordName, lookup.getErrorString());
|
||||
log.warn(msg);
|
||||
builder.setCode(CollectRep.Code.FAIL);
|
||||
builder.setMsg(msg);
|
||||
return;
|
||||
}
|
||||
Record[] records = lookup.getAnswers();
|
||||
if (records == null || records.length == 0) {
|
||||
log.info("No record type: {} records found for host: {}", type, hostName);
|
||||
builder.setCode(CollectRep.Code.SUCCESS);
|
||||
return;
|
||||
}
|
||||
processRecords(builder, records, type);
|
||||
} catch (TextParseException e) {
|
||||
String errorMsg = CommonUtil.getMessageFromThrowable(e);
|
||||
log.warn("Failed to parse dns query... {}", errorMsg);
|
||||
builder.setCode(CollectRep.Code.FAIL);
|
||||
builder.setMsg(errorMsg);
|
||||
} catch (Exception e) {
|
||||
String errorMsg = CommonUtil.getMessageFromThrowable(e);
|
||||
log.error("Failed to fetch dns sd...{}", errorMsg);
|
||||
builder.setCode(CollectRep.Code.FAIL);
|
||||
builder.setMsg(errorMsg);
|
||||
}
|
||||
}
|
||||
|
||||
private void processRecords(CollectRep.MetricsData.Builder builder, Record[] records, int recordType) {
|
||||
switch (recordType) {
|
||||
case Type.A:
|
||||
processARecords(builder, records);
|
||||
break;
|
||||
case Type.AAAA:
|
||||
processAAAARecords(builder, records);
|
||||
break;
|
||||
case Type.SRV:
|
||||
processSrvRecords(builder, records);
|
||||
break;
|
||||
case Type.MX:
|
||||
processMxRecords(builder, records);
|
||||
break;
|
||||
case Type.NS:
|
||||
processNsRecords(builder, records);
|
||||
break;
|
||||
default:
|
||||
throw new IllegalStateException("Invalid record type: " + recordType);
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings({"checkstyle:AbbreviationAsWordInName", "checkstyle:LambdaParameterName"})
|
||||
private void processARecords(CollectRep.MetricsData.Builder builder, Record[] records) {
|
||||
Arrays.stream(records).filter(ARecord.class::isInstance).map(ARecord.class::cast).forEach(aRecord -> {
|
||||
CollectRep.ValueRow.Builder row = CollectRep.ValueRow.newBuilder();
|
||||
row.addColumn(aRecord.getAddress().getHostAddress());
|
||||
row.addColumn(""); //A record has no port
|
||||
builder.addValueRow(row.build());
|
||||
});
|
||||
}
|
||||
|
||||
@SuppressWarnings("checkstyle:AbbreviationAsWordInName")
|
||||
private void processAAAARecords(CollectRep.MetricsData.Builder builder, Record[] records) {
|
||||
Arrays.stream(records).filter(AAAARecord.class::isInstance).map(AAAARecord.class::cast).forEach(aaaaRecord -> {
|
||||
CollectRep.ValueRow.Builder row = CollectRep.ValueRow.newBuilder();
|
||||
row.addColumn(aaaaRecord.getAddress().getHostAddress());
|
||||
row.addColumn(""); //AAAA record has no port
|
||||
builder.addValueRow(row.build());
|
||||
});
|
||||
}
|
||||
|
||||
private void processSrvRecords(CollectRep.MetricsData.Builder builder, Record[] records) {
|
||||
Arrays.stream(records).filter(SRVRecord.class::isInstance).map(SRVRecord.class::cast).forEach(srvRecord -> {
|
||||
CollectRep.ValueRow.Builder row = CollectRep.ValueRow.newBuilder();
|
||||
row.addColumn(srvRecord.getTarget().toString(true));
|
||||
row.addColumn(String.valueOf(srvRecord.getPort()));
|
||||
builder.addValueRow(row.build());
|
||||
});
|
||||
}
|
||||
|
||||
private void processMxRecords(CollectRep.MetricsData.Builder builder, Record[] records) {
|
||||
Arrays.stream(records).filter(MXRecord.class::isInstance).map(MXRecord.class::cast).forEach(mxRecord -> {
|
||||
CollectRep.ValueRow.Builder row = CollectRep.ValueRow.newBuilder();
|
||||
row.addColumn(mxRecord.getTarget().toString(true));
|
||||
row.addColumn(""); //MX record has no port
|
||||
builder.addValueRow(row.build());
|
||||
});
|
||||
}
|
||||
|
||||
private void processNsRecords(CollectRep.MetricsData.Builder builder, Record[] records) {
|
||||
Arrays.stream(records).filter(NSRecord.class::isInstance).map(NSRecord.class::cast).forEach(nsRecord -> {
|
||||
CollectRep.ValueRow.Builder row = CollectRep.ValueRow.newBuilder();
|
||||
row.addColumn(nsRecord.getTarget().toString(true));
|
||||
row.addColumn(""); //NS record has no port
|
||||
builder.addValueRow(row.build());
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public String supportProtocol() {
|
||||
return DispatchConstants.PROTOCOL_DNS_SD;
|
||||
}
|
||||
}
|
||||
+111
@@ -0,0 +1,111 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.apache.hertzbeat.collector.collect.sd;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
import java.io.IOException;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.List;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.hertzbeat.collector.collect.AbstractCollect;
|
||||
import org.apache.hertzbeat.collector.collect.common.http.CommonHttpClient;
|
||||
import org.apache.hertzbeat.collector.dispatch.DispatchConstants;
|
||||
import org.apache.hertzbeat.common.entity.job.Metrics;
|
||||
import org.apache.hertzbeat.common.entity.job.protocol.EurekaSdProtocol;
|
||||
import org.apache.hertzbeat.common.entity.message.CollectRep;
|
||||
import org.apache.hertzbeat.common.entity.sd.ConnectionConfig;
|
||||
import org.apache.hertzbeat.common.entity.sd.EurekaDiscoveryResponseEntity;
|
||||
import org.apache.hertzbeat.common.util.CommonUtil;
|
||||
import org.apache.hertzbeat.common.util.XmlUtil;
|
||||
import org.apache.http.client.methods.CloseableHttpResponse;
|
||||
import org.apache.http.client.methods.HttpUriRequest;
|
||||
import org.apache.http.client.methods.RequestBuilder;
|
||||
import org.apache.http.util.EntityUtils;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
|
||||
/**
|
||||
* eureka service discovery collect impl
|
||||
*/
|
||||
@Slf4j
|
||||
public class EurekaSdCollectImpl extends AbstractCollect {
|
||||
|
||||
private static final String APP_LIST_PATH = "/apps";
|
||||
|
||||
@Override
|
||||
public void preCheck(Metrics metrics) throws IllegalArgumentException {
|
||||
EurekaSdProtocol eurekaSd = metrics.getEureka_sd();
|
||||
if (eurekaSd == null || eurekaSd.getUrl() == null) {
|
||||
throw new IllegalArgumentException("Eureka Service Discovery url is required.");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void collect(CollectRep.MetricsData.Builder builder, Metrics metrics) {
|
||||
List<ConnectionConfig> configList = Lists.newArrayList();
|
||||
HttpUriRequest request = RequestBuilder.get().setUri(metrics.getEureka_sd().getUrl() + APP_LIST_PATH).build();
|
||||
try (CloseableHttpResponse response = CommonHttpClient.getHttpClient().execute(request)) {
|
||||
int statusCode = response.getStatusLine().getStatusCode();
|
||||
if (statusCode != 200) {
|
||||
log.warn("Failed to fetch eureka sd...");
|
||||
builder.setMsg("StatusCode " + statusCode);
|
||||
builder.setCode(CollectRep.Code.FAIL);
|
||||
return;
|
||||
}
|
||||
String responseBody = EntityUtils.toString(response.getEntity(), StandardCharsets.UTF_8);
|
||||
EurekaDiscoveryResponseEntity responseEntity =
|
||||
XmlUtil.fromXml(responseBody, EurekaDiscoveryResponseEntity.class);
|
||||
if (responseEntity == null || CollectionUtils.isEmpty(responseEntity.getApplications())) {
|
||||
return;
|
||||
}
|
||||
|
||||
responseEntity.getApplications()
|
||||
.stream()
|
||||
.filter(application -> !CollectionUtils.isEmpty(application.getInstances()))
|
||||
.forEach(application -> convertTarget(configList, application));
|
||||
|
||||
configList.forEach(config -> {
|
||||
CollectRep.ValueRow.Builder valueRowBuilder = CollectRep.ValueRow.newBuilder();
|
||||
valueRowBuilder.addColumn(config.getHost());
|
||||
valueRowBuilder.addColumn(config.getPort());
|
||||
builder.addValueRow(valueRowBuilder.build());
|
||||
});
|
||||
} catch (IOException e) {
|
||||
String errorMsg = CommonUtil.getMessageFromThrowable(e);
|
||||
log.warn("Failed to fetch eureka sd... {}", errorMsg);
|
||||
builder.setCode(CollectRep.Code.FAIL);
|
||||
builder.setMsg(errorMsg);
|
||||
}
|
||||
}
|
||||
|
||||
private void convertTarget(List<ConnectionConfig> configList,
|
||||
EurekaDiscoveryResponseEntity.Application application) {
|
||||
application.getInstances().forEach(instance -> {
|
||||
String host = instance.getIpAddr();
|
||||
int port = instance.getPort() == null ? 80 : instance.getPort();
|
||||
configList.add(ConnectionConfig.builder()
|
||||
.host(host)
|
||||
.port(String.valueOf(port))
|
||||
.build());
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public String supportProtocol() {
|
||||
return DispatchConstants.PROTOCOL_EUREKA_SD;
|
||||
}
|
||||
}
|
||||
+1
-1
@@ -52,7 +52,7 @@ public class HttpSdCollectImpl extends AbstractCollect {
|
||||
@Override
|
||||
public void collect(CollectRep.MetricsData.Builder builder, Metrics metrics) {
|
||||
List<ConnectionConfig> configList = Lists.newArrayList();
|
||||
HttpUriRequest request = RequestBuilder.get().setUri(metrics.getSdProtocol().getSdSource()).build();
|
||||
HttpUriRequest request = RequestBuilder.get().setUri(metrics.getHttp_sd().getUrl()).build();
|
||||
|
||||
try (CloseableHttpResponse response = CommonHttpClient.getHttpClient().execute(request)) {
|
||||
int statusCode = response.getStatusLine().getStatusCode();
|
||||
|
||||
+2
-1
@@ -281,7 +281,8 @@ public class CommonDispatcher implements MetricsTaskDispatch, CollectDataDispatc
|
||||
}
|
||||
// If it is an asynchronous periodic cyclic task, directly response the collected data
|
||||
if (job.isSd()) {
|
||||
commonDataQueue.sendServiceDiscoveryData(metricsData);
|
||||
CollectRep.MetricsData sdMetricsData = CollectRep.MetricsData.newBuilder(metricsData).build();
|
||||
commonDataQueue.sendServiceDiscoveryData(sdMetricsData);
|
||||
}
|
||||
commonDataQueue.sendMetricsData(metricsData);
|
||||
} else {
|
||||
|
||||
+4
-1
@@ -29,5 +29,8 @@ org.apache.hertzbeat.collector.collect.mqtt.MqttCollectImpl
|
||||
org.apache.hertzbeat.collector.collect.ipmi2.IpmiCollectImpl
|
||||
org.apache.hertzbeat.collector.collect.kafka.KafkaCollectImpl
|
||||
org.apache.hertzbeat.collector.collect.sd.HttpSdCollectImpl
|
||||
org.apache.hertzbeat.collector.collect.sd.DnsSdCollectImpl
|
||||
org.apache.hertzbeat.collector.collect.sd.EurekaSdCollectImpl
|
||||
org.apache.hertzbeat.collector.collect.sd.ConsulSdCollectImpl
|
||||
org.apache.hertzbeat.collector.collect.modbus.ModbusCollectImpl
|
||||
org.apache.hertzbeat.collector.collect.s7.S7CollectImpl
|
||||
org.apache.hertzbeat.collector.collect.s7.S7CollectImpl
|
||||
|
||||
+1
-1
@@ -39,7 +39,7 @@ spring:
|
||||
|
||||
collector:
|
||||
info:
|
||||
version: ${COLLECTOR_VERSION:1.7.0}
|
||||
version: ${COLLECTOR_VERSION:1.7.1}
|
||||
ip: ${COLLECTOR_IP:}
|
||||
dispatch:
|
||||
entrance:
|
||||
|
||||
+14
-1
@@ -126,7 +126,20 @@ public interface DispatchConstants {
|
||||
/**
|
||||
* protocol http sd
|
||||
*/
|
||||
String PROTOCOL_HTTP_SD = "httpsd";
|
||||
String PROTOCOL_HTTP_SD = "http_sd";
|
||||
/**
|
||||
* protocol dns sd
|
||||
*/
|
||||
String PROTOCOL_DNS_SD = "dns_sd";
|
||||
/**
|
||||
* protocol eureka sd
|
||||
*/
|
||||
String PROTOCOL_EUREKA_SD = "eureka_sd";
|
||||
|
||||
/**
|
||||
* protocol consul sd
|
||||
*/
|
||||
String PROTOCOL_CONSUL_SD = "consul_sd";
|
||||
/**
|
||||
* protocol redfish
|
||||
*/
|
||||
|
||||
+2
-2
@@ -17,10 +17,10 @@
|
||||
|
||||
package org.apache.hertzbeat.collector.dispatch.timer;
|
||||
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.ConcurrentLinkedDeque;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
@@ -87,7 +87,7 @@ public class TimerDispatcher implements TimerDispatch, DisposableBean {
|
||||
for (Metrics metric : addJob.getMetrics()) {
|
||||
metric.setInterval(0L);
|
||||
}
|
||||
addJob.setIntervals(new LinkedList<>(List.of(0L)));
|
||||
addJob.setIntervals(new ConcurrentLinkedDeque<>(List.of(0L)));
|
||||
Timeout timeout = wheelTimer.newTimeout(timerJob, addJob.getInterval(), TimeUnit.SECONDS);
|
||||
currentTempTaskMap.put(addJob.getId(), timeout);
|
||||
eventListeners.put(addJob.getId(), eventListener);
|
||||
|
||||
@@ -72,6 +72,10 @@
|
||||
<artifactId>jackson-annotations</artifactId>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.fasterxml.jackson.dataformat</groupId>
|
||||
<artifactId>jackson-dataformat-xml</artifactId>
|
||||
</dependency>
|
||||
<!-- swagger -->
|
||||
<dependency>
|
||||
<groupId>org.springdoc</groupId>
|
||||
|
||||
+4
-107
@@ -73,14 +73,14 @@ public interface CommonConstants {
|
||||
byte MONITOR_DOWN_CODE = 0x02;
|
||||
|
||||
/**
|
||||
* Monitor bind type, 0: monitor that auto-created by sd
|
||||
* scrape type static
|
||||
*/
|
||||
byte MONITOR_BIND_TYPE_SD_SUB_MONITOR = 0x00;
|
||||
String SCRAPE_STATIC = "static";
|
||||
|
||||
/**
|
||||
* Monitor bind type, 1: the main monitor of sd
|
||||
* scrape type
|
||||
*/
|
||||
byte MONITOR_BIND_TYPE_SD_MAIN_MONITOR = 0x01;
|
||||
String SCRAPE_HTTP_SD = "http_sd";
|
||||
|
||||
/**
|
||||
* label key: instance
|
||||
@@ -192,11 +192,6 @@ public interface CommonConstants {
|
||||
*/
|
||||
String PROM_VALUE = "value";
|
||||
|
||||
/**
|
||||
* Monitor total availability metrics
|
||||
*/
|
||||
String AVAILABILITY = "availability";
|
||||
|
||||
/**
|
||||
* Parameter Type Number
|
||||
*/
|
||||
@@ -222,104 +217,6 @@ public interface CommonConstants {
|
||||
*/
|
||||
byte PARAM_TYPE_ARRAY = 4;
|
||||
|
||||
/**
|
||||
* Authentication type Account password
|
||||
*/
|
||||
byte AUTH_TYPE_PASSWORD = 1;
|
||||
|
||||
/**
|
||||
* Authentication type GitHub three-party login
|
||||
*/
|
||||
byte AUTH_TYPE_GITHUB = 2;
|
||||
|
||||
/**
|
||||
* Authentication type WeChat three-party login
|
||||
*/
|
||||
byte AUTH_TYPE_WEIXIN = 3;
|
||||
|
||||
/**
|
||||
* Authentication type GITEE three-party login
|
||||
*/
|
||||
byte AUTH_TYPE_GITEE = 5;
|
||||
|
||||
/**
|
||||
* inner default label key __instance__
|
||||
*/
|
||||
String LABEL_INNER_KEY_INSTANCE = "__instance__";
|
||||
|
||||
/**
|
||||
* Inside the tag: monitorId Monitor task ID
|
||||
*/
|
||||
String TAG_MONITOR_ID = "monitorId";
|
||||
|
||||
/**
|
||||
* Inside the tag: monitorName Task name
|
||||
*/
|
||||
String TAG_MONITOR_NAME = "monitorName";
|
||||
|
||||
/**
|
||||
* Inside the tag: indicate that this monitor is auto-created by main monitor
|
||||
*/
|
||||
String TAG_AUTO_CREATED = "autoCreated";
|
||||
|
||||
/**
|
||||
* Inside the tag: indicate that this monitor is a main monitor which provides service discovery
|
||||
*/
|
||||
String TAG_SD_MAIN_MONITOR = "sdMainMonitor";
|
||||
|
||||
/**
|
||||
* Inside the tag: monitorHost Task host
|
||||
*/
|
||||
String TAG_MONITOR_HOST = "monitorHost";
|
||||
|
||||
/**
|
||||
* Inside the tag: policyId Alarm threshold rule ID
|
||||
*/
|
||||
String TAG_THRESHOLD_ID = "thresholdId";
|
||||
|
||||
/**
|
||||
* Inside the tag: app Type of monitoring
|
||||
*/
|
||||
String TAG_MONITOR_APP = "app";
|
||||
|
||||
/**
|
||||
* Inside the tag: metrics
|
||||
*/
|
||||
String TAG_METRICS = "metrics";
|
||||
|
||||
/**
|
||||
* Inside the tag: metric
|
||||
*/
|
||||
String TAG_METRIC = "metric";
|
||||
|
||||
/**
|
||||
* Inside the tag: code
|
||||
*/
|
||||
String TAG_CODE = "code";
|
||||
|
||||
/**
|
||||
* Tag Type: Auto-generated
|
||||
*/
|
||||
byte TAG_TYPE_AUTO_GENERATE = 0;
|
||||
/**
|
||||
* Tag Type: User-generated
|
||||
*/
|
||||
byte TAG_TYPE_USER_GENERATE = 1;
|
||||
/**
|
||||
* Tag Type: System preset
|
||||
*/
|
||||
byte TAG_TYPE_SYSTEM_PRESET = 2;
|
||||
|
||||
/**
|
||||
* notice_period type Type field, daily type
|
||||
*/
|
||||
int NOTICE_PERIOD_DAILY = 0;
|
||||
|
||||
/**
|
||||
* key is receiver.id, value is noticePeriod cache key prefix
|
||||
*/
|
||||
String RECEIVER_NOTICE_PERIOD_CACHE_PREFIX = "receiver_notice_period:";
|
||||
|
||||
/**
|
||||
* cache key notice_rule
|
||||
*/
|
||||
|
||||
+1
-1
@@ -86,7 +86,7 @@ public class GroupAlert {
|
||||
|
||||
@Schema(title = "Alert Fingerprints", example = "[\"dxsdfdsf\"]")
|
||||
@Convert(converter = JsonStringListAttributeConverter.class)
|
||||
@Column(length = 2048)
|
||||
@Column(length = 8192)
|
||||
private List<String> alertFingerprints;
|
||||
|
||||
@Schema(title = "The creator of this record", example = "tom")
|
||||
|
||||
@@ -28,6 +28,7 @@ import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.ConcurrentLinkedDeque;
|
||||
import java.util.stream.Collectors;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Builder;
|
||||
@@ -114,7 +115,7 @@ public class Job {
|
||||
/**
|
||||
* Refresh time list for one cycle of the job
|
||||
*/
|
||||
private LinkedList<Long> intervals;
|
||||
private ConcurrentLinkedDeque<Long> intervals;
|
||||
/**
|
||||
* Whether it is a recurring periodic task true is yes, false is no
|
||||
*/
|
||||
@@ -328,7 +329,7 @@ public class Job {
|
||||
* @param metricsIntervals A unique list composed of intervals for all metrics
|
||||
* Generate a list of refresh intervals for metric collection
|
||||
*/
|
||||
public void generateMetricsIntervals(List<Long> metricsIntervals) {
|
||||
public synchronized void generateMetricsIntervals(List<Long> metricsIntervals) {
|
||||
// 1. To find the least common multiple (LCM) of all metric refresh intervals
|
||||
long lcm = lcm(metricsIntervals);
|
||||
List<Long> refreshTimes = new LinkedList<>();
|
||||
@@ -348,14 +349,16 @@ public class Job {
|
||||
for (int i = 1; i < refreshTimes.size(); i++) {
|
||||
intervals.add(refreshTimes.get(i) - refreshTimes.get(i - 1));
|
||||
}
|
||||
setIntervals(intervals);
|
||||
setIntervals(new ConcurrentLinkedDeque<>(intervals));
|
||||
}
|
||||
|
||||
public long getInterval() {
|
||||
if (!CollectionUtils.isEmpty(getIntervals())) {
|
||||
long interval = getIntervals().remove();
|
||||
getIntervals().add(interval);
|
||||
return interval;
|
||||
public synchronized long getInterval() {
|
||||
if (!CollectionUtils.isEmpty(this.intervals)) {
|
||||
Long interval = this.intervals.removeFirst();
|
||||
if (interval != null) {
|
||||
this.intervals.addLast(interval);
|
||||
return interval;
|
||||
}
|
||||
}
|
||||
return getDefaultInterval();
|
||||
}
|
||||
|
||||
@@ -30,8 +30,11 @@ import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.hertzbeat.common.entity.job.protocol.DnsProtocol;
|
||||
import org.apache.hertzbeat.common.entity.job.protocol.DnsSdProtocol;
|
||||
import org.apache.hertzbeat.common.entity.job.protocol.FtpProtocol;
|
||||
import org.apache.hertzbeat.common.entity.job.protocol.HttpProtocol;
|
||||
import org.apache.hertzbeat.common.entity.job.protocol.EurekaSdProtocol;
|
||||
import org.apache.hertzbeat.common.entity.job.protocol.ConsulSdProtocol;
|
||||
import org.apache.hertzbeat.common.entity.job.protocol.ModbusProtocol;
|
||||
import org.apache.hertzbeat.common.entity.job.protocol.PlcProtocol;
|
||||
import org.apache.hertzbeat.common.entity.job.protocol.RegistryProtocol;
|
||||
@@ -63,7 +66,6 @@ import org.apache.hertzbeat.common.entity.job.protocol.TelnetProtocol;
|
||||
import org.apache.hertzbeat.common.entity.job.protocol.UdpProtocol;
|
||||
import org.apache.hertzbeat.common.entity.job.protocol.WebsocketProtocol;
|
||||
import org.apache.hertzbeat.common.entity.message.CollectRep;
|
||||
import org.apache.hertzbeat.common.entity.sd.ServiceDiscoveryProtocol;
|
||||
|
||||
/**
|
||||
* Details of the monitoring metrics collected
|
||||
@@ -74,6 +76,7 @@ import org.apache.hertzbeat.common.entity.sd.ServiceDiscoveryProtocol;
|
||||
@NoArgsConstructor
|
||||
@Builder
|
||||
@Slf4j
|
||||
@SuppressWarnings("checkstyle:MemberName")
|
||||
public class Metrics {
|
||||
|
||||
/**
|
||||
@@ -260,9 +263,21 @@ public class Metrics {
|
||||
*/
|
||||
private KafkaProtocol kclient;
|
||||
/**
|
||||
* Collect sd data protocol
|
||||
* http sd protocol
|
||||
*/
|
||||
private ServiceDiscoveryProtocol sdProtocol;
|
||||
private HttpProtocol http_sd;
|
||||
/**
|
||||
* dns sd protocol
|
||||
*/
|
||||
private DnsSdProtocol dns_sd;
|
||||
/**
|
||||
* eureka sd protocol
|
||||
*/
|
||||
private EurekaSdProtocol eureka_sd;
|
||||
/**
|
||||
* consul sd protocol
|
||||
*/
|
||||
private ConsulSdProtocol consul_sd;
|
||||
/**
|
||||
* Monitoring configuration information using the public plc protocol
|
||||
*/
|
||||
|
||||
+2
-1
@@ -21,7 +21,8 @@ package org.apache.hertzbeat.common.entity.job.protocol;
|
||||
* Define common field method for each protocol in {@link org.apache.hertzbeat.common.entity.job.Metrics}
|
||||
*/
|
||||
public interface CommonRequestProtocol {
|
||||
|
||||
void setHost(String host);
|
||||
|
||||
void setPort(String port);
|
||||
}
|
||||
}
|
||||
|
||||
+10
-35
@@ -15,53 +15,28 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.apache.hertzbeat.common.entity.sd;
|
||||
package org.apache.hertzbeat.common.entity.job.protocol;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Builder;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
/**
|
||||
* service discovery common field
|
||||
* consul sd protocol
|
||||
*/
|
||||
@Data
|
||||
@Builder
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
public class ServiceDiscoveryProtocol {
|
||||
private Long id;
|
||||
private List<Long> jobIdList;
|
||||
/**
|
||||
* sd type
|
||||
*/
|
||||
private Type type;
|
||||
/**
|
||||
* Target sd sources by which collector updates SDCache.
|
||||
*/
|
||||
private String sdSource;
|
||||
@NoArgsConstructor
|
||||
public class ConsulSdProtocol implements Protocol{
|
||||
|
||||
/**
|
||||
* sd Type
|
||||
*/
|
||||
public enum Type {
|
||||
HTTP_SD("httpsd"),
|
||||
;
|
||||
private String host;
|
||||
|
||||
private final String protocolName;
|
||||
private String port;
|
||||
|
||||
Type(String protocolName) {
|
||||
this.protocolName = protocolName;
|
||||
}
|
||||
|
||||
public static Type getType(String str) {
|
||||
return Arrays.stream(Type.values()).filter(t -> t.toString().equalsIgnoreCase(str)).findFirst().orElse(null);
|
||||
}
|
||||
|
||||
public String getProtocolName() {
|
||||
return protocolName;
|
||||
}
|
||||
public boolean isInvalid() {
|
||||
return StringUtils.isAnyBlank(host, port);
|
||||
}
|
||||
}
|
||||
}
|
||||
+41
@@ -0,0 +1,41 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.apache.hertzbeat.common.entity.job.protocol;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Builder;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
/**
|
||||
* Dns protocol
|
||||
*/
|
||||
@Data
|
||||
@Builder
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
public class DnsSdProtocol implements Protocol {
|
||||
|
||||
private String host;
|
||||
|
||||
private String port;
|
||||
|
||||
private String recordType;
|
||||
|
||||
private String recordName;
|
||||
}
|
||||
+6
-8
@@ -15,7 +15,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.apache.hertzbeat.common.entity.manager;
|
||||
package org.apache.hertzbeat.common.entity.job.protocol;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Builder;
|
||||
@@ -23,15 +23,13 @@ import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
/**
|
||||
* sd monitor param
|
||||
* eureka sd protocol
|
||||
*/
|
||||
@Data
|
||||
@Builder
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
public class SdMonitorParam {
|
||||
private String detectedHost;
|
||||
private String detectedPort;
|
||||
private Param sdParam;
|
||||
private Long bizId;
|
||||
}
|
||||
public class EurekaSdProtocol implements Protocol{
|
||||
|
||||
private String url;
|
||||
}
|
||||
+35
@@ -0,0 +1,35 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.apache.hertzbeat.common.entity.job.protocol;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Builder;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
/**
|
||||
* Dns protocol
|
||||
*/
|
||||
@Data
|
||||
@Builder
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
public class HttpSdProtocol implements Protocol {
|
||||
|
||||
private String url;
|
||||
}
|
||||
@@ -77,6 +77,10 @@ public class Monitor {
|
||||
@Size(max = 100)
|
||||
private String app;
|
||||
|
||||
@Schema(title = "Scrape type: static | http_sd | dns_sd", example = "static", accessMode = READ_WRITE)
|
||||
@Size(max = 100)
|
||||
private String scrape;
|
||||
|
||||
@Schema(title = "peer host: ipv4, ipv6, domain name", example = "192.167.25.11", accessMode = READ_WRITE)
|
||||
@Size(max = 100)
|
||||
@HostValid
|
||||
|
||||
+5
-10
@@ -17,7 +17,6 @@
|
||||
|
||||
package org.apache.hertzbeat.common.entity.manager;
|
||||
|
||||
import static io.swagger.v3.oas.annotations.media.Schema.AccessMode.READ_WRITE;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import jakarta.persistence.Column;
|
||||
import jakarta.persistence.Entity;
|
||||
@@ -27,8 +26,6 @@ import jakarta.persistence.GenerationType;
|
||||
import jakarta.persistence.Id;
|
||||
import jakarta.persistence.Index;
|
||||
import jakarta.persistence.Table;
|
||||
import jakarta.validation.constraints.Max;
|
||||
import jakarta.validation.constraints.Min;
|
||||
import java.time.LocalDateTime;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Builder;
|
||||
@@ -60,18 +57,16 @@ public class MonitorBind {
|
||||
@Schema(title = "primary id", example = "23")
|
||||
private Long id;
|
||||
|
||||
@Schema(title = "collector name", example = "87432674384")
|
||||
@Schema(title = "key string: ip:port")
|
||||
private String keyStr;
|
||||
|
||||
@Schema(title = "connect bind id", example = "87432674384")
|
||||
private Long bizId;
|
||||
|
||||
@Schema(title = "monitor ID", example = "87432674336")
|
||||
@Column(name = "monitor_id")
|
||||
private Long monitorId;
|
||||
|
||||
@Schema(title = "Bind type 0: sd", accessMode = READ_WRITE)
|
||||
@Min(0)
|
||||
@Max(3)
|
||||
private byte type;
|
||||
|
||||
@Schema(title = "The creator of this record", example = "tom")
|
||||
@CreatedBy
|
||||
private String creator;
|
||||
@@ -87,4 +82,4 @@ public class MonitorBind {
|
||||
@Schema(title = "Record the latest modification time (timestamp in milliseconds)")
|
||||
@LastModifiedDate
|
||||
private LocalDateTime gmtUpdate;
|
||||
}
|
||||
}
|
||||
|
||||
+2
-1
@@ -454,8 +454,9 @@ public final class CollectRep {
|
||||
return new MetricsData(new ArrowTable(root));
|
||||
} catch (Exception e1) {
|
||||
log.error(e1.getMessage(), e1);
|
||||
root.close();
|
||||
throw e1;
|
||||
} finally {
|
||||
root.close();
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.error(e.getMessage(), e);
|
||||
|
||||
+88
@@ -0,0 +1,88 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.apache.hertzbeat.common.entity.sd;
|
||||
|
||||
import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlElementWrapper;
|
||||
import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlProperty;
|
||||
import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlRootElement;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Builder;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* eureka service discovery entity
|
||||
*/
|
||||
@Data
|
||||
@Builder
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
@JacksonXmlRootElement(localName = "applications")
|
||||
public class EurekaDiscoveryResponseEntity {
|
||||
|
||||
@JacksonXmlProperty(localName = "versions__delta")
|
||||
private int versionsDelta;
|
||||
|
||||
@JacksonXmlProperty(localName = "apps__hashcode")
|
||||
private String appsHashcode;
|
||||
|
||||
@JacksonXmlElementWrapper(useWrapping = false)
|
||||
@JacksonXmlProperty(localName = "application")
|
||||
private List<Application> applications;
|
||||
|
||||
/**
|
||||
* eureka application entity
|
||||
*/
|
||||
@Data
|
||||
public static class Application {
|
||||
|
||||
@JacksonXmlProperty(localName = "name")
|
||||
private String name;
|
||||
|
||||
@JacksonXmlElementWrapper(useWrapping = false)
|
||||
@JacksonXmlProperty(localName = "instance")
|
||||
private List<Instance> instances;
|
||||
}
|
||||
|
||||
/**
|
||||
* eureka instance entity
|
||||
*/
|
||||
@Data
|
||||
public static class Instance {
|
||||
@JacksonXmlProperty(localName = "instanceId")
|
||||
private String instanceId;
|
||||
|
||||
@JacksonXmlProperty(localName = "hostName")
|
||||
private String hostName;
|
||||
|
||||
@JacksonXmlProperty(localName = "app")
|
||||
private String app;
|
||||
|
||||
@JacksonXmlProperty(localName = "ipAddr")
|
||||
private String ipAddr;
|
||||
|
||||
@JacksonXmlProperty(localName = "status")
|
||||
private String status;
|
||||
|
||||
@JacksonXmlProperty(localName = "port")
|
||||
private Integer port;
|
||||
|
||||
}
|
||||
}
|
||||
+6
-2
@@ -20,6 +20,7 @@ package org.apache.hertzbeat.common.support.valid;
|
||||
import jakarta.validation.ConstraintValidator;
|
||||
import jakarta.validation.ConstraintValidatorContext;
|
||||
import org.apache.hertzbeat.common.util.IpDomainUtil;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
/**
|
||||
* Host Param Validator
|
||||
@@ -33,10 +34,13 @@ public class HostParamValidator implements ConstraintValidator<HostValid, String
|
||||
|
||||
@Override
|
||||
public boolean isValid(String value, ConstraintValidatorContext context) {
|
||||
if (value != null && value.toLowerCase().contains(HTTP)){
|
||||
if (!StringUtils.hasText(value)) {
|
||||
return true;
|
||||
}
|
||||
if (value.toLowerCase().contains(HTTP)){
|
||||
value = value.replaceFirst(PATTERN_HTTP, BLANK);
|
||||
}
|
||||
if (value != null && value.toLowerCase().contains(HTTPS)){
|
||||
if (value.toLowerCase().contains(HTTPS)){
|
||||
value = value.replaceFirst(PATTERN_HTTPS, BLANK);
|
||||
}
|
||||
|
||||
|
||||
@@ -64,6 +64,7 @@ public final class ArrowUtil {
|
||||
writer.writeBatch();
|
||||
writer.end();
|
||||
writer.close();
|
||||
root.close();
|
||||
}
|
||||
return out.toByteArray();
|
||||
} catch (IOException e) {
|
||||
|
||||
-151
@@ -1,151 +0,0 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.apache.hertzbeat.common.util;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
import com.google.common.collect.Maps;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.Optional;
|
||||
import java.util.stream.Collectors;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.hertzbeat.common.constants.CommonConstants;
|
||||
import org.apache.hertzbeat.common.entity.job.Configmap;
|
||||
import org.apache.hertzbeat.common.entity.job.Job;
|
||||
import org.apache.hertzbeat.common.entity.job.Metrics;
|
||||
import org.apache.hertzbeat.common.entity.manager.MonitorBind;
|
||||
import org.apache.hertzbeat.common.entity.manager.Param;
|
||||
import org.apache.hertzbeat.common.entity.manager.SdMonitorParam;
|
||||
import org.apache.hertzbeat.common.entity.manager.Label;
|
||||
import org.apache.hertzbeat.common.entity.sd.ServiceDiscoveryProtocol;
|
||||
|
||||
/**
|
||||
* Operator for service discovery
|
||||
*/
|
||||
public class SdMonitorOperator {
|
||||
public static Optional<Param> getSdParam(List<Param> params) {
|
||||
return params.stream()
|
||||
.filter(param -> StringUtils.isNoneBlank(param.getField(), param.getParamValue()))
|
||||
.filter(param -> Objects.nonNull(ServiceDiscoveryProtocol.Type.getType(param.getField())))
|
||||
.findFirst();
|
||||
}
|
||||
|
||||
public static List<Param> removeSdParam(List<Param> params) {
|
||||
return params.stream()
|
||||
.filter(param -> Objects.isNull(ServiceDiscoveryProtocol.Type.getType(param.getField())))
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
public static List<Param> cloneParamList(List<Param> params) {
|
||||
return params.stream()
|
||||
.map(Param::clone)
|
||||
.peek(param -> param.setId(null))
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
public static MonitorBind buildSdSubMonitorBind(SdMonitorParam sdMonitorParam, long monitorId, Map<String, String> labels) {
|
||||
if (Objects.isNull(sdMonitorParam.getBizId())) {
|
||||
return null;
|
||||
}
|
||||
labels.put(CommonConstants.TAG_AUTO_CREATED, String.valueOf(sdMonitorParam.getBizId()));
|
||||
return MonitorBind.builder()
|
||||
.id(SnowFlakeIdGenerator.generateId())
|
||||
.bizId(sdMonitorParam.getBizId())
|
||||
.monitorId(monitorId)
|
||||
.type(CommonConstants.MONITOR_BIND_TYPE_SD_SUB_MONITOR)
|
||||
.build();
|
||||
}
|
||||
|
||||
public static MonitorBind buildSdMainMonitorBind(SdMonitorParam sdMonitorParam, long monitorId) {
|
||||
if (Objects.isNull(sdMonitorParam.getSdParam())) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return MonitorBind.builder()
|
||||
.id(SnowFlakeIdGenerator.generateId())
|
||||
.bizId(sdMonitorParam.getBizId())
|
||||
.monitorId(monitorId)
|
||||
.type(CommonConstants.MONITOR_BIND_TYPE_SD_MAIN_MONITOR)
|
||||
.build();
|
||||
}
|
||||
|
||||
public static Job constructSdJobAndTag(SdMonitorParam sdMonitorParam, Map<String, String> labels, Job appDefine) {
|
||||
if (Objects.isNull(sdMonitorParam.getSdParam())) {
|
||||
return appDefine;
|
||||
}
|
||||
labels.put(CommonConstants.TAG_SD_MAIN_MONITOR, ServiceDiscoveryProtocol.Type.getType(sdMonitorParam.getSdParam().getField()).name());
|
||||
return constructSdJob(appDefine, sdMonitorParam.getSdParam());
|
||||
}
|
||||
|
||||
public static Job constructSdJob(Job appDefine, Param sdParam) {
|
||||
final Job sdJob = appDefine.clone();
|
||||
final ServiceDiscoveryProtocol.Type sdType = ServiceDiscoveryProtocol.Type.getType(sdParam.getField());
|
||||
List<Metrics> metricsList = Lists.newArrayList();
|
||||
Map<String, String> i18n = Maps.newHashMap();
|
||||
i18n.put("zh-CN", "监控目标");
|
||||
i18n.put("en-US", "Monitor Target");
|
||||
List<Metrics.Field> fields = Lists.newArrayList();
|
||||
fields.add(Metrics.Field.builder()
|
||||
.field("host")
|
||||
.type(CommonConstants.TYPE_STRING)
|
||||
.i18n(constructSdFieldI18n("主机", "host"))
|
||||
.build());
|
||||
fields.add(Metrics.Field.builder()
|
||||
.field("port")
|
||||
.type(CommonConstants.TYPE_STRING)
|
||||
.i18n(constructSdFieldI18n("端口", "port"))
|
||||
.build());
|
||||
metricsList.add(Metrics.builder()
|
||||
.name("target")
|
||||
.fields(fields)
|
||||
.i18n(i18n)
|
||||
.protocol(sdType.getProtocolName())
|
||||
.sdProtocol(ServiceDiscoveryProtocol.builder()
|
||||
.sdSource(sdParam.getParamValue())
|
||||
.type(sdType)
|
||||
.build())
|
||||
.build());
|
||||
|
||||
sdJob.setSd(Boolean.TRUE);
|
||||
sdJob.setMetrics(metricsList);
|
||||
sdJob.setConfigmap(Lists.newArrayList(new Configmap(sdParam.getField(), sdParam.getParamValue(), sdParam.getType())));
|
||||
return sdJob;
|
||||
}
|
||||
|
||||
public static List<Label> addMainMonitorTag(List<Label> tagList, Param sdParam) {
|
||||
tagList = tagList.stream()
|
||||
.filter(tag -> !StringUtils.equals(tag.getName(), CommonConstants.TAG_SD_MAIN_MONITOR))
|
||||
.filter(tag -> !StringUtils.equals(tag.getName(), CommonConstants.TAG_AUTO_CREATED))
|
||||
.collect(Collectors.toList());
|
||||
|
||||
tagList.add(Label.builder().name(CommonConstants.TAG_SD_MAIN_MONITOR)
|
||||
.tagValue(ServiceDiscoveryProtocol.Type.getType(sdParam.getField()).name())
|
||||
.type(CommonConstants.TAG_TYPE_AUTO_GENERATE)
|
||||
.build());
|
||||
|
||||
return tagList;
|
||||
}
|
||||
|
||||
private static Map<String, String> constructSdFieldI18n(String zh, String en) {
|
||||
Map<String, String> i18n = Maps.newHashMap();
|
||||
i18n.put("zh-CN", zh);
|
||||
i18n.put("en-US", en);
|
||||
return i18n;
|
||||
}
|
||||
}
|
||||
@@ -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.common.util;
|
||||
|
||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||
import com.fasterxml.jackson.core.type.TypeReference;
|
||||
import com.fasterxml.jackson.databind.DeserializationFeature;
|
||||
import com.fasterxml.jackson.databind.SerializationFeature;
|
||||
import com.fasterxml.jackson.dataformat.xml.XmlMapper;
|
||||
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
/**
|
||||
* xml util
|
||||
*/
|
||||
@Slf4j
|
||||
public class XmlUtil {
|
||||
|
||||
private static final XmlMapper XML_MAPPER = new XmlMapper();
|
||||
|
||||
static {
|
||||
XML_MAPPER.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false)
|
||||
.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false)
|
||||
.registerModule(new JavaTimeModule());
|
||||
}
|
||||
|
||||
public String toXml(Object source) {
|
||||
if (source == null) {
|
||||
return null;
|
||||
}
|
||||
try {
|
||||
return XML_MAPPER.writeValueAsString(source);
|
||||
} catch (JsonProcessingException e) {
|
||||
log.error(e.getMessage(), e);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public static <T> T fromXml(String xml, Class<T> clazz) {
|
||||
if (!StringUtils.hasText(xml)) {
|
||||
return null;
|
||||
}
|
||||
try {
|
||||
return XML_MAPPER.readValue(xml, clazz);
|
||||
} catch (Exception e) {
|
||||
log.error(e.getMessage(), e);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public static <T> T fromXml(String xml, TypeReference<T> type) {
|
||||
if (!StringUtils.hasText(xml)) {
|
||||
return null;
|
||||
}
|
||||
try {
|
||||
return XML_MAPPER.readValue(xml, type);
|
||||
} catch (Exception e) {
|
||||
log.error(e.getMessage(), e);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
+3
-3
@@ -53,13 +53,13 @@ class HostParamValidatorTest {
|
||||
@Test
|
||||
public void testIsValid() {
|
||||
boolean result = hostParamValidator.isValid(null, context);
|
||||
assertFalse(result);
|
||||
assertTrue(result);
|
||||
|
||||
result = hostParamValidator.isValid("", context);
|
||||
assertFalse(result);
|
||||
assertTrue(result);
|
||||
|
||||
result = hostParamValidator.isValid(" ", context);
|
||||
assertFalse(result);
|
||||
assertTrue(result);
|
||||
|
||||
result = hostParamValidator.isValid("192.168.1.1", context);
|
||||
assertTrue(result);
|
||||
|
||||
@@ -1,117 +0,0 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
*/
|
||||
|
||||
package org.apache.hertzbeat.log.config;
|
||||
|
||||
import static io.opentelemetry.semconv.ServiceAttributes.SERVICE_NAME;
|
||||
import io.opentelemetry.api.OpenTelemetry;
|
||||
import io.opentelemetry.exporter.otlp.http.logs.OtlpHttpLogRecordExporter;
|
||||
import io.opentelemetry.instrumentation.logback.appender.v1_0.OpenTelemetryAppender;
|
||||
import io.opentelemetry.sdk.OpenTelemetrySdk;
|
||||
import io.opentelemetry.sdk.logs.SdkLoggerProvider;
|
||||
import io.opentelemetry.sdk.logs.export.BatchLogRecordProcessor;
|
||||
import io.opentelemetry.sdk.resources.Resource;
|
||||
|
||||
import jakarta.annotation.PostConstruct;
|
||||
import java.util.Base64;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.hertzbeat.warehouse.store.history.greptime.GreptimeProperties;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
/**
|
||||
* OpenTelemetryConfig is responsible for initializing OpenTelemetry with the specified service name and GrepTimeDB endpoint.
|
||||
* It ensures that the initialization is done in a thread-safe manner and includes authentication for GrepTimeDB.
|
||||
*/
|
||||
@Configuration
|
||||
@Slf4j
|
||||
public class OpenTelemetryConfig {
|
||||
|
||||
@Autowired
|
||||
private GreptimeProperties greptimeProperties;
|
||||
|
||||
/**
|
||||
* Initializes OpenTelemetry with the given service name and GrepTimeDB endpoint.
|
||||
* Includes authentication if configured in GreptimeProperties.
|
||||
*/
|
||||
@PostConstruct
|
||||
public void initializeOpenTelemetry() {
|
||||
if (greptimeProperties == null || !greptimeProperties.enabled()) {
|
||||
log.info("GrepTimeDB logging is disabled, skipping OpenTelemetry configuration.");
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
Resource resource = Resource.getDefault()
|
||||
.merge(Resource.builder()
|
||||
.put(SERVICE_NAME, "HertzBeat")
|
||||
.build());
|
||||
|
||||
Map<String, String> headers = new HashMap<>();
|
||||
|
||||
headers.put("X-Greptime-DB-Name", "public");
|
||||
headers.put("X-Greptime-Log-Table-Name", "hzb_log");
|
||||
|
||||
addAuthenticationHeaders(headers);
|
||||
|
||||
OtlpHttpLogRecordExporter logExporter = OtlpHttpLogRecordExporter.builder()
|
||||
.setEndpoint(greptimeProperties.httpEndpoint() + "/v1/otlp/v1/logs")
|
||||
.setHeaders(()-> headers)
|
||||
.setTimeout(10, TimeUnit.SECONDS)
|
||||
.build();
|
||||
|
||||
SdkLoggerProvider loggerProvider = SdkLoggerProvider.builder()
|
||||
.setResource(resource)
|
||||
.addLogRecordProcessor(
|
||||
BatchLogRecordProcessor.builder(logExporter)
|
||||
.setScheduleDelay(1000, TimeUnit.MILLISECONDS)
|
||||
.setMaxExportBatchSize(512)
|
||||
.build())
|
||||
.build();
|
||||
|
||||
OpenTelemetry openTelemetry = OpenTelemetrySdk.builder()
|
||||
.setLoggerProvider(loggerProvider)
|
||||
.build();
|
||||
|
||||
OpenTelemetryAppender.install(openTelemetry);
|
||||
log.info("OpenTelemetry successfully configured with GrepTimeDB exporter.");
|
||||
} catch (Exception e) {
|
||||
log.error("Failed to initialize OpenTelemetry with GrepTimeDB", e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds authentication headers to the provided map if username and password are configured.
|
||||
*
|
||||
* @param headers the map to which authentication headers will be added
|
||||
*/
|
||||
private void addAuthenticationHeaders(Map<String, String> headers) {
|
||||
if (StringUtils.isNotBlank(greptimeProperties.username())
|
||||
&& StringUtils.isNotBlank(greptimeProperties.password())) {
|
||||
String credentials = greptimeProperties.username() + ":" + greptimeProperties.password();
|
||||
String encodedCredentials = Base64.getEncoder().encodeToString(credentials.getBytes());
|
||||
headers.put("Authorization", "Basic " + encodedCredentials);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -47,7 +47,7 @@
|
||||
<dependency>
|
||||
<groupId>org.apache.hertzbeat</groupId>
|
||||
<artifactId>hertzbeat-base</artifactId>
|
||||
</dependency>
|
||||
</dependency>
|
||||
<!-- data warehouse -->
|
||||
<dependency>
|
||||
<groupId>org.apache.hertzbeat</groupId>
|
||||
@@ -92,7 +92,7 @@
|
||||
<!-- log -->
|
||||
<dependency>
|
||||
<groupId>org.apache.hertzbeat</groupId>
|
||||
<artifactId>hertzbeat-log</artifactId>
|
||||
<artifactId>hertzbeat-otel</artifactId>
|
||||
</dependency>
|
||||
<!-- spring -->
|
||||
<dependency>
|
||||
@@ -409,5 +409,5 @@
|
||||
</build>
|
||||
</profile>
|
||||
</profiles>
|
||||
|
||||
|
||||
</project>
|
||||
|
||||
+63
-60
@@ -18,25 +18,22 @@
|
||||
package org.apache.hertzbeat.manager.component.sd;
|
||||
|
||||
import com.google.common.collect.Maps;
|
||||
import com.google.common.collect.Sets;
|
||||
import java.util.HashSet;
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.hertzbeat.common.constants.CommonConstants;
|
||||
import org.apache.hertzbeat.common.entity.arrow.RowWrapper;
|
||||
import org.apache.hertzbeat.common.entity.manager.CollectorMonitorBind;
|
||||
import org.apache.hertzbeat.common.entity.manager.Monitor;
|
||||
import org.apache.hertzbeat.common.entity.manager.MonitorBind;
|
||||
import org.apache.hertzbeat.common.entity.manager.Param;
|
||||
import org.apache.hertzbeat.common.entity.manager.SdMonitorParam;
|
||||
import org.apache.hertzbeat.common.entity.message.CollectRep;
|
||||
import org.apache.hertzbeat.common.queue.CommonDataQueue;
|
||||
import org.apache.hertzbeat.common.util.SdMonitorOperator;
|
||||
import org.apache.hertzbeat.manager.dao.CollectorMonitorBindDao;
|
||||
import org.apache.hertzbeat.manager.dao.MonitorBindDao;
|
||||
import org.apache.hertzbeat.manager.dao.MonitorDao;
|
||||
@@ -45,7 +42,6 @@ import org.apache.hertzbeat.manager.scheduler.ManagerWorkerPool;
|
||||
import org.apache.hertzbeat.manager.service.MonitorService;
|
||||
import org.springframework.beans.factory.InitializingBean;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
|
||||
/**
|
||||
* Service Discovery Worker
|
||||
@@ -53,6 +49,9 @@ import org.springframework.util.CollectionUtils;
|
||||
@Slf4j
|
||||
@Component
|
||||
public class ServiceDiscoveryWorker implements InitializingBean {
|
||||
|
||||
private static final String FILED_HOST = "host";
|
||||
private static final String FILED_PORT = "port";
|
||||
private final MonitorService monitorService;
|
||||
private final ParamDao paramDao;
|
||||
private final MonitorDao monitorDao;
|
||||
@@ -83,74 +82,78 @@ public class ServiceDiscoveryWorker implements InitializingBean {
|
||||
public void run() {
|
||||
while (!Thread.currentThread().isInterrupted()) {
|
||||
try (final CollectRep.MetricsData metricsData = dataQueue.pollServiceDiscoveryData()) {
|
||||
|
||||
Long monitorId = metricsData.getId();
|
||||
final Monitor mainMonitor = monitorDao.findMonitorsByIdIn(Sets.newHashSet(monitorId)).get(0);
|
||||
mainMonitor.getLabels().remove(CommonConstants.TAG_SD_MAIN_MONITOR);
|
||||
final Monitor mainMonitor = monitorDao.findById(monitorId).orElse(null);
|
||||
if (mainMonitor == null) {
|
||||
log.warn("No monitor found for id {}", monitorId);
|
||||
continue;
|
||||
}
|
||||
// collector
|
||||
final Optional<CollectorMonitorBind> collectorBind = collectorMonitorBindDao.findCollectorMonitorBindByMonitorId(mainMonitor.getId());
|
||||
final Optional<CollectorMonitorBind> collectorBind = collectorMonitorBindDao.findCollectorMonitorBindByMonitorId(monitorId);
|
||||
String collector = collectorBind.map(CollectorMonitorBind::getCollector).orElse(null);
|
||||
// param
|
||||
List<Param> mainMonitorParamList = paramDao.findParamsByMonitorId(mainMonitor.getId());
|
||||
mainMonitorParamList = SdMonitorOperator.removeSdParam(mainMonitorParamList);
|
||||
|
||||
final Set<Long> subMonitorIdSet = monitorBindDao.findMonitorBindByBizIdAndType(monitorId, CommonConstants.MONITOR_BIND_TYPE_SD_SUB_MONITOR)
|
||||
.stream()
|
||||
.map(MonitorBind::getMonitorId)
|
||||
.collect(Collectors.toSet());
|
||||
final Map<String, List<Monitor>> hostMonitorMap = CollectionUtils.isEmpty(subMonitorIdSet)
|
||||
? Maps.newHashMap()
|
||||
: monitorDao.findMonitorsByIdIn(subMonitorIdSet).stream().collect(Collectors.groupingBy(Monitor::getHost));
|
||||
|
||||
// params
|
||||
List<Param> mainMonitorParams = paramDao.findParamsByMonitorId(monitorId);
|
||||
final Map<String, MonitorBind> subMonitorBindMap = monitorBindDao.findMonitorBindsByBizId(monitorId)
|
||||
.stream().collect(Collectors.toMap(MonitorBind::getKeyStr, item -> item));
|
||||
RowWrapper rowWrapper = metricsData.readRow();
|
||||
|
||||
Map<String, String> fieldsValue = Maps.newHashMapWithExpectedSize(8);
|
||||
String defaultPort = mainMonitorParams.stream()
|
||||
.filter(param -> FILED_PORT.equals(param.getField()))
|
||||
.findFirst()
|
||||
.map(Param::getParamValue)
|
||||
.orElse("");
|
||||
while (rowWrapper.hasNextRow()) {
|
||||
rowWrapper = rowWrapper.nextRow();
|
||||
|
||||
|
||||
final String host = rowWrapper.nextCell().getValue();
|
||||
final String port = rowWrapper.nextCell().getValue();
|
||||
final List<Monitor> monitorList = hostMonitorMap.get(host);
|
||||
if (CollectionUtils.isEmpty(monitorList)) {
|
||||
monitorService.addAndSaveMonitorJob(mainMonitor.clone(), SdMonitorOperator.cloneParamList(mainMonitorParamList), collector,
|
||||
SdMonitorParam.builder()
|
||||
.detectedHost(host)
|
||||
.detectedPort(port)
|
||||
.bizId(mainMonitor.getId())
|
||||
.build(), null);
|
||||
return;
|
||||
fieldsValue.clear();
|
||||
rowWrapper.cellStream().forEach(cell -> {
|
||||
String value = cell.getValue();
|
||||
fieldsValue.put(cell.getField().getName(), value);
|
||||
});
|
||||
final String host = fieldsValue.get(FILED_HOST);
|
||||
final String port = fieldsValue.getOrDefault(FILED_PORT, defaultPort);
|
||||
final String keyStr = host + ":" + port;
|
||||
if (subMonitorBindMap.containsKey(keyStr)) {
|
||||
subMonitorBindMap.remove(keyStr);
|
||||
continue;
|
||||
}
|
||||
|
||||
for (Monitor monitor : monitorList) {
|
||||
// make sure monitor that has the same host and port is not existed.
|
||||
final Optional<Param> samePortParam = paramDao.findParamsByMonitorId(monitor.getId()).stream()
|
||||
.filter(param -> StringUtils.equals(param.getField(), "port"))
|
||||
.filter(param -> StringUtils.equals(param.getParamValue(), port))
|
||||
.findFirst();
|
||||
if (samePortParam.isEmpty()) {
|
||||
monitorService.addAndSaveMonitorJob(mainMonitor.clone(), SdMonitorOperator.cloneParamList(mainMonitorParamList), collector,
|
||||
SdMonitorParam.builder()
|
||||
.detectedHost(host)
|
||||
.detectedPort(port)
|
||||
.bizId(mainMonitor.getId())
|
||||
.build(), null);
|
||||
} else {
|
||||
monitorService.enableManageMonitors(Sets.newHashSet(monitor.getId()));
|
||||
Monitor newMonitor = mainMonitor.clone();
|
||||
newMonitor.setId(null);
|
||||
newMonitor.setHost(host);
|
||||
newMonitor.setName(newMonitor.getName() + "-" + host + ":" + port);
|
||||
newMonitor.setScrape(CommonConstants.SCRAPE_STATIC);
|
||||
newMonitor.setGmtCreate(LocalDateTime.now());
|
||||
newMonitor.setGmtUpdate(LocalDateTime.now());
|
||||
// replace host port
|
||||
List<Param> newParams = new LinkedList<>();
|
||||
for (Param param : mainMonitorParams) {
|
||||
Param newParam = param.clone();
|
||||
newParam.setId(null);
|
||||
newParam.setGmtUpdate(null);
|
||||
newParam.setGmtCreate(null);
|
||||
if (FILED_HOST.equals(newParam.getField())) {
|
||||
newParam.setParamValue(host);
|
||||
} else if (FILED_PORT.equals(newParam.getField())) {
|
||||
newParam.setParamValue(port);
|
||||
}
|
||||
newParams.add(newParam);
|
||||
}
|
||||
|
||||
// make sure hostMonitorMap contains monitors that have not judged yet.
|
||||
hostMonitorMap.remove(host);
|
||||
monitorService.addMonitor(newMonitor, newParams, collector, null);
|
||||
MonitorBind monitorBind = MonitorBind.builder()
|
||||
.bizId(monitorId)
|
||||
.monitorId(newMonitor.getId())
|
||||
.keyStr(keyStr)
|
||||
.build();
|
||||
monitorBindDao.save(monitorBind);
|
||||
}
|
||||
|
||||
// hostMonitorMap only contains monitors which are already existed but not in service discovery data
|
||||
// due to monitors that coincide with service discovery data are removed.
|
||||
// Thus, all monitors still in hostMonitorMap need to be cancelled.
|
||||
final HashSet<Long> needCancelMonitorIdSet = Sets.newHashSet();
|
||||
hostMonitorMap.forEach((key, value) -> needCancelMonitorIdSet.addAll(value.stream()
|
||||
.map(Monitor::getId)
|
||||
.collect(Collectors.toSet())));
|
||||
final Set<Long> needCancelMonitorIdSet = subMonitorBindMap.values().stream()
|
||||
.map(MonitorBind::getMonitorId).collect(Collectors.toSet());
|
||||
monitorService.cancelManageMonitors(needCancelMonitorIdSet);
|
||||
for (Long id : needCancelMonitorIdSet) {
|
||||
monitorBindDao.deleteMonitorBindByBizIdAndMonitorId(monitorId, id);
|
||||
}
|
||||
} catch (Exception exception) {
|
||||
log.error(exception.getMessage(), exception);
|
||||
}
|
||||
|
||||
+1
-1
@@ -35,7 +35,7 @@ import org.springframework.http.converter.json.Jackson2ObjectMapperBuilder;
|
||||
public class JacksonConfig {
|
||||
|
||||
@Bean
|
||||
public Jackson2ObjectMapperBuilderCustomizer customizer() {
|
||||
public Jackson2ObjectMapperBuilderCustomizer jacksonCustomizer() {
|
||||
return builder -> {
|
||||
JavaTimeModule javaTimeModule = new JavaTimeModule();
|
||||
final SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSX");
|
||||
|
||||
-12
@@ -127,16 +127,4 @@ public class MonitorsController {
|
||||
monitorService.importConfig(file);
|
||||
return ResponseEntity.ok(Message.success("Import success"));
|
||||
}
|
||||
|
||||
|
||||
@PostMapping("/copy")
|
||||
@Operation(summary = "copy monitors by ids", description = "copy monitors by ids")
|
||||
public ResponseEntity<Message<Void>> duplicateMonitors(
|
||||
@Parameter(description = "Monitor ID List", example = "6565463543") @RequestParam List<Long> ids
|
||||
) {
|
||||
if (ids != null && !ids.isEmpty()) {
|
||||
monitorService.copyMonitors(ids);
|
||||
}
|
||||
return ResponseEntity.ok(Message.success("copy success"));
|
||||
}
|
||||
}
|
||||
|
||||
+9
-9
@@ -18,22 +18,22 @@
|
||||
package org.apache.hertzbeat.manager.dao;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import org.apache.hertzbeat.common.entity.manager.MonitorBind;
|
||||
import org.springframework.data.jpa.repository.JpaRepository;
|
||||
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
|
||||
import org.springframework.data.jpa.repository.Modifying;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
/**
|
||||
* AuthResources database operation
|
||||
* MonitorBind database operation
|
||||
*/
|
||||
public interface MonitorBindDao extends JpaRepository<MonitorBind, Long>, JpaSpecificationExecutor<MonitorBind> {
|
||||
List<MonitorBind> findAllByBizIdInAndType(Set<Long> bizIdList, byte type);
|
||||
|
||||
List<MonitorBind> findMonitorBindByBizIdAndType(Long bizId, byte type);
|
||||
|
||||
MonitorBind findMonitorBindByBizIdAndMonitorIdAndType(Long bizId, Long monitorId, byte type);
|
||||
|
||||
List<MonitorBind> findAllByType(byte type);
|
||||
List<MonitorBind> findMonitorBindsByBizId(Long bizId);
|
||||
|
||||
void deleteByMonitorId(Long monitorId);
|
||||
}
|
||||
|
||||
@Modifying
|
||||
@Transactional
|
||||
void deleteMonitorBindByBizIdAndMonitorId(Long bizId, Long monitorId);
|
||||
}
|
||||
|
||||
+2
-2
@@ -36,12 +36,12 @@ import org.apache.hertzbeat.common.entity.manager.Param;
|
||||
@Schema(description = "Monitoring information entities")
|
||||
public class MonitorDto {
|
||||
|
||||
@Schema(description = "Monitor Content", accessMode = READ_WRITE)
|
||||
@Schema(description = "monitor content", accessMode = READ_WRITE)
|
||||
@NotNull
|
||||
@Valid
|
||||
private Monitor monitor;
|
||||
|
||||
@Schema(description = "Monitor Params", accessMode = READ_WRITE)
|
||||
@Schema(description = "monitor params", accessMode = READ_WRITE)
|
||||
@NotEmpty
|
||||
@Valid
|
||||
private List<Param> params;
|
||||
|
||||
+8
-17
@@ -19,10 +19,8 @@ package org.apache.hertzbeat.manager.scheduler;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.hertzbeat.common.constants.CommonConstants;
|
||||
import org.apache.hertzbeat.common.entity.dto.CollectorInfo;
|
||||
import org.apache.hertzbeat.common.entity.job.Configmap;
|
||||
@@ -30,13 +28,10 @@ import org.apache.hertzbeat.common.entity.job.Job;
|
||||
import org.apache.hertzbeat.common.entity.manager.Collector;
|
||||
import org.apache.hertzbeat.common.entity.manager.CollectorMonitorBind;
|
||||
import org.apache.hertzbeat.common.entity.manager.Monitor;
|
||||
import org.apache.hertzbeat.common.entity.manager.MonitorBind;
|
||||
import org.apache.hertzbeat.common.entity.manager.Param;
|
||||
import org.apache.hertzbeat.common.entity.manager.ParamDefine;
|
||||
import org.apache.hertzbeat.common.util.SdMonitorOperator;
|
||||
import org.apache.hertzbeat.manager.dao.CollectorDao;
|
||||
import org.apache.hertzbeat.manager.dao.CollectorMonitorBindDao;
|
||||
import org.apache.hertzbeat.manager.dao.MonitorBindDao;
|
||||
import org.apache.hertzbeat.manager.dao.MonitorDao;
|
||||
import org.apache.hertzbeat.manager.dao.ParamDao;
|
||||
import org.apache.hertzbeat.manager.service.AppService;
|
||||
@@ -45,6 +40,7 @@ import org.springframework.boot.CommandLineRunner;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.core.Ordered;
|
||||
import org.springframework.core.annotation.Order;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
/**
|
||||
* scheduler init
|
||||
@@ -77,9 +73,6 @@ public class SchedulerInit implements CommandLineRunner {
|
||||
|
||||
@Autowired
|
||||
private CollectorMonitorBindDao collectorMonitorBindDao;
|
||||
|
||||
@Autowired
|
||||
private MonitorBindDao monitorBindDao;
|
||||
|
||||
@Override
|
||||
public void run(String... args) throws Exception {
|
||||
@@ -98,20 +91,18 @@ public class SchedulerInit implements CommandLineRunner {
|
||||
// init jobs
|
||||
List<Monitor> monitors = monitorDao.findMonitorsByStatusNotInAndJobIdNotNull(List.of(CommonConstants.MONITOR_PAUSED_CODE));
|
||||
List<CollectorMonitorBind> monitorBinds = collectorMonitorBindDao.findAll();
|
||||
final Set<Long> sdMonitorIds = monitorBindDao.findAllByType(CommonConstants.MONITOR_BIND_TYPE_SD_SUB_MONITOR).stream()
|
||||
.map(MonitorBind::getBizId)
|
||||
.collect(Collectors.toSet());
|
||||
Map<Long, String> monitorIdCollectorMap = monitorBinds.stream().collect(
|
||||
Collectors.toMap(CollectorMonitorBind::getMonitorId, CollectorMonitorBind::getCollector));
|
||||
for (Monitor monitor : monitors) {
|
||||
try {
|
||||
// build collect job entity
|
||||
Job appDefine = appService.getAppDefine(monitor.getApp());
|
||||
List<Param> params = paramDao.findParamsByMonitorId(monitor.getId());
|
||||
if (sdMonitorIds.contains(monitor.getId())) {
|
||||
appDefine = SdMonitorOperator.constructSdJob(appDefine, SdMonitorOperator.getSdParam(params).get());
|
||||
boolean isStatic = CommonConstants.SCRAPE_STATIC.equals(monitor.getScrape()) || !StringUtils.hasText(monitor.getScrape());
|
||||
String app = isStatic ? monitor.getApp() : monitor.getScrape();
|
||||
Job appDefine = appService.getAppDefine(app);
|
||||
if (!isStatic) {
|
||||
appDefine.setSd(true);
|
||||
}
|
||||
|
||||
List<Param> params = paramDao.findParamsByMonitorId(monitor.getId());
|
||||
if (CommonConstants.PROMETHEUS.equals(monitor.getApp())) {
|
||||
appDefine.setApp(CommonConstants.PROMETHEUS_APP_PREFIX + monitor.getName());
|
||||
}
|
||||
@@ -129,7 +120,7 @@ public class SchedulerInit implements CommandLineRunner {
|
||||
.map(param -> new Configmap(param.getField(), param.getParamValue(),
|
||||
param.getType())).collect(Collectors.toList());
|
||||
List<ParamDefine> paramDefaultValue = appDefine.getParams().stream()
|
||||
.filter(item -> StringUtils.isNotBlank(item.getDefaultValue()))
|
||||
.filter(item -> StringUtils.hasText(item.getDefaultValue()))
|
||||
.toList();
|
||||
paramDefaultValue.forEach(defaultVar -> {
|
||||
if (configmaps.stream().noneMatch(item -> item.getKey().equals(defaultVar.getField()))) {
|
||||
|
||||
+11
@@ -18,6 +18,10 @@
|
||||
package org.apache.hertzbeat.manager.service;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import org.apache.hertzbeat.common.entity.manager.Label;
|
||||
import org.springframework.data.domain.Page;
|
||||
|
||||
@@ -53,4 +57,11 @@ public interface LabelService {
|
||||
* @param ids label id list
|
||||
*/
|
||||
void deleteLabels(HashSet<Long> ids);
|
||||
|
||||
/**
|
||||
* Identifies new labels from the given entry that are not yet in the database
|
||||
* @param originLabels k-v entry
|
||||
* @return new labels
|
||||
*/
|
||||
List<Label> determineNewLabels(Set<Map.Entry<String, String>> originLabels);
|
||||
}
|
||||
|
||||
+3
-14
@@ -22,14 +22,12 @@ import org.apache.hertzbeat.common.entity.grafana.GrafanaDashboard;
|
||||
import org.apache.hertzbeat.common.entity.job.Job;
|
||||
import org.apache.hertzbeat.common.entity.manager.Monitor;
|
||||
import org.apache.hertzbeat.common.entity.manager.Param;
|
||||
import org.apache.hertzbeat.common.entity.manager.SdMonitorParam;
|
||||
import org.apache.hertzbeat.manager.pojo.dto.AppCount;
|
||||
import org.apache.hertzbeat.manager.pojo.dto.MonitorDto;
|
||||
import org.apache.hertzbeat.manager.support.exception.MonitorDetectException;
|
||||
import org.springframework.data.domain.Page;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
@@ -125,14 +123,14 @@ public interface MonitorService {
|
||||
*
|
||||
* @param ids Monitoring ID List
|
||||
*/
|
||||
void cancelManageMonitors(HashSet<Long> ids);
|
||||
void cancelManageMonitors(Set<Long> ids);
|
||||
|
||||
/**
|
||||
* Start the managed monitoring items in batches according to the monitoring ID list
|
||||
*
|
||||
* @param ids Monitoring ID List
|
||||
*/
|
||||
void enableManageMonitors(HashSet<Long> ids);
|
||||
void enableManageMonitors(Set<Long> ids);
|
||||
|
||||
/**
|
||||
* Query the monitoring category and its corresponding monitoring quantity
|
||||
@@ -183,22 +181,13 @@ public interface MonitorService {
|
||||
*/
|
||||
void importConfig(MultipartFile file) throws Exception;
|
||||
|
||||
/**
|
||||
* Copy monitor in batches based on the id
|
||||
*
|
||||
* @param ids monitor id
|
||||
*/
|
||||
void copyMonitors(List<Long> ids);
|
||||
|
||||
/**
|
||||
* update app collect job by app
|
||||
*
|
||||
* @param job job content
|
||||
*/
|
||||
void updateAppCollectJob(Job job);
|
||||
|
||||
void addAndSaveMonitorJob(Monitor monitor, List<Param> params, String collector, SdMonitorParam sdMonitorParam, GrafanaDashboard grafanaDashboard);
|
||||
|
||||
|
||||
/**
|
||||
* Copy monitor by id
|
||||
*
|
||||
|
||||
-4
@@ -270,10 +270,6 @@ public class AppServiceImpl implements AppService, InitializingBean {
|
||||
public List<Hierarchy> getAllAppHierarchy(String lang) {
|
||||
LinkedList<Hierarchy> hierarchies = new LinkedList<>();
|
||||
for (var job : appDefines.values()) {
|
||||
// TODO temporarily filter out push to solve the front-end problem, and open it after the subsequent design optimization
|
||||
if (DispatchConstants.PROTOCOL_PUSH.equalsIgnoreCase(job.getApp())) {
|
||||
continue;
|
||||
}
|
||||
queryAppHierarchy(lang, hierarchies, job);
|
||||
}
|
||||
return hierarchies;
|
||||
|
||||
+28
@@ -22,7 +22,11 @@ import jakarta.persistence.criteria.Predicate;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.collections.CollectionUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
@@ -117,4 +121,28 @@ public class LabelServiceImpl implements LabelService {
|
||||
}
|
||||
labelDao.deleteLabelsByIdIn(ids);
|
||||
}
|
||||
|
||||
public List<Label> determineNewLabels(Set<Map.Entry<String, String>> originLabels){
|
||||
|
||||
if (originLabels == null || originLabels.isEmpty()) return List.of();
|
||||
|
||||
// Get all labels from the database
|
||||
Set<Map.Entry<String, String>> allLabels = labelDao.findAll().stream()
|
||||
.map(label -> Map.entry(label.getName(), label.getTagValue()))
|
||||
.collect(Collectors.toSet());
|
||||
|
||||
// If the bound label (key:value) does not exist, then add it
|
||||
Set<Map.Entry<String, String>> addLabelsKv = originLabels.stream()
|
||||
.filter(label -> !allLabels.contains(label))
|
||||
.collect(Collectors.toCollection(HashSet::new));
|
||||
|
||||
return addLabelsKv.stream().map(kv -> {
|
||||
Label label = new Label();
|
||||
label.setId(null);
|
||||
label.setName(kv.getKey());
|
||||
label.setTagValue(kv.getValue());
|
||||
label.setType((byte) 0);
|
||||
return label;
|
||||
}).toList();
|
||||
}
|
||||
}
|
||||
|
||||
+147
-326
@@ -23,7 +23,6 @@ import jakarta.persistence.criteria.CriteriaBuilder;
|
||||
import jakarta.persistence.criteria.Predicate;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.hertzbeat.alert.dao.AlertDefineBindDao;
|
||||
import org.apache.hertzbeat.collector.dispatch.DispatchConstants;
|
||||
import org.apache.hertzbeat.common.constants.CommonConstants;
|
||||
@@ -34,28 +33,26 @@ import org.apache.hertzbeat.common.entity.grafana.GrafanaDashboard;
|
||||
import org.apache.hertzbeat.common.entity.job.Configmap;
|
||||
import org.apache.hertzbeat.common.entity.job.Job;
|
||||
import org.apache.hertzbeat.common.entity.job.Metrics;
|
||||
import org.apache.hertzbeat.common.entity.job.protocol.CommonRequestProtocol;
|
||||
import org.apache.hertzbeat.common.entity.manager.Collector;
|
||||
import org.apache.hertzbeat.common.entity.manager.CollectorMonitorBind;
|
||||
import org.apache.hertzbeat.common.entity.manager.Label;
|
||||
import org.apache.hertzbeat.common.entity.manager.Monitor;
|
||||
import org.apache.hertzbeat.common.entity.manager.MonitorBind;
|
||||
import org.apache.hertzbeat.common.entity.manager.Param;
|
||||
import org.apache.hertzbeat.common.entity.manager.ParamDefine;
|
||||
import org.apache.hertzbeat.common.entity.manager.SdMonitorParam;
|
||||
import org.apache.hertzbeat.common.entity.message.CollectRep;
|
||||
import org.apache.hertzbeat.common.entity.sd.ServiceDiscoveryProtocol;
|
||||
import org.apache.hertzbeat.common.support.event.MonitorDeletedEvent;
|
||||
import org.apache.hertzbeat.common.util.AesUtil;
|
||||
import org.apache.hertzbeat.common.util.CommonUtil;
|
||||
import org.apache.hertzbeat.common.util.FileUtil;
|
||||
import org.apache.hertzbeat.common.util.IntervalExpressionUtil;
|
||||
import org.apache.hertzbeat.common.util.IpDomainUtil;
|
||||
import org.apache.hertzbeat.common.util.JsonUtil;
|
||||
import org.apache.hertzbeat.common.util.SdMonitorOperator;
|
||||
import org.apache.hertzbeat.common.util.SnowFlakeIdGenerator;
|
||||
import org.apache.hertzbeat.grafana.service.DashboardService;
|
||||
import org.apache.hertzbeat.manager.config.ManagerSseManager;
|
||||
import org.apache.hertzbeat.manager.dao.CollectorDao;
|
||||
import org.apache.hertzbeat.manager.dao.CollectorMonitorBindDao;
|
||||
import org.apache.hertzbeat.manager.dao.LabelDao;
|
||||
import org.apache.hertzbeat.manager.dao.MonitorBindDao;
|
||||
import org.apache.hertzbeat.manager.dao.MonitorDao;
|
||||
import org.apache.hertzbeat.manager.dao.ParamDao;
|
||||
@@ -64,8 +61,8 @@ import org.apache.hertzbeat.manager.pojo.dto.MonitorDto;
|
||||
import org.apache.hertzbeat.manager.scheduler.CollectJobScheduling;
|
||||
import org.apache.hertzbeat.manager.service.AppService;
|
||||
import org.apache.hertzbeat.manager.service.ImExportService;
|
||||
import org.apache.hertzbeat.manager.service.MonitorService;
|
||||
import org.apache.hertzbeat.manager.service.LabelService;
|
||||
import org.apache.hertzbeat.manager.service.MonitorService;
|
||||
import org.apache.hertzbeat.manager.support.exception.MonitorDatabaseException;
|
||||
import org.apache.hertzbeat.manager.support.exception.MonitorDetectException;
|
||||
import org.apache.hertzbeat.warehouse.service.WarehouseService;
|
||||
@@ -81,15 +78,14 @@ import org.springframework.http.MediaType;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
import org.springframework.util.StringUtils;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
import java.net.URLEncoder;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
@@ -109,15 +105,11 @@ public class MonitorServiceImpl implements MonitorService {
|
||||
private static final Long MONITOR_ID_TMP = 1000000000L;
|
||||
private static final byte ALL_MONITOR_STATUS = 9;
|
||||
|
||||
private static final int TAG_LENGTH = 2;
|
||||
|
||||
private static final String CONTENT_VALUE = MediaType.APPLICATION_OCTET_STREAM_VALUE + SignConstants.SINGLE_MARK + "charset=" + StandardCharsets.UTF_8;
|
||||
private final Map<String, ImExportService> imExportServiceMap = new HashMap<>();
|
||||
@Autowired
|
||||
private AppService appService;
|
||||
@Autowired
|
||||
private LabelService tagService;
|
||||
@Autowired
|
||||
private CollectJobScheduling collectJobScheduling;
|
||||
@Autowired
|
||||
private MonitorDao monitorDao;
|
||||
@@ -139,6 +131,10 @@ public class MonitorServiceImpl implements MonitorService {
|
||||
private DashboardService dashboardService;
|
||||
@Autowired
|
||||
private ManagerSseManager managerSseManager;
|
||||
@Autowired
|
||||
private LabelDao labelDao;
|
||||
@Autowired
|
||||
private LabelService labelService;
|
||||
|
||||
public MonitorServiceImpl(List<ImExportService> imExportServiceList) {
|
||||
imExportServiceList.forEach(it -> imExportServiceMap.put(it.type(), it));
|
||||
@@ -147,25 +143,80 @@ public class MonitorServiceImpl implements MonitorService {
|
||||
@Override
|
||||
@Transactional(readOnly = true)
|
||||
public void detectMonitor(Monitor monitor, List<Param> params, String collector) throws MonitorDetectException {
|
||||
final Optional<Param> sdParam = SdMonitorOperator.getSdParam(params);
|
||||
|
||||
if (sdParam.isPresent()) {
|
||||
collectOneTimeSdData(monitor, collector, sdParam.get());
|
||||
} else {
|
||||
if (CommonConstants.SCRAPE_STATIC.equals(monitor.getScrape()) || !StringUtils.hasText(monitor.getScrape())) {
|
||||
detectMonitorDirectly(monitor, params, collector);
|
||||
} else {
|
||||
detectSdMonitor(monitor, params, collector);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public void addMonitor(Monitor monitor, List<Param> params, String collector, GrafanaDashboard grafanaDashboard) throws RuntimeException {
|
||||
final Optional<Param> sdParam = SdMonitorOperator.getSdParam(params);
|
||||
if (sdParam.isPresent()) {
|
||||
addAndSaveMonitorJob(monitor.clone(), params, collector, SdMonitorParam.builder().sdParam(sdParam.get()).build(), grafanaDashboard);
|
||||
return;
|
||||
// Apply for monitor id
|
||||
long monitorId = SnowFlakeIdGenerator.generateId();
|
||||
Map<String, String> labels = monitor.getLabels();
|
||||
if (labels == null) {
|
||||
labels = new HashMap<>(8);
|
||||
monitor.setLabels(labels);
|
||||
}
|
||||
List<Label> addLabels = labelService.determineNewLabels(labels.entrySet());
|
||||
|
||||
if (!addLabels.isEmpty()) {
|
||||
labelDao.saveAll(addLabels);
|
||||
}
|
||||
|
||||
addAndSaveMonitorJob(monitor, params, collector, null, grafanaDashboard);
|
||||
// Construct the collection task Job entity
|
||||
boolean isStatic = CommonConstants.SCRAPE_STATIC.equals(monitor.getScrape()) || !StringUtils.hasText(monitor.getScrape());
|
||||
String app = isStatic ? monitor.getApp() : monitor.getScrape();
|
||||
Job appDefine = appService.getAppDefine(app);
|
||||
if (!isStatic) {
|
||||
appDefine.setSd(true);
|
||||
}
|
||||
if (CommonConstants.PROMETHEUS.equals(monitor.getApp())) {
|
||||
appDefine.setApp(CommonConstants.PROMETHEUS_APP_PREFIX + monitor.getName());
|
||||
}
|
||||
appDefine.setMonitorId(monitorId);
|
||||
appDefine.setDefaultInterval(monitor.getIntervals());
|
||||
appDefine.setCyclic(true);
|
||||
appDefine.setTimestamp(System.currentTimeMillis());
|
||||
Map<String, String> metadata = Map.of(CommonConstants.LABEL_INSTANCE_NAME, monitor.getName(),
|
||||
CommonConstants.LABEL_INSTANCE_HOST, monitor.getHost());
|
||||
appDefine.setMetadata(metadata);
|
||||
appDefine.setLabels(monitor.getLabels());
|
||||
appDefine.setAnnotations(monitor.getAnnotations());
|
||||
List<Configmap> configmaps = params.stream().map(param -> {
|
||||
param.setMonitorId(monitorId);
|
||||
return new Configmap(param.getField(), param.getParamValue(), param.getType());
|
||||
}).collect(Collectors.toList());
|
||||
appDefine.setConfigmap(configmaps);
|
||||
long jobId = collector == null ? collectJobScheduling.addAsyncCollectJob(appDefine, null) :
|
||||
collectJobScheduling.addAsyncCollectJob(appDefine, collector);
|
||||
try {
|
||||
detectMonitor(monitor, params, collector);
|
||||
} catch (Exception ignored) {}
|
||||
|
||||
try {
|
||||
if (collector != null) {
|
||||
CollectorMonitorBind collectorMonitorBind = CollectorMonitorBind.builder()
|
||||
.collector(collector)
|
||||
.monitorId(monitorId)
|
||||
.build();
|
||||
collectorMonitorBindDao.save(collectorMonitorBind);
|
||||
}
|
||||
monitor.setId(monitorId);
|
||||
monitor.setJobId(jobId);
|
||||
// create grafana dashboard
|
||||
if (monitor.getApp().equals(CommonConstants.PROMETHEUS) && grafanaDashboard != null && grafanaDashboard.isEnabled()) {
|
||||
dashboardService.createOrUpdateDashboard(grafanaDashboard.getTemplate(), monitorId);
|
||||
}
|
||||
monitorDao.save(monitor);
|
||||
paramDao.saveAll(params);
|
||||
} catch (Exception e) {
|
||||
log.error("Error while adding monitor: {}", e.getMessage(), e);
|
||||
collectJobScheduling.cancelAsyncCollectJob(jobId);
|
||||
throw new MonitorDatabaseException(e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -233,7 +284,7 @@ public class MonitorServiceImpl implements MonitorService {
|
||||
}
|
||||
}
|
||||
// the dispatch collector must exist if pin
|
||||
if (StringUtils.isNotBlank(monitorDto.getCollector())) {
|
||||
if (StringUtils.hasText(monitorDto.getCollector())) {
|
||||
Optional<Collector> optionalCollector = collectorDao.findCollectorByName(monitorDto.getCollector());
|
||||
if (optionalCollector.isEmpty()) {
|
||||
throw new IllegalArgumentException("The pinned collector does not exist.");
|
||||
@@ -250,7 +301,7 @@ public class MonitorServiceImpl implements MonitorService {
|
||||
if (paramDefine.isRequired() && (param == null || param.getParamValue() == null)) {
|
||||
throw new IllegalArgumentException("Params field " + field + " is required.");
|
||||
}
|
||||
if (param != null && param.getParamValue() != null && StringUtils.isNotBlank(param.getParamValue())) {
|
||||
if (param != null && StringUtils.hasText(param.getParamValue())) {
|
||||
switch (paramDefine.getType()) {
|
||||
case "number":
|
||||
double doubleValue;
|
||||
@@ -376,7 +427,6 @@ public class MonitorServiceImpl implements MonitorService {
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public void modifyMonitor(Monitor monitor, List<Param> params, String collector, GrafanaDashboard grafanaDashboard) throws RuntimeException {
|
||||
final Optional<Param> sdParam = SdMonitorOperator.getSdParam(params);
|
||||
long monitorId = monitor.getId();
|
||||
// Check to determine whether the monitor corresponding to the monitor id exists
|
||||
Optional<Monitor> queryOption = monitorDao.findById(monitorId);
|
||||
@@ -394,35 +444,20 @@ public class MonitorServiceImpl implements MonitorService {
|
||||
monitor.setLabels(labels);
|
||||
}
|
||||
|
||||
List<Label> addLabels = labelService.determineNewLabels(labels.entrySet());
|
||||
|
||||
if (!addLabels.isEmpty()) {
|
||||
labelDao.saveAll(addLabels);
|
||||
}
|
||||
|
||||
boolean isStatic = CommonConstants.SCRAPE_STATIC.equals(monitor.getScrape()) || !StringUtils.hasText(monitor.getScrape());
|
||||
if (preMonitor.getStatus() != CommonConstants.MONITOR_PAUSED_CODE) {
|
||||
// Construct the collection task Job entity
|
||||
Job appDefine = appService.getAppDefine(monitor.getApp());
|
||||
if (sdParam.isPresent()) {
|
||||
// not allow to modify a sub monitor to main monitor
|
||||
labels.entrySet()
|
||||
.stream()
|
||||
.filter(label -> org.apache.commons.lang3.StringUtils.equals(label.getKey(), CommonConstants.TAG_AUTO_CREATED))
|
||||
.findFirst()
|
||||
.ifPresent(label -> {
|
||||
final MonitorBind isSubMonitorBefore = monitorBindDao.findMonitorBindByBizIdAndMonitorIdAndType(Long.valueOf(label.getValue()),
|
||||
monitorId, CommonConstants.MONITOR_BIND_TYPE_SD_SUB_MONITOR);
|
||||
if (Objects.nonNull(isSubMonitorBefore)) {
|
||||
throw new UnsupportedOperationException("Can not change a auto-created monitor to sd! ");
|
||||
}
|
||||
});
|
||||
// create main monitor bind
|
||||
final List<MonitorBind> mainMonitorBind = monitorBindDao.findMonitorBindByBizIdAndType(monitorId, CommonConstants.MONITOR_BIND_TYPE_SD_MAIN_MONITOR);
|
||||
if (CollectionUtils.isEmpty(mainMonitorBind)) {
|
||||
monitorBindDao.save(Objects.requireNonNull(
|
||||
SdMonitorOperator.buildSdMainMonitorBind(
|
||||
SdMonitorParam.builder().sdParam(sdParam.get()).build(), monitorId
|
||||
)));
|
||||
}
|
||||
|
||||
appDefine = SdMonitorOperator.constructSdJob(appDefine, sdParam.get());
|
||||
labels.put(CommonConstants.TAG_SD_MAIN_MONITOR, ServiceDiscoveryProtocol.Type.getType(sdParam.get().getField()).name());
|
||||
String app = isStatic ? monitor.getApp() : monitor.getScrape();
|
||||
Job appDefine = appService.getAppDefine(app);
|
||||
if (!isStatic) {
|
||||
appDefine.setSd(true);
|
||||
}
|
||||
|
||||
if (CommonConstants.PROMETHEUS.equals(monitor.getApp())) {
|
||||
appDefine.setApp(CommonConstants.PROMETHEUS_APP_PREFIX + monitor.getName());
|
||||
}
|
||||
@@ -450,8 +485,7 @@ public class MonitorServiceImpl implements MonitorService {
|
||||
// execute only in non paused status
|
||||
try {
|
||||
detectMonitor(monitor, params, collector);
|
||||
} catch (Exception ignored) {
|
||||
}
|
||||
} catch (Exception ignored) {}
|
||||
}
|
||||
|
||||
// After the update is successfully released, refresh the database
|
||||
@@ -474,12 +508,6 @@ public class MonitorServiceImpl implements MonitorService {
|
||||
}
|
||||
}
|
||||
monitorDao.save(monitor);
|
||||
|
||||
// delete all sub monitor if sd param is removed
|
||||
final List<MonitorBind> subMonitorBindList = monitorBindDao.findMonitorBindByBizIdAndType(monitorId, CommonConstants.MONITOR_BIND_TYPE_SD_SUB_MONITOR);
|
||||
if (!CollectionUtils.isEmpty(subMonitorBindList) && sdParam.isEmpty()) {
|
||||
deleteMonitors(subMonitorBindList.stream().map(MonitorBind::getMonitorId).collect(Collectors.toSet()));
|
||||
}
|
||||
paramDao.saveAll(params);
|
||||
} catch (Exception e) {
|
||||
log.error(e.getMessage(), e);
|
||||
@@ -501,12 +529,6 @@ public class MonitorServiceImpl implements MonitorService {
|
||||
if (CollectionUtils.isEmpty(ids)) {
|
||||
return;
|
||||
}
|
||||
|
||||
final List<MonitorBind> allSubMonitorBind = monitorBindDao.findAllByBizIdInAndType(ids, CommonConstants.MONITOR_BIND_TYPE_SD_SUB_MONITOR);
|
||||
if (!CollectionUtils.isEmpty(allSubMonitorBind)) {
|
||||
ids.addAll(allSubMonitorBind.stream().map(MonitorBind::getMonitorId).collect(Collectors.toSet()));
|
||||
}
|
||||
|
||||
List<Monitor> monitors = monitorDao.findMonitorsByIdIn(ids);
|
||||
if (!monitors.isEmpty()) {
|
||||
monitorDao.deleteAll(monitors);
|
||||
@@ -537,7 +559,9 @@ public class MonitorServiceImpl implements MonitorService {
|
||||
monitorDto.setMetrics(metrics);
|
||||
monitorDto.setGrafanaDashboard(dashboardService.getDashboardByMonitorId(id));
|
||||
} else {
|
||||
Job job = appService.getAppDefine(monitor.getApp());
|
||||
boolean isStatic = CommonConstants.SCRAPE_STATIC.equals(monitor.getScrape()) || !StringUtils.hasText(monitor.getScrape());
|
||||
String type = isStatic ? monitor.getApp() : monitor.getScrape();
|
||||
Job job = appService.getAppDefine(type);
|
||||
List<String> metrics = job.getMetrics().stream()
|
||||
.filter(Metrics::isVisible)
|
||||
.map(Metrics::getName).collect(Collectors.toList());
|
||||
@@ -563,7 +587,7 @@ public class MonitorServiceImpl implements MonitorService {
|
||||
}
|
||||
andList.add(inPredicate);
|
||||
}
|
||||
if (StringUtils.isNotBlank(app)) {
|
||||
if (StringUtils.hasText(app)) {
|
||||
Predicate predicateApp = criteriaBuilder.equal(root.get("app"), app);
|
||||
andList.add(predicateApp);
|
||||
}
|
||||
@@ -575,17 +599,17 @@ public class MonitorServiceImpl implements MonitorService {
|
||||
Predicate andPredicate = criteriaBuilder.and(andList.toArray(andPredicates));
|
||||
|
||||
List<Predicate> orList = new ArrayList<>();
|
||||
if (StringUtils.isNotBlank(search)) {
|
||||
if (StringUtils.hasText(search)) {
|
||||
Predicate predicateHost = criteriaBuilder.like(root.get("host"), "%" + search + "%");
|
||||
Predicate predicateName = criteriaBuilder.like(criteriaBuilder.lower(root.get("name")), "%" + search.toLowerCase() + "%");
|
||||
if (StringUtils.isNumeric(search)){
|
||||
if (CommonUtil.isNumeric(search)){
|
||||
Predicate predicateId = criteriaBuilder.equal(root.get("id"), Long.parseLong(search));
|
||||
orList.add(predicateId);
|
||||
}
|
||||
orList.add(predicateHost);
|
||||
orList.add(predicateName);
|
||||
}
|
||||
if (StringUtils.isNotBlank(labels)) {
|
||||
if (StringUtils.hasText(labels)) {
|
||||
String[] labelAres = labels.split(",");
|
||||
for (String label : labelAres) {
|
||||
String[] labelArr = label.split(":");
|
||||
@@ -620,18 +644,10 @@ public class MonitorServiceImpl implements MonitorService {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void cancelManageMonitors(HashSet<Long> ids) {
|
||||
public void cancelManageMonitors(Set<Long> ids) {
|
||||
if (CollectionUtils.isEmpty(ids)) {
|
||||
return;
|
||||
}
|
||||
|
||||
final Set<Long> subMonitorIds = monitorBindDao.findAllByBizIdInAndType(ids, CommonConstants.MONITOR_BIND_TYPE_SD_SUB_MONITOR).stream()
|
||||
.map(MonitorBind::getMonitorId)
|
||||
.collect(Collectors.toSet());
|
||||
if (!CollectionUtils.isEmpty(subMonitorIds)) {
|
||||
ids.addAll(subMonitorIds);
|
||||
}
|
||||
|
||||
// Update monitoring status Delete corresponding monitoring periodic task
|
||||
// The jobId is not deleted, and the jobId is reused again after the management is started.
|
||||
List<Monitor> managedMonitors = monitorDao.findMonitorsByIdIn(ids)
|
||||
@@ -648,7 +664,7 @@ public class MonitorServiceImpl implements MonitorService {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void enableManageMonitors(HashSet<Long> ids) {
|
||||
public void enableManageMonitors(Set<Long> ids) {
|
||||
// Update monitoring status Add corresponding monitoring periodic task
|
||||
List<Monitor> unManagedMonitors = monitorDao.findMonitorsByIdIn(ids)
|
||||
.stream().filter(monitor ->
|
||||
@@ -662,20 +678,12 @@ public class MonitorServiceImpl implements MonitorService {
|
||||
for (Monitor monitor : unManagedMonitors) {
|
||||
// Construct the collection task Job entity
|
||||
List<Param> params = paramDao.findParamsByMonitorId(monitor.getId());
|
||||
final Optional<Param> sdParam = SdMonitorOperator.getSdParam(params);
|
||||
Job appDefine = appService.getAppDefine(monitor.getApp());
|
||||
if (sdParam.isPresent()) {
|
||||
final List<MonitorBind> mainMonitorBind = monitorBindDao.findMonitorBindByBizIdAndType(monitor.getId(), CommonConstants.MONITOR_BIND_TYPE_SD_MAIN_MONITOR);
|
||||
if (CollectionUtils.isEmpty(mainMonitorBind)) {
|
||||
monitorBindDao.save(Objects.requireNonNull(
|
||||
SdMonitorOperator.buildSdMainMonitorBind(
|
||||
SdMonitorParam.builder().sdParam(sdParam.get()).build(), monitor.getId()
|
||||
)));
|
||||
}
|
||||
|
||||
appDefine = SdMonitorOperator.constructSdJob(appDefine, sdParam.get());
|
||||
boolean isStatic = CommonConstants.SCRAPE_STATIC.equals(monitor.getScrape()) || !StringUtils.hasText(monitor.getScrape());
|
||||
String app = isStatic ? monitor.getApp() : monitor.getScrape();
|
||||
Job appDefine = appService.getAppDefine(app);
|
||||
if (!isStatic) {
|
||||
appDefine.setSd(true);
|
||||
}
|
||||
|
||||
if (CommonConstants.PROMETHEUS.equals(monitor.getApp())) {
|
||||
appDefine.setApp(CommonConstants.PROMETHEUS_APP_PREFIX + monitor.getName());
|
||||
}
|
||||
@@ -691,7 +699,7 @@ public class MonitorServiceImpl implements MonitorService {
|
||||
List<Configmap> configmaps = params.stream().map(param ->
|
||||
new Configmap(param.getField(), param.getParamValue(), param.getType())).collect(Collectors.toList());
|
||||
List<ParamDefine> paramDefaultValue = appDefine.getParams().stream()
|
||||
.filter(item -> StringUtils.isNotBlank(item.getDefaultValue()))
|
||||
.filter(item -> StringUtils.hasText(item.getDefaultValue()))
|
||||
.toList();
|
||||
paramDefaultValue.forEach(defaultVar -> {
|
||||
if (configmaps.stream().noneMatch(item -> item.getKey().equals(defaultVar.getField()))) {
|
||||
@@ -752,25 +760,6 @@ public class MonitorServiceImpl implements MonitorService {
|
||||
}).filter(Objects::nonNull).collect(Collectors.toList());
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public void copyMonitors(List<Long> ids) {
|
||||
|
||||
ids.stream().parallel().forEach(id -> {
|
||||
// get monitor and Params according id
|
||||
Optional<Monitor> monitorOpt = monitorDao.findById(id);
|
||||
List<Param> params = paramDao.findParamsByMonitorId(id);
|
||||
|
||||
monitorOpt.ifPresentOrElse(monitor -> {
|
||||
// deep copy original monitor to achieve persist in JPA
|
||||
Monitor newMonitor = JsonUtil.fromJson(JsonUtil.toJson(monitor), Monitor.class);
|
||||
if (newMonitor != null) {
|
||||
copyMonitor(newMonitor, params);
|
||||
}
|
||||
}, () -> log.warn("can not find the monitor for id :{}", id));
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateAppCollectJob(Job job) {
|
||||
List<Monitor> monitors = monitorDao.findMonitorsByAppEquals(job.getApp())
|
||||
@@ -807,7 +796,7 @@ public class MonitorServiceImpl implements MonitorService {
|
||||
List<Configmap> configmaps = params.stream().map(param -> new Configmap(param.getField(),
|
||||
param.getParamValue(), param.getType())).collect(Collectors.toList());
|
||||
List<ParamDefine> paramDefaultValue = appDefine.getParams().stream()
|
||||
.filter(item -> StringUtils.isNotBlank(item.getDefaultValue()))
|
||||
.filter(item -> StringUtils.hasText(item.getDefaultValue()))
|
||||
.toList();
|
||||
paramDefaultValue.forEach(defaultVar -> {
|
||||
if (configmaps.stream().noneMatch(item -> item.getKey().equals(defaultVar.getField()))) {
|
||||
@@ -827,80 +816,7 @@ public class MonitorServiceImpl implements MonitorService {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addAndSaveMonitorJob(Monitor monitor, List<Param> params, String collector, SdMonitorParam sdMonitorParam, GrafanaDashboard grafanaDashboard) {
|
||||
// Apply for monitor id
|
||||
long monitorId = SnowFlakeIdGenerator.generateId();
|
||||
Map<String, String> labels = monitor.getLabels();
|
||||
if (labels == null) {
|
||||
labels = new HashMap<>(8);
|
||||
monitor.setLabels(labels);
|
||||
}
|
||||
MonitorBind monitorBind = null;
|
||||
// Construct the collection task Job entity
|
||||
Job appDefine = appService.getAppDefine(monitor.getApp());
|
||||
if (Objects.nonNull(sdMonitorParam)) {
|
||||
monitorBind = Objects.isNull(sdMonitorParam.getSdParam())
|
||||
? SdMonitorOperator.buildSdSubMonitorBind(sdMonitorParam, monitorId, labels)
|
||||
: SdMonitorOperator.buildSdMainMonitorBind(sdMonitorParam, monitorId);
|
||||
|
||||
appDefine = SdMonitorOperator.constructSdJobAndTag(sdMonitorParam, labels, appDefine);
|
||||
}
|
||||
if (CommonConstants.PROMETHEUS.equals(monitor.getApp())) {
|
||||
appDefine.setApp(CommonConstants.PROMETHEUS_APP_PREFIX + monitor.getName());
|
||||
}
|
||||
appDefine.setMonitorId(monitorId);
|
||||
appDefine.setDefaultInterval(monitor.getIntervals());
|
||||
appDefine.setCyclic(true);
|
||||
appDefine.setTimestamp(System.currentTimeMillis());
|
||||
Map<String, String> metadata = Map.of(CommonConstants.LABEL_INSTANCE_NAME, monitor.getName(),
|
||||
CommonConstants.LABEL_INSTANCE_HOST, monitor.getHost());
|
||||
appDefine.setMetadata(metadata);
|
||||
appDefine.setLabels(monitor.getLabels());
|
||||
appDefine.setAnnotations(monitor.getAnnotations());
|
||||
resetMetricsCommonField(monitor, appDefine, sdMonitorParam);
|
||||
|
||||
List<Configmap> configmaps = params.stream().map(param -> {
|
||||
param.setMonitorId(monitorId);
|
||||
return new Configmap(param.getField(), param.getParamValue(), param.getType());
|
||||
}).collect(Collectors.toList());
|
||||
appDefine.setConfigmap(configmaps);
|
||||
|
||||
long jobId = collector == null ? collectJobScheduling.addAsyncCollectJob(appDefine, null) :
|
||||
collectJobScheduling.addAsyncCollectJob(appDefine, collector);
|
||||
|
||||
try {
|
||||
detectMonitor(monitor, params, collector);
|
||||
} catch (Exception ignored) {
|
||||
}
|
||||
|
||||
try {
|
||||
if (collector != null) {
|
||||
CollectorMonitorBind collectorMonitorBind = CollectorMonitorBind.builder()
|
||||
.collector(collector)
|
||||
.monitorId(monitorId)
|
||||
.build();
|
||||
collectorMonitorBindDao.save(collectorMonitorBind);
|
||||
}
|
||||
monitor.setId(monitorId);
|
||||
monitor.setJobId(jobId);
|
||||
// create grafana dashboard
|
||||
if (monitor.getApp().equals(CommonConstants.PROMETHEUS) && grafanaDashboard != null && grafanaDashboard.isEnabled()) {
|
||||
dashboardService.createOrUpdateDashboard(grafanaDashboard.getTemplate(), monitorId);
|
||||
}
|
||||
monitorDao.save(monitor);
|
||||
if (Objects.nonNull(monitorBind)) {
|
||||
monitorBindDao.save(monitorBind);
|
||||
}
|
||||
paramDao.saveAll(params);
|
||||
} catch (Exception e) {
|
||||
log.error("Error while adding monitor: {}", e.getMessage(), e);
|
||||
collectJobScheduling.cancelAsyncCollectJob(jobId);
|
||||
throw new MonitorDatabaseException(e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Monitor getMonitor(Long monitorId) {
|
||||
return monitorDao.findById(monitorId).orElse(null);
|
||||
@@ -916,73 +832,69 @@ public class MonitorServiceImpl implements MonitorService {
|
||||
return monitorDao.findMonitorsByAppEquals(app);
|
||||
}
|
||||
|
||||
private void resetMetricsCommonField(Monitor monitor, Job appDefine, SdMonitorParam sdMonitorParam) {
|
||||
if (Objects.isNull(sdMonitorParam)
|
||||
|| org.apache.commons.lang3.StringUtils.isAnyBlank(sdMonitorParam.getDetectedHost(), sdMonitorParam.getDetectedPort())) {
|
||||
return;
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public void copyMonitor(Long id) {
|
||||
// Get the source monitor information
|
||||
Optional<Monitor> monitorOptional = monitorDao.findById(id);
|
||||
if (monitorOptional.isEmpty()) {
|
||||
throw new IllegalArgumentException("Monitor not found: " + id);
|
||||
}
|
||||
|
||||
for (Metrics metric : appDefine.getMetrics()) {
|
||||
Arrays.stream(metric.getClass().getDeclaredFields())
|
||||
.filter(field -> metric.getProtocol().equalsIgnoreCase(field.getName()))
|
||||
.findFirst()
|
||||
.ifPresent(field -> {
|
||||
field.setAccessible(true);
|
||||
final Object obj;
|
||||
try {
|
||||
obj = field.get(metric);
|
||||
if (obj instanceof CommonRequestProtocol protocol) {
|
||||
protocol.setHost(sdMonitorParam.getDetectedHost());
|
||||
protocol.setPort(sdMonitorParam.getDetectedPort());
|
||||
}
|
||||
} catch (IllegalAccessException exception) {
|
||||
log.warn("Not such field {}", field.getName());
|
||||
}
|
||||
});
|
||||
Monitor sourceMonitor = monitorOptional.get();
|
||||
// Get the parameters of source monitor
|
||||
List<Param> sourceParams = paramDao.findParamsByMonitorId(id);
|
||||
// Create new monitor object
|
||||
Monitor newMonitor = new Monitor();
|
||||
// Copy basic properties, exclude ID, jobId and status
|
||||
BeanUtils.copyProperties(sourceMonitor, newMonitor, "id", "jobId", "status");
|
||||
// Set new name
|
||||
newMonitor.setName(sourceMonitor.getName() + "_copy");
|
||||
// Set initial status
|
||||
newMonitor.setStatus(CommonConstants.MONITOR_UP_CODE);
|
||||
// Set create and update time
|
||||
newMonitor.setGmtCreate(LocalDateTime.now());
|
||||
newMonitor.setGmtUpdate(LocalDateTime.now());
|
||||
// Copy parameters
|
||||
List<Param> newParams = new ArrayList<>();
|
||||
if (!sourceParams.isEmpty()) {
|
||||
for (Param sourceParam : sourceParams) {
|
||||
Param newParam = new Param();
|
||||
BeanUtils.copyProperties(sourceParam, newParam, "id");
|
||||
newParam.setMonitorId(newMonitor.getId());
|
||||
newParams.add(newParam);
|
||||
}
|
||||
}
|
||||
|
||||
monitor.setHost(sdMonitorParam.getDetectedHost());
|
||||
Map<String, String> labels = monitor.getLabels();
|
||||
if (labels == null) {
|
||||
labels = new HashMap<>(8);
|
||||
monitor.setLabels(labels);
|
||||
}
|
||||
labels.put(CommonConstants.TAG_MONITOR_HOST, sdMonitorParam.getDetectedHost());
|
||||
monitor.setName(monitor.getApp().toUpperCase() + CommonConstants.LOCALE_SEPARATOR + sdMonitorParam.getDetectedHost()
|
||||
+ CommonConstants.LOCALE_SEPARATOR + SnowFlakeIdGenerator.generateId());
|
||||
addMonitor(newMonitor, newParams, null, null);
|
||||
}
|
||||
|
||||
private void copyMonitor(Monitor monitor, List<Param> params) {
|
||||
monitor.setName(String.format("%s - copy", monitor.getName()));
|
||||
addMonitor(monitor, params, null, null);
|
||||
}
|
||||
|
||||
private void collectOneTimeSdData(Monitor monitor, String collector, Param sdParam) {
|
||||
private void detectSdMonitor(Monitor monitor, List<Param> params, String collector) {
|
||||
Long monitorId = monitor.getId();
|
||||
if (monitorId == null || monitorId == 0) {
|
||||
monitorId = MONITOR_ID_TMP;
|
||||
}
|
||||
Job appDefine = appService.getAppDefine(monitor.getApp());
|
||||
if (CommonConstants.PROMETHEUS.equals(monitor.getApp())) {
|
||||
appDefine.setApp(CommonConstants.PROMETHEUS_APP_PREFIX + monitor.getName());
|
||||
if (monitor.getScrape() == null || params == null || params.isEmpty()) {
|
||||
throw new IllegalArgumentException("scrape params is null or empty!");
|
||||
}
|
||||
Job appDefine = appService.getAppDefine(monitor.getScrape());
|
||||
appDefine.setMonitorId(monitorId);
|
||||
appDefine.setCyclic(false);
|
||||
appDefine.setTimestamp(System.currentTimeMillis());
|
||||
Map<String, String> metadata = Map.of(CommonConstants.LABEL_INSTANCE_NAME, monitor.getName(),
|
||||
CommonConstants.LABEL_INSTANCE_HOST, monitor.getHost());
|
||||
Map<String, String> metadata = Map.of(CommonConstants.LABEL_INSTANCE_NAME, monitor.getName());
|
||||
appDefine.setMetadata(metadata);
|
||||
appDefine.setLabels(monitor.getLabels());
|
||||
appDefine.setAnnotations(monitor.getAnnotations());
|
||||
final Job sdJob = SdMonitorOperator.constructSdJob(appDefine, sdParam);
|
||||
List<Configmap> configmaps = params.stream().map(param ->
|
||||
new Configmap(param.getField(), param.getParamValue(), param.getType())).collect(Collectors.toList());
|
||||
appDefine.setConfigmap(configmaps);
|
||||
appDefine.setSd(true);
|
||||
List<CollectRep.MetricsData> collectRep;
|
||||
if (collector != null) {
|
||||
collectRep = collectJobScheduling.collectSyncJobData(sdJob, collector);
|
||||
collectRep = collectJobScheduling.collectSyncJobData(appDefine, collector);
|
||||
} else {
|
||||
collectRep = collectJobScheduling.collectSyncJobData(sdJob);
|
||||
collectRep = collectJobScheduling.collectSyncJobData(appDefine);
|
||||
}
|
||||
monitor.setStatus(CommonConstants.MONITOR_UP_CODE);
|
||||
|
||||
// If the detection result fails, a detection exception is thrown
|
||||
if (collectRep == null || collectRep.isEmpty()) {
|
||||
monitor.setStatus(CommonConstants.MONITOR_DOWN_CODE);
|
||||
@@ -1038,95 +950,4 @@ public class MonitorServiceImpl implements MonitorService {
|
||||
}
|
||||
collectRep.forEach(CollectRep.MetricsData::close);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public void copyMonitor(Long id) {
|
||||
// Get the source monitor information
|
||||
Optional<Monitor> monitorOptional = monitorDao.findById(id);
|
||||
if (monitorOptional.isEmpty()) {
|
||||
throw new IllegalArgumentException("Monitor not found: " + id);
|
||||
}
|
||||
Monitor sourceMonitor = monitorOptional.get();
|
||||
|
||||
// Get the parameters of source monitor
|
||||
List<Param> sourceParams = paramDao.findParamsByMonitorId(id);
|
||||
|
||||
// Create new monitor object
|
||||
Monitor newMonitor = new Monitor();
|
||||
// Copy basic properties, exclude ID, jobId and status
|
||||
BeanUtils.copyProperties(sourceMonitor, newMonitor, "id", "jobId", "status");
|
||||
// Set new name
|
||||
newMonitor.setName(sourceMonitor.getName() + "_copy");
|
||||
// Set initial status
|
||||
newMonitor.setStatus(CommonConstants.MONITOR_UP_CODE);
|
||||
// Set create and update time
|
||||
newMonitor.setGmtCreate(LocalDateTime.now());
|
||||
newMonitor.setGmtUpdate(LocalDateTime.now());
|
||||
// Generate new ID using snowflake algorithm
|
||||
newMonitor.setId(SnowFlakeIdGenerator.generateId());
|
||||
// Save new monitor
|
||||
newMonitor = monitorDao.save(newMonitor);
|
||||
|
||||
// Ensure ID is set
|
||||
if (newMonitor.getId() == null) {
|
||||
throw new RuntimeException("Failed to generate monitor ID");
|
||||
}
|
||||
|
||||
// Copy parameters
|
||||
if (!sourceParams.isEmpty()) {
|
||||
List<Param> newParams = new ArrayList<>();
|
||||
for (Param sourceParam : sourceParams) {
|
||||
Param newParam = new Param();
|
||||
BeanUtils.copyProperties(sourceParam, newParam, "id");
|
||||
newParam.setMonitorId(newMonitor.getId());
|
||||
newParams.add(newParam);
|
||||
}
|
||||
paramDao.saveAll(newParams);
|
||||
}
|
||||
|
||||
try {
|
||||
// Build collect job
|
||||
Job appDefine = appService.getAppDefine(newMonitor.getApp());
|
||||
if (CommonConstants.PROMETHEUS.equals(newMonitor.getApp())) {
|
||||
appDefine.setApp(CommonConstants.PROMETHEUS_APP_PREFIX + newMonitor.getName());
|
||||
}
|
||||
// Ensure using correct monitor ID
|
||||
appDefine.setMonitorId(newMonitor.getId());
|
||||
appDefine.setDefaultInterval(newMonitor.getIntervals());
|
||||
appDefine.setCyclic(true);
|
||||
appDefine.setTimestamp(System.currentTimeMillis());
|
||||
Map<String, String> metadata = Map.of(CommonConstants.LABEL_INSTANCE_NAME, newMonitor.getName(),
|
||||
CommonConstants.LABEL_INSTANCE_HOST, newMonitor.getHost());
|
||||
appDefine.setMetadata(metadata);
|
||||
appDefine.setLabels(newMonitor.getLabels());
|
||||
appDefine.setAnnotations(newMonitor.getAnnotations());
|
||||
List<Configmap> configmaps = sourceParams.stream()
|
||||
.map(param -> new Configmap(param.getField(), param.getParamValue(), param.getType()))
|
||||
.collect(Collectors.toList());
|
||||
appDefine.setConfigmap(configmaps);
|
||||
|
||||
// Get collector configuration from source monitor
|
||||
Optional<CollectorMonitorBind> bindOptional =
|
||||
collectorMonitorBindDao.findCollectorMonitorBindByMonitorId(sourceMonitor.getId());
|
||||
String collector = bindOptional.map(CollectorMonitorBind::getCollector).orElse(null);
|
||||
|
||||
// Dispatch collect job
|
||||
long jobId = collectJobScheduling.addAsyncCollectJob(appDefine, collector);
|
||||
newMonitor.setJobId(jobId);
|
||||
monitorDao.save(newMonitor);
|
||||
|
||||
// Copy collector binding if exists
|
||||
if (collector != null) {
|
||||
CollectorMonitorBind newBind = CollectorMonitorBind.builder()
|
||||
.collector(collector)
|
||||
.monitorId(newMonitor.getId())
|
||||
.build();
|
||||
collectorMonitorBindDao.save(newBind);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.error("Create collect job error: {}", e.getMessage(), e);
|
||||
throw new RuntimeException("Create collect job failed: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -132,10 +132,21 @@ warehouse:
|
||||
# (please set this configuration reasonably as history records can affect performance when it is large)
|
||||
max-history-record-num: 6000
|
||||
victoria-metrics:
|
||||
# Standalone mode toggle — must be set to false when using cluster mode
|
||||
enabled: false
|
||||
url: http://localhost:8428
|
||||
username: root
|
||||
password: root
|
||||
cluster:
|
||||
enabled: false
|
||||
select:
|
||||
url: http://localhost:8481
|
||||
username: root
|
||||
password: root
|
||||
insert:
|
||||
url: http://localhost:8480
|
||||
username: root
|
||||
password: root
|
||||
td-engine:
|
||||
enabled: false
|
||||
driver-class-name: com.taosdata.jdbc.rs.RestfulDriver
|
||||
|
||||
@@ -21,11 +21,13 @@ app: activemq
|
||||
name:
|
||||
zh-CN: ActiveMQ消息系统
|
||||
en-US: ActiveMQ Message
|
||||
ja-JP: ActiveMQメッセージングシステム
|
||||
# The description and help of this monitoring type
|
||||
help:
|
||||
zh-CN: HertzBeat 使用 <a class='help_module_content' href='https://hertzbeat.apache.org/docs/advanced/extend-jmx'> JMX 协议</a> 对 Apache ActiveMQ 消息中间件的运行状态,节点,Topic等相关指标(broker、topic、memory pool、class loading、thread)进行监测。<br><span class='help_module_span'>⚠️注意:您需要在 ActiveMQ 开启 JMX 服务。<a class='help_module_content' href='https://hertzbeat.apache.org/zh-cn/docs/help/activemq'>点击查看开启步骤</a>。</span>
|
||||
en-US: "HertzBeat uses <a class='help_module_content' href='https://hertzbeat.apache.org/docs/advanced/extend-jmx'> JMX protocol</a> to monitor the running status, nodes, topics, and other metrics of Apache ActiveMQ message-oriented middleware. <br><span class='help_module_span'>⚠️Note: You should enable the JMX service in ActiveMQ. <a class='help_module_content' href='https://hertzbeat.apache.org/docs/help/activemq'>Click here to view the specific steps.</a></span>"
|
||||
zh-TW: HertzBeat使用 <a class='help_module_content' href='https://hertzbeat.apache.org/docs/advanced/extend-jmx'> JMX 協定</a> 對 Apache ActiveMQ 消息中介軟體的運行狀態,節點,Topic 等相關名額(broker、topic、memory pool、class loading、thread)進行監測。<br><span class='help_module_span'> ⚠️注意:您需要在 ActiveMQ 開啟 JMX 服務。<a class='help_module_content' href=' https://hertzbeat.apache.org/zh-cn/docs/help/activemq'>點擊查看開啟步驟</a>。</span>
|
||||
ja-JP: HertzBeatは <a class='help_module_content' href='https://hertzbeat.apache.org/docs/advanced/extend-jmx'> JMXプロトコルを介して</a> Apache ActiveMQメッセージングシステムのランタイムステータス、ノード、トピック、その他の関連指標を監視します。<br><span class='help_module_span'> ⚠️注意:ActiveMQ で JMX サービスを有効にする必要があります。<a class='help_module_content' href=' https://hertzbeat.apache.org/zh-cn/docs/help/activemq'>クリックしてガイドを見ます</a>。</span>
|
||||
helpLink:
|
||||
zh-CN: https://hertzbeat.apache.org/zh-cn/docs/help/activemq
|
||||
en-US: https://hertzbeat.apache.org/docs/help/activemq
|
||||
@@ -37,6 +39,7 @@ params:
|
||||
name:
|
||||
zh-CN: 目标 Host
|
||||
en-US: Target Host
|
||||
ja-JP: 目標ホスト
|
||||
# type-param field type(most mapping the html input type)
|
||||
type: host
|
||||
# required-true or false
|
||||
@@ -47,6 +50,7 @@ params:
|
||||
name:
|
||||
zh-CN: JMX 端口
|
||||
en-US: JMX Port
|
||||
ja-JP: JMXポート
|
||||
# type-param field type(most mapping the html input type)
|
||||
type: number
|
||||
# when type is number, range is required
|
||||
@@ -61,6 +65,7 @@ params:
|
||||
name:
|
||||
zh-CN: JMX URL
|
||||
en-US: JMX URL
|
||||
ja-JP: JMX URL
|
||||
# type-param field type(most mapping the html input type)
|
||||
type: text
|
||||
# required-true or false
|
||||
@@ -75,6 +80,7 @@ params:
|
||||
name:
|
||||
zh-CN: 用户名
|
||||
en-US: Username
|
||||
ja-JP: ユーザー名
|
||||
# type-param field type(most mapping the html input type)
|
||||
type: text
|
||||
# when type is text, use limit to limit string length
|
||||
@@ -89,6 +95,7 @@ params:
|
||||
name:
|
||||
zh-CN: 密码
|
||||
en-US: Password
|
||||
ja-JP: パスワード
|
||||
# type-param field type(most mapping the html input tag)
|
||||
type: password
|
||||
# required-true or false
|
||||
@@ -103,6 +110,7 @@ metrics:
|
||||
i18n:
|
||||
zh-CN: 虚拟机基础信息
|
||||
en-US: JVM Basic
|
||||
ja-JP: Java仮想マシン基礎情報
|
||||
# metrics scheduling priority(0->127)->(high->low), metrics with the same priority will be scheduled in parallel
|
||||
# priority 0's metrics is availability metrics, it will be scheduled first, only availability metrics collect success will the scheduling continue
|
||||
priority: 0
|
||||
@@ -114,22 +122,26 @@ metrics:
|
||||
i18n:
|
||||
zh-CN: 名称
|
||||
en-US: Vm Name
|
||||
ja-JP: 仮想マシン名
|
||||
- field: VmVendor
|
||||
type: 1
|
||||
i18n:
|
||||
zh-CN: 厂商
|
||||
en-US: Vm Vendor
|
||||
ja-JP: 仮想マシンベンダー
|
||||
- field: VmVersion
|
||||
type: 1
|
||||
i18n:
|
||||
zh-CN: 版本
|
||||
en-US: Vm Version
|
||||
ja-JP: 仮想マシンバージョン
|
||||
- field: Uptime
|
||||
type: 0
|
||||
unit: ms
|
||||
i18n:
|
||||
zh-CN: 运行时长
|
||||
en-US: Up time
|
||||
ja-JP: アップタイム
|
||||
# the protocol used for monitoring, eg: sql, ssh, http, telnet, wmi, snmp, sdk
|
||||
protocol: jmx
|
||||
# the config content when protocol is jmx
|
||||
@@ -151,6 +163,7 @@ metrics:
|
||||
i18n:
|
||||
zh-CN: Broker 信息
|
||||
en-US: Broker Info
|
||||
ja-JP: ブローカー情報
|
||||
priority: 1
|
||||
fields:
|
||||
- field: BrokerName
|
||||
@@ -159,99 +172,118 @@ metrics:
|
||||
i18n:
|
||||
zh-CN: Broker 名称
|
||||
en-US: Broker Name
|
||||
ja-JP: ブローカー名
|
||||
- field: BrokerVersion
|
||||
i18n:
|
||||
zh-CN: Broker 版本
|
||||
en-US: Broker Version
|
||||
ja-JP: ブローカーバージョン
|
||||
type: 1
|
||||
- field: Uptime
|
||||
i18n:
|
||||
zh-CN: 启动时长
|
||||
en-US: Uptime
|
||||
ja-JP: アップタイム
|
||||
type: 1
|
||||
- field: UptimeMillis
|
||||
i18n:
|
||||
zh-CN: 启动时长(毫秒)
|
||||
en-US: Uptime Millis
|
||||
ja-JP: アップタイム(ms)
|
||||
type: 0
|
||||
unit: ms
|
||||
- field: Persistent
|
||||
i18n:
|
||||
zh-CN: 持久化
|
||||
en-US: Persistent
|
||||
en-US: Persistence
|
||||
ja-JP: 永続性
|
||||
type: 1
|
||||
- field: DataDirectory
|
||||
i18n:
|
||||
zh-CN: 数据目录
|
||||
en-US: Data Directory
|
||||
ja-JP: データディレクトリ
|
||||
type: 1
|
||||
- field: MemoryPercentUsage
|
||||
i18n:
|
||||
zh-CN: 内存使用率
|
||||
en-US: Memory Percent Usage
|
||||
ja-JP: メモリ使用率
|
||||
type: 0
|
||||
unit: '%'
|
||||
- field: StorePercentUsage
|
||||
i18n:
|
||||
zh-CN: 存储使用率
|
||||
en-US: Store Percent Usage
|
||||
ja-JP: ストレージ使用率
|
||||
type: 0
|
||||
unit: '%'
|
||||
- field: TempPercentUsage
|
||||
i18n:
|
||||
zh-CN: 临时使用率
|
||||
en-US: Temp Percent Usage
|
||||
ja-JP: 一時使用率
|
||||
type: 0
|
||||
unit: '%'
|
||||
- field: CurrentConnectionsCount
|
||||
i18n:
|
||||
zh-CN: 当前连接数
|
||||
en-US: Current Connections Count
|
||||
ja-JP: 現在接続数
|
||||
type: 0
|
||||
- field: TotalConnectionsCount
|
||||
i18n:
|
||||
zh-CN: 总连接数
|
||||
en-US: Total Connections Count
|
||||
ja-JP: 合計接続数
|
||||
type: 0
|
||||
- field: TotalEnqueueCount
|
||||
i18n:
|
||||
zh-CN: 总入队数
|
||||
en-US: Total Enqueue Count
|
||||
ja-JP: 合計エンキュー数
|
||||
type: 0
|
||||
- field: TotalDequeueCount
|
||||
i18n:
|
||||
zh-CN: 总出队数
|
||||
en-US: Total Dequeue Count
|
||||
ja-JP: 合計デキュー数
|
||||
type: 0
|
||||
- field: TotalConsumerCount
|
||||
i18n:
|
||||
zh-CN: 消费者总数
|
||||
en-US: Total Consumer Count
|
||||
ja-JP: 消費者総数
|
||||
type: 0
|
||||
- field: TotalProducerCount
|
||||
i18n:
|
||||
zh-CN: 生产者总数
|
||||
en-US: Total Producer Count
|
||||
ja-JP: 生産者総数
|
||||
type: 0
|
||||
- field: TotalMessageCount
|
||||
i18n:
|
||||
zh-CN: 总消息数
|
||||
en-US: Total Message Count
|
||||
ja-JP: メッセージ総数
|
||||
type: 0
|
||||
- field: AverageMessageSize
|
||||
i18n:
|
||||
zh-CN: 平均消息大小
|
||||
en-US: Average Message Size
|
||||
ja-JP: 平均メッセージサイズ
|
||||
type: 0
|
||||
- field: MaxMessageSize
|
||||
i18n:
|
||||
zh-CN: 最大消息大小
|
||||
en-US: Max Message Size
|
||||
ja-JP: 最大メッセージサイズ
|
||||
type: 0
|
||||
- field: MinMessageSize
|
||||
i18n:
|
||||
zh-CN: 最小消息大小
|
||||
en-US: Min Message Size
|
||||
ja-JP: 最小メッセージサイズ
|
||||
type: 0
|
||||
protocol: jmx
|
||||
jmx:
|
||||
@@ -271,106 +303,125 @@ metrics:
|
||||
i18n:
|
||||
zh-CN: Topic 名称
|
||||
en-US: Topic Name
|
||||
ja-JP: トピック名
|
||||
- field: MemoryLimit
|
||||
type: 0
|
||||
unit: MB
|
||||
i18n:
|
||||
zh-CN: 内存限制
|
||||
en-US: Memory Limit
|
||||
ja-JP: メモリ制限
|
||||
- field: MemoryPercentUsage
|
||||
type: 0
|
||||
unit: '%'
|
||||
i18n:
|
||||
zh-CN: 内存使用率
|
||||
en-US: Memory Percent Usage
|
||||
ja-JP: メモリ使用率
|
||||
- field: ProducerCount
|
||||
type: 0
|
||||
i18n:
|
||||
zh-CN: 生产者数量
|
||||
en-US: Producer Count
|
||||
ja-JP: 生産者数
|
||||
- field: ConsumerCount
|
||||
type: 0
|
||||
i18n:
|
||||
zh-CN: 消费者数量
|
||||
en-US: Consumer Count
|
||||
ja-JP: 消費者数
|
||||
- field: EnqueueCount
|
||||
type: 0
|
||||
i18n:
|
||||
zh-CN: 入队数量
|
||||
en-US: Enqueue Count
|
||||
ja-JP: エンキュー数
|
||||
- field: DequeueCount
|
||||
type: 0
|
||||
i18n:
|
||||
zh-CN: 出队数量
|
||||
en-US: Dequeue Count
|
||||
ja-JP: デキュー数
|
||||
- field: ForwardCount
|
||||
type: 0
|
||||
i18n:
|
||||
zh-CN: 转发数量
|
||||
en-US: Forward Count
|
||||
ja-JP: フォワード数
|
||||
- field: InFlightCount
|
||||
type: 0
|
||||
i18n:
|
||||
zh-CN: 进行中数量
|
||||
en-US: In Flight Count
|
||||
ja-JP: 処理数
|
||||
- field: DispatchCount
|
||||
type: 0
|
||||
i18n:
|
||||
zh-CN: 分发数量
|
||||
en-US: Dispatch Count
|
||||
ja-JP: ディスパッチ数
|
||||
- field: ExpiredCount
|
||||
type: 0
|
||||
i18n:
|
||||
zh-CN: 过期数量
|
||||
en-US: Expired Count
|
||||
ja-JP: 期限切れ数
|
||||
- field: StoreMessageSize
|
||||
type: 0
|
||||
unit: B
|
||||
i18n:
|
||||
zh-CN: 存储消息大小
|
||||
en-US: Store Message Size
|
||||
ja-JP: ストレージメッセージサイズ
|
||||
- field: AverageEnqueueTime
|
||||
type: 0
|
||||
unit: ms
|
||||
i18n:
|
||||
zh-CN: 平均入队时间
|
||||
en-US: Average Enqueue Time
|
||||
ja-JP: 平均エンキュー時間
|
||||
- field: MaxEnqueueTime
|
||||
type: 0
|
||||
unit: ms
|
||||
i18n:
|
||||
zh-CN: 最大入队时间
|
||||
en-US: Max Enqueue Time
|
||||
ja-JP: 最大エンキュー時間
|
||||
- field: MinEnqueueTime
|
||||
type: 0
|
||||
unit: ms
|
||||
i18n:
|
||||
zh-CN: 最小入队时间
|
||||
en-US: Min Enqueue Time
|
||||
ja-JP: 最小エンキュー時間
|
||||
- field: TotalBlockedTime
|
||||
type: 0
|
||||
unit: ms
|
||||
i18n:
|
||||
zh-CN: 总阻塞时间
|
||||
en-US: Total Blocked Time
|
||||
ja-JP: 合計ブロック時間
|
||||
- field: AverageMessageSize
|
||||
type: 0
|
||||
unit: B
|
||||
i18n:
|
||||
zh-CN: 平均消息大小
|
||||
en-US: Average Message Size
|
||||
ja-JP: 平均メッセージサイズ
|
||||
- field: MaxMessageSize
|
||||
type: 0
|
||||
unit: B
|
||||
i18n:
|
||||
zh-CN: 最大消息大小
|
||||
en-US: Max Message Size
|
||||
ja-JP: 最大メッセージサイズ
|
||||
- field: MinMessageSize
|
||||
type: 0
|
||||
unit: B
|
||||
i18n:
|
||||
zh-CN: 最小消息大小
|
||||
en-US: Min Message Size
|
||||
ja-JP: 最小メッセージサイズ
|
||||
units:
|
||||
- MemoryLimit=B->MB
|
||||
protocol: jmx
|
||||
@@ -386,6 +437,7 @@ metrics:
|
||||
i18n:
|
||||
zh-CN: 内存池
|
||||
en-US: Memory Pool
|
||||
ja-JP: メモリプール
|
||||
priority: 2
|
||||
fields:
|
||||
- field: name
|
||||
@@ -394,30 +446,35 @@ metrics:
|
||||
i18n:
|
||||
zh-CN: 指标名称
|
||||
en-US: Name
|
||||
ja-JP: 指標名
|
||||
- field: committed
|
||||
type: 0
|
||||
unit: MB
|
||||
i18n:
|
||||
zh-CN: 已分配内存
|
||||
en-US: Committed
|
||||
ja-JP: コミットメモリー
|
||||
- field: init
|
||||
type: 0
|
||||
unit: MB
|
||||
i18n:
|
||||
zh-CN: 初始化内存
|
||||
en-US: Init
|
||||
ja-JP: イニシャルメモリ
|
||||
- field: max
|
||||
type: 0
|
||||
unit: MB
|
||||
i18n:
|
||||
zh-CN: 最大内存
|
||||
en-US: Max
|
||||
ja-JP: 最大メモリ
|
||||
- field: used
|
||||
type: 0
|
||||
unit: MB
|
||||
i18n:
|
||||
zh-CN: 已使用内存
|
||||
en-US: Used
|
||||
ja-JP: 使用済みメモリ
|
||||
units:
|
||||
- committed=B->MB
|
||||
- init=B->MB
|
||||
@@ -448,6 +505,7 @@ metrics:
|
||||
i18n:
|
||||
zh-CN: 类加载信息
|
||||
en-US: Class Loading
|
||||
ja-JP: クラスローディング情報
|
||||
priority: 2
|
||||
fields:
|
||||
- field: LoadedClassCount
|
||||
@@ -455,16 +513,19 @@ metrics:
|
||||
i18n:
|
||||
zh-CN: 当前已加载类数量
|
||||
en-US: Loaded Class Count
|
||||
ja-JP: ロードされたクラス数
|
||||
- field: TotalLoadedClassCount
|
||||
type: 0
|
||||
i18n:
|
||||
zh-CN: 已加载类总数量
|
||||
en-US: Total Loaded Class Count
|
||||
ja-JP: ロードされたクラス総数
|
||||
- field: UnloadedClassCount
|
||||
type: 0
|
||||
i18n:
|
||||
zh-CN: 未加载类总数量
|
||||
en-US: Unloaded Class Count
|
||||
ja-JP: アンロードされたクラス総数
|
||||
protocol: jmx
|
||||
jmx:
|
||||
host: ^_^host^_^
|
||||
@@ -478,6 +539,7 @@ metrics:
|
||||
i18n:
|
||||
zh-CN: 线程信息
|
||||
en-US: Thread
|
||||
ja-JP: スレッド情報
|
||||
priority: 2
|
||||
fields:
|
||||
- field: TotalStartedThreadCount
|
||||
@@ -485,33 +547,39 @@ metrics:
|
||||
i18n:
|
||||
zh-CN: 已启动线程总数
|
||||
en-US: Total Started Thread Count
|
||||
ja-JP: スレッド総数
|
||||
- field: ThreadCount
|
||||
type: 0
|
||||
i18n:
|
||||
zh-CN: 活跃线程数
|
||||
en-US: Thread Count
|
||||
ja-JP: 活躍スレッド数
|
||||
- field: PeakThreadCount
|
||||
type: 0
|
||||
i18n:
|
||||
zh-CN: 最大峰值线程数
|
||||
en-US: Peak Thread Count
|
||||
ja-JP: 最大スレッド数
|
||||
- field: DaemonThreadCount
|
||||
type: 0
|
||||
i18n:
|
||||
zh-CN: 活跃守护线程数
|
||||
en-US: Daemon Thread Count
|
||||
ja-JP: デーモンスレッド数
|
||||
- field: CurrentThreadUserTime
|
||||
type: 0
|
||||
unit: s
|
||||
i18n:
|
||||
zh-CN: 线程占用的CPU时间(用户态)
|
||||
en-US: Current Thread User Time
|
||||
ja-JP: 現在のスレッドユーザー時間
|
||||
- field: CurrentThreadCpuTime
|
||||
type: 0
|
||||
unit: s
|
||||
i18n:
|
||||
zh-CN: 线程占用的CPU时间
|
||||
en-US: Current Thread CPU Time
|
||||
ja-JP: 現在のスレッドシステム時間
|
||||
units:
|
||||
- CurrentThreadUserTime=NS->S
|
||||
- CurrentThreadCpuTime=NS->S
|
||||
|
||||
@@ -21,11 +21,13 @@ app: airflow
|
||||
name:
|
||||
zh-CN: Apache Airflow
|
||||
en-US: Apache Airflow
|
||||
ja-JP: Apache Airflow
|
||||
# The description and help of this monitoring type
|
||||
help:
|
||||
zh-CN: Hertzbeat 对 Apache Airflow 通用性能指标(airflow health、airflow version)进行采集监控。<br>您可以点击“<i>新建 Apache Airflow </i>”并进行配置,或者选择“<i>更多操作</i>”,导入已有配置。
|
||||
en-US: HertzBeat monitors Apache Airflow through general performance metrics such as airflow health and airflow version. You could click the "<i>New Apache Airflow</i>" button and proceed with the configuration or import an existing setup through the "<i>More Actions</i>" menu.
|
||||
zh-TW: Hertzbeat對Apache Airflow通用性能指標(airflow health、airflow version)進行採集監控。<br>您可以點擊“<i>新建 Apache Airflow</i>”並進行配寘,或者選擇“<i>更多操作</i>”,導入已有配寘。
|
||||
ja-JP: Hertzbeatは、Apache Airflowの一般的なパフォーマンス指標を監視します。 <br><i>新規Apache Airflow</i>をクリックして設定しましょう。
|
||||
helpLink:
|
||||
zh-CN: https://hertzbeat.apache.org/zh-cn/docs/help/airflow/
|
||||
en-US: https://hertzbeat.apache.org/docs/help/airflow/
|
||||
@@ -37,6 +39,7 @@ params:
|
||||
name:
|
||||
zh-CN: 服务器 Host
|
||||
en-US: Target Host
|
||||
ja-JP: 目標ホスト
|
||||
# type-param field type(most mapping the html input type)
|
||||
type: host
|
||||
# required-true or false
|
||||
@@ -47,6 +50,7 @@ params:
|
||||
name:
|
||||
zh-CN: 服务端口
|
||||
en-US: Port
|
||||
ja-JP: ポート
|
||||
# type-param field type(most mapping the html input type)
|
||||
type: number
|
||||
# when type is number, range is required
|
||||
@@ -60,6 +64,7 @@ params:
|
||||
name:
|
||||
zh-CN: 启用HTTPS
|
||||
en-US: HTTPS
|
||||
ja-JP: HTTPS
|
||||
type: boolean
|
||||
hide: true
|
||||
required: true
|
||||
@@ -68,6 +73,7 @@ params:
|
||||
name:
|
||||
zh-CN: 超时时间(ms)
|
||||
en-US: Timeout(ms)
|
||||
ja-JP: タイムアウト(ms)
|
||||
type: number
|
||||
hide: true
|
||||
required: false
|
||||
@@ -78,22 +84,26 @@ metrics:
|
||||
i18n:
|
||||
zh-CN: airflow 健康状态
|
||||
en-US: airflow health status
|
||||
ja-JP: airflow 健全状態
|
||||
priority: 0
|
||||
fields:
|
||||
- field: metadatabase
|
||||
i18n:
|
||||
zh-CN: metadatabase 健康情况
|
||||
en-US: metadatabase status
|
||||
ja-JP: metadatabase 健全状態
|
||||
type: 1
|
||||
- field: scheduler
|
||||
i18n:
|
||||
zh-CN: scheduler 健康情况
|
||||
en-US: scheduler status
|
||||
ja-JP: scheduler 健全状態
|
||||
type: 1
|
||||
- field: triggerer
|
||||
i18n:
|
||||
zh-CN: triggerer 健康情况
|
||||
en-US: triggerer status
|
||||
ja-JP: triggerer 健全状態
|
||||
type: 1
|
||||
aliasFields:
|
||||
- $.metadatabase.status
|
||||
@@ -121,18 +131,21 @@ metrics:
|
||||
- name: airflow_version
|
||||
i18n:
|
||||
zh-CN: Airflow 版本
|
||||
en-US: airflow version
|
||||
en-US: Airflow version
|
||||
ja-JP: Airflowバージョン
|
||||
priority: 1
|
||||
fields:
|
||||
- field: version
|
||||
i18n:
|
||||
zh-CN: Airflow 版本
|
||||
en-US: Airflow version
|
||||
ja-JP: Airflowバージョン
|
||||
type: 1
|
||||
- field: git_version
|
||||
i18n:
|
||||
zh-CN: Airflow git版本
|
||||
zh-CN: git版本
|
||||
en-US: git version
|
||||
ja-JP: Gitバージョン
|
||||
type: 1
|
||||
protocol: http
|
||||
http:
|
||||
|
||||
@@ -21,11 +21,13 @@ app: almalinux
|
||||
name:
|
||||
zh-CN: AlmaLinux
|
||||
en-US: AlmaLinux
|
||||
ja-JP: AlmaLinux
|
||||
# The description and help of this monitoring type
|
||||
help:
|
||||
zh-CN: Hertzbeat 使用 <a class='help_module_content' href='https://hertzbeat.apache.org/docs/advanced/extend-ssh'> SSH 协议</a> 对 AlmaLinux 操作系统的通用性能指标 (系统信息、CPU、内存、磁盘、网卡、文件系统、TOP资源进程等) 进行采集监控。<br>您可以点击“<i>新建 AlmaLinux</i>”并配置HOST端口账户等相关参数进行添加,支持SSH账户密码或密钥认证。或者选择“<i>更多操作</i>”,导入已有配置。
|
||||
en-US: HertzBeat uses <a class='help_module_content' href='https://hertzbeat.apache.org/docs/advanced/extend-ssh'> SSH protocol</a> to monitors AlmaLinux operating system's general performance metrics such as cpu, memory, disk, basic, interface, disk_free, top_process etc. <br>You can click the "<i>New AlmaLinux</i>" and config host port and other related params to add, auth support password or secretKey. Or import an existing setup through the "<i>More Actions</i>" menu.
|
||||
zh-TW: Hertzbeat 使用 <a class='help_module_content' href='https://hertzbeat.apache.org/docs/advanced/extend-ssh'> SSH 协议</a> 對 AlmaLinux 操作系统的通用性能指標 (系統信息、CPU、內存、磁盤、網卡、文件系統、TOP資源進程等) 進行採集監控。<br>您可以點擊“<i>新建AlmaLinux</i>”並配置HOST端口賬戶等相關參數進行添加,支持SSH賬戶密碼或密鑰認證。或者選擇“<i>更多操作</i>”,導入已有配寘。
|
||||
ja-JP: Hertzbeat は <a class='help_module_content' href='https://hertzbeat.apache.org/docs/advanced/extend-ssh'> SSHプロトコルを介して</a> AlmaLinux 操作系统的通用性能指标 (系统信息、CPU、内存、磁盘、网卡、文件系统、TOP资源进程等) 进行采集监控。<br>「<i>新規 AlmaLinux</i>」をクリックしてホストなどのパラメタを設定した後、新規することができます。SSHまたはキー認証をサポートします。
|
||||
helpLink:
|
||||
zh-CN: https://hertzbeat.apache.org/zh-cn/docs/help/almalinux
|
||||
en-US: https://hertzbeat.apache.org/docs/help/almalinux
|
||||
@@ -37,6 +39,7 @@ params:
|
||||
name:
|
||||
zh-CN: 目标 Host
|
||||
en-US: Target Host
|
||||
ja-JP: 目標ホスト
|
||||
# type-param field type(most mapping the html input type)
|
||||
type: host
|
||||
# required-true or false
|
||||
@@ -47,6 +50,7 @@ params:
|
||||
name:
|
||||
zh-CN: 端口
|
||||
en-US: Port
|
||||
ja-JP: ポート
|
||||
# type-param field type(most mapping the html input type)
|
||||
type: number
|
||||
# when type is number, range is required
|
||||
@@ -61,6 +65,7 @@ params:
|
||||
name:
|
||||
zh-CN: 超时时间(ms)
|
||||
en-US: Timeout(ms)
|
||||
ja-JP: タイムアウト(ms)
|
||||
# type-param field type(most mapping the html input type)
|
||||
type: number
|
||||
# when type is number, range is required
|
||||
@@ -75,6 +80,7 @@ params:
|
||||
name:
|
||||
zh-CN: 复用连接
|
||||
en-US: Reuse Connection
|
||||
ja-JP: コネクション再利用
|
||||
# type-param field type(most mapping the html input type)
|
||||
type: boolean
|
||||
# required-true or false
|
||||
@@ -86,6 +92,7 @@ params:
|
||||
name:
|
||||
zh-CN: 使用代理
|
||||
en-US: Use Proxy Connection
|
||||
ja-JP: プロキシ利用
|
||||
# type-param field type(most mapping the html input type)
|
||||
type: boolean
|
||||
# required-true or false
|
||||
@@ -97,6 +104,7 @@ params:
|
||||
name:
|
||||
zh-CN: 用户名
|
||||
en-US: Username
|
||||
ja-JP: ユーザー名
|
||||
# type-param field type(most mapping the html input type)
|
||||
type: text
|
||||
# when type is text, use limit to limit string length
|
||||
@@ -109,6 +117,7 @@ params:
|
||||
name:
|
||||
zh-CN: 密码
|
||||
en-US: Password
|
||||
ja-JP: パスワード
|
||||
# type-param field type(most mapping the html input tag)
|
||||
type: password
|
||||
# required-true or false
|
||||
@@ -118,7 +127,8 @@ params:
|
||||
# name-param field display i18n name
|
||||
name:
|
||||
zh-CN: 私钥
|
||||
en-US: PrivateKey
|
||||
en-US: Private Key
|
||||
ja-JP: 秘密鍵
|
||||
# type-param field type(most mapping the html input type)
|
||||
type: textarea
|
||||
placeholder: -----BEGIN RSA PRIVATE KEY-----
|
||||
@@ -132,6 +142,7 @@ params:
|
||||
name:
|
||||
zh-CN: 密钥短语
|
||||
en-US: PrivateKey PassPhrase
|
||||
ja-JP: 秘密鍵フレーズ
|
||||
# type-param field type(most mapping the html input type)
|
||||
type: password
|
||||
# required-true or false
|
||||
@@ -144,6 +155,7 @@ params:
|
||||
name:
|
||||
zh-CN: 代理主机
|
||||
en-US: Proxy Host
|
||||
ja-JP: プロキシホスト
|
||||
# type-param field type(most mapping the html input type)
|
||||
type: text
|
||||
# required-true or false
|
||||
@@ -155,6 +167,7 @@ params:
|
||||
name:
|
||||
zh-CN: 代理端口
|
||||
en-US: Proxy Port
|
||||
ja-JP: プロキシポート
|
||||
# type-param field type(most mapping the html input type)
|
||||
type: number
|
||||
# when type is number, range is required
|
||||
@@ -171,6 +184,7 @@ params:
|
||||
name:
|
||||
zh-CN: 代理用户名
|
||||
en-US: Proxy Username
|
||||
ja-JP: プロキシユーザー名
|
||||
# type-param field type(most mapping the html input type)
|
||||
type: text
|
||||
# when type is text, use limit to limit string length
|
||||
@@ -185,6 +199,7 @@ params:
|
||||
name:
|
||||
zh-CN: 代理密码
|
||||
en-US: Proxy Password
|
||||
ja-JP: プロキシパスワード
|
||||
# type-param field type(most mapping the html input tag)
|
||||
type: password
|
||||
# required-true or false
|
||||
@@ -197,6 +212,7 @@ params:
|
||||
name:
|
||||
zh-CN: 代理主机私钥
|
||||
en-US: proxyPrivateKey
|
||||
ja-JP: プロキシ秘密鍵
|
||||
# type-param field type(most mapping the html input type)
|
||||
type: textarea
|
||||
placeholder: -----BEGIN RSA PRIVATE KEY-----
|
||||
@@ -211,6 +227,7 @@ metrics:
|
||||
i18n:
|
||||
zh-CN: 系统基本信息
|
||||
en-US: Basic Info
|
||||
ja-JP: システム基礎情報
|
||||
# metrics scheduling priority(0->127)->(high->low), metrics with the same priority will be scheduled in parallel
|
||||
# priority 0's metrics is availability metrics, it will be scheduled first, only availability metrics collect success will the scheduling continue
|
||||
priority: 0
|
||||
@@ -223,16 +240,19 @@ metrics:
|
||||
i18n:
|
||||
zh-CN: 主机名称
|
||||
en-US: Host Name
|
||||
ja-JP: ホスト名
|
||||
- field: version
|
||||
type: 1
|
||||
i18n:
|
||||
zh-CN: 操作系统版本
|
||||
en-US: System Version
|
||||
ja-JP: システムバージョン
|
||||
- field: uptime
|
||||
type: 1
|
||||
i18n:
|
||||
zh-CN: 启动时间
|
||||
en-US: Uptime
|
||||
ja-JP: アップタイム
|
||||
# the protocol used for monitoring, eg: sql, ssh, http, telnet, wmi, snmp, sdk
|
||||
protocol: ssh
|
||||
# the config content when protocol is ssh
|
||||
@@ -272,6 +292,7 @@ metrics:
|
||||
i18n:
|
||||
zh-CN: CPU 信息
|
||||
en-US: CPU Info
|
||||
ja-JP: CPU情報
|
||||
priority: 1
|
||||
fields:
|
||||
- field: info
|
||||
@@ -279,32 +300,38 @@ metrics:
|
||||
i18n:
|
||||
zh-CN: 型号
|
||||
en-US: Info
|
||||
ja-JP: バージョン
|
||||
- field: cores
|
||||
type: 1
|
||||
i18n:
|
||||
zh-CN: 核数
|
||||
en-US: Cores
|
||||
ja-JP: コア数
|
||||
- field: interrupt
|
||||
type: 0
|
||||
i18n:
|
||||
zh-CN: 中断数
|
||||
en-US: Interrupt
|
||||
ja-JP: 割り込み数
|
||||
- field: load
|
||||
type: 1
|
||||
i18n:
|
||||
zh-CN: 负载
|
||||
en-US: Load
|
||||
ja-JP: ロード
|
||||
- field: context_switch
|
||||
type: 0
|
||||
i18n:
|
||||
zh-CN: 上下文切换
|
||||
en-US: Context Switch
|
||||
ja-JP: コンテキストスイッチ
|
||||
- field: usage
|
||||
type: 0
|
||||
unit: '%'
|
||||
i18n:
|
||||
zh-CN: 使用率
|
||||
en-US: Usage
|
||||
ja-JP: 使用率
|
||||
# (optional)metrics field alias name, it is used as an alias field to map and convert the collected data and metrics field
|
||||
aliasFields:
|
||||
- info
|
||||
@@ -351,6 +378,7 @@ metrics:
|
||||
i18n:
|
||||
zh-CN: 内存信息
|
||||
en-US: Memory Info
|
||||
ja-JP: メモリ情報
|
||||
priority: 2
|
||||
fields:
|
||||
- field: total
|
||||
@@ -359,36 +387,42 @@ metrics:
|
||||
i18n:
|
||||
zh-CN: 总内存容量
|
||||
en-US: Total Memory
|
||||
ja-JP: メモリ容量
|
||||
- field: used
|
||||
type: 0
|
||||
unit: Mb
|
||||
i18n:
|
||||
zh-CN: 用户程序内存量
|
||||
en-US: User Program Memory
|
||||
ja-JP: ユーザープログラムメモリ
|
||||
- field: free
|
||||
type: 0
|
||||
unit: Mb
|
||||
i18n:
|
||||
zh-CN: 空闲内存容量
|
||||
en-US: Free Memory
|
||||
ja-JP: 空きメモリ
|
||||
- field: buff_cache
|
||||
type: 0
|
||||
unit: Mb
|
||||
i18n:
|
||||
zh-CN: 缓存占用内存
|
||||
en-US: Buff Cache Memory
|
||||
ja-JP: バッファメモリ
|
||||
- field: available
|
||||
type: 0
|
||||
unit: Mb
|
||||
i18n:
|
||||
zh-CN: 剩余可用内存
|
||||
en-US: Available Memory
|
||||
ja-JP: 使用可能なメモリ
|
||||
- field: usage
|
||||
type: 0
|
||||
unit: '%'
|
||||
i18n:
|
||||
zh-CN: 内存使用率
|
||||
en-US: Memory Usage
|
||||
ja-JP: メモリ使用率
|
||||
aliasFields:
|
||||
- total
|
||||
- used
|
||||
@@ -431,6 +465,7 @@ metrics:
|
||||
i18n:
|
||||
zh-CN: 磁盘信息
|
||||
en-US: Disk Info
|
||||
ja-JP: ディスク情報
|
||||
priority: 3
|
||||
fields:
|
||||
- field: disk_num
|
||||
@@ -438,27 +473,32 @@ metrics:
|
||||
i18n:
|
||||
zh-CN: 磁盘总数
|
||||
en-US: Disk Num
|
||||
ja-JP: ディスク番号
|
||||
- field: partition_num
|
||||
type: 1
|
||||
i18n:
|
||||
zh-CN: 分区总数
|
||||
en-US: Partition Num
|
||||
ja-JP: パーティション
|
||||
- field: block_write
|
||||
type: 0
|
||||
i18n:
|
||||
zh-CN: 写磁盘块数
|
||||
en-US: Block Write
|
||||
ja-JP: 書き込みディスクブロック数
|
||||
- field: block_read
|
||||
type: 0
|
||||
i18n:
|
||||
zh-CN: 读磁盘块数
|
||||
en-US: Block Read
|
||||
ja-JP: 読み取りブロック数
|
||||
- field: write_rate
|
||||
type: 0
|
||||
unit: iops
|
||||
i18n:
|
||||
zh-CN: 磁盘写速率
|
||||
en-US: Write Rate
|
||||
ja-JP: ディスク書き込み速度
|
||||
protocol: ssh
|
||||
ssh:
|
||||
host: ^_^host^_^
|
||||
@@ -488,6 +528,7 @@ metrics:
|
||||
i18n:
|
||||
zh-CN: 网卡信息
|
||||
en-US: Interface Info
|
||||
ja-JP: ネットワークカード情報
|
||||
priority: 4
|
||||
fields:
|
||||
- field: interface_name
|
||||
@@ -496,18 +537,21 @@ metrics:
|
||||
i18n:
|
||||
zh-CN: 网卡名称
|
||||
en-US: Interface Name
|
||||
ja-JP: ネットワークカード名
|
||||
- field: receive_bytes
|
||||
type: 0
|
||||
unit: Mb
|
||||
i18n:
|
||||
zh-CN: 入站数据流量
|
||||
en-US: Receive Bytes
|
||||
ja-JP: 受信バイト数
|
||||
- field: transmit_bytes
|
||||
type: 0
|
||||
unit: Mb
|
||||
i18n:
|
||||
zh-CN: 出站数据流量
|
||||
en-US: Transmit Bytes
|
||||
ja-JP: 送信バイト数
|
||||
units:
|
||||
- receive_bytes=B->MB
|
||||
- transmit_bytes=B->MB
|
||||
@@ -540,6 +584,7 @@ metrics:
|
||||
i18n:
|
||||
zh-CN: 文件系统
|
||||
en-US: Disk Free
|
||||
ja-JP: ファイルシステム
|
||||
priority: 5
|
||||
fields:
|
||||
- field: filesystem
|
||||
@@ -547,30 +592,35 @@ metrics:
|
||||
i18n:
|
||||
zh-CN: 文件系统
|
||||
en-US: Filesystem
|
||||
ja-JP: ファイルシステム
|
||||
- field: used
|
||||
type: 0
|
||||
unit: Mb
|
||||
i18n:
|
||||
zh-CN: 已使用量
|
||||
en-US: Used
|
||||
ja-JP: 使用済み
|
||||
- field: available
|
||||
type: 0
|
||||
unit: Mb
|
||||
i18n:
|
||||
zh-CN: 可用量
|
||||
en-US: Available
|
||||
ja-JP: 使用可能
|
||||
- field: usage
|
||||
type: 0
|
||||
unit: '%'
|
||||
i18n:
|
||||
zh-CN: 使用率
|
||||
en-US: Usage
|
||||
ja-JP: 使用率
|
||||
- field: mounted
|
||||
type: 1
|
||||
label: true
|
||||
i18n:
|
||||
zh-CN: 挂载点
|
||||
en-US: Mounted
|
||||
ja-JP: マウント
|
||||
protocol: ssh
|
||||
ssh:
|
||||
host: ^_^host^_^
|
||||
@@ -600,6 +650,7 @@ metrics:
|
||||
i18n:
|
||||
zh-CN: Top10 CPU 进程
|
||||
en-US: Top10 CPU Process
|
||||
ja-JP: トップ10 CPUプロセス
|
||||
priority: 6
|
||||
fields:
|
||||
- field: pid
|
||||
@@ -608,23 +659,27 @@ metrics:
|
||||
i18n:
|
||||
zh-CN: 进程ID
|
||||
en-US: PID
|
||||
ja-JP: プロセスID
|
||||
- field: cpu_usage
|
||||
type: 0
|
||||
unit: '%'
|
||||
i18n:
|
||||
zh-CN: CPU 占用率
|
||||
en-US: CPU Usage
|
||||
ja-JP: CPU使用率
|
||||
- field: mem_usage
|
||||
type: 0
|
||||
unit: '%'
|
||||
i18n:
|
||||
zh-CN: 内存占用率
|
||||
en-US: Memory Usage
|
||||
ja-JP: メモリ使用率
|
||||
- field: command
|
||||
type: 1
|
||||
i18n:
|
||||
zh-CN: 执行命令
|
||||
en-US: Command
|
||||
ja-JP: 指令
|
||||
protocol: ssh
|
||||
ssh:
|
||||
host: ^_^host^_^
|
||||
@@ -654,6 +709,7 @@ metrics:
|
||||
i18n:
|
||||
zh-CN: Top10 内存进程
|
||||
en-US: Top10 Memory Process
|
||||
ja-JP: トップ10 メモリプロセス
|
||||
priority: 7
|
||||
fields:
|
||||
- field: pid
|
||||
@@ -662,23 +718,27 @@ metrics:
|
||||
i18n:
|
||||
zh-CN: 进程ID
|
||||
en-US: PID
|
||||
ja-JP: プロセスID
|
||||
- field: mem_usage
|
||||
type: 0
|
||||
unit: '%'
|
||||
i18n:
|
||||
zh-CN: 内存占用率
|
||||
en-US: Memory Usage
|
||||
ja-JP: メモリ使用率
|
||||
- field: cpu_usage
|
||||
type: 0
|
||||
unit: '%'
|
||||
i18n:
|
||||
zh-CN: CPU 占用率
|
||||
en-US: CPU Usage
|
||||
ja-JP: CPU使用率
|
||||
- field: command
|
||||
type: 1
|
||||
i18n:
|
||||
zh-CN: 执行命令
|
||||
en-US: Command
|
||||
ja-JP: 指令
|
||||
protocol: ssh
|
||||
ssh:
|
||||
host: ^_^host^_^
|
||||
|
||||
@@ -21,11 +21,13 @@ app: api
|
||||
name:
|
||||
zh-CN: HTTP API
|
||||
en-US: HTTP API
|
||||
ja-JP: HTTP API
|
||||
# The description and help of this monitoring type
|
||||
help:
|
||||
zh-CN: Hertzbeat 将调用 HTTP API 接口,查看接口是否可用,并以 ms 为指标单位对其响应时间等指标进行监测。您可以先点击“新增 HTTP API”按钮并进行配置,或在“更多操作”中导入已有配置。
|
||||
en-US: The platform will invoke an HTTP API endpoint to verify its accessibility and monitor various metrics, including response time, measured in milliseconds (ms). <br>To set up this functionality, you could click the "Add HTTP API" button and proceed with the configuration or import an existing setup through the "More Actions" menu.
|
||||
zh-TW: Hertzbeat將調用HTTP API介面,查看介面是否可用,並以ms為名額組織對其回應時間等名額進行監測。 您可以先點擊“新增HTTP API”按鈕並進行配寘,或在“更多操作”中導入已有配寘。
|
||||
ja-JP: Hertzbeatは、HTTP APIを呼び出して利用可能かどうかを確認し、応答時間(ms)などのメトリクスを監視します。「新規HTTP API」をクリックして設定しましょう。
|
||||
helpLink:
|
||||
zh-CN: https://hertzbeat.apache.org/zh-cn/docs/help/api
|
||||
en-US: https://hertzbeat.apache.org/docs/help/api
|
||||
@@ -37,6 +39,7 @@ params:
|
||||
name:
|
||||
zh-CN: 目标Host
|
||||
en-US: Target Host
|
||||
ja-JP: 目標ホスト
|
||||
# type-param field type(most mapping the html input type)
|
||||
type: host
|
||||
# required-true or false
|
||||
@@ -47,6 +50,7 @@ params:
|
||||
name:
|
||||
zh-CN: 端口
|
||||
en-US: Port
|
||||
ja-JP: ポート
|
||||
# type-param field type(most mapping the html input type)
|
||||
type: number
|
||||
# when type is number, range is required
|
||||
@@ -61,6 +65,7 @@ params:
|
||||
name:
|
||||
zh-CN: 请求方式
|
||||
en-US: Method
|
||||
ja-JP: リクエストメソッド
|
||||
# type-param field type(most mapping the html input type)
|
||||
type: radio
|
||||
# required-true or false
|
||||
@@ -81,6 +86,7 @@ params:
|
||||
name:
|
||||
zh-CN: 相对路径
|
||||
en-US: URI
|
||||
ja-JP: URI
|
||||
# type-param field type(most mapping the html input type)
|
||||
type: text
|
||||
# when type is text, use limit to limit string length
|
||||
@@ -95,6 +101,7 @@ params:
|
||||
name:
|
||||
zh-CN: 启用HTTPS
|
||||
en-US: HTTPS
|
||||
ja-JP: HTTPS利用
|
||||
# type-param field type(most mapping the html input type)
|
||||
type: boolean
|
||||
# required-true or false
|
||||
@@ -105,6 +112,7 @@ params:
|
||||
name:
|
||||
zh-CN: 超时时间(ms)
|
||||
en-US: Timeout(ms)
|
||||
ja-JP: タイムアウト(ms)
|
||||
# type-param field type(most mapping the html input type)
|
||||
type: number
|
||||
# required-true or false
|
||||
@@ -117,6 +125,7 @@ params:
|
||||
name:
|
||||
zh-CN: 请求Headers
|
||||
en-US: Headers
|
||||
ja-JP: ヘッダ
|
||||
# type-param field type(most mapping the html input type)
|
||||
type: key-value
|
||||
# required-true or false
|
||||
@@ -131,6 +140,7 @@ params:
|
||||
name:
|
||||
zh-CN: 查询Params
|
||||
en-US: Params
|
||||
ja-JP: パラメータ
|
||||
# type-param field type(most mapping the html input type)
|
||||
type: key-value
|
||||
# required-true or false
|
||||
@@ -145,6 +155,7 @@ params:
|
||||
name:
|
||||
zh-CN: Content-Type
|
||||
en-US: Content-Type
|
||||
ja-JP: コンテンツタイプ
|
||||
# type-param field type(most mapping the html input type)
|
||||
type: text
|
||||
# param field input placeholder
|
||||
@@ -179,6 +190,7 @@ params:
|
||||
name:
|
||||
zh-CN: 认证方式
|
||||
en-US: Auth Type
|
||||
ja-JP: 認証方法
|
||||
# type-param field type(most mapping the html input type)
|
||||
type: radio
|
||||
# required-true or false
|
||||
@@ -197,6 +209,7 @@ params:
|
||||
name:
|
||||
zh-CN: 用户名
|
||||
en-US: Username
|
||||
ja-JP: ユーザー名
|
||||
# type-param field type(most mapping the html input type)
|
||||
type: text
|
||||
# when type is text, use limit to limit string length
|
||||
@@ -211,6 +224,7 @@ params:
|
||||
name:
|
||||
zh-CN: 密码
|
||||
en-US: Password
|
||||
ja-JP: パスワード
|
||||
# type-param field type(most mapping the html input type)
|
||||
type: password
|
||||
# required-true or false
|
||||
@@ -223,6 +237,7 @@ params:
|
||||
name:
|
||||
zh-CN: 计数关键字
|
||||
en-US: Keyword
|
||||
ja-JP: キーワード
|
||||
# type-param field type(most mapping the html input type)
|
||||
type: text
|
||||
# param field input placeholder
|
||||
@@ -237,6 +252,7 @@ params:
|
||||
name:
|
||||
zh-CN: 校验成功状态码
|
||||
en-US: Verify Success Code
|
||||
ja-JP: 成功ステータスコードの検証
|
||||
# type-param field type(most mapping the html input type)
|
||||
type: array
|
||||
# param field input placeholder
|
||||
@@ -252,6 +268,7 @@ params:
|
||||
name:
|
||||
zh-CN: 启用URL编码(UTF-8)
|
||||
en-US: Enable URL Encoding(UTF-8)
|
||||
ja-JP: URL Encoding利用(UTF-8)
|
||||
# type-param field type(most mapping the html input type)
|
||||
type: boolean
|
||||
# required-true or false
|
||||
@@ -267,6 +284,7 @@ metrics:
|
||||
i18n:
|
||||
zh-CN: 概要
|
||||
en-US: Summary
|
||||
ja-JP: 概要
|
||||
# metrics scheduling priority(0->127)->(high->low), metrics with the same priority will be scheduled in parallel
|
||||
# priority 0's metrics is availability metrics, it will be scheduled first, only availability metrics collect success will the scheduling continue
|
||||
priority: 0
|
||||
@@ -279,11 +297,13 @@ metrics:
|
||||
i18n:
|
||||
zh-CN: 响应时间
|
||||
en-US: Response Time
|
||||
ja-JP: 応答時間
|
||||
- field: keyword
|
||||
type: 0
|
||||
i18n:
|
||||
zh-CN: 关键词数量
|
||||
en-US: Keyword
|
||||
ja-JP: キーワード
|
||||
# the protocol used for monitoring, eg: sql, ssh, http, telnet, wmi, snmp, sdk
|
||||
protocol: http
|
||||
# the config content when protocol is http
|
||||
@@ -329,6 +349,7 @@ metrics:
|
||||
i18n:
|
||||
zh-CN: 请求头
|
||||
en-US: Header
|
||||
ja-JP: ヘッダ
|
||||
# metrics scheduling priority(0->127)->(high->low), metrics with the same priority will be scheduled in parallel
|
||||
# priority 0's metrics is availability metrics, it will be scheduled first, only availability metrics collect success will the scheduling continue
|
||||
priority: 1
|
||||
@@ -340,11 +361,13 @@ metrics:
|
||||
i18n:
|
||||
zh-CN: Content Type
|
||||
en-US: Content Type
|
||||
ja-JP: コンテンツタイプ
|
||||
- field: Content-Length
|
||||
type: 1
|
||||
i18n:
|
||||
zh-CN: 响应内容长度
|
||||
en-US: Content Length
|
||||
ja-JP: コンテンツの長さ
|
||||
# the protocol used for monitoring, eg: sql, ssh, http, telnet, wmi, snmp, sdk
|
||||
protocol: http
|
||||
# the config content when protocol is http
|
||||
|
||||
@@ -21,11 +21,13 @@ app: api_code
|
||||
name:
|
||||
zh-CN: API业务状态码
|
||||
en-US: API Code
|
||||
ja-JP: APIコード
|
||||
# The description and help of this monitoring type
|
||||
help:
|
||||
zh-CN: 监控 HTTP API 接口,对 API 返回的业务自定义状态码(非 Http 状态码)进行监控。此需通过配置 JsonPath 来解析您 API 的业务状态码路径。<br>您可以点击 “<i>新建 API Code</i>” 并进行配置,或者选择“<i>更多操作</i>”,导入已有配置。
|
||||
en-US: Monitor HTTP API to monitor business-defined status codes (non-HTTP status codes) returned by API. To do this, you need to configure JsonPath to resolve the business status code path of your API. <br>You could click the "<i>New API Codes</i>" button and proceed with the configuration or import an existing setup through the "<i>More Actions</i>" menu.
|
||||
zh-TW: 監控 HTTP API 接口,對 API 返回的業務自定義狀態碼(非 Http 狀態碼)進行監控。此需通過配置 JsonPath 來解析您 API 的業務狀態碼路徑。<br>您可以點擊“<i>新建API Code</i>”並進行配寘,或者選擇“<i>更多操作</i>”,導入已有配寘。
|
||||
ja-JP: 目標ホスト
|
||||
helpLink:
|
||||
zh-CN: https://hertzbeat.apache.org/zh-cn/docs/help/api_code
|
||||
en-US: https://hertzbeat.apache.org/docs/help/api_code
|
||||
@@ -37,6 +39,7 @@ params:
|
||||
name:
|
||||
zh-CN: 目标Host
|
||||
en-US: Target Host
|
||||
ja-JP: 目標ホスト
|
||||
# type-param field type(most mapping the html input type)
|
||||
type: host
|
||||
# required-true or false
|
||||
@@ -47,6 +50,7 @@ params:
|
||||
name:
|
||||
zh-CN: 端口
|
||||
en-US: Port
|
||||
ja-JP: ポート
|
||||
# type-param field type(most mapping the html input type)
|
||||
type: number
|
||||
# when type is number, range is required
|
||||
@@ -61,6 +65,7 @@ params:
|
||||
name:
|
||||
zh-CN: 请求方式
|
||||
en-US: Method
|
||||
ja-JP: リクエストメソッド
|
||||
# type-param field type(most mapping the html input type)
|
||||
type: radio
|
||||
# required-true or false
|
||||
@@ -81,6 +86,7 @@ params:
|
||||
name:
|
||||
zh-CN: 相对路径
|
||||
en-US: URI
|
||||
ja-JP: URI
|
||||
# type-param field type(most mapping the html input type)
|
||||
type: text
|
||||
# when type is text, use limit to limit string length
|
||||
@@ -95,6 +101,7 @@ params:
|
||||
name:
|
||||
zh-CN: 启用HTTPS
|
||||
en-US: HTTPS
|
||||
ja-JP: HTTPS利用
|
||||
# type-param field type(most mapping the html input type)
|
||||
type: boolean
|
||||
# required-true or false
|
||||
@@ -105,6 +112,7 @@ params:
|
||||
name:
|
||||
zh-CN: 超时时间(ms)
|
||||
en-US: Timeout(ms)
|
||||
ja-JP: タイムアウト(ms)
|
||||
# type-param field type(most mapping the html input type)
|
||||
type: number
|
||||
# required-true or false
|
||||
@@ -117,6 +125,7 @@ params:
|
||||
name:
|
||||
zh-CN: JsonPath解析状态码路径
|
||||
en-US: JsonPath Parse Code
|
||||
ja-JP: JsonPath 解析ステータスコード
|
||||
# type-param field type(most mapping the html input type)
|
||||
type: text
|
||||
# required-true or false
|
||||
@@ -131,6 +140,7 @@ params:
|
||||
name:
|
||||
zh-CN: 请求Headers
|
||||
en-US: Headers
|
||||
ja-JP: ヘッダ
|
||||
# type-param field type(most mapping the html input type)
|
||||
type: key-value
|
||||
# required-true or false
|
||||
@@ -146,6 +156,7 @@ params:
|
||||
name:
|
||||
zh-CN: 查询Params
|
||||
en-US: Params
|
||||
ja-JP: パラメータ
|
||||
# type-param field type(most mapping the html input type)
|
||||
type: key-value
|
||||
# required-true or false
|
||||
@@ -162,6 +173,7 @@ params:
|
||||
name:
|
||||
zh-CN: Content-Type
|
||||
en-US: Content-Type
|
||||
ja-JP: コンテンツタイプ
|
||||
# type-param field type(most mapping the html input type)
|
||||
type: text
|
||||
# param field input placeholder
|
||||
@@ -176,6 +188,7 @@ params:
|
||||
name:
|
||||
zh-CN: 请求BODY
|
||||
en-US: BODY
|
||||
ja-JP: ボディ
|
||||
# type-param field type(most mapping the html input type)
|
||||
type: textarea
|
||||
# param field input placeholder
|
||||
@@ -195,6 +208,7 @@ params:
|
||||
name:
|
||||
zh-CN: 认证方式
|
||||
en-US: Auth Type
|
||||
ja-JP: 認証方法
|
||||
# type-param field type(most mapping the html input type)
|
||||
type: radio
|
||||
# required-true or false
|
||||
@@ -215,6 +229,7 @@ params:
|
||||
name:
|
||||
zh-CN: 用户名
|
||||
en-US: Username
|
||||
ja-JP: ユーザー名
|
||||
# type-param field type(most mapping the html input type)
|
||||
type: text
|
||||
# when type is text, use limit to limit string length
|
||||
@@ -229,6 +244,7 @@ params:
|
||||
name:
|
||||
zh-CN: 密码
|
||||
en-US: Password
|
||||
ja-JP: パスワード
|
||||
# type-param field type(most mapping the html input type)
|
||||
type: password
|
||||
# required-true or false
|
||||
@@ -241,6 +257,7 @@ params:
|
||||
name:
|
||||
zh-CN: 认证Token
|
||||
en-US: Access Token
|
||||
ja-JP: アクセストークン
|
||||
# type-param field type(most mapping the html input type)
|
||||
type: text
|
||||
# required-true or false
|
||||
@@ -253,6 +270,7 @@ params:
|
||||
name:
|
||||
zh-CN: 计数关键字
|
||||
en-US: Keyword
|
||||
ja-JP: キーワード
|
||||
# type-param field type(most mapping the html input type)
|
||||
type: text
|
||||
# param field input placeholder
|
||||
@@ -268,6 +286,7 @@ metrics:
|
||||
i18n:
|
||||
zh-CN: 状态
|
||||
en-US: Status
|
||||
ja-JP: ステータス
|
||||
# metrics scheduling priority(0->127)->(high->low), metrics with the same priority will be scheduled in parallel
|
||||
# priority 0's metrics is availability metrics, it will be scheduled first, only availability metrics collect success will the scheduling continue
|
||||
priority: 0
|
||||
@@ -279,11 +298,13 @@ metrics:
|
||||
i18n:
|
||||
zh-CN: 响应时间
|
||||
en-US: Response Time
|
||||
ja-JP: 応答時間
|
||||
- field: code
|
||||
type: 1
|
||||
i18n:
|
||||
zh-CN: 业务状态码
|
||||
en-US: Status Code
|
||||
ja-JP: ステータスコード
|
||||
aliasFields:
|
||||
- ^_^jsonPath^_^
|
||||
- responseTime
|
||||
|
||||
@@ -0,0 +1,70 @@
|
||||
# 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.
|
||||
|
||||
# The monitoring type category:service-application service monitoring db-database monitoring custom-custom monitoring os-operating system monitoring
|
||||
category: __system__
|
||||
# Monitoring application type name (consistent with file name) eg: linux windows tomcat mysql aws...
|
||||
app: consul_sd
|
||||
# The app api i18n name
|
||||
name:
|
||||
zh-CN: Consul Service Discovery
|
||||
en-US: Consul Service Discovery
|
||||
# Input params define for app api(render web ui by the definition)
|
||||
params:
|
||||
# field-param field key
|
||||
- field: __sd_host__
|
||||
# name-param field display i18n name
|
||||
name:
|
||||
zh-CN: Consul Host
|
||||
en-US: Consul Host
|
||||
# type-param field type(most mapping the html input type)
|
||||
type: text
|
||||
# required-true or false
|
||||
required: true
|
||||
- field: __sd_port__
|
||||
name:
|
||||
zh-CN: Consul 端口
|
||||
en-US: Consul Port
|
||||
type: number
|
||||
range: '[0,65535]'
|
||||
required: true
|
||||
|
||||
metrics:
|
||||
- name: target
|
||||
i18n:
|
||||
zh-CN: 监控目标
|
||||
en-US: Monitor Target
|
||||
# metrics scheduling priority(0->127)->(high->low), metrics with the same priority will be scheduled in parallel
|
||||
# priority 0's metrics is availability metrics, it will be scheduled first, only availability metrics collect success will the scheduling continue
|
||||
priority: 0
|
||||
# collect metrics content
|
||||
fields:
|
||||
# field-metric name, type-metric type(0-number,1-string), unit-metric unit('%','ms','MB'), label-whether it is a metrics label field
|
||||
- field: host
|
||||
type: 1
|
||||
i18n:
|
||||
zh-CN: Host
|
||||
en-US: Host
|
||||
- field: port
|
||||
type: 1
|
||||
i18n:
|
||||
zh-CN: Port
|
||||
en-US: Port
|
||||
# the protocol used for monitoring, eg: sql, ssh, http, telnet, wmi, snmp, sdk
|
||||
protocol: consul_sd
|
||||
# the config content when protocol is http_sd
|
||||
consul_sd:
|
||||
host: ^_^__sd_host__^_^
|
||||
port: ^_^__sd_port__^_^
|
||||
@@ -0,0 +1,106 @@
|
||||
# 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.
|
||||
|
||||
# The monitoring type category:service-application service monitoring db-database monitoring custom-custom monitoring os-operating system monitoring
|
||||
category: __system__
|
||||
# Monitoring application type name (consistent with file name) eg: linux windows tomcat mysql aws...
|
||||
app: dns_sd
|
||||
# The app api i18n name
|
||||
name:
|
||||
zh-CN: Dns Service Discovery
|
||||
en-US: Dns Service Discovery
|
||||
# Input params define for app api(render web ui by the definition)
|
||||
params:
|
||||
# field-param field key
|
||||
- field: __sd_host__
|
||||
# name-param field display i18n name
|
||||
name:
|
||||
zh-CN: DNS地址
|
||||
en-US: DNS Host
|
||||
# type-param field type(most mapping the html input type)
|
||||
type: text
|
||||
# required-true or false
|
||||
required: true
|
||||
# field-param field key
|
||||
- field: __sd_port__
|
||||
# name-param field display i18n name
|
||||
name:
|
||||
zh-CN: DNS端口
|
||||
en-US: DNS Port
|
||||
# type-param field type(most mapping the html input type)
|
||||
type: text
|
||||
# required-true or false
|
||||
required: true
|
||||
# default value
|
||||
defaultValue: 53
|
||||
- field: __sd_record_type__
|
||||
# name-param field display i18n name
|
||||
name:
|
||||
zh-CN: 记录类型
|
||||
en-US: Record Type
|
||||
# type-param field type(radio mapping the html radio tag)
|
||||
type: radio
|
||||
# required-true or false
|
||||
required: true
|
||||
# when type is radio checkbox, use option to show optional values {name1:value1,name2:value2}
|
||||
options:
|
||||
- label: SRV
|
||||
value: 33
|
||||
- label: A
|
||||
value: 1
|
||||
- label: AAAA
|
||||
value: 28
|
||||
- label: MX
|
||||
value: 15
|
||||
- label: NS
|
||||
value: 2
|
||||
- field: __sd_record_name__
|
||||
# name-param field display i18n name
|
||||
name:
|
||||
zh-CN: 记录名
|
||||
en-US: Record Name
|
||||
# type-param field type(most mapping the html input type)
|
||||
type: text
|
||||
# required-true or false
|
||||
required: true
|
||||
metrics:
|
||||
- name: target
|
||||
i18n:
|
||||
zh-CN: 监控目标
|
||||
en-US: Monitor Target
|
||||
# metrics scheduling priority(0->127)->(high->low), metrics with the same priority will be scheduled in parallel
|
||||
# priority 0's metrics is availability metrics, it will be scheduled first, only availability metrics collect success will the scheduling continue
|
||||
priority: 0
|
||||
# collect metrics content
|
||||
fields:
|
||||
# field-metric name, type-metric type(0-number,1-string), unit-metric unit('%','ms','MB'), label-whether it is a metrics label field
|
||||
- field: host
|
||||
type: 1
|
||||
i18n:
|
||||
zh-CN: Host
|
||||
en-US: Host
|
||||
- field: port
|
||||
type: 1
|
||||
i18n:
|
||||
zh-CN: Port
|
||||
en-US: Port
|
||||
# the protocol used for monitoring, eg: sql, ssh, http, telnet, wmi, snmp, sdk
|
||||
protocol: dns_sd
|
||||
# the config content when protocol is dns_sd
|
||||
dns_sd:
|
||||
host: ^_^__sd_host__^_^
|
||||
port: ^_^__sd_port__^_^
|
||||
recordType: ^_^__sd_record_type__^_^
|
||||
recordName: ^_^__sd_record_name__^_^
|
||||
@@ -0,0 +1,62 @@
|
||||
# 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.
|
||||
|
||||
# The monitoring type category:service-application service monitoring db-database monitoring custom-custom monitoring os-operating system monitoring
|
||||
category: __system__
|
||||
# Monitoring application type name (consistent with file name) eg: linux windows tomcat mysql aws...
|
||||
app: eureka_sd
|
||||
# The app api i18n name
|
||||
name:
|
||||
zh-CN: Eureka Service Discovery
|
||||
en-US: Eureka Service Discovery
|
||||
# Input params define for app api(render web ui by the definition)
|
||||
params:
|
||||
# field-param field key
|
||||
- field: __sd_url__
|
||||
# name-param field display i18n name
|
||||
name:
|
||||
zh-CN: Eureka服务发现地址
|
||||
en-US: Eureka Service Discovery Url
|
||||
# type-param field type(most mapping the html input type)
|
||||
type: text
|
||||
# required-true or false
|
||||
required: true
|
||||
|
||||
metrics:
|
||||
- name: target
|
||||
i18n:
|
||||
zh-CN: 监控目标
|
||||
en-US: Monitor Target
|
||||
# metrics scheduling priority(0->127)->(high->low), metrics with the same priority will be scheduled in parallel
|
||||
# priority 0's metrics is availability metrics, it will be scheduled first, only availability metrics collect success will the scheduling continue
|
||||
priority: 0
|
||||
# collect metrics content
|
||||
fields:
|
||||
# field-metric name, type-metric type(0-number,1-string), unit-metric unit('%','ms','MB'), label-whether it is a metrics label field
|
||||
- field: host
|
||||
type: 1
|
||||
i18n:
|
||||
zh-CN: Host
|
||||
en-US: Host
|
||||
- field: port
|
||||
type: 1
|
||||
i18n:
|
||||
zh-CN: Port
|
||||
en-US: Port
|
||||
# the protocol used for monitoring, eg: sql, ssh, http, telnet, wmi, snmp, sdk
|
||||
protocol: eureka_sd
|
||||
# the config content when protocol is http_sd
|
||||
eureka_sd:
|
||||
url: ^_^__sd_url__^_^
|
||||
@@ -0,0 +1,62 @@
|
||||
# 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.
|
||||
|
||||
# The monitoring type category:service-application service monitoring db-database monitoring custom-custom monitoring os-operating system monitoring
|
||||
category: __system__
|
||||
# Monitoring application type name (consistent with file name) eg: linux windows tomcat mysql aws...
|
||||
app: http_sd
|
||||
# The app api i18n name
|
||||
name:
|
||||
zh-CN: Http Service Discovery
|
||||
en-US: Http Service Discovery
|
||||
# Input params define for app api(render web ui by the definition)
|
||||
params:
|
||||
# field-param field key
|
||||
- field: __sd_url__
|
||||
# name-param field display i18n name
|
||||
name:
|
||||
zh-CN: 服务发现地址
|
||||
en-US: Service Discovery Url
|
||||
# type-param field type(most mapping the html input type)
|
||||
type: text
|
||||
# required-true or false
|
||||
required: true
|
||||
|
||||
metrics:
|
||||
- name: target
|
||||
i18n:
|
||||
zh-CN: 监控目标
|
||||
en-US: Monitor Target
|
||||
# metrics scheduling priority(0->127)->(high->low), metrics with the same priority will be scheduled in parallel
|
||||
# priority 0's metrics is availability metrics, it will be scheduled first, only availability metrics collect success will the scheduling continue
|
||||
priority: 0
|
||||
# collect metrics content
|
||||
fields:
|
||||
# field-metric name, type-metric type(0-number,1-string), unit-metric unit('%','ms','MB'), label-whether it is a metrics label field
|
||||
- field: host
|
||||
type: 1
|
||||
i18n:
|
||||
zh-CN: Host
|
||||
en-US: Host
|
||||
- field: port
|
||||
type: 1
|
||||
i18n:
|
||||
zh-CN: Port
|
||||
en-US: Port
|
||||
# the protocol used for monitoring, eg: sql, ssh, http, telnet, wmi, snmp, sdk
|
||||
protocol: http_sd
|
||||
# the config content when protocol is http_sd
|
||||
http_sd:
|
||||
url: ^_^__sd_url__^_^
|
||||
@@ -14,7 +14,7 @@
|
||||
# limitations under the License.
|
||||
|
||||
# The monitoring type category:service-application service monitoring db-database monitoring custom-custom monitoring os-operating system monitoring
|
||||
category: service
|
||||
category: __system__
|
||||
# Monitoring application type name (consistent with file name) eg: linux windows tomcat mysql aws...
|
||||
app: push
|
||||
# The app api i18n name
|
||||
|
||||
@@ -207,12 +207,12 @@ metrics:
|
||||
# collect metrics content
|
||||
fields:
|
||||
# field-metric name, type-metric type(0-number,1-string), unit-metric unit('%','ms','MB'), label-whether it is a metrics label field
|
||||
- field: Content-Type
|
||||
- field: content_type
|
||||
type: 1
|
||||
i18n:
|
||||
zh-CN: Content Type
|
||||
en-US: Content Type
|
||||
- field: Content-Length
|
||||
- field: content_length
|
||||
type: 1
|
||||
i18n:
|
||||
zh-CN: 响应内容长度
|
||||
|
||||
-11
@@ -145,15 +145,4 @@ class MonitorsControllerTest {
|
||||
.andExpect(jsonPath("$.code").value("0"))
|
||||
.andExpect(jsonPath("$.msg").value("Import success"));
|
||||
}
|
||||
|
||||
@Test
|
||||
void duplicateMonitors() throws Exception {
|
||||
// Mock the behavior of monitorService.copyMonitors
|
||||
doNothing().when(monitorService).copyMonitors(List.of(6565463543L));
|
||||
|
||||
// Perform the POST request and verify the response
|
||||
this.mockMvc.perform(MockMvcRequestBuilders.post("/api/monitors/copy")
|
||||
.param("ids", "6565463543"))
|
||||
.andExpect(status().isOk());
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -744,7 +744,7 @@ class MonitorServiceTest {
|
||||
List<Param> params = Collections.singletonList(new Param());
|
||||
when(monitorDao.findById(1L)).thenReturn(Optional.of(monitor));
|
||||
when(paramDao.findParamsByMonitorId(1L)).thenReturn(params);
|
||||
assertDoesNotThrow(() -> monitorService.copyMonitors(List.of(1L)));
|
||||
assertDoesNotThrow(() -> monitorService.copyMonitor(1L));
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
<version>2.0-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>hertzbeat-log</artifactId>
|
||||
<artifactId>hertzbeat-otel</artifactId>
|
||||
<name>${project.artifactId}</name>
|
||||
<properties>
|
||||
<maven-jar-plugin.version>3.2.0</maven-jar-plugin.version>
|
||||
@@ -43,25 +43,14 @@
|
||||
<artifactId>hertzbeat-warehouse</artifactId>
|
||||
</dependency>
|
||||
<!-- OpenTelemetry -->
|
||||
<dependency>
|
||||
<groupId>io.opentelemetry</groupId>
|
||||
<artifactId>opentelemetry-api</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>io.opentelemetry</groupId>
|
||||
<artifactId>opentelemetry-sdk</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>io.opentelemetry</groupId>
|
||||
<artifactId>opentelemetry-sdk-logs</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>io.opentelemetry</groupId>
|
||||
<artifactId>opentelemetry-exporter-otlp</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>io.opentelemetry.instrumentation</groupId>
|
||||
<artifactId>opentelemetry-logback-appender-1.0</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>io.opentelemetry.instrumentation</groupId>
|
||||
<artifactId>opentelemetry-spring-boot-starter</artifactId>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
</project>
|
||||
+1
-1
@@ -15,7 +15,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.apache.hertzbeat.log.config;
|
||||
package org.apache.hertzbeat.otel.config;
|
||||
|
||||
import org.apache.hertzbeat.common.constants.ConfigConstants;
|
||||
import org.apache.hertzbeat.common.constants.SignConstants;
|
||||
+154
@@ -0,0 +1,154 @@
|
||||
/*
|
||||
* 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.otel.config;
|
||||
|
||||
import static io.opentelemetry.semconv.ServiceAttributes.SERVICE_NAME;
|
||||
import static org.apache.http.HttpHeaders.CONTENT_TYPE;
|
||||
|
||||
import io.opentelemetry.exporter.otlp.http.logs.OtlpHttpLogRecordExporter;
|
||||
import io.opentelemetry.exporter.otlp.http.trace.OtlpHttpSpanExporter;
|
||||
import io.opentelemetry.exporter.otlp.http.trace.OtlpHttpSpanExporterBuilder;
|
||||
import io.opentelemetry.sdk.autoconfigure.spi.AutoConfigurationCustomizerProvider;
|
||||
import io.opentelemetry.sdk.logs.export.BatchLogRecordProcessor;
|
||||
import io.opentelemetry.sdk.resources.Resource;
|
||||
|
||||
import java.util.Base64;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.hertzbeat.warehouse.store.history.greptime.GreptimeProperties;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
/**
|
||||
* OpenTelemetryConfig provides customizations for the auto-configured OpenTelemetry SDK,
|
||||
* specifically for integrating with GrepTimeDB for logs and traces.
|
||||
*/
|
||||
@Configuration
|
||||
@Slf4j
|
||||
public class OpenTelemetryConfig {
|
||||
|
||||
private static final String HERTZBEAT_SERVICE_NAME = "HertzBeat";
|
||||
private static final String DEFAULT_GREPTIME_DB_NAME = "public";
|
||||
private static final String DEFAULT_LOGS_TABLE_NAME = "hzb_logs";
|
||||
private static final String DEFAULT_TRACES_TABLE_NAME = "hzb_traces";
|
||||
private static final String GREPTIME_DB_NAME_HEADER = "X-Greptime-DB-Name";
|
||||
private static final String GREPTIME_LOG_TABLE_NAME_HEADER = "X-Greptime-Log-Table-Name";
|
||||
private static final String GREPTIME_TRACE_TABLE_NAME_HEADER = "X-Greptime-Trace-Table-Name";
|
||||
private static final String GREPTIME_PIPELINE_NAME_HEADER = "X-Greptime-Pipeline-Name";
|
||||
|
||||
/**
|
||||
* Adds authentication headers if credentials are provided.
|
||||
*/
|
||||
private void addAuthenticationHeaders(Map<String, String> headers, GreptimeProperties greptimeProps) {
|
||||
if (greptimeProps != null && StringUtils.isNotBlank(greptimeProps.username())
|
||||
&& StringUtils.isNotBlank(greptimeProps.password())) {
|
||||
String credentials = greptimeProps.username() + ":" + greptimeProps.password();
|
||||
String encodedCredentials = Base64.getEncoder().encodeToString(credentials.getBytes());
|
||||
headers.put("Authorization", "Basic " + encodedCredentials);
|
||||
log.debug("Added Basic Authentication header for GreptimeDB.");
|
||||
} else {
|
||||
log.debug("GreptimeDB username/password not configured, skipping Authentication header.");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds HTTP Log headers for OTLP communication with GreptimeDB.
|
||||
*/
|
||||
private Map<String, String> buildGreptimeOtlpLogHeaders(GreptimeProperties greptimeProps) {
|
||||
Map<String, String> headers = new HashMap<>();
|
||||
headers.put(GREPTIME_DB_NAME_HEADER, DEFAULT_GREPTIME_DB_NAME);
|
||||
headers.put(GREPTIME_LOG_TABLE_NAME_HEADER, DEFAULT_LOGS_TABLE_NAME);
|
||||
addAuthenticationHeaders(headers, greptimeProps);
|
||||
return Collections.unmodifiableMap(headers);
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds HTTP Trace headers for OTLP communication with GreptimeDB.
|
||||
*/
|
||||
private Map<String, String> buildGreptimeOtlpTraceHeaders(GreptimeProperties greptimeProps) {
|
||||
Map<String, String> headers = new HashMap<>();
|
||||
headers.put(GREPTIME_DB_NAME_HEADER, DEFAULT_GREPTIME_DB_NAME);
|
||||
headers.put(GREPTIME_TRACE_TABLE_NAME_HEADER, DEFAULT_TRACES_TABLE_NAME);
|
||||
headers.put(CONTENT_TYPE, "application/x-protobuf");
|
||||
headers.put(GREPTIME_PIPELINE_NAME_HEADER, "greptime_trace_v1");
|
||||
addAuthenticationHeaders(headers, greptimeProps);
|
||||
return Collections.unmodifiableMap(headers);
|
||||
}
|
||||
|
||||
/**
|
||||
* Provides an AutoConfigurationCustomizerProvider to tailor the auto-configured OpenTelemetry SDK.
|
||||
* This includes setting up GrepTimeDB exporters for logs and traces, and customizing the resource.
|
||||
* Active only if 'greptime.enabled' is true.
|
||||
*
|
||||
* @param greptimeProperties Configuration for GrepTimeDB.
|
||||
* @return AutoConfigurationCustomizerProvider instance.
|
||||
*/
|
||||
@Bean
|
||||
@ConditionalOnProperty(name = "warehouse.store.greptime.enabled", havingValue = "true")
|
||||
public AutoConfigurationCustomizerProvider greptimeOtelCustomizer(GreptimeProperties greptimeProperties) {
|
||||
log.info("GreptimeDB is enabled. Applying OpenTelemetry SDK customizations.");
|
||||
|
||||
return providerCustomizer -> providerCustomizer
|
||||
.addPropertiesCustomizer(sdkConfigProperties -> {
|
||||
Map<String, String> newProperties = new HashMap<>();
|
||||
newProperties.put("otel.metrics.exporter", "none");
|
||||
newProperties.put("otel.traces.exporter", "otlp");
|
||||
newProperties.put("otel.logs.exporter", "none");
|
||||
return newProperties;
|
||||
})
|
||||
.addResourceCustomizer((resource, configProperties) -> {
|
||||
log.info("Customizing auto-configured OpenTelemetry Resource with service name: {}.", HERTZBEAT_SERVICE_NAME);
|
||||
return resource.merge(Resource.builder().put(SERVICE_NAME, HERTZBEAT_SERVICE_NAME).build());
|
||||
})
|
||||
.addSpanExporterCustomizer((originalSpanExporter, configProperties) -> {
|
||||
String traceEndpoint = greptimeProperties.httpEndpoint() + "/v1/otlp/v1/traces";
|
||||
log.info("Programmatically configuring OtlpHttpSpanExporter for GreptimeDB traces. Endpoint: {}", traceEndpoint);
|
||||
Map<String, String> traceHeaders = buildGreptimeOtlpTraceHeaders(greptimeProperties);
|
||||
log.info("Trace Headers for GreptimeDB (programmatic HTTP config): {}", traceHeaders);
|
||||
|
||||
OtlpHttpSpanExporterBuilder httpExporterBuilder = OtlpHttpSpanExporter.builder()
|
||||
.setEndpoint(traceEndpoint)
|
||||
.setHeaders(() -> traceHeaders)
|
||||
.setTimeout(10000, TimeUnit.MILLISECONDS);
|
||||
return httpExporterBuilder.build();
|
||||
})
|
||||
.addLoggerProviderCustomizer((sdkLoggerProviderBuilder, configProperties) -> {
|
||||
log.info("Customizing auto-configured SdkLoggerProviderBuilder for GrepTimeDB logs.");
|
||||
|
||||
OtlpHttpLogRecordExporter logExporter = OtlpHttpLogRecordExporter.builder()
|
||||
.setEndpoint(greptimeProperties.httpEndpoint() + "/v1/otlp/v1/logs")
|
||||
.setHeaders(() -> buildGreptimeOtlpLogHeaders(greptimeProperties))
|
||||
.setTimeout(10000, TimeUnit.MILLISECONDS)
|
||||
.build();
|
||||
|
||||
BatchLogRecordProcessor batchLogProcessor = BatchLogRecordProcessor.builder(logExporter)
|
||||
.setScheduleDelay(1000, TimeUnit.MILLISECONDS)
|
||||
.setMaxExportBatchSize(512)
|
||||
.build();
|
||||
|
||||
return sdkLoggerProviderBuilder.addLogRecordProcessor(batchLogProcessor);
|
||||
});
|
||||
}
|
||||
}
|
||||
+58
@@ -0,0 +1,58 @@
|
||||
/*
|
||||
* 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.otel.config;
|
||||
|
||||
import io.opentelemetry.api.OpenTelemetry;
|
||||
import io.opentelemetry.instrumentation.logback.appender.v1_0.OpenTelemetryAppender;
|
||||
import io.opentelemetry.sdk.OpenTelemetrySdk;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.InitializingBean;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
/**
|
||||
* Installs the OpenTelemetryAppender for Logback once the auto-configured
|
||||
* OpenTelemetry SDK is available and GrepTimeDB integration is enabled.
|
||||
*/
|
||||
@Component
|
||||
@ConditionalOnProperty(name = "warehouse.store.greptime.enabled", havingValue = "true")
|
||||
@Slf4j
|
||||
public class OpenTelemetryLogbackAppenderInstaller implements InitializingBean {
|
||||
|
||||
private final OpenTelemetry openTelemetry;
|
||||
|
||||
@Autowired
|
||||
public OpenTelemetryLogbackAppenderInstaller(OpenTelemetry openTelemetry) {
|
||||
this.openTelemetry = openTelemetry;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void afterPropertiesSet() {
|
||||
if (this.openTelemetry instanceof OpenTelemetrySdk) {
|
||||
log.info("Auto-configured OpenTelemetry SDK detected. Installing OpenTelemetryAppender for Logback.");
|
||||
OpenTelemetryAppender.install(this.openTelemetry);
|
||||
} else {
|
||||
log.warn("OpenTelemetry SDK is not an instance of OpenTelemetrySdk (type: {}). "
|
||||
+ "OpenTelemetryAppender for Logback will not be installed. "
|
||||
+ "Ensure OpenTelemetry auto-configuration is active and correctly providing an SDK.",
|
||||
this.openTelemetry != null ? this.openTelemetry.getClass().getName() : "null");
|
||||
}
|
||||
}
|
||||
}
|
||||
+1
-1
@@ -14,4 +14,4 @@
|
||||
# limitations under the License.
|
||||
|
||||
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
|
||||
org.apache.hertzbeat.log.config.LogAutoConfiguration
|
||||
org.apache.hertzbeat.otel.config.LogAutoConfiguration
|
||||
+75
-33
@@ -25,6 +25,7 @@ import java.net.URI;
|
||||
import java.net.URLEncoder;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.time.Duration;
|
||||
import java.time.Instant;
|
||||
import java.time.ZonedDateTime;
|
||||
import java.time.temporal.TemporalAmount;
|
||||
import java.util.Arrays;
|
||||
@@ -33,6 +34,9 @@ import java.util.HashMap;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import com.google.common.collect.Maps;
|
||||
import lombok.AllArgsConstructor;
|
||||
@@ -76,11 +80,13 @@ import static org.apache.hertzbeat.common.constants.ConfigConstants.FunctionModu
|
||||
@Slf4j
|
||||
public class VictoriaMetricsClusterDataStorage extends AbstractHistoryDataStorage {
|
||||
|
||||
private static final String IMPORT_PATH = "/api/v1/import";
|
||||
private static final String EXPORT_PATH = "/api/v1/export";
|
||||
private static final String STATUS_PATH = "/api/v1/status/tsdb";
|
||||
private static final String VM_INSERT_BASE_PATH = "/insert/%s/%s";
|
||||
private static final String VM_SELECT_BASE_PATH = "/select/%s/%s";
|
||||
private static final String IMPORT_PATH = "prometheus/api/v1/import";
|
||||
private static final String EXPORT_PATH = "prometheus/api/v1/export";
|
||||
private static final String STATUS_PATH = "prometheus/api/v1/status/tsdb";
|
||||
private static final String STATUS_SUCCESS = "success";
|
||||
private static final String QUERY_RANGE_PATH = "/api/v1/query_range";
|
||||
private static final String QUERY_RANGE_PATH = "prometheus/api/v1/query_range";
|
||||
private static final String LABEL_KEY_NAME = "__name__";
|
||||
private static final String LABEL_KEY_JOB = "job";
|
||||
private static final String LABEL_KEY_INSTANCE = "instance";
|
||||
@@ -88,6 +94,7 @@ public class VictoriaMetricsClusterDataStorage extends AbstractHistoryDataStorag
|
||||
private static final String MONITOR_METRICS_KEY = "__metrics__";
|
||||
private static final String MONITOR_METRIC_KEY = "__metric__";
|
||||
|
||||
private final VictoriaMetricsClusterProperties vmClusterProps;
|
||||
private final VictoriaMetricsInsertProperties vmInsertProps;
|
||||
private final VictoriaMetricsSelectProperties vmSelectProps;
|
||||
|
||||
@@ -100,6 +107,7 @@ public class VictoriaMetricsClusterDataStorage extends AbstractHistoryDataStorag
|
||||
throw new IllegalArgumentException("please config Warehouse victoriaMetrics cluster props");
|
||||
}
|
||||
this.restTemplate = restTemplate;
|
||||
this.vmClusterProps = vmClusterProps;
|
||||
this.vmInsertProps = vmClusterProps.insert();
|
||||
this.vmSelectProps = vmClusterProps.select();
|
||||
serverAvailable = checkVictoriaMetricsDatasourceAvailable();
|
||||
@@ -108,7 +116,23 @@ public class VictoriaMetricsClusterDataStorage extends AbstractHistoryDataStorag
|
||||
private boolean checkVictoriaMetricsDatasourceAvailable() {
|
||||
// check server status
|
||||
try {
|
||||
String result = restTemplate.getForObject(vmSelectProps.url() + STATUS_PATH, String.class);
|
||||
String selectNodeStatusUrl = vmClusterProps.select().url() + VM_SELECT_BASE_PATH.formatted(vmClusterProps.accountID(), STATUS_PATH);
|
||||
HttpHeaders headers = new HttpHeaders();
|
||||
if (StringUtils.hasText(vmInsertProps.username())
|
||||
&& StringUtils.hasText(vmInsertProps.password())) {
|
||||
String authStr = vmInsertProps.username() + ":" + vmInsertProps.password();
|
||||
String encodedAuth = Base64Util.encode(authStr);
|
||||
headers.add(HttpHeaders.AUTHORIZATION, NetworkConstants.BASIC + SignConstants.BLANK + encodedAuth);
|
||||
}
|
||||
HttpEntity<Void> requestEntity = new HttpEntity<>(headers);
|
||||
ResponseEntity<String> responseEntity = restTemplate.exchange(
|
||||
selectNodeStatusUrl,
|
||||
HttpMethod.GET,
|
||||
requestEntity,
|
||||
String.class
|
||||
);
|
||||
|
||||
String result = responseEntity.getBody();
|
||||
|
||||
JsonNode jsonNode = JsonUtil.fromJson(result);
|
||||
if (jsonNode != null && STATUS_SUCCESS.equalsIgnoreCase(jsonNode.get(STATUS).asText())) {
|
||||
@@ -225,7 +249,8 @@ public class VictoriaMetricsClusterDataStorage extends AbstractHistoryDataStorag
|
||||
stringBuilder.append(JsonUtil.toJson(content)).append("\n");
|
||||
}
|
||||
HttpEntity<String> httpEntity = new HttpEntity<>(stringBuilder.toString(), headers);
|
||||
ResponseEntity<String> responseEntity = restTemplate.postForEntity(vmInsertProps.url() + IMPORT_PATH,
|
||||
String importUrl = vmClusterProps.insert().url() + VM_INSERT_BASE_PATH.formatted(vmClusterProps.accountID(), IMPORT_PATH);
|
||||
ResponseEntity<String> responseEntity = restTemplate.postForEntity(importUrl,
|
||||
httpEntity, String.class);
|
||||
if (responseEntity.getStatusCode().is2xxSuccessful()) {
|
||||
log.debug("insert metrics data to victoria-metrics success.");
|
||||
@@ -252,9 +277,11 @@ public class VictoriaMetricsClusterDataStorage extends AbstractHistoryDataStorag
|
||||
if (CommonConstants.PROMETHEUS.equals(app)) {
|
||||
labelName = metrics;
|
||||
}
|
||||
String timeSeriesSelector =
|
||||
LABEL_KEY_NAME + "=\"" + labelName + "\"" + "," + LABEL_KEY_INSTANCE + "=\"" + monitorId + "\"" + ","
|
||||
+ (CommonConstants.PROMETHEUS.equals(app) ? "" : "," + MONITOR_METRIC_KEY + "=\"" + metric + "\"");
|
||||
String timeSeriesSelector = Stream.of(
|
||||
LABEL_KEY_NAME + "=\"" + labelName + "\"",
|
||||
LABEL_KEY_INSTANCE + "=\"" + monitorId + "\"",
|
||||
CommonConstants.PROMETHEUS.equals(app) ? null : MONITOR_METRIC_KEY + "=\"" + metric + "\""
|
||||
).filter(Objects::nonNull).collect(Collectors.joining(","));
|
||||
Map<String, List<Value>> instanceValuesMap = new HashMap<>(8);
|
||||
try {
|
||||
HttpHeaders headers = new HttpHeaders();
|
||||
@@ -267,11 +294,15 @@ public class VictoriaMetricsClusterDataStorage extends AbstractHistoryDataStorag
|
||||
+ SignConstants.BLANK + encodedAuth);
|
||||
}
|
||||
HttpEntity<Void> httpEntity = new HttpEntity<>(headers);
|
||||
URI uri = UriComponentsBuilder.fromHttpUrl(vmSelectProps.url() + EXPORT_PATH)
|
||||
.queryParam(URLEncoder.encode("match[]", StandardCharsets.UTF_8),
|
||||
URLEncoder.encode("{" + timeSeriesSelector + "}", StandardCharsets.UTF_8))
|
||||
.queryParam("start", URLEncoder.encode("now-" + history, StandardCharsets.UTF_8))
|
||||
.queryParam("end", "now").build(true).toUri();
|
||||
Instant end = Instant.now();
|
||||
Duration duration = Duration.ofHours(Long.parseLong(history.replace("h", "")));
|
||||
Instant start = end.minus(duration);
|
||||
String exportUrl = vmClusterProps.select().url() + VM_SELECT_BASE_PATH.formatted(vmClusterProps.accountID(), EXPORT_PATH);
|
||||
URI uri = UriComponentsBuilder.fromHttpUrl(exportUrl)
|
||||
.queryParam("match", URLEncoder.encode("{" + timeSeriesSelector + "}", StandardCharsets.UTF_8))
|
||||
.queryParam("start", String.valueOf(start.getEpochSecond()))
|
||||
.queryParam("end", String.valueOf(end.getEpochSecond()))
|
||||
.build(true).toUri();
|
||||
ResponseEntity<String> responseEntity = restTemplate.exchange(uri, HttpMethod.GET, httpEntity,
|
||||
String.class);
|
||||
if (responseEntity.getStatusCode().is2xxSuccessful()) {
|
||||
@@ -347,9 +378,11 @@ public class VictoriaMetricsClusterDataStorage extends AbstractHistoryDataStorag
|
||||
if (CommonConstants.PROMETHEUS.equals(app)) {
|
||||
labelName = metrics;
|
||||
}
|
||||
String timeSeriesSelector =
|
||||
LABEL_KEY_NAME + "=\"" + labelName + "\"" + "," + LABEL_KEY_INSTANCE + "=\"" + monitorId + "\"" + ","
|
||||
+ (CommonConstants.PROMETHEUS.equals(app) ? "" : "," + MONITOR_METRIC_KEY + "=\"" + metric + "\"");
|
||||
String timeSeriesSelector = Stream.of(
|
||||
LABEL_KEY_NAME + "=\"" + labelName + "\"",
|
||||
LABEL_KEY_INSTANCE + "=\"" + monitorId + "\"",
|
||||
CommonConstants.PROMETHEUS.equals(app) ? null : MONITOR_METRIC_KEY + "=\"" + metric + "\""
|
||||
).filter(Objects::nonNull).collect(Collectors.joining(","));
|
||||
Map<String, List<Value>> instanceValuesMap = new HashMap<>(8);
|
||||
try {
|
||||
HttpHeaders headers = new HttpHeaders();
|
||||
@@ -362,10 +395,13 @@ public class VictoriaMetricsClusterDataStorage extends AbstractHistoryDataStorag
|
||||
+ SignConstants.BLANK + encodedAuth);
|
||||
}
|
||||
HttpEntity<Void> httpEntity = new HttpEntity<>(headers);
|
||||
URI uri = UriComponentsBuilder.fromHttpUrl(vmSelectProps.url() + QUERY_RANGE_PATH)
|
||||
.queryParam(URLEncoder.encode("query", StandardCharsets.UTF_8),
|
||||
URLEncoder.encode("{" + timeSeriesSelector + "}", StandardCharsets.UTF_8))
|
||||
.queryParam("step", "4h").queryParam("start", startTime).queryParam("end", endTime).build(true)
|
||||
String rangeUrl = VM_SELECT_BASE_PATH.formatted(vmClusterProps.accountID(), QUERY_RANGE_PATH);
|
||||
URI uri = UriComponentsBuilder.fromHttpUrl(rangeUrl)
|
||||
.queryParam("query", URLEncoder.encode("{" + timeSeriesSelector + "}", StandardCharsets.UTF_8))
|
||||
.queryParam("step", "4h")
|
||||
.queryParam("start", startTime)
|
||||
.queryParam("end", endTime)
|
||||
.build(true)
|
||||
.toUri();
|
||||
ResponseEntity<PromQlQueryContent> responseEntity = restTemplate.exchange(uri, HttpMethod.GET,
|
||||
httpEntity, PromQlQueryContent.class);
|
||||
@@ -400,10 +436,12 @@ public class VictoriaMetricsClusterDataStorage extends AbstractHistoryDataStorag
|
||||
log.error("query metrics data from victoria-metrics failed. {}", responseEntity);
|
||||
}
|
||||
// max
|
||||
uri = UriComponentsBuilder.fromHttpUrl(vmSelectProps.url() + QUERY_RANGE_PATH)
|
||||
.queryParam(URLEncoder.encode("query", StandardCharsets.UTF_8),
|
||||
URLEncoder.encode("max_over_time({" + timeSeriesSelector + "})", StandardCharsets.UTF_8))
|
||||
.queryParam("step", "4h").queryParam("start", startTime).queryParam("end", endTime).build(true)
|
||||
uri = UriComponentsBuilder.fromHttpUrl(rangeUrl)
|
||||
.queryParam("query", URLEncoder.encode("max_over_time({" + timeSeriesSelector + "})", StandardCharsets.UTF_8))
|
||||
.queryParam("step", "4h")
|
||||
.queryParam("start", startTime)
|
||||
.queryParam("end", endTime)
|
||||
.build(true)
|
||||
.toUri();
|
||||
responseEntity = restTemplate.exchange(uri, HttpMethod.GET, httpEntity, PromQlQueryContent.class);
|
||||
if (responseEntity.getStatusCode().is2xxSuccessful()) {
|
||||
@@ -436,10 +474,12 @@ public class VictoriaMetricsClusterDataStorage extends AbstractHistoryDataStorag
|
||||
}
|
||||
}
|
||||
// min
|
||||
uri = UriComponentsBuilder.fromHttpUrl(vmSelectProps.url() + QUERY_RANGE_PATH)
|
||||
.queryParam(URLEncoder.encode("query", StandardCharsets.UTF_8),
|
||||
URLEncoder.encode("min_over_time({" + timeSeriesSelector + "})", StandardCharsets.UTF_8))
|
||||
.queryParam("step", "4h").queryParam("start", startTime).queryParam("end", endTime).build(true)
|
||||
uri = UriComponentsBuilder.fromHttpUrl(rangeUrl)
|
||||
.queryParam("query", URLEncoder.encode("min_over_time({" + timeSeriesSelector + "})", StandardCharsets.UTF_8))
|
||||
.queryParam("step", "4h")
|
||||
.queryParam("start", startTime)
|
||||
.queryParam("end", endTime)
|
||||
.build(true)
|
||||
.toUri();
|
||||
responseEntity = restTemplate.exchange(uri, HttpMethod.GET, httpEntity, PromQlQueryContent.class);
|
||||
if (responseEntity.getStatusCode().is2xxSuccessful()) {
|
||||
@@ -472,10 +512,12 @@ public class VictoriaMetricsClusterDataStorage extends AbstractHistoryDataStorag
|
||||
}
|
||||
}
|
||||
// avg
|
||||
uri = UriComponentsBuilder.fromHttpUrl(vmSelectProps.url() + QUERY_RANGE_PATH)
|
||||
.queryParam(URLEncoder.encode("query", StandardCharsets.UTF_8),
|
||||
URLEncoder.encode("avg_over_time({" + timeSeriesSelector + "})", StandardCharsets.UTF_8))
|
||||
.queryParam("step", "4h").queryParam("start", startTime).queryParam("end", endTime).build(true)
|
||||
uri = UriComponentsBuilder.fromHttpUrl(rangeUrl)
|
||||
.queryParam("query", URLEncoder.encode("avg_over_time({" + timeSeriesSelector + "})", StandardCharsets.UTF_8))
|
||||
.queryParam("step", "4h")
|
||||
.queryParam("start", startTime)
|
||||
.queryParam("end", endTime)
|
||||
.build(true)
|
||||
.toUri();
|
||||
responseEntity = restTemplate.exchange(uri, HttpMethod.GET, httpEntity, PromQlQueryContent.class);
|
||||
if (responseEntity.getStatusCode().is2xxSuccessful()) {
|
||||
|
||||
+3
@@ -21,6 +21,7 @@ import org.apache.hertzbeat.common.constants.ConfigConstants;
|
||||
import org.apache.hertzbeat.common.constants.SignConstants;
|
||||
import org.apache.hertzbeat.warehouse.constants.WarehouseConstants;
|
||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
import org.springframework.boot.context.properties.bind.DefaultValue;
|
||||
|
||||
/**
|
||||
* Victoriametrics configuration information
|
||||
@@ -32,6 +33,8 @@ import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
+ SignConstants.DOT
|
||||
+ WarehouseConstants.HistoryName.VM_CLUSTER)
|
||||
public record VictoriaMetricsClusterProperties(
|
||||
@DefaultValue("false") boolean enabled,
|
||||
@DefaultValue("0") String accountID,
|
||||
VictoriaMetricsInsertProperties insert,
|
||||
VictoriaMetricsSelectProperties select
|
||||
) {
|
||||
|
||||
@@ -97,7 +97,7 @@ Due to the Apache Foundation's requirements for license compliance, HertzBeat's
|
||||
|
||||
- MySQL: [https://dev.mysql.com/get/Downloads/Connector-J/mysql-connector-java-8.0.25.zip](https://dev.mysql.com/get/Downloads/Connector-J/mysql-connector-java-8.0.25.zip)
|
||||
- Oracle (If you want to monitor Oracle, these two drivers are required):
|
||||
- [https://download.oracle.com/otn-pub/otn_software/jdbc/234/ojdbc8.jar](https://download.oracle.com/otn-pub/otn_software/jdbc/234/ojdbc8.jar)
|
||||
- [https://repo1.maven.org/maven2/com/oracle/database/jdbc/ojdbc8/23.4.0.24.05/ojdbc8-23.4.0.24.05.jar](https://repo1.maven.org/maven2/com/oracle/database/jdbc/ojdbc8/23.4.0.24.05/ojdbc8-23.4.0.24.05.jar)
|
||||
- [https://repo.mavenlibs.com/maven/com/oracle/database/nls/orai18n/21.5.0.0/orai18n-21.5.0.0.jar](https://repo.mavenlibs.com/maven/com/oracle/database/nls/orai18n/21.5.0.0/orai18n-21.5.0.0.jar)
|
||||
|
||||
Next, run the start-up script as before to experience the latest HertzBeat 1.6.0!
|
||||
|
||||
@@ -0,0 +1,94 @@
|
||||
# HertzBeat Upgrade Guide (Docker Mode)
|
||||
|
||||
## Docker-based Upgrade
|
||||
|
||||
### 1. Data Backup
|
||||
|
||||
- **Back up the database**: Manually back up MySQL data as needed.
|
||||
|
||||
```bash
|
||||
mysqldump -h<HOST-IP> -P<PORT> -uroot -p"PASSWORD" <DB_NAME> > hertzbeat_backup-`date +%Y-%m-%d`.sql # Single database
|
||||
mysqldump -h<HOST-IP> -P<PORT> -uroot -p"PASSWORD" --all-databases > hertzbeat_backup-`date +%Y-%m-%d`.sql # Full database
|
||||
```
|
||||
|
||||
- **Back up configuration files and data directory**:
|
||||
|
||||
```bash
|
||||
mv application.yml application-bak.yml && mv sureness.yml sureness-bak.yml
|
||||
cp -R data data-`date +%Y-%m-%d`.bak
|
||||
```
|
||||
|
||||
### 2. Stop and Remove the HertzBeat Container
|
||||
|
||||
```bash
|
||||
docker stop hertzbeat && docker rm hertzbeat
|
||||
```
|
||||
|
||||
### 3. Upgrade Database Schema
|
||||
|
||||
Navigate to [HertzBeat GitHub Migration Scripts](https://github.com/apache/hertzbeat/tree/master/hertzbeat-manager/src/main/resources/db/migration), select the appropriate `V160__update_column.sql` file under your database type (e.g., MySQL), and execute it in MySQL.
|
||||
|
||||
### 4. Restart HertzBeat with the New Image
|
||||
|
||||
```bash
|
||||
docker run -d -p 1157:1157 -p 1158:1158 \
|
||||
-v $(pwd)/data:/opt/hertzbeat/data \
|
||||
-v $(pwd)/logs:/opt/hertzbeat/logs \
|
||||
-v $(pwd)/application.yml:/opt/hertzbeat/config/application.yml \
|
||||
-v $(pwd)/sureness.yml:/opt/hertzbeat/config/sureness.yml \
|
||||
--restart=always \
|
||||
--name hertzbeat apache/hertzbeat:v1.7.0
|
||||
```
|
||||
|
||||
### 5. Update Configuration Files
|
||||
|
||||
Modify the backup configurations as needed:
|
||||
|
||||
- **`application.yml`** (Typical modifications):
|
||||
|
||||
```yaml
|
||||
datasource:
|
||||
driver-class-name: com.mysql.cj.jdbc.Driver
|
||||
username: root
|
||||
password: root
|
||||
url: jdbc:mysql://localhost:3306/hertzbeat?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=Asia/Shanghai
|
||||
hikari:
|
||||
max-lifetime: 120000
|
||||
|
||||
jpa:
|
||||
show-sql: false
|
||||
database-platform: org.eclipse.persistence.platform.database.MySQLPlatform
|
||||
database: mysql
|
||||
properties:
|
||||
eclipselink:
|
||||
logging:
|
||||
level: SEVERE
|
||||
```
|
||||
|
||||
- **`sureness.yml`** (Optional, modify for account/password changes):
|
||||
|
||||
```yaml
|
||||
account:
|
||||
- appId: admin
|
||||
credential: hertzbeat
|
||||
role: [admin]
|
||||
- appId: tom
|
||||
credential: hertzbeat
|
||||
role: [user]
|
||||
- appId: guest
|
||||
credential: hertzbeat
|
||||
role: [guest]
|
||||
- appId: lili
|
||||
credential: 94C6B34E7A199A9F9D4E1F208093B489
|
||||
salt: 123
|
||||
role: [user]
|
||||
```
|
||||
|
||||
### 6. Add Database Drivers
|
||||
|
||||
Due to Apache Foundation’s license compliance requirements, HertzBeat cannot include GPL-licensed dependencies (e.g., MySQL, Oracle). Users must manually download drivers and place them in the `ext-lib` directory, then mount it to `/opt/hertzbeat/ext-lib`:
|
||||
|
||||
- **MySQL Driver**: [Download MySQL Connector/J 8.0.25](https://dev.mysql.com/get/Downloads/Connector-J/mysql-connector-java-8.0.25.zip)
|
||||
- **Oracle Driver** (Required for Oracle monitoring):
|
||||
- [ojdbc8.jar](https://download.oracle.com/otn-pub/otn_software/jdbc/234/ojdbc8.jar)
|
||||
- [orai18n-21.5.0.0.jar](https://repo.mavenlibs.com/maven/com/oracle/database/nls/orai18n/21.5.0.0/orai18n-21.5.0.0.jar)
|
||||
@@ -0,0 +1,95 @@
|
||||
# HertzBeat Upgrade Guide from v1.6.1 to v1.7.0 (Helm Mode)
|
||||
|
||||
## 1. Prerequisites
|
||||
|
||||
1. Ensure the following tools are installed:
|
||||
- Helm 3.x
|
||||
- kubectl
|
||||
- Git (optional)
|
||||
|
||||
2. Verify current deployment information:
|
||||
|
||||
```bash
|
||||
helm list -n <your-namespace>
|
||||
# If the old chart package is missing, export values.yaml with:
|
||||
helm get values hertzbeat -n <your-namespace> > hertzbeat-1.6.1-values.yaml
|
||||
```
|
||||
|
||||
3. Data Backup:
|
||||
|
||||
> **For custom monitoring templates:**
|
||||
>
|
||||
> - Backup `/opt/hertzbeat/define` from the running pod:
|
||||
>
|
||||
> ```bash
|
||||
> kubectl cp hertzbeat/hertzbeat-978477f84-fr894:/opt/hertzbeat/define ./define
|
||||
> ```
|
||||
>
|
||||
> **For external databases (MySQL/PostgreSQL):**
|
||||
>
|
||||
> - Use `mysqldump`/`pg_dump` or copy PVC directories:
|
||||
>
|
||||
> ```bash
|
||||
> kubectl get pvc -n hertzbeat
|
||||
> ```
|
||||
|
||||
## 2. Upgrade Steps
|
||||
|
||||
### 1. Pull the latest Chart
|
||||
|
||||
```bash
|
||||
helm repo update
|
||||
helm pull hertzbeat/hertzbeat --version 1.7.0 --untar
|
||||
cd hertzbeat
|
||||
```
|
||||
|
||||
Or clone from GitHub:
|
||||
|
||||
```bash
|
||||
git clone https://github.com/hertzbeat/helm-charts.git
|
||||
cd helm-charts/charts/hertzbeat
|
||||
```
|
||||
|
||||
### 2. Update values.yaml
|
||||
|
||||
Compare and merge configurations:
|
||||
|
||||
```bash
|
||||
diff -u ../hertzbeat-1.6.1-values.yaml values.yaml
|
||||
# Use vimdiff to compare and merge changes
|
||||
```
|
||||
|
||||
Key configurations to check:
|
||||
|
||||
- `image.tag`
|
||||
- `resources`
|
||||
- `persistence`
|
||||
- `service.type`
|
||||
- Ingress settings
|
||||
- External database configurations
|
||||
|
||||
### 3. Dry-run Upgrade
|
||||
|
||||
```bash
|
||||
helm upgrade hertzbeat . -n <your-namespace> \
|
||||
--values values.yaml \
|
||||
--dry-run \
|
||||
--debug
|
||||
```
|
||||
|
||||
### 4. Execute Upgrade
|
||||
|
||||
```bash
|
||||
helm upgrade hertzbeat . -n <your-namespace> \
|
||||
--values values.yaml \
|
||||
--atomic \ # Auto-rollback on failure
|
||||
--timeout 10m # Set timeout
|
||||
```
|
||||
|
||||
### 5. Verify Upgrade
|
||||
|
||||
```bash
|
||||
helm status hertzbeat -n <your-namespace>
|
||||
kubectl get pods -n <your-namespace> -l app.kubernetes.io/instance=hertzbeat
|
||||
kubectl logs -n <your-namespace> -l app.kubernetes.io/instance=hertzbeat --tail=100
|
||||
```
|
||||
@@ -0,0 +1,38 @@
|
||||
---
|
||||
id: alert_integration
|
||||
title: Alert Integration
|
||||
sidebar_label: Alert Integration
|
||||
keywords:
|
||||
[
|
||||
open-source monitoring,
|
||||
alert integration,
|
||||
alert management,
|
||||
multi-source alerts,
|
||||
]
|
||||
---
|
||||
|
||||
> The alert integration module of HertzBeat is designed to achieve unified reception, standardized processing, and intelligent dispatching of alerts from various third-party monitoring and observability platforms. As a centralized "Alert Center," HertzBeat efficiently ingests external alert information and applies flexible alert management strategies.
|
||||
|
||||
### Core Capabilities
|
||||
|
||||
- **Multi-Source Alert Ingestion**: Supports receiving alert messages from major platforms such as Webhook, Prometheus, Alertmanager, SkyWalking, and Tencent Cloud.
|
||||
- **Alert Format Standardization**: Converts alerts from different platforms into a unified internal format within HertzBeat for easier processing.
|
||||
- **Comprehensive Alert Processing Mechanisms**, including:
|
||||
- **Grouping and Convergence**: Manage alerts by grouping them based on labels and deduplicate repeated alerts within a specific time window.
|
||||
- **Inhibition**: Automatically suppresses secondary alerts when specific conditions are met.
|
||||
- **Silencing**: Temporarily disables alert notifications during system maintenance or known issues to avoid unnecessary noise.
|
||||
|
||||
### Supported Alert Sources
|
||||
|
||||
HertzBeat currently supports alert integration from the following third-party monitoring platforms:
|
||||
|
||||
- **Webhook**: A generic integration method supporting customized alert format push.
|
||||
- **Prometheus**: You can configure HertzBeat’s service address directly in the Prometheus Server's Alertmanager configuration, allowing HertzBeat to replace Alertmanager for receiving and handling Prometheus Server alerts.
|
||||
- **Alertmanager**: Supports forwarding alerts from Prometheus AlertManager to the HertzBeat alert platform.
|
||||
- **SkyWalking**: Sends SkyWalking alerts to the HertzBeat alert platform via Webhook.
|
||||
- **Tencent Cloud Monitoring**: Sends Tencent Cloud alerts to the HertzBeat alert platform via Webhook.
|
||||
- **And more**:HertzBeat is actively expanding its integration support. If the integration you need is not yet available, the community is actively contributing and can assist in adding it.
|
||||
|
||||
You can view the detailed integration methods and configuration examples through the "Integration" interface in HertzBeat.
|
||||
|
||||

|
||||
+36
-31
@@ -9,40 +9,47 @@ keywords: [open-source monitoring system, open-source operating system monitorin
|
||||
|
||||
### Configuration Parameters
|
||||
|
||||
| Parameter Name | Parameter Help Description |
|
||||
|-------------------|---------------------------------------------------------------------------------------------------------------------------------------|
|
||||
| Monitoring Host | The monitored peer's IPv4, IPv6, or domain name. Note ⚠️ No protocol header (e.g., https://, http://). |
|
||||
| Task Name | A unique name to identify this monitoring task. |
|
||||
| Port | The port provided by Linux SSH, default is 22. |
|
||||
| Timeout | Set the connection timeout in milliseconds, default is 6000 ms. |
|
||||
| Connection Reuse | Set whether to reuse SSH connections, default is false. If false, a new connection will be created for each retrieval of information. |
|
||||
| Username | SSH connection username, optional. |
|
||||
| Password | SSH connection password, optional. |
|
||||
| Collector | Configure which collector to use for scheduling data collection for this monitoring. |
|
||||
| Monitoring Period | The interval time for periodic data collection, in seconds, with a minimum interval of 30 seconds. |
|
||||
| Binding Tags | Used for classifying and managing monitoring resources. |
|
||||
| Description Note | Additional notes to identify and describe this monitoring, where users can make notes. |
|
||||
| Key | The key required to connect to the server. |
|
||||
| Parameter Name | Parameter Help Description |
|
||||
|-----------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
|
||||
| Monitored Host | The IPV4, IPV6, or domain name of the host being monitored. Note ⚠️ No protocol header (e.g., https://, http://). |
|
||||
| Task Name | The name that identifies this monitoring, which must be unique. |
|
||||
| Port | The port provided by Linux SSH, default is 22. |
|
||||
| Timeout | Sets the connection timeout in milliseconds, default is 6000 ms. |
|
||||
| Connection Reuse | Sets whether SSH connections are reused, default is :false. If false, a new connection is created each time information is retrieved. |
|
||||
| Use Proxy Connection | Sets Whether connect via proxy, default is false. |
|
||||
| Username | SSH connection username, optional. |
|
||||
| Password | SSH connection password, optional. |
|
||||
| Collector | Configures which collector is used to schedule data collection for this monitoring. |
|
||||
| Monitoring Period | The interval time for periodic data collection in seconds, with a minimum interval of 30 seconds. |
|
||||
| Binding Tags | Used for categorized management of monitoring resources. |
|
||||
| Description | Additional notes and descriptions for this monitoring, where users can make notes. |
|
||||
| PrivateKey | The private key required to connect to the server. |
|
||||
| PrivateKey PassPhrase | The password phrase used to encrypt the SSH private key. If the private key was generated with a passphrase, this field must be filled to decrypt and use the key for authentication. |
|
||||
| Proxy Host | The address of the proxy server, supporting IPV4, IPV6, or domain name format. Required when using SSH jump host to access the target host. |
|
||||
| Proxy Port | The port number of the proxy service, default is 22. |
|
||||
| Proxy Username | The authentication username required to connect to the proxy server. |
|
||||
| Proxy Username | The authentication password required to connect to the proxy server. |
|
||||
| Proxy PrivateKey | The private key required to authenticate with the proxy server. |
|
||||
|
||||
### Data Collection Metrics
|
||||
|
||||
#### Metric Set: Basic System Information
|
||||
|
||||
| Metric Name | Metric Unit | Metric Help Description |
|
||||
|----------------|-------------|--------------------------|
|
||||
| Host Name | None | Host name |
|
||||
| System Version | None | Operating system version |
|
||||
| Uptime | None | Uptime |
|
||||
| Metric Name | Metric Unit | Metric Help Description |
|
||||
|-------------|-------------|-------------------------|
|
||||
| hostname | None | Host name |
|
||||
| version | None | System version |
|
||||
| uptime | None | System Uptime |
|
||||
|
||||
#### Metric Set: CPU Information
|
||||
|
||||
| Metric Name | Metric Unit | Metric Help Description |
|
||||
| Metric Name | Metric Unit | Metric Help Description |
|
||||
|----------------|-------------|-----------------------------------|
|
||||
| info | None | CPU model |
|
||||
| cores | Cores | Number of CPU cores |
|
||||
| interrupt | Count | Number of CPU interrupts |
|
||||
| cores | None | Number of CPU cores |
|
||||
| interrupt | None | Number of CPU interrupts |
|
||||
| load | None | Average CPU load (1/5/15 minutes) |
|
||||
| context_switch | Count | Number of context switches |
|
||||
| context_switch | None | Number of context switches |
|
||||
| usage | % | CPU usage |
|
||||
|
||||
#### Metric Set: Memory Information
|
||||
@@ -58,13 +65,13 @@ keywords: [open-source monitoring system, open-source operating system monitorin
|
||||
|
||||
#### Metric Set: Disk Information
|
||||
|
||||
| Metric Name | Metric Unit | Metric Help Description |
|
||||
| Metric Name | Metric Unit | Metric Help Description |
|
||||
|---------------|-------------|----------------------------------------|
|
||||
| disk_num | Count | Total number of disks |
|
||||
| partition_num | Count | Total number of partitions |
|
||||
| block_write | Blocks | Total number of blocks written to disk |
|
||||
| block_read | Blocks | Total number of blocks read from disk |
|
||||
| write_rate | IOPS | Disk block write rate per second |
|
||||
| disk_num | None | Total number of disks |
|
||||
| partition_num | None | Total number of partitions |
|
||||
| block_write | None | Total number of blocks written to disk |
|
||||
| block_read | None | Total number of blocks read from disk |
|
||||
| write_rate | iops | Disk block write rate per second |
|
||||
|
||||
#### Metric Set: Network Card Information
|
||||
|
||||
@@ -105,5 +112,3 @@ Statistics for the top 10 processes using memory. Statistics include: process ID
|
||||
| mem_usage | % | Memory usage |
|
||||
| cpu_usage | % | CPU usage |
|
||||
| command | None | Executed command |
|
||||
|
||||
---
|
||||
|
||||
+82
-49
@@ -9,73 +9,106 @@ keywords: [open source monitoring tool, open source os monitoring tool, monitori
|
||||
|
||||
### Configuration parameter
|
||||
|
||||
| Parameter name | Parameter help description |
|
||||
|---------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
|
||||
| Monitoring Host | Monitored IPV4, IPV6 or domain name. Note⚠️Without protocol header (eg: https://, http://) |
|
||||
| Monitoring name | Identify the name of this monitoring. The name needs to be unique |
|
||||
| Port | Port provided by Linux SSH. The default is 22 |
|
||||
| Username | SSH connection user name, optional |
|
||||
| Password | SSH connection password, optional |
|
||||
| Collection interval | Interval time of monitor periodic data collection, unit: second, and the minimum interval that can be set is 30 seconds |
|
||||
| Whether to detect | Whether to detect and check the availability of monitoring before adding monitoring. Adding and modifying operations will continue only after the detection is successful |
|
||||
| Description remarks | For more information about identifying and describing this monitoring, users can note information here |
|
||||
| Parameter Name | Parameter Help Description |
|
||||
|-----------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
|
||||
| Monitored Host | The IPV4, IPV6, or domain name of the host being monitored. Note ⚠️ No protocol header (e.g., https://, http://). |
|
||||
| Task Name | The name that identifies this monitoring, which must be unique. |
|
||||
| Port | The port provided by Linux SSH, default is 22. |
|
||||
| Timeout | Sets the connection timeout in milliseconds, default is 6000 ms. |
|
||||
| Connection Reuse | Sets whether SSH connections are reused, default is :false. If false, a new connection is created each time information is retrieved. |
|
||||
| Use Proxy Connection | Sets Whether connect via proxy, default is false. |
|
||||
| Username | SSH connection username, optional. |
|
||||
| Password | SSH connection password, optional. |
|
||||
| Collector | Configures which collector is used to schedule data collection for this monitoring. |
|
||||
| Monitoring Period | The interval time for periodic data collection in seconds, with a minimum interval of 30 seconds. |
|
||||
| Binding Tags | Used for categorized management of monitoring resources. |
|
||||
| Description | Additional notes and descriptions for this monitoring, where users can make notes. |
|
||||
| PrivateKey | The private key required to connect to the server. |
|
||||
| PrivateKey PassPhrase | The password phrase used to encrypt the SSH private key. If the private key was generated with a passphrase, this field must be filled to decrypt and use the key for authentication. |
|
||||
| Proxy Host | The address of the proxy server, supporting IPV4, IPV6, or domain name format. Required when using SSH jump host to access the target host. |
|
||||
| Proxy Port | The port number of the proxy service, default is 22. |
|
||||
| Proxy Username | The authentication username required to connect to the proxy server. |
|
||||
| Proxy Username | The authentication password required to connect to the proxy server. |
|
||||
| Proxy PrivateKey | The private key required to authenticate with the proxy server. |
|
||||
|
||||
### Collection Metric
|
||||
### Data Collection Metrics
|
||||
|
||||
#### Metric set:basic
|
||||
#### Metric Set: Basic System Information
|
||||
|
||||
| Metric name | Metric unit | Metric help description |
|
||||
|-------------|-------------|--------------------------|
|
||||
| hostname | none | Host name |
|
||||
| version | none | Operating system version |
|
||||
| uptime | none | System running time |
|
||||
| Metric Name | Metric Unit | Metric Help Description |
|
||||
|-------------|-------------|-------------------------|
|
||||
| hostname | None | Host name |
|
||||
| version | None | System version |
|
||||
| uptime | None | System Uptime |
|
||||
|
||||
#### Metric set:cpu
|
||||
#### Metric Set: CPU Information
|
||||
|
||||
| Metric name | Metric unit | Metric help description |
|
||||
|----------------|-------------|------------------------------------------------|
|
||||
| info | none | CPU model |
|
||||
| cores | cores | Number of CPU cores |
|
||||
| interrupt | number | Number of CPU interrupts |
|
||||
| load | none | Average load of CPU in the last 1/5/15 minutes |
|
||||
| context_switch | number | Number of current context switches |
|
||||
| usage | % | CPU usage |
|
||||
| Metric Name | Metric Unit | Metric Help Description |
|
||||
|----------------|-------------|-----------------------------------|
|
||||
| info | None | CPU model |
|
||||
| cores | None | Number of CPU cores |
|
||||
| interrupt | None | Number of CPU interrupts |
|
||||
| load | None | Average CPU load (1/5/15 minutes) |
|
||||
| context_switch | None | Number of context switches |
|
||||
| usage | % | CPU usage |
|
||||
|
||||
#### Metric set:memory
|
||||
#### Metric Set: Memory Information
|
||||
|
||||
| Metric name | Metric unit | Metric help description |
|
||||
| Metric Name | Metric Unit | Metric Help Description |
|
||||
|-------------|-------------|-------------------------------------|
|
||||
| total | Mb | Total memory capacity |
|
||||
| used | Mb | User program memory |
|
||||
| used | Mb | Memory used by user programs |
|
||||
| free | Mb | Free memory capacity |
|
||||
| buff_cache | Mb | Memory occupied by cache |
|
||||
| buff_cache | Mb | Memory used for cache |
|
||||
| available | Mb | Remaining available memory capacity |
|
||||
| usage | % | Memory usage |
|
||||
| usage | % | Memory usage rate |
|
||||
|
||||
#### Metric set:disk
|
||||
#### Metric Set: Disk Information
|
||||
|
||||
| Metric name | Metric unit | Metric help description |
|
||||
| Metric Name | Metric Unit | Metric Help Description |
|
||||
|---------------|-------------|----------------------------------------|
|
||||
| disk_num | blocks | Total number of disks |
|
||||
| partition_num | partitions | Total number of partitions |
|
||||
| block_write | blocks | Total number of blocks written to disk |
|
||||
| block_read | blocks | Number of blocks read from disk |
|
||||
| write_rate | iops | Rate of writing disk blocks per second |
|
||||
| disk_num | None | Total number of disks |
|
||||
| partition_num | None | Total number of partitions |
|
||||
| block_write | None | Total number of blocks written to disk |
|
||||
| block_read | None | Total number of blocks read from disk |
|
||||
| write_rate | iops | Disk block write rate per second |
|
||||
|
||||
#### Metric set:interface
|
||||
#### Metric Set: Network Card Information
|
||||
|
||||
| Metric name | Metric unit | Metric help description |
|
||||
|----------------|-------------|------------------------------|
|
||||
| interface_name | none | Network card name |
|
||||
| receive_bytes | byte | Inbound data traffic(bytes) |
|
||||
| transmit_bytes | byte | Outbound data traffic(bytes) |
|
||||
| Metric Name | Metric Unit | Metric Help Description |
|
||||
|----------------|-------------|-------------------------------|
|
||||
| interface_name | None | Network card name |
|
||||
| receive_bytes | Byte | Inbound data traffic (bytes) |
|
||||
| transmit_bytes | Byte | Outbound data traffic (bytes) |
|
||||
|
||||
#### Metric set:disk_free
|
||||
#### Metric Set: File System
|
||||
|
||||
| Metric name | Metric unit | Metric help description |
|
||||
| Metric Name | Metric Unit | Metric Help Description |
|
||||
|-------------|-------------|-------------------------|
|
||||
| filesystem | none | File system name |
|
||||
| filesystem | None | Name of the file system |
|
||||
| used | Mb | Used disk size |
|
||||
| available | Mb | Available disk size |
|
||||
| usage | % | usage |
|
||||
| mounted | none | Mount point directory |
|
||||
| usage | % | Usage rate |
|
||||
| mounted | None | Mount point directory |
|
||||
|
||||
#### Metric Set: Top 10 CPU Processes
|
||||
|
||||
Statistics for the top 10 processes using the CPU. Statistics include: process ID, CPU usage, memory usage, and executed command.
|
||||
|
||||
| Metric Name | Metric Unit | Metric Help Description |
|
||||
|-------------|-------------|-------------------------|
|
||||
| pid | None | Process ID |
|
||||
| cpu_usage | % | CPU usage |
|
||||
| mem_usage | % | Memory usage |
|
||||
| command | None | Executed command |
|
||||
|
||||
#### Metric Set: Top 10 Memory Processes
|
||||
|
||||
Statistics for the top 10 processes using memory. Statistics include: process ID, memory usage, CPU usage, and executed command.
|
||||
|
||||
| Metric Name | Metric Unit | Metric Help Description |
|
||||
|-------------|-------------|-------------------------|
|
||||
| pid | None | Process ID |
|
||||
| mem_usage | % | Memory usage |
|
||||
| cpu_usage | % | CPU usage |
|
||||
| command | None | Executed command |
|
||||
|
||||
+77
-60
@@ -9,89 +9,106 @@ keywords: [Open Source Monitoring System, Operating System Monitoring, Debian Mo
|
||||
|
||||
## Configuration Parameters
|
||||
|
||||
| Parameter Name | Metric help description |
|
||||
|-------------------------|-------------------------------------------------------------------------------------------------------------------|
|
||||
| Target Host | The monitored destination IPV4, IPV6, or domain name. Note: no protocol header (e.g., https://, http://). |
|
||||
| Task Name | A unique name to identify this monitoring task. |
|
||||
| Port | SSH port of the Debian system, default: 22 |
|
||||
| Timeout | Timeout for the connection, in milliseconds, default: 6000 milliseconds. |
|
||||
| Connection Reuse | Whether to reuse the SSH connection, default: false. False means a new connection will be created for each query. |
|
||||
| Username | Server username |
|
||||
| Password | Server password |
|
||||
| Collector | Configure which collector to use for scheduling this monitoring. |
|
||||
| Monitoring Period | The interval for periodically collecting data, in seconds, with a minimum interval of 30 seconds. |
|
||||
| Binding Tags | Used for categorizing and managing monitoring resources. |
|
||||
| Metric help description | Additional notes and Metric help descriptions for this monitoring, users can add notes here. |
|
||||
| Key | Key required to connect to the server. |
|
||||
| Parameter Name | Parameter Help Description |
|
||||
|-----------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
|
||||
| Monitored Host | The IPV4, IPV6, or domain name of the host being monitored. Note ⚠️ No protocol header (e.g., https://, http://). |
|
||||
| Task Name | The name that identifies this monitoring, which must be unique. |
|
||||
| Port | The port provided by Linux SSH, default is 22. |
|
||||
| Timeout | Sets the connection timeout in milliseconds, default is 6000 ms. |
|
||||
| Connection Reuse | Sets whether SSH connections are reused, default is :false. If false, a new connection is created each time information is retrieved. |
|
||||
| Use Proxy Connection | Sets Whether connect via proxy, default is false. |
|
||||
| Username | SSH connection username, optional. |
|
||||
| Password | SSH connection password, optional. |
|
||||
| Collector | Configures which collector is used to schedule data collection for this monitoring. |
|
||||
| Monitoring Period | The interval time for periodic data collection in seconds, with a minimum interval of 30 seconds. |
|
||||
| Binding Tags | Used for categorized management of monitoring resources. |
|
||||
| Description | Additional notes and descriptions for this monitoring, where users can make notes. |
|
||||
| PrivateKey | The private key required to connect to the server. |
|
||||
| PrivateKey PassPhrase | The password phrase used to encrypt the SSH private key. If the private key was generated with a passphrase, this field must be filled to decrypt and use the key for authentication. |
|
||||
| Proxy Host | The address of the proxy server, supporting IPV4, IPV6, or domain name format. Required when using SSH jump host to access the target host. |
|
||||
| Proxy Port | The port number of the proxy service, default is 22. |
|
||||
| Proxy Username | The authentication username required to connect to the proxy server. |
|
||||
| Proxy Username | The authentication password required to connect to the proxy server. |
|
||||
| Proxy PrivateKey | The private key required to authenticate with the proxy server. |
|
||||
|
||||
### Monitoring Metrics
|
||||
### Data Collection Metrics
|
||||
|
||||
#### Metric Set: Basic System Information
|
||||
|
||||
| Metric Name | Metric Unit | Metric help description |
|
||||
|----------------|-------------|--------------------------|
|
||||
| Host Name | N/A | Host name |
|
||||
| System Version | N/A | Operating system version |
|
||||
| Uptime | N/A | Boot time |
|
||||
| Metric Name | Metric Unit | Metric Help Description |
|
||||
|-------------|-------------|-------------------------|
|
||||
| hostname | None | Host name |
|
||||
| version | None | System version |
|
||||
| uptime | None | System Uptime |
|
||||
|
||||
#### Metric Set: CPU Information
|
||||
|
||||
| Metric Name | Metric Unit | Metric help description |
|
||||
|----------------|-------------|-------------------------|
|
||||
| Info | N/A | Model |
|
||||
| Cores | N/A | Number of cores |
|
||||
| Interrupt | N/A | Number of interrupts |
|
||||
| Load | N/A | Load |
|
||||
| Context Switch | N/A | Context switches |
|
||||
| Usage | % | Usage rate |
|
||||
| Metric Name | Metric Unit | Metric Help Description |
|
||||
|----------------|-------------|-----------------------------------|
|
||||
| info | None | CPU model |
|
||||
| cores | None | Number of CPU cores |
|
||||
| interrupt | None | Number of CPU interrupts |
|
||||
| load | None | Average CPU load (1/5/15 minutes) |
|
||||
| context_switch | None | Number of context switches |
|
||||
| usage | % | CPU usage |
|
||||
|
||||
#### Metric Set: Memory Information
|
||||
|
||||
| Metric Name | Metric Unit | Metric help description |
|
||||
|---------------------|-------------|------------------------------|
|
||||
| Total Memory | Mb | Total memory capacity |
|
||||
| User Program Memory | Mb | Memory used by user programs |
|
||||
| Free Memory | Mb | Free memory capacity |
|
||||
| Buff Cache Memory | Mb | Memory used by cache |
|
||||
| Available Memory | Mb | Available memory |
|
||||
| Memory Usage | % | Memory usage rate |
|
||||
| Metric Name | Metric Unit | Metric Help Description |
|
||||
|-------------|-------------|-------------------------------------|
|
||||
| total | Mb | Total memory capacity |
|
||||
| used | Mb | Memory used by user programs |
|
||||
| free | Mb | Free memory capacity |
|
||||
| buff_cache | Mb | Memory used for cache |
|
||||
| available | Mb | Remaining available memory capacity |
|
||||
| usage | % | Memory usage rate |
|
||||
|
||||
#### Metric Set: Disk Information
|
||||
|
||||
| Metric Name | Metric Unit | Metric help description |
|
||||
|---------------|-------------|-------------------------------|
|
||||
| Disk Num | N/A | Total number of disks |
|
||||
| Partition Num | N/A | Total number of partitions |
|
||||
| Block Write | N/A | Number of disk blocks written |
|
||||
| Block Read | N/A | Number of disk blocks read |
|
||||
| Write Rate | iops | Disk write rate |
|
||||
| Metric Name | Metric Unit | Metric Help Description |
|
||||
|---------------|-------------|----------------------------------------|
|
||||
| disk_num | None | Total number of disks |
|
||||
| partition_num | None | Total number of partitions |
|
||||
| block_write | None | Total number of blocks written to disk |
|
||||
| block_read | None | Total number of blocks read from disk |
|
||||
| write_rate | iops | Disk block write rate per second |
|
||||
|
||||
#### Metric Set: Network Interface Information
|
||||
#### Metric Set: Network Card Information
|
||||
|
||||
Statistics for all network interface cards, including interface name, incoming data traffic, and outgoing data traffic.
|
||||
Metric Unit: Mb
|
||||
| Metric Name | Metric Unit | Metric Help Description |
|
||||
|----------------|-------------|-------------------------------|
|
||||
| interface_name | None | Network card name |
|
||||
| receive_bytes | Byte | Inbound data traffic (bytes) |
|
||||
| transmit_bytes | Byte | Outbound data traffic (bytes) |
|
||||
|
||||
#### Metric Set: File System
|
||||
|
||||
Statistics for all mounted file systems. Statistics include: file system, usage, available space, usage rate, mount point.
|
||||
Metric Unit:
|
||||
|
||||
- Usage: Mb
|
||||
- Available Space: Mb
|
||||
- Usage Rate: %
|
||||
| Metric Name | Metric Unit | Metric Help Description |
|
||||
|-------------|-------------|-------------------------|
|
||||
| filesystem | None | Name of the file system |
|
||||
| used | Mb | Used disk size |
|
||||
| available | Mb | Available disk size |
|
||||
| usage | % | Usage rate |
|
||||
| mounted | None | Mount point directory |
|
||||
|
||||
#### Metric Set: Top 10 CPU Processes
|
||||
|
||||
Statistics for the top 10 processes by CPU usage. Statistics include: process ID, CPU usage rate, memory usage rate, command being executed.
|
||||
Metric Unit:
|
||||
Statistics for the top 10 processes using the CPU. Statistics include: process ID, CPU usage, memory usage, and executed command.
|
||||
|
||||
- CPU Usage Rate: %
|
||||
- Memory Usage Rate: %
|
||||
| Metric Name | Metric Unit | Metric Help Description |
|
||||
|-------------|-------------|-------------------------|
|
||||
| pid | None | Process ID |
|
||||
| cpu_usage | % | CPU usage |
|
||||
| mem_usage | % | Memory usage |
|
||||
| command | None | Executed command |
|
||||
|
||||
#### Metric Set: Top 10 Memory Processes
|
||||
|
||||
Statistics for the top 10 processes by memory usage. Statistics include: process ID, memory usage rate, CPU usage rate, command being executed.
|
||||
Metric Unit:
|
||||
Statistics for the top 10 processes using memory. Statistics include: process ID, memory usage, CPU usage, and executed command.
|
||||
|
||||
- Memory Usage Rate: %
|
||||
- CPU Usage Rate: %
|
||||
| Metric Name | Metric Unit | Metric Help Description |
|
||||
|-------------|-------------|-------------------------|
|
||||
| pid | None | Process ID |
|
||||
| mem_usage | % | Memory usage |
|
||||
| cpu_usage | % | CPU usage |
|
||||
| command | None | Executed command |
|
||||
|
||||
+74
-67
@@ -9,97 +9,104 @@ keywords: [ Open Source Monitoring System, Open Source OS Monitoring, EulerOS Mo
|
||||
|
||||
### Configuration Parameters
|
||||
|
||||
| Parameter Name | Parameter help description |
|
||||
|---------------------|----------------------------------------------------------------------------------------------------------------------------------|
|
||||
| Monitoring Host | The IP, IPV6, or domain name of the monitored endpoint. Note ⚠️: Do not include protocol headers (eg: https://, http://). |
|
||||
| Task Name | Identifies the name of this monitoring, ensuring uniqueness. |
|
||||
| Port | Port provided by Linux SSH externally, defaults to 22. |
|
||||
| Timeout | Sets the timeout for connection in milliseconds (ms), defaults to 6000 ms. |
|
||||
| Connection Reuse | Sets whether the SSH connection is reused, defaults to: false. Creates a new connection for each information retrieval if false. |
|
||||
| Username | SSH connection username, optional. |
|
||||
| Password | SSH connection password, optional. |
|
||||
| Collector | Specifies which collector schedules the collection for this monitoring. |
|
||||
| Monitoring Interval | Interval for periodically collecting data, in seconds. Minimum interval is 30 seconds. |
|
||||
| Binding Tags | Used for categorizing and managing monitored resources. |
|
||||
| Description | Additional remarks and descriptions for this monitoring, for users' reference. |
|
||||
| PrivateKey | Key required for connecting to the server. |
|
||||
| Parameter Name | Parameter Help Description |
|
||||
|-----------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
|
||||
| Monitored Host | The IPV4, IPV6, or domain name of the host being monitored. Note ⚠️ No protocol header (e.g., https://, http://). |
|
||||
| Task Name | The name that identifies this monitoring, which must be unique. |
|
||||
| Port | The port provided by Linux SSH, default is 22. |
|
||||
| Timeout | Sets the connection timeout in milliseconds, default is 6000 ms. |
|
||||
| Connection Reuse | Sets whether SSH connections are reused, default is :false. If false, a new connection is created each time information is retrieved. |
|
||||
| Use Proxy Connection | Sets Whether connect via proxy, default is false. |
|
||||
| Username | SSH connection username, optional. |
|
||||
| Password | SSH connection password, optional. |
|
||||
| Collector | Configures which collector is used to schedule data collection for this monitoring. |
|
||||
| Monitoring Period | The interval time for periodic data collection in seconds, with a minimum interval of 30 seconds. |
|
||||
| Binding Tags | Used for categorized management of monitoring resources. |
|
||||
| Description | Additional notes and descriptions for this monitoring, where users can make notes. |
|
||||
| PrivateKey | The private key required to connect to the server. |
|
||||
| PrivateKey PassPhrase | The password phrase used to encrypt the SSH private key. If the private key was generated with a passphrase, this field must be filled to decrypt and use the key for authentication. |
|
||||
| Proxy Host | The address of the proxy server, supporting IPV4, IPV6, or domain name format. Required when using SSH jump host to access the target host. |
|
||||
| Proxy Port | The port number of the proxy service, default is 22. |
|
||||
| Proxy Username | The authentication username required to connect to the proxy server. |
|
||||
| Proxy Username | The authentication password required to connect to the proxy server. |
|
||||
| Proxy PrivateKey | The private key required to authenticate with the proxy server. |
|
||||
|
||||
### Collected Metrics
|
||||
### Data Collection Metrics
|
||||
|
||||
#### Metric Set: Basic Info
|
||||
#### Metric Set: Basic System Information
|
||||
|
||||
| Metric Name | Metric Unit | Metric help description |
|
||||
|----------------|-------------|---------------------------|
|
||||
| Host Name | None | Host name. |
|
||||
| System Version | None | Operating system version. |
|
||||
| Uptime | None | System uptime. |
|
||||
| Metric Name | Metric Unit | Metric Help Description |
|
||||
|-------------|-------------|-------------------------|
|
||||
| hostname | None | Host name |
|
||||
| version | None | System version |
|
||||
| uptime | None | System Uptime |
|
||||
|
||||
#### Metric Set: CPU Info
|
||||
#### Metric Set: CPU Information
|
||||
|
||||
| Metric Name | Metric Unit | Metric help description |
|
||||
|----------------|-------------|-------------------------------------------|
|
||||
| info | None | CPU model. |
|
||||
| cores | None | Number of CPU cores. |
|
||||
| interrupt | None | Number of CPU interrupts. |
|
||||
| load | None | Average load for the last 1/5/15 minutes. |
|
||||
| context_switch | None | Current context switches. |
|
||||
| usage | % | CPU usage percentage. |
|
||||
| Metric Name | Metric Unit | Metric Help Description |
|
||||
|----------------|-------------|-----------------------------------|
|
||||
| info | None | CPU model |
|
||||
| cores | None | Number of CPU cores |
|
||||
| interrupt | None | Number of CPU interrupts |
|
||||
| load | None | Average CPU load (1/5/15 minutes) |
|
||||
| context_switch | None | Number of context switches |
|
||||
| usage | % | CPU usage |
|
||||
|
||||
#### Metric Set: Memory Info
|
||||
#### Metric Set: Memory Information
|
||||
|
||||
| Metric Name | Metric Unit | Metric help description |
|
||||
|-------------|-------------|------------------------------------|
|
||||
| total | Mb | Total memory capacity. |
|
||||
| used | Mb | Used memory by user programs. |
|
||||
| free | Mb | Free memory capacity. |
|
||||
| buff_cache | Mb | Memory used for buffers and cache. |
|
||||
| available | Mb | Available memory capacity. |
|
||||
| usage | % | Memory usage percentage. |
|
||||
| Metric Name | Metric Unit | Metric Help Description |
|
||||
|-------------|-------------|-------------------------------------|
|
||||
| total | Mb | Total memory capacity |
|
||||
| used | Mb | Memory used by user programs |
|
||||
| free | Mb | Free memory capacity |
|
||||
| buff_cache | Mb | Memory used for cache |
|
||||
| available | Mb | Remaining available memory capacity |
|
||||
| usage | % | Memory usage rate |
|
||||
|
||||
#### Metric Set: Disk Info
|
||||
#### Metric Set: Disk Information
|
||||
|
||||
| Metric Name | Metric Unit | Metric help description |
|
||||
|---------------|-------------|------------------------------------|
|
||||
| disk_num | None | Total number of disks. |
|
||||
| partition_num | None | Total number of partitions. |
|
||||
| block_write | None | Total blocks written to disk. |
|
||||
| block_read | None | Total blocks read from disk. |
|
||||
| write_rate | iops | Rate of blocks written per second. |
|
||||
| Metric Name | Metric Unit | Metric Help Description |
|
||||
|---------------|-------------|----------------------------------------|
|
||||
| disk_num | None | Total number of disks |
|
||||
| partition_num | None | Total number of partitions |
|
||||
| block_write | None | Total number of blocks written to disk |
|
||||
| block_read | None | Total number of blocks read from disk |
|
||||
| write_rate | iops | Disk block write rate per second |
|
||||
|
||||
#### Metric Set: Interface Info
|
||||
#### Metric Set: Network Card Information
|
||||
|
||||
| Metric Name | Metric Unit | Metric help description |
|
||||
|----------------|-------------|--------------------------------|
|
||||
| interface_name | None | Name of the network interface. |
|
||||
| receive_bytes | Mb | Inbound data traffic. |
|
||||
| transmit_bytes | Mb | Outbound data traffic. |
|
||||
| Metric Name | Metric Unit | Metric Help Description |
|
||||
|----------------|-------------|-------------------------------|
|
||||
| interface_name | None | Network card name |
|
||||
| receive_bytes | Byte | Inbound data traffic (bytes) |
|
||||
| transmit_bytes | Byte | Outbound data traffic (bytes) |
|
||||
|
||||
#### Metric Set: Disk Free
|
||||
#### Metric Set: File System
|
||||
|
||||
| Metric Name | Metric Unit | Metric help description |
|
||||
|-------------|-------------|--------------------------|
|
||||
| filesystem | None | Name of the file system. |
|
||||
| used | Mb | Used disk space. |
|
||||
| available | Mb | Available disk space. |
|
||||
| usage | % | Disk usage percentage. |
|
||||
| mounted | None | Mount point directory. |
|
||||
| Metric Name | Metric Unit | Metric Help Description |
|
||||
|-------------|-------------|-------------------------|
|
||||
| filesystem | None | Name of the file system |
|
||||
| used | Mb | Used disk size |
|
||||
| available | Mb | Available disk size |
|
||||
| usage | % | Usage rate |
|
||||
| mounted | None | Mount point directory |
|
||||
|
||||
#### Metric Set: Top10 CPU Process
|
||||
#### Metric Set: Top 10 CPU Processes
|
||||
|
||||
Top 10 processes consuming CPU. Metrics include: Process ID, CPU usage, Memory usage, Command.
|
||||
Statistics for the top 10 processes using the CPU. Statistics include: process ID, CPU usage, memory usage, and executed command.
|
||||
|
||||
| Metric Name | Metric Unit | Metric help description |
|
||||
| Metric Name | Metric Unit | Metric Help Description |
|
||||
|-------------|-------------|-------------------------|
|
||||
| pid | None | Process ID |
|
||||
| cpu_usage | % | CPU usage |
|
||||
| mem_usage | % | Memory usage |
|
||||
| command | None | Executed command |
|
||||
|
||||
#### Metric Set: Top10 Memory Process
|
||||
#### Metric Set: Top 10 Memory Processes
|
||||
|
||||
Top 10 processes consuming memory. Metrics include: Process ID, Memory usage, CPU usage, Command.
|
||||
Statistics for the top 10 processes using memory. Statistics include: process ID, memory usage, CPU usage, and executed command.
|
||||
|
||||
| Metric Name | Metric Unit | Metric help description |
|
||||
| Metric Name | Metric Unit | Metric Help Description |
|
||||
|-------------|-------------|-------------------------|
|
||||
| pid | None | Process ID |
|
||||
| mem_usage | % | Memory usage |
|
||||
|
||||
@@ -0,0 +1,114 @@
|
||||
---
|
||||
id: fedora
|
||||
title: Monitoring Fedora Operating System
|
||||
sidebar_label: Fedora OS Operating System
|
||||
keywords: [ Open Source Monitoring System, Open Source OS Monitoring, Fedora OS Monitoring ]
|
||||
---
|
||||
|
||||
> Collect and monitor general performance metrics for Fedora operating systems (system information, CPU, memory, disk, network interface, file system, top resource processes, etc.).
|
||||
|
||||
### Configuration Parameters
|
||||
|
||||
| Parameter Name | Parameter Help Description |
|
||||
|-----------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
|
||||
| Monitored Host | The IPV4, IPV6, or domain name of the host being monitored. Note ⚠️ No protocol header (e.g., https://, http://). |
|
||||
| Task Name | The name that identifies this monitoring, which must be unique. |
|
||||
| Port | The port provided by Linux SSH, default is 22. |
|
||||
| Timeout | Sets the connection timeout in milliseconds, default is 6000 ms. |
|
||||
| Connection Reuse | Sets whether SSH connections are reused, default is :false. If false, a new connection is created each time information is retrieved. |
|
||||
| Use Proxy Connection | Sets Whether connect via proxy, default is false. |
|
||||
| Username | SSH connection username, optional. |
|
||||
| Password | SSH connection password, optional. |
|
||||
| Collector | Configures which collector is used to schedule data collection for this monitoring. |
|
||||
| Monitoring Period | The interval time for periodic data collection in seconds, with a minimum interval of 30 seconds. |
|
||||
| Binding Tags | Used for categorized management of monitoring resources. |
|
||||
| Description | Additional notes and descriptions for this monitoring, where users can make notes. |
|
||||
| PrivateKey | The private key required to connect to the server. |
|
||||
| PrivateKey PassPhrase | The password phrase used to encrypt the SSH private key. If the private key was generated with a passphrase, this field must be filled to decrypt and use the key for authentication. |
|
||||
| Proxy Host | The address of the proxy server, supporting IPV4, IPV6, or domain name format. Required when using SSH jump host to access the target host. |
|
||||
| Proxy Port | The port number of the proxy service, default is 22. |
|
||||
| Proxy Username | The authentication username required to connect to the proxy server. |
|
||||
| Proxy Username | The authentication password required to connect to the proxy server. |
|
||||
| Proxy PrivateKey | The private key required to authenticate with the proxy server. |
|
||||
|
||||
### Data Collection Metrics
|
||||
|
||||
#### Metric Set: Basic System Information
|
||||
|
||||
| Metric Name | Metric Unit | Metric Help Description |
|
||||
|-------------|-------------|-------------------------|
|
||||
| hostname | None | Host name |
|
||||
| version | None | System version |
|
||||
| uptime | None | System Uptime |
|
||||
|
||||
#### Metric Set: CPU Information
|
||||
|
||||
| Metric Name | Metric Unit | Metric Help Description |
|
||||
|----------------|-------------|-----------------------------------|
|
||||
| info | None | CPU model |
|
||||
| cores | None | Number of CPU cores |
|
||||
| interrupt | None | Number of CPU interrupts |
|
||||
| load | None | Average CPU load (1/5/15 minutes) |
|
||||
| context_switch | None | Number of context switches |
|
||||
| usage | % | CPU usage |
|
||||
|
||||
#### Metric Set: Memory Information
|
||||
|
||||
| Metric Name | Metric Unit | Metric Help Description |
|
||||
|-------------|-------------|-------------------------------------|
|
||||
| total | Mb | Total memory capacity |
|
||||
| used | Mb | Memory used by user programs |
|
||||
| free | Mb | Free memory capacity |
|
||||
| buff_cache | Mb | Memory used for cache |
|
||||
| available | Mb | Remaining available memory capacity |
|
||||
| usage | % | Memory usage rate |
|
||||
|
||||
#### Metric Set: Disk Information
|
||||
|
||||
| Metric Name | Metric Unit | Metric Help Description |
|
||||
|---------------|-------------|----------------------------------------|
|
||||
| disk_num | None | Total number of disks |
|
||||
| partition_num | None | Total number of partitions |
|
||||
| block_write | None | Total number of blocks written to disk |
|
||||
| block_read | None | Total number of blocks read from disk |
|
||||
| write_rate | iops | Disk block write rate per second |
|
||||
|
||||
#### Metric Set: Network Card Information
|
||||
|
||||
| Metric Name | Metric Unit | Metric Help Description |
|
||||
|----------------|-------------|-------------------------------|
|
||||
| interface_name | None | Network card name |
|
||||
| receive_bytes | Byte | Inbound data traffic (bytes) |
|
||||
| transmit_bytes | Byte | Outbound data traffic (bytes) |
|
||||
|
||||
#### Metric Set: File System
|
||||
|
||||
| Metric Name | Metric Unit | Metric Help Description |
|
||||
|-------------|-------------|-------------------------|
|
||||
| filesystem | None | Name of the file system |
|
||||
| used | Mb | Used disk size |
|
||||
| available | Mb | Available disk size |
|
||||
| usage | % | Usage rate |
|
||||
| mounted | None | Mount point directory |
|
||||
|
||||
#### Metric Set: Top 10 CPU Processes
|
||||
|
||||
Statistics for the top 10 processes using the CPU. Statistics include: process ID, CPU usage, memory usage, and executed command.
|
||||
|
||||
| Metric Name | Metric Unit | Metric Help Description |
|
||||
|-------------|-------------|-------------------------|
|
||||
| pid | None | Process ID |
|
||||
| cpu_usage | % | CPU usage |
|
||||
| mem_usage | % | Memory usage |
|
||||
| command | None | Executed command |
|
||||
|
||||
#### Metric Set: Top 10 Memory Processes
|
||||
|
||||
Statistics for the top 10 processes using memory. Statistics include: process ID, memory usage, CPU usage, and executed command.
|
||||
|
||||
| Metric Name | Metric Unit | Metric Help Description |
|
||||
|-------------|-------------|-------------------------|
|
||||
| pid | None | Process ID |
|
||||
| mem_usage | % | Memory usage |
|
||||
| cpu_usage | % | CPU usage |
|
||||
| command | None | Executed command |
|
||||
+29
-22
@@ -9,40 +9,47 @@ keywords: [ Open Source Monitoring System, Open Source Operating System Monitori
|
||||
|
||||
### Configuration Parameters
|
||||
|
||||
| Parameter Name | Parameter help description |
|
||||
|---------------------|------------------------------------------------------------------------------------------------------------------------------|
|
||||
| Monitoring Host | The IPv4, IPv6, or domain name of the monitored peer. Note ⚠️ without the protocol header (eg: https://, http://). |
|
||||
| Task Name | Identifies the name of this monitor, ensuring uniqueness of the name. |
|
||||
| Port | The port where SSH for Linux is exposed, default is 22. |
|
||||
| Timeout | Set the connection timeout, in milliseconds, default is 6000 milliseconds. |
|
||||
| Reuse Connection | Set whether SSH connections are reused, default is: false. If false, a connection is created for each information retrieval. |
|
||||
| Username | SSH connection username, optional. |
|
||||
| Password | SSH connection password, optional. |
|
||||
| Collector | Configure which collector to use for scheduling collection for this monitor. |
|
||||
| Monitoring Interval | Interval for periodically collecting data, in seconds. The minimum interval that can be set is 30 seconds. |
|
||||
| Bind Labels | Used to categorize and manage monitored resources. |
|
||||
| Description | Additional information for identifying and describing this monitor. Users can add remarks here. |
|
||||
| PrivateKey | Private key required to connect to the server. |
|
||||
| Parameter Name | Parameter Help Description |
|
||||
|-----------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
|
||||
| Monitored Host | The IPV4, IPV6, or domain name of the host being monitored. Note ⚠️ No protocol header (e.g., https://, http://). |
|
||||
| Task Name | The name that identifies this monitoring, which must be unique. |
|
||||
| Port | The port provided by Linux SSH, default is 22. |
|
||||
| Timeout | Sets the connection timeout in milliseconds, default is 6000 ms. |
|
||||
| Connection Reuse | Sets whether SSH connections are reused, default is :false. If false, a new connection is created each time information is retrieved. |
|
||||
| Use Proxy Connection | Sets Whether connect via proxy, default is false. |
|
||||
| Username | SSH connection username, optional. |
|
||||
| Password | SSH connection password, optional. |
|
||||
| Collector | Configures which collector is used to schedule data collection for this monitoring. |
|
||||
| Monitoring Period | The interval time for periodic data collection in seconds, with a minimum interval of 30 seconds. |
|
||||
| Binding Tags | Used for categorized management of monitoring resources. |
|
||||
| Description | Additional notes and descriptions for this monitoring, where users can make notes. |
|
||||
| PrivateKey | The private key required to connect to the server. |
|
||||
| PrivateKey PassPhrase | The password phrase used to encrypt the SSH private key. If the private key was generated with a passphrase, this field must be filled to decrypt and use the key for authentication. |
|
||||
| Proxy Host | The address of the proxy server, supporting IPV4, IPV6, or domain name format. Required when using SSH jump host to access the target host. |
|
||||
| Proxy Port | The port number of the proxy service, default is 22. |
|
||||
| Proxy Username | The authentication username required to connect to the proxy server. |
|
||||
| Proxy Username | The authentication password required to connect to the proxy server. |
|
||||
| Proxy PrivateKey | The private key required to authenticate with the proxy server. |
|
||||
|
||||
### Collection Metrics
|
||||
|
||||
#### Metric Set: Basic Info
|
||||
|
||||
| Metric Name | Metric Unit | Metric help description |
|
||||
|----------------|-------------|--------------------------|
|
||||
| Host Name | None | Host name |
|
||||
| System Version | None | Operating system version |
|
||||
| Uptime | None | System uptime |
|
||||
| Metric Name | Metric Unit | Metric Help Description |
|
||||
|-------------|-------------|-------------------------|
|
||||
| hostname | None | Host name |
|
||||
| version | None | System version |
|
||||
| uptime | None | System Uptime |
|
||||
|
||||
#### Metric Set: CPU Info
|
||||
|
||||
| Metric Name | Metric Unit | Metric help description |
|
||||
|----------------|-------------|----------------------------------------------|
|
||||
| info | None | CPU model |
|
||||
| cores | Number | Number of CPU cores |
|
||||
| interrupt | Number | Number of CPU interrupts |
|
||||
| cores | None | Number of CPU cores |
|
||||
| interrupt | None | Number of CPU interrupts |
|
||||
| load | None | Average CPU load for the last 1/5/15 minutes |
|
||||
| context_switch | Number | Current context switches |
|
||||
| context_switch | None | Current context switches |
|
||||
| usage | % | CPU usage |
|
||||
|
||||
#### Metric Set: Memory Info
|
||||
|
||||
+82
-49
@@ -9,73 +9,106 @@ keywords: [open source monitoring tool, open source linux monitoring tool, monit
|
||||
|
||||
### Configuration parameter
|
||||
|
||||
| Parameter name | Parameter help description |
|
||||
|---------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
|
||||
| Monitoring Host | Monitored IPV4, IPV6 or domain name. Note⚠️Without protocol header (eg: https://, http://) |
|
||||
| Monitoring name | Identify the name of this monitoring. The name needs to be unique |
|
||||
| Port | Port provided by Linux SSH. The default is 22 |
|
||||
| Username | SSH connection user name, optional |
|
||||
| Password | SSH connection password, optional |
|
||||
| Collection interval | Interval time of monitor periodic data collection, unit: second, and the minimum interval that can be set is 30 seconds |
|
||||
| Whether to detect | Whether to detect and check the availability of monitoring before adding monitoring. Adding and modifying operations will continue only after the detection is successful |
|
||||
| Description remarks | For more information about identifying and describing this monitoring, users can note information here |
|
||||
| Parameter Name | Parameter Help Description |
|
||||
|-----------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
|
||||
| Monitored Host | The IPV4, IPV6, or domain name of the host being monitored. Note ⚠️ No protocol header (e.g., https://, http://). |
|
||||
| Task Name | The name that identifies this monitoring, which must be unique. |
|
||||
| Port | The port provided by Linux SSH, default is 22. |
|
||||
| Timeout | Sets the connection timeout in milliseconds, default is 6000 ms. |
|
||||
| Connection Reuse | Sets whether SSH connections are reused, default is :false. If false, a new connection is created each time information is retrieved. |
|
||||
| Use Proxy Connection | Sets Whether connect via proxy, default is false. |
|
||||
| Username | SSH connection username, optional. |
|
||||
| Password | SSH connection password, optional. |
|
||||
| Collector | Configures which collector is used to schedule data collection for this monitoring. |
|
||||
| Monitoring Period | The interval time for periodic data collection in seconds, with a minimum interval of 30 seconds. |
|
||||
| Binding Tags | Used for categorized management of monitoring resources. |
|
||||
| Description | Additional notes and descriptions for this monitoring, where users can make notes. |
|
||||
| PrivateKey | The private key required to connect to the server. |
|
||||
| PrivateKey PassPhrase | The password phrase used to encrypt the SSH private key. If the private key was generated with a passphrase, this field must be filled to decrypt and use the key for authentication. |
|
||||
| Proxy Host | The address of the proxy server, supporting IPV4, IPV6, or domain name format. Required when using SSH jump host to access the target host. |
|
||||
| Proxy Port | The port number of the proxy service, default is 22. |
|
||||
| Proxy Username | The authentication username required to connect to the proxy server. |
|
||||
| Proxy Username | The authentication password required to connect to the proxy server. |
|
||||
| Proxy PrivateKey | The private key required to authenticate with the proxy server. |
|
||||
|
||||
### Collection Metric
|
||||
### Data Collection Metrics
|
||||
|
||||
#### Metric set:basic
|
||||
#### Metric Set: Basic System Information
|
||||
|
||||
| Metric name | Metric unit | Metric help description |
|
||||
|-------------|-------------|--------------------------|
|
||||
| hostname | none | Host name |
|
||||
| version | none | Operating system version |
|
||||
| uptime | none | System running time |
|
||||
| Metric Name | Metric Unit | Metric Help Description |
|
||||
|-------------|-------------|-------------------------|
|
||||
| hostname | None | Host name |
|
||||
| version | None | System version |
|
||||
| uptime | None | System Uptime |
|
||||
|
||||
#### Metric set:cpu
|
||||
#### Metric Set: CPU Information
|
||||
|
||||
| Metric name | Metric unit | Metric help description |
|
||||
|----------------|-------------|------------------------------------------------|
|
||||
| info | none | CPU model |
|
||||
| cores | cores | Number of CPU cores |
|
||||
| interrupt | number | Number of CPU interrupts |
|
||||
| load | none | Average load of CPU in the last 1/5/15 minutes |
|
||||
| context_switch | number | Number of current context switches |
|
||||
| usage | % | CPU usage |
|
||||
| Metric Name | Metric Unit | Metric Help Description |
|
||||
|----------------|-------------|-----------------------------------|
|
||||
| info | None | CPU model |
|
||||
| cores | None | Number of CPU cores |
|
||||
| interrupt | None | Number of CPU interrupts |
|
||||
| load | None | Average CPU load (1/5/15 minutes) |
|
||||
| context_switch | None | Number of context switches |
|
||||
| usage | % | CPU usage |
|
||||
|
||||
#### Metric set:memory
|
||||
#### Metric Set: Memory Information
|
||||
|
||||
| Metric name | Metric unit | Metric help description |
|
||||
| Metric Name | Metric Unit | Metric Help Description |
|
||||
|-------------|-------------|-------------------------------------|
|
||||
| total | Mb | Total memory capacity |
|
||||
| used | Mb | User program memory |
|
||||
| used | Mb | Memory used by user programs |
|
||||
| free | Mb | Free memory capacity |
|
||||
| buff_cache | Mb | Memory occupied by cache |
|
||||
| buff_cache | Mb | Memory used for cache |
|
||||
| available | Mb | Remaining available memory capacity |
|
||||
| usage | % | Memory usage |
|
||||
| usage | % | Memory usage rate |
|
||||
|
||||
#### Metric set:disk
|
||||
#### Metric Set: Disk Information
|
||||
|
||||
| Metric name | Metric unit | Metric help description |
|
||||
| Metric Name | Metric Unit | Metric Help Description |
|
||||
|---------------|-------------|----------------------------------------|
|
||||
| disk_num | blocks | Total number of disks |
|
||||
| partition_num | partitions | Total number of partitions |
|
||||
| block_write | blocks | Total number of blocks written to disk |
|
||||
| block_read | blocks | Number of blocks read from disk |
|
||||
| write_rate | iops | Rate of writing disk blocks per second |
|
||||
| disk_num | None | Total number of disks |
|
||||
| partition_num | None | Total number of partitions |
|
||||
| block_write | None | Total number of blocks written to disk |
|
||||
| block_read | None | Total number of blocks read from disk |
|
||||
| write_rate | iops | Disk block write rate per second |
|
||||
|
||||
#### Metric set:interface
|
||||
#### Metric Set: Network Card Information
|
||||
|
||||
| Metric name | Metric unit | Metric help description |
|
||||
|----------------|-------------|------------------------------|
|
||||
| interface_name | none | Network card name |
|
||||
| receive_bytes | byte | Inbound data traffic(bytes) |
|
||||
| transmit_bytes | byte | Outbound data traffic(bytes) |
|
||||
| Metric Name | Metric Unit | Metric Help Description |
|
||||
|----------------|-------------|-------------------------------|
|
||||
| interface_name | None | Network card name |
|
||||
| receive_bytes | Byte | Inbound data traffic (bytes) |
|
||||
| transmit_bytes | Byte | Outbound data traffic (bytes) |
|
||||
|
||||
#### Metric set:disk_free
|
||||
#### Metric Set: File System
|
||||
|
||||
| Metric name | Metric unit | Metric help description |
|
||||
| Metric Name | Metric Unit | Metric Help Description |
|
||||
|-------------|-------------|-------------------------|
|
||||
| filesystem | none | File system name |
|
||||
| filesystem | None | Name of the file system |
|
||||
| used | Mb | Used disk size |
|
||||
| available | Mb | Available disk size |
|
||||
| usage | % | usage |
|
||||
| mounted | none | Mount point directory |
|
||||
| usage | % | Usage rate |
|
||||
| mounted | None | Mount point directory |
|
||||
|
||||
#### Metric Set: Top 10 CPU Processes
|
||||
|
||||
Statistics for the top 10 processes using the CPU. Statistics include: process ID, CPU usage, memory usage, and executed command.
|
||||
|
||||
| Metric Name | Metric Unit | Metric Help Description |
|
||||
|-------------|-------------|-------------------------|
|
||||
| pid | None | Process ID |
|
||||
| cpu_usage | % | CPU usage |
|
||||
| mem_usage | % | Memory usage |
|
||||
| command | None | Executed command |
|
||||
|
||||
#### Metric Set: Top 10 Memory Processes
|
||||
|
||||
Statistics for the top 10 processes using memory. Statistics include: process ID, memory usage, CPU usage, and executed command.
|
||||
|
||||
| Metric Name | Metric Unit | Metric Help Description |
|
||||
|-------------|-------------|-------------------------|
|
||||
| pid | None | Process ID |
|
||||
| mem_usage | % | Memory usage |
|
||||
| cpu_usage | % | CPU usage |
|
||||
| command | None | Executed command |
|
||||
|
||||
+77
-70
@@ -9,99 +9,106 @@ keywords: [open source monitoring system, open source operating system monitorin
|
||||
|
||||
### Configuration Parameters
|
||||
|
||||
| Parameter Name | Parameter Help Description |
|
||||
|-------------------|---------------------------------------------------------------------------------------------------------------------------------------|
|
||||
| Monitored Host | The IPV4, IPV6, or domain name of the host being monitored. Note ⚠️ No protocol header (e.g., https://, http://). |
|
||||
| Task Name | The name that identifies this monitoring, which must be unique. |
|
||||
| Port | The port provided by Linux SSH, default is 22. |
|
||||
| Timeout | Sets the connection timeout in milliseconds, default is 6000 ms. |
|
||||
| Connection Reuse | Sets whether SSH connections are reused, default is :false. If false, a new connection is created each time information is retrieved. |
|
||||
| Username | SSH connection username, optional. |
|
||||
| Password | SSH connection password, optional. |
|
||||
| Collector | Configures which collector is used to schedule data collection for this monitoring. |
|
||||
| Monitoring Period | The interval time for periodic data collection in seconds, with a minimum interval of 30 seconds. |
|
||||
| Binding Tags | Used for categorized management of monitoring resources. |
|
||||
| Description | Additional notes and descriptions for this monitoring, where users can make notes. |
|
||||
| Key | The key required to connect to the server. |
|
||||
| Parameter Name | Parameter Help Description |
|
||||
|-----------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
|
||||
| Monitored Host | The IPV4, IPV6, or domain name of the host being monitored. Note ⚠️ No protocol header (e.g., https://, http://). |
|
||||
| Task Name | The name that identifies this monitoring, which must be unique. |
|
||||
| Port | The port provided by Linux SSH, default is 22. |
|
||||
| Timeout | Sets the connection timeout in milliseconds, default is 6000 ms. |
|
||||
| Connection Reuse | Sets whether SSH connections are reused, default is :false. If false, a new connection is created each time information is retrieved. |
|
||||
| Use Proxy Connection | Sets Whether connect via proxy, default is false. |
|
||||
| Username | SSH connection username, optional. |
|
||||
| Password | SSH connection password, optional. |
|
||||
| Collector | Configures which collector is used to schedule data collection for this monitoring. |
|
||||
| Monitoring Period | The interval time for periodic data collection in seconds, with a minimum interval of 30 seconds. |
|
||||
| Binding Tags | Used for categorized management of monitoring resources. |
|
||||
| Description | Additional notes and descriptions for this monitoring, where users can make notes. |
|
||||
| PrivateKey | The private key required to connect to the server. |
|
||||
| PrivateKey PassPhrase | The password phrase used to encrypt the SSH private key. If the private key was generated with a passphrase, this field must be filled to decrypt and use the key for authentication. |
|
||||
| Proxy Host | The address of the proxy server, supporting IPV4, IPV6, or domain name format. Required when using SSH jump host to access the target host. |
|
||||
| Proxy Port | The port number of the proxy service, default is 22. |
|
||||
| Proxy Username | The authentication username required to connect to the proxy server. |
|
||||
| Proxy Username | The authentication password required to connect to the proxy server. |
|
||||
| Proxy PrivateKey | The private key required to authenticate with the proxy server. |
|
||||
|
||||
### Collection Metrics
|
||||
### Data Collection Metrics
|
||||
|
||||
#### Metric Set: System Basic Information
|
||||
#### Metric Set: Basic System Information
|
||||
|
||||
| Metric Name | Unit | Metric Help Description |
|
||||
|----------------|------|--------------------------|
|
||||
| Host Name | None | Host name |
|
||||
| System Version | None | Operating system version |
|
||||
| Uptime | None | Uptime |
|
||||
| Metric Name | Metric Unit | Metric Help Description |
|
||||
|-------------|-------------|-------------------------|
|
||||
| hostname | None | Host name |
|
||||
| version | None | System version |
|
||||
| uptime | None | System Uptime |
|
||||
|
||||
#### Metric Set: CPU Information
|
||||
|
||||
| Metric Name | Unit | Metric Help Description |
|
||||
|----------------|-------|-----------------------------------------------|
|
||||
| info | None | CPU model |
|
||||
| cores | Cores | Number of CPU cores |
|
||||
| interrupt | Count | Number of CPU interrupts |
|
||||
| load | None | Average CPU load over the last 1/5/15 minutes |
|
||||
| context_switch | Count | Number of context switches |
|
||||
| usage | % | CPU usage rate |
|
||||
| Metric Name | Metric Unit | Metric Help Description |
|
||||
|----------------|-------------|-----------------------------------|
|
||||
| info | None | CPU model |
|
||||
| cores | None | Number of CPU cores |
|
||||
| interrupt | None | Number of CPU interrupts |
|
||||
| load | None | Average CPU load (1/5/15 minutes) |
|
||||
| context_switch | None | Number of context switches |
|
||||
| usage | % | CPU usage |
|
||||
|
||||
#### Metric Set: Memory Information
|
||||
|
||||
| Metric Name | Unit | Metric Help Description |
|
||||
|-------------|------|-------------------------------------|
|
||||
| total | Mb | Total memory capacity |
|
||||
| used | Mb | Memory used by user programs |
|
||||
| free | Mb | Free memory capacity |
|
||||
| buff_cache | Mb | Memory used for cache |
|
||||
| available | Mb | Remaining available memory capacity |
|
||||
| usage | % | Memory usage rate |
|
||||
| Metric Name | Metric Unit | Metric Help Description |
|
||||
|-------------|-------------|-------------------------------------|
|
||||
| total | Mb | Total memory capacity |
|
||||
| used | Mb | Memory used by user programs |
|
||||
| free | Mb | Free memory capacity |
|
||||
| buff_cache | Mb | Memory used for cache |
|
||||
| available | Mb | Remaining available memory capacity |
|
||||
| usage | % | Memory usage rate |
|
||||
|
||||
#### Metric Set: Disk Information
|
||||
|
||||
| Metric Name | Unit | Metric Help Description |
|
||||
|---------------|-------|----------------------------------------|
|
||||
| disk_num | Count | Total number of disks |
|
||||
| partition_num | Count | Total number of partitions |
|
||||
| block_write | Count | Total number of blocks written to disk |
|
||||
| block_read | Count | Total number of blocks read from disk |
|
||||
| write_rate | iops | Disk block write rate per second |
|
||||
| Metric Name | Metric Unit | Metric Help Description |
|
||||
|---------------|-------------|----------------------------------------|
|
||||
| disk_num | None | Total number of disks |
|
||||
| partition_num | None | Total number of partitions |
|
||||
| block_write | None | Total number of blocks written to disk |
|
||||
| block_read | None | Total number of blocks read from disk |
|
||||
| write_rate | iops | Disk block write rate per second |
|
||||
|
||||
#### Metric Set: Network Card Information
|
||||
|
||||
| Metric Name | Unit | Metric Help Description |
|
||||
|----------------|------|-------------------------|
|
||||
| interface_name | None | Network card name |
|
||||
| receive_bytes | Mb | Inbound data traffic |
|
||||
| transmit_bytes | Mb | Outbound data traffic |
|
||||
| Metric Name | Metric Unit | Metric Help Description |
|
||||
|----------------|-------------|-------------------------------|
|
||||
| interface_name | None | Network card name |
|
||||
| receive_bytes | Byte | Inbound data traffic (bytes) |
|
||||
| transmit_bytes | Byte | Outbound data traffic (bytes) |
|
||||
|
||||
#### Metric Set: File System
|
||||
|
||||
| Metric Name | Unit | Metric Help Description |
|
||||
|-------------|------|-------------------------|
|
||||
| filesystem | None | Name of the file system |
|
||||
| used | Mb | Used disk size |
|
||||
| available | Mb | Available disk size |
|
||||
| usage | % | Usage rate |
|
||||
| mounted | None | Mount point directory |
|
||||
| Metric Name | Metric Unit | Metric Help Description |
|
||||
|-------------|-------------|-------------------------|
|
||||
| filesystem | None | Name of the file system |
|
||||
| used | Mb | Used disk size |
|
||||
| available | Mb | Available disk size |
|
||||
| usage | % | Usage rate |
|
||||
| mounted | None | Mount point directory |
|
||||
|
||||
#### Metric Set: Top 10 CPU Processes
|
||||
|
||||
Statistics for the top 10 processes using the CPU. Statistics include: Process ID, CPU usage, memory usage, executed command.
|
||||
Statistics for the top 10 processes using the CPU. Statistics include: process ID, CPU usage, memory usage, and executed command.
|
||||
|
||||
| Metric Name | Unit | Metric Help Description |
|
||||
|-------------|------|-------------------------|
|
||||
| pid | None | Process ID |
|
||||
| cpu_usage | % | CPU usage rate |
|
||||
| mem_usage | % | Memory usage rate |
|
||||
| command | None | Executed command |
|
||||
| Metric Name | Metric Unit | Metric Help Description |
|
||||
|-------------|-------------|-------------------------|
|
||||
| pid | None | Process ID |
|
||||
| cpu_usage | % | CPU usage |
|
||||
| mem_usage | % | Memory usage |
|
||||
| command | None | Executed command |
|
||||
|
||||
#### Metric Set: Top 10 Memory Processes
|
||||
|
||||
Statistics for the top 10 processes using memory. Statistics include: Process ID, memory usage, CPU usage, executed command.
|
||||
Statistics for the top 10 processes using memory. Statistics include: process ID, memory usage, CPU usage, and executed command.
|
||||
|
||||
| Metric Name | Unit | Metric Help Description |
|
||||
|-------------|------|-------------------------|
|
||||
| pid | None | Process ID |
|
||||
| mem_usage | % | Memory usage rate |
|
||||
| cpu_usage | % | CPU usage rate |
|
||||
| command | None | Executed command |
|
||||
| Metric Name | Metric Unit | Metric Help Description |
|
||||
|-------------|-------------|-------------------------|
|
||||
| pid | None | Process ID |
|
||||
| mem_usage | % | Memory usage |
|
||||
| cpu_usage | % | CPU usage |
|
||||
| command | None | Executed command |
|
||||
|
||||
@@ -9,7 +9,7 @@ keywords: [open source monitoring tool, open source database monitoring tool, mo
|
||||
|
||||
### Attention, Need Add ORACLE jdbc driver jar
|
||||
|
||||
- Download the ORACLE jdbc driver jar package, such as [ojdbc8.jar](https://download.oracle.com/otn-pub/otn_software/jdbc/234/ojdbc8.jar) [oracle-i18n](https://repo.mavenlibs.com/maven/com/oracle/database/nls/orai18n/21.5.0.0/orai18n-21.5.0.0.jar)
|
||||
- Download the ORACLE jdbc driver jar package, such as [ojdbc8.jar](https://repo1.maven.org/maven2/com/oracle/database/jdbc/ojdbc8/23.4.0.24.05/ojdbc8-23.4.0.24.05.jar) [oracle-i18n](https://repo.mavenlibs.com/maven/com/oracle/database/nls/orai18n/21.5.0.0/orai18n-21.5.0.0.jar)
|
||||
- Copy the jar package to the `hertzbeat/ext-lib` directory.
|
||||
- Restart the HertzBeat service.
|
||||
|
||||
|
||||
+74
-67
@@ -9,97 +9,104 @@ keywords: [ Open Source Monitoring System, Open Source OS Monitoring, RedHat OS
|
||||
|
||||
### Configuration Parameters
|
||||
|
||||
| Parameter Name | Parameter help description |
|
||||
|---------------------|----------------------------------------------------------------------------------------------------------------------------------|
|
||||
| Monitoring Host | The IP, IPV6, or domain name of the monitored endpoint. Note ⚠️: Do not include protocol headers (eg: https://, http://). |
|
||||
| Task Name | Identifies the name of this monitoring, ensuring uniqueness. |
|
||||
| Port | Port provided by Linux SSH externally, defaults to 22. |
|
||||
| Timeout | Sets the timeout for connection in milliseconds (ms), defaults to 6000 ms. |
|
||||
| Connection Reuse | Sets whether the SSH connection is reused, defaults to: false. Creates a new connection for each information retrieval if false. |
|
||||
| Username | SSH connection username, optional. |
|
||||
| Password | SSH connection password, optional. |
|
||||
| Collector | Specifies which collector schedules the collection for this monitoring. |
|
||||
| Monitoring Interval | Interval for periodically collecting data, in seconds. Minimum interval is 30 seconds. |
|
||||
| Binding Tags | Used for categorizing and managing monitored resources. |
|
||||
| Description | Additional remarks and descriptions for this monitoring, for users' reference. |
|
||||
| PrivateKey | Key required for connecting to the server. |
|
||||
| Parameter Name | Parameter Help Description |
|
||||
|-----------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
|
||||
| Monitored Host | The IPV4, IPV6, or domain name of the host being monitored. Note ⚠️ No protocol header (e.g., https://, http://). |
|
||||
| Task Name | The name that identifies this monitoring, which must be unique. |
|
||||
| Port | The port provided by Linux SSH, default is 22. |
|
||||
| Timeout | Sets the connection timeout in milliseconds, default is 6000 ms. |
|
||||
| Connection Reuse | Sets whether SSH connections are reused, default is :false. If false, a new connection is created each time information is retrieved. |
|
||||
| Use Proxy Connection | Sets Whether connect via proxy, default is false. |
|
||||
| Username | SSH connection username, optional. |
|
||||
| Password | SSH connection password, optional. |
|
||||
| Collector | Configures which collector is used to schedule data collection for this monitoring. |
|
||||
| Monitoring Period | The interval time for periodic data collection in seconds, with a minimum interval of 30 seconds. |
|
||||
| Binding Tags | Used for categorized management of monitoring resources. |
|
||||
| Description | Additional notes and descriptions for this monitoring, where users can make notes. |
|
||||
| PrivateKey | The private key required to connect to the server. |
|
||||
| PrivateKey PassPhrase | The password phrase used to encrypt the SSH private key. If the private key was generated with a passphrase, this field must be filled to decrypt and use the key for authentication. |
|
||||
| Proxy Host | The address of the proxy server, supporting IPV4, IPV6, or domain name format. Required when using SSH jump host to access the target host. |
|
||||
| Proxy Port | The port number of the proxy service, default is 22. |
|
||||
| Proxy Username | The authentication username required to connect to the proxy server. |
|
||||
| Proxy Username | The authentication password required to connect to the proxy server. |
|
||||
| Proxy PrivateKey | The private key required to authenticate with the proxy server. |
|
||||
|
||||
### Collected Metrics
|
||||
### Data Collection Metrics
|
||||
|
||||
#### Metric Set: Basic Info
|
||||
#### Metric Set: Basic System Information
|
||||
|
||||
| Metric Name | Metric Unit | Metric help description |
|
||||
|----------------|-------------|---------------------------|
|
||||
| Host Name | None | Host name. |
|
||||
| System Version | None | Operating system version. |
|
||||
| Uptime | None | System uptime. |
|
||||
| Metric Name | Metric Unit | Metric Help Description |
|
||||
|-------------|-------------|-------------------------|
|
||||
| hostname | None | Host name |
|
||||
| version | None | System version |
|
||||
| uptime | None | System Uptime |
|
||||
|
||||
#### Metric Set: CPU Info
|
||||
#### Metric Set: CPU Information
|
||||
|
||||
| Metric Name | Metric Unit | Metric help description |
|
||||
|----------------|-------------|-------------------------------------------|
|
||||
| info | None | CPU model. |
|
||||
| cores | None | Number of CPU cores. |
|
||||
| interrupt | None | Number of CPU interrupts. |
|
||||
| load | None | Average load for the last 1/5/15 minutes. |
|
||||
| context_switch | None | Current context switches. |
|
||||
| usage | % | CPU usage percentage. |
|
||||
| Metric Name | Metric Unit | Metric Help Description |
|
||||
|----------------|-------------|-----------------------------------|
|
||||
| info | None | CPU model |
|
||||
| cores | None | Number of CPU cores |
|
||||
| interrupt | None | Number of CPU interrupts |
|
||||
| load | None | Average CPU load (1/5/15 minutes) |
|
||||
| context_switch | None | Number of context switches |
|
||||
| usage | % | CPU usage |
|
||||
|
||||
#### Metric Set: Memory Info
|
||||
#### Metric Set: Memory Information
|
||||
|
||||
| Metric Name | Metric Unit | Metric help description |
|
||||
|-------------|-------------|------------------------------------|
|
||||
| total | Mb | Total memory capacity. |
|
||||
| used | Mb | Used memory by user programs. |
|
||||
| free | Mb | Free memory capacity. |
|
||||
| buff_cache | Mb | Memory used for buffers and cache. |
|
||||
| available | Mb | Available memory capacity. |
|
||||
| usage | % | Memory usage percentage. |
|
||||
| Metric Name | Metric Unit | Metric Help Description |
|
||||
|-------------|-------------|-------------------------------------|
|
||||
| total | Mb | Total memory capacity |
|
||||
| used | Mb | Memory used by user programs |
|
||||
| free | Mb | Free memory capacity |
|
||||
| buff_cache | Mb | Memory used for cache |
|
||||
| available | Mb | Remaining available memory capacity |
|
||||
| usage | % | Memory usage rate |
|
||||
|
||||
#### Metric Set: Disk Info
|
||||
#### Metric Set: Disk Information
|
||||
|
||||
| Metric Name | Metric Unit | Metric help description |
|
||||
|---------------|-------------|------------------------------------|
|
||||
| disk_num | None | Total number of disks. |
|
||||
| partition_num | None | Total number of partitions. |
|
||||
| block_write | None | Total blocks written to disk. |
|
||||
| block_read | None | Total blocks read from disk. |
|
||||
| write_rate | iops | Rate of blocks written per second. |
|
||||
| Metric Name | Metric Unit | Metric Help Description |
|
||||
|---------------|-------------|----------------------------------------|
|
||||
| disk_num | None | Total number of disks |
|
||||
| partition_num | None | Total number of partitions |
|
||||
| block_write | None | Total number of blocks written to disk |
|
||||
| block_read | None | Total number of blocks read from disk |
|
||||
| write_rate | iops | Disk block write rate per second |
|
||||
|
||||
#### Metric Set: Interface Info
|
||||
#### Metric Set: Network Card Information
|
||||
|
||||
| Metric Name | Metric Unit | Metric help description |
|
||||
|----------------|-------------|--------------------------------|
|
||||
| interface_name | None | Name of the network interface. |
|
||||
| receive_bytes | Mb | Inbound data traffic. |
|
||||
| transmit_bytes | Mb | Outbound data traffic. |
|
||||
| Metric Name | Metric Unit | Metric Help Description |
|
||||
|----------------|-------------|-------------------------------|
|
||||
| interface_name | None | Network card name |
|
||||
| receive_bytes | Byte | Inbound data traffic (bytes) |
|
||||
| transmit_bytes | Byte | Outbound data traffic (bytes) |
|
||||
|
||||
#### Metric Set: Disk Free
|
||||
#### Metric Set: File System
|
||||
|
||||
| Metric Name | Metric Unit | Metric help description |
|
||||
|-------------|-------------|--------------------------|
|
||||
| filesystem | None | Name of the file system. |
|
||||
| used | Mb | Used disk space. |
|
||||
| available | Mb | Available disk space. |
|
||||
| usage | % | Disk usage percentage. |
|
||||
| mounted | None | Mount point directory. |
|
||||
| Metric Name | Metric Unit | Metric Help Description |
|
||||
|-------------|-------------|-------------------------|
|
||||
| filesystem | None | Name of the file system |
|
||||
| used | Mb | Used disk size |
|
||||
| available | Mb | Available disk size |
|
||||
| usage | % | Usage rate |
|
||||
| mounted | None | Mount point directory |
|
||||
|
||||
#### Metric Set: Top10 CPU Process
|
||||
#### Metric Set: Top 10 CPU Processes
|
||||
|
||||
Top 10 processes consuming CPU. Metrics include: Process ID, CPU usage, Memory usage, Command.
|
||||
Statistics for the top 10 processes using the CPU. Statistics include: process ID, CPU usage, memory usage, and executed command.
|
||||
|
||||
| Metric Name | Metric Unit | Metric help description |
|
||||
| Metric Name | Metric Unit | Metric Help Description |
|
||||
|-------------|-------------|-------------------------|
|
||||
| pid | None | Process ID |
|
||||
| cpu_usage | % | CPU usage |
|
||||
| mem_usage | % | Memory usage |
|
||||
| command | None | Executed command |
|
||||
|
||||
#### Metric Set: Top10 Memory Process
|
||||
#### Metric Set: Top 10 Memory Processes
|
||||
|
||||
Top 10 processes consuming memory. Metrics include: Process ID, Memory usage, CPU usage, Command.
|
||||
Statistics for the top 10 processes using memory. Statistics include: process ID, memory usage, CPU usage, and executed command.
|
||||
|
||||
| Metric Name | Metric Unit | Metric help description |
|
||||
| Metric Name | Metric Unit | Metric Help Description |
|
||||
|-------------|-------------|-------------------------|
|
||||
| pid | None | Process ID |
|
||||
| mem_usage | % | Memory usage |
|
||||
|
||||
@@ -9,97 +9,104 @@ keywords: [ Open Source Monitoring System, Open Source OS Monitoring, Rocky Linu
|
||||
|
||||
### Configuration Parameters
|
||||
|
||||
| Parameter Name | Parameter help description |
|
||||
|---------------------|----------------------------------------------------------------------------------------------------------------------------------|
|
||||
| Monitoring Host | The IP, IPV6, or domain name of the monitored endpoint. Note ⚠️: Do not include protocol headers (eg: https://, http://). |
|
||||
| Task Name | Identifies the name of this monitoring, ensuring uniqueness. |
|
||||
| Port | Port provided by Linux SSH externally, defaults to 22. |
|
||||
| Timeout | Sets the timeout for connection in milliseconds (ms), defaults to 6000 ms. |
|
||||
| Connection Reuse | Sets whether the SSH connection is reused, defaults to: false. Creates a new connection for each information retrieval if false. |
|
||||
| Username | SSH connection username, optional. |
|
||||
| Password | SSH connection password, optional. |
|
||||
| Collector | Specifies which collector schedules the collection for this monitoring. |
|
||||
| Monitoring Interval | Interval for periodically collecting data, in seconds. Minimum interval is 30 seconds. |
|
||||
| Binding Tags | Used for categorizing and managing monitored resources. |
|
||||
| Description | Additional remarks and descriptions for this monitoring, for users' reference. |
|
||||
| PrivateKey | Key required for connecting to the server. |
|
||||
| Parameter Name | Parameter Help Description |
|
||||
|-----------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
|
||||
| Monitored Host | The IPV4, IPV6, or domain name of the host being monitored. Note ⚠️ No protocol header (e.g., https://, http://). |
|
||||
| Task Name | The name that identifies this monitoring, which must be unique. |
|
||||
| Port | The port provided by Linux SSH, default is 22. |
|
||||
| Timeout | Sets the connection timeout in milliseconds, default is 6000 ms. |
|
||||
| Connection Reuse | Sets whether SSH connections are reused, default is :false. If false, a new connection is created each time information is retrieved. |
|
||||
| Use Proxy Connection | Sets Whether connect via proxy, default is false. |
|
||||
| Username | SSH connection username, optional. |
|
||||
| Password | SSH connection password, optional. |
|
||||
| Collector | Configures which collector is used to schedule data collection for this monitoring. |
|
||||
| Monitoring Period | The interval time for periodic data collection in seconds, with a minimum interval of 30 seconds. |
|
||||
| Binding Tags | Used for categorized management of monitoring resources. |
|
||||
| Description | Additional notes and descriptions for this monitoring, where users can make notes. |
|
||||
| PrivateKey | The private key required to connect to the server. |
|
||||
| PrivateKey PassPhrase | The password phrase used to encrypt the SSH private key. If the private key was generated with a passphrase, this field must be filled to decrypt and use the key for authentication. |
|
||||
| Proxy Host | The address of the proxy server, supporting IPV4, IPV6, or domain name format. Required when using SSH jump host to access the target host. |
|
||||
| Proxy Port | The port number of the proxy service, default is 22. |
|
||||
| Proxy Username | The authentication username required to connect to the proxy server. |
|
||||
| Proxy Username | The authentication password required to connect to the proxy server. |
|
||||
| Proxy PrivateKey | The private key required to authenticate with the proxy server. |
|
||||
|
||||
### Collected Metrics
|
||||
### Data Collection Metrics
|
||||
|
||||
#### Metric Set: Basic Info
|
||||
#### Metric Set: Basic System Information
|
||||
|
||||
| Metric Name | Metric Unit | Metric help description |
|
||||
|----------------|-------------|---------------------------|
|
||||
| Host Name | None | Host name. |
|
||||
| System Version | None | Operating system version. |
|
||||
| Uptime | None | System uptime. |
|
||||
| Metric Name | Metric Unit | Metric Help Description |
|
||||
|-------------|-------------|-------------------------|
|
||||
| hostname | None | Host name |
|
||||
| version | None | System version |
|
||||
| uptime | None | System Uptime |
|
||||
|
||||
#### Metric Set: CPU Info
|
||||
#### Metric Set: CPU Information
|
||||
|
||||
| Metric Name | Metric Unit | Metric help description |
|
||||
|----------------|-------------|-------------------------------------------|
|
||||
| info | None | CPU model. |
|
||||
| cores | None | Number of CPU cores. |
|
||||
| interrupt | None | Number of CPU interrupts. |
|
||||
| load | None | Average load for the last 1/5/15 minutes. |
|
||||
| context_switch | None | Current context switches. |
|
||||
| usage | % | CPU usage percentage. |
|
||||
| Metric Name | Metric Unit | Metric Help Description |
|
||||
|----------------|-------------|-----------------------------------|
|
||||
| info | None | CPU model |
|
||||
| cores | None | Number of CPU cores |
|
||||
| interrupt | None | Number of CPU interrupts |
|
||||
| load | None | Average CPU load (1/5/15 minutes) |
|
||||
| context_switch | None | Number of context switches |
|
||||
| usage | % | CPU usage |
|
||||
|
||||
#### Metric Set: Memory Info
|
||||
#### Metric Set: Memory Information
|
||||
|
||||
| Metric Name | Metric Unit | Metric help description |
|
||||
|-------------|-------------|------------------------------------|
|
||||
| total | Mb | Total memory capacity. |
|
||||
| used | Mb | Used memory by user programs. |
|
||||
| free | Mb | Free memory capacity. |
|
||||
| buff_cache | Mb | Memory used for buffers and cache. |
|
||||
| available | Mb | Available memory capacity. |
|
||||
| usage | % | Memory usage percentage. |
|
||||
| Metric Name | Metric Unit | Metric Help Description |
|
||||
|-------------|-------------|-------------------------------------|
|
||||
| total | Mb | Total memory capacity |
|
||||
| used | Mb | Memory used by user programs |
|
||||
| free | Mb | Free memory capacity |
|
||||
| buff_cache | Mb | Memory used for cache |
|
||||
| available | Mb | Remaining available memory capacity |
|
||||
| usage | % | Memory usage rate |
|
||||
|
||||
#### Metric Set: Disk Info
|
||||
#### Metric Set: Disk Information
|
||||
|
||||
| Metric Name | Metric Unit | Metric help description |
|
||||
|---------------|-------------|------------------------------------|
|
||||
| disk_num | None | Total number of disks. |
|
||||
| partition_num | None | Total number of partitions. |
|
||||
| block_write | None | Total blocks written to disk. |
|
||||
| block_read | None | Total blocks read from disk. |
|
||||
| write_rate | iops | Rate of blocks written per second. |
|
||||
| Metric Name | Metric Unit | Metric Help Description |
|
||||
|---------------|-------------|----------------------------------------|
|
||||
| disk_num | None | Total number of disks |
|
||||
| partition_num | None | Total number of partitions |
|
||||
| block_write | None | Total number of blocks written to disk |
|
||||
| block_read | None | Total number of blocks read from disk |
|
||||
| write_rate | iops | Disk block write rate per second |
|
||||
|
||||
#### Metric Set: Interface Info
|
||||
#### Metric Set: Network Card Information
|
||||
|
||||
| Metric Name | Metric Unit | Metric help description |
|
||||
|----------------|-------------|--------------------------------|
|
||||
| interface_name | None | Name of the network interface. |
|
||||
| receive_bytes | Mb | Inbound data traffic. |
|
||||
| transmit_bytes | Mb | Outbound data traffic. |
|
||||
| Metric Name | Metric Unit | Metric Help Description |
|
||||
|----------------|-------------|-------------------------------|
|
||||
| interface_name | None | Network card name |
|
||||
| receive_bytes | Byte | Inbound data traffic (bytes) |
|
||||
| transmit_bytes | Byte | Outbound data traffic (bytes) |
|
||||
|
||||
#### Metric Set: Disk Free
|
||||
#### Metric Set: File System
|
||||
|
||||
| Metric Name | Metric Unit | Metric help description |
|
||||
|-------------|-------------|--------------------------|
|
||||
| filesystem | None | Name of the file system. |
|
||||
| used | Mb | Used disk space. |
|
||||
| available | Mb | Available disk space. |
|
||||
| usage | % | Disk usage percentage. |
|
||||
| mounted | None | Mount point directory. |
|
||||
| Metric Name | Metric Unit | Metric Help Description |
|
||||
|-------------|-------------|-------------------------|
|
||||
| filesystem | None | Name of the file system |
|
||||
| used | Mb | Used disk size |
|
||||
| available | Mb | Available disk size |
|
||||
| usage | % | Usage rate |
|
||||
| mounted | None | Mount point directory |
|
||||
|
||||
#### Metric Set: Top10 CPU Process
|
||||
#### Metric Set: Top 10 CPU Processes
|
||||
|
||||
Top 10 processes consuming CPU. Metrics include: Process ID, CPU usage, Memory usage, Command.
|
||||
Statistics for the top 10 processes using the CPU. Statistics include: process ID, CPU usage, memory usage, and executed command.
|
||||
|
||||
| Metric Name | Metric Unit | Metric help description |
|
||||
| Metric Name | Metric Unit | Metric Help Description |
|
||||
|-------------|-------------|-------------------------|
|
||||
| pid | None | Process ID |
|
||||
| cpu_usage | % | CPU usage |
|
||||
| mem_usage | % | Memory usage |
|
||||
| command | None | Executed command |
|
||||
|
||||
#### Metric Set: Top10 Memory Process
|
||||
#### Metric Set: Top 10 Memory Processes
|
||||
|
||||
Top 10 processes consuming memory. Metrics include: Process ID, Memory usage, CPU usage, Command.
|
||||
Statistics for the top 10 processes using memory. Statistics include: process ID, memory usage, CPU usage, and executed command.
|
||||
|
||||
| Metric Name | Metric Unit | Metric help description |
|
||||
| Metric Name | Metric Unit | Metric Help Description |
|
||||
|-------------|-------------|-------------------------|
|
||||
| pid | None | Process ID |
|
||||
| mem_usage | % | Memory usage |
|
||||
|
||||
+90
-49
@@ -9,73 +9,114 @@ keywords: [open source monitoring tool, open source linux ubuntu monitoring tool
|
||||
|
||||
### Configuration parameter
|
||||
|
||||
| Parameter name | Parameter help description |
|
||||
|---------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
|
||||
| Monitoring Host | Monitored IPV4, IPV6 or domain name. Note⚠️Without protocol header (eg: https://, http://) |
|
||||
| Monitoring name | Identify the name of this monitoring. The name needs to be unique |
|
||||
| Port | Port provided by Linux SSH. The default is 22 |
|
||||
| Username | SSH connection user name, optional |
|
||||
| Password | SSH connection password, optional |
|
||||
| Collection interval | Interval time of monitor periodic data collection, unit: second, and the minimum interval that can be set is 30 seconds |
|
||||
| Whether to detect | Whether to detect and check the availability of monitoring before adding monitoring. Adding and modifying operations will continue only after the detection is successful |
|
||||
| Description remarks | For more information about identifying and describing this monitoring, users can note information here |
|
||||
| Parameter Name | Parameter Help Description |
|
||||
|-----------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
|
||||
| Monitored Host | The IPV4, IPV6, or domain name of the host being monitored. Note ⚠️ No protocol header (e.g., https://, http://). |
|
||||
| Task Name | The name that identifies this monitoring, which must be unique. |
|
||||
| Port | The port provided by Linux SSH, default is 22. |
|
||||
| Timeout | Sets the connection timeout in milliseconds, default is 6000 ms. |
|
||||
| Connection Reuse | Sets whether SSH connections are reused, default is :false. If false, a new connection is created each time information is retrieved. |
|
||||
| Use Proxy Connection | Sets Whether connect via proxy, default is false. |
|
||||
| Username | SSH connection username, optional. |
|
||||
| Password | SSH connection password, optional. |
|
||||
| Collector | Configures which collector is used to schedule data collection for this monitoring. |
|
||||
| Monitoring Period | The interval time for periodic data collection in seconds, with a minimum interval of 30 seconds. |
|
||||
| Binding Tags | Used for categorized management of monitoring resources. |
|
||||
| Description | Additional notes and descriptions for this monitoring, where users can make notes. |
|
||||
| PrivateKey | The private key required to connect to the server. |
|
||||
| PrivateKey PassPhrase | The password phrase used to encrypt the SSH private key. If the private key was generated with a passphrase, this field must be filled to decrypt and use the key for authentication. |
|
||||
| Proxy Host | The address of the proxy server, supporting IPV4, IPV6, or domain name format. Required when using SSH jump host to access the target host. |
|
||||
| Proxy Port | The port number of the proxy service, default is 22. |
|
||||
| Proxy Username | The authentication username required to connect to the proxy server. |
|
||||
| Proxy Username | The authentication password required to connect to the proxy server. |
|
||||
| Proxy PrivateKey | The private key required to authenticate with the proxy server. |
|
||||
|
||||
### Collection Metric
|
||||
### Collected Metrics
|
||||
|
||||
#### Metric set:basic
|
||||
### Data Collection Metrics
|
||||
|
||||
| Metric name | Metric unit | Metric help description |
|
||||
|-------------|-------------|--------------------------|
|
||||
| hostname | none | Host name |
|
||||
| version | none | Operating system version |
|
||||
| uptime | none | System running time |
|
||||
#### Metric Set: Basic System Information
|
||||
|
||||
#### Metric set:cpu
|
||||
| Metric Name | Metric Unit | Metric Help Description |
|
||||
|-------------|-------------|-------------------------|
|
||||
| hostname | None | Host name |
|
||||
| version | None | System version |
|
||||
| uptime | None | System Uptime |
|
||||
|
||||
| Metric name | Metric unit | Metric help description |
|
||||
|----------------|-------------|------------------------------------------------|
|
||||
| info | none | CPU model |
|
||||
| cores | cores | Number of CPU cores |
|
||||
| interrupt | number | Number of CPU interrupts |
|
||||
| load | none | Average load of CPU in the last 1/5/15 minutes |
|
||||
| context_switch | number | Number of current context switches |
|
||||
| usage | % | CPU usage |
|
||||
#### Metric Set: CPU Information
|
||||
|
||||
#### Metric set:memory
|
||||
| Metric Name | Metric Unit | Metric Help Description |
|
||||
|----------------|-------------|-----------------------------------|
|
||||
| info | None | CPU model |
|
||||
| cores | None | Number of CPU cores |
|
||||
| interrupt | None | Number of CPU interrupts |
|
||||
| load | None | Average CPU load (1/5/15 minutes) |
|
||||
| context_switch | None | Number of context switches |
|
||||
| usage | % | CPU usage |
|
||||
|
||||
| Metric name | Metric unit | Metric help description |
|
||||
#### Metric Set: Memory Information
|
||||
|
||||
| Metric Name | Metric Unit | Metric Help Description |
|
||||
|-------------|-------------|-------------------------------------|
|
||||
| total | Mb | Total memory capacity |
|
||||
| used | Mb | User program memory |
|
||||
| used | Mb | Memory used by user programs |
|
||||
| free | Mb | Free memory capacity |
|
||||
| buff_cache | Mb | Memory occupied by cache |
|
||||
| buff_cache | Mb | Memory used for cache |
|
||||
| available | Mb | Remaining available memory capacity |
|
||||
| usage | % | Memory usage |
|
||||
| usage | % | Memory usage rate |
|
||||
|
||||
#### Metric set:disk
|
||||
#### Metric Set: Disk Information
|
||||
|
||||
| Metric name | Metric unit | Metric help description |
|
||||
| Metric Name | Metric Unit | Metric Help Description |
|
||||
|---------------|-------------|----------------------------------------|
|
||||
| disk_num | blocks | Total number of disks |
|
||||
| partition_num | partitions | Total number of partitions |
|
||||
| block_write | blocks | Total number of blocks written to disk |
|
||||
| block_read | blocks | Number of blocks read from disk |
|
||||
| write_rate | iops | Rate of writing disk blocks per second |
|
||||
| disk_num | None | Total number of disks |
|
||||
| partition_num | None | Total number of partitions |
|
||||
| block_write | None | Total number of blocks written to disk |
|
||||
| block_read | None | Total number of blocks read from disk |
|
||||
| write_rate | iops | Disk block write rate per second |
|
||||
|
||||
#### Metric set:interface
|
||||
#### Metric Set: Network Card Information
|
||||
|
||||
| Metric name | Metric unit | Metric help description |
|
||||
|----------------|-------------|------------------------------|
|
||||
| interface_name | none | Network card name |
|
||||
| receive_bytes | byte | Inbound data traffic(bytes) |
|
||||
| transmit_bytes | byte | Outbound data traffic(bytes) |
|
||||
| Metric Name | Metric Unit | Metric Help Description |
|
||||
|----------------|-------------|-------------------------------|
|
||||
| interface_name | None | Network card name |
|
||||
| receive_bytes | Byte | Inbound data traffic (bytes) |
|
||||
| transmit_bytes | Byte | Outbound data traffic (bytes) |
|
||||
|
||||
#### Metric set:disk_free
|
||||
#### Metric Set: File System
|
||||
|
||||
| Metric name | Metric unit | Metric help description |
|
||||
| Metric Name | Metric Unit | Metric Help Description |
|
||||
|-------------|-------------|-------------------------|
|
||||
| filesystem | none | File system name |
|
||||
| filesystem | None | Name of the file system |
|
||||
| used | Mb | Used disk size |
|
||||
| available | Mb | Available disk size |
|
||||
| usage | % | usage |
|
||||
| mounted | none | Mount point directory |
|
||||
| usage | % | Usage rate |
|
||||
| mounted | None | Mount point directory |
|
||||
|
||||
#### Metric Set: Top 10 CPU Processes
|
||||
|
||||
Statistics for the top 10 processes using the CPU. Statistics include: process ID, CPU usage, memory usage, and executed command.
|
||||
|
||||
| Metric Name | Metric Unit | Metric Help Description |
|
||||
|-------------|-------------|-------------------------|
|
||||
| pid | None | Process ID |
|
||||
| cpu_usage | % | CPU usage |
|
||||
| mem_usage | % | Memory usage |
|
||||
| command | None | Executed command |
|
||||
|
||||
#### Metric Set: Top 10 Memory Processes
|
||||
|
||||
Statistics for the top 10 processes using memory. Statistics include: process ID, memory usage, CPU usage, and executed command.
|
||||
|
||||
| Metric Name | Metric Unit | Metric Help Description |
|
||||
|-------------|-------------|-------------------------|
|
||||
| pid | None | Process ID |
|
||||
| mem_usage | % | Memory usage |
|
||||
| cpu_usage | % | CPU usage |
|
||||
| command | None | Executed command |
|
||||
|
||||
#### Metric Set: Average CPU Temperature Across All Cores
|
||||
|
||||
| Metric Name | Metric Unit | Metric help description |
|
||||
|--------------|-------------|-------------------------|
|
||||
| avg_cpu_temp | C | Average Temp All Cores |
|
||||
|
||||
@@ -35,7 +35,7 @@ It is necessary to have Docker environment in your environment. If not installed
|
||||
- `-v $(pwd)/logs:/opt/hertzbeat/logs` : (optional) Mount the log file to the local host to facilitate viewing.
|
||||
- `-v $(pwd)/application.yml:/opt/hertzbeat/config/application.yml` : (optional) Mount the configuration file to the container (please ensure that the file exists locally). [Download](https://github.com/apache/hertzbeat/raw/master/script/application.yml)
|
||||
- `-v $(pwd)/sureness.yml:/opt/hertzbeat/config/sureness.yml` : (optional) Mount the account configuration file to the container (please ensure that the file exists locally). [Download](https://github.com/apache/hertzbeat/raw/master/script/sureness.yml)
|
||||
- `-v $(pwd)/ext-lib:/opt/hertzbeat/ext-lib` : (optional) Mount external third-party JAR package [mysql-jdbc](https://dev.mysql.com/get/Downloads/Connector-J/mysql-connector-java-8.0.25.zip) [oracle-jdbc](https://download.oracle.com/otn-pub/otn_software/jdbc/234/ojdbc8.jar) [oracle-i18n](https://repo.mavenlibs.com/maven/com/oracle/database/nls/orai18n/21.5.0.0/orai18n-21.5.0.0.jar)
|
||||
- `-v $(pwd)/ext-lib:/opt/hertzbeat/ext-lib` : (optional) Mount external third-party JAR package [mysql-jdbc](https://dev.mysql.com/get/Downloads/Connector-J/mysql-connector-java-8.0.25.zip) [oracle-jdbc](https://repo1.maven.org/maven2/com/oracle/database/jdbc/ojdbc8/23.4.0.24.05/ojdbc8-23.4.0.24.05.jar) [oracle-i18n](https://repo.mavenlibs.com/maven/com/oracle/database/nls/orai18n/21.5.0.0/orai18n-21.5.0.0.jar)
|
||||
- `--name hertzbeat` : (optional) Naming container name hertzbeat
|
||||
- `--restart=always` : (optional) Configure the container to restart automatically.
|
||||
- `apache/hertzbeat` : Use the [official application mirror](https://hub.docker.com/r/apache/hertzbeat) to start the container, if the network times out, use `quay.io/tancloud/hertzbeat` instead.
|
||||
|
||||
@@ -1,20 +1,20 @@
|
||||
---
|
||||
id: greptime-init
|
||||
title: Use Time Series Database GreptimeDB to Store Metrics Data (Optional)
|
||||
sidebar_label: Metrics Store GreptimeDB
|
||||
title: Use Time Series Database Greptime to Store Metrics Data (Recommended)
|
||||
sidebar_label: Metrics Store Greptime (Recommended)
|
||||
---
|
||||
|
||||
Apache HertzBeat (incubating)'s historical data storage relies on the time series database, you can choose one of them to install and initialize, or not to install (note ⚠️ but it is strongly recommended to configure in the production environment)
|
||||
|
||||
> It is recommended to use VictoriaMetrics as metrics storage.
|
||||
> It is recommended to use Greptime as metrics storage.
|
||||
|
||||
[GreptimeDB](https://github.com/GreptimeTeam/greptimedb) is an open-source time-series database with a special focus on scalability, analytical capabilities and efficiency.
|
||||
[Greptime](https://github.com/GreptimeTeam/greptimedb) is an Open-source, cloud-native, unified observability database for metrics, logs and traces, supporting SQL/PromQL/Streaming.
|
||||
|
||||
It's designed to work on infrastructure of the cloud era, and users benefit from its elasticity and commodity storage.
|
||||
|
||||
**⚠️ If you do not configure a time series database, only the last hour of historical data is retained.**
|
||||
|
||||
### Install GreptimeDB via Docker
|
||||
### Install GreptimeDvia Docker
|
||||
|
||||
1. Download and install Docker environment
|
||||
Docker tools download refer to [Docker official document](https://docs.docker.com/get-docker/).
|
||||
@@ -25,7 +25,7 @@ After the installation you can check if the Docker version normally output at th
|
||||
Docker version 20.10.12, build e91ed57
|
||||
```
|
||||
|
||||
2. Install GreptimeDB with Docker
|
||||
2. Install Greptime with Docker
|
||||
|
||||
```shell
|
||||
$ docker run -d -p 127.0.0.1:4000-4003:4000-4003 \
|
||||
@@ -38,7 +38,7 @@ After the installation you can check if the Docker version normally output at th
|
||||
--postgres-addr 0.0.0.0:4003
|
||||
```
|
||||
|
||||
`-v "$(pwd)/greptimedb:/tmp/greptimedb"` is local persistent mount of greptimedb data directory. `$(pwd)/greptimedb` should be replaced with the actual local directory, default is the `greptimedb` directory under the current directory.
|
||||
`-v "$(pwd)/greptimedb:/tmp/greptimedb"` is local persistent mount of greptime data directory. `$(pwd)/greptimedb` should be replaced with the actual local directory, default is the `greptimedb` directory under the current directory.
|
||||
use```$ docker ps``` to check if the database started successfully
|
||||
|
||||
### Configure the database connection in hertzbeat `application.yml` configuration file
|
||||
@@ -69,6 +69,6 @@ use```$ docker ps``` to check if the database started successfully
|
||||
|
||||
### FAQ
|
||||
|
||||
1. Do both the time series databases Greptime, IoTDB or TDengine need to be configured? Can they both be used?
|
||||
1. Do both the time series databases need to be configured? Can they both be used?
|
||||
|
||||
> You don't need to configure all of them, you can choose one of them. Use the enable parameter to control whether it is used or not. You can also install and configure neither, which only affects the historical chart data.
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user