All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.lwohvye.log.service.impl.LogServiceImpl Maven / Gradle / Ivy

/*
 *  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 com.lwohvye.log.service.impl;

import cn.hutool.core.lang.Dict;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.json.JSONUtil;
import com.lwohvye.core.annotation.log.OprLog;
import com.lwohvye.core.utils.*;
import com.lwohvye.log.domain.Log;
import com.lwohvye.log.repository.LogRepository;
import com.lwohvye.log.service.ILogService;
import com.lwohvye.log.service.dto.LogErrorDTO;
import com.lwohvye.log.service.dto.LogQueryCriteria;
import com.lwohvye.log.service.dto.LogSmallDTO;
import lombok.RequiredArgsConstructor;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.core.convert.ConversionService;
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.util.Assert;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestParam;

import jakarta.servlet.http.HttpServletResponse;

import java.io.IOException;
import java.lang.reflect.Method;
import java.util.*;

/**
 * @author Zheng Jie
 * @date 2018-11-24
 */
@Service
//有参构造
@RequiredArgsConstructor
public class LogServiceImpl implements ILogService {
    private final LogRepository logRepository;

    private final ConversionService conversionService;

    @Override
    @Transactional(rollbackFor = Exception.class, readOnly = true)
    public Map queryAll(LogQueryCriteria criteria, Pageable pageable) {
        Page page = logRepository.findAll(((root, criteriaQuery, criteriaBuilder) -> QueryHelp.getPredicate(root, criteria, criteriaBuilder)), pageable);
        String status = "ERROR";
        if (status.equals(criteria.getLogType())) {
            return PageUtils.toPage(page.map(errInfo -> conversionService.convert(errInfo, LogErrorDTO.class)));
        }
        return PageUtils.toPage(page);
    }

    @Override
    @Transactional(rollbackFor = Exception.class, readOnly = true)
    public List queryAll(LogQueryCriteria criteria) {
        return logRepository.findAll(((root, criteriaQuery, criteriaBuilder) -> QueryHelp.getPredicate(root, criteria, criteriaBuilder)));
    }

    @Override
    @Transactional(rollbackFor = Exception.class, readOnly = true)
    public Map queryAllByUser(LogQueryCriteria criteria, Pageable pageable) {
        Page page = logRepository.findAll(((root, criteriaQuery, criteriaBuilder) -> QueryHelp.getPredicate(root, criteria, criteriaBuilder)), pageable);
        return PageUtils.toPage(page.map(logInfo -> conversionService.convert(logInfo, LogSmallDTO.class)));
    }

    /**
     * 日志为异步写的。不影响相关的业务
     *
     * @params [username, browser, ip, joinPoint, log]
     * @date 2021/3/25 23:39
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void save(String username, String browser, String ip, ProceedingJoinPoint joinPoint, Log log) {

        var signature = (MethodSignature) joinPoint.getSignature();
        var method = signature.getMethod();
        var aopLog = method.getAnnotation(OprLog.class);

        // 方法路径
        var methodName = joinPoint.getTarget().getClass().getName() + "." + signature.getName() + "()";

        // 描述
        if (log != null) {
            log.setDescription(aopLog.value());
        }
        Assert.notNull(log, "信息有误,不可为空");
        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);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void save(Log resource) {
        logRepository.save(resource);
    }

    /**
     * 根据方法和传入的参数获取请求参数.
     * 虽然尴尬,但我们通过反射只能拿到方法签名和参数列表,签名中每个参数的具体含义是不知道的
     */
    private String getParameter(Method method, Object[] args) {
        var argList = new ArrayList<>();
        var parameters = method.getParameters();
        for (int i = 0; i < parameters.length; i++) {
            //将RequestBody注解修饰的参数作为请求参数
            var requestBody = parameters[i].getAnnotation(RequestBody.class);
            if (requestBody != null) {
                argList.add(args[i]);
            }
            //将RequestParam注解修饰的参数作为请求参数
            var requestParam = parameters[i].getAnnotation(RequestParam.class);
            if (requestParam != null) {
                var map = new HashMap<>();
                var key = parameters[i].getName();
                if (!StringUtils.isEmpty(requestParam.value())) {
                    key = requestParam.value();
                }
                map.put(key, args[i]);
                argList.add(map);
            }
        }
        if (argList.isEmpty()) {
            return "";
        }
        return argList.size() == 1 ? JSONUtil.toJsonStr(argList.get(0)) : JSONUtil.toJsonStr(argList);
    }

    @Override
    @Transactional(rollbackFor = Exception.class, readOnly = true)
    public Dict findByErrDetail(Long id) {
        Log log = logRepository.findById(id).orElseGet(Log::new);
        ValidationUtils.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);
        }
        FileUtils.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");
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy