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

com.github.azbh111.utils.java.stack.StackTraceManager Maven / Gradle / Ivy

The newest version!
package com.github.azbh111.utils.java.stack;

import com.github.azbh111.utils.java.stack.model.StackTraceInfo;
import lombok.Builder;
import lombok.Getter;
import lombok.ToString;

import java.util.*;
import java.util.concurrent.ConcurrentHashMap;

/**
 *
 * @author pyz
 * @date 2019/1/16 11:47 AM
 */
public class StackTraceManager {
    /**
     * 前缀匹配项目包
     */
    @Getter
    private final Set packagePrefixs = new HashSet<>();
    /**
     * 前缀排除包
     */
    @Getter
    private final Set packageExecludes = new HashSet<>();
    /**
     * 缓存项目包,加快判断速度
     */
    private final Map projectStackTraceCache = new ConcurrentHashMap<>();

    @Getter
    private static final StackTraceManager instance = new StackTraceManager();

    {
//        quartz
        packagePrefixs.add("org.quartz.");
//      排除jdk包和连接池包
        packageExecludes.add("java.");
        packageExecludes.add("javax.");
        packageExecludes.add("sun.");
        packageExecludes.add("com.alibaba.druid.");
        packageExecludes.add("com.github.azbh111.");
    }

    public StackTraceInfo getStackTraceInfo() {
        StackTraceElement[] stackTraces = Thread.currentThread().getStackTrace();
        int length = stackTraces.length;
        LoggerStackTraceElement preStackTrace = null;
        LoggerStackTraceElement currentStackTrace = null;
        StackTraceElement stackTrace;
        StackTraceInfo info = new StackTraceInfo();
        for (int i = 0; i < length; i++) {
            stackTrace = stackTraces[i];
            preStackTrace = currentStackTrace;
            currentStackTrace = toLoggerStackTrace(stackTrace);

            if (!currentStackTrace.isProxy() && currentStackTrace.isProjectClass()) {
                if (preStackTrace != null) {
                    info.setInvokeMethodName(stackTraces[i - 1].getMethodName());
                }
                info.setMethodName(stackTraces[i].getMethodName());
                info.setFileName(currentStackTrace.getFileName());
                info.setLineNumer(stackTrace.getLineNumber());
                return info;
            }
        }
        return info;
    }

    private LoggerStackTraceElement toLoggerStackTrace(StackTraceElement element) {
        LoggerStackTraceElement loggerStackTraceElement = projectStackTraceCache.get(element.getClassName());
        if (loggerStackTraceElement == null) {
            loggerStackTraceElement = parse(element);
            projectStackTraceCache.put(element.getClassName(), loggerStackTraceElement);
        }
        return loggerStackTraceElement;
    }

    private boolean isProjectStackTrace(StackTraceElement element) {
        String className = element.getClassName();
        for (String prefix : packagePrefixs) {
            A:
            if (className.startsWith(prefix)) {
                for (String execlude : packageExecludes) {
                    if (className.startsWith(execlude)) {
                        break A;
                    }
                }
                return true;
            }
        }
        return false;
    }

    private LoggerStackTraceElement parse(StackTraceElement element) {
        return LoggerStackTraceElement.builder()
                .proxy(element.getClassName().contains("$$") || element.getClassName().startsWith("com.sun.proxy.$Proxy"))
                .fileName(trimJavaSuffix(element.getFileName()))
                .projectClass(isProjectStackTrace(element))
                .build();
    }

    private String trimJavaSuffix(String fileName) {
        if (fileName == null) {
            return "";
        }
        return fileName.endsWith(".java") ? fileName.substring(0, fileName.length() - 5) : fileName;
    }

    @Getter
    @Builder
    @ToString
    private static class LoggerStackTraceElement {
        /**
         * 是否是代理类
         */
        private boolean proxy;
        /**
         * 是否是项目类
         */
        private boolean projectClass;
        private String fileName;
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy