【Java日志】

1.直接存储日志到指定文件夹

package com.example.demo.log.util;


import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;

/**
 * @ClassName: 文本记录日志
 * @Description: 1,使用子线程写入文本日志;2,添加异常日志记录
 * @Author: Wzp
 * @Date: 2022/3/21
 * @Version 1.0
 **/
public class logUtil {
    /**
     * 日志保存路径
     */
    private static String log_path = getBasePath("card");
    /**
     * 可以给日志的文件名加表示 example:card/pay
     */
    private static String log_name = "card";
    /**
     * 是否输出大控制台
     */
    private static boolean console_out = true;
    /**
     * 更新日志频率
     * yyyy-MM: 每个月更新一个log日志 yyyy-ww: 每个星期更新一个log日志 yyyy-MM-dd: 每天更新一个log日志
     * yyyy-MM-dd-a: 每天的午夜和正午更新一个log日志
     * yyyy-MM-dd-HH: 每小时更新一个log日志
     * yyyy-MM-dd-HH-mm: 每分钟更新一个log日志
     */
    private static String update_hz = "yyyy-MM-dd-HH";
    /**
     * 可以设置单个日志文件的大小 10M
     */
    private static long max_log_size = 1024 * 1024 * 10;

    public static void info(String msg) {
        runWrite(msg, log_path, log_name + "_info");
    }


    public static void debug(String msg) {
        runWrite(msg, log_path, log_name + "_debug");
    }

    public static void error(String msg) {
        runWrite(msg, log_path, log_name + "_error");
    }

    public static void exception(Exception e) {
        String errorMessage = e.getMessage() + "";
        StackTraceElement[] eArray = e.getCause().getStackTrace();
        for (int i = 0; i < eArray.length; i++) {
            String className = e.getCause().getStackTrace()[i].getClassName();
            String MethodName = e.getCause().getStackTrace()[i].getMethodName();
            int LineNumber = e.getCause().getStackTrace()[i].getLineNumber();
            errorMessage = errorMessage + "\n\t---" + className + "." + MethodName + ",\tline:" + LineNumber;
        }
        logResult(errorMessage, log_path, log_name + "_exception");
    }

    /**
     * 日志根目录
     *
     * @return
     */
    public static String getBasePath(String type) {
//        String fPath = "/Users/yz/BILogs/" + type;
//        String fPath = folder + value.name().toLowerCase() + "/{0}/" + wordsFilename + value.getSuffix();
//
//        fPath = MessageFormat.format(fPath, keyFormatService.formatFolder(value, language));
//        try {
//            FileUtil.mkdir(fPath);
//        }catch (Exception e){
//            String result = e.getMessage();
//        }
//        File file = new File(fPath);
//        //如果文件夹不存在则创建
//        if (!file.exists() && !file.isDirectory()) {
//            System.out.println("//不存在");
//            boolean result = file.mkdir();
//        } else {
//            System.out.println("//目录存在");
//        }
        String fPath = "/Users/yz/data/BILogs" + File.separator + type + File.separator;
//        fPath = fPath + ;
//        fPath = fPath + type + ;
        return fPath;
    }

    /**
     * 写日志
     *
     * @param sWord 要写入日志里的文本内容
     */
    public static void logResult(String sWord) {
        runWrite(sWord, log_path, log_name);
    }

    public static void logResult(String sWord, String logPath, String logName) {
        FileWriter writer = null;
        try {
            File dir = new File(logPath);
            if (!dir.exists()) {
                dir.mkdirs();
            }
            String dt = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS").format(new Date());
            File f = new File(logPath + logName + "_" + new SimpleDateFormat(update_hz).format(new Date()) + ".txt");
            if (!f.exists()) {
                f.createNewFile();
                sWord = "AllMing 日志\r\n" + "[" + dt + "]\t" + sWord;
            } else {
                long logSize = f.length();
                // 文件大小超过10M,备份
                if (logSize >= max_log_size) {
                    String backLogName = logPath + logName
                            + new SimpleDateFormat("_yyyy-MM-dd.HHmmss.SSS").format(new Date()) + ".txt";
                    f.renameTo(new File(backLogName));
                }
            }
            writer = new FileWriter(f, true);
            writer.write("[" + dt + "]\t" + sWord + "\r\n");
            if (console_out) {
                System.out.println("[" + dt + "]\t" + sWord);
            }
        } catch (Exception e) {
            System.out.println("记录日志异常:" + e.toString());
            e.printStackTrace();
        } finally {
            if (writer != null) {
                try {
                    writer.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }


    public static void runWrite(final String sWord,final String logPath,final String logName) {
        new Thread() {
            public void run() {
                logResult(sWord, logPath, logName);
            }
        }.start();;
    }

    public static void main(String[] args) {
//        getBasePath("card");
        for (int i = 0; i <1000; i++) {
            info("demo"+i);
        }
//        String fPath = "/Users/yz/BILogs/card";
//        File file = new File(fPath);
//        judeDirExists(file);
    }

    public static void judeDirExists(File file) {

        if (file.exists()) {
            if (file.isDirectory()) {
                System.out.println("dir exists");
            } else {
                System.out.println("the same name file exists, can not create dir");
            }
        } else {
            System.out.println("dir not exists, create it ...");
            file.mkdir();
        }

    }
}

2.利用切面获取日志并存储到指定位置

package com.aig.payout.log.aspect;

import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;

/**
 * @ClassName:
 * @Description: 日志内容
 * @Author: Wzp
 * @Date: 2022/3/28
 * @Version 1.0
 **/
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class BiOperationLog {
    // ip
    private String ip;
    // url
    private String url;
    // http方法 GET POST PUT DELETE PATCH
    private String httpMethod;
    // 请求参数
    private Object requestParams;
    // 返回参数
    private Object result;
    // 接口耗时
    private Long timeCost;
    /**
     * 事件类型
     */
    private String eventType;
    /**
     * 返回内容
     */
    private Object contentInfo;
}

package com.aig.payout.log.annotation;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

/**
 * @ClassName:
 * @Description:
 * @Author: Wzp
 * @Date: 2022/3/28
 * @Version 1.0
 **/
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface BiOperationLogFlag {
    /**
     * 事件名
     * @return
     */
    String eventName() default "" ;
}

package com.aig.payout.log.aspect;

import cn.hutool.core.util.ArrayUtil;
import cn.hutool.json.JSONUtil;
import com.aig.payout.common.enums.CardEventEnum;
import com.aig.payout.common.utils.BiLogUtil;
import com.aig.payout.common.utils.BiLogVo;
import com.aig.payout.common.utils.IPUtil;
import com.aig.payout.log.annotation.BiOperationLogFlag;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.*;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.Method;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.*;

/**
 * @ClassName:
 * @Description: bi日志切面
 * @Author: Wzp
 * @Date: 2022/3/28
 * @Version 1.0
 **/
@Aspect
@Component
@Slf4j
public class BiOperationLogAspect {

    private static final String UNKNOWN = "unknown";

    @Pointcut("@annotation(com.aig.payout.log.annotation.BiOperationLogFlag)")
    public void biLog() {
    }
    @Autowired
    private BiLogUtil biLogUtil;
    /**
     * 环绕操作
     *
     * @param point 切入点
     * @return 原方法返回值
     * @throws Throwable 异常信息
     */
    @Around("biLog()")
    public Object aroundLog(ProceedingJoinPoint point) throws Throwable {

        ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        HttpServletRequest request = Objects.requireNonNull(attributes).getRequest();

        // 解决ip的问题(无请求的时候)否则可以直接利用getIp(request)
        String ip = IPUtil.getIpAdd();
        // 打印请求相关参数
        long startTime = System.currentTimeMillis();
        Object result = point.proceed();

        final BiOperationLog operationLog = BiOperationLog.builder()
                .ip(ip)
                .url(request.getRequestURL().toString())
                .httpMethod(request.getMethod())
                .requestParams(getNameAndValue(point))
                .result(result)
                .eventType(getControllerMethodEvent(point))
                .contentInfo(result)
                .timeCost(System.currentTimeMillis() - startTime)
                .build();
        setBiLog(operationLog);
        log.info("Request Log Info : {}", JSONUtil.toJsonStr(operationLog));
        return result;
    }

    /**
     * bi 日志信息
     * @param operationLog  响应对象内容
     */
    private void setBiLog(BiOperationLog operationLog) {
        log.info("打印BI日志响应内容是:{}",operationLog);
        BiLogVo biLogVo = new BiLogVo();
        biLogVo.setClientIp(operationLog.getIp());
        biLogVo.setEventType(CardEventEnum.getEventByMethod(operationLog.getEventType()));
        biLogVo.setContent(operationLog.getContentInfo());
        biLogUtil.info(biLogVo, "card");
    }

    private Map<String, Object> getNameAndValue(ProceedingJoinPoint joinPoint) {
        final Signature signature = joinPoint.getSignature();
        MethodSignature methodSignature = (MethodSignature) signature;
        final String[] names = methodSignature.getParameterNames();
        final Object[] args = joinPoint.getArgs();

        if (ArrayUtil.isEmpty(names) || ArrayUtil.isEmpty(args)) {
            return Collections.emptyMap();
        }
        if (names.length != args.length) {
            log.warn("{}方法参数名和参数值数量不一致", methodSignature.getName());
            return Collections.emptyMap();
        }
        Map<String, Object> map = new HashMap<>();
        for (int i = 0; i < names.length; i++) {
            map.put(names[i], args[i]);
        }
        return map;
    }

    /**
     * 获取ip
     * @param request
     * @return
     */
    public static String getIp(HttpServletRequest request) {
        String ip = request.getHeader("x-forwarded-for");
        if (ip == null || ip.length() == 0 || UNKNOWN.equalsIgnoreCase(ip)) {
            ip = request.getHeader("Proxy-Client-IP");
        }
        if (ip == null || ip.length() == 0 || UNKNOWN.equalsIgnoreCase(ip)) {
            ip = request.getHeader("WL-Proxy-Client-IP");
        }
        if (ip == null || ip.length() == 0 || UNKNOWN.equalsIgnoreCase(ip)) {
            ip = request.getRemoteAddr();
        }
        String comma = ",";
        String localhost = "127.0.0.1";
        if (ip.contains(comma)) {
            ip = ip.split(",")[0];
        }
        if (localhost.equals(ip)) {
            // 获取本机真正的ip地址
            try {
                ip = InetAddress.getLocalHost().getHostAddress();
            } catch (UnknownHostException e) {
                log.error(e.getMessage(), e);
            }
        }
        return ip;
    }

    /**
     * 获取对应的事件名
     * @param point
     * @return
     * @throws Exception
     */
    public static String getControllerMethodEvent(JoinPoint point) throws Exception {
        // 获取连接点目标类名
        String targetName = point.getTarget().getClass().getName();
        // 获取连接点签名的方法名
        String methodName = point.getSignature().getName();
        //获取连接点参数
        Object[] args = point.getArgs();
        //根据连接点类的名字获取指定类
        Class targetClass = Class.forName(targetName);
        //获取类里面的方法
        Method[] methods = targetClass.getMethods();
        String eventName = "";
        for (Method method : methods) {
            if (method.getName().equals(methodName)) {
                Class[] clazzs = method.getParameterTypes();
                if (clazzs.length == args.length) {
                    eventName = method.getAnnotation(BiOperationLogFlag.class).eventName();
                    break;
                }
            }
        }
        return eventName;
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值