This is an automated email from the ASF dual-hosted git repository.
psxjoy pushed a commit to branch intelligence
in repository https://gitbox.apache.org/repos/asf/ozhera.git
The following commit(s) were added to refs/heads/intelligence by this push:
new 1cb9f8ee fix: add intelligence implementation (#533)
1cb9f8ee is described below
commit 1cb9f8ee53270324c9154dd22493063e8c8eb329
Author: EricDing <[email protected]>
AuthorDate: Tue Jan 21 11:40:54 2025 +0800
fix: add intelligence implementation (#533)
* feat: add trace query and analyze filter
* feat: add log query
* feat: add metrics query
* feat: add controller layer code; improve the documentation
* feat: operator add intelligence yaml and nacos properties
* fix: transform en
---
ozhera-intelligence/README.md | 12 +
ozhera-intelligence/README_cn.md | 14 +
.../ozhera-intelligence-domain/pom.xml | 4 +
...QueryParam.java => HeraRootCaseAnalyseRes.java} | 21 +-
.../intelligence/domain/rootanalysis/Metric.java | 94 +++++++
...eryParam.java => MetricDataRangeSetVector.java} | 13 +-
...eQueryParam.java => MetricDataRangeVector.java} | 12 +-
...ryParam.java => MetricRangeResponseVector.java} | 13 +-
.../domain/rootanalysis/MetricsQueryParam.java | 4 +
.../domain/rootanalysis/TraceQueryParam.java | 4 +-
.../{TraceQueryParam.java => TraceTreeNode.java} | 25 +-
.../ozhera-intelligence-server/pom.xml | 2 +-
.../intelligence/config/DubboConfiguration.java | 71 +++++
.../intelligence/config/NacosConfiguration.java} | 27 +-
.../controller/RootAnalysisController.java | 56 +++-
.../intelligence/filter/TokenValidationFilter.java | 53 ++++
.../src/main/resources/application.properties | 13 +-
.../resources/config/opensource-outer.properties | 13 +-
.../ozhera-intelligence-service/pom.xml | 80 +++++-
.../ozhera/intelligence/service/LogService.java | 42 ++-
.../intelligence/service/MetricsService.java | 220 +++++++++++++++-
.../ozhera/intelligence/service/TraceService.java | 286 ++++++++++++++++++++-
.../ozhera/intelligence/util/CommitPoolUtil.java | 48 ++++
.../ozhera/intelligence/util/HttpClient.java | 92 +++++++
ozhera-intelligence/pom.xml | 15 ++
.../intelligence/ozhera_intelligence.yml | 34 ++-
..._intelligence_config_#_DEFAULT_GROUP.properties | 10 +-
readme/images/ozhera-intelligence.png | Bin 0 -> 347752 bytes
.../trace/etl/api/service/TraceQueryService.java | 22 +-
.../etl/manager/dubbo/TraceQueryServiceImpl.java | 61 +++++
30 files changed, 1264 insertions(+), 97 deletions(-)
diff --git a/ozhera-intelligence/README.md b/ozhera-intelligence/README.md
index fcbee8e4..6df452c4 100644
--- a/ozhera-intelligence/README.md
+++ b/ozhera-intelligence/README.md
@@ -30,4 +30,16 @@
## ozhera-intelligence-server
+ Service to initiate intelligent functionalities.
++ Access to the ozhera-intelligence-server requires the x-token to be included
in the header for authorized access to ozhera's data.
+## ozhera-intelligence-service
+
++ LogService: Retrieves log data
++ MetricsService: Retrieves monitoring metric data
++ TraceService: Retrieves trace data
+
+# Important Dependencies
+It relies on a Xiaomi open-source [Agent builder
platform--m78](https://github.com/XiaoMi/mone/tree/master/m78-all)
+
+# Intelligent Workflow (Sequence Diagram)
+
\ No newline at end of file
diff --git a/ozhera-intelligence/README_cn.md b/ozhera-intelligence/README_cn.md
index d1f3e85a..d2a448c2 100644
--- a/ozhera-intelligence/README_cn.md
+++ b/ozhera-intelligence/README_cn.md
@@ -29,3 +29,17 @@
## ozhera-intelligence-server
+ 智能化功能启动服务。
++ ozhera-intelligence-server访问需要header中带上x-token,实现有权限的访问ozhera的数据。
+
+## ozhera-intelligence-service
+
++ LogService,取日志数据
++ MetricsService,取监控指标数据
++ TraceService,取链路数据
+
+# 重要依赖
+会依赖小米开源的一款[Agent构建平台——m78](https://github.com/XiaoMi/mone/tree/master/m78-all)
+
+
+# 智能化工作流程(时序图)
+
\ No newline at end of file
diff --git a/ozhera-intelligence/ozhera-intelligence-domain/pom.xml
b/ozhera-intelligence/ozhera-intelligence-domain/pom.xml
index e1cf6cef..605a0315 100644
--- a/ozhera-intelligence/ozhera-intelligence-domain/pom.xml
+++ b/ozhera-intelligence/ozhera-intelligence-domain/pom.xml
@@ -41,6 +41,10 @@
<artifactId>lombok</artifactId>
<scope>provided</scope>
</dependency>
+ <dependency>
+ <groupId>org.apache.ozhera</groupId>
+ <artifactId>trace-etl-domain</artifactId>
+ </dependency>
</dependencies>
<build>
diff --git
a/ozhera-intelligence/ozhera-intelligence-domain/src/main/java/org/apache/ozhera/intelligence/domain/rootanalysis/TraceQueryParam.java
b/ozhera-intelligence/ozhera-intelligence-domain/src/main/java/org/apache/ozhera/intelligence/domain/rootanalysis/HeraRootCaseAnalyseRes.java
similarity index 74%
copy from
ozhera-intelligence/ozhera-intelligence-domain/src/main/java/org/apache/ozhera/intelligence/domain/rootanalysis/TraceQueryParam.java
copy to
ozhera-intelligence/ozhera-intelligence-domain/src/main/java/org/apache/ozhera/intelligence/domain/rootanalysis/HeraRootCaseAnalyseRes.java
index 18fdcdf1..bca831c3 100644
---
a/ozhera-intelligence/ozhera-intelligence-domain/src/main/java/org/apache/ozhera/intelligence/domain/rootanalysis/TraceQueryParam.java
+++
b/ozhera-intelligence/ozhera-intelligence-domain/src/main/java/org/apache/ozhera/intelligence/domain/rootanalysis/HeraRootCaseAnalyseRes.java
@@ -18,15 +18,20 @@
*/
package org.apache.ozhera.intelligence.domain.rootanalysis;
-import lombok.Builder;
import lombok.Data;
+import lombok.ToString;
-import java.util.List;
-
+/**
+ * @author dingtao
+ * @date 2025/1/20 11:26
+ */
@Data
-@Builder
-public class TraceQueryParam {
- private String traceId;
- private String env;
- private List<String> timeStamp;
+@ToString
+public class HeraRootCaseAnalyseRes {
+ private Double maxCpuUsage;
+ private Double maxLoad;
+ private Double maxJvmHeapUsage;
+ private Double maxSTWCost;
+ private Double STWCountOf1m;
+ private Double cpuCount;
}
diff --git
a/ozhera-intelligence/ozhera-intelligence-domain/src/main/java/org/apache/ozhera/intelligence/domain/rootanalysis/Metric.java
b/ozhera-intelligence/ozhera-intelligence-domain/src/main/java/org/apache/ozhera/intelligence/domain/rootanalysis/Metric.java
new file mode 100644
index 00000000..d3cd46d8
--- /dev/null
+++
b/ozhera-intelligence/ozhera-intelligence-domain/src/main/java/org/apache/ozhera/intelligence/domain/rootanalysis/Metric.java
@@ -0,0 +1,94 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.ozhera.intelligence.domain.rootanalysis;
+
+import lombok.Data;
+
+import java.io.Serializable;
+
+@Data
+public class Metric implements Serializable {
+ private String application;
+ private String instance;
+ private String ip;
+ private String job;
+
+ private String replica;
+ private String serverIp;
+
+ //dubbo label
+ private String methodName;
+ private String serviceName;
+
+ //sql
+ private String sqlMethod;
+ private String sql;
+ private String dataSource;
+
+ //redis
+ private String host;
+ private String port;
+ private String dbindex;
+ private String method;
+
+ //env
+ private String serverEnv;
+
+ //container info
+ private String container_label_PROJECT_ID;
+ private String name;//container name eg:zzytest-20220323221926067
+ private String container;//container name for k8s
eg:youpin-gateway-dingtao-test2-900329(gitGroup-gitName-envId)
+ private String pod;//pod name for k8s
eg:91102-dingtao-test-644758f5b4-jk9t7
+ private String namespace;//namespace name for k8s eg:nrme
+
+ private String lastCreateTime;
+
+ private double value;
+
+ private String timestamp;
+
+ private String traceId;
+
+ private String service;
+
+ private String apiid;
+
+ private String serialid;
+
+ private String sceneid;
+
+ private String pod_ip;
+
+ private String calert;
+
+ private String alert_op;
+
+ private String alert_value;
+
+ private String detailRedirectUrl;
+
+ private String __priority__;
+
+ // downstream service information
+ private String clientProjectId;
+ private String clientProjectName;
+ private String clientEnv;
+ private String clientIp;
+
+}
diff --git
a/ozhera-intelligence/ozhera-intelligence-domain/src/main/java/org/apache/ozhera/intelligence/domain/rootanalysis/TraceQueryParam.java
b/ozhera-intelligence/ozhera-intelligence-domain/src/main/java/org/apache/ozhera/intelligence/domain/rootanalysis/MetricDataRangeSetVector.java
similarity index 82%
copy from
ozhera-intelligence/ozhera-intelligence-domain/src/main/java/org/apache/ozhera/intelligence/domain/rootanalysis/TraceQueryParam.java
copy to
ozhera-intelligence/ozhera-intelligence-domain/src/main/java/org/apache/ozhera/intelligence/domain/rootanalysis/MetricDataRangeSetVector.java
index 18fdcdf1..eac24817 100644
---
a/ozhera-intelligence/ozhera-intelligence-domain/src/main/java/org/apache/ozhera/intelligence/domain/rootanalysis/TraceQueryParam.java
+++
b/ozhera-intelligence/ozhera-intelligence-domain/src/main/java/org/apache/ozhera/intelligence/domain/rootanalysis/MetricDataRangeSetVector.java
@@ -18,15 +18,16 @@
*/
package org.apache.ozhera.intelligence.domain.rootanalysis;
-import lombok.Builder;
import lombok.Data;
+import lombok.ToString;
+import java.io.Serializable;
import java.util.List;
@Data
-@Builder
-public class TraceQueryParam {
- private String traceId;
- private String env;
- private List<String> timeStamp;
+@ToString
+public class MetricDataRangeSetVector implements Serializable {
+ private Metric metric;
+ private List<List<String>> values;
}
+
diff --git
a/ozhera-intelligence/ozhera-intelligence-domain/src/main/java/org/apache/ozhera/intelligence/domain/rootanalysis/TraceQueryParam.java
b/ozhera-intelligence/ozhera-intelligence-domain/src/main/java/org/apache/ozhera/intelligence/domain/rootanalysis/MetricDataRangeVector.java
similarity index 81%
copy from
ozhera-intelligence/ozhera-intelligence-domain/src/main/java/org/apache/ozhera/intelligence/domain/rootanalysis/TraceQueryParam.java
copy to
ozhera-intelligence/ozhera-intelligence-domain/src/main/java/org/apache/ozhera/intelligence/domain/rootanalysis/MetricDataRangeVector.java
index 18fdcdf1..8f2e1d2d 100644
---
a/ozhera-intelligence/ozhera-intelligence-domain/src/main/java/org/apache/ozhera/intelligence/domain/rootanalysis/TraceQueryParam.java
+++
b/ozhera-intelligence/ozhera-intelligence-domain/src/main/java/org/apache/ozhera/intelligence/domain/rootanalysis/MetricDataRangeVector.java
@@ -18,15 +18,15 @@
*/
package org.apache.ozhera.intelligence.domain.rootanalysis;
-import lombok.Builder;
import lombok.Data;
+import lombok.ToString;
+import java.io.Serializable;
import java.util.List;
@Data
-@Builder
-public class TraceQueryParam {
- private String traceId;
- private String env;
- private List<String> timeStamp;
+@ToString
+public class MetricDataRangeVector implements Serializable {
+ private String resultType;
+ private List<MetricDataRangeSetVector> result;
}
diff --git
a/ozhera-intelligence/ozhera-intelligence-domain/src/main/java/org/apache/ozhera/intelligence/domain/rootanalysis/TraceQueryParam.java
b/ozhera-intelligence/ozhera-intelligence-domain/src/main/java/org/apache/ozhera/intelligence/domain/rootanalysis/MetricRangeResponseVector.java
similarity index 82%
copy from
ozhera-intelligence/ozhera-intelligence-domain/src/main/java/org/apache/ozhera/intelligence/domain/rootanalysis/TraceQueryParam.java
copy to
ozhera-intelligence/ozhera-intelligence-domain/src/main/java/org/apache/ozhera/intelligence/domain/rootanalysis/MetricRangeResponseVector.java
index 18fdcdf1..70bc9343 100644
---
a/ozhera-intelligence/ozhera-intelligence-domain/src/main/java/org/apache/ozhera/intelligence/domain/rootanalysis/TraceQueryParam.java
+++
b/ozhera-intelligence/ozhera-intelligence-domain/src/main/java/org/apache/ozhera/intelligence/domain/rootanalysis/MetricRangeResponseVector.java
@@ -18,15 +18,14 @@
*/
package org.apache.ozhera.intelligence.domain.rootanalysis;
-import lombok.Builder;
import lombok.Data;
+import lombok.ToString;
-import java.util.List;
+import java.io.Serializable;
@Data
-@Builder
-public class TraceQueryParam {
- private String traceId;
- private String env;
- private List<String> timeStamp;
+@ToString
+public class MetricRangeResponseVector implements Serializable {
+ private String status;
+ private MetricDataRangeVector data;
}
diff --git
a/ozhera-intelligence/ozhera-intelligence-domain/src/main/java/org/apache/ozhera/intelligence/domain/rootanalysis/MetricsQueryParam.java
b/ozhera-intelligence/ozhera-intelligence-domain/src/main/java/org/apache/ozhera/intelligence/domain/rootanalysis/MetricsQueryParam.java
index 96541b9d..98a64481 100644
---
a/ozhera-intelligence/ozhera-intelligence-domain/src/main/java/org/apache/ozhera/intelligence/domain/rootanalysis/MetricsQueryParam.java
+++
b/ozhera-intelligence/ozhera-intelligence-domain/src/main/java/org/apache/ozhera/intelligence/domain/rootanalysis/MetricsQueryParam.java
@@ -20,9 +20,11 @@ package org.apache.ozhera.intelligence.domain.rootanalysis;
import lombok.Builder;
import lombok.Data;
+import lombok.ToString;
@Data
@Builder
+@ToString
public class MetricsQueryParam {
private String env;
@@ -33,6 +35,8 @@ public class MetricsQueryParam {
private String startTime;
+ private String endTime;
+
private String duration;
// The error margin between the start time and end time,
diff --git
a/ozhera-intelligence/ozhera-intelligence-domain/src/main/java/org/apache/ozhera/intelligence/domain/rootanalysis/TraceQueryParam.java
b/ozhera-intelligence/ozhera-intelligence-domain/src/main/java/org/apache/ozhera/intelligence/domain/rootanalysis/TraceQueryParam.java
index 18fdcdf1..b9de7208 100644
---
a/ozhera-intelligence/ozhera-intelligence-domain/src/main/java/org/apache/ozhera/intelligence/domain/rootanalysis/TraceQueryParam.java
+++
b/ozhera-intelligence/ozhera-intelligence-domain/src/main/java/org/apache/ozhera/intelligence/domain/rootanalysis/TraceQueryParam.java
@@ -20,13 +20,15 @@ package org.apache.ozhera.intelligence.domain.rootanalysis;
import lombok.Builder;
import lombok.Data;
+import lombok.ToString;
import java.util.List;
@Data
@Builder
+@ToString
public class TraceQueryParam {
private String traceId;
private String env;
- private List<String> timeStamp;
+ private long timeStamp;
}
diff --git
a/ozhera-intelligence/ozhera-intelligence-domain/src/main/java/org/apache/ozhera/intelligence/domain/rootanalysis/TraceQueryParam.java
b/ozhera-intelligence/ozhera-intelligence-domain/src/main/java/org/apache/ozhera/intelligence/domain/rootanalysis/TraceTreeNode.java
similarity index 68%
copy from
ozhera-intelligence/ozhera-intelligence-domain/src/main/java/org/apache/ozhera/intelligence/domain/rootanalysis/TraceQueryParam.java
copy to
ozhera-intelligence/ozhera-intelligence-domain/src/main/java/org/apache/ozhera/intelligence/domain/rootanalysis/TraceTreeNode.java
index 18fdcdf1..14998c59 100644
---
a/ozhera-intelligence/ozhera-intelligence-domain/src/main/java/org/apache/ozhera/intelligence/domain/rootanalysis/TraceQueryParam.java
+++
b/ozhera-intelligence/ozhera-intelligence-domain/src/main/java/org/apache/ozhera/intelligence/domain/rootanalysis/TraceTreeNode.java
@@ -18,15 +18,28 @@
*/
package org.apache.ozhera.intelligence.domain.rootanalysis;
-import lombok.Builder;
import lombok.Data;
+import org.apache.ozhera.trace.etl.domain.tracequery.Span;
+import java.util.ArrayList;
import java.util.List;
@Data
-@Builder
-public class TraceQueryParam {
- private String traceId;
- private String env;
- private List<String> timeStamp;
+public class TraceTreeNode {
+
+ private Span span;
+ private List<TraceTreeNode> children;
+
+ public TraceTreeNode(Span span){
+ this.span = span;
+ this.children = new ArrayList<>();
+ }
+
+ public TraceTreeNode(){
+
+ }
+
+ public void addChild(TraceTreeNode child) {
+ children.add(child);
+ }
}
diff --git a/ozhera-intelligence/ozhera-intelligence-server/pom.xml
b/ozhera-intelligence/ozhera-intelligence-server/pom.xml
index 02cdac4c..5664c130 100644
--- a/ozhera-intelligence/ozhera-intelligence-server/pom.xml
+++ b/ozhera-intelligence/ozhera-intelligence-server/pom.xml
@@ -80,7 +80,7 @@
<artifactId>spring-boot-maven-plugin</artifactId>
<version>2.7.15</version>
<configuration>
-
<mainClass>org.apache.ozhera.trace.etl.bootstrap.TraceEtlBootstrap</mainClass>
+
<mainClass>org.apache.ozhera.intelligence.bootstrap.IntelligenceBootStrap</mainClass>
</configuration>
<executions>
<execution>
diff --git
a/ozhera-intelligence/ozhera-intelligence-server/src/main/java/org/apache/ozhera/intelligence/config/DubboConfiguration.java
b/ozhera-intelligence/ozhera-intelligence-server/src/main/java/org/apache/ozhera/intelligence/config/DubboConfiguration.java
new file mode 100644
index 00000000..f672299f
--- /dev/null
+++
b/ozhera-intelligence/ozhera-intelligence-server/src/main/java/org/apache/ozhera/intelligence/config/DubboConfiguration.java
@@ -0,0 +1,71 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.ozhera.intelligence.config;
+
+import com.alibaba.nacos.api.config.annotation.NacosValue;
+import com.google.common.collect.Maps;
+import org.apache.dubbo.config.ApplicationConfig;
+import org.apache.dubbo.config.ProtocolConfig;
+import org.apache.dubbo.config.RegistryConfig;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+
+@Configuration
+public class DubboConfiguration {
+
+ @Value("${dubbo.protocol.port}")
+ private int port;
+
+ @Value("${server.port}")
+ private String httpGateWayPort;
+
+ @NacosValue("${dubbo.registry.address}")
+ private String regAddress;
+
+ @Bean
+ public ApplicationConfig applicationConfig() {
+ ApplicationConfig applicationConfig = new ApplicationConfig();
+ applicationConfig.setName("Trace-etl-manager");
+ applicationConfig.setParameters(Maps.newHashMap());
+ applicationConfig.getParameters().put("http_gateway_port",
httpGateWayPort);
+ applicationConfig.getParameters().put("dubbo_version", "1.0");
+ applicationConfig.setQosEnable(false);
+ return applicationConfig;
+ }
+
+ @Bean
+ public RegistryConfig registryConfig() {
+ RegistryConfig registryConfig = new RegistryConfig();
+ registryConfig.setAddress(regAddress);
+ return registryConfig;
+ }
+
+ @Bean
+ public ProtocolConfig protocolConfig() {
+ ProtocolConfig protocolConfig = new ProtocolConfig();
+ protocolConfig.setPort(port);
+ protocolConfig.setTransporter("netty4");
+ protocolConfig.setThreadpool("fixed");
+ protocolConfig.setThreads(800);
+ return protocolConfig;
+ }
+
+}
\ No newline at end of file
diff --git
a/ozhera-intelligence/ozhera-intelligence-service/src/main/java/org/apache/ozhera/intelligence/service/MetricsService.java
b/ozhera-intelligence/ozhera-intelligence-server/src/main/java/org/apache/ozhera/intelligence/config/NacosConfiguration.java
similarity index 60%
copy from
ozhera-intelligence/ozhera-intelligence-service/src/main/java/org/apache/ozhera/intelligence/service/MetricsService.java
copy to
ozhera-intelligence/ozhera-intelligence-server/src/main/java/org/apache/ozhera/intelligence/config/NacosConfiguration.java
index 9b17a893..cb7d29d4 100644
---
a/ozhera-intelligence/ozhera-intelligence-service/src/main/java/org/apache/ozhera/intelligence/service/MetricsService.java
+++
b/ozhera-intelligence/ozhera-intelligence-server/src/main/java/org/apache/ozhera/intelligence/config/NacosConfiguration.java
@@ -16,23 +16,16 @@
* specific language governing permissions and limitations
* under the License.
*/
-package org.apache.ozhera.intelligence.service;
-import org.springframework.stereotype.Service;
-import org.apache.ozhera.intelligence.domain.rootanalysis.MetricsQueryParam;
+package org.apache.ozhera.intelligence.config;
-/**
- *
- */
-@Service
-public class MetricsService {
+import com.alibaba.nacos.api.annotation.NacosProperties;
+import com.alibaba.nacos.spring.context.annotation.config.EnableNacosConfig;
+import com.alibaba.nacos.spring.context.annotation.config.NacosPropertySource;
+import org.springframework.context.annotation.Configuration;
- /**
- * Query metrics based on the specified metric query conditions.
- * @param param
- * @return
- */
- public String queryMetricsRootAnalysis(MetricsQueryParam param){
- return null;
- }
-}
+@Configuration
+@EnableNacosConfig(globalProperties = @NacosProperties(serverAddr =
"${nacos.address}"))
+@NacosPropertySource(dataId = "hera_intelligence_config", autoRefreshed = true)
+public class NacosConfiguration {
+}
\ No newline at end of file
diff --git
a/ozhera-intelligence/ozhera-intelligence-server/src/main/java/org/apache/ozhera/intelligence/controller/RootAnalysisController.java
b/ozhera-intelligence/ozhera-intelligence-server/src/main/java/org/apache/ozhera/intelligence/controller/RootAnalysisController.java
index 62ba03c2..aad511cc 100644
---
a/ozhera-intelligence/ozhera-intelligence-server/src/main/java/org/apache/ozhera/intelligence/controller/RootAnalysisController.java
+++
b/ozhera-intelligence/ozhera-intelligence-server/src/main/java/org/apache/ozhera/intelligence/controller/RootAnalysisController.java
@@ -19,13 +19,23 @@
package org.apache.ozhera.intelligence.controller;
import com.xiaomi.youpin.infra.rpc.Result;
+import com.xiaomi.youpin.infra.rpc.errors.GeneralCodes;
import lombok.extern.slf4j.Slf4j;
+import
org.apache.ozhera.intelligence.domain.rootanalysis.HeraRootCaseAnalyseRes;
+import org.apache.ozhera.intelligence.domain.rootanalysis.LogParam;
+import org.apache.ozhera.intelligence.domain.rootanalysis.MetricsQueryParam;
+import org.apache.ozhera.intelligence.service.LogService;
+import org.apache.ozhera.intelligence.service.MetricsService;
+import org.apache.ozhera.intelligence.service.TraceService;
+import org.apache.ozhera.trace.etl.domain.tracequery.Span;
import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.apache.ozhera.intelligence.domain.rootanalysis.TraceQueryParam;
-import org.apache.ozhera.intelligence.service.RootAnalysisService;
+
+import java.util.List;
+import java.util.Map;
@RestController
@RequestMapping("/analysis")
@@ -33,10 +43,44 @@ import
org.apache.ozhera.intelligence.service.RootAnalysisService;
public class RootAnalysisController {
@Autowired
- private RootAnalysisService rootAnalysisService;
+ private TraceService traceService;
+
+ @Autowired
+ private LogService logService;
+
+ @Autowired
+ private MetricsService metricsService;
+
+ @PostMapping("/trace/sectional/span")
+ public Result<List<Span>> traceRootAnalysis(TraceQueryParam param) {
+ try {
+ List<Span> spans = traceService.queryTraceRootAnalysis(param);
+ return Result.success(spans);
+ }catch (Exception e){
+ log.error("trace analyze error , ", e);
+ return Result.fail(GeneralCodes.InternalError, "trace analyze
error");
+ }
+ }
+
+ @PostMapping("/log/condition")
+ public Result<List<Map<String, Object>>> logCondition(LogParam param) {
+ try {
+ List<Map<String, Object>> logs =
logService.queryLogRootAnalysis(param);
+ return Result.success(logs);
+ }catch (Exception e){
+ log.error("log analyze error , ", e);
+ return Result.fail(GeneralCodes.InternalError, "log analyze
error");
+ }
+ }
- @GetMapping("/trace")
- public Result<String> traceRootAnalysis(TraceQueryParam param) {
- return rootAnalysisService.traceRootAnalysis(param);
+ @PostMapping("/metrics")
+ public Result<HeraRootCaseAnalyseRes> metrics(MetricsQueryParam param) {
+ try {
+ HeraRootCaseAnalyseRes metrics =
metricsService.queryMetricsRootAnalysis(param);
+ return Result.success(metrics);
+ }catch (Exception e){
+ log.error("metrics analyze error , ", e);
+ return Result.fail(GeneralCodes.InternalError, "metrics analyze
error");
+ }
}
}
diff --git
a/ozhera-intelligence/ozhera-intelligence-server/src/main/java/org/apache/ozhera/intelligence/filter/TokenValidationFilter.java
b/ozhera-intelligence/ozhera-intelligence-server/src/main/java/org/apache/ozhera/intelligence/filter/TokenValidationFilter.java
new file mode 100644
index 00000000..572da052
--- /dev/null
+++
b/ozhera-intelligence/ozhera-intelligence-server/src/main/java/org/apache/ozhera/intelligence/filter/TokenValidationFilter.java
@@ -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.
+ */
+package org.apache.ozhera.intelligence.filter;
+
+import com.alibaba.nacos.api.config.annotation.NacosValue;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.stereotype.Component;
+import org.springframework.web.filter.OncePerRequestFilter;
+
+import javax.servlet.FilterChain;
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.io.IOException;
+
+@Component
+public class TokenValidationFilter extends OncePerRequestFilter {
+
+ private static final Logger logger =
LoggerFactory.getLogger(TokenValidationFilter.class);
+
+ @NacosValue("${analyze.token}")
+ private String validToken;
+
+ @Override
+ protected void doFilterInternal(HttpServletRequest request,
HttpServletResponse response, FilterChain filterChain)
+ throws ServletException, IOException {
+ String token = request.getHeader("x-token");
+
+ if (token != null && token.equals(validToken)) {
+ filterChain.doFilter(request, response);
+ } else {
+ logger.warn("Token incorrect, illegal request!");
+ response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
+ }
+ }
+}
diff --git
a/ozhera-intelligence/ozhera-intelligence-server/src/main/resources/application.properties
b/ozhera-intelligence/ozhera-intelligence-server/src/main/resources/application.properties
index a38e97e5..56919051 100644
---
a/ozhera-intelligence/ozhera-intelligence-server/src/main/resources/application.properties
+++
b/ozhera-intelligence/ozhera-intelligence-server/src/main/resources/application.properties
@@ -18,4 +18,15 @@ app.name=${app.name}
server.type=${server.type}
server.port=${server.port}
-log.path=${log.path}
\ No newline at end of file
+log.path=${log.path}
+
+dubbo.group=${dubbo.group}
+dubbo.protocol.id=${dubbo.protocol.id}
+dubbo.protocol.name=${dubbo.protocol.name}
+dubbo.protocol.port=${dubbo.protocol.port}
+trace.query.group=${trace.query.group}
+trace.query.version=${trace.query.version}
+log.query.group=${log.query.group}
+log.query.version=${log.query.version}
+
+nacos.address=${nacos.address}
\ No newline at end of file
diff --git
a/ozhera-intelligence/ozhera-intelligence-server/src/main/resources/config/opensource-outer.properties
b/ozhera-intelligence/ozhera-intelligence-server/src/main/resources/config/opensource-outer.properties
index 5ad085dd..08fdc828 100644
---
a/ozhera-intelligence/ozhera-intelligence-server/src/main/resources/config/opensource-outer.properties
+++
b/ozhera-intelligence/ozhera-intelligence-server/src/main/resources/config/opensource-outer.properties
@@ -18,4 +18,15 @@ app.name=ozhera-intelligence
server.type=staging
server.port=8080
-log.path=/tmp/work/log
\ No newline at end of file
+log.path=/tmp/work/log
+
+dubbo.group=staging
+dubbo.protocol.id=dubbo
+dubbo.protocol.name=dubbo
+dubbo.protocol.port=-1
+trace.query.group=staging
+trace.query.version=1.0
+log.query.group=
+log.query.version=1.0
+
+nacos.address=nacos:80
\ No newline at end of file
diff --git a/ozhera-intelligence/ozhera-intelligence-service/pom.xml
b/ozhera-intelligence/ozhera-intelligence-service/pom.xml
index e1afc94f..fc97b77f 100644
--- a/ozhera-intelligence/ozhera-intelligence-service/pom.xml
+++ b/ozhera-intelligence/ozhera-intelligence-service/pom.xml
@@ -72,11 +72,16 @@
<artifactId>spring-test</artifactId>
</dependency>
- <!-- trace domain -->
+ <!-- trace api -->
<dependency>
<groupId>org.apache.ozhera</groupId>
- <artifactId>trace-etl-domain</artifactId>
- <version>2.2.5-incubating</version>
+ <artifactId>trace-etl-api</artifactId>
+ </dependency>
+
+ <!-- log api -->
+ <dependency>
+ <groupId>org.apache.ozhera</groupId>
+ <artifactId>log-api</artifactId>
</dependency>
<dependency>
@@ -88,6 +93,75 @@
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
+
+ <dependency>
+ <groupId>run.mone</groupId>
+ <artifactId>dubbo</artifactId>
+ <exclusions>
+ <exclusion>
+ <groupId>com.alibaba.spring</groupId>
+ <artifactId>spring-context-support</artifactId>
+ </exclusion>
+ </exclusions>
+ </dependency>
+
+ <!-- nacos -->
+ <dependency>
+ <groupId>run.mone</groupId>
+ <artifactId>spring-context-support</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>run.mone</groupId>
+ <artifactId>nacos-client</artifactId>
+ <exclusions>
+ <exclusion>
+ <groupId>org.slf4j</groupId>
+ <artifactId>slf4j-api</artifactId>
+ </exclusion>
+ <exclusion>
+ <groupId>com.fasterxml.jackson.core</groupId>
+ <artifactId>jackson-core</artifactId>
+ </exclusion>
+ <exclusion>
+ <groupId>com.fasterxml.jackson.core</groupId>
+ <artifactId>jackson-databind</artifactId>
+ </exclusion>
+ </exclusions>
+ </dependency>
+ <dependency>
+ <groupId>run.mone</groupId>
+ <artifactId>dubbo-registry-nacos</artifactId>
+ <exclusions>
+ <exclusion>
+ <artifactId>spring-context-support</artifactId>
+ <groupId>com.alibaba.spring</groupId>
+ </exclusion>
+ </exclusions>
+ </dependency>
+ <dependency>
+ <groupId>com.alibaba.nacos</groupId>
+ <artifactId>nacos-spring-context</artifactId>
+ <exclusions>
+ <exclusion>
+ <groupId>com.fasterxml.jackson.core</groupId>
+ <artifactId>jackson-databind</artifactId>
+ </exclusion>
+ <exclusion>
+ <groupId>com.fasterxml.jackson.core</groupId>
+ <artifactId>jackson-core</artifactId>
+ </exclusion>
+ <exclusion>
+ <groupId>com.alibaba.spring</groupId>
+ <artifactId>spring-context-support</artifactId>
+ </exclusion>
+ </exclusions>
+ </dependency>
+
+ <!-- okhttp -->
+ <dependency>
+ <groupId>com.squareup.okhttp3</groupId>
+ <artifactId>okhttp</artifactId>
+ </dependency>
</dependencies>
<build>
diff --git
a/ozhera-intelligence/ozhera-intelligence-service/src/main/java/org/apache/ozhera/intelligence/service/LogService.java
b/ozhera-intelligence/ozhera-intelligence-service/src/main/java/org/apache/ozhera/intelligence/service/LogService.java
index 4a1075d4..a59402f2 100644
---
a/ozhera-intelligence/ozhera-intelligence-service/src/main/java/org/apache/ozhera/intelligence/service/LogService.java
+++
b/ozhera-intelligence/ozhera-intelligence-service/src/main/java/org/apache/ozhera/intelligence/service/LogService.java
@@ -18,18 +18,54 @@
*/
package org.apache.ozhera.intelligence.service;
+import org.apache.dubbo.config.annotation.DubboReference;
+import org.apache.ozhera.log.api.model.dto.LogFilterOptions;
+import org.apache.ozhera.log.api.service.HeraLogApiService;
import org.springframework.stereotype.Service;
import org.apache.ozhera.intelligence.domain.rootanalysis.LogParam;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * @author dingtao
+ * @date 2025/1/20 11:26
+ */
@Service
public class LogService {
+ @DubboReference(interfaceClass = HeraLogApiService.class, group =
"${log.query.group}", version = "${log.query.version}")
+ private HeraLogApiService heraLogApiService;
+
/**
+ * To cover the trace time in the log, we extend the trace time by 5
minutes before and after as a condition to query the log
+ */
+ private static final int LOG_QUERY_TIME_GAP = 1000 * 60 * 5;
+
+
+ /**
* Query logs based on the specified log query conditions.
+ *
* @param param
* @return
*/
- public String queryLogRootAnalysis(LogParam param){
- return null;
+ public List<Map<String, Object>> queryLogRootAnalysis(LogParam param) {
+ List<Map<String, Object>> maps =
heraLogApiService.queryLogData(buildLogFilterOptions(param));
+ return maps;
+ }
+
+
+ private LogFilterOptions buildLogFilterOptions(LogParam param) {
+ LogFilterOptions logFilterOptions = new LogFilterOptions();
+ logFilterOptions.setProjectId(Long.parseLong(param.getApplication()));
+ logFilterOptions.setEnvId(Long.parseLong(param.getEnvId()));
+ logFilterOptions.setTraceId(param.getTraceId());
+ Long startTime = Long.parseLong(param.getStartTime());
+ Long duration = Long.parseLong(param.getDuration());
+ Long endTime = startTime + duration;
+ logFilterOptions.setStartTime(String.valueOf(startTime / 1000 -
LOG_QUERY_TIME_GAP));
+ logFilterOptions.setEndTime(String.valueOf(endTime / 1000 +
LOG_QUERY_TIME_GAP));
+ logFilterOptions.setLevel(param.getLevel());
+ return logFilterOptions;
}
-}
+}
\ No newline at end of file
diff --git
a/ozhera-intelligence/ozhera-intelligence-service/src/main/java/org/apache/ozhera/intelligence/service/MetricsService.java
b/ozhera-intelligence/ozhera-intelligence-service/src/main/java/org/apache/ozhera/intelligence/service/MetricsService.java
index 9b17a893..0207be19 100644
---
a/ozhera-intelligence/ozhera-intelligence-service/src/main/java/org/apache/ozhera/intelligence/service/MetricsService.java
+++
b/ozhera-intelligence/ozhera-intelligence-service/src/main/java/org/apache/ozhera/intelligence/service/MetricsService.java
@@ -18,21 +18,231 @@
*/
package org.apache.ozhera.intelligence.service;
+import com.alibaba.nacos.api.config.annotation.NacosValue;
+import com.google.gson.Gson;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.http.client.utils.URIBuilder;
+import
org.apache.ozhera.intelligence.domain.rootanalysis.HeraRootCaseAnalyseRes;
+import
org.apache.ozhera.intelligence.domain.rootanalysis.MetricDataRangeSetVector;
+import
org.apache.ozhera.intelligence.domain.rootanalysis.MetricRangeResponseVector;
+import org.apache.ozhera.intelligence.util.HttpClient;
import org.springframework.stereotype.Service;
import org.apache.ozhera.intelligence.domain.rootanalysis.MetricsQueryParam;
+import java.net.MalformedURLException;
+import java.net.URISyntaxException;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.CompletableFuture;
+import java.util.concurrent.TimeUnit;
+
+import static
org.apache.ozhera.intelligence.util.CommitPoolUtil.HERA_SOLUTION_METRICS_POOL;
+
/**
- *
+ * @author dingtao
+ * @date 2025/1/20 11:26
*/
@Service
+@Slf4j
public class MetricsService {
+ @NacosValue("${prometheus.api.url}")
+ private String prometheusUrl;
+
+ private static final String URI_QUERY_RANGE = "/api/v1/query_range";
+ private static final String P_QUERY = "query";
+ private static final String P_STEP = "step";
+ private static final String P_START = "start";
+ private static final String P_END = "end";
+
/**
* Query metrics based on the specified metric query conditions.
- * @param param
+ *
+ * @param req
* @return
*/
- public String queryMetricsRootAnalysis(MetricsQueryParam param){
- return null;
+ public HeraRootCaseAnalyseRes queryMetricsRootAnalysis(MetricsQueryParam
req) {
+ HeraRootCaseAnalyseRes res = new HeraRootCaseAnalyseRes();
+ try {
+ updateParam(req);
+ log.info("updated param is : " + req);
+ String kubePodInfoPromQl = getKubePodInfoPromQl(req.getIp());
+ log.info("getPodNameByKubePodInfo.kubePodInfoPromQl:{}",
kubePodInfoPromQl);
+ MetricRangeResponseVector podPodIpListVector =
requestPrometheusRangeV2(kubePodInfoPromQl,
+ req.getStartTime(), req.getEndTime(), req.getEnv());
+ List<MetricDataRangeSetVector> kubePodInfo =
podPodIpListVector.getData().getResult();
+ MetricDataRangeSetVector kubePodInfoMetrics =
kubePodInfo.get(kubePodInfo.size() - 1);
+ String podName = kubePodInfoMetrics.getMetric().getPod();
+ String cpuPromQl =
"max(rate(container_cpu_user_seconds_total{system=\"mione\",application=\"" +
req.getApplication() + "\", pod=\"" + podName + "\", image!=\"\", container =~
\"^(?:\\\\d+-0-\\\\d+|faas-sidecar)$\"}[30s]) * 100)";
+ String loadPromQl =
"max(container_cpu_load_average_10s{system=\"mione\",application=\"" +
req.getApplication() + "\", pod=\"" + podName + "\", image!=\"\", container =~
\"^(?:\\\\d+-0-\\\\d+|faas-sidecar)$\"} / 1000)";
+ String gcMaxTimes =
"max(delta(jvm_gc_pause_seconds_count{serverIp=\"" + req.getIp() + "\",
application=\"" + req.getApplication() + "\",containerName=\"main\"}[1m]))";
+ String memoryUsedRate =
"avg(sum(jvm_memory_used_bytes{application=\"" + req.getApplication() +
"\",area=\"heap\",ip=\"" + req.getIp() + "\",containerName=\"main\"}) /
sum(jvm_memory_max_bytes{application=\"" + req.getApplication() +
"\",area=\"heap\",ip=\"" + req.getIp() + "\",containerName=\"main\"})) * 100";
+ String maxGCDuration =
"max(max_over_time(jvm_gc_pause_seconds_max{serverIp=~\"" + req.getIp() + "\",
application=\"" + req.getApplication() + "\",containerName=\"main\"}[1m]))";
+ String cpuCount = "system_cpu_count{serverIp=~\"" + req.getIp() +
"\", application=\"" + req.getApplication() + "\",containerName=~\".*\"}";
+ log.info("getPodNameByKubePodInfo.cpuPromQl:{}", cpuPromQl);
+ log.info("getPodNameByKubePodInfo.loadPromQl:{}", loadPromQl);
+ log.info("getPodNameByKubePodInfo.gcMaxTimes:{}", gcMaxTimes);
+ log.info("getPodNameByKubePodInfo.memoryUsedRate:{}",
memoryUsedRate);
+ log.info("getPodNameByKubePodInfo.maxGCDuration:{}",
maxGCDuration);
+ log.info("getPodNameByKubePodInfo.cpuCount:{}", cpuCount);
+ CompletableFuture<MetricRangeResponseVector> cpuFuture =
CompletableFuture.supplyAsync(() -> requestPrometheusRangeV2(cpuPromQl,
+ req.getStartTime(), req.getEndTime(), req.getEnv()),
HERA_SOLUTION_METRICS_POOL);
+ CompletableFuture<MetricRangeResponseVector> loadFuture =
CompletableFuture.supplyAsync(() -> requestPrometheusRangeV2(loadPromQl,
+ req.getStartTime(), req.getEndTime(), req.getEnv()),
HERA_SOLUTION_METRICS_POOL);
+ CompletableFuture<MetricRangeResponseVector> gcMaxTimesFuture =
CompletableFuture.supplyAsync(() -> requestPrometheusRangeV2(gcMaxTimes,
+ req.getStartTime(), req.getEndTime(), req.getEnv()),
HERA_SOLUTION_METRICS_POOL);
+ CompletableFuture<MetricRangeResponseVector> memoryFuture =
CompletableFuture.supplyAsync(() -> requestPrometheusRangeV2(memoryUsedRate,
+ req.getStartTime(), req.getEndTime(), req.getEnv()),
HERA_SOLUTION_METRICS_POOL);
+ CompletableFuture<MetricRangeResponseVector> maxGCFuture =
CompletableFuture.supplyAsync(() -> requestPrometheusRangeV2(maxGCDuration,
+ req.getStartTime(), req.getEndTime(), req.getEnv()),
HERA_SOLUTION_METRICS_POOL);
+ CompletableFuture<MetricRangeResponseVector> cpuCountFuture =
CompletableFuture.supplyAsync(() -> requestPrometheusRangeV2(cpuCount,
+ req.getStartTime(), req.getEndTime(), req.getEnv()),
HERA_SOLUTION_METRICS_POOL);
+ CompletableFuture<Void> allComplete =
CompletableFuture.allOf(cpuFuture, loadFuture, gcMaxTimesFuture, memoryFuture,
maxGCFuture);
+ allComplete.get(8000, TimeUnit.MILLISECONDS);
+ MetricRangeResponseVector cpuMetrics = cpuFuture.get();
+ if (cpuMetrics != null) {
+ log.info("getPodNameByKubePodInfo cpuMetrics : " + cpuMetrics);
+ List<MetricDataRangeSetVector> cpuResult =
cpuMetrics.getData().getResult();
+ if (cpuResult != null && cpuResult.size() > 0) {
+ List<List<String>> values = cpuResult.get(0).getValues();
+ res.setMaxCpuUsage(getMaxValue(values));
+ }
+ }
+ MetricRangeResponseVector loadMetrics = loadFuture.get();
+ if (loadMetrics != null) {
+ log.info("getPodNameByKubePodInfo loadMetrics : " +
loadMetrics);
+ List<MetricDataRangeSetVector> loadResult =
loadMetrics.getData().getResult();
+ if (loadResult != null && loadResult.size() > 0) {
+ List<List<String>> values = loadResult.get(0).getValues();
+ res.setMaxLoad(getMaxValue(values));
+ }
+ }
+ MetricRangeResponseVector gcMaxTimesMetrics =
gcMaxTimesFuture.get();
+ if (gcMaxTimesMetrics != null) {
+ log.info("getPodNameByKubePodInfo gcMaxTimesMetrics : " +
gcMaxTimesMetrics);
+ List<MetricDataRangeSetVector> gcMaxTimesResult =
gcMaxTimesMetrics.getData().getResult();
+ if (gcMaxTimesResult != null && gcMaxTimesResult.size() > 0) {
+ List<List<String>> values =
gcMaxTimesResult.get(0).getValues();
+ res.setMaxSTWCost(getMaxValue(values));
+ }
+ }
+ MetricRangeResponseVector memoryMetrics = memoryFuture.get();
+ if (memoryMetrics != null) {
+ log.info("getPodNameByKubePodInfo memoryMetrics : " +
memoryMetrics);
+ List<MetricDataRangeSetVector> memoryResult =
memoryMetrics.getData().getResult();
+ if (memoryResult != null && memoryResult.size() > 0) {
+ List<List<String>> values =
memoryResult.get(0).getValues();
+ res.setMaxJvmHeapUsage(getMaxValue(values));
+ }
+ }
+ MetricRangeResponseVector maxGCMetrics = maxGCFuture.get();
+ if (maxGCMetrics != null) {
+ log.info("getPodNameByKubePodInfo maxGCMetrics : " +
maxGCMetrics);
+ List<MetricDataRangeSetVector> maxGCResult =
maxGCMetrics.getData().getResult();
+ if (maxGCResult != null && maxGCResult.size() > 0) {
+ List<List<String>> values = maxGCResult.get(0).getValues();
+ res.setSTWCountOf1m(getMaxValue(values));
+ }
+ }
+ MetricRangeResponseVector cpuCountMetrics = cpuCountFuture.get();
+ if (cpuCountMetrics != null) {
+ log.info("getPodNameByKubePodInfo maxGCMetrics : " +
cpuCountMetrics);
+ List<MetricDataRangeSetVector> cpuCountResult =
cpuCountMetrics.getData().getResult();
+ if (cpuCountResult != null && cpuCountResult.size() > 0) {
+ List<List<String>> values =
cpuCountResult.get(0).getValues();
+ res.setCpuCount(getMaxValue(values));
+ }
+ }
+ } catch (Exception e) {
+ log.error("get root cause analysis error , ", e);
+ }
+ return res;
+ }
+
+ private void updateParam(MetricsQueryParam req) {
+ Long startTime = Long.parseLong(req.getStartTime());
+ Long duration = Long.parseLong(req.getDuration());
+ Long endTime = startTime + duration;
+ Long gap = Long.parseLong(req.getGap());
+ // startTime is in microseconds, convert to milliseconds
+ Long startTimeMs = startTime / 1000;
+ Long endTimeMs = endTime / 1000;
+ req.setStartTime(addGap(startTimeMs, gap * -1));
+ req.setEndTime(addGap(endTimeMs, gap));
+ req.setApplication(convertApp(req.getApplication()));
+ }
+
+ private String getKubePodInfoPromQl(String hostIp) {
+ return "count(kube_pod_info{system=\"mione\",pod_ip=~\"" + hostIp +
"\"}) by (pod_ip,pod)";
+ }
+
+ private MetricRangeResponseVector requestPrometheusRangeV2(String promQl,
String startTime, String endTime, String env) {
+ try {
+ Map<String, String> map = new HashMap<>();
+ map.put(P_QUERY, promQl); // Metric parameter
+ // step: 1h = 15, 2h = 2 * 15
+ Long multi = (Long.parseLong(endTime) - Long.parseLong(startTime))
/ 3600;
+ if (multi < 1) {
+ multi = 1L;
+
+ }
+ map.put(P_STEP, String.valueOf(multi * 15));
+ map.put(P_START, startTime);
+ map.put(P_END, endTime);
+ String url = completeQueryUrl(prometheusUrl, URI_QUERY_RANGE,
promQl, map);
+ System.out.println(url);
+ Map<String, String> headers = new HashMap<>();
+ headers.put("Accept", "*/*");
+ log.info("queryPrometheusRangeResponse : {}", url.toString());
+ String data = HttpClient.get(url.toString(), headers);
+ MetricRangeResponseVector metricResult = new Gson().fromJson(data,
MetricRangeResponseVector.class);
+ if (metricResult == null ||
!"success".equals(metricResult.getStatus())) {
+ return null;
+ } else {
+ return metricResult;
+ }
+ } catch (Exception e) {
+ log.error("requestPrometheusRange err", e);
+ return null;
+ }
+ }
+
+ private String completeQueryUrl(String domain, String path, String query,
Map<String, String> map) {
+ URIBuilder builder = new URIBuilder();
+ builder.setScheme("http");
+ builder.setHost(domain);
+ builder.setPath(path);
+ map.forEach(builder::addParameter);
+ URL url = null;
+ try {
+ url = builder.build().toURL();
+ } catch (MalformedURLException e) {
+ throw new RuntimeException(e);
+ } catch (URISyntaxException e) {
+ throw new RuntimeException(e);
+ }
+ return url.toString();
+ }
+
+ private double getMaxValue(List<List<String>> values) {
+ List<Double> temValues = new ArrayList<>();
+ for (List<String> value : values) {
+ temValues.add(Double.valueOf(value.get(1)));
+ }
+ Collections.sort(temValues);
+ return temValues.get(temValues.size() - 1);
+ }
+
+ private String addGap(long time, long gap) {
+ // After calculating the time interval, convert ms to s
+ return String.valueOf((time + gap) / 1000);
+ }
+
+ private String convertApp(String application) {
+ return application.replaceAll("-", "_");
}
-}
+}
\ No newline at end of file
diff --git
a/ozhera-intelligence/ozhera-intelligence-service/src/main/java/org/apache/ozhera/intelligence/service/TraceService.java
b/ozhera-intelligence/ozhera-intelligence-service/src/main/java/org/apache/ozhera/intelligence/service/TraceService.java
index 0705d049..b2ec745e 100644
---
a/ozhera-intelligence/ozhera-intelligence-service/src/main/java/org/apache/ozhera/intelligence/service/TraceService.java
+++
b/ozhera-intelligence/ozhera-intelligence-service/src/main/java/org/apache/ozhera/intelligence/service/TraceService.java
@@ -18,18 +18,298 @@
*/
package org.apache.ozhera.intelligence.service;
+import org.apache.dubbo.config.annotation.DubboReference;
+import org.apache.ozhera.intelligence.domain.rootanalysis.TraceTreeNode;
+import org.apache.ozhera.trace.etl.api.service.TraceQueryService;
+import org.apache.ozhera.trace.etl.domain.jaegeres.JaegerAttribute;
+import org.apache.ozhera.trace.etl.domain.tracequery.Span;
+import org.apache.ozhera.trace.etl.domain.tracequery.Trace;
+import org.apache.ozhera.trace.etl.domain.tracequery.TraceIdQueryVo;
import org.springframework.stereotype.Service;
import org.apache.ozhera.intelligence.domain.rootanalysis.TraceQueryParam;
+import org.apache.ozhera.trace.etl.domain.jaegeres.JaegerProcess;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Comparator;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * @author dingtao
+ * @date 2025/1/20 11:26
+ */
@Service
public class TraceService {
+ /**
+ * call trace-etl-manager TraceQueryService, The group and version in
Dubbo should be consistent with the group and version in TraceQueryServiceImpl
in trace-etl-manager.
+ */
+ @DubboReference(interfaceClass = TraceQueryService.class, group =
"${trace.query.group}", version = "${trace.query.version}")
+ private TraceQueryService traceQueryService;
+
+ /**
+ * The time range threshold for querying before and after the given
timestamp.
+ * The actual query range is calculated by subtracting and adding
QUERY_TIME_RANGE to the given timestamp.
+ */
+ private static final long QUERY_TIME_RANGE = 30 * 60 * 1000;
+
+ /**
+ * The maximum depth of the analyzed trace to be retrieved.
+ */
+ private static final int TRACE_DEEP = 5;
+
+
+ private static final String SERVICE_ENV_ID_KEY = "service.env.id";
+ private static final List<String> NOT_RETAIN_SPAN_NAMES = List.of("UDS");
+ private static final List<String> RETAIN_TAGS =
Arrays.asList("net.sock.peer.addr", "span.kind", "net.sock.peer.port",
"http.target", "net.host.name", "net.peer.name", "net.peer.port",
"rpc.service", "rpc.method", "rpc.system", "db.statement", "error", "http.url");
+ private static final List<String> RETAIN_PROCESS_TAGS =
Arrays.asList(SERVICE_ENV_ID_KEY, "ip", "service.env", "service.env.id",
"service.container.name", "host.name");
+
/**
* Query trace based on the specified trace query conditions.
+ *
* @param param
* @return
*/
- public String queryTraceRootAnalysis(TraceQueryParam param){
- return null;
+ public List<Span> queryTraceRootAnalysis(TraceQueryParam param) {
+ Trace traceResult =
traceQueryService.getByTraceId(buildTraceIdQueryVo(param));
+ List<Span> result = new ArrayList<>();
+ if (traceResult != null && traceResult.getSpans() != null &&
!traceResult.getSpans().isEmpty()) {
+ // analyze and cut span
+ List<Span> analyze = analyzeTrace(traceResult.getSpans(),
TRACE_DEEP);
+ result = getSpansFilter(analyze);
+ }
+ return result;
+ }
+
+ /**
+ * Analyze trace information and return a list of key Spans
+ * <p>
+ * This method first builds a TraceTreeNode tree, then analyzes the trace
information based on whether errors exist.
+ * If there are errors, it will find and return the most recent error node
and its child nodes.
+ * If there are no errors, it will search for time-consuming nodes.
+ *
+ * @param spans The list of Spans to be analyzed
+ * @param N The number of child nodes to return in case of errors
+ * @return A list containing key Spans, representing error nodes or
time-consuming nodes
+ */
+ public List<Span> analyzeTrace(List<Span> spans, int N) {
+ // Build TraceTreeNode tree
+
+ // Build TraceTreeNode tree
+ Map<String, TraceTreeNode> nodeMap = new HashMap<>();
+ boolean hasError = false;
+ for (Span span : spans) {
+ if (hasException(span)) {
+ hasError = true;
+ }
+ TraceTreeNode node = new TraceTreeNode(span);
+
+ nodeMap.put(span.getSpanID(), node);
+ }
+ List<TraceTreeNode> roots = new ArrayList<>();
+ for (TraceTreeNode node : nodeMap.values()) {
+ if (node.getSpan().getReferences().isEmpty() ||
+
!nodeMap.containsKey(node.getSpan().getReferences().get(0).getSpanID())) {
+ roots.add(node);
+ } else {
+ TraceTreeNode parentNode =
nodeMap.get(node.getSpan().getReferences().get(0).getSpanID());
+ parentNode.addChild(node);
+ }
+ }
+ // Sort sibling nodes by startTime
+ for (TraceTreeNode root : roots) {
+ sortChildren(root);
+ }
+ List<Span> result = new ArrayList<>();
+ if (hasError) {
+ // Find error nodes
+ List<TraceTreeNode> errorNodes = new ArrayList<>();
+ for (TraceTreeNode root : roots) {
+ findErrorTargetNode(root, errorNodes);
+ if (errorNodes != null && errorNodes.size() > 0) {
+ int currentChildCount = 0;
+ // Sort by Span.startTime, analyze the Span with the
latest start time, which is likely the most relevant
+ errorNodes.sort(Comparator.comparing(s ->
s.getSpan().getStartTime()));
+ TraceTreeNode lastErrorNode =
errorNodes.get(errorNodes.size() - 1);
+ result.add(lastErrorNode.getSpan());
+ addNChild(result, lastErrorNode, N, currentChildCount);
+ }
+ }
+ } else {
+ // Finding time-consuming nodes is more complex. We start with the
root node's duration as a baseline,
+ // and search level by level until there are no more child nodes
or no child nodes with significantly high duration.
+ List<TraceTreeNode> slowNodes = new ArrayList<>();
+ for (TraceTreeNode root : roots) {
+ long rootDuration = root.getSpan().getDuration();
+ slowNodes.add(root);
+ findSlowNode(root, slowNodes, rootDuration);
+ for (TraceTreeNode node : slowNodes) {
+ result.add(node.getSpan());
+
+ }
+ }
+ }
+
+ return result;
+ }
+
+ /**
+ * Filter and process the given list of Spans
+ *
+ * @param spans The list of Spans to be processed
+ * @return The filtered and processed list of Spans
+ * <p>
+ * This method mainly performs the following operations:
+ * 1. Filters out Spans that don't need to be retained based on
NOT_RETAIN_SPAN_NAMES
+ * 2. For retained Spans, only keeps tags specified in RETAIN_TAGS
+ * 3. For each Span's Process, only keeps tags specified in
RETAIN_PROCESS_TAGS
+ * If the input spans is null or empty, it returns the original spans
directly
+ */
+ private List<Span> getSpansFilter(List<Span> spans) {
+ if (spans != null && spans.size() > 0) {
+ List<Span> newSpans = new ArrayList<>();
+ for (Span span : spans) {
+ String operationName = span.getOperationName();
+
+ boolean isRetain = true;
+ for (String filter : NOT_RETAIN_SPAN_NAMES) {
+ if (operationName.contains(filter)) {
+ isRetain = false;
+ }
+ }
+ if (isRetain) {
+ newSpans.add(span);
+ }
+ }
+ for (Span span : newSpans) {
+ List<JaegerAttribute> newTags = new ArrayList<>();
+ for (JaegerAttribute attribute : span.getTags()) {
+ if (RETAIN_TAGS.contains(attribute.getKey())) {
+ newTags.add(attribute);
+ }
+ }
+ span.setTags(newTags);
+ List<JaegerAttribute> newProcessTags = new ArrayList<>();
+ JaegerProcess process = span.getProcess();
+ List<JaegerAttribute> processTags = process.getTags();
+ for (JaegerAttribute processTag : processTags) {
+ if (RETAIN_PROCESS_TAGS.contains(processTag.getKey())) {
+ newProcessTags.add(processTag);
+ }
+ }
+ process.setTags(newProcessTags);
+ }
+ return newSpans;
+ }
+ return spans;
+ }
+
+ private boolean hasException(Span span) {
+ // Determine if the span contains any errors based on the actual
situation
+ for (JaegerAttribute tag : span.getTags()) {
+ if ("error".equals(tag.getKey())) {
+ return true;
+
+
+ }
+ }
+ return false;
+ }
+
+ private void sortChildren(TraceTreeNode node) {
+ if (node.getChildren() != null) {
+ node.getChildren().sort(Comparator.comparingLong(n ->
n.getSpan().getStartTime()));
+ for (TraceTreeNode child : node.getChildren()) {
+ sortChildren(child);
+ }
+ }
+ }
+
+ private void findSlowNode(TraceTreeNode root, List<TraceTreeNode>
slowNodes, long rootDuration) {
+ // Find nodes with duration greater than 80% of the parent node's
duration.
+ // If none found, look for 50%, then 30%, 20%, and finally 10%.
+ if (!root.getChildren().isEmpty()) {
+ for (TraceTreeNode childNode : root.getChildren()) {
+ if (findByPercent(childNode, slowNodes, rootDuration, 0.8)) {
+
+ findSlowNode(childNode, slowNodes,
childNode.getSpan().getDuration());
+ } else if (findByPercent(childNode, slowNodes, rootDuration,
0.5)) {
+ findSlowNode(childNode, slowNodes,
childNode.getSpan().getDuration());
+ } else if (findByPercent(childNode, slowNodes, rootDuration,
0.3)) {
+ findSlowNode(childNode, slowNodes,
childNode.getSpan().getDuration());
+ } else if (findByPercent(childNode, slowNodes, rootDuration,
0.2)) {
+ findSlowNode(childNode, slowNodes,
childNode.getSpan().getDuration());
+ } else if (findByPercent(childNode, slowNodes, rootDuration,
0.1)) {
+ findSlowNode(childNode, slowNodes,
childNode.getSpan().getDuration());
+ }
+ }
+ }
+ }
+
+ private boolean findByPercent(TraceTreeNode parent, List<TraceTreeNode>
slowNodes, long rootDuration, double percent) {
+ boolean result = false;
+ for (TraceTreeNode childNode : parent.getChildren()) {
+ if (childNode.getSpan().getDuration() > rootDuration * percent) {
+ result = true;
+ slowNodes.add(childNode);
+ }
+ }
+ return result;
+ }
+
+ private void findErrorTargetNode(TraceTreeNode node, List<TraceTreeNode>
errorNodes) {
+ if (hasException(node.getSpan())) {
+ errorNodes.add(node);
+ }
+
+ if (node.getChildren() != null) {
+ for (TraceTreeNode child : node.getChildren()) {
+ findErrorTargetNode(child, errorNodes);
+ }
+ }
+ }
+
+ /**
+ * Add the specified number of child nodes of the targetNode to the result.
+ * First, add the first-level child nodes; if the quantity is not
sufficient,
+ * then add the second-level child nodes. If the number of child nodes
exceeds afterNumber,
+ * or if there are no more child nodes, the method returns.
+ *
+ * @param result List to store the resulting Span objects
+ * @param targetNode
+ * @param afterNumber
+ */
+ private void addNChild(List<Span> result, TraceTreeNode targetNode, int
afterNumber, int currentChildCount) {
+ List<TraceTreeNode> children = targetNode.getChildren();
+ if (!children.isEmpty()) {
+ List<TraceTreeNode> childs = new ArrayList<>();
+ for (TraceTreeNode treeNode : children) {
+ result.add(treeNode.getSpan());
+ currentChildCount++;
+ if (currentChildCount >= afterNumber) {
+ return;
+ }
+ if (!treeNode.getChildren().isEmpty()) {
+ childs.add(treeNode);
+ }
+ }
+ // If the number of first-level child nodes is less than
afterNumber, continue adding second-level child nodes
+ for (TraceTreeNode secondChild : childs) {
+ addNChild(result, secondChild, afterNumber, currentChildCount);
+ }
+ }
+ }
+
+ private TraceIdQueryVo buildTraceIdQueryVo(TraceQueryParam param) {
+
+ TraceIdQueryVo vo = new TraceIdQueryVo();
+ vo.setTraceId(param.getTraceId());
+ long startTime = param.getTimeStamp() - QUERY_TIME_RANGE;
+ long endTime = param.getTimeStamp() + QUERY_TIME_RANGE;
+ vo.setStartTime(startTime);
+ vo.setEndTime(endTime);
+ return vo;
}
-}
+}
\ No newline at end of file
diff --git
a/ozhera-intelligence/ozhera-intelligence-service/src/main/java/org/apache/ozhera/intelligence/util/CommitPoolUtil.java
b/ozhera-intelligence/ozhera-intelligence-service/src/main/java/org/apache/ozhera/intelligence/util/CommitPoolUtil.java
new file mode 100644
index 00000000..ce873e96
--- /dev/null
+++
b/ozhera-intelligence/ozhera-intelligence-service/src/main/java/org/apache/ozhera/intelligence/util/CommitPoolUtil.java
@@ -0,0 +1,48 @@
+/*
+ * 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.ozhera.intelligence.util;
+
+import java.util.concurrent.ArrayBlockingQueue;
+import java.util.concurrent.BlockingQueue;
+import java.util.concurrent.ThreadFactory;
+import java.util.concurrent.ThreadPoolExecutor;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicInteger;
+
+public class CommitPoolUtil {
+
+ public static final ThreadPoolExecutor HERA_SOLUTION_METRICS_POOL;
+ private static final BlockingQueue<Runnable> heraSolutionMetricsQueue =
new ArrayBlockingQueue<>(30);
+ private static final AtomicInteger heraSolutionThreadNumber = new
AtomicInteger(1);
+
+ static {
+ HERA_SOLUTION_METRICS_POOL = new ThreadPoolExecutor(15, 20,
+ 0L, TimeUnit.MILLISECONDS,
+ heraSolutionMetricsQueue, new ThreadFactory() {
+ @Override
+ public Thread newThread(Runnable r) {
+ Thread thread = new Thread(r);
+ thread.setDaemon(false);
+ thread.setName("hera-solution-metrics" +
heraSolutionThreadNumber.getAndIncrement());
+ return thread;
+ }
+ });
+ }
+
+}
diff --git
a/ozhera-intelligence/ozhera-intelligence-service/src/main/java/org/apache/ozhera/intelligence/util/HttpClient.java
b/ozhera-intelligence/ozhera-intelligence-service/src/main/java/org/apache/ozhera/intelligence/util/HttpClient.java
new file mode 100644
index 00000000..f250ff1f
--- /dev/null
+++
b/ozhera-intelligence/ozhera-intelligence-service/src/main/java/org/apache/ozhera/intelligence/util/HttpClient.java
@@ -0,0 +1,92 @@
+/*
+ * 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.ozhera.intelligence.util;
+
+import com.google.gson.JsonObject;
+import com.google.gson.JsonParser;
+import lombok.extern.slf4j.Slf4j;
+import okhttp3.MediaType;
+import okhttp3.OkHttpClient;
+import okhttp3.Request;
+import okhttp3.RequestBody;
+import okhttp3.Response;
+
+import java.io.IOException;
+import java.util.Map;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * @author dingtao
+ * @date 2025/1/20 11:26
+ */
+@Slf4j
+public class HttpClient {
+
+ private static final OkHttpClient client;
+
+ static {
+ client = new OkHttpClient.Builder()
+ .connectTimeout(10, TimeUnit.SECONDS)
+ .writeTimeout(10, TimeUnit.SECONDS)
+ .readTimeout(60, TimeUnit.SECONDS)
+ .build();
+ }
+
+ public static JsonObject postRequest(String url, JsonObject jsonObject) {
+ MediaType JSON = MediaType.parse("application/json; charset=utf-8");
+ RequestBody body = RequestBody.create(JSON, jsonObject.toString());
+ Request request = new Request.Builder()
+ .url(url)
+ .post(body)
+ .build();
+ try (Response response = client.newCall(request).execute()) {
+ if (!response.isSuccessful()) {
+ throw new IOException("Unexpected code " + response);
+ }
+ return new
JsonParser().parse(response.body().string()).getAsJsonObject();
+ } catch (Exception e) {
+ log.error("HttpClient post error, ", e);
+ return null;
+ }
+ }
+
+
+ public static String get(String url, Map<String, String> headers) {
+ Request.Builder requestBuilder = new Request.Builder().url(url);
+
+ if (headers != null) {
+ for (Map.Entry<String, String> entry : headers.entrySet()) {
+ requestBuilder.addHeader(entry.getKey(), entry.getValue());
+ }
+ }
+
+ Request request = requestBuilder.build();
+
+ try (Response response = client.newCall(request).execute()) {
+ if (!response.isSuccessful()) {
+ throw new IOException("Unexpected code " + response);
+ }
+ return response.body().string();
+ } catch (Exception e) {
+ log.error("HttpClient get error, ", e);
+ return null;
+ }
+
+ }
+}
diff --git a/ozhera-intelligence/pom.xml b/ozhera-intelligence/pom.xml
index 3f3c5acd..1a6d9b66 100644
--- a/ozhera-intelligence/pom.xml
+++ b/ozhera-intelligence/pom.xml
@@ -68,6 +68,21 @@
<artifactId>trace-etl-domain</artifactId>
<version>2.2.5-incubating</version>
</dependency>
+ <dependency>
+ <groupId>org.apache.ozhera</groupId>
+ <artifactId>trace-etl-api</artifactId>
+ <version>2.2.5-incubating</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.ozhera</groupId>
+ <artifactId>log-api</artifactId>
+ <version>2.2.5-incubating</version>
+ </dependency>
+ <dependency>
+ <groupId>com.squareup.okhttp3</groupId>
+ <artifactId>okhttp</artifactId>
+ <version>4.12.0</version>
+ </dependency>
</dependencies>
</dependencyManagement>
diff --git
a/ozhera-intelligence/ozhera-intelligence-server/src/main/resources/application.properties
b/ozhera-operator/ozhera-operator-server/src/main/resources/ozhera_init/intelligence/ozhera_intelligence.yml
similarity index 55%
copy from
ozhera-intelligence/ozhera-intelligence-server/src/main/resources/application.properties
copy to
ozhera-operator/ozhera-operator-server/src/main/resources/ozhera_init/intelligence/ozhera_intelligence.yml
index a38e97e5..90cb38a6 100644
---
a/ozhera-intelligence/ozhera-intelligence-server/src/main/resources/application.properties
+++
b/ozhera-operator/ozhera-operator-server/src/main/resources/ozhera_init/intelligence/ozhera_intelligence.yml
@@ -12,10 +12,30 @@
# 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.
-
-#server
-app.name=${app.name}
-server.type=${server.type}
-server.port=${server.port}
-
-log.path=${log.path}
\ No newline at end of file
+apiVersion: apps/v1
+kind: Deployment
+metadata:
+ name: ozhera-intelligence
+ namespace: ozhera-namespace
+ labels:
+ app: ozhera-intelligence
+spec:
+ replicas: 1
+ selector:
+ matchLabels:
+ app: ozhera-intelligence
+ template:
+ metadata:
+ labels:
+ app: ozhera-intelligence
+ spec:
+ containers:
+ - name: ozhera-intelligence-container
+ image:
herahub/opensource-pub:ozhera-intelligence-2.2.5-incubating-beta-v1
+ imagePullPolicy: Always
+ ports:
+ - containerPort: 4446
+ resources:
+ limits:
+ cpu: '500m'
+ memory: 1Gi
diff --git
a/ozhera-intelligence/ozhera-intelligence-server/src/main/resources/application.properties
b/ozhera-operator/ozhera-operator-server/src/main/resources/ozhera_init/nacos/config/hera_intelligence_config_#_DEFAULT_GROUP.properties
similarity index 87%
copy from
ozhera-intelligence/ozhera-intelligence-server/src/main/resources/application.properties
copy to
ozhera-operator/ozhera-operator-server/src/main/resources/ozhera_init/nacos/config/hera_intelligence_config_#_DEFAULT_GROUP.properties
index a38e97e5..5bf79dad 100644
---
a/ozhera-intelligence/ozhera-intelligence-server/src/main/resources/application.properties
+++
b/ozhera-operator/ozhera-operator-server/src/main/resources/ozhera_init/nacos/config/hera_intelligence_config_#_DEFAULT_GROUP.properties
@@ -12,10 +12,6 @@
# 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.
-
-#server
-app.name=${app.name}
-server.type=${server.type}
-server.port=${server.port}
-
-log.path=${log.path}
\ No newline at end of file
+analyze.token=
+dubbo.registry.address=nacos://${hera.nacos.address}
+prometheus.api.url=${hera.prometheus.url}
diff --git a/readme/images/ozhera-intelligence.png
b/readme/images/ozhera-intelligence.png
new file mode 100644
index 00000000..79d9020c
Binary files /dev/null and b/readme/images/ozhera-intelligence.png differ
diff --git
a/ozhera-intelligence/ozhera-intelligence-domain/src/main/java/org/apache/ozhera/intelligence/domain/rootanalysis/TraceQueryParam.java
b/trace-etl/trace-etl-api/src/main/java/org/apache/ozhera/trace/etl/api/service/TraceQueryService.java
similarity index 66%
copy from
ozhera-intelligence/ozhera-intelligence-domain/src/main/java/org/apache/ozhera/intelligence/domain/rootanalysis/TraceQueryParam.java
copy to
trace-etl/trace-etl-api/src/main/java/org/apache/ozhera/trace/etl/api/service/TraceQueryService.java
index 18fdcdf1..d657d5d7 100644
---
a/ozhera-intelligence/ozhera-intelligence-domain/src/main/java/org/apache/ozhera/intelligence/domain/rootanalysis/TraceQueryParam.java
+++
b/trace-etl/trace-etl-api/src/main/java/org/apache/ozhera/trace/etl/api/service/TraceQueryService.java
@@ -16,17 +16,21 @@
* specific language governing permissions and limitations
* under the License.
*/
-package org.apache.ozhera.intelligence.domain.rootanalysis;
+package org.apache.ozhera.trace.etl.api.service;
-import lombok.Builder;
-import lombok.Data;
+import org.apache.ozhera.trace.etl.domain.tracequery.Trace;
+import org.apache.ozhera.trace.etl.domain.tracequery.TraceIdQueryVo;
+import org.apache.ozhera.trace.etl.domain.tracequery.TraceListQueryVo;
import java.util.List;
-@Data
-@Builder
-public class TraceQueryParam {
- private String traceId;
- private String env;
- private List<String> timeStamp;
+/**
+ * @author dingtao
+ * @date 2025/1/20 11:26
+ */
+public interface TraceQueryService {
+
+ List<Trace> getList(TraceListQueryVo vo);
+
+ Trace getByTraceId(TraceIdQueryVo vo);
}
diff --git
a/trace-etl/trace-etl-manager/src/main/java/org/apache/ozhera/trace/etl/manager/dubbo/TraceQueryServiceImpl.java
b/trace-etl/trace-etl-manager/src/main/java/org/apache/ozhera/trace/etl/manager/dubbo/TraceQueryServiceImpl.java
new file mode 100644
index 00000000..bc8bc30c
--- /dev/null
+++
b/trace-etl/trace-etl-manager/src/main/java/org/apache/ozhera/trace/etl/manager/dubbo/TraceQueryServiceImpl.java
@@ -0,0 +1,61 @@
+/*
+ * 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.ozhera.trace.etl.manager.dubbo;
+
+import org.apache.dubbo.config.annotation.Service;
+import org.apache.ozhera.trace.etl.api.service.DataSourceService;
+import org.apache.ozhera.trace.etl.api.service.TraceQueryService;
+import org.apache.ozhera.trace.etl.domain.tracequery.Trace;
+import org.apache.ozhera.trace.etl.domain.tracequery.TraceIdQueryVo;
+import org.apache.ozhera.trace.etl.domain.tracequery.TraceListQueryVo;
+import org.apache.ozhera.trace.etl.domain.tracequery.TraceQueryResult;
+import org.springframework.beans.factory.annotation.Autowired;
+
+import java.util.List;
+
+/**
+ * @author dingtao
+ * @date 2025/1/20 11:26
+ */
+@Service(interfaceClass = TraceQueryService.class, group = "${dubbo.group}",
version = "1.0")
+public class TraceQueryServiceImpl implements TraceQueryService {
+
+ @Autowired
+ private DataSourceService dataSourceService;
+
+ @Override
+ public List<Trace> getList(TraceListQueryVo vo) {
+ TraceQueryResult<List<Trace>> result = dataSourceService.getList(vo);
+ if (result != null) {
+ return result.getData();
+ } else {
+ return null;
+ }
+ }
+
+ @Override
+ public Trace getByTraceId(TraceIdQueryVo vo) {
+ TraceQueryResult<List<Trace>> result =
dataSourceService.getByTraceId(vo);
+ if (result != null) {
+ return result.getData().getFirst();
+ } else {
+ return null;
+ }
+ }
+}
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]