/* * Copyright 2019-2020 Zheng Jie * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package me.zhengjie.service.impl; import cn.hutool.core.lang.Dict; import cn.hutool.core.util.ObjectUtil; import cn.hutool.json.JSONUtil; import lombok.RequiredArgsConstructor; import me.zhengjie.domain.Log; import me.zhengjie.repository.LogRepository; import me.zhengjie.service.LogService; import me.zhengjie.service.dto.LogQueryCriteria; import me.zhengjie.service.mapstruct.LogErrorMapper; import me.zhengjie.service.mapstruct.LogSmallMapper; import me.zhengjie.utils.*; import org.aspectj.lang.ProceedingJoinPoint; import org.aspectj.lang.reflect.MethodSignature; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.data.domain.Page; import org.springframework.data.domain.Pageable; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestParam; import javax.servlet.http.HttpServletResponse; import java.io.IOException; import java.lang.reflect.Method; import java.lang.reflect.Parameter; import java.util.*; /** * @author Zheng Jie * @date 2018-11-24 */ @Service @RequiredArgsConstructor public class LogServiceImpl implements LogService { private static final Logger log = LoggerFactory.getLogger(LogServiceImpl.class); private final LogRepository logRepository; private final LogErrorMapper logErrorMapper; private final LogSmallMapper logSmallMapper; @Override public Object queryAll(LogQueryCriteria criteria, Pageable pageable) { Page page = logRepository.findAll(((root, criteriaQuery, cb) -> QueryHelp.getPredicate(root, criteria, cb)), pageable); String status = "ERROR"; if (status.equals(criteria.getLogType())) { return PageUtil.toPage(page.map(logErrorMapper::toDto)); } return page; } @Override public List queryAll(LogQueryCriteria criteria) { return logRepository.findAll(((root, criteriaQuery, cb) -> QueryHelp.getPredicate(root, criteria, cb))); } @Override public Object queryAllByUser(LogQueryCriteria criteria, Pageable pageable) { Page page = logRepository.findAll(((root, criteriaQuery, cb) -> QueryHelp.getPredicate(root, criteria, cb)), pageable); return PageUtil.toPage(page.map(logSmallMapper::toDto)); } @Override @Transactional(rollbackFor = Exception.class) public void save(String username, String browser, String ip, ProceedingJoinPoint joinPoint, Log log) { if (log == null) { throw new IllegalArgumentException("Log 不能为 null!"); } MethodSignature signature = (MethodSignature) joinPoint.getSignature(); Method method = signature.getMethod(); me.zhengjie.annotation.Log aopLog = method.getAnnotation(me.zhengjie.annotation.Log.class); // 方法路径 String methodName = joinPoint.getTarget().getClass().getName() + "." + signature.getName() + "()"; // 描述 log.setDescription(aopLog.value()); log.setRequestIp(ip); log.setAddress(StringUtils.getCityInfo(log.getRequestIp())); log.setMethod(methodName); log.setUsername(username); log.setParams(getParameter(method, joinPoint.getArgs())); log.setBrowser(browser); logRepository.save(log); } /** * 根据方法和传入的参数获取请求参数 */ private String getParameter(Method method, Object[] args) { List argList = new ArrayList<>(); Parameter[] parameters = method.getParameters(); for (int i = 0; i < parameters.length; i++) { //将RequestBody注解修饰的参数作为请求参数 RequestBody requestBody = parameters[i].getAnnotation(RequestBody.class); if (requestBody != null) { argList.add(args[i]); } //将RequestParam注解修饰的参数作为请求参数 RequestParam requestParam = parameters[i].getAnnotation(RequestParam.class); if (requestParam != null) { Map map = new HashMap<>(); String key = parameters[i].getName(); if (!StringUtils.isEmpty(requestParam.value())) { key = requestParam.value(); } map.put(key, args[i]); argList.add(map); } } if (argList.isEmpty() == 0) { return ""; } return argList.size() == 1 ? JSONUtil.toJsonStr(argList.get(0)) : JSONUtil.toJsonStr(argList); } @Override public Object findByErrDetail(Long id) { Log log = logRepository.findById(id).orElseGet(Log::new); ValidationUtil.isNull(log.getId(), "Log", "id", id); byte[] details = log.getExceptionDetail(); return Dict.create().set("exception", new String(ObjectUtil.isNotNull(details) ? details : "".getBytes())); } @Override public void download(List logs, HttpServletResponse response) throws IOException { List> list = new ArrayList<>(); for (Log log : logs) { Map map = new LinkedHashMap<>(); map.put("用户名", log.getUsername()); map.put("IP", log.getRequestIp()); map.put("IP来源", log.getAddress()); map.put("描述", log.getDescription()); map.put("浏览器", log.getBrowser()); map.put("请求耗时/毫秒", log.getTime()); map.put("异常详情", new String(ObjectUtil.isNotNull(log.getExceptionDetail()) ? log.getExceptionDetail() : "".getBytes())); map.put("创建日期", log.getCreateTime()); list.add(map); } FileUtil.downloadExcel(list, response); } @Override @Transactional(rollbackFor = Exception.class) public void delAllByError() { logRepository.deleteByLogType("ERROR"); } @Override @Transactional(rollbackFor = Exception.class) public void delAllByInfo() { logRepository.deleteByLogType("INFO"); } }