堆栈跟踪记录器

时间:2012-12-08 19:04:47

标签: java stack-trace

我需要编写一个父Java类,使用递归的类可以扩展。无论何时调用堆栈发生更改(您输入一个方法,暂时让它转到另一个方法调用,或者您正在使用该方法),父类将能够实现,然后将其打印出来。我希望它在控制台上打印,但每次都清除控制台,所以它显示堆栈horizantaly所以你可以看到每个堆栈的高度,以查看弹出的内容和弹出的内容...如果基线也打印出来已达到递归函数。

首先。如果堆栈弹出或推送元素而不手动调用它,我如何使用StackTraceElements和Thread类自动检测?

其次,我将如何进行清算?

例如,如果我有代码:

public class recursion(int i)
{ 
    private static void recursion(int i)
    {
        if(i < 10)
            System.out.println('A');
        else
        {
            recursion(i / 10 );
            System.out.println('B');
        }
    } 
    public static void main(String[] argv)
    {
        recursion(102);
    }

}

当从main()输入递归(102)时,当它从递归(102)进入递归(102/10)(递归(10))时,需要打印出堆栈。当它进入递归(10/10)时,它是递归(10)的递归(1)。当消息到达基线递归(1)时打印出消息。然后打印出函数递归(10),递归(102)和main()的反向重访的堆栈。最后打印出来我们正在退出main()。

2 个答案:

答案 0 :(得分:2)

Thread类允许管理OS线程,它与调用堆栈没有任何关系。 StackTraceElement表示堆栈框架,但您需要StackTrace才能访问它。

您正在寻找堆栈跟踪更改时间的通知,例如添加框架(输入方法)或删除框架(退出方法)。

到目前为止,此任务最合适的工具是AspectJ。它允许您定义在输入或存在其他方法时被调用的advices(一种方法)(除了其他情况)。导致建议被调用的这些触发器被称为pointcuts - 它们可以是方法入口,退出,并且可以使用通配符来描述方法:切入点MyClass.get*适用于MyClass的所有get方法。

答案 1 :(得分:0)

在看到你的答案之前,我开始写自己的。它的形式简单,但外壳是:

package stackTraceLogger;

import java.util.ArrayList;

public class StackTraceLogger 
{

static final int MAX_ROW = Integer.MAX_VALUE;
static final int MAX_COLUMN = Integer.MAX_VALUE;

static public ArrayList<ArrayList<String>> stringTrace;
//private ArrayList<ArrayList<StackTraceElement>> stack;


public StackTraceLogger()
{
     stringTrace = new ArrayList< ArrayList <String>>();
    //stack = new ArrayList<ArrayList<StackTraceElement>>();
}

static public void addStack(StackTraceElement[] inputTrace) 
{
        int size = inputTrace.length;
        // make an ArrayList with the strings of all the StrackTraceElements
        ArrayList<String> str = new  ArrayList<>(size);

        for(int i = 0; i < size; i++)
        {
            str.add(i,inputTrace[i].getMethodName());
        }   

        // Add the ArrayList to the 2D ArrayList of the stacks

}
static public void printTrace()
{

/*  if(stringTrace.get(0).size() > 0)
    {
        for(int i = 0; i < stringTrace.size(); i++)
        {
            System.out.println(stringTrace.get(i));
            for(int j = 0; j < stringTrace.get(j).size(); j++)
                System.out.println(stringTrace.get(i).get(j));
        }
    }*/
}

static private ArrayList<String> convertToArrayList(StackTraceElement[] inputTrace) 
{
    ArrayList<String> strTrace = new ArrayList<>();
    for(int j = 0; j < inputTrace.length; j++ )
        strTrace.add(inputTrace[j].getMethodName());
    return strTrace;
}
}