From 2423e27b3466e176665338ebf7a367a332df9701 Mon Sep 17 00:00:00 2001 From: ovo Date: Tue, 24 Dec 2024 13:39:36 +0800 Subject: [PATCH] =?UTF-8?q?feat(java=E6=9F=A5=E8=AF=A2elk=E6=97=A5?= =?UTF-8?q?=E5=BF=97=E6=8E=A5=E5=8F=A3):=20java=E6=9F=A5=E8=AF=A2elk?= =?UTF-8?q?=E6=97=A5=E5=BF=97=E6=8E=A5=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit java查询elk日志接口 --- .../backend/controller/LogController.java | 43 +++++++++ .../elasticsearch/document/LogstashLog.java | 89 +++++++++++++++++++ .../mapper/LogstashLogEsMapper.java | 9 ++ .../backend/service/LogstashLogService.java | 54 +++++++++++ .../backend/service/impl/UserServiceImpl.java | 48 ++++++---- 5 files changed, 224 insertions(+), 19 deletions(-) create mode 100644 src/main/java/com/guwan/backend/controller/LogController.java create mode 100644 src/main/java/com/guwan/backend/elasticsearch/document/LogstashLog.java create mode 100644 src/main/java/com/guwan/backend/elasticsearch/mapper/LogstashLogEsMapper.java create mode 100644 src/main/java/com/guwan/backend/service/LogstashLogService.java diff --git a/src/main/java/com/guwan/backend/controller/LogController.java b/src/main/java/com/guwan/backend/controller/LogController.java new file mode 100644 index 0000000..91b06c1 --- /dev/null +++ b/src/main/java/com/guwan/backend/controller/LogController.java @@ -0,0 +1,43 @@ +package com.guwan.backend.controller; + +import cn.easyes.core.biz.EsPageInfo; +import com.guwan.backend.elasticsearch.document.LogstashLog; +import com.guwan.backend.service.LogstashLogService; +import lombok.RequiredArgsConstructor; +import org.springframework.format.annotation.DateTimeFormat; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; + +import java.util.Date; +import java.util.List; + +@RestController +@RequestMapping("/api/logs") +@RequiredArgsConstructor +public class LogController { + + private final LogstashLogService logstashLogService; + + @GetMapping("/search") + public List searchLogs( + @RequestParam @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") Date startTime, + @RequestParam @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") Date endTime, + @RequestParam(required = false) String level, + @RequestParam(required = false) String keyword) { + + if (keyword != null) { + return logstashLogService.searchLogsByKeyword(keyword, startTime, endTime); + } else { + return logstashLogService.queryLogsByTimeRangeAndLevel(startTime, endTime, level); + } + } + + @GetMapping("/errors") + public EsPageInfo getRecentErrors( + @RequestParam(defaultValue = "1") int pageNum, + @RequestParam(defaultValue = "10") int pageSize) { + return logstashLogService.getRecentErrorLogs(pageNum, pageSize); + } +} \ No newline at end of file diff --git a/src/main/java/com/guwan/backend/elasticsearch/document/LogstashLog.java b/src/main/java/com/guwan/backend/elasticsearch/document/LogstashLog.java new file mode 100644 index 0000000..37cb7e0 --- /dev/null +++ b/src/main/java/com/guwan/backend/elasticsearch/document/LogstashLog.java @@ -0,0 +1,89 @@ +package com.guwan.backend.elasticsearch.document; + +import cn.easyes.annotation.IndexField; +import cn.easyes.annotation.IndexId; +import cn.easyes.annotation.IndexName; +import cn.easyes.annotation.rely.FieldType; +import com.fasterxml.jackson.annotation.JsonFormat; +import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.Data; + +import java.util.Date; +import java.util.List; +import java.time.Instant; + +@Data +@IndexName("logstash-logs-*") +public class LogstashLog { + + @IndexId + private String id; + + @JsonProperty("@timestamp") + @IndexField(value = "@timestamp", fieldType = FieldType.DATE) + private Instant timestamp; + + @JsonProperty("@version") + @IndexField(fieldType = FieldType.KEYWORD) + private String version; + + @IndexField(fieldType = FieldType.TEXT) + private String message; + + @IndexField(fieldType = FieldType.TEXT) + private String level; + + @IndexField(fieldType = FieldType.LONG) + private Long level_value; + + @IndexField(fieldType = FieldType.TEXT) + private String logger_name; + + @IndexField(fieldType = FieldType.TEXT) + private String thread_name; + + @IndexField(fieldType = FieldType.TEXT) + private String stack_trace; + + @IndexField(fieldType = FieldType.TEXT) + private String app_name; + + @IndexField(fieldType = FieldType.TEXT) + private String host; + + @IndexField(fieldType = FieldType.LONG) + private Long port; + + @IndexField(fieldType = FieldType.TEXT) + private List tags; + + @Data + public static class GeoIP { + @IndexField(fieldType = FieldType.IP) + private String ip; + + @IndexField(fieldType = FieldType.FLOAT) + private Float latitude; + + @IndexField(fieldType = FieldType.FLOAT) + private Float longitude; + + @IndexField(fieldType = FieldType.GEO_POINT) + private String location; + } + + @IndexField(fieldType = FieldType.OBJECT) + private GeoIP geoip; + + @JsonProperty("APP_NAME") + @IndexField(fieldType = FieldType.TEXT) + private String APP_NAME; + + @JsonProperty("LOGSTASH_HOST") + @IndexField(fieldType = FieldType.TEXT) + private String LOGSTASH_HOST; + + @JsonProperty("LOGSTASH_PORT") + @IndexField(fieldType = FieldType.TEXT) + private String LOGSTASH_PORT; +} \ No newline at end of file diff --git a/src/main/java/com/guwan/backend/elasticsearch/mapper/LogstashLogEsMapper.java b/src/main/java/com/guwan/backend/elasticsearch/mapper/LogstashLogEsMapper.java new file mode 100644 index 0000000..cdc6145 --- /dev/null +++ b/src/main/java/com/guwan/backend/elasticsearch/mapper/LogstashLogEsMapper.java @@ -0,0 +1,9 @@ +package com.guwan.backend.elasticsearch.mapper; + +import cn.easyes.core.conditions.interfaces.BaseEsMapper; +import com.guwan.backend.elasticsearch.document.LogstashLog; +import org.springframework.stereotype.Repository; + +@Repository +public interface LogstashLogEsMapper extends BaseEsMapper { +} \ No newline at end of file diff --git a/src/main/java/com/guwan/backend/service/LogstashLogService.java b/src/main/java/com/guwan/backend/service/LogstashLogService.java new file mode 100644 index 0000000..e19a699 --- /dev/null +++ b/src/main/java/com/guwan/backend/service/LogstashLogService.java @@ -0,0 +1,54 @@ +package com.guwan.backend.service; + +import cn.easyes.core.biz.EsPageInfo; +import cn.easyes.core.conditions.LambdaEsQueryWrapper; +import com.guwan.backend.elasticsearch.document.LogstashLog; +import com.guwan.backend.elasticsearch.mapper.LogstashLogEsMapper; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; + +import java.util.Date; +import java.util.List; + +@Service +@RequiredArgsConstructor +public class LogstashLogService { + + private final LogstashLogEsMapper logstashLogEsMapper; + + /** + * 按时间范围和日志级别查询 + */ + public List queryLogsByTimeRangeAndLevel(Date startTime, Date endTime, String level) { + LambdaEsQueryWrapper wrapper = new LambdaEsQueryWrapper<>(); + wrapper.between(LogstashLog::getTimestamp, startTime, endTime) + .eq(LogstashLog::getLevel, level) + .orderByDesc(LogstashLog::getTimestamp); + + return logstashLogEsMapper.selectList(wrapper); + } + + /** + * 按关键字搜索日志内容 + */ + public List searchLogsByKeyword(String keyword, Date startTime, Date endTime) { + LambdaEsQueryWrapper wrapper = new LambdaEsQueryWrapper<>(); + wrapper.between(LogstashLog::getTimestamp, startTime, endTime) + .match(LogstashLog::getMessage, keyword) + .orderByDesc(LogstashLog::getTimestamp); + + return logstashLogEsMapper.selectList(wrapper); + } + + /** + * 分页查询最近的错误日志 + */ + public EsPageInfo getRecentErrorLogs(int pageNum, int pageSize) { + LambdaEsQueryWrapper wrapper = new LambdaEsQueryWrapper<>(); + wrapper.orderByDesc(LogstashLog::getTimestamp) + .from((pageNum - 1) * pageSize) + .size(pageSize); + + return logstashLogEsMapper.pageQuery(wrapper, pageNum, pageSize); + } +} \ No newline at end of file diff --git a/src/main/java/com/guwan/backend/service/impl/UserServiceImpl.java b/src/main/java/com/guwan/backend/service/impl/UserServiceImpl.java index 316a1ac..536d973 100644 --- a/src/main/java/com/guwan/backend/service/impl/UserServiceImpl.java +++ b/src/main/java/com/guwan/backend/service/impl/UserServiceImpl.java @@ -28,6 +28,7 @@ import org.springframework.cache.annotation.Cacheable; import org.springframework.security.crypto.password.PasswordEncoder; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; +import org.slf4j.MDC; import java.time.LocalDateTime; @@ -172,24 +173,34 @@ public class UserServiceImpl extends ServiceImpl implements Us @OperationLog(description = "根据Id获取用户信息") @Cacheable(value = "userCache", key = "#id") public UserDTO getUserById(Long id) { - log.info("查询redis缓存"); - // 先从缓存获取 - Object cached = redisUtil.get(USER_CACHE_KEY + id); - if (cached != null) { - return (UserDTO) cached; - }else { - log.info("redis缓存为空"); - } + MDC.put("userId", String.valueOf(id)); // 添加用户ID到日志上下文 + try { + log.info("开始获取用户信息"); + + // Redis缓存检查 + Object cached = redisUtil.get(USER_CACHE_KEY + id); + if (cached != null) { + log.debug("Redis缓存命中, userId={}", id); + return (UserDTO) cached; + } + log.debug("Redis缓存未命中"); - log.info("查询数据库, id: {}", id); - User user = userMapper.selectById(id); - if (user == null) { - return null; - } + // 数据库查询 + log.debug("从数据库查询用户信息, userId={}", id); + User user = userMapper.selectById(id); + if (user == null) { + log.warn("用户不存在, userId={}", id); + return null; + } - UserDTO userDTO = convertToDTO(user); - redisUtil.set(USER_CACHE_KEY + id, userDTO, USER_CACHE_DURATION); - return userDTO; + UserDTO userDTO = convertToDTO(user); + redisUtil.set(USER_CACHE_KEY + id, userDTO, USER_CACHE_DURATION); + log.info("用户信息获取成功, userId={}", id); + + return userDTO; + } finally { + MDC.remove("userId"); // 清理上下文 + } } @Override @@ -208,7 +219,7 @@ public class UserServiceImpl extends ServiceImpl implements Us User user = this.lambdaQuery().eq(User::getUsername, changePasswordDTO.getInfo()).one(); - //传入密码 库中密码 + //matches(传入密码 库中密码) boolean matches = passwordEncoder.matches(changePasswordDTO.getCode(), user.getPassword()); if (!matches){ log.error("原密码不正确"); @@ -226,8 +237,7 @@ public class UserServiceImpl extends ServiceImpl implements Us } - - + } if (changePasswordDTO.getChangeWay().equals(UserEnums.ACCOUNT.getValue())){