| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148 |
- package com.demo.seecanalysisbackend.service;
- import com.demo.seecanalysisbackend.dto.LogSearchRequest;
- import com.demo.seecanalysisbackend.dto.LogSearchResponse;
- import com.demo.seecanalysisbackend.model.LogEntry;
- import com.demo.seecanalysisbackend.repository.LogEntryRepository;
- import lombok.RequiredArgsConstructor;
- import lombok.extern.slf4j.Slf4j;
- import org.springframework.data.domain.Page;
- import org.springframework.data.domain.PageRequest;
- import org.springframework.data.domain.Pageable;
- import org.springframework.data.domain.Sort;
- import org.springframework.stereotype.Service;
- import java.time.LocalDateTime;
- 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;
- import java.util.stream.Collectors;
- @Service
- @RequiredArgsConstructor
- @Slf4j
- public class LogSearchService {
-
- private final LogEntryRepository logEntryRepository;
- private static final Map<String, String> SORT_FIELD_MAPPING = createSortFieldMapping();
- private static final Set<String> ALLOWED_SORT_PROPERTIES = Set.of(
- "timestamp", "level", "serviceName", "traceId", "spanId", "bizName",
- "className", "methodName", "thread", "application", "rawMessage"
- );
-
- public LogSearchResponse searchLogs(LogSearchRequest request) {
- log.info("Searching logs with criteria: {}", request);
-
- Pageable pageable = createPageable(request);
- Page<LogEntry> logPage = performSearch(request, pageable);
-
- List<LogSearchResponse.LogEntryDto> logDtos = logPage.getContent().stream()
- .map(this::convertToDto)
- .collect(Collectors.toList());
-
- return LogSearchResponse.builder()
- .logs(logDtos)
- .totalCount(logPage.getTotalElements())
- .currentPage(logPage.getNumber())
- .pageSize(logPage.getSize())
- .totalPages(logPage.getTotalPages())
- .hasNext(logPage.hasNext())
- .hasPrevious(logPage.hasPrevious())
- .build();
- }
-
- private Page<LogEntry> performSearch(LogSearchRequest request, Pageable pageable) {
- if (request.getSearchText() != null && !request.getSearchText().trim().isEmpty()) {
- return logEntryRepository.findByTimestampBetweenAndMessage(
- request.getStartTime(), request.getEndTime(),
- request.getSearchText(), pageable);
- }
-
- if (request.getBizNames() != null && !request.getBizNames().isEmpty()) {
- return logEntryRepository.findByTimestampBetweenAndBizNameIn(
- request.getStartTime(), request.getEndTime(),
- request.getBizNames(), pageable);
- }
-
- if (request.getServices() != null && !request.getServices().isEmpty()) {
- String serviceName = request.getServices().getFirst();
- return logEntryRepository.findByTimestampBetweenAndServiceName(
- request.getStartTime(), request.getEndTime(),
- serviceName, pageable);
- }
-
- if (request.getTraceId() != null && !request.getTraceId().trim().isEmpty()) {
- return logEntryRepository.findByTimestampBetweenAndTraceId(
- request.getStartTime(), request.getEndTime(),
- request.getTraceId(), pageable);
- }
-
- if (request.getLevels() != null && !request.getLevels().isEmpty()) {
- return logEntryRepository.findByTimestampBetweenAndLevelIn(
- request.getStartTime(), request.getEndTime(),
- request.getLevels(), pageable);
- }
-
- if (request.getApplications() != null && !request.getApplications().isEmpty()) {
- return logEntryRepository.findByTimestampBetweenAndApplicationIn(
- request.getStartTime(), request.getEndTime(),
- request.getApplications(), pageable);
- }
-
- return logEntryRepository.findByTimestampBetween(
- request.getStartTime(), request.getEndTime(), pageable);
- }
-
- private Pageable createPageable(LogSearchRequest request) {
- Sort.Direction direction = "asc".equalsIgnoreCase(request.getSortDirection()) ?
- Sort.Direction.ASC : Sort.Direction.DESC;
- String requestedSortBy = request.getSortBy() == null ? "timestamp" : request.getSortBy();
- String normalizedSortProperty = SORT_FIELD_MAPPING.getOrDefault(requestedSortBy, requestedSortBy);
- String actualSortField = ALLOWED_SORT_PROPERTIES.contains(normalizedSortProperty)
- ? normalizedSortProperty
- : "timestamp";
-
- return PageRequest.of(request.getPage(), request.getSize(),
- Sort.by(direction, actualSortField));
- }
- private static Map<String, String> createSortFieldMapping() {
- Map<String, String> mapping = new HashMap<>();
- // Accept external ES field names and normalize them to entity property names.
- mapping.put("@timestamp", "timestamp");
- mapping.put("log_level", "level");
- mapping.put("service_name", "serviceName");
- mapping.put("trace_id", "traceId");
- mapping.put("span_id", "spanId");
- mapping.put("biz_name", "bizName");
- mapping.put("bizName", "bizName");
- mapping.put("timestamp", "timestamp");
- mapping.put("level", "level");
- mapping.put("serviceName", "serviceName");
- mapping.put("traceId", "traceId");
- mapping.put("spanId", "spanId");
- return mapping;
- }
-
- private LogSearchResponse.LogEntryDto convertToDto(LogEntry logEntry) {
- return LogSearchResponse.LogEntryDto.builder()
- .id(logEntry.getId())
- .timestamp(logEntry.getTimestamp() != null ?
- logEntry.getTimestamp().format(DateTimeFormatter.ISO_LOCAL_DATE_TIME) : null)
- .rawMessage(logEntry.getRawMessage())
- .serviceName(logEntry.getServiceName())
- .thread(logEntry.getThread())
- .level(logEntry.getLevel())
- .className(logEntry.getClassName())
- .methodName(logEntry.getMethodName())
- .traceId(logEntry.getTraceId())
- .spanId(logEntry.getSpanId())
- .bizName(logEntry.getBizName())
- .context(logEntry.getContext())
- .build();
- }
- }
|