This is an automated email from the ASF dual-hosted git repository.
doleyzi pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/inlong.git
The following commit(s) were added to refs/heads/master by this push:
new c96830dac9 [INLONG-11998][Audit] Add the function of fetching Audit
Data and Alert Policies from Manager for audit tool (#11992)
c96830dac9 is described below
commit c96830dac936a603790760f02c5da8e067284d83
Author: Evanwqd <[email protected]>
AuthorDate: Sun Sep 14 17:16:30 2025 +0800
[INLONG-11998][Audit] Add the function of fetching Audit Data and Alert
Policies from Manager for audit tool (#11992)
* [INLONG-11923][Audit] Add the function of fetching Audit Data and Alert
Policies from Manager
* [Feature][Audit]Implement APIs for Audit Tool to interact with Manager
* [Feature][Audit]add AuditToolMain
---
.idea/icon.png | Bin 2060 -> 0 bytes
inlong-audit/audit-tool/pom.xml | 350 +++++++++++++++++++++
.../apache/inlong/audit/tool/AuditToolMain.java | 25 ++
.../inlong/audit/tool/DTO/AuditAlertCondition.java | 43 +++
.../inlong/audit/tool/DTO/AuditAlertRule.java | 90 ++++++
.../apache/inlong/audit/tool/config/AppConfig.java | 73 +++++
.../inlong/audit/tool/config/ConfigConstants.java | 46 +++
.../audit/tool/manager/AuditAlertRuleManager.java | 214 +++++++++++++
.../inlong/audit/tool/response/Response.java | 32 ++
.../audit/tool/util/AuditAlertRulePageRequest.java | 59 ++++
.../apache/inlong/audit/tool/util/HttpUtil.java | 73 +++++
.../apache/inlong/audit/tool/util/PageRequest.java | 45 +++
.../apache/inlong/audit/tool/util/PageResult.java | 45 +++
.../src/main/resources/application.properties | 53 ++++
.../AuditAlertRuleManagerTest.java | 83 +++++
inlong-audit/pom.xml | 1 +
16 files changed, 1232 insertions(+)
diff --git a/.idea/icon.png b/.idea/icon.png
deleted file mode 100644
index bfe2a04261..0000000000
Binary files a/.idea/icon.png and /dev/null differ
diff --git a/inlong-audit/audit-tool/pom.xml b/inlong-audit/audit-tool/pom.xml
new file mode 100644
index 0000000000..f880b6e8cf
--- /dev/null
+++ b/inlong-audit/audit-tool/pom.xml
@@ -0,0 +1,350 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements. See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership. The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied. See the License for the
+ specific language governing permissions and limitations
+ under the License.
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+ <parent>
+ <groupId>org.apache.inlong</groupId>
+ <artifactId>inlong-audit</artifactId>
+ <version>2.3.0-SNAPSHOT</version>
+ </parent>
+
+ <artifactId>audit-tool</artifactId>
+ <name>Apache InLong - Audit tool</name>
+
+ <properties>
+ <inlong.root.dir>${project.parent.parent.basedir}</inlong.root.dir>
+ <otel.version>1.32.0</otel.version>
+ </properties>
+
+ <dependencyManagement>
+ <dependencies>
+ <dependency>
+ <groupId>io.opentelemetry</groupId>
+ <artifactId>opentelemetry-bom</artifactId>
+ <version>${otel.version}</version>
+ <type>pom</type>
+ <scope>import</scope>
+ </dependency>
+ </dependencies>
+ </dependencyManagement>
+
+ <dependencies>
+ <dependency>
+ <groupId>org.apache.inlong</groupId>
+ <artifactId>audit-common</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+
+ <dependency>
+ <groupId>io.opentelemetry</groupId>
+ <artifactId>opentelemetry-exporter-otlp</artifactId>
+ </dependency>
+
+ <dependency>
+ <groupId>org.mybatis</groupId>
+ <artifactId>mybatis</artifactId>
+ <version>3.5.9</version>
+ </dependency>
+ <dependency>
+ <groupId>mysql</groupId>
+ <artifactId>mysql-connector-java</artifactId>
+ <scope>compile</scope>
+ </dependency>
+
+ <dependency>
+ <groupId>io.opentelemetry</groupId>
+ <artifactId>opentelemetry-sdk</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.junit.jupiter</groupId>
+ <artifactId>junit-jupiter-api</artifactId>
+ <version>5.8.2</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.junit.jupiter</groupId>
+ <artifactId>junit-jupiter-engine</artifactId>
+ <version>5.8.2</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.assertj</groupId>
+ <artifactId>assertj-core</artifactId>
+ <version>3.4.1</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>io.opentelemetry</groupId>
+ <artifactId>opentelemetry-sdk-testing</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.inlong</groupId>
+ <artifactId>manager-pojo</artifactId>
+ <version>${project.version}</version>
+ <scope>compile</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.mockito</groupId>
+ <artifactId>mockito-inline</artifactId>
+ <version>3.12.4</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.inlong</groupId>
+ <artifactId>audit-sdk</artifactId>
+ <version>${project.version}</version>
+ <scope>compile</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.mockito</groupId>
+ <artifactId>mockito-junit-jupiter</artifactId>
+ <version>4.0.0</version>
+ <scope>test</scope>
+ </dependency>
+
+ </dependencies>
+
+ <build>
+ <resources>
+ <resource>
+ <filtering>true</filtering>
+ <directory>${basedir}/src/main/resources</directory>
+ <includes>
+ <include>**/application*.yml</include>
+ <include>**/application*.yaml</include>
+ <include>**/application*.properties</include>
+ </includes>
+ </resource>
+ <resource>
+ <directory>${basedir}/src/main/resources</directory>
+ <excludes>
+ <exclude>**/application*.yml</exclude>
+ <exclude>**/application*.yaml</exclude>
+ <exclude>**/application*.properties</exclude>
+ </excludes>
+ </resource>
+ </resources>
+ <pluginManagement>
+ <plugins>
+ <plugin>
+ <groupId>org.jetbrains.kotlin</groupId>
+ <artifactId>kotlin-maven-plugin</artifactId>
+ <version>${kotlin.version}</version>
+ <configuration>
+ <jvmTarget>${java.version}</jvmTarget>
+ <javaParameters>true</javaParameters>
+ </configuration>
+ <executions>
+ <execution>
+ <id>compile</id>
+ <goals>
+ <goal>compile</goal>
+ </goals>
+ <phase>compile</phase>
+ </execution>
+ <execution>
+ <id>test-compile</id>
+ <goals>
+ <goal>test-compile</goal>
+ </goals>
+ <phase>test-compile</phase>
+ </execution>
+ </executions>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-compiler-plugin</artifactId>
+ <configuration>
+ <parameters>true</parameters>
+ </configuration>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-failsafe-plugin</artifactId>
+ <configuration>
+
<classesDirectory>${project.build.outputDirectory}</classesDirectory>
+ </configuration>
+ <executions>
+ <execution>
+ <goals>
+ <goal>integration-test</goal>
+ <goal>verify</goal>
+ </goals>
+ </execution>
+ </executions>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-jar-plugin</artifactId>
+ <configuration>
+ <archive>
+ <manifest>
+ <mainClass>${start-class}</mainClass>
+
<addDefaultImplementationEntries>true</addDefaultImplementationEntries>
+ </manifest>
+ </archive>
+ </configuration>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-war-plugin</artifactId>
+ <configuration>
+ <archive>
+ <manifest>
+ <mainClass>${start-class}</mainClass>
+
<addDefaultImplementationEntries>true</addDefaultImplementationEntries>
+ </manifest>
+ </archive>
+ </configuration>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-resources-plugin</artifactId>
+ <configuration>
+ <delimiters>
+ <delimiter>${resource.delimiter}</delimiter>
+ </delimiters>
+ <useDefaultDelimiters>false</useDefaultDelimiters>
+ </configuration>
+ </plugin>
+ <plugin>
+ <groupId>pl.project13.maven</groupId>
+ <artifactId>git-commit-id-plugin</artifactId>
+ <configuration>
+ <verbose>true</verbose>
+ <dateFormat>yyyy-MM-dd'T'HH:mm:ssZ</dateFormat>
+
<generateGitPropertiesFile>true</generateGitPropertiesFile>
+
<generateGitPropertiesFilename>${project.build.outputDirectory}/git.properties</generateGitPropertiesFilename>
+ </configuration>
+ <executions>
+ <execution>
+ <goals>
+ <goal>revision</goal>
+ </goals>
+ </execution>
+ </executions>
+ </plugin>
+ <plugin>
+ <groupId>org.springframework.boot</groupId>
+ <artifactId>spring-boot-maven-plugin</artifactId>
+ <version>${spring.plugin.version}</version>
+ <configuration>
+ <mainClass>${start-class}</mainClass>
+ </configuration>
+ <executions>
+ <execution>
+ <id>repackage</id>
+ <goals>
+ <goal>repackage</goal>
+ </goals>
+ </execution>
+ </executions>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-shade-plugin</artifactId>
+ <configuration>
+
<keepDependenciesWithProvidedScope>true</keepDependenciesWithProvidedScope>
+
<createDependencyReducedPom>false</createDependencyReducedPom>
+ <filters>
+ <filter>
+ <artifact>*:*</artifact>
+ <excludes>
+ <exclude>META-INF/*.SF</exclude>
+ <exclude>META-INF/*.DSA</exclude>
+ <exclude>META-INF/*.RSA</exclude>
+ </excludes>
+ </filter>
+ </filters>
+ </configuration>
+ <dependencies>
+ <dependency>
+ <groupId>org.springframework.boot</groupId>
+ <artifactId>spring-boot-maven-plugin</artifactId>
+ <version>${spring.plugin.version}</version>
+ </dependency>
+ </dependencies>
+ <executions>
+ <execution>
+ <goals>
+ <goal>shade</goal>
+ </goals>
+ <phase>package</phase>
+ <configuration>
+ <transformers>
+ <transformer
implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
+
<resource>META-INF/spring.handlers</resource>
+ </transformer>
+ <transformer
implementation="org.springframework.boot.maven.PropertiesMergingResourceTransformer">
+
<resource>META-INF/spring.factories</resource>
+ </transformer>
+ <transformer
implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
+
<resource>META-INF/spring.schemas</resource>
+ </transformer>
+ <transformer
implementation="org.apache.maven.plugins.shade.resource.ServicesResourceTransformer"
/>
+ <transformer
implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
+ <mainClass>${start-class}</mainClass>
+ </transformer>
+ </transformers>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
+ </plugins>
+ </pluginManagement>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-jar-plugin</artifactId>
+ <configuration>
+ <excludes>
+ <exclude>**/*.properties</exclude>
+ <exclude>**/*.xml</exclude>
+ <exclude>**/*.yml</exclude>
+ </excludes>
+ </configuration>
+ </plugin>
+ <plugin>
+ <groupId>org.springframework.boot</groupId>
+ <artifactId>spring-boot-maven-plugin</artifactId>
+ <version>${spring.plugin.version}</version>
+ <configuration>
+ <layout>ZIP</layout>
+ <includes>
+ <include>
+ <groupId>nothing</groupId>
+ <artifactId>nothing</artifactId>
+ </include>
+ </includes>
+ </configuration>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-compiler-plugin</artifactId>
+ <configuration>
+ <source>8</source>
+ <target>8</target>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+</project>
diff --git
a/inlong-audit/audit-tool/src/main/java/org/apache/inlong/audit/tool/AuditToolMain.java
b/inlong-audit/audit-tool/src/main/java/org/apache/inlong/audit/tool/AuditToolMain.java
new file mode 100644
index 0000000000..6508923127
--- /dev/null
+++
b/inlong-audit/audit-tool/src/main/java/org/apache/inlong/audit/tool/AuditToolMain.java
@@ -0,0 +1,25 @@
+/*
+ * 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.inlong.audit.tool;
+
+public class AuditToolMain {
+
+ public static void main(String[] args) {
+
+ }
+}
\ No newline at end of file
diff --git
a/inlong-audit/audit-tool/src/main/java/org/apache/inlong/audit/tool/DTO/AuditAlertCondition.java
b/inlong-audit/audit-tool/src/main/java/org/apache/inlong/audit/tool/DTO/AuditAlertCondition.java
new file mode 100644
index 0000000000..2e5013d3cb
--- /dev/null
+++
b/inlong-audit/audit-tool/src/main/java/org/apache/inlong/audit/tool/DTO/AuditAlertCondition.java
@@ -0,0 +1,43 @@
+/*
+ * 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.inlong.audit.tool.dto;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import javax.validation.constraints.NotBlank;
+import javax.validation.constraints.NotNull;
+
+@Data
+@ApiModel("Audit Alert Condition")
+public class AuditAlertCondition {
+
+ @ApiModelProperty(value = "Condition type (e.g., data_loss, delay,
count)", required = true)
+ @NotBlank(message = "Condition type cannot be blank")
+ private String type;
+
+ @ApiModelProperty(value = "Operator for comparison (e.g., >, <, >=, <=,
==, !=)", required = true)
+ @NotBlank(message = "Operator cannot be blank")
+ private String operator;
+
+ @ApiModelProperty(value = "Value for comparison", required = true)
+ @NotNull(message = "Value cannot be null")
+ private Double value;
+
+}
\ No newline at end of file
diff --git
a/inlong-audit/audit-tool/src/main/java/org/apache/inlong/audit/tool/DTO/AuditAlertRule.java
b/inlong-audit/audit-tool/src/main/java/org/apache/inlong/audit/tool/DTO/AuditAlertRule.java
new file mode 100644
index 0000000000..5f20e1307b
--- /dev/null
+++
b/inlong-audit/audit-tool/src/main/java/org/apache/inlong/audit/tool/DTO/AuditAlertRule.java
@@ -0,0 +1,90 @@
+/*
+ * 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.inlong.audit.tool.dto;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import javax.validation.Valid;
+import javax.validation.constraints.NotBlank;
+import javax.validation.constraints.NotNull;
+import javax.validation.constraints.Pattern;
+
+import java.util.Date;
+
+@Data
+@ApiModel("Audit Alert Rule Configuration")
+public class AuditAlertRule {
+
+ @ApiModelProperty("Rule ID")
+ private Integer id;
+
+ @ApiModelProperty(value = "Associated InLong Group ID", required = true)
+ @NotBlank(message = "InLong Group ID cannot be blank")
+ private String inlongGroupId;
+
+ @ApiModelProperty("Associated InLong Stream ID")
+ private String inlongStreamId;
+
+ @ApiModelProperty(value = "Audit ID (associated with specific audit
metrics, such as send success count, delay, etc.)", required = true)
+ @NotBlank(message = "Audit ID cannot be blank")
+ private String auditId;
+
+ @ApiModelProperty(value = "Alert name", required = true)
+ @NotBlank(message = "Alert name cannot be blank")
+ private String alertName;
+
+ @ApiModelProperty(value = "Trigger condition", required = true)
+ @NotNull(message = "Trigger condition cannot be null")
+ @Valid
+ private AuditAlertCondition condition;
+
+ @ApiModelProperty("Alert level (INFO/WARN/ERROR/CRITICAL)")
+ @Pattern(regexp = "^(INFO|WARN|ERROR|CRITICAL)$", message = "Alert level
must be one of INFO, WARN, ERROR, or CRITICAL")
+ private String level;
+
+ @ApiModelProperty("Notification type (EMAIL/SMS/HTTP)")
+ @Pattern(regexp = "^(EMAIL|SMS|HTTP)$", message = "Notification type must
be one of EMAIL, SMS, or HTTP")
+ private String notifyType;
+
+ @ApiModelProperty("Notification recipients (separated by commas for
multiple recipients)")
+ private String receivers;
+
+ @ApiModelProperty(value = "Whether enabled", required = true)
+ @NotNull(message = "Enabled status cannot be null")
+ private Boolean enabled;
+
+ @ApiModelProperty("Whether deleted")
+ private Integer isDeleted; // Use Integer to match database int(11) type
+
+ @ApiModelProperty("Creator name")
+ private String creator;
+
+ @ApiModelProperty("Modifier name")
+ private String modifier;
+
+ @ApiModelProperty("Create time")
+ private Date createTime;
+
+ @ApiModelProperty("Modify time")
+ private Date modifyTime;
+
+ @ApiModelProperty("Version number")
+ private Integer version; // Add version field
+}
\ No newline at end of file
diff --git
a/inlong-audit/audit-tool/src/main/java/org/apache/inlong/audit/tool/config/AppConfig.java
b/inlong-audit/audit-tool/src/main/java/org/apache/inlong/audit/tool/config/AppConfig.java
new file mode 100644
index 0000000000..3a94763a53
--- /dev/null
+++
b/inlong-audit/audit-tool/src/main/java/org/apache/inlong/audit/tool/config/AppConfig.java
@@ -0,0 +1,73 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.inlong.audit.tool.config;
+
+import lombok.Getter;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Properties;
+
+import static org.apache.inlong.audit.tool.config.ConfigConstants.*;
+
+/**
+ * App Config
+ */
+@Getter
+public class AppConfig {
+
+ private final Properties properties;
+
+ public AppConfig() {
+ properties = new Properties();
+ loadProperties();
+
+ }
+
+ private void loadProperties() {
+ try {
+
properties.load(getClass().getClassLoader().getResourceAsStream("application.properties"));
+ } catch (Exception e) {
+ throw new RuntimeException("Failed to load application
properties", e);
+ }
+ }
+
+ public String getManagerUrl() {
+ return properties.getProperty("manager.url");
+ }
+
+ public Map<String, Object> getPrometheusConfig() {
+ Map<String, Object> config = new HashMap<>();
+ config.put(KEY_PROMETHEUS_ENABLED,
+
Boolean.parseBoolean(properties.getProperty(KEY_PROMETHEUS_ENABLED, "false")));
+ config.put(KEY_PROMETHEUS_ENDPOINT,
+ properties.getProperty(KEY_PROMETHEUS_ENDPOINT,
"http://localhost:9090/api/v1/write"));
+ config.put(KEY_PROMETHEUS_PORT,
+ Integer.parseInt(properties.getProperty(KEY_PROMETHEUS_PORT,
+ String.valueOf(DEFAULT_PROMETHEUS_PORT))));
+ return config;
+ }
+
+ public String getSecretId() {
+ return properties.getProperty("audit.secretId");
+ }
+
+ public String getSecretKey() {
+ return properties.getProperty("audit.secretKey");
+ }
+}
\ No newline at end of file
diff --git
a/inlong-audit/audit-tool/src/main/java/org/apache/inlong/audit/tool/config/ConfigConstants.java
b/inlong-audit/audit-tool/src/main/java/org/apache/inlong/audit/tool/config/ConfigConstants.java
new file mode 100644
index 0000000000..098eba5bf6
--- /dev/null
+++
b/inlong-audit/audit-tool/src/main/java/org/apache/inlong/audit/tool/config/ConfigConstants.java
@@ -0,0 +1,46 @@
+/*
+ * 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.inlong.audit.tool.config;
+
+/**
+ * Config constants
+ */
+public class ConfigConstants {
+
+ public static final String AUDIT_TOOL_NAME = "audit-tool";
+ public static final String KEY_GROUP_ID = "group_id";
+ public static final String KEY_STREAM_ID = "stream_id";
+ public static final String KEY_ALERT_TYPE = "alert_type";
+ public static final String KEY_PROMETHEUS_PORT = "prometheus.port";
+ public static final String KEY_PROMETHEUS = "prometheus";
+ public static final String KEY_OTEL = "opentelemetry";
+ public static final String KEY_OTEL_ENDPOINT = "otel.exporter.endpoint";
+ public static final int DEFAULT_PROMETHEUS_PORT = 9091;
+ public static final String DEFAULT_OTEL_ENDPOINT = "http://localhost:4317";
+
+ public static final String AUDIT_TOOL_ALERTS_TOTAL =
"audit_tool_alerts_total";
+ public static final String DESC_AUDIT_TOOL_ALERTS_TOTAL = "Total number of
alerts";
+ public static final String AUDIT_TOOL_DATA_LOSS_RATE =
"audit_tool_data_loss_rate";
+ public static final String DESC_AUDIT_TOOL_DATA_LOSS_RATE = "Data loss
rate between Sort and DataProxy";
+ public static final String AUDIT_ALERT_RULE_lIST_PATH =
"/api/audit/alert/rule/list";
+ public static final String KEY_DELAY_TIME = "audit.data.time.delay.minute";
+ public static final String KEY_INTERVAL_TIME =
"audit.data.time.interval.minute";
+ public static final String KEY_SOURCE_AUDIT_ID = "audit.id.source";
+ public static final String KEY_PROMETHEUS_ENABLED = "prometheus.enabled";
+ public static final String KEY_PROMETHEUS_ENDPOINT = "prometheus.endpoint";
+}
diff --git
a/inlong-audit/audit-tool/src/main/java/org/apache/inlong/audit/tool/manager/AuditAlertRuleManager.java
b/inlong-audit/audit-tool/src/main/java/org/apache/inlong/audit/tool/manager/AuditAlertRuleManager.java
new file mode 100644
index 0000000000..0d8fc2775f
--- /dev/null
+++
b/inlong-audit/audit-tool/src/main/java/org/apache/inlong/audit/tool/manager/AuditAlertRuleManager.java
@@ -0,0 +1,214 @@
+/*
+ * 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.inlong.audit.tool.manager;
+
+import org.apache.inlong.audit.tool.config.AppConfig;
+import org.apache.inlong.audit.tool.dto.AuditAlertRule;
+import org.apache.inlong.audit.tool.response.Response;
+import org.apache.inlong.audit.tool.util.AuditAlertRulePageRequest;
+import org.apache.inlong.audit.tool.util.HttpUtil;
+import org.apache.inlong.audit.tool.util.PageResult;
+import org.apache.inlong.audit.utils.HttpUtils;
+
+import lombok.Getter;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.core.ParameterizedTypeReference;
+import org.springframework.http.HttpMethod;
+import org.springframework.util.LinkedMultiValueMap;
+import org.springframework.util.MultiValueMap;
+import org.springframework.web.client.RestTemplate;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.CopyOnWriteArrayList;
+import java.util.concurrent.Executors;
+import java.util.concurrent.ScheduledExecutorService;
+import java.util.concurrent.TimeUnit;
+import java.util.stream.Collectors;
+
+import static
org.apache.inlong.audit.tool.config.ConfigConstants.AUDIT_ALERT_RULE_lIST_PATH;
+
+/**
+ * Audit Alert Rule Manager implementation
+ */
+public class AuditAlertRuleManager {
+
+ private AppConfig appConfig;
+ private static final Logger LOGGER =
LoggerFactory.getLogger(AuditAlertRuleManager.class);
+ private final RestTemplate restTemplate = new RestTemplate();
+ @Getter
+ private List<AuditAlertRule> auditAlertRuleList = new
CopyOnWriteArrayList<>();
+
+ private static class Holder {
+
+ private static final AuditAlertRuleManager INSTANCE = new
AuditAlertRuleManager();
+ }
+
+ public static AuditAlertRuleManager getInstance() {
+ return Holder.INSTANCE;
+ }
+
+ /**
+ * Initialize the manager with application configuration.
+ * This method is idempotent; subsequent calls are ignored with a warning.
+ *
+ * @param appConfig non-null configuration
+ */
+ public synchronized void init(AppConfig appConfig) {
+ if (this.appConfig != null) {
+ LOGGER.warn("AuditAlertRuleManager already initialized. Ignoring
re-initialization");
+ return;
+ }
+ if (appConfig != null) {
+ this.appConfig = appConfig;
+ } else {
+ LOGGER.error("appConfig must not be null");
+ throw new IllegalStateException("appConfig is null");
+ }
+ }
+
+ private AuditAlertRuleManager() {
+ }
+
+ // Single-thread scheduler for periodic fetch
+ private final ScheduledExecutorService scheduler =
Executors.newSingleThreadScheduledExecutor(r -> {
+ Thread t = new Thread(r, "audit-alert-rule-scheduler");
+ t.setDaemon(true);
+ return t;
+ });
+
+ /**
+ * Safely runs the fetch task, logging any exceptions without throwing.
+ */
+ private void runFetchTaskSafe() {
+ try {
+ LOGGER.info("Running scheduled fetch task...");
+ List<AuditAlertRule> rules = fetchAlertRulesFromManager();
+ if (!rules.isEmpty()) {
+ auditAlertRuleList = rules;
+ }
+ LOGGER.info("Scheduled fetch task completed. rules={}",
rules.size());
+ } catch (Exception e) {
+ LOGGER.error("Error during scheduled fetch task", e);
+ }
+ }
+
+ /**
+ * Schedules periodic fetching of rules at a fixed rate.
+ * If the configured interval is <= 0, runs immediately once and returns.
+ */
+ public synchronized void schedule() {
+ int executionIntervalTime =
+
Integer.parseInt(appConfig.getProperties().getProperty("audit.data.time.interval.minute"));
+ if (executionIntervalTime < 0) {
+ LOGGER.warn("Execution Interval Time {} is in the past. Executing
immediately", executionIntervalTime);
+ executionIntervalTime = 0;
+ }
+ scheduler.scheduleAtFixedRate(
+ this::runFetchTaskSafe,
+ 0L, // initial delay: fetch immediately
+ executionIntervalTime,
+ TimeUnit.MINUTES);
+ LOGGER.info("Scheduled fetch task at {}", executionIntervalTime);
+ }
+
+ /**
+ * Fetches the list of audit alert rules from the manager API.
+ * Constructs the request URL, sends an HTTP GET request, and processes
the response.
+ *
+ * @return A list of {@link AuditAlertRule} objects if successful, or null
if the request fails.
+ */
+ public List<AuditAlertRule> fetchAlertRulesFromManager() {
+ List<AuditAlertRule> auditAlertRules = new ArrayList<>();
+ try {
+ // Get the manager URL from app configuration
+ String managerUrl = appConfig.getManagerUrl();
+
+ // Ensure there is only one forward slash between the base URL and
path
+ String url = (managerUrl.endsWith("/") ? managerUrl.substring(0,
managerUrl.length() - 1) : managerUrl)
+ + AUDIT_ALERT_RULE_lIST_PATH;
+
+ Map<String, String> authHeader =
HttpUtils.getAuthHeader(appConfig.getSecretId(), appConfig.getSecretKey());
+ MultiValueMap<String, String> header = new LinkedMultiValueMap<>();
+ authHeader.forEach(header::add);
+
+ LOGGER.info("begin query audit alertRule list");
+
+ // Send HTTP POST request to the manager API to retrieve audit
alert rules
+ Response<PageResult<AuditAlertRule>> result = HttpUtil.request(
+ restTemplate,
+ url,
+ HttpMethod.POST,
+ new AuditAlertRulePageRequest(),
+ header,
+ new
ParameterizedTypeReference<Response<PageResult<AuditAlertRule>>>() {
+ });
+
+ LOGGER.info("success to query audit info for url ={}", url);
+
+ // Copy and return the list of audit alert rules
+ if (result.isSuccess()) {
+ auditAlertRules = result.getData().getList();
+ } else {
+ LOGGER.error("fetchAlertPolicies fail:{}", result.getErrMsg());
+ }
+ } catch (Exception e) {
+ LOGGER.error("fetchAlertPolicies fail: ", e);
+ }
+ return auditAlertRules;
+ }
+
+ /**
+ * Fetches audit data by retrieving audit alert rules and querying
detailed audit information for each rule.
+ *
+ * @return List of {@link String} containing detailed audit information
+ * @see #fetchAlertRulesFromManager()
+ */
+ public List<String> getAuditIds() {
+ List<String> auditIds = new ArrayList<>();
+ // Process each audit alert rule to get corresponding auditIds
+ for (AuditAlertRule auditAlertRule : auditAlertRuleList) {
+ // Convert comma-separated audit IDs to list and trim whitespace
+ List<String> auditIdList =
Arrays.stream(auditAlertRule.getAuditId().split(","))
+ .map(String::trim)
+ .collect(Collectors.toList());
+ auditIds.addAll(auditIdList);
+ }
+
+ // Return empty list if no successful responses were received
+ return auditIds;
+ }
+
+ /**
+ * Stop the fetch task
+ */
+ public void stop() {
+ scheduler.shutdown();
+ try {
+ if (!scheduler.awaitTermination(5, TimeUnit.SECONDS)) {
+ scheduler.shutdownNow();
+ }
+ } catch (InterruptedException e) {
+ scheduler.shutdownNow();
+ Thread.currentThread().interrupt();
+ }
+ }
+}
\ No newline at end of file
diff --git
a/inlong-audit/audit-tool/src/main/java/org/apache/inlong/audit/tool/response/Response.java
b/inlong-audit/audit-tool/src/main/java/org/apache/inlong/audit/tool/response/Response.java
new file mode 100644
index 0000000000..7180a1b62d
--- /dev/null
+++
b/inlong-audit/audit-tool/src/main/java/org/apache/inlong/audit/tool/response/Response.java
@@ -0,0 +1,32 @@
+/*
+ * 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.inlong.audit.tool.response;
+
+import lombok.Data;
+
+/**
+ * The response info of API
+ */
+@Data
+public class Response<T> {
+
+ private boolean success;
+ private String errMsg;
+ private T data;
+
+}
\ No newline at end of file
diff --git
a/inlong-audit/audit-tool/src/main/java/org/apache/inlong/audit/tool/util/AuditAlertRulePageRequest.java
b/inlong-audit/audit-tool/src/main/java/org/apache/inlong/audit/tool/util/AuditAlertRulePageRequest.java
new file mode 100644
index 0000000000..31c55bfa21
--- /dev/null
+++
b/inlong-audit/audit-tool/src/main/java/org/apache/inlong/audit/tool/util/AuditAlertRulePageRequest.java
@@ -0,0 +1,59 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.inlong.audit.tool.util;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.NoArgsConstructor;
+
+/**
+ * Audit alert rule paging query conditions
+ */
+@Data
+@Builder
+@NoArgsConstructor
+@AllArgsConstructor
+@EqualsAndHashCode(callSuper = false)
+@ApiModel("Audit alert rule paging query request")
+public class AuditAlertRulePageRequest extends PageRequest {
+
+ @ApiModelProperty("Rule ID")
+ private Integer id;
+
+ @ApiModelProperty(value = "Associated InLong Group ID")
+ private String inlongGroupId;
+
+ @ApiModelProperty("Associated InLong Stream ID")
+ private String inlongStreamId;
+
+ @ApiModelProperty(value = "Audit ID (associated with specific audit
metrics)")
+ private String auditId;
+
+ @ApiModelProperty("Alert name")
+ private String alertName;
+
+ @ApiModelProperty("Alert level (INFO/WARN/ERROR/CRITICAL)")
+ private String level;
+
+ @ApiModelProperty("Whether enabled")
+ private Boolean enabled;
+}
\ No newline at end of file
diff --git
a/inlong-audit/audit-tool/src/main/java/org/apache/inlong/audit/tool/util/HttpUtil.java
b/inlong-audit/audit-tool/src/main/java/org/apache/inlong/audit/tool/util/HttpUtil.java
new file mode 100644
index 0000000000..4526be4f13
--- /dev/null
+++
b/inlong-audit/audit-tool/src/main/java/org/apache/inlong/audit/tool/util/HttpUtil.java
@@ -0,0 +1,73 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.inlong.audit.tool.util;
+
+/*
+ * 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.
+ */
+
+import org.apache.inlong.manager.common.util.Preconditions;
+
+import com.google.gson.Gson;
+import com.google.gson.GsonBuilder;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.core.ParameterizedTypeReference;
+import org.springframework.http.HttpEntity;
+import org.springframework.http.HttpMethod;
+import org.springframework.http.ResponseEntity;
+import org.springframework.util.MultiValueMap;
+import org.springframework.web.client.RestTemplate;
+
+/**
+ * HTTP utils
+ */
+@Slf4j
+public class HttpUtil {
+
+ private static final Gson GSON = new GsonBuilder().create(); // thread safe
+
+ /**
+ * Send an HTTP request
+ */
+ public static <T> T request(RestTemplate restTemplate, String url,
HttpMethod httpMethod, Object requestBody,
+ MultiValueMap<String, String> header,
ParameterizedTypeReference<T> typeReference) {
+ if (log.isDebugEnabled()) {
+ log.debug("begin request to {} by request body {}", url,
GSON.toJson(requestBody));
+ }
+ HttpEntity<Object> requestEntity = new HttpEntity<>(requestBody,
header);
+ ResponseEntity<T> response = restTemplate.exchange(url, httpMethod,
requestEntity, typeReference);
+
+ log.debug("success request to {}, status code {}", url,
response.getStatusCode());
+ Preconditions.expectTrue(response.getStatusCode().is2xxSuccessful(),
"Request failed: " + response.getBody());
+ return response.getBody();
+ }
+
+}
diff --git
a/inlong-audit/audit-tool/src/main/java/org/apache/inlong/audit/tool/util/PageRequest.java
b/inlong-audit/audit-tool/src/main/java/org/apache/inlong/audit/tool/util/PageRequest.java
new file mode 100644
index 0000000000..0193807a3d
--- /dev/null
+++
b/inlong-audit/audit-tool/src/main/java/org/apache/inlong/audit/tool/util/PageRequest.java
@@ -0,0 +1,45 @@
+/*
+ * 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.inlong.audit.tool.util;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+/**
+ * Pagination request
+ */
+@Data
+@ApiModel(value = "Pagination request")
+public class PageRequest {
+
+ public static final Integer MAX_PAGE_SIZE = 100;
+
+ @ApiModelProperty(value = "Current page number, default is 1")
+ private int pageNum = 1;
+
+ @ApiModelProperty(value = "Page size, default is 10")
+ private int pageSize = 10;
+
+ @ApiModelProperty(value = "Order field, support create_time and
modify_time, default is create_time")
+ private String orderField = "create_time";
+
+ @ApiModelProperty(value = "Order type, only support asc and desc, default
is desc")
+ private String orderType = "desc";
+
+}
diff --git
a/inlong-audit/audit-tool/src/main/java/org/apache/inlong/audit/tool/util/PageResult.java
b/inlong-audit/audit-tool/src/main/java/org/apache/inlong/audit/tool/util/PageResult.java
new file mode 100644
index 0000000000..6f37ce3ef3
--- /dev/null
+++
b/inlong-audit/audit-tool/src/main/java/org/apache/inlong/audit/tool/util/PageResult.java
@@ -0,0 +1,45 @@
+/*
+ * 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.inlong.audit.tool.util;
+
+import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import java.io.Serializable;
+import java.util.List;
+
+@Data
+@JsonIgnoreProperties(ignoreUnknown = true)
+@ApiModel("Paginated query results")
+public final class PageResult<T> implements Serializable {
+
+ @ApiModelProperty(value = "data record", required = true)
+ private List<T> list;
+
+ @ApiModelProperty(value = "The total number of items matching the filter
criteria", required = true)
+ private Long total;
+
+ @ApiModelProperty(value = "pageSize", required = true)
+ private Integer pageSize;
+
+ @ApiModelProperty(value = "pageNum", required = true)
+ private Integer pageNum;
+
+}
\ No newline at end of file
diff --git a/inlong-audit/audit-tool/src/main/resources/application.properties
b/inlong-audit/audit-tool/src/main/resources/application.properties
new file mode 100644
index 0000000000..998e9e18d1
--- /dev/null
+++ b/inlong-audit/audit-tool/src/main/resources/application.properties
@@ -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.
+
+# Application properties for the audit tool
+# Configuration for connecting to the manager service
+manager.url=http://localhost:8083
+manager.api.key=your_api_key
+
+# Alert policy configuration
+alert.policy.threshold=5
+alert.policy.check.interval=60
+
+# Prometheus reporting configuration
+prometheus.enabled=true
+prometheus.endpoint=http://localhost:9090/api/v1/write
+prometheus.port=9091
+
+# OpenTelemetry reporting configuration
+opentelemetry.enabled=true
+opentelemetry.endpoint=http://localhost:4317
+opentelemetry.service.name=audit-tool
+
+# Logging configuration
+logging.level.root=INFO
+logging.file.path=/var/log/inlong/audit-tool.log
+
+# Audit Database settings
+audit.data.source=apache_inlong_audit
+audit.data.source.url=jdbc:mysql://192.168.10.3:3306/apache_inlong_audit
+audit.data.source.username=root
+audit.data.source.password=inlong
+audit.data.time.interval.minute=1
+audit.data.time.delay.minute=1
+audit.id.source=5
+
+# Audit SecretId SecretKey
+audit.secretId = admin
+audit.secretKey = inlong
\ No newline at end of file
diff --git
a/inlong-audit/audit-tool/src/test/java/org/apache/inlong/tool/AuditAlertRuleManager/AuditAlertRuleManagerTest.java
b/inlong-audit/audit-tool/src/test/java/org/apache/inlong/tool/AuditAlertRuleManager/AuditAlertRuleManagerTest.java
new file mode 100644
index 0000000000..19c0cff240
--- /dev/null
+++
b/inlong-audit/audit-tool/src/test/java/org/apache/inlong/tool/AuditAlertRuleManager/AuditAlertRuleManagerTest.java
@@ -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.inlong.tool.AuditAlertRuleManager;
+
+import org.apache.inlong.audit.tool.config.AppConfig;
+import org.apache.inlong.audit.tool.dto.AuditAlertRule;
+import org.apache.inlong.audit.tool.manager.AuditAlertRuleManager;
+import org.apache.inlong.audit.tool.response.Response;
+
+import org.junit.jupiter.api.Test;
+
+import java.util.Collections;
+import java.util.List;
+
+import static org.junit.jupiter.api.Assertions.*;
+
+class AuditAlertRuleManagerTest {
+
+ private final AuditAlertRuleManager auditAlertRuleManager =
AuditAlertRuleManager.getInstance();
+
+ @Test
+ void testFetchAlertRulesFromManager() {
+ // Mock data
+ AuditAlertRule rule = new AuditAlertRule();
+ rule.setId(1);
+ rule.setInlongGroupId("group1");
+
+ Response<List<AuditAlertRule>> mockResponse = new Response<>();
+ mockResponse.setSuccess(true);
+ mockResponse.setData(Collections.singletonList(rule));
+
+ try {
+ // Execute
+ auditAlertRuleManager.init(new AppConfig());
+ List<AuditAlertRule> result =
auditAlertRuleManager.fetchAlertRulesFromManager();
+
+ // Verify
+ assertNotNull(result);
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+
+ @Test
+ void testFetchAuditIds() {
+ // Mock alert rules
+ AuditAlertRule rule = new AuditAlertRule();
+ rule.setInlongGroupId("group1");
+ rule.setInlongStreamId("stream1");
+ rule.setAuditId("1,2,3");
+
+ Response<List<AuditAlertRule>> alertRulesResponse = new Response<>();
+ alertRulesResponse.setSuccess(true);
+ alertRulesResponse.setData(Collections.singletonList(rule));
+
+ try {
+ // Execute
+ auditAlertRuleManager.init(new AppConfig());
+ List<String> result = auditAlertRuleManager.getAuditIds();
+
+ // Verify
+ assertNotNull(result);
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+
+}
\ No newline at end of file
diff --git a/inlong-audit/pom.xml b/inlong-audit/pom.xml
index 81b4d0faf4..4bd11c39f6 100644
--- a/inlong-audit/pom.xml
+++ b/inlong-audit/pom.xml
@@ -38,6 +38,7 @@
<module>audit-sdk</module>
<module>audit-release</module>
<module>audit-docker</module>
+ <module>audit-tool</module>
</modules>
<properties>