changeset 166:cf00c05c2431

Bug 3002: HeapStats CLI should show ID in each subcommand Reviewed-by: ykubota https://github.com/HeapStats/heapstats/pull/39
author Yasumasa Suenaga <yasuenag@gmail.com>
date Tue, 11 Oct 2016 21:29:15 +0900
parents 61807fc09405
children fb425a4e5af7
files ChangeLog analyzer/cli/src/main/java/jp/co/ntt/oss/heapstats/cli/processor/LogProcessor.java analyzer/cli/src/main/java/jp/co/ntt/oss/heapstats/cli/processor/SnapShotProcessor.java analyzer/cli/src/main/java/jp/co/ntt/oss/heapstats/cli/processor/ThreadRecordProcessor.java
diffstat 4 files changed, 67 insertions(+), 48 deletions(-) [+]
line wrap: on
line diff
--- a/ChangeLog	Fri Oct 07 22:13:17 2016 +0900
+++ b/ChangeLog	Tue Oct 11 21:29:15 2016 +0900
@@ -1,3 +1,7 @@
+2016-10-06  Yasumasa Suenaga <yasuenag@gmail.com>
+
+	* Bug 3002: HeapStats CLI should show ID in each subcommand
+
 2016-10-07  KUBOTA Yuji <kubota.yuji@lab.ntt.co.jp>
 
 	* Bug 3191: Enable to change font size of Reference Tree by config
--- a/analyzer/cli/src/main/java/jp/co/ntt/oss/heapstats/cli/processor/LogProcessor.java	Fri Oct 07 22:13:17 2016 +0900
+++ b/analyzer/cli/src/main/java/jp/co/ntt/oss/heapstats/cli/processor/LogProcessor.java	Tue Oct 11 21:29:15 2016 +0900
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 Yasumasa Suenaga
+ * Copyright (C) 2015-2016 Yasumasa Suenaga
  *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License
@@ -71,15 +71,17 @@
             switch(options.getMode()){
                 case JAVA_CPU:
                     System.out.println("Java CPU:");
-                    System.out.println("date time,  %user,  %sys");
+                    System.out.println("ID, date time,  %user,  %sys");
                     IntStream.range(start, options.getEnd().orElse(diffEntries.size()))
+                             .peek(i -> System.out.print(i + ": "))
                              .mapToObj(i -> diffEntries.get(i))
                              .forEach(d -> System.out.println(String.format("%s: %.2f %.2f", d.getDateTime().format(DateTimeFormatter.ISO_LOCAL_DATE_TIME), d.getJavaUserUsage(), d.getJavaSysUsage())));
                     break;
                 case SYSTEM_CPU:
                     System.out.println("System CPU:");
-                    System.out.println("date time,  %user,  %nice,  %sys,  %iowait,  %irq,  %softirq,  %steal,  %guest,  %idle");
+                    System.out.println("ID, date time,  %user,  %nice,  %sys,  %iowait,  %irq,  %softirq,  %steal,  %guest,  %idle");
                     IntStream.range(start, options.getEnd().orElse(diffEntries.size()))
+                             .peek(i -> System.out.print(i + ": "))
                              .mapToObj(i -> diffEntries.get(i))
                              .forEach(d -> System.out.println(String.format("%s: %.2f %.2f %.2f %.2f %.2f %.2f %.2f %.2f %.2f", d.getDateTime().format(DateTimeFormatter.ISO_LOCAL_DATE_TIME),
                                                                                                                                 d.getCpuUserUsage(), d.getCpuNiceUsage(), d.getCpuSysUsage(),
@@ -88,38 +90,43 @@
                     break;
                 case MEMORIES:
                     System.out.println("Java Memory:");
-                    System.out.println("date time,  VSZ (MB),  RSS (MB)");
+                    System.out.println("ID, date time,  VSZ (MB),  RSS (MB)");
                     IntStream.range(start, options.getEnd().orElse(logEntries.size()))
+                             .peek(i -> System.out.print(i + ": "))
                              .mapToObj(i -> logEntries.get(i))
                              .forEach(d -> System.out.println(String.format("%s: %d %d", d.getDateTime().format(DateTimeFormatter.ISO_LOCAL_DATE_TIME), d.getJavaVSSize() / 1024 / 1024, d.getJavaRSSize() / 1024 / 1024)));
                     break;
                 case SAFEPOINTS:
                     System.out.println("Safepoints:");
-                    System.out.println("date time,  count,  time (ms)");
+                    System.out.println("ID, date time,  count,  time (ms)");
                     IntStream.range(start, options.getEnd().orElse(diffEntries.size()))
+                             .peek(i -> System.out.print(i + ": "))
                              .mapToObj(i -> diffEntries.get(i))
                              .forEach(d -> System.out.println(String.format("%s: %d %d", d.getDateTime().format(DateTimeFormatter.ISO_LOCAL_DATE_TIME), d.getJvmSafepoints(), d.getJvmSafepointTime())));
                     break;
                 case MONITORS:
                     System.out.println("Monitor Contention:");
-                    System.out.println("date time,  count");
+                    System.out.println("ID, date time,  count");
                     IntStream.range(start, options.getEnd().orElse(diffEntries.size()))
+                             .peek(i -> System.out.print(i + ": "))
                              .mapToObj(i -> diffEntries.get(i))
                              .forEach(d -> System.out.println(String.format("%s: %d", d.getDateTime().format(DateTimeFormatter.ISO_LOCAL_DATE_TIME), d.getJvmSyncPark())));
                     break;
                 case THREADS:
                     System.out.println("Live threads:");
-                    System.out.println("date time,  count");
+                    System.out.println("ID, date time,  count");
                     IntStream.range(start, options.getEnd().orElse(logEntries.size()))
+                             .peek(i -> System.out.print(i + ": "))
                              .mapToObj(i -> logEntries.get(i))
                              .forEach(d -> System.out.println(String.format("%s: %d", d.getDateTime().format(DateTimeFormatter.ISO_LOCAL_DATE_TIME), d.getJvmLiveThreads())));
                     break;
                 case PARSE_ARCHIVES:
                     System.out.println("Archive list:");
-                    System.out.println("date time,  path");
+                    System.out.println("ID, date time,  path");
                     IntStream.range(start, options.getEnd().orElse(logEntries.size()))
+                             .filter(i -> logEntries.get(i).getArchivePath() != null)
+                             .peek(i -> System.out.print(i + ": "))
                              .mapToObj(i -> logEntries.get(i))
-                             .filter(d -> d.getArchivePath() != null)
                              .map(d -> new ArchiveData(d, new File(d.getArchivePath().replaceAll("\\..*$", ""))))
                              .peek(a -> a.getExtractPath().mkdir())
                              .peek(new ConsumerWrapper<>(a -> a.parseArchive()))
--- a/analyzer/cli/src/main/java/jp/co/ntt/oss/heapstats/cli/processor/SnapShotProcessor.java	Fri Oct 07 22:13:17 2016 +0900
+++ b/analyzer/cli/src/main/java/jp/co/ntt/oss/heapstats/cli/processor/SnapShotProcessor.java	Tue Oct 11 21:29:15 2016 +0900
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 Yasumasa Suenaga
+ * Copyright (C) 2015-2016 Yasumasa Suenaga
  *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License
@@ -18,6 +18,7 @@
 package jp.co.ntt.oss.heapstats.cli.processor;
 
 import java.time.format.DateTimeFormatter;
+import java.util.AbstractMap;
 import java.util.Arrays;
 import java.util.Comparator;
 import java.util.List;
@@ -57,10 +58,11 @@
     
     /**
      * Show SnapShot summary.
+     * @param id SnapShot ID
      * @param header SnapShot header.
      */
-    private void showSnapShotSummary(SnapShotHeader header){
-        System.out.println(header.getSnapShotDate().format(DateTimeFormatter.ISO_LOCAL_DATE_TIME) + ": Cause: " + header.getCauseString());
+    private void showSnapShotSummary(int id, SnapShotHeader header){
+        System.out.println(id + ": " + header.getSnapShotDate().format(DateTimeFormatter.ISO_LOCAL_DATE_TIME) + ": Cause: " + header.getCauseString());
         System.out.println("GC Cause: " + header.getGcCause() + ", Full: " + header.getFullCount() + ", Young: " + header.getYngCount() + ", GC Time: " + header.getGcTime() + "ms");
         System.out.printf("Java heap: capacity: %dMB, new: %dMB, old: %dMB\n", header.getTotalCapacity() / 1024 / 1024, header.getNewHeap() / 1024 / 1024, header.getOldHeap() / 1024 / 1024);
         System.out.printf("Metaspace: capacity: %dMB, usage: %dMB\n", header.getMetaspaceCapacity() / 1024 / 1024, header.getMetaspaceUsage() / 1024 / 1024);
@@ -87,10 +89,11 @@
     
     /**
      * Show class histogram.
+     * @param id SnapShot ID
      * @param header SnapShot header.
      */
-    private void showClassHistogram(SnapShotHeader header){
-        System.out.println(header.getSnapShotDate().format(DateTimeFormatter.ISO_LOCAL_DATE_TIME));
+    private void showClassHistogram(int id, SnapShotHeader header){
+        System.out.println(id + ": " + header.getSnapShotDate().format(DateTimeFormatter.ISO_LOCAL_DATE_TIME));
         System.out.println("Tag\tClass\tClassLoader\tInstances\tSize(KB)");
         
         Stream<ObjectData> stream = header.getSnapShot(true).values().stream();
@@ -134,13 +137,14 @@
 
     /**
      * Show class reference.
+     * @param id SnapShot ID
      * @param header SnapShot header.
      */
-    private void showClassReference(SnapShotHeader header){
+    private void showClassReference(int id, SnapShotHeader header){
         long refStart = options.getRefStartTag();
         Map<Long, ObjectData> snapShot = header.getSnapShot(true);
         
-        System.out.println(header.getSnapShotDate().format(DateTimeFormatter.ISO_LOCAL_DATE_TIME));
+        System.out.println(id + ": " + header.getSnapShotDate().format(DateTimeFormatter.ISO_LOCAL_DATE_TIME));
         System.out.println("Start: " + snapShot.get(refStart).getName());
         System.out.println("Direction: " + (options.isRefToParent() ? "Parent" : "Child"));
         System.out.println("\tTag\tClass\tClassLoader\tInstances\tSize(KB)");
@@ -177,30 +181,30 @@
                      .mapToObj(i -> String.format("%d: %s", i, snapShots.get(i).getSnapShotDate().format(DateTimeFormatter.ISO_LOCAL_DATE_TIME)))
                      .forEachOrdered(System.out::println);
         }
+        else if(options.getMode() == Options.Mode.DIFF_HISTO){
+            System.out.println(options.getEnd().orElse(snapShots.size() - 1));
+            showDiffHistogram(snapShots.get(start), snapShots.get(options.getEnd().orElse(snapShots.size()) - 1));
+        }
         else{
-            Stream<SnapShotHeader> snapshotStream = IntStream.range(start, options.getEnd().orElse(snapShots.size()))
-                                                             .mapToObj(i -> snapShots.get(i));
+            Stream<AbstractMap.SimpleImmutableEntry<Integer, SnapShotHeader>> snapshotStream = IntStream.range(start, options.getEnd().orElse(snapShots.size()))
+                                                                                                        .mapToObj(i -> new AbstractMap.SimpleImmutableEntry<Integer, SnapShotHeader>(i, snapShots.get(i)));
             
             switch(options.getMode()){
                 case SNAPSHOT_SUMMARY:
-                    snapshotStream.forEachOrdered(this::showSnapShotSummary);
+                    snapshotStream.forEachOrdered(e -> showSnapShotSummary(e.getKey(), e.getValue()));
                     break;
                 case CLASS_HISTO:
-                    snapshotStream.forEachOrdered(this::showClassHistogram);
-                    break;
-                case DIFF_HISTO:
-                    System.out.println(options.getEnd().orElse(snapShots.size() - 1));
-                    showDiffHistogram(snapShots.get(start), snapShots.get(options.getEnd().orElse(snapShots.size()) - 1));
+                    snapshotStream.forEachOrdered(e -> showClassHistogram(e.getKey(), e.getValue()));
                     break;
                 case CLASS_REFERENCES:
-                    snapshotStream.forEachOrdered(this::showClassReference);
+                    snapshotStream.forEachOrdered(e -> showClassReference(e.getKey(), e.getValue()));
                     break;
                 case HEAP_CSV:
-                    CSVDumpHeap heapDumper = new CSVDumpHeap(options.getCsvFile(), snapshotStream.collect(Collectors.toList()), options.getFilterPredicate(), true);
+                    CSVDumpHeap heapDumper = new CSVDumpHeap(options.getCsvFile(), snapshotStream.map(e -> e.getValue()).collect(Collectors.toList()), options.getFilterPredicate(), true);
                     heapDumper.run();
                     break;
                 case GC_CSV:
-                    CSVDumpGC csvDumper = new CSVDumpGC(options.getCsvFile(), snapshotStream.collect(Collectors.toList()));
+                    CSVDumpGC csvDumper = new CSVDumpGC(options.getCsvFile(), snapshotStream.map(e -> e.getValue()).collect(Collectors.toList()));
                     csvDumper.run();
                     break;
             }
--- a/analyzer/cli/src/main/java/jp/co/ntt/oss/heapstats/cli/processor/ThreadRecordProcessor.java	Fri Oct 07 22:13:17 2016 +0900
+++ b/analyzer/cli/src/main/java/jp/co/ntt/oss/heapstats/cli/processor/ThreadRecordProcessor.java	Tue Oct 11 21:29:15 2016 +0900
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 Yasumasa Suenaga
+ * Copyright (C) 2015-2016 Yasumasa Suenaga
  *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License
@@ -18,8 +18,11 @@
 package jp.co.ntt.oss.heapstats.cli.processor;
 
 import java.time.format.DateTimeFormatter;
-import java.util.Arrays;
+import java.util.AbstractMap;
+import java.util.Comparator;
+import java.util.EnumSet;
 import java.util.List;
+import java.util.Set;
 import java.util.stream.IntStream;
 import java.util.stream.Stream;
 import jp.co.ntt.oss.heapstats.cli.Options;
@@ -66,34 +69,35 @@
             threadRecordParser.getIdMap().forEach((k, v) -> System.out.println(k.toString() + ": " + v));
         }
         else{
-            Stream<ThreadStat> threadStatStream = IntStream.range(start, options.getEnd().orElse(threadStatList.size()))
-                                                                                .mapToObj(threadStatList::get)
-                                                                                .filter(options.getIdPredicate())
-                                                                                .sorted();
-            
+            Stream<AbstractMap.SimpleImmutableEntry<Integer, ThreadStat>> threadStatStream = IntStream.range(start, options.getEnd().orElse(threadStatList.size()))
+                                                                                                      .mapToObj(i -> new AbstractMap.SimpleImmutableEntry<Integer, ThreadStat>(i, threadStatList.get(i)))
+                                                                                                      .filter(e -> options.getIdPredicate().test(e.getValue()))
+                                                                                                      .sorted(Comparator.comparing(e -> e.getValue()));
+            Set<ThreadEvent> includedSet;
             switch(options.getMode()){
                 case DUMP_SUSPEND_EVENTS:
-                    List<ThreadEvent> suspendEventList = Arrays.asList(ThreadEvent.MonitorWait, ThreadEvent.MonitorWaited,
-                                                                       ThreadEvent.MonitorContendedEnter, ThreadEvent.MonitorContendedEntered,
-                                                                       ThreadEvent.ThreadSleepStart, ThreadEvent.ThreadSleepEnd,
-                                                                       ThreadEvent.Park, ThreadEvent.Unpark);
-                    threadStatStream = threadStatStream.filter(s -> suspendEventList.contains(s.getEvent()));
+                    includedSet = EnumSet.of(ThreadEvent.MonitorWait, ThreadEvent.MonitorWaited,
+                                             ThreadEvent.MonitorContendedEnter, ThreadEvent.MonitorContendedEntered,
+                                             ThreadEvent.ThreadSleepStart, ThreadEvent.ThreadSleepEnd,
+                                             ThreadEvent.Park, ThreadEvent.Unpark);
                     break;
                 case DUMP_LOCK_EVENTS:
-                    List<ThreadEvent> lockEventList = Arrays.asList(ThreadEvent.MonitorContendedEnter, ThreadEvent.MonitorContendedEntered,
-                                                                    ThreadEvent.Park, ThreadEvent.Unpark);
-                    threadStatStream = threadStatStream.filter(s -> lockEventList.contains(s.getEvent()));
+                    includedSet = EnumSet.of(ThreadEvent.MonitorContendedEnter, ThreadEvent.MonitorContendedEntered,
+                                             ThreadEvent.Park, ThreadEvent.Unpark);
                     break;
                 case DUMP_IO_EVENTS:
-                    List<ThreadEvent> ioEventList = Arrays.asList(ThreadEvent.FileWriteStart, ThreadEvent.FileWriteEnd,
-                                                                  ThreadEvent.FileReadStart, ThreadEvent.FileReadEnd,
-                                                                  ThreadEvent.SocketWriteStart, ThreadEvent.SocketWriteEnd,
-                                                                  ThreadEvent.SocketReadStart, ThreadEvent.SocketReadEnd);
-                    threadStatStream = threadStatStream.filter(s -> ioEventList.contains(s.getEvent()));
+                    includedSet = EnumSet.of(ThreadEvent.FileWriteStart, ThreadEvent.FileWriteEnd,
+                                             ThreadEvent.FileReadStart, ThreadEvent.FileReadEnd,
+                                             ThreadEvent.SocketWriteStart, ThreadEvent.SocketWriteEnd,
+                                             ThreadEvent.SocketReadStart, ThreadEvent.SocketReadEnd);
+                    break;
+                default:
+                    includedSet = EnumSet.allOf(ThreadEvent.class);
                     break;
             }
             
-            threadStatStream.forEachOrdered(System.out::println);
+            threadStatStream.filter(e -> includedSet.contains(e.getValue().getEvent()))
+                            .forEachOrdered(e -> System.out.println(e.getKey() + ": " + e.getValue()));
         }
         
     }