|
@@ -2,12 +2,15 @@ package cn.reghao.devops.mgr.ops.srv.mon;
|
|
|
|
|
|
|
|
import com.fasterxml.jackson.databind.JsonNode;
|
|
import com.fasterxml.jackson.databind.JsonNode;
|
|
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
|
|
|
|
+import freemarker.template.Configuration;
|
|
|
import freemarker.template.Template;
|
|
import freemarker.template.Template;
|
|
|
|
|
+import freemarker.template.TemplateException;
|
|
|
import lombok.extern.slf4j.Slf4j;
|
|
import lombok.extern.slf4j.Slf4j;
|
|
|
import org.springframework.stereotype.Service;
|
|
import org.springframework.stereotype.Service;
|
|
|
import org.springframework.ui.freemarker.FreeMarkerTemplateUtils;
|
|
import org.springframework.ui.freemarker.FreeMarkerTemplateUtils;
|
|
|
import org.springframework.web.servlet.view.freemarker.FreeMarkerConfigurer;
|
|
import org.springframework.web.servlet.view.freemarker.FreeMarkerConfigurer;
|
|
|
|
|
|
|
|
|
|
+import java.io.IOException;
|
|
|
import java.net.URLEncoder;
|
|
import java.net.URLEncoder;
|
|
|
import java.nio.charset.StandardCharsets;
|
|
import java.nio.charset.StandardCharsets;
|
|
|
import java.nio.file.Files;
|
|
import java.nio.file.Files;
|
|
@@ -27,7 +30,7 @@ import java.util.*;
|
|
|
@Slf4j
|
|
@Slf4j
|
|
|
@Service
|
|
@Service
|
|
|
public class PrometheusService {
|
|
public class PrometheusService {
|
|
|
- private String baseUrl = "http://prometheus.reghao.cn";
|
|
|
|
|
|
|
+ private String baseUrl = "http://prometheus.iquizoo.cn";
|
|
|
private ObjectMapper objectMapper = new ObjectMapper();
|
|
private ObjectMapper objectMapper = new ObjectMapper();
|
|
|
private final PrometheusAsyncClient promClient = new PrometheusAsyncClient(baseUrl);
|
|
private final PrometheusAsyncClient promClient = new PrometheusAsyncClient(baseUrl);
|
|
|
|
|
|
|
@@ -190,15 +193,12 @@ public class PrometheusService {
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- public static FreeMarkerConfigurer createConfigurer() {
|
|
|
|
|
|
|
+ public static Configuration getTemplateConfiguration() throws TemplateException, IOException {
|
|
|
FreeMarkerConfigurer configurer = new FreeMarkerConfigurer();
|
|
FreeMarkerConfigurer configurer = new FreeMarkerConfigurer();
|
|
|
-
|
|
|
|
|
// 1. 设置模板存放路径 (通常在 resources/templates 下)
|
|
// 1. 设置模板存放路径 (通常在 resources/templates 下)
|
|
|
configurer.setTemplateLoaderPath("classpath:/templates/");
|
|
configurer.setTemplateLoaderPath("classpath:/templates/");
|
|
|
-
|
|
|
|
|
// 2. 设置默认编码
|
|
// 2. 设置默认编码
|
|
|
configurer.setDefaultEncoding("UTF-8");
|
|
configurer.setDefaultEncoding("UTF-8");
|
|
|
-
|
|
|
|
|
// 3. 配置 FreeMarker 的原生属性
|
|
// 3. 配置 FreeMarker 的原生属性
|
|
|
Properties settings = new Properties();
|
|
Properties settings = new Properties();
|
|
|
settings.setProperty("template_update_delay", "0"); // 检查模板更新延迟
|
|
settings.setProperty("template_update_delay", "0"); // 检查模板更新延迟
|
|
@@ -206,24 +206,27 @@ public class PrometheusService {
|
|
|
settings.setProperty("number_format", "0.##"); // 数字格式化,防止 1000 变 1,000
|
|
settings.setProperty("number_format", "0.##"); // 数字格式化,防止 1000 变 1,000
|
|
|
settings.setProperty("datetime_format", "yyyy-MM-dd HH:mm:ss");
|
|
settings.setProperty("datetime_format", "yyyy-MM-dd HH:mm:ss");
|
|
|
configurer.setFreemarkerSettings(settings);
|
|
configurer.setFreemarkerSettings(settings);
|
|
|
-
|
|
|
|
|
- try {
|
|
|
|
|
- // 重要:必须调用此方法来初始化内部的 Configuration 对象
|
|
|
|
|
- configurer.afterPropertiesSet();
|
|
|
|
|
- } catch (Exception e) {
|
|
|
|
|
- e.printStackTrace();
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- return configurer;
|
|
|
|
|
|
|
+ // 重要:必须调用此方法来初始化内部的 Configuration 对象
|
|
|
|
|
+ configurer.afterPropertiesSet();
|
|
|
|
|
+ return configurer.getConfiguration();
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
/**
|
|
|
- * 生成最终的 HTML 字符串
|
|
|
|
|
|
|
+ * @param templatePath 相对于 src/main/resources/templates/ 的路径
|
|
|
|
|
+ * @return
|
|
|
|
|
+ * @date 2026-03-29 00:03:145
|
|
|
*/
|
|
*/
|
|
|
|
|
+ public String renderHtml(String templatePath, Map<String, Object> root) throws Exception {
|
|
|
|
|
+ // 2. 加载模板文件
|
|
|
|
|
+ // 默认路径:src/main/resources/templates/pillar_report.ftl
|
|
|
|
|
+ Template template = getTemplateConfiguration().getTemplate(templatePath);
|
|
|
|
|
+ // 渲染并返回 HTML 字符串, FreeMarkerTemplateUtils 会自动处理异常并转换为 String
|
|
|
|
|
+ return FreeMarkerTemplateUtils.processTemplateIntoString(template, root);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
public String generateHtmlReport() throws Exception {
|
|
public String generateHtmlReport() throws Exception {
|
|
|
// 1. 获取聚合后的数据 DTO
|
|
// 1. 获取聚合后的数据 DTO
|
|
|
OperationReportDTO reportData = getAggregatedData();
|
|
OperationReportDTO reportData = getAggregatedData();
|
|
|
-
|
|
|
|
|
// 2. 准备 FreeMarker 数据模型 (Root Map)
|
|
// 2. 准备 FreeMarker 数据模型 (Root Map)
|
|
|
Map<String, Object> root = new HashMap<>();
|
|
Map<String, Object> root = new HashMap<>();
|
|
|
root.put("report", reportData);
|
|
root.put("report", reportData);
|
|
@@ -236,11 +239,10 @@ public class PrometheusService {
|
|
|
root.put("startTime", reportData.getStartTime());
|
|
root.put("startTime", reportData.getStartTime());
|
|
|
root.put("endTime", reportData.getEndTime());
|
|
root.put("endTime", reportData.getEndTime());
|
|
|
root.put("containerCount", reportData.getContainerCount());
|
|
root.put("containerCount", reportData.getContainerCount());
|
|
|
|
|
+ String templatePath = "daily_report.ftl";
|
|
|
|
|
|
|
|
- // 3. 加载模板 (确保文件位于 src/main/resources/templates/daily_report.ftl)
|
|
|
|
|
- Template template = createConfigurer().getConfiguration().getTemplate("daily_report.ftl");
|
|
|
|
|
- // 4. 合并数据与模板生成字符串
|
|
|
|
|
- return FreeMarkerTemplateUtils.processTemplateIntoString(template, root);
|
|
|
|
|
|
|
+ String htmlContent = renderHtml(templatePath, root);
|
|
|
|
|
+ return htmlContent;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
/**
|
|
@@ -249,9 +251,8 @@ public class PrometheusService {
|
|
|
public Map<String, String> fetchFromPrometheus() {
|
|
public Map<String, String> fetchFromPrometheus() {
|
|
|
// 1. 计算时间范围:昨天 00:00:00 到 23:59:59
|
|
// 1. 计算时间范围:昨天 00:00:00 到 23:59:59
|
|
|
// 也可以根据需求改为:当前时间向前推 24 小时
|
|
// 也可以根据需求改为:当前时间向前推 24 小时
|
|
|
- long now = Instant.now().getEpochSecond();
|
|
|
|
|
- long start = now - (24 * 3600);
|
|
|
|
|
- long end = now;
|
|
|
|
|
|
|
+ long end = Instant.now().getEpochSecond();
|
|
|
|
|
+ long start = end - (24 * 3600);
|
|
|
String step = "30m"; // 30分钟一个采样点,适合 24h 趋势图
|
|
String step = "30m"; // 30分钟一个采样点,适合 24h 趋势图
|
|
|
|
|
|
|
|
// 2. 定义 PromQL 查询语句
|
|
// 2. 定义 PromQL 查询语句
|
|
@@ -373,14 +374,10 @@ public class PrometheusService {
|
|
|
// 在模板中可以通过 ${report.reportDate} 或直接 ${reportDate} 访问
|
|
// 在模板中可以通过 ${report.reportDate} 或直接 ${reportDate} 访问
|
|
|
Map<String, Object> model = new HashMap<>();
|
|
Map<String, Object> model = new HashMap<>();
|
|
|
model.put("report", dto);
|
|
model.put("report", dto);
|
|
|
|
|
+ String templatePath = "pillar_report.ftl";
|
|
|
|
|
|
|
|
- // 2. 加载模板文件
|
|
|
|
|
- // 默认路径:src/main/resources/templates/pillar_report.ftl
|
|
|
|
|
- Template template = createConfigurer().getConfiguration().getTemplate("pillar_report.ftl");
|
|
|
|
|
-
|
|
|
|
|
- // 3. 执行渲染并返回 HTML 字符串
|
|
|
|
|
- // FreeMarkerTemplateUtils 会自动处理异常并转换为 String
|
|
|
|
|
- return FreeMarkerTemplateUtils.processTemplateIntoString(template, model);
|
|
|
|
|
|
|
+ String htmlContent = renderHtml(templatePath, model);
|
|
|
|
|
+ return htmlContent;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
public static void main(String[] args) throws Exception {
|
|
public static void main(String[] args) throws Exception {
|