public static void printCallstack(final Level logLevel, final String[] carePackages, final String[] exceptablePackages) {
        if (null == logLevel) {
            LOGGER.log(Level.WARN, "Requires parameter [logLevel]");

            return;
        }

        final Throwable throwable = new Throwable();
        final StackTraceElement[] stackElements = throwable.getStackTrace();

        if (null == stackElements) {
            LOGGER.log(Level.WARN, "Empty call stack");

            return;
        }

        final long tId = Thread.currentThread().getId();
        final StringBuilder stackBuilder = new StringBuilder("CallStack [tId=").append(tId).append(Strings.LINE_SEPARATOR);

        for (int i = 1; i < stackElements.length; i++) {
            final String stackElemClassName = stackElements[i].getClassName();

            if (!StringUtils.startsWithAny(stackElemClassName, carePackages)
                    || StringUtils.startsWithAny(stackElemClassName, exceptablePackages)) {
                continue;
            }

            stackBuilder.append("    [className=").append(stackElements[i].getClassName()).append(", fileName=").append(stackElements[i].getFileName()).append(", lineNumber=").append(stackElements[i].getLineNumber()).append(", methodName=").append(stackElements[i].getMethodName()).append(']').append(
                    Strings.LINE_SEPARATOR);
        }
        stackBuilder.append("], full depth [").append(stackElements.length).append("]");

        LOGGER.log(logLevel, stackBuilder.toString());
    }
public static void printCallstack ( final Level logLevel , final String [ ] carePackages , final String [ ] exceptablePackages ) { if ( null == logLevel ) { LOGGER . log ( Level . WARN , "Requires parameter [logLevel]" ) ; return ; } final Throwable throwable = new Throwable ( ) ; final StackTraceElement [ ] stackElements = throwable . getStackTrace ( ) ; if ( null == stackElements ) { LOGGER . log ( Level . WARN , "Empty call stack" ) ; return ; } final long tId = Thread . currentThread ( ) . getId ( ) ; final StringBuilder stackBuilder = new StringBuilder ( "CallStack [tId=" ) . append ( tId ) . append ( Strings . LINE_SEPARATOR ) ; for ( int i = 1 ; i < stackElements . length ; i ++ ) { final String stackElemClassName = stackElements [ i ] . getClassName ( ) ; if ( ! StringUtils . startsWithAny ( stackElemClassName , carePackages ) || StringUtils . startsWithAny ( stackElemClassName , exceptablePackages ) ) { continue ; } stackBuilder . append ( "    [className=" ) . append ( stackElements [ i ] . getClassName ( ) ) . append ( ", fileName=" ) . append ( stackElements [ i ] . getFileName ( ) ) . append ( ", lineNumber=" ) . append ( stackElements [ i ] . getLineNumber ( ) ) . append ( ", methodName=" ) . append ( stackElements [ i ] . getMethodName ( ) ) . append ( ']' ) . append ( Strings . LINE_SEPARATOR ) ; } stackBuilder . append ( "], full depth [" ) . append ( stackElements . length ) . append ( "]" ) ; LOGGER . log ( logLevel , stackBuilder . toString ( ) ) ; }
Prints call stack with the specified logging level.

@param logLevel           the specified logging level
@param carePackages       the specified packages to print, for example, ["org.b3log.latke", "org.b3log.solo"], {@code null} to care
nothing
@param exceptablePackages the specified packages to skip, for example, ["com.sun", "java.io", "org.b3log.solo.filter"],
{@code null} to skip nothing