Package org.gridkit.jvmtool.cmd

Source Code of org.gridkit.jvmtool.cmd.StackSampleAnalyzerCmd$SSA$HistoCmd

/**
* Copyright 2014 Alexey Ragozin
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
*     http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.gridkit.jvmtool.cmd;

import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import org.gridkit.jvmtool.Cascade;
import org.gridkit.jvmtool.SJK;
import org.gridkit.jvmtool.SJK.CmdRef;
import org.gridkit.jvmtool.StackHisto;
import org.gridkit.jvmtool.StackTraceClassifier;
import org.gridkit.jvmtool.StackTraceClassifier.Config;
import org.gridkit.jvmtool.StackTraceCodec;
import org.gridkit.jvmtool.StackTraceReader;
import org.gridkit.util.formating.Formats;

import com.beust.jcommander.Parameter;
import com.beust.jcommander.Parameters;
import com.beust.jcommander.ParametersDelegate;

public class StackSampleAnalyzerCmd implements CmdRef {

  @Override
  public String getCommandName() {
    return "ssa";
  }

  @Override
  public Runnable newCommand(SJK host) {
    return new SSA(host);
  }

  @Parameters(commandDescription = "Analyzing stack trace dumps")
  public static class SSA implements Runnable {
   
    @SuppressWarnings("unused")
    @ParametersDelegate
    private SJK host;
   
    @Parameter(names={"-f", "--file"}, required = true, variableArity=true, description="Path to stack dump file")
    private List<String> files;
   
    @Parameter(names={"-c", "--classifier"}, required = false, description="Path to file with stack trace classification definition")
    private String classifier = null;

        @Parameter(names = { "-b", "--buckets" }, required = false, description = "Restrict analysis to specific class")
        private String bucket = null;

        @Parameter(names={"-sf", "--simple-filter"}, required = false, description="Process only traces containing this string")
        private String simpleFilter = null;

       
        private List<SsaCmd> allCommands = new ArrayList<SsaCmd>();

        @SuppressWarnings("unused")
        @ParametersDelegate
    private SsaCmd print = new PrintCmd();

    @SuppressWarnings("unused")
        @ParametersDelegate
    private SsaCmd histo = new HistoCmd();

    @SuppressWarnings("unused")
        @ParametersDelegate
    private SsaCmd csummary = new ClassSummaryCmd();

    StackTraceClassifier buckets;


    public SSA(SJK host) {
      this.host = host;
    }

    @Override
    public void run() {
      try {
        List<Runnable> action = new ArrayList<Runnable>();
        for(SsaCmd cmd: allCommands) {
            if (cmd.isSelected()) {
                action.add(cmd);
            }
        }
        if (action.isEmpty() || action.size() > 1) {
          SJK.failAndPrintUsage("You should choose one of " + allCommands);
        }
        if (classifier != null) {
            Config cfg = new Config();
            Cascade.parse(new FileReader(classifier), cfg);
            buckets = cfg.create();
        }
        if (classifier == null  && bucket != null) {
            SJK.failAndPrintUsage("--bucket option requires --classifer");
        }
        action.get(0).run();
      } catch (Exception e) {
        SJK.fail(e.toString());
      }
    }

    StackTraceReader getFilteredReader() throws IOException {
        if (classifier == null ) {
            if (simpleFilter == null) {
                return getUnclassifiedReader();
            }
            else {
                final StackTraceReader unclassified = getUnclassifiedReader();
                return new StackTraceReader() {
                       
                        @Override
                        public boolean loadNext() throws IOException {
                            while(unclassified.loadNext()) {
                                StackTraceElement[] trace = getTrace();
                                for(StackTraceElement e: trace) {
                                    if (e.toString().startsWith(simpleFilter)) {
                                        return true;
                                    }
                                }
                            }
                            return false;
                        }
                       
                        @Override
                        public boolean isLoaded() {
                            return unclassified.isLoaded();
                        }
                       
                        @Override
                        public StackTraceElement[] getTrace() {
                            return unclassified.getTrace();
                        }
                       
                        @Override
                        public long getTimestamp() {
                            return unclassified.getTimestamp();
                        }
                       
                        @Override
                        public long getThreadId() {
                            return unclassified.getThreadId();
                        }
                    };
            }
        }
        else {
            if (simpleFilter != null) {
                SJK.fail("Simple filter cannot be used with classification");
            }           
            if (bucket != null && !buckets.getClasses().contains(bucket)) {
                SJK.fail("Bucket [" + bucket + "] is not defined");
            }
            final StackTraceReader unfiltered = getUnclassifiedReader();
            return new StackTraceReader() {

                    @Override
                    public boolean loadNext() throws IOException {
                        while(true) {
                            if (unfiltered.loadNext()) {
                                String cl = buckets.classify(unfiltered.getTrace());
                                if (bucket != null) {
                                    if (!bucket.equals(cl)) {
                                        continue;
                                    }
                                }
                                else if (cl == null) {
                                    continue;
                                }
                                return true;
                            }
                            else {
                                return false;
                            }
                        }
                    }

                    @Override
                    public boolean isLoaded() {
                        return unfiltered.isLoaded();
                    }

                    @Override
                    public StackTraceElement[] getTrace() {
                        return unfiltered.getTrace();
                    }

                    @Override
                    public long getTimestamp() {
                        return unfiltered.getTimestamp();
                    }

                    @Override
                    public long getThreadId() {
                        return unfiltered.getThreadId();
                    }
                };
        }
    }

    StackTraceReader getUnclassifiedReader() throws IOException {
        return StackTraceCodec.newReader(files.toArray(new String[0]));
    }

    abstract class SsaCmd implements Runnable {
       
        public SsaCmd() {
                allCommands.add(this);
            }

        public abstract boolean isSelected();
    }
   
    class PrintCmd extends SsaCmd {

      @Parameter(names={"--print"}, description="Print traces from file")
      boolean run;

      @Override
            public boolean isSelected() {
                return run;
            }

            @Override
      public void run() {
        try {
           
              StackTraceReader reader = getFilteredReader();
              while(reader.loadNext()) {
                  String timestamp = Formats.toDatestamp(reader.getTimestamp());
                  System.out.println(String.format("Thread [%d] at %s", reader.getThreadId(), timestamp));
                  StackTraceElement[] trace = reader.getTrace();
                  for(int i = 0; i != trace.length; ++i) {
                      System.out.println(trace[i]);
                  }
                  System.out.println();
              }
           
        } catch (Exception e) {
          e.printStackTrace();
          SJK.fail();
        }
      }
           
            public String toString() {
                return "--print";
            }
    }

        class HistoCmd extends SsaCmd {

            @Parameter(names={"--histo"}, description="Print frame histogram")
            boolean run;

            @Override
            public boolean isSelected() {
                return run;
            }

            @Override
            public void run() {
                try {

                    StackHisto histo = new StackHisto();
                   
                    StackTraceReader reader = getFilteredReader();
                    while(reader.loadNext()) {
                        StackTraceElement[] trace = reader.getTrace();
                        histo.feed(trace);
                    }
                   
                    System.out.println(histo.formatHisto());
                   
                } catch (Exception e) {
                    e.printStackTrace();
                    SJK.fail();
                }
            }
           
            public String toString() {
                return "--histo";
            }
        }

        class ClassSummaryCmd extends SsaCmd {

            @Parameter(names={"--summary"}, description="Print summary for provided classification")
            boolean run;

            @Override
            public boolean isSelected() {
                return run;
            }

            @Override
            public void run() {
                try {

                    if (classifier == null) {
                        SJK.failAndPrintUsage("Classification is required");
                    }
                    if (bucket != null) {
                        SJK.failAndPrintUsage("--summary cannot be used with --bucket option");
                    }
                    List<String> bucketNames = new ArrayList<String>(buckets.getClasses());
                    long[] counters = new long[bucketNames.size()];
                    long total = 0;

                    StackTraceReader reader = getUnclassifiedReader();
                    while(reader.loadNext()) {
                        StackTraceElement[] trace = reader.getTrace();
                        String cl = buckets.classify(trace);
                        if (cl != null) {
                            ++total;
                            ++counters[bucketNames.indexOf(cl)];
                        }
                    }

                    System.out.println(String.format("%-40s\t%d\t%.2f%%", "Total samples", total, 100f));
                    for(int i = 0; i != counters.length; ++i) {
                        System.out.println(String.format("%-40s\t%d\t%.2f%%", bucketNames.get(i), counters[i], (100f * counters[i]) / total));
                    }

                } catch (Exception e) {
                    e.printStackTrace();
                    SJK.fail();
                }
            }

            public String toString() {
                return "--his";
            }
        }
  } 
}
TOP

Related Classes of org.gridkit.jvmtool.cmd.StackSampleAnalyzerCmd$SSA$HistoCmd

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.