Explorar el Código

add-D4Metric-6.1

Qyanger hace 4 meses
padre
commit
c3fdfa61f9

+ 3 - 3
src/main/java/com/demo/seecanalysisbackend/model/LogEntry.java

@@ -10,7 +10,7 @@ import org.springframework.data.elasticsearch.annotations.Field;
 import org.springframework.data.elasticsearch.annotations.DateFormat;
 import org.springframework.data.elasticsearch.annotations.FieldType;
 
-import java.time.LocalDateTime;
+import java.time.Instant;
 import java.util.Map;
 
 @Data
@@ -23,8 +23,8 @@ public class LogEntry {
     @Id
     private String id;
     
-    @Field(type = FieldType.Date, name = "@timestamp", format = DateFormat.date_time)
-    private LocalDateTime timestamp;
+    @Field(type = FieldType.Date, name = "@timestamp", format = DateFormat.date_optional_time)
+    private Instant timestamp;
     
     @Field(type = FieldType.Text, name = "raw_message")
     private String rawMessage;

+ 13 - 13
src/main/java/com/demo/seecanalysisbackend/repository/LogEntryRepository.java

@@ -7,46 +7,46 @@ import org.springframework.data.elasticsearch.annotations.Query;
 import org.springframework.data.elasticsearch.repository.ElasticsearchRepository;
 import org.springframework.stereotype.Repository;
 
-import java.time.LocalDateTime;
+import java.time.Instant;
 import java.util.List;
 
 @Repository
 public interface LogEntryRepository extends ElasticsearchRepository<LogEntry, String> {
     
-    Page<LogEntry> findByTimestampBetween(LocalDateTime startTime, LocalDateTime endTime, Pageable pageable);
+    Page<LogEntry> findByTimestampBetween(Instant startTime, Instant endTime, Pageable pageable);
     
-    Page<LogEntry> findByTimestampBetweenAndLevelIn(LocalDateTime startTime, LocalDateTime endTime, 
+    Page<LogEntry> findByTimestampBetweenAndLevelIn(Instant startTime, Instant endTime,
                                                    List<String> levels, Pageable pageable);
     
-    Page<LogEntry> findByTimestampBetweenAndApplicationIn(LocalDateTime startTime, LocalDateTime endTime, 
+    Page<LogEntry> findByTimestampBetweenAndApplicationIn(Instant startTime, Instant endTime,
                                                          List<String> applications, Pageable pageable);
     
-    List<LogEntry> findByTimestampBetweenAndLevel(LocalDateTime startTime, LocalDateTime endTime, String level);
+    List<LogEntry> findByTimestampBetweenAndLevel(Instant startTime, Instant endTime, String level);
     
-    Page<LogEntry> findByTimestampBetweenAndBizName(LocalDateTime startTime, LocalDateTime endTime, 
+    Page<LogEntry> findByTimestampBetweenAndBizName(Instant startTime, Instant endTime,
                                                     String bizName, Pageable pageable);
     
-    Page<LogEntry> findByTimestampBetweenAndBizNameIn(LocalDateTime startTime, LocalDateTime endTime, 
+    Page<LogEntry> findByTimestampBetweenAndBizNameIn(Instant startTime, Instant endTime,
                                                      List<String> bizNames, Pageable pageable);
     
     @Query("{\"bool\": {\"must\": [{\"range\": {\"@timestamp\": {\"gte\": \"?0\", \"lte\": \"?1\"}}}, {\"multi_match\": {\"query\": \"?2\", \"fields\": [\"raw_message\", \"business_info\", \"method_location\", \"service_name\", \"trace_id\", \"bizName\"]}}]}}")
-    Page<LogEntry> findByTimestampBetweenAndMessage(LocalDateTime startTime, LocalDateTime endTime, 
+    Page<LogEntry> findByTimestampBetweenAndMessage(Instant startTime, Instant endTime,
                                                    String message, Pageable pageable);
     
     @Query("{\"bool\": {\"must\": [{\"range\": {\"@timestamp\": {\"gte\": \"?0\", \"lte\": \"?1\"}}}, {\"term\": {\"log_level\": \"?2\"}}]}}")
-    long countByTimestampBetweenAndLevel(LocalDateTime startTime, LocalDateTime endTime, String level);
+    long countByTimestampBetweenAndLevel(Instant startTime, Instant endTime, String level);
     
     @Query("{\"bool\": {\"must\": [{\"range\": {\"@timestamp\": {\"gte\": \"?0\", \"lte\": \"?1\"}}}]}}")
-    long countByTimestampBetween(LocalDateTime startTime, LocalDateTime endTime);
+    long countByTimestampBetween(Instant startTime, Instant endTime);
     
     @Query("{\"bool\": {\"must\": [{\"range\": {\"@timestamp\": {\"gte\": \"?0\", \"lte\": \"?1\"}}}, {\"term\": {\"bizName\": \"?2\"}}]}}")
-    long countByTimestampBetweenAndBizName(LocalDateTime startTime, LocalDateTime endTime, String bizName);
+    long countByTimestampBetweenAndBizName(Instant startTime, Instant endTime, String bizName);
     
     @Query("{\"bool\": {\"must\": [{\"range\": {\"@timestamp\": {\"gte\": \"?0\", \"lte\": \"?1\"}}}, {\"term\": {\"service_name\": \"?2\"}}]}}")
-    Page<LogEntry> findByTimestampBetweenAndServiceName(LocalDateTime startTime, LocalDateTime endTime, 
+    Page<LogEntry> findByTimestampBetweenAndServiceName(Instant startTime, Instant endTime,
                                                        String serviceName, Pageable pageable);
     
     @Query("{\"bool\": {\"must\": [{\"range\": {\"@timestamp\": {\"gte\": \"?0\", \"lte\": \"?1\"}}}, {\"term\": {\"trace_id\": \"?2\"}}]}}")
-    Page<LogEntry> findByTimestampBetweenAndTraceId(LocalDateTime startTime, LocalDateTime endTime, 
+    Page<LogEntry> findByTimestampBetweenAndTraceId(Instant startTime, Instant endTime,
                                                    String traceId, Pageable pageable);
 }

+ 21 - 9
src/main/java/com/demo/seecanalysisbackend/service/D4MetricsService.java

@@ -11,7 +11,9 @@ import org.springframework.data.domain.Pageable;
 import org.springframework.stereotype.Service;
 
 import java.time.Duration;
+import java.time.Instant;
 import java.time.LocalDateTime;
+import java.time.ZoneOffset;
 import java.util.*;
 import java.util.concurrent.ConcurrentHashMap;
 import java.util.stream.Collectors;
@@ -112,7 +114,7 @@ public class D4MetricsService {
         
         Map<String, Long> collaborationsBySource = calculateCollaborationsBySource(collabEffectiveLogs);
         Map<String, Long> conflictsByType = calculateConflictsByType(conflictCreatedLogs);
-        Map<String, LocalDateTime> conflictCreatedTimeByKey = buildConflictCreatedTimeIndex(conflictCreatedLogs);
+        Map<String, Instant> conflictCreatedTimeByKey = buildConflictCreatedTimeIndex(conflictCreatedLogs);
         
         List<D4Metrics.ResponseTimeDetail> recentResponseTimes = messageResponseLogs.stream()
             .limit(10)
@@ -137,13 +139,15 @@ public class D4MetricsService {
     }
 
     private List<LogEntry> loadAllD4Logs(LocalDateTime startTime, LocalDateTime endTime) {
+        Instant startInstant = toUtcInstant(startTime);
+        Instant endInstant = toUtcInstant(endTime);
         List<LogEntry> allLogs = new ArrayList<>();
         List<String> d4Events = new ArrayList<>(D4_EVENTS);
         int page = 0;
 
         while (true) {
             Pageable pageable = PageRequest.of(page, D4_QUERY_PAGE_SIZE);
-            Page<LogEntry> pageResult = logEntryRepository.findByTimestampBetweenAndBizNameIn(startTime, endTime, d4Events, pageable);
+            Page<LogEntry> pageResult = logEntryRepository.findByTimestampBetweenAndBizNameIn(startInstant, endInstant, d4Events, pageable);
             allLogs.addAll(pageResult.getContent());
 
             if (!pageResult.hasNext()) {
@@ -290,7 +294,7 @@ public class D4MetricsService {
             .taskType(getContextString(log, "taskType"))
             .projectId(getContextString(log, "projectId"))
             .userId(extractExecutorUserId(log))
-            .completedTime(log.getTimestamp())
+                .completedTime(toUtcLocalDateTime(log.getTimestamp()))
             .durationMs(durationMs)
             .onTime(durationMs != null ? durationMs <= DEFAULT_D4_SLA_THRESHOLD_MS : null)
             .build();
@@ -301,16 +305,16 @@ public class D4MetricsService {
             .messageId(getContextString(log, "messageId"))
             .creatorId(getContextString(log, "creatorId"))
             .receiverId(getContextString(log, "receiverId"))
-            .responseTime(log.getTimestamp())
+                .responseTime(toUtcLocalDateTime(log.getTimestamp()))
             .responseMs(getContextLong(log, "responseMs"))
             .build();
     }
     
     private D4Metrics.ConflictResolutionDetail convertToConflictResolutionDetail(
             LogEntry log,
-            Map<String, LocalDateTime> conflictCreatedTimeByKey) {
+            Map<String, Instant> conflictCreatedTimeByKey) {
         String conflictKey = buildConflictKey(log);
-        LocalDateTime createdTime = conflictCreatedTimeByKey.get(conflictKey);
+        Instant createdTime = conflictCreatedTimeByKey.get(conflictKey);
         Long resolutionTimeMs = null;
         if (createdTime != null && log.getTimestamp() != null && !log.getTimestamp().isBefore(createdTime)) {
             resolutionTimeMs = Duration.between(createdTime, log.getTimestamp()).toMillis();
@@ -321,7 +325,7 @@ public class D4MetricsService {
             .conflictType(getContextString(log, "conflictType"))
             .projectId(getContextString(log, "projectId"))
             .resolverId(getContextString(log, "resolverId"))
-            .resolvedTime(log.getTimestamp())
+                .resolvedTime(toUtcLocalDateTime(log.getTimestamp()))
             .resolutionTimeMs(resolutionTimeMs)
             .build();
     }
@@ -334,8 +338,8 @@ public class D4MetricsService {
             .count();
     }
 
-    private Map<String, LocalDateTime> buildConflictCreatedTimeIndex(List<LogEntry> conflictCreatedLogs) {
-        Map<String, LocalDateTime> result = new HashMap<>();
+    private Map<String, Instant> buildConflictCreatedTimeIndex(List<LogEntry> conflictCreatedLogs) {
+        Map<String, Instant> result = new HashMap<>();
         for (LogEntry log : conflictCreatedLogs) {
             String key = buildConflictKey(log);
             if (key == null || log.getTimestamp() == null) {
@@ -451,4 +455,12 @@ public class D4MetricsService {
 
         return logEntry.getContext();
     }
+
+    private Instant toUtcInstant(LocalDateTime dateTime) {
+        return dateTime.atZone(ZoneOffset.UTC).toInstant();
+    }
+
+    private LocalDateTime toUtcLocalDateTime(Instant instant) {
+        return instant == null ? null : LocalDateTime.ofInstant(instant, ZoneOffset.UTC);
+    }
 }

+ 26 - 10
src/main/java/com/demo/seecanalysisbackend/service/LogAnalysisService.java

@@ -10,7 +10,9 @@ import org.springframework.data.domain.PageRequest;
 import org.springframework.data.domain.Pageable;
 import org.springframework.stereotype.Service;
 
+import java.time.Instant;
 import java.time.LocalDateTime;
+import java.time.ZoneOffset;
 import java.time.format.DateTimeFormatter;
 import java.util.*;
 import java.util.stream.Collectors;
@@ -24,19 +26,22 @@ public class LogAnalysisService {
     
     public LogStatistics getLogStatistics(LocalDateTime startTime, LocalDateTime endTime) {
         log.info("Calculating log statistics from {} to {}", startTime, endTime);
+
+        Instant startInstant = toUtcInstant(startTime);
+        Instant endInstant = toUtcInstant(endTime);
         
-        long totalLogs = logEntryRepository.countByTimestampBetween(startTime, endTime);
+        long totalLogs = logEntryRepository.countByTimestampBetween(startInstant, endInstant);
         
         Map<String, Long> logsByLevel = new HashMap<>();
         for (String level : Arrays.asList("ERROR", "WARN", "INFO", "DEBUG")) {
-            long count = logEntryRepository.countByTimestampBetweenAndLevel(startTime, endTime, level);
+            long count = logEntryRepository.countByTimestampBetweenAndLevel(startInstant, endInstant, level);
             if (count > 0) {
                 logsByLevel.put(level, count);
             }
         }
         
         Pageable pageable = PageRequest.of(0, 1000);
-        Page<LogEntry> allLogs = logEntryRepository.findByTimestampBetween(startTime, endTime, pageable);
+        Page<LogEntry> allLogs = logEntryRepository.findByTimestampBetween(startInstant, endInstant, pageable);
         
         Map<String, Long> logsByService = allLogs.getContent().stream()
             .filter(log -> log.getServiceName() != null)
@@ -61,7 +66,9 @@ public class LogAnalysisService {
     }
     
     private List<LogStatistics.ErrorStatistics> calculateErrorStatistics(LocalDateTime startTime, LocalDateTime endTime) {
-        List<LogEntry> errorLogs = logEntryRepository.findByTimestampBetweenAndLevel(startTime, endTime, "ERROR");
+        Instant startInstant = toUtcInstant(startTime);
+        Instant endInstant = toUtcInstant(endTime);
+        List<LogEntry> errorLogs = logEntryRepository.findByTimestampBetweenAndLevel(startInstant, endInstant, "ERROR");
         
         Map<String, List<LogEntry>> errorsByType = errorLogs.stream()
             .collect(Collectors.groupingBy(log -> {
@@ -79,7 +86,8 @@ public class LogAnalysisService {
                 
                 String lastOccurrence = logs.stream()
                     .max(Comparator.comparing(LogEntry::getTimestamp))
-                    .map(log -> log.getTimestamp().format(DateTimeFormatter.ISO_LOCAL_DATE_TIME))
+                    .map(log -> DateTimeFormatter.ISO_LOCAL_DATE_TIME.format(
+                        LocalDateTime.ofInstant(log.getTimestamp(), ZoneOffset.UTC)))
                     .orElse("");
                 
                 List<String> sampleMessages = logs.stream()
@@ -100,8 +108,10 @@ public class LogAnalysisService {
     }
     
     private List<LogStatistics.PerformanceStatistics> calculatePerformanceStatistics(LocalDateTime startTime, LocalDateTime endTime) {
+        Instant startInstant = toUtcInstant(startTime);
+        Instant endInstant = toUtcInstant(endTime);
         Pageable pageable = PageRequest.of(0, 1000);
-        Page<LogEntry> allLogs = logEntryRepository.findByTimestampBetween(startTime, endTime, pageable);
+        Page<LogEntry> allLogs = logEntryRepository.findByTimestampBetween(startInstant, endInstant, pageable);
         
         Map<String, List<LogEntry>> logsByEndpoint = allLogs.getContent().stream()
             .filter(log -> log.getContext() != null && log.getContext().get("responseTime") != null)
@@ -181,12 +191,14 @@ public class LogAnalysisService {
     }
     
     private LogStatistics.TrendData calculateTrendForInterval(LocalDateTime startTime, LocalDateTime endTime) {
-        long totalCount = logEntryRepository.countByTimestampBetween(startTime, endTime);
-        long errorCount = logEntryRepository.countByTimestampBetweenAndLevel(startTime, endTime, "ERROR");
-        long warningCount = logEntryRepository.countByTimestampBetweenAndLevel(startTime, endTime, "WARN");
+        Instant startInstant = toUtcInstant(startTime);
+        Instant endInstant = toUtcInstant(endTime);
+        long totalCount = logEntryRepository.countByTimestampBetween(startInstant, endInstant);
+        long errorCount = logEntryRepository.countByTimestampBetweenAndLevel(startInstant, endInstant, "ERROR");
+        long warningCount = logEntryRepository.countByTimestampBetweenAndLevel(startInstant, endInstant, "WARN");
         
         Pageable pageable = PageRequest.of(0, 1000);
-        Page<LogEntry> logs = logEntryRepository.findByTimestampBetween(startTime, endTime, pageable);
+        Page<LogEntry> logs = logEntryRepository.findByTimestampBetween(startInstant, endInstant, pageable);
 
         double avgResponseTime = logs.getContent().stream()
                 .filter(log -> log.getContext() != null && log.getContext().get("responseTime") != null)
@@ -205,4 +217,8 @@ public class LogAnalysisService {
             .avgResponseTime(avgResponseTime)
             .build();
     }
+
+    private Instant toUtcInstant(LocalDateTime dateTime) {
+        return dateTime.atZone(ZoneOffset.UTC).toInstant();
+    }
 }

+ 17 - 9
src/main/java/com/demo/seecanalysisbackend/service/LogSearchService.java

@@ -12,10 +12,11 @@ import org.springframework.data.domain.Pageable;
 import org.springframework.data.domain.Sort;
 import org.springframework.stereotype.Service;
 
+import java.time.Instant;
 import java.time.LocalDateTime;
+import java.time.ZoneOffset;
 import java.time.format.DateTimeFormatter;
 import java.util.HashMap;
-import java.util.HashSet;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
@@ -55,45 +56,48 @@ public class LogSearchService {
     }
     
     private Page<LogEntry> performSearch(LogSearchRequest request, Pageable pageable) {
+        Instant startTime = toUtcInstant(request.getStartTime());
+        Instant endTime = toUtcInstant(request.getEndTime());
+
         if (request.getSearchText() != null && !request.getSearchText().trim().isEmpty()) {
             return logEntryRepository.findByTimestampBetweenAndMessage(
-                request.getStartTime(), request.getEndTime(), 
+                startTime, endTime,
                 request.getSearchText(), pageable);
         }
         
         if (request.getBizNames() != null && !request.getBizNames().isEmpty()) {
             return logEntryRepository.findByTimestampBetweenAndBizNameIn(
-                request.getStartTime(), request.getEndTime(), 
+                startTime, endTime,
                 request.getBizNames(), pageable);
         }
         
         if (request.getServices() != null && !request.getServices().isEmpty()) {
             String serviceName = request.getServices().getFirst();
             return logEntryRepository.findByTimestampBetweenAndServiceName(
-                request.getStartTime(), request.getEndTime(), 
+                startTime, endTime,
                 serviceName, pageable);
         }
         
         if (request.getTraceId() != null && !request.getTraceId().trim().isEmpty()) {
             return logEntryRepository.findByTimestampBetweenAndTraceId(
-                request.getStartTime(), request.getEndTime(), 
+                startTime, endTime,
                 request.getTraceId(), pageable);
         }
         
         if (request.getLevels() != null && !request.getLevels().isEmpty()) {
             return logEntryRepository.findByTimestampBetweenAndLevelIn(
-                request.getStartTime(), request.getEndTime(), 
+                startTime, endTime,
                 request.getLevels(), pageable);
         }
         
         if (request.getApplications() != null && !request.getApplications().isEmpty()) {
             return logEntryRepository.findByTimestampBetweenAndApplicationIn(
-                request.getStartTime(), request.getEndTime(), 
+                startTime, endTime,
                 request.getApplications(), pageable);
         }
         
         return logEntryRepository.findByTimestampBetween(
-            request.getStartTime(), request.getEndTime(), pageable);
+            startTime, endTime, pageable);
     }
     
     private Pageable createPageable(LogSearchRequest request) {
@@ -132,7 +136,7 @@ public class LogSearchService {
         return LogSearchResponse.LogEntryDto.builder()
             .id(logEntry.getId())
             .timestamp(logEntry.getTimestamp() != null ? 
-                logEntry.getTimestamp().format(DateTimeFormatter.ISO_LOCAL_DATE_TIME) : null)
+                DateTimeFormatter.ISO_LOCAL_DATE_TIME.format(logEntry.getTimestamp().atOffset(ZoneOffset.UTC).toLocalDateTime()) : null)
             .rawMessage(logEntry.getRawMessage())
             .serviceName(logEntry.getServiceName())
             .thread(logEntry.getThread())
@@ -145,4 +149,8 @@ public class LogSearchService {
             .context(logEntry.getContext())
             .build();
     }
+
+    private Instant toUtcInstant(LocalDateTime dateTime) {
+        return dateTime.atZone(ZoneOffset.UTC).toInstant();
+    }
 }