日志埋点-初级工具类
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?
自省推动进步,视野决定未来。
心怀远大理想。
为了家庭幸福而努力。
商业合作请看此处:https://www.magicube.ai
心怀远大理想。
为了家庭幸福而努力。
商业合作请看此处:https://www.magicube.ai