日志埋点-初级工具类

import lombok.extern.slf4j.Slf4j;
import org.springframework.util.StringUtils;

import java.util.ArrayList;
import java.util.List;
import java.util.Stack;
import java.util.stream.Collectors;

@Slf4j
public class JournalUtil {

    public static void debug(String msg) {
        String prefix=getParentCallerClassMethod(Thread.currentThread().getStackTrace());
        if(!StringUtils.isEmpty(JournalHolder.getStickyLog()))
            msg="["+JournalHolder.getStickyLog()+"]"+msg;
        log.debug("["+prefix+"]"+msg);
    }

    public static void debug(String format, Object... arguments) {
        String prefix=getParentCallerClassMethod(Thread.currentThread().getStackTrace());

        String format_1="[{}]";
        String format_2="";
        if(!StringUtils.isEmpty(JournalHolder.getStickyLog()))
            format_2="["+JournalHolder.getStickyLog()+"]";

        format=format_1+format_2+format;

        List<Object> objs=new ArrayList<>();
        objs.add(prefix);
        if(arguments!=null)
        {
            for(Object obj:arguments)
            {
                objs.add(obj);
            }
        }

        log.debug(format, objs.toArray(arguments));
    }





    public static void info(String msg) {
        String prefix=getParentCallerClassMethod(Thread.currentThread().getStackTrace());
        if(!StringUtils.isEmpty(JournalHolder.getStickyLog()))
            msg="["+JournalHolder.getStickyLog()+"]"+msg;
        log.info("["+prefix+"]"+msg);
    }

    public static void info(String format, Object... arguments) {
        String prefix=getParentCallerClassMethod(Thread.currentThread().getStackTrace());

        String format_1="[{}]";
        String format_2="";
        if(!StringUtils.isEmpty(JournalHolder.getStickyLog()))
            format_2="["+JournalHolder.getStickyLog()+"]";

        format=format_1+format_2+format;

        List<Object> objs=new ArrayList<>();
        objs.add(prefix);
        if(arguments!=null)
        {
            for(Object obj:arguments)
            {
                objs.add(obj);
            }
        }

        log.info(format, objs.toArray(arguments));
    }







    public static void warn(String msg) {
        String prefix=getParentCallerClassMethod(Thread.currentThread().getStackTrace());
        if(!StringUtils.isEmpty(JournalHolder.getStickyLog()))
            msg="["+JournalHolder.getStickyLog()+"]"+msg;
        log.warn("["+prefix+"]"+msg);
    }

    public static void warn(String format, Object... arguments) {
        String prefix=getParentCallerClassMethod(Thread.currentThread().getStackTrace());

        String format_1="[{}]";
        String format_2="";
        if(!StringUtils.isEmpty(JournalHolder.getStickyLog()))
            format_2="["+JournalHolder.getStickyLog()+"]";

        format=format_1+format_2+format;

        List<Object> objs=new ArrayList<>();
        objs.add(prefix);
        if(arguments!=null)
        {
            for(Object obj:arguments)
            {
                objs.add(obj);
            }
        }

        log.warn(format, objs.toArray(arguments));
    }







    public static void error(String msg) {
        String prefix=getParentCallerClassMethod(Thread.currentThread().getStackTrace());
        if(!StringUtils.isEmpty(JournalHolder.getStickyLog()))
            msg="["+JournalHolder.getStickyLog()+"]"+msg;
        log.error("["+prefix+"]"+msg);
    }

    public static void error(String format, Object... arguments) {
        String prefix=getParentCallerClassMethod(Thread.currentThread().getStackTrace());

        String format_1="[{}]";
        String format_2="";
        if(!StringUtils.isEmpty(JournalHolder.getStickyLog()))
            format_2="["+JournalHolder.getStickyLog()+"]";

        format=format_1+format_2+format;

        List<Object> objs=new ArrayList<>();
        objs.add(prefix);
        if(arguments!=null)
        {
            for(Object obj:arguments)
            {
                objs.add(obj);
            }
        }

        log.error(format, objs.toArray(arguments));
    }





    public static void throwException(RuntimeException exception) {
        info(exception.getMessage());
        throw exception;
    }

    public static void throwException(RuntimeException exception, String msg) {
        info(msg);
        throw exception;
    }

    public static void throwException(RuntimeException exception, String format, Object... arguments) {
        info(format, arguments);
        throw exception;
    }



    private static String getParentCallerClassMethod(StackTraceElement[] stackTrace)
    {
        if(stackTrace==null)
            return "STACK EMPTY";

        StackTraceElement foundElement=null;
        for(StackTraceElement element:stackTrace)
        {
            if(needIgnoreElement(element))
            {
                continue;
            }
            foundElement=element;
        }

        if(foundElement==null)
            return "STACK NOT FOUND";

        return foundElement.getClassName()+" "+foundElement.getMethodName()+ " "+foundElement.getLineNumber();
    }

    private static boolean needIgnoreElement(StackTraceElement element) {
        if(element.getClassName().equals("java.lang.Thread")&&element.getMethodName().equals("getStackTrace"))
            return true;

        if(element.getClassName().equals(JournalUtil.class.getName()))
            return true;

        return false;
    }

    public static void tag(String stickylog) {
        JournalHolder.setStickyLog(stickylog);
    }

    public static void unTag() {
        JournalHolder.popStickyLog();
    }

    public static void resetTag()
    {
        JournalHolder.resetStickyLog();
    }

    public static class JournalHolder
    {
        private static ThreadLocal<Stack<String>> logLocal =  new  ThreadLocal<Stack<String>>();
        public static void setStickyLog(String stickyLog)
        {
            Stack<String> oldStack=logLocal.get();
            if(oldStack==null)
            {
                oldStack=new Stack<>();
            }
            oldStack.push(stickyLog);
            logLocal.set(oldStack);
        }

        public static String getStickyLog()
        {
            Stack<String> oldStack=logLocal.get();
            if(oldStack==null)
            {
                oldStack=new Stack<>();
            }
            List<String> msgs=oldStack.stream().collect(Collectors.toList());
            StringBuilder fullMsg=new StringBuilder();
            for(String msg:msgs)
            {
                fullMsg.append(msg);
            }
            return fullMsg.toString();
        }

        public static void popStickyLog()
        {
            Stack<String> oldStack=logLocal.get();
            if(oldStack==null)
            {
                oldStack=new Stack<>();
            }
            if(!oldStack.empty())
                oldStack.pop();
        }

        public static void resetStickyLog()
        {
            logLocal.remove();
        }
    }
}

  

用法:

public static void main(String[] args) {

        StopWatch stopWatch=new StopWatch();
        stopWatch.start();
        for(int i=0;i<10;i++) {
            JournalUtil.resetTag();
            JournalUtil.info("main中直接写日志");
            test1();
            JournalUtil.tag("保持住");
            test2();
            JournalUtil.unTag();
            test2();
        }
        stopWatch.stop();
        System.out.println("共耗时:"+stopWatch.getTotalTimeSeconds()+"秒");

        try {
            JournalUtil.throwException(new RuntimeException("some exception"));
        }
        catch (Exception ex)
        {
//            System.out.println("ex1 occurred");
        }


        try {
            JournalUtil.throwException(new RuntimeException("some exception"), "log msg");
        }
        catch (Exception ex)
        {
//            System.out.println("ex2 occurred");
        }

        try {
            JournalUtil.throwException(new RuntimeException("some exception"), "log msg{}aa{}a", 666, "111");
        }
        catch (Exception ex)
        {
//            System.out.println("ex3 occurred");
        }

        JournalUtil.debug("OK");
        JournalUtil.warn("OK{}?", 100.265);
    }

    private static void test1()
    {
        test2();
    }

    private static void test2()
    {
        JournalUtil.tag("内部再保持住");

        JournalUtil.info("这是个测试日志");
        JournalUtil.info("这是个测试日志{}这是第二段日志", 100);

        JournalUtil.unTag();
    }

  

2021-05-01 13:21:56.231  INFO   --- [           main] [PaymentRefundJob main 40]main中直接写日志
2021-05-01 13:21:56.237  INFO   --- [           main] [PaymentRefundJob main 41][内部再保持住]这是个测试日志
2021-05-01 13:21:56.237  INFO   --- [           main] [PaymentRefundJob main 41][内部再保持住]这是个测试日志100这是第二段日志
2021-05-01 13:21:56.240  INFO   --- [           main] [PaymentRefundJob main 43][保持住内部再保持住]这是个测试日志
2021-05-01 13:21:56.240  INFO   --- [           main] [PaymentRefundJob main 43][保持住内部再保持住]这是个测试日志100这是第二段日志
2021-05-01 13:21:56.240  INFO   --- [           main] [PaymentRefundJob main 45][内部再保持住]这是个测试日志
2021-05-01 13:21:56.241  INFO   --- [           main] [PaymentRefundJob main 45][内部再保持住]这是个测试日志100这是第二段日志
2021-05-01 13:21:56.241  INFO   --- [           main] [PaymentRefundJob main 40]main中直接写日志
2021-05-01 13:21:56.241  INFO   --- [           main] [PaymentRefundJob main 41][内部再保持住]这是个测试日志
2021-05-01 13:21:56.241  INFO   --- [           main] [PaymentRefundJob main 41][内部再保持住]这是个测试日志100这是第二段日志
2021-05-01 13:21:56.241  INFO   --- [           main] [PaymentRefundJob main 43][保持住内部再保持住]这是个测试日志
2021-05-01 13:21:56.241  INFO   --- [           main] [PaymentRefundJob main 43][保持住内部再保持住]这是个测试日志100这是第二段日志
2021-05-01 13:21:56.241  INFO   --- [           main] [PaymentRefundJob main 45][内部再保持住]这是个测试日志
2021-05-01 13:21:56.242  INFO   --- [           main] [PaymentRefundJob main 45][内部再保持住]这是个测试日志100这是第二段日志
2021-05-01 13:21:56.242  INFO   --- [           main] [PaymentRefundJob main 40]main中直接写日志
2021-05-01 13:21:56.242  INFO   --- [           main] [PaymentRefundJob main 41][内部再保持住]这是个测试日志
2021-05-01 13:21:56.242  INFO   --- [           main] [PaymentRefundJob main 41][内部再保持住]这是个测试日志100这是第二段日志
2021-05-01 13:21:56.243  INFO   --- [           main] [PaymentRefundJob main 43][保持住内部再保持住]这是个测试日志
2021-05-01 13:21:56.243  INFO   --- [           main] [PaymentRefundJob main 43][保持住内部再保持住]这是个测试日志100这是第二段日志
2021-05-01 13:21:56.243  INFO   --- [           main] [PaymentRefundJob main 45][内部再保持住]这是个测试日志
2021-05-01 13:21:56.243  INFO   --- [           main] [PaymentRefundJob main 45][内部再保持住]这是个测试日志100这是第二段日志
2021-05-01 13:21:56.243  INFO   --- [           main] [PaymentRefundJob main 40]main中直接写日志
2021-05-01 13:21:56.243  INFO   --- [           main] [PaymentRefundJob main 41][内部再保持住]这是个测试日志
2021-05-01 13:21:56.243  INFO   --- [           main] [PaymentRefundJob main 41][内部再保持住]这是个测试日志100这是第二段日志
2021-05-01 13:21:56.243  INFO   --- [           main] [PaymentRefundJob main 43][保持住内部再保持住]这是个测试日志
2021-05-01 13:21:56.244  INFO   --- [           main] [PaymentRefundJob main 43][保持住内部再保持住]这是个测试日志100这是第二段日志
2021-05-01 13:21:56.244  INFO   --- [           main] [PaymentRefundJob main 45][内部再保持住]这是个测试日志
2021-05-01 13:21:56.244  INFO   --- [           main] [PaymentRefundJob main 45][内部再保持住]这是个测试日志100这是第二段日志
2021-05-01 13:21:56.244  INFO   --- [           main] [PaymentRefundJob main 40]main中直接写日志
2021-05-01 13:21:56.244  INFO   --- [           main] [PaymentRefundJob main 41][内部再保持住]这是个测试日志
2021-05-01 13:21:56.244  INFO   --- [           main] [PaymentRefundJob main 41][内部再保持住]这是个测试日志100这是第二段日志
2021-05-01 13:21:56.244  INFO   --- [           main] [PaymentRefundJob main 43][保持住内部再保持住]这是个测试日志
2021-05-01 13:21:56.245  INFO   --- [           main] [PaymentRefundJob main 43][保持住内部再保持住]这是个测试日志100这是第二段日志
2021-05-01 13:21:56.245  INFO   --- [           main] [PaymentRefundJob main 45][内部再保持住]这是个测试日志
2021-05-01 13:21:56.246  INFO   --- [           main] [PaymentRefundJob main 45][内部再保持住]这是个测试日志100这是第二段日志
2021-05-01 13:21:56.247  INFO   --- [           main] [PaymentRefundJob main 40]main中直接写日志
2021-05-01 13:21:56.247  INFO   --- [           main] [PaymentRefundJob main 41][内部再保持住]这是个测试日志
2021-05-01 13:21:56.247  INFO   --- [           main] [PaymentRefundJob main 41][内部再保持住]这是个测试日志100这是第二段日志
2021-05-01 13:21:56.247  INFO   --- [           main] [PaymentRefundJob main 43][保持住内部再保持住]这是个测试日志
2021-05-01 13:21:56.247  INFO   --- [           main] [PaymentRefundJob main 43][保持住内部再保持住]这是个测试日志100这是第二段日志
2021-05-01 13:21:56.247  INFO   --- [           main] [PaymentRefundJob main 45][内部再保持住]这是个测试日志
2021-05-01 13:21:56.247  INFO   --- [           main] [PaymentRefundJob main 45][内部再保持住]这是个测试日志100这是第二段日志
2021-05-01 13:21:56.248  INFO   --- [           main] [PaymentRefundJob main 40]main中直接写日志
2021-05-01 13:21:56.248  INFO   --- [           main] [PaymentRefundJob main 41][内部再保持住]这是个测试日志
2021-05-01 13:21:56.248  INFO   --- [           main] [PaymentRefundJob main 41][内部再保持住]这是个测试日志100这是第二段日志
2021-05-01 13:21:56.249  INFO   --- [           main] [PaymentRefundJob main 43][保持住内部再保持住]这是个测试日志
2021-05-01 13:21:56.249  INFO   --- [           main] [PaymentRefundJob main 43][保持住内部再保持住]这是个测试日志100这是第二段日志
2021-05-01 13:21:56.249  INFO   --- [           main] [PaymentRefundJob main 45][内部再保持住]这是个测试日志
2021-05-01 13:21:56.249  INFO   --- [           main] [PaymentRefundJob main 45][内部再保持住]这是个测试日志100这是第二段日志
2021-05-01 13:21:56.249  INFO   --- [           main] [PaymentRefundJob main 40]main中直接写日志
2021-05-01 13:21:56.249  INFO   --- [           main] [PaymentRefundJob main 41][内部再保持住]这是个测试日志
2021-05-01 13:21:56.250  INFO   --- [           main] [PaymentRefundJob main 41][内部再保持住]这是个测试日志100这是第二段日志
2021-05-01 13:21:56.250  INFO   --- [           main] [PaymentRefundJob main 43][保持住内部再保持住]这是个测试日志
2021-05-01 13:21:56.250  INFO   --- [           main] [PaymentRefundJob main 43][保持住内部再保持住]这是个测试日志100这是第二段日志
2021-05-01 13:21:56.250  INFO   --- [           main] [PaymentRefundJob main 45][内部再保持住]这是个测试日志
2021-05-01 13:21:56.250  INFO   --- [           main] [PaymentRefundJob main 45][内部再保持住]这是个测试日志100这是第二段日志
2021-05-01 13:21:56.251  INFO   --- [           main] [PaymentRefundJob main 40]main中直接写日志
2021-05-01 13:21:56.251  INFO   --- [           main] [PaymentRefundJob main 41][内部再保持住]这是个测试日志
2021-05-01 13:21:56.251  INFO   --- [           main] [PaymentRefundJob main 41][内部再保持住]这是个测试日志100这是第二段日志
2021-05-01 13:21:56.251  INFO   --- [           main] [PaymentRefundJob main 43][保持住内部再保持住]这是个测试日志
2021-05-01 13:21:56.251  INFO   --- [           main] [PaymentRefundJob main 43][保持住内部再保持住]这是个测试日志100这是第二段日志
2021-05-01 13:21:56.251  INFO   --- [           main] [PaymentRefundJob main 45][内部再保持住]这是个测试日志
2021-05-01 13:21:56.252  INFO   --- [           main] [PaymentRefundJob main 45][内部再保持住]这是个测试日志100这是第二段日志
2021-05-01 13:21:56.252  INFO   --- [           main] [PaymentRefundJob main 40]main中直接写日志
2021-05-01 13:21:56.253  INFO   --- [           main] [PaymentRefundJob main 41][内部再保持住]这是个测试日志
2021-05-01 13:21:56.253  INFO   --- [           main] [PaymentRefundJob main 41][内部再保持住]这是个测试日志100这是第二段日志
2021-05-01 13:21:56.254  INFO   --- [           main] [PaymentRefundJob main 43][保持住内部再保持住]这是个测试日志
2021-05-01 13:21:56.254  INFO   --- [           main] [PaymentRefundJob main 43][保持住内部再保持住]这是个测试日志100这是第二段日志
2021-05-01 13:21:56.254  INFO   --- [           main] [PaymentRefundJob main 45][内部再保持住]这是个测试日志
2021-05-01 13:21:56.254  INFO   --- [           main] [PaymentRefundJob main 45][内部再保持住]这是个测试日志100这是第二段日志
共耗时:0.073秒
2021-05-01 13:21:56.259  INFO   --- [           main] [PaymentRefundJob main 52][末尾逻辑处理中]some exception
2021-05-01 13:21:56.259  INFO   --- [           main] [PaymentRefundJob main 61][末尾逻辑处理中]log msg
2021-05-01 13:21:56.259  INFO   --- [           main] [PaymentRefundJob main 69][末尾逻辑处理中]log msg666aa111a
2021-05-01 13:21:56.259  WARN   --- [           main] [PaymentRefundJob main 77][末尾逻辑处理中]OK100.265

 

posted @ 2021-05-01 13:25  McKay  阅读(347)  评论(0编辑  收藏  举报