datai/docs/archive/prompts/025-logging.md

20 KiB
Raw Blame History

Prompt - 详细日志记录和查询

输入引用

引用相关的 docs 文档链接:

Context Maps

强制列出本次 Prompt 依赖的 Canvas 文件:

目标

实现详细日志记录和查询功能,包括日志记录、日志查询、日志导出、日志分析。支持记录拉取和部署作业的详细执行日志,支持日志查询和导出,支持日志分析。

输出格式

代码示例语言Java

1. 日志级别枚举

package com.datai.salesforce.metadata.log.enums;

import lombok.Getter;

@Getter
public enum LogLevel {
    INFO("信息"),
    WARN("警告"),
    ERROR("错误");
    
    private final String description;
    
    LogLevel(String description) {
        this.description = description;
    }
}

2. 操作日志实体类

package com.datai.salesforce.metadata.log.entity;

import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.datai.salesforce.metadata.log.enums.LogLevel;
import lombok.Data;

import java.time.LocalDateTime;

@Data
@TableName("datai_operation_log")
public class OperationLog {
    
    @TableId(type = IdType.AUTO)
    private Long id;
    
    private Long jobExecutionId;
    
    private LogLevel logLevel;
    
    private String logContent;
    
    private String logModule;
    
    private String logOperation;
    
    private String logUser;
    
    private String logIp;
    
    private LocalDateTime logTime;
    
    private LocalDateTime createTime;
}

3. 操作日志服务接口

package com.datai.salesforce.metadata.log.service;

import com.datai.salesforce.metadata.log.entity.OperationLog;
import com.datai.salesforce.metadata.log.enums.LogLevel;

import java.util.List;

public interface IOperationLogService {
    
    Long saveLog(OperationLog operationLog);
    
    void saveLogAsync(OperationLog operationLog);
    
    OperationLog getLog(Long id);
    
    List<OperationLog> getLogsByJobExecutionId(Long jobExecutionId);
    
    List<OperationLog> getLogsByLogLevel(LogLevel logLevel);
    
    boolean deleteLog(Long id);
    
    boolean batchDeleteLogs(List<Long> ids);
}

4. 日志查询服务接口

package com.datai.salesforce.metadata.log.service;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.datai.salesforce.metadata.log.entity.OperationLog;
import com.datai.salesforce.metadata.log.enums.LogLevel;

import java.time.LocalDateTime;
import java.util.List;

public interface ILogQueryService {
    
    IPage<OperationLog> queryLogs(Page<OperationLog> page, 
                                 Long jobExecutionId, 
                                 LogLevel logLevel, 
                                 String keyword, 
                                 LocalDateTime startTime, 
                                 LocalDateTime endTime);
    
    List<OperationLog> queryLogsByCondition(Long jobExecutionId, 
                                           LogLevel logLevel, 
                                           String keyword, 
                                           LocalDateTime startTime, 
                                           LocalDateTime endTime);
    
    IPage<OperationLog> queryLogsByTimeRange(Page<OperationLog> page, 
                                             LocalDateTime startTime, 
                                             LocalDateTime endTime);
    
    IPage<OperationLog> queryLogsByJobExecutionId(Page<OperationLog> page, 
                                                  Long jobExecutionId);
}

5. 日志导出服务接口

package com.datai.salesforce.metadata.log.service;

import com.datai.salesforce.metadata.log.entity.OperationLog;
import org.springframework.http.ResponseEntity;

import java.time.LocalDateTime;
import java.util.List;

public interface ILogExportService {
    
    ResponseEntity<byte[]> exportToText(List<Long> logIds);
    
    ResponseEntity<byte[]> exportToExcel(List<Long> logIds);
    
    ResponseEntity<byte[]> exportToCsv(List<Long> logIds);
    
    ResponseEntity<byte[]> exportToTextByCondition(Long jobExecutionId, 
                                                  String logLevel, 
                                                  String keyword, 
                                                  LocalDateTime startTime, 
                                                  LocalDateTime endTime);
    
    ResponseEntity<byte[]> exportToExcelByCondition(Long jobExecutionId, 
                                                  String logLevel, 
                                                  String keyword, 
                                                  LocalDateTime startTime, 
                                                  LocalDateTime endTime);
    
    ResponseEntity<byte[]> exportToCsvByCondition(Long jobExecutionId, 
                                                 String logLevel, 
                                                 String keyword, 
                                                 LocalDateTime startTime, 
                                                 LocalDateTime endTime);
}

6. 日志分析服务接口

package com.datai.salesforce.metadata.log.service;

import java.time.LocalDateTime;
import java.util.Map;

public interface ILogAnalysisService {
    
    Map<String, Object> analyzeLogs(Long jobExecutionId);
    
    Map<String, Object> analyzeLogsByTimeRange(LocalDateTime startTime, 
                                                LocalDateTime endTime);
    
    Map<String, Object> analyzeLogsByLogLevel(String logLevel, 
                                             LocalDateTime startTime, 
                                             LocalDateTime endTime);
    
    Map<String, Object> analyzeLogTrend(LocalDateTime startTime, 
                                        LocalDateTime endTime);
    
    Map<String, Object> analyzeLogStatistics(LocalDateTime startTime, 
                                           LocalDateTime endTime);
}

7. 日志查询控制器

package com.datai.salesforce.metadata.log.controller;

import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.datai.common.core.domain.R;
import com.datai.salesforce.metadata.log.entity.OperationLog;
import com.datai.salesforce.metadata.log.enums.LogLevel;
import com.datai.salesforce.metadata.log.service.ILogQueryService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.RequiredArgsConstructor;
import org.springframework.format.annotation.DateTimeFormat;
import org.springframework.web.bind.annotation.*;

import java.time.LocalDateTime;
import java.util.List;

@Tag(name = "日志查询管理")
@RestController
@RequestMapping("/log/query")
@RequiredArgsConstructor
public class LogQueryController {
    
    private final ILogQueryService logQueryService;
    
    @Operation(summary = "查询日志列表")
    @GetMapping("/list")
    public R<Page<OperationLog>> queryLogs(
            @RequestParam(defaultValue = "1") int pageNum,
            @RequestParam(defaultValue = "10") int pageSize,
            @RequestParam(required = false) Long jobExecutionId,
            @RequestParam(required = false) LogLevel logLevel,
            @RequestParam(required = false) String keyword,
            @RequestParam(required = false) @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") LocalDateTime startTime,
            @RequestParam(required = false) @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") LocalDateTime endTime) {
        Page<OperationLog> page = new Page<>(pageNum, pageSize);
        Page<OperationLog> result = logQueryService.queryLogs(page, jobExecutionId, logLevel, keyword, startTime, endTime);
        return R.ok(result);
    }
    
    @Operation(summary = "查询日志列表(按条件)")
    @GetMapping("/condition")
    public R<List<OperationLog>> queryLogsByCondition(
            @RequestParam(required = false) Long jobExecutionId,
            @RequestParam(required = false) LogLevel logLevel,
            @RequestParam(required = false) String keyword,
            @RequestParam(required = false) @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") LocalDateTime startTime,
            @RequestParam(required = false) @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") LocalDateTime endTime) {
        List<OperationLog> logs = logQueryService.queryLogsByCondition(jobExecutionId, logLevel, keyword, startTime, endTime);
        return R.ok(logs);
    }
    
    @Operation(summary = "查询日志列表(按时间范围)")
    @GetMapping("/time-range")
    public R<Page<OperationLog>> queryLogsByTimeRange(
            @RequestParam(defaultValue = "1") int pageNum,
            @RequestParam(defaultValue = "10") int pageSize,
            @RequestParam @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") LocalDateTime startTime,
            @RequestParam @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") LocalDateTime endTime) {
        Page<OperationLog> page = new Page<>(pageNum, pageSize);
        Page<OperationLog> result = logQueryService.queryLogsByTimeRange(page, startTime, endTime);
        return R.ok(result);
    }
    
    @Operation(summary = "查询日志列表按作业ID")
    @GetMapping("/job-execution")
    public R<Page<OperationLog>> queryLogsByJobExecutionId(
            @RequestParam(defaultValue = "1") int pageNum,
            @RequestParam(defaultValue = "10") int pageSize,
            @RequestParam Long jobExecutionId) {
        Page<OperationLog> page = new Page<>(pageNum, pageSize);
        Page<OperationLog> result = logQueryService.queryLogsByJobExecutionId(page, jobExecutionId);
        return R.ok(result);
    }
}

8. 日志导出控制器

package com.datai.salesforce.metadata.log.controller;

import com.datai.common.core.domain.R;
import com.datai.salesforce.metadata.log.service.ILogExportService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.RequiredArgsConstructor;
import org.springframework.format.annotation.DateTimeFormat;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

import java.time.LocalDateTime;
import java.util.List;

@Tag(name = "日志导出管理")
@RestController
@RequestMapping("/log/export")
@RequiredArgsConstructor
public class LogExportController {
    
    private final ILogExportService logExportService;
    
    @Operation(summary = "导出为文本文件")
    @PostMapping("/text")
    public ResponseEntity<byte[]> exportToText(@RequestBody List<Long> logIds) {
        return logExportService.exportToText(logIds);
    }
    
    @Operation(summary = "导出为Excel文件")
    @PostMapping("/excel")
    public ResponseEntity<byte[]> exportToExcel(@RequestBody List<Long> logIds) {
        return logExportService.exportToExcel(logIds);
    }
    
    @Operation(summary = "导出为CSV文件")
    @PostMapping("/csv")
    public ResponseEntity<byte[]> exportToCsv(@RequestBody List<Long> logIds) {
        return logExportService.exportToCsv(logIds);
    }
    
    @Operation(summary = "按条件导出为文本文件")
    @GetMapping("/text/condition")
    public ResponseEntity<byte[]> exportToTextByCondition(
            @RequestParam(required = false) Long jobExecutionId,
            @RequestParam(required = false) String logLevel,
            @RequestParam(required = false) String keyword,
            @RequestParam(required = false) @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") LocalDateTime startTime,
            @RequestParam(required = false) @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") LocalDateTime endTime) {
        return logExportService.exportToTextByCondition(jobExecutionId, logLevel, keyword, startTime, endTime);
    }
    
    @Operation(summary = "按条件导出为Excel文件")
    @GetMapping("/excel/condition")
    public ResponseEntity<byte[]> exportToExcelByCondition(
            @RequestParam(required = false) Long jobExecutionId,
            @RequestParam(required = false) String logLevel,
            @RequestParam(required = false) String keyword,
            @RequestParam(required = false) @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") LocalDateTime startTime,
            @RequestParam(required = false) @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") LocalDateTime endTime) {
        return logExportService.exportToExcelByCondition(jobExecutionId, logLevel, keyword, startTime, endTime);
    }
    
    @Operation(summary = "按条件导出为CSV文件")
    @GetMapping("/csv/condition")
    public ResponseEntity<byte[]> exportToCsvByCondition(
            @RequestParam(required = false) Long jobExecutionId,
            @RequestParam(required = false) String logLevel,
            @RequestParam(required = false) String keyword,
            @RequestParam(required = false) @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") LocalDateTime startTime,
            @RequestParam(required = false) @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") LocalDateTime endTime) {
        return logExportService.exportToCsvByCondition(jobExecutionId, logLevel, keyword, startTime, endTime);
    }
}

9. 日志分析控制器

package com.datai.salesforce.metadata.log.controller;

import com.datai.common.core.domain.R;
import com.datai.salesforce.metadata.log.service.ILogAnalysisService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.RequiredArgsConstructor;
import org.springframework.format.annotation.DateTimeFormat;
import org.springframework.web.bind.annotation.*;

import java.time.LocalDateTime;
import java.util.Map;

@Tag(name = "日志分析管理")
@RestController
@RequestMapping("/log/analysis")
@RequiredArgsConstructor
public class LogAnalysisController {
    
    private final ILogAnalysisService logAnalysisService;
    
    @Operation(summary = "分析日志按作业ID")
    @GetMapping("/job-execution")
    public R<Map<String, Object>> analyzeLogs(@RequestParam Long jobExecutionId) {
        Map<String, Object> analysis = logAnalysisService.analyzeLogs(jobExecutionId);
        return R.ok(analysis);
    }
    
    @Operation(summary = "分析日志(按时间范围)")
    @GetMapping("/time-range")
    public R<Map<String, Object>> analyzeLogsByTimeRange(
            @RequestParam @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") LocalDateTime startTime,
            @RequestParam @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") LocalDateTime endTime) {
        Map<String, Object> analysis = logAnalysisService.analyzeLogsByTimeRange(startTime, endTime);
        return R.ok(analysis);
    }
    
    @Operation(summary = "分析日志(按日志级别)")
    @GetMapping("/log-level")
    public R<Map<String, Object>> analyzeLogsByLogLevel(
            @RequestParam String logLevel,
            @RequestParam(required = false) @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") LocalDateTime startTime,
            @RequestParam(required = false) @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") LocalDateTime endTime) {
        Map<String, Object> analysis = logAnalysisService.analyzeLogsByLogLevel(logLevel, startTime, endTime);
        return R.ok(analysis);
    }
    
    @Operation(summary = "分析日志趋势")
    @GetMapping("/trend")
    public R<Map<String, Object>> analyzeLogTrend(
            @RequestParam @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") LocalDateTime startTime,
            @RequestParam @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") LocalDateTime endTime) {
        Map<String, Object> analysis = logAnalysisService.analyzeLogTrend(startTime, endTime);
        return R.ok(analysis);
    }
    
    @Operation(summary = "分析日志统计")
    @GetMapping("/statistics")
    public R<Map<String, Object>> analyzeLogStatistics(
            @RequestParam @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") LocalDateTime startTime,
            @RequestParam @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") LocalDateTime endTime) {
        Map<String, Object> analysis = logAnalysisService.analyzeLogStatistics(startTime, endTime);
        return R.ok(analysis);
    }
}

约束

  • 技术栈限制: 必须基于现有的 Spring Boot 3 + Vue 3 技术栈
  • 架构约束: 必须遵循 Authentication.canvas 中定义的架构和调用关系
  • 模块约束: 必须在 datai-salesforce-metadata 模块下实现
  • 数据库约束: 必须使用 MyBatis Plus 作为持久层框架
  • 性能约束: 日志记录和查询性能必须满足要求,不能影响作业执行
  • 依赖约束: 必须依赖于 REQ-010-1, REQ-010-2, REQ-010-6, REQ-010-8, REQ-010-14

Rule Set

"请严格参考 @Authentication.canvas 中的状态机转移逻辑,不要自行发挥。"

具体规则

  • 必须使用 Canvas 中定义的类名和方法名
  • 必须遵循 Canvas 中定义的调用关系
  • 必须参考 Canvas 中的流程图逻辑

验收标准

定义验证输出质量的具体标准,例如:

  • 功能完整性: 所有日志记录和查询功能能够正常工作

    • 日志记录功能正常工作
    • 日志查询功能正常工作
    • 日志导出功能正常工作
    • 日志分析功能正常工作
  • 性能指标: 日志记录和查询性能满足要求,不影响作业执行

    • 日志记录响应时间 < 100ms
    • 日志查询响应时间 < 2s
    • 日志导出响应时间 < 10s1000条日志
    • 日志分析响应时间 < 5s
  • 完整性: 日志信息完整详细,能够追溯作业执行过程

    • 日志信息完整详细
    • 能够追溯作业执行过程
  • 代码规范性: 代码符合项目编码规范,有清晰的注释

    • 使用 Lombok 的 @Data、@RequiredArgsConstructor 注解
    • 使用 Swagger 的 @Tag、@Operation 注解
    • 使用 MyBatis Plus 的 @TableName、@TableId 注解
  • 可维护性: 代码结构清晰,易于扩展和维护

    • 服务接口和实现分离
    • 控制器、服务、实体、Mapper 分层清晰
    • 使用枚举管理日志级别
  • 可测试性: 代码易于单元测试和集成测试

    • 编写单元测试,测试覆盖率 > 80%
    • 编写集成测试,确保功能正常

风险

识别使用此提示词可能带来的风险,例如:

  • 输出质量风险: 代码质量可能不符合项目规范

    • 缓解措施: 使用代码审查,确保代码质量符合项目规范
  • 技术实现风险: 技术实现可能不符合架构决策

    • 缓解措施: 参考架构决策文档,确保技术实现符合架构决策
  • 时间成本风险: 开发周期可能较长

    • 缓解措施: 分阶段实施,优先实现核心功能,逐步完善
  • 性能风险: 日志记录和查询性能可能不佳

    • 缓解措施: 使用异步日志记录,使用索引优化查询,使用缓存提高查询性能

使用记录

日期 使用场景 输入参数 输出结果 反馈 改进措施
2026-01-19 详细日志记录和查询实现 REQ-010-15, 0024-logging 日志记录和查询代码 代码质量良好