Java:以文本格式构建方法树并检测丢失的计时

Java:以文本格式构建方法树并检测丢失的计时,java,Java,我有一个Java类,它将为日志文件构建一个带有计时的方法树,如: TIMER: method1 - Begin ... [verbose stuff] ... TIMER: method2 - Begin ... [verbose stuff] ... TIMER: method3 - Begin ... [verbose stuff] ... TIMER: method3 - End [1ms] ... [verbose stuff] ... TIMER: method2 - End [2ms

我有一个Java类,它将为日志文件构建一个带有计时的方法树,如:

TIMER: method1 - Begin
... [verbose stuff] ...
TIMER: method2 - Begin
... [verbose stuff] ...
TIMER: method3 - Begin
... [verbose stuff] ...
TIMER: method3 - End [1ms]
... [verbose stuff] ...
TIMER: method2 - End [2ms]
... [verbose stuff] ...
TIMER: method1 - End [3ms]
输出类似于:

method1
  method2
   method3
   method3 [1ms]
  method2 [2ms]
method1 [3ms]
基本上,它从我的应用程序的计时器跟踪中构建了一个Java方法树,因此很容易可视化方法结构和计时。除了有一个方法在跟踪中丢失了Begin或End标记之外,我的方法工作得很好。这是由于应用程序中存在错误,但我仍然希望我的分析器能够正常工作。现在它构建了树,但是缩进会因为缺少标记而变得混乱(缺少结束标记很常见,而不是开始标记)

这是我所拥有的,我不确定如何检测标签是否丢失。有人能给点建议吗

while (((line = br.readLine()) != null)) {
  if (line.contains(threadString) && line.contains("TIMER")) {

    int startMethod = line.indexOf(parseString) + parseString.length();
    int endMethod = line.indexOf(" - ", startMethod);
    String method = line.substring(startMethod, endMethod);

    int startBeginEnd = line.indexOf(" -", endMethod) + 3;
    int endBeginEnd = line.indexOf(" ", startBeginEnd);
    String beginEnd = line.substring(startBeginEnd, endBeginEnd);

    if (beginEnd.equalsIgnoreCase("Begin")) {
      System.out.println(tabs + method);
      tabs = tabs + "   ";
    }
    else if (beginEnd.equalsIgnoreCase("End")) {
      tabs = tabs.substring(0, tabs.length() - 3);
      int startTime = line.indexOf("[", endBeginEnd) + 1;
      int endTime = line.indexOf("]", startTime);
      String time = line.substring(startTime, endTime);
      System.out.println(tabs + method + " [" + time + "] ms");
      previousMethod = method;
    }

  }

}
编辑:

下面是实际日志的一个示例:

2014-03-12 10:17:04,628:TIMER  :Thread-27_Agent_0: method3 - Begin                                     [system]: Class1       
2014-03-12 10:17:04,628:VERBOSE:Thread-27_Agent_0: Parameters:Code=TESTER                           [system]: Class1       
2014-03-12 10:17:04,629:TIMER  :Thread-27_Agent_0: method3 - End -  [1]                                [system]: Class1       
2014-03-12 10:17:04,629:VERBOSE:Thread-27_Agent_0: Class2- No Parameters                                [system]: Class2           
2014-03-12 10:17:04,629:VERBOSE:Thread-27_Agent_0: Parameters:::TESTER:Projectors:EACH::                   [system]: Class2           
2014-03-12 10:17:04,629:TIMER  :Thread-27_Agent_0: method1 - Begin                           [system]: Class4                 
2014-03-12 10:17:04,629:VERBOSE:Thread-27_Agent_0: Parameters::TESTER                                           [system]: Class4                 
2014-03-12 10:17:04,629:TIMER  :Thread-27_Agent_0: method1 - End -  [0]                      [system]: Class4                 
2014-03-12 10:17:04,629:TIMER  :Thread-27_Agent_0: method2 - Begin                                     [system]: Class3          
2014-03-12 10:17:04,629:TIMER  :Thread-27_Agent_0: method3 - Begin                                     [system]: Class1       
2014-03-12 10:17:04,629:VERBOSE:Thread-27_Agent_0: Parameters:                                                  [system]: Class1       
2014-03-12 10:17:04,629:VERBOSE:Thread-27_Agent_0: Parameters:blank: : :true            [system]: Class1       
2014-03-12 10:17:04,629:VERBOSE:Thread-27_Agent_0: returning rules for key [system]: Class1       
2014-03-12 10:17:04,629:TIMER  :Thread-27_Agent_0: method3 - End -  [0]                                [system]: Class1       
2014-03-12 10:17:04,629:DEBUG  :Thread-27_Agent_0: parameter is activated                                     [system]: Class3          
2014-03-12 10:17:04,630:TIMER  :Thread-27_Agent_0: method2 - End -  [1]                                [system]: Class3          
2014-03-12 10:17:04,630:TIMER  :Thread-27_Agent_0: method4 - Begin    

如果同一方法中没有相同的方法,那么使用
Map
就可以轻松解决问题

此方法:

  public static void main(String[] args) {
        Map<String, Boolean> map = new HashMap<>();
        String whatItIs;
        String[] inputs = {"method1", "method1", "method1", "method2", "method3", "method3", "method2", "method1"};
        int nested = 0;        

        for (String methodname : inputs) {
            if (map.get(methodname) == null) {
                whatItIs = "BEGIN";
                nested++;
                map.put(methodname, true);
            } else {
                whatItIs = "END";
                map.remove(methodname);
            }

            for (int i = 0; i < nested; i++) {
                System.out.print(" ");
            }

            System.out.println(methodname + whatItIs);

            if (whatItIs.equals("END")){
                nested--;
            }
        }

    }

是否缺少方法的整行,或者它在行尾仅不包含“开始”或“结束”?向我们展示一个写得不好的日志示例。我添加了一个真实的日志示例。问题主要在于,并非所有方法都有“End”标记,即使它们应该有。因此,在构建树时,缩进是不正确的。可能会有这样一种情况,即没有“Begin”标记,但这种情况不太常见。
 method1BEGIN
 method1END
 method1BEGIN
  method2BEGIN
   method3BEGIN
   method3END
  method2END
 method1END