You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@jackrabbit.apache.org by GitBox <gi...@apache.org> on 2021/09/20 04:18:40 UTC

[GitHub] [jackrabbit-oak] nit0906 opened a new pull request #372: OAK-9566 | Improve index stats

nit0906 opened a new pull request #372:
URL: https://github.com/apache/jackrabbit-oak/pull/372


   * Added support for Json format 
   * Fixed issue with local index dir size - currently with composite node store - it was just reporting size of read only mount
   * Added new stats for indexCreationTimestamp, ReindexCompletionTimestamp, suggestDirSize, If the index has hidden property index node and if it has a hidden read only libs mount.


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: dev-unsubscribe@jackrabbit.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [jackrabbit-oak] thomasmueller commented on a change in pull request #372: OAK-9566 | Improve index stats

Posted by GitBox <gi...@apache.org>.
thomasmueller commented on a change in pull request #372:
URL: https://github.com/apache/jackrabbit-oak/pull/372#discussion_r712763314



##########
File path: oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/inventory/IndexPrinter.java
##########
@@ -66,97 +71,200 @@ public IndexPrinter(IndexInfoService indexInfoService, AsyncIndexInfoService asy
 
     @Override
     public void print(PrintWriter pw, Format format, boolean isZip) {
-        //TODO Highlight if failing
-        printAsyncIndexInfo(pw);
-        printIndexInfo(pw);
+
+        if (format == Format.JSON) {
+            JsopBuilder json = new JsopBuilder();
+            startJsonObject(json);
+            printAsyncIndexInfo(pw, json, format);
+            printIndexInfo(pw, json, format);
+            endJsonObject(json);
+            pw.print(JsopBuilder.prettyPrint(json.toString()));
+        } else {
+            //TODO Highlight if failing
+            printAsyncIndexInfo(pw, null, format);
+            printIndexInfo(pw, null, format);
+        }
     }
 
-    private void printAsyncIndexInfo(PrintWriter pw) {
+    private void printAsyncIndexInfo(PrintWriter pw, JsopBuilder json, Format format) {
         List<String> asyncLanes = ImmutableList.copyOf(asyncIndexInfoService.getAsyncLanes());
         String title = "Async Indexers State";
-        printTitle(pw, title);
-        pw.printf("Number of async indexer lanes : %d%n", asyncLanes.size());
-        pw.println();
+        printTitle(pw, title, format);
+        addJsonKey(json, title);
+        startJsonObject(json);
+        keyValue("Number of async indexer lanes ", asyncLanes.size(), pw, json, format);
+        printWithNewLine(pw, "", format);
+
         for (String lane : asyncLanes) {
-            pw.println(lane);
+            printWithNewLine(pw, lane, format);
+            addJsonKey(json, lane);
             AsyncIndexInfo info = asyncIndexInfoService.getInfo(lane);
+            startJsonObject(json);
             if (info != null) {
-                        pw.printf("    Last indexed to      : %s%n", formatTime(info.getLastIndexedTo()));
+                keyValue("    Last indexed to      ", formatTime(info.getLastIndexedTo()), pw, json, format);
                 IndexStatsMBean stats = info.getStatsMBean();
                 if (stats != null) {
-                        pw.printf("    Status              : %s%n", stats.getStatus());
-                        pw.printf("    Failing             : %s%n", stats.isFailing());
-                        pw.printf("    Paused              : %s%n", stats.isPaused());
+                    keyValue("    Status              ", stats.getStatus(), pw, json, format);
+                    keyValue("    Failing             ", stats.isFailing(), pw, json, format);
+                    keyValue("    Paused              ", stats.isPaused(), pw, json, format);
                     if (stats.isFailing()) {
-                        pw.printf("    Failing since       : %s%n", stats.getFailingSince());
-                        pw.printf("    Latest error        : %s%n", stats.getLatestError());
+                        keyValue("    Failing since       ", stats.getFailingSince(), pw, json, format);
+                        keyValue("    Latest error        ", stats.getLatestError(), pw, json, format);
                     }
                 }
-                pw.println();
+                printWithNewLine(pw, "", format);
             }
+            endJsonObject(json);
         }
+        endJsonObject(json);
     }
 
-    private static void printTitle(PrintWriter pw, String title) {
-        pw.println(title);
-        pw.println(Strings.repeat("=", title.length()));
+    private static void printTitle(PrintWriter pw, String title, Format format) {
+        if (format == Format.TEXT) {
+            pw.println(title);
+            pw.println(Strings.repeat("=", title.length()));
+            pw.println();
+        }
     }
 
-    private void printIndexInfo(PrintWriter pw) {
+    private static void printWithNewLine(PrintWriter pw, String printLine, Format format) {
+        if (format == Format.TEXT) {
+            pw.println(printLine);
+        }
+    }
+
+    private void printIndexInfo(PrintWriter pw, JsopBuilder json, Format format) {
         ListMultimap<String, IndexInfo> infos = ArrayListMultimap.create();
         for (IndexInfo info : indexInfoService.getAllIndexInfo()) {
             infos.put(info.getType(), info);
         }
 
-        pw.printf("Total number of indexes : %d%n", infos.size());
+        keyValue("Total number of indexes ", infos.size(), pw, json, format);
+
         for (String type : infos.keySet()){
             List<IndexInfo> typedInfo = infos.get(type);
             String title = String.format("%s(%d)", type, typedInfo.size());
-            printTitle(pw, title);
-            pw.println();
+            printTitle(pw, title, format);
+            addJsonKey(json, type);
+            startJsonObject(json);
             for (IndexInfo info : typedInfo){
-                printIndexInfo(pw, info);
+                printIndexInfo(pw, json, info, format);
             }
+            endJsonObject(json);
         }
     }
 
-    private static void printIndexInfo(PrintWriter pw, IndexInfo info) {
-        pw.println(info.getIndexPath());
-        pw.printf("    Type                    : %s%n", info.getType());
+
+    private static void printIndexInfo(PrintWriter pw, JsopBuilder json, IndexInfo info, Format format) {
+        if (format == Format.TEXT) {
+            pw.println(info.getIndexPath());
+        }
+        addJsonKey(json, info.getIndexPath());
+        startJsonObject(json);
+
+        keyValue("    Type                    ", info.getType(), pw, json, format);
         if (info.getAsyncLaneName() != null) {
-            pw.printf("    Async                   : true%n");
-            pw.printf("    Async lane name         : %s%n", info.getAsyncLaneName());
+            keyValue("    Async                    ", true, pw, json, format);
+            keyValue("    Async lane name          ", info.getAsyncLaneName(), pw, json, format);
         }
 
         if (info.getIndexedUpToTime() > 0){
-            pw.printf("    Last indexed up to      : %s%n", formatTime(info.getIndexedUpToTime()));
+            keyValue("    Last indexed up to       ", formatTime(info.getIndexedUpToTime()), pw, json, format);
         }
 
         if (info.getLastUpdatedTime() > 0){
-            pw.printf("    Last updated time       : %s%n", formatTime(info.getLastUpdatedTime()));
+            keyValue("     Last updated time       ", formatTime(info.getLastUpdatedTime()), pw, json, format);
+        }
+
+        if (info.getCreationTimestamp() > 0){
+            keyValue("     Creation time           ", formatTime(info.getCreationTimestamp()), pw, json, format);
+        }
+
+        if (info.getReindexCompletionTimestamp() > 0){
+            keyValue("     Reindex completion time ", formatTime(info.getReindexCompletionTimestamp()), pw, json, format);
         }
 
         if (info.getSizeInBytes() >= 0){
-            pw.printf("    Size                    : %s%n", IOUtils.humanReadableByteCount(info.getSizeInBytes()));
+            keyValue("    Size                     ", IOUtils.humanReadableByteCount(info.getSizeInBytes()), pw, json, format);
+            keyValue("    Size (in Bytes)          ", info.getSizeInBytes(), pw, json, format);
+        }
+
+        if (info.getSuggestSizeInBytes() >= 0){
+            keyValue("    Suggest size             ", IOUtils.humanReadableByteCount(info.getSuggestSizeInBytes()), pw, json, format);
+            keyValue("    Suggest size (in Bytes)  ", info.getSuggestSizeInBytes(), pw, json, format);
         }
 
         if (info.getEstimatedEntryCount() >= 0){
-            pw.printf("    Estimated entry count   : %d%n", info.getEstimatedEntryCount());
+            keyValue("    Estimated entry count    ", info.getEstimatedEntryCount(), pw, json, format);
+        }
+
+        if ("lucene".equals(info.getType())) {
+            // Only valid for lucene type indexes, for others it will simply show false.
+            keyValue("    Has hidden oak mount     ", info.hasHiddenOakLibsMount(), pw, json, format);
+            keyValue("    Has property index       ", info.hasPropertyIndexNode(), pw, json, format);
         }
 
         if (info.hasIndexDefinitionChangedWithoutReindexing()) {
-            pw.println("    Index definition changed without reindexing");
             String diff = info.getIndexDefinitionDiff();
             if (diff != null) {
-                pw.println("    "+diff);
+                keyValue("    Index definition changed without reindexing ", diff, pw, json, format);
+                printWithNewLine(pw, "", format);
             }
         }
-        pw.println();
+        endJsonObject(json);
     }
 
     private static String formatTime(long time){
         Calendar cal = Calendar.getInstance();
         cal.setTimeInMillis(time);
-        return ISO8601.format(cal);
+        Date date = cal.getTime();
+        SimpleDateFormat outputFmt = new SimpleDateFormat("yyyy-mm-dd'T'HH:mm:ss.s z");

Review comment:
       mm is for minutes, but you need month, I think that would be MM. "ss.s" is incorrect, it shows seconds twice. I don't think we need milliseconds or fractional seconds, but if you want them then this needs to be fixed.
   
   For human readable, what about
   
       SimpleDateFormat outputFmt = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss 'UTC'");
   
   For ISO 8601, I think this would be correct:
   
       SimpleDateFormat outputFmt = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'");

##########
File path: oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/inventory/IndexPrinter.java
##########
@@ -66,97 +71,200 @@ public IndexPrinter(IndexInfoService indexInfoService, AsyncIndexInfoService asy
 
     @Override
     public void print(PrintWriter pw, Format format, boolean isZip) {
-        //TODO Highlight if failing
-        printAsyncIndexInfo(pw);
-        printIndexInfo(pw);
+
+        if (format == Format.JSON) {
+            JsopBuilder json = new JsopBuilder();
+            startJsonObject(json);
+            printAsyncIndexInfo(pw, json, format);
+            printIndexInfo(pw, json, format);
+            endJsonObject(json);
+            pw.print(JsopBuilder.prettyPrint(json.toString()));
+        } else {
+            //TODO Highlight if failing
+            printAsyncIndexInfo(pw, null, format);
+            printIndexInfo(pw, null, format);
+        }
     }
 
-    private void printAsyncIndexInfo(PrintWriter pw) {
+    private void printAsyncIndexInfo(PrintWriter pw, JsopBuilder json, Format format) {
         List<String> asyncLanes = ImmutableList.copyOf(asyncIndexInfoService.getAsyncLanes());
         String title = "Async Indexers State";
-        printTitle(pw, title);
-        pw.printf("Number of async indexer lanes : %d%n", asyncLanes.size());
-        pw.println();
+        printTitle(pw, title, format);
+        addJsonKey(json, title);
+        startJsonObject(json);
+        keyValue("Number of async indexer lanes ", asyncLanes.size(), pw, json, format);
+        printWithNewLine(pw, "", format);
+
         for (String lane : asyncLanes) {
-            pw.println(lane);
+            printWithNewLine(pw, lane, format);
+            addJsonKey(json, lane);
             AsyncIndexInfo info = asyncIndexInfoService.getInfo(lane);
+            startJsonObject(json);
             if (info != null) {
-                        pw.printf("    Last indexed to      : %s%n", formatTime(info.getLastIndexedTo()));
+                keyValue("    Last indexed to      ", formatTime(info.getLastIndexedTo()), pw, json, format);
                 IndexStatsMBean stats = info.getStatsMBean();
                 if (stats != null) {
-                        pw.printf("    Status              : %s%n", stats.getStatus());
-                        pw.printf("    Failing             : %s%n", stats.isFailing());
-                        pw.printf("    Paused              : %s%n", stats.isPaused());
+                    keyValue("    Status              ", stats.getStatus(), pw, json, format);
+                    keyValue("    Failing             ", stats.isFailing(), pw, json, format);
+                    keyValue("    Paused              ", stats.isPaused(), pw, json, format);
                     if (stats.isFailing()) {
-                        pw.printf("    Failing since       : %s%n", stats.getFailingSince());
-                        pw.printf("    Latest error        : %s%n", stats.getLatestError());
+                        keyValue("    Failing since       ", stats.getFailingSince(), pw, json, format);
+                        keyValue("    Latest error        ", stats.getLatestError(), pw, json, format);
                     }
                 }
-                pw.println();
+                printWithNewLine(pw, "", format);
             }
+            endJsonObject(json);
         }
+        endJsonObject(json);
     }
 
-    private static void printTitle(PrintWriter pw, String title) {
-        pw.println(title);
-        pw.println(Strings.repeat("=", title.length()));
+    private static void printTitle(PrintWriter pw, String title, Format format) {
+        if (format == Format.TEXT) {
+            pw.println(title);
+            pw.println(Strings.repeat("=", title.length()));
+            pw.println();
+        }
     }
 
-    private void printIndexInfo(PrintWriter pw) {
+    private static void printWithNewLine(PrintWriter pw, String printLine, Format format) {
+        if (format == Format.TEXT) {
+            pw.println(printLine);
+        }
+    }
+
+    private void printIndexInfo(PrintWriter pw, JsopBuilder json, Format format) {
         ListMultimap<String, IndexInfo> infos = ArrayListMultimap.create();
         for (IndexInfo info : indexInfoService.getAllIndexInfo()) {
             infos.put(info.getType(), info);
         }
 
-        pw.printf("Total number of indexes : %d%n", infos.size());
+        keyValue("Total number of indexes ", infos.size(), pw, json, format);
+
         for (String type : infos.keySet()){
             List<IndexInfo> typedInfo = infos.get(type);
             String title = String.format("%s(%d)", type, typedInfo.size());
-            printTitle(pw, title);
-            pw.println();
+            printTitle(pw, title, format);
+            addJsonKey(json, type);
+            startJsonObject(json);
             for (IndexInfo info : typedInfo){
-                printIndexInfo(pw, info);
+                printIndexInfo(pw, json, info, format);
             }
+            endJsonObject(json);
         }
     }
 
-    private static void printIndexInfo(PrintWriter pw, IndexInfo info) {
-        pw.println(info.getIndexPath());
-        pw.printf("    Type                    : %s%n", info.getType());
+
+    private static void printIndexInfo(PrintWriter pw, JsopBuilder json, IndexInfo info, Format format) {
+        if (format == Format.TEXT) {
+            pw.println(info.getIndexPath());
+        }
+        addJsonKey(json, info.getIndexPath());
+        startJsonObject(json);
+
+        keyValue("    Type                    ", info.getType(), pw, json, format);
         if (info.getAsyncLaneName() != null) {
-            pw.printf("    Async                   : true%n");
-            pw.printf("    Async lane name         : %s%n", info.getAsyncLaneName());
+            keyValue("    Async                    ", true, pw, json, format);
+            keyValue("    Async lane name          ", info.getAsyncLaneName(), pw, json, format);
         }
 
         if (info.getIndexedUpToTime() > 0){
-            pw.printf("    Last indexed up to      : %s%n", formatTime(info.getIndexedUpToTime()));
+            keyValue("    Last indexed up to       ", formatTime(info.getIndexedUpToTime()), pw, json, format);
         }
 
         if (info.getLastUpdatedTime() > 0){
-            pw.printf("    Last updated time       : %s%n", formatTime(info.getLastUpdatedTime()));
+            keyValue("     Last updated time       ", formatTime(info.getLastUpdatedTime()), pw, json, format);
+        }
+
+        if (info.getCreationTimestamp() > 0){
+            keyValue("     Creation time           ", formatTime(info.getCreationTimestamp()), pw, json, format);
+        }
+
+        if (info.getReindexCompletionTimestamp() > 0){
+            keyValue("     Reindex completion time ", formatTime(info.getReindexCompletionTimestamp()), pw, json, format);
         }
 
         if (info.getSizeInBytes() >= 0){
-            pw.printf("    Size                    : %s%n", IOUtils.humanReadableByteCount(info.getSizeInBytes()));
+            keyValue("    Size                     ", IOUtils.humanReadableByteCount(info.getSizeInBytes()), pw, json, format);
+            keyValue("    Size (in Bytes)          ", info.getSizeInBytes(), pw, json, format);
+        }
+
+        if (info.getSuggestSizeInBytes() >= 0){
+            keyValue("    Suggest size             ", IOUtils.humanReadableByteCount(info.getSuggestSizeInBytes()), pw, json, format);
+            keyValue("    Suggest size (in Bytes)  ", info.getSuggestSizeInBytes(), pw, json, format);
         }
 
         if (info.getEstimatedEntryCount() >= 0){
-            pw.printf("    Estimated entry count   : %d%n", info.getEstimatedEntryCount());
+            keyValue("    Estimated entry count    ", info.getEstimatedEntryCount(), pw, json, format);
+        }
+
+        if ("lucene".equals(info.getType())) {
+            // Only valid for lucene type indexes, for others it will simply show false.
+            keyValue("    Has hidden oak mount     ", info.hasHiddenOakLibsMount(), pw, json, format);
+            keyValue("    Has property index       ", info.hasPropertyIndexNode(), pw, json, format);
         }
 
         if (info.hasIndexDefinitionChangedWithoutReindexing()) {
-            pw.println("    Index definition changed without reindexing");
             String diff = info.getIndexDefinitionDiff();
             if (diff != null) {
-                pw.println("    "+diff);
+                keyValue("    Index definition changed without reindexing ", diff, pw, json, format);
+                printWithNewLine(pw, "", format);
             }
         }
-        pw.println();
+        endJsonObject(json);
     }
 
     private static String formatTime(long time){
         Calendar cal = Calendar.getInstance();
         cal.setTimeInMillis(time);
-        return ISO8601.format(cal);
+        Date date = cal.getTime();
+        SimpleDateFormat outputFmt = new SimpleDateFormat("yyyy-mm-dd'T'HH:mm:ss.s z");
+        outputFmt.setTimeZone(TimeZone.getTimeZone("UTC"));
+        return outputFmt.format(date);
+    }
+
+    private static void keyValue(String key, Object value, PrintWriter pw, JsopBuilder json, Format format) {
+        // In case the key is null or an emppty String or value is null,
+        // throw an IllegalArgumentException.
+        if (value == null || key == null || key.equals("")) {

Review comment:
       I would support null values.




-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: dev-unsubscribe@jackrabbit.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [jackrabbit-oak] thomasmueller commented on pull request #372: OAK-9566 | Improve index stats

Posted by GitBox <gi...@apache.org>.
thomasmueller commented on pull request #372:
URL: https://github.com/apache/jackrabbit-oak/pull/372#issuecomment-923697436


   > https://issues.apache.org/jira/browse/OAK-9566?focusedCommentId=17417733&page=com.atlassian.jira.plugin.system.issuetabpanels%3Acomment-tabpanel#comment-17417733
   
   The example uses "2021-55-20T16:55:53.53 UTC", you have used seconds instead of month...
   
   While "2021-09-20T16:55:53.53 UTC" is clear for the user, is not a standardized format... https://www.w3.org/TR/NOTE-datetime specifies "2021-09-17T07:52:02.619Z". 
   
   If we want "human readable", then what about "2021-09-20 16:55:53 UTC" (no "T", and no fractional seconds).


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: dev-unsubscribe@jackrabbit.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [jackrabbit-oak] nit0906 edited a comment on pull request #372: OAK-9566 | Improve index stats

Posted by GitBox <gi...@apache.org>.
nit0906 edited a comment on pull request #372:
URL: https://github.com/apache/jackrabbit-oak/pull/372#issuecomment-922720268


   @thomasmueller -
   >> Could you add an example output, in Json format, to https://issues.apache.org/jira/browse/OAK-9566 ?
   
   Attached a sample o/p to the jira. Please note that the values in it are not correct and some are missing, since It's from an earlier revision and was not run on composite node store - but the format is same so it'll give an idea about how it's structured.
   
    >> Or (might be easier) add a test case with Json output... anyway having a test case would be good.
   
   I added a couple of tests cases. See IndexPrinterTest#asyncIndexInfoJson and  IndexPrinterTest#indexInfoJson


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: dev-unsubscribe@jackrabbit.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [jackrabbit-oak] thomasmueller commented on a change in pull request #372: OAK-9566 | Improve index stats

Posted by GitBox <gi...@apache.org>.
thomasmueller commented on a change in pull request #372:
URL: https://github.com/apache/jackrabbit-oak/pull/372#discussion_r712181089



##########
File path: oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/inventory/IndexPrinter.java
##########
@@ -66,97 +68,190 @@ public IndexPrinter(IndexInfoService indexInfoService, AsyncIndexInfoService asy
 
     @Override
     public void print(PrintWriter pw, Format format, boolean isZip) {
-        //TODO Highlight if failing
-        printAsyncIndexInfo(pw);
-        printIndexInfo(pw);
+
+        if (format == Format.JSON) {
+            JsopBuilder json = new JsopBuilder();
+            startJsonObject(json);
+            printAsyncIndexInfo(pw, json, format);
+            printIndexInfo(pw, json, format);
+            endJsonObject(json);
+            pw.print(JsopBuilder.prettyPrint(json.toString()));
+        } else {
+            //TODO Highlight if failing
+            printAsyncIndexInfo(pw, null, format);
+            printIndexInfo(pw, null, format);
+        }
     }
 
-    private void printAsyncIndexInfo(PrintWriter pw) {
+    private void printAsyncIndexInfo(PrintWriter pw, JsopBuilder json, Format format) {
         List<String> asyncLanes = ImmutableList.copyOf(asyncIndexInfoService.getAsyncLanes());
         String title = "Async Indexers State";
-        printTitle(pw, title);
-        pw.printf("Number of async indexer lanes : %d%n", asyncLanes.size());
-        pw.println();
+        printTitle(pw, title, format);
+        addJsonKey(json, title);
+        startJsonObject(json);
+        keyValue("Number of async indexer lanes ", asyncLanes.size(), pw, json, format);
+        printWithNewLine(pw, "", format);
+
         for (String lane : asyncLanes) {
-            pw.println(lane);
+            printWithNewLine(pw, lane, format);
+            addJsonKey(json, lane);
             AsyncIndexInfo info = asyncIndexInfoService.getInfo(lane);
+            startJsonObject(json);
             if (info != null) {
-                        pw.printf("    Last indexed to      : %s%n", formatTime(info.getLastIndexedTo()));
+                keyValue("    Last indexed to      ", formatTime(info.getLastIndexedTo()), pw, json, format);
                 IndexStatsMBean stats = info.getStatsMBean();
                 if (stats != null) {
-                        pw.printf("    Status              : %s%n", stats.getStatus());
-                        pw.printf("    Failing             : %s%n", stats.isFailing());
-                        pw.printf("    Paused              : %s%n", stats.isPaused());
+                    keyValue("    Status              ", stats.getStatus(), pw, json, format);
+                    keyValue("    Failing             ", stats.isFailing(), pw, json, format);
+                    keyValue("    Paused              ", stats.isPaused(), pw, json, format);
                     if (stats.isFailing()) {
-                        pw.printf("    Failing since       : %s%n", stats.getFailingSince());
-                        pw.printf("    Latest error        : %s%n", stats.getLatestError());
+                        keyValue("    Failing since       ", stats.getFailingSince(), pw, json, format);
+                        keyValue("    Latest error        ", stats.getLatestError(), pw, json, format);
                     }
                 }
-                pw.println();
+                printWithNewLine(pw, "", format);
             }
+            endJsonObject(json);
         }
+        endJsonObject(json);
     }
 
-    private static void printTitle(PrintWriter pw, String title) {
-        pw.println(title);
-        pw.println(Strings.repeat("=", title.length()));
+    private static void printTitle(PrintWriter pw, String title, Format format) {
+        if (format == Format.TEXT) {
+            pw.println(title);
+            pw.println(Strings.repeat("=", title.length()));
+            pw.println();
+        }
     }
 
-    private void printIndexInfo(PrintWriter pw) {
+    private static void printWithNewLine(PrintWriter pw, String printLine, Format format) {
+        if (format == Format.TEXT) {
+            pw.println(printLine);
+        }
+    }
+
+    private void printIndexInfo(PrintWriter pw, JsopBuilder json, Format format) {
         ListMultimap<String, IndexInfo> infos = ArrayListMultimap.create();
         for (IndexInfo info : indexInfoService.getAllIndexInfo()) {
             infos.put(info.getType(), info);
         }
 
-        pw.printf("Total number of indexes : %d%n", infos.size());
+        keyValue("Total number of indexes ", infos.size(), pw, json, format);
+
         for (String type : infos.keySet()){
             List<IndexInfo> typedInfo = infos.get(type);
             String title = String.format("%s(%d)", type, typedInfo.size());
-            printTitle(pw, title);
-            pw.println();
+            printTitle(pw, title, format);
+            addJsonKey(json, type);
+            startJsonObject(json);
             for (IndexInfo info : typedInfo){
-                printIndexInfo(pw, info);
+                printIndexInfo(pw, json, info, format);
+                if (format == Format.TEXT) {
+                    if (info.hasIndexDefinitionChangedWithoutReindexing()) {
+                        pw.println("    Index definition changed without reindexing");
+                        String diff = info.getIndexDefinitionDiff();
+                        if (diff != null) {
+                            pw.println("    "+diff);
+                        }
+                    }
+                    pw.println();
+                }
             }
+            endJsonObject(json);
         }
     }
 
-    private static void printIndexInfo(PrintWriter pw, IndexInfo info) {
-        pw.println(info.getIndexPath());
-        pw.printf("    Type                    : %s%n", info.getType());
+
+    private static void printIndexInfo(PrintWriter pw, JsopBuilder json, IndexInfo info, Format format) {
+        if (format == Format.TEXT) {
+            pw.println(info.getIndexPath());
+        }
+        addJsonKey(json, info.getIndexPath());
+        startJsonObject(json);
+
+        keyValue("    Type                    ", info.getType(), pw, json, format);
         if (info.getAsyncLaneName() != null) {
-            pw.printf("    Async                   : true%n");
-            pw.printf("    Async lane name         : %s%n", info.getAsyncLaneName());
+            keyValue("    Async                    ", true, pw, json, format);
+            keyValue("    Async lane name          ", info.getAsyncLaneName(), pw, json, format);
         }
 
         if (info.getIndexedUpToTime() > 0){
-            pw.printf("    Last indexed up to      : %s%n", formatTime(info.getIndexedUpToTime()));
+            keyValue("    Last indexed up to       ", formatTime(info.getIndexedUpToTime()), pw, json, format);
         }
 
         if (info.getLastUpdatedTime() > 0){
-            pw.printf("    Last updated time       : %s%n", formatTime(info.getLastUpdatedTime()));
+            keyValue("     Last updated time       ", formatTime(info.getLastUpdatedTime()), pw, json, format);
+        }
+
+        if (info.getCreationTimestamp() > 0){
+            keyValue("     Creation time           ", formatTime(info.getCreationTimestamp()), pw, json, format);
+        }
+
+        if (info.getReindexCompletionTimestamp() > 0){
+            keyValue("     Reindex completion time ", formatTime(info.getReindexCompletionTimestamp()), pw, json, format);
         }
 
         if (info.getSizeInBytes() >= 0){
-            pw.printf("    Size                    : %s%n", IOUtils.humanReadableByteCount(info.getSizeInBytes()));
+            keyValue("    Size                     ", IOUtils.humanReadableByteCount(info.getSizeInBytes()), pw, json, format);

Review comment:
       > I disagree a bit here.
   
   That's fine, it's just my personal opinion. When I investigate a problem, in the Lucene index stats, it I usually search for "GB" and then look at only those that have this unit; or use grep "GB". I would miss entries with "TB" however. 
   
   So I argue that even for a human, using the same unit would make sense, assuming there is a sensible default unit.
   
   We could round to 3 digits after the comma (e.g. round up from 0.000001 GB => 0.001 GB).




-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: dev-unsubscribe@jackrabbit.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [jackrabbit-oak] nit0906 edited a comment on pull request #372: OAK-9566 | Improve index stats

Posted by GitBox <gi...@apache.org>.
nit0906 edited a comment on pull request #372:
URL: https://github.com/apache/jackrabbit-oak/pull/372#issuecomment-923107955


   @thomasmueller 
   >>> I wonder if the timestamps would be better listed in UTC?
   
   Sure - I transformed them in UTC now. And also added another property to show the sized in bytes (numeric) that can be used for alerts etc.


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: dev-unsubscribe@jackrabbit.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [jackrabbit-oak] nit0906 commented on a change in pull request #372: OAK-9566 | Improve index stats

Posted by GitBox <gi...@apache.org>.
nit0906 commented on a change in pull request #372:
URL: https://github.com/apache/jackrabbit-oak/pull/372#discussion_r712774461



##########
File path: oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/inventory/IndexPrinter.java
##########
@@ -66,97 +71,200 @@ public IndexPrinter(IndexInfoService indexInfoService, AsyncIndexInfoService asy
 
     @Override
     public void print(PrintWriter pw, Format format, boolean isZip) {
-        //TODO Highlight if failing
-        printAsyncIndexInfo(pw);
-        printIndexInfo(pw);
+
+        if (format == Format.JSON) {
+            JsopBuilder json = new JsopBuilder();
+            startJsonObject(json);
+            printAsyncIndexInfo(pw, json, format);
+            printIndexInfo(pw, json, format);
+            endJsonObject(json);
+            pw.print(JsopBuilder.prettyPrint(json.toString()));
+        } else {
+            //TODO Highlight if failing
+            printAsyncIndexInfo(pw, null, format);
+            printIndexInfo(pw, null, format);
+        }
     }
 
-    private void printAsyncIndexInfo(PrintWriter pw) {
+    private void printAsyncIndexInfo(PrintWriter pw, JsopBuilder json, Format format) {
         List<String> asyncLanes = ImmutableList.copyOf(asyncIndexInfoService.getAsyncLanes());
         String title = "Async Indexers State";
-        printTitle(pw, title);
-        pw.printf("Number of async indexer lanes : %d%n", asyncLanes.size());
-        pw.println();
+        printTitle(pw, title, format);
+        addJsonKey(json, title);
+        startJsonObject(json);
+        keyValue("Number of async indexer lanes ", asyncLanes.size(), pw, json, format);
+        printWithNewLine(pw, "", format);
+
         for (String lane : asyncLanes) {
-            pw.println(lane);
+            printWithNewLine(pw, lane, format);
+            addJsonKey(json, lane);
             AsyncIndexInfo info = asyncIndexInfoService.getInfo(lane);
+            startJsonObject(json);
             if (info != null) {
-                        pw.printf("    Last indexed to      : %s%n", formatTime(info.getLastIndexedTo()));
+                keyValue("    Last indexed to      ", formatTime(info.getLastIndexedTo()), pw, json, format);
                 IndexStatsMBean stats = info.getStatsMBean();
                 if (stats != null) {
-                        pw.printf("    Status              : %s%n", stats.getStatus());
-                        pw.printf("    Failing             : %s%n", stats.isFailing());
-                        pw.printf("    Paused              : %s%n", stats.isPaused());
+                    keyValue("    Status              ", stats.getStatus(), pw, json, format);
+                    keyValue("    Failing             ", stats.isFailing(), pw, json, format);
+                    keyValue("    Paused              ", stats.isPaused(), pw, json, format);
                     if (stats.isFailing()) {
-                        pw.printf("    Failing since       : %s%n", stats.getFailingSince());
-                        pw.printf("    Latest error        : %s%n", stats.getLatestError());
+                        keyValue("    Failing since       ", stats.getFailingSince(), pw, json, format);
+                        keyValue("    Latest error        ", stats.getLatestError(), pw, json, format);
                     }
                 }
-                pw.println();
+                printWithNewLine(pw, "", format);
             }
+            endJsonObject(json);
         }
+        endJsonObject(json);
     }
 
-    private static void printTitle(PrintWriter pw, String title) {
-        pw.println(title);
-        pw.println(Strings.repeat("=", title.length()));
+    private static void printTitle(PrintWriter pw, String title, Format format) {
+        if (format == Format.TEXT) {
+            pw.println(title);
+            pw.println(Strings.repeat("=", title.length()));
+            pw.println();
+        }
     }
 
-    private void printIndexInfo(PrintWriter pw) {
+    private static void printWithNewLine(PrintWriter pw, String printLine, Format format) {
+        if (format == Format.TEXT) {
+            pw.println(printLine);
+        }
+    }
+
+    private void printIndexInfo(PrintWriter pw, JsopBuilder json, Format format) {
         ListMultimap<String, IndexInfo> infos = ArrayListMultimap.create();
         for (IndexInfo info : indexInfoService.getAllIndexInfo()) {
             infos.put(info.getType(), info);
         }
 
-        pw.printf("Total number of indexes : %d%n", infos.size());
+        keyValue("Total number of indexes ", infos.size(), pw, json, format);
+
         for (String type : infos.keySet()){
             List<IndexInfo> typedInfo = infos.get(type);
             String title = String.format("%s(%d)", type, typedInfo.size());
-            printTitle(pw, title);
-            pw.println();
+            printTitle(pw, title, format);
+            addJsonKey(json, type);
+            startJsonObject(json);
             for (IndexInfo info : typedInfo){
-                printIndexInfo(pw, info);
+                printIndexInfo(pw, json, info, format);
             }
+            endJsonObject(json);
         }
     }
 
-    private static void printIndexInfo(PrintWriter pw, IndexInfo info) {
-        pw.println(info.getIndexPath());
-        pw.printf("    Type                    : %s%n", info.getType());
+
+    private static void printIndexInfo(PrintWriter pw, JsopBuilder json, IndexInfo info, Format format) {
+        if (format == Format.TEXT) {
+            pw.println(info.getIndexPath());
+        }
+        addJsonKey(json, info.getIndexPath());
+        startJsonObject(json);
+
+        keyValue("    Type                    ", info.getType(), pw, json, format);
         if (info.getAsyncLaneName() != null) {
-            pw.printf("    Async                   : true%n");
-            pw.printf("    Async lane name         : %s%n", info.getAsyncLaneName());
+            keyValue("    Async                    ", true, pw, json, format);
+            keyValue("    Async lane name          ", info.getAsyncLaneName(), pw, json, format);
         }
 
         if (info.getIndexedUpToTime() > 0){
-            pw.printf("    Last indexed up to      : %s%n", formatTime(info.getIndexedUpToTime()));
+            keyValue("    Last indexed up to       ", formatTime(info.getIndexedUpToTime()), pw, json, format);
         }
 
         if (info.getLastUpdatedTime() > 0){
-            pw.printf("    Last updated time       : %s%n", formatTime(info.getLastUpdatedTime()));
+            keyValue("     Last updated time       ", formatTime(info.getLastUpdatedTime()), pw, json, format);
+        }
+
+        if (info.getCreationTimestamp() > 0){
+            keyValue("     Creation time           ", formatTime(info.getCreationTimestamp()), pw, json, format);
+        }
+
+        if (info.getReindexCompletionTimestamp() > 0){
+            keyValue("     Reindex completion time ", formatTime(info.getReindexCompletionTimestamp()), pw, json, format);
         }
 
         if (info.getSizeInBytes() >= 0){
-            pw.printf("    Size                    : %s%n", IOUtils.humanReadableByteCount(info.getSizeInBytes()));
+            keyValue("    Size                     ", IOUtils.humanReadableByteCount(info.getSizeInBytes()), pw, json, format);
+            keyValue("    Size (in Bytes)          ", info.getSizeInBytes(), pw, json, format);
+        }
+
+        if (info.getSuggestSizeInBytes() >= 0){
+            keyValue("    Suggest size             ", IOUtils.humanReadableByteCount(info.getSuggestSizeInBytes()), pw, json, format);
+            keyValue("    Suggest size (in Bytes)  ", info.getSuggestSizeInBytes(), pw, json, format);
         }
 
         if (info.getEstimatedEntryCount() >= 0){
-            pw.printf("    Estimated entry count   : %d%n", info.getEstimatedEntryCount());
+            keyValue("    Estimated entry count    ", info.getEstimatedEntryCount(), pw, json, format);
+        }
+
+        if ("lucene".equals(info.getType())) {
+            // Only valid for lucene type indexes, for others it will simply show false.
+            keyValue("    Has hidden oak mount     ", info.hasHiddenOakLibsMount(), pw, json, format);
+            keyValue("    Has property index       ", info.hasPropertyIndexNode(), pw, json, format);
         }
 
         if (info.hasIndexDefinitionChangedWithoutReindexing()) {
-            pw.println("    Index definition changed without reindexing");
             String diff = info.getIndexDefinitionDiff();
             if (diff != null) {
-                pw.println("    "+diff);
+                keyValue("    Index definition changed without reindexing ", diff, pw, json, format);
+                printWithNewLine(pw, "", format);
             }
         }
-        pw.println();
+        endJsonObject(json);
     }
 
     private static String formatTime(long time){
         Calendar cal = Calendar.getInstance();
         cal.setTimeInMillis(time);
-        return ISO8601.format(cal);
+        Date date = cal.getTime();
+        SimpleDateFormat outputFmt = new SimpleDateFormat("yyyy-mm-dd'T'HH:mm:ss.s z");
+        outputFmt.setTimeZone(TimeZone.getTimeZone("UTC"));
+        return outputFmt.format(date);
+    }
+
+    private static void keyValue(String key, Object value, PrintWriter pw, JsopBuilder json, Format format) {
+        // In case the key is null or an emppty String or value is null,
+        // throw an IllegalArgumentException.
+        if (value == null || key == null || key.equals("")) {

Review comment:
       done




-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: dev-unsubscribe@jackrabbit.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [jackrabbit-oak] thomasmueller commented on a change in pull request #372: OAK-9566 | Improve index stats

Posted by GitBox <gi...@apache.org>.
thomasmueller commented on a change in pull request #372:
URL: https://github.com/apache/jackrabbit-oak/pull/372#discussion_r712185794



##########
File path: oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/inventory/IndexPrinter.java
##########
@@ -66,97 +68,190 @@ public IndexPrinter(IndexInfoService indexInfoService, AsyncIndexInfoService asy
 
     @Override
     public void print(PrintWriter pw, Format format, boolean isZip) {
-        //TODO Highlight if failing
-        printAsyncIndexInfo(pw);
-        printIndexInfo(pw);
+
+        if (format == Format.JSON) {
+            JsopBuilder json = new JsopBuilder();
+            startJsonObject(json);
+            printAsyncIndexInfo(pw, json, format);
+            printIndexInfo(pw, json, format);
+            endJsonObject(json);
+            pw.print(JsopBuilder.prettyPrint(json.toString()));
+        } else {
+            //TODO Highlight if failing
+            printAsyncIndexInfo(pw, null, format);
+            printIndexInfo(pw, null, format);
+        }
     }
 
-    private void printAsyncIndexInfo(PrintWriter pw) {
+    private void printAsyncIndexInfo(PrintWriter pw, JsopBuilder json, Format format) {
         List<String> asyncLanes = ImmutableList.copyOf(asyncIndexInfoService.getAsyncLanes());
         String title = "Async Indexers State";
-        printTitle(pw, title);
-        pw.printf("Number of async indexer lanes : %d%n", asyncLanes.size());
-        pw.println();
+        printTitle(pw, title, format);
+        addJsonKey(json, title);
+        startJsonObject(json);
+        keyValue("Number of async indexer lanes ", asyncLanes.size(), pw, json, format);
+        printWithNewLine(pw, "", format);
+
         for (String lane : asyncLanes) {
-            pw.println(lane);
+            printWithNewLine(pw, lane, format);
+            addJsonKey(json, lane);
             AsyncIndexInfo info = asyncIndexInfoService.getInfo(lane);
+            startJsonObject(json);
             if (info != null) {
-                        pw.printf("    Last indexed to      : %s%n", formatTime(info.getLastIndexedTo()));
+                keyValue("    Last indexed to      ", formatTime(info.getLastIndexedTo()), pw, json, format);
                 IndexStatsMBean stats = info.getStatsMBean();
                 if (stats != null) {
-                        pw.printf("    Status              : %s%n", stats.getStatus());
-                        pw.printf("    Failing             : %s%n", stats.isFailing());
-                        pw.printf("    Paused              : %s%n", stats.isPaused());
+                    keyValue("    Status              ", stats.getStatus(), pw, json, format);
+                    keyValue("    Failing             ", stats.isFailing(), pw, json, format);
+                    keyValue("    Paused              ", stats.isPaused(), pw, json, format);
                     if (stats.isFailing()) {
-                        pw.printf("    Failing since       : %s%n", stats.getFailingSince());
-                        pw.printf("    Latest error        : %s%n", stats.getLatestError());
+                        keyValue("    Failing since       ", stats.getFailingSince(), pw, json, format);
+                        keyValue("    Latest error        ", stats.getLatestError(), pw, json, format);
                     }
                 }
-                pw.println();
+                printWithNewLine(pw, "", format);
             }
+            endJsonObject(json);
         }
+        endJsonObject(json);
     }
 
-    private static void printTitle(PrintWriter pw, String title) {
-        pw.println(title);
-        pw.println(Strings.repeat("=", title.length()));
+    private static void printTitle(PrintWriter pw, String title, Format format) {
+        if (format == Format.TEXT) {
+            pw.println(title);
+            pw.println(Strings.repeat("=", title.length()));
+            pw.println();
+        }
     }
 
-    private void printIndexInfo(PrintWriter pw) {
+    private static void printWithNewLine(PrintWriter pw, String printLine, Format format) {
+        if (format == Format.TEXT) {
+            pw.println(printLine);
+        }
+    }
+
+    private void printIndexInfo(PrintWriter pw, JsopBuilder json, Format format) {
         ListMultimap<String, IndexInfo> infos = ArrayListMultimap.create();
         for (IndexInfo info : indexInfoService.getAllIndexInfo()) {
             infos.put(info.getType(), info);
         }
 
-        pw.printf("Total number of indexes : %d%n", infos.size());
+        keyValue("Total number of indexes ", infos.size(), pw, json, format);
+
         for (String type : infos.keySet()){
             List<IndexInfo> typedInfo = infos.get(type);
             String title = String.format("%s(%d)", type, typedInfo.size());
-            printTitle(pw, title);
-            pw.println();
+            printTitle(pw, title, format);
+            addJsonKey(json, type);
+            startJsonObject(json);
             for (IndexInfo info : typedInfo){
-                printIndexInfo(pw, info);
+                printIndexInfo(pw, json, info, format);
+                if (format == Format.TEXT) {
+                    if (info.hasIndexDefinitionChangedWithoutReindexing()) {
+                        pw.println("    Index definition changed without reindexing");
+                        String diff = info.getIndexDefinitionDiff();
+                        if (diff != null) {
+                            pw.println("    "+diff);
+                        }
+                    }
+                    pw.println();
+                }
             }
+            endJsonObject(json);
         }
     }
 
-    private static void printIndexInfo(PrintWriter pw, IndexInfo info) {
-        pw.println(info.getIndexPath());
-        pw.printf("    Type                    : %s%n", info.getType());
+
+    private static void printIndexInfo(PrintWriter pw, JsopBuilder json, IndexInfo info, Format format) {
+        if (format == Format.TEXT) {
+            pw.println(info.getIndexPath());
+        }
+        addJsonKey(json, info.getIndexPath());
+        startJsonObject(json);
+
+        keyValue("    Type                    ", info.getType(), pw, json, format);
         if (info.getAsyncLaneName() != null) {
-            pw.printf("    Async                   : true%n");
-            pw.printf("    Async lane name         : %s%n", info.getAsyncLaneName());
+            keyValue("    Async                    ", true, pw, json, format);
+            keyValue("    Async lane name          ", info.getAsyncLaneName(), pw, json, format);
         }
 
         if (info.getIndexedUpToTime() > 0){
-            pw.printf("    Last indexed up to      : %s%n", formatTime(info.getIndexedUpToTime()));
+            keyValue("    Last indexed up to       ", formatTime(info.getIndexedUpToTime()), pw, json, format);
         }
 
         if (info.getLastUpdatedTime() > 0){
-            pw.printf("    Last updated time       : %s%n", formatTime(info.getLastUpdatedTime()));
+            keyValue("     Last updated time       ", formatTime(info.getLastUpdatedTime()), pw, json, format);
+        }
+
+        if (info.getCreationTimestamp() > 0){
+            keyValue("     Creation time           ", formatTime(info.getCreationTimestamp()), pw, json, format);
+        }
+
+        if (info.getReindexCompletionTimestamp() > 0){
+            keyValue("     Reindex completion time ", formatTime(info.getReindexCompletionTimestamp()), pw, json, format);
         }
 
         if (info.getSizeInBytes() >= 0){
-            pw.printf("    Size                    : %s%n", IOUtils.humanReadableByteCount(info.getSizeInBytes()));
+            keyValue("    Size                     ", IOUtils.humanReadableByteCount(info.getSizeInBytes()), pw, json, format);

Review comment:
       > If we want to use these for some calculations/alerting
   
   Looking at the json output, I think it would make sense to use it for alerting... What about we list both the "human readable" as well as the "same unit" numbers?




-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: dev-unsubscribe@jackrabbit.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [jackrabbit-oak] nit0906 commented on a change in pull request #372: OAK-9566 | Improve index stats

Posted by GitBox <gi...@apache.org>.
nit0906 commented on a change in pull request #372:
URL: https://github.com/apache/jackrabbit-oak/pull/372#discussion_r711983030



##########
File path: oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/inventory/IndexPrinter.java
##########
@@ -66,97 +68,190 @@ public IndexPrinter(IndexInfoService indexInfoService, AsyncIndexInfoService asy
 
     @Override
     public void print(PrintWriter pw, Format format, boolean isZip) {
-        //TODO Highlight if failing
-        printAsyncIndexInfo(pw);
-        printIndexInfo(pw);
+
+        if (format == Format.JSON) {
+            JsopBuilder json = new JsopBuilder();
+            startJsonObject(json);
+            printAsyncIndexInfo(pw, json, format);
+            printIndexInfo(pw, json, format);
+            endJsonObject(json);
+            pw.print(JsopBuilder.prettyPrint(json.toString()));
+        } else {
+            //TODO Highlight if failing
+            printAsyncIndexInfo(pw, null, format);
+            printIndexInfo(pw, null, format);
+        }
     }
 
-    private void printAsyncIndexInfo(PrintWriter pw) {
+    private void printAsyncIndexInfo(PrintWriter pw, JsopBuilder json, Format format) {
         List<String> asyncLanes = ImmutableList.copyOf(asyncIndexInfoService.getAsyncLanes());
         String title = "Async Indexers State";
-        printTitle(pw, title);
-        pw.printf("Number of async indexer lanes : %d%n", asyncLanes.size());
-        pw.println();
+        printTitle(pw, title, format);
+        addJsonKey(json, title);
+        startJsonObject(json);
+        keyValue("Number of async indexer lanes ", asyncLanes.size(), pw, json, format);
+        printWithNewLine(pw, "", format);
+
         for (String lane : asyncLanes) {
-            pw.println(lane);
+            printWithNewLine(pw, lane, format);
+            addJsonKey(json, lane);
             AsyncIndexInfo info = asyncIndexInfoService.getInfo(lane);
+            startJsonObject(json);
             if (info != null) {
-                        pw.printf("    Last indexed to      : %s%n", formatTime(info.getLastIndexedTo()));
+                keyValue("    Last indexed to      ", formatTime(info.getLastIndexedTo()), pw, json, format);
                 IndexStatsMBean stats = info.getStatsMBean();
                 if (stats != null) {
-                        pw.printf("    Status              : %s%n", stats.getStatus());
-                        pw.printf("    Failing             : %s%n", stats.isFailing());
-                        pw.printf("    Paused              : %s%n", stats.isPaused());
+                    keyValue("    Status              ", stats.getStatus(), pw, json, format);
+                    keyValue("    Failing             ", stats.isFailing(), pw, json, format);
+                    keyValue("    Paused              ", stats.isPaused(), pw, json, format);
                     if (stats.isFailing()) {
-                        pw.printf("    Failing since       : %s%n", stats.getFailingSince());
-                        pw.printf("    Latest error        : %s%n", stats.getLatestError());
+                        keyValue("    Failing since       ", stats.getFailingSince(), pw, json, format);
+                        keyValue("    Latest error        ", stats.getLatestError(), pw, json, format);
                     }
                 }
-                pw.println();
+                printWithNewLine(pw, "", format);
             }
+            endJsonObject(json);
         }
+        endJsonObject(json);
     }
 
-    private static void printTitle(PrintWriter pw, String title) {
-        pw.println(title);
-        pw.println(Strings.repeat("=", title.length()));
+    private static void printTitle(PrintWriter pw, String title, Format format) {
+        if (format == Format.TEXT) {
+            pw.println(title);
+            pw.println(Strings.repeat("=", title.length()));
+            pw.println();
+        }
     }
 
-    private void printIndexInfo(PrintWriter pw) {
+    private static void printWithNewLine(PrintWriter pw, String printLine, Format format) {
+        if (format == Format.TEXT) {
+            pw.println(printLine);
+        }
+    }
+
+    private void printIndexInfo(PrintWriter pw, JsopBuilder json, Format format) {
         ListMultimap<String, IndexInfo> infos = ArrayListMultimap.create();
         for (IndexInfo info : indexInfoService.getAllIndexInfo()) {
             infos.put(info.getType(), info);
         }
 
-        pw.printf("Total number of indexes : %d%n", infos.size());
+        keyValue("Total number of indexes ", infos.size(), pw, json, format);
+
         for (String type : infos.keySet()){
             List<IndexInfo> typedInfo = infos.get(type);
             String title = String.format("%s(%d)", type, typedInfo.size());
-            printTitle(pw, title);
-            pw.println();
+            printTitle(pw, title, format);
+            addJsonKey(json, type);
+            startJsonObject(json);
             for (IndexInfo info : typedInfo){
-                printIndexInfo(pw, info);
+                printIndexInfo(pw, json, info, format);
+                if (format == Format.TEXT) {
+                    if (info.hasIndexDefinitionChangedWithoutReindexing()) {
+                        pw.println("    Index definition changed without reindexing");
+                        String diff = info.getIndexDefinitionDiff();
+                        if (diff != null) {
+                            pw.println("    "+diff);
+                        }
+                    }
+                    pw.println();
+                }
             }
+            endJsonObject(json);
         }
     }
 
-    private static void printIndexInfo(PrintWriter pw, IndexInfo info) {
-        pw.println(info.getIndexPath());
-        pw.printf("    Type                    : %s%n", info.getType());
+
+    private static void printIndexInfo(PrintWriter pw, JsopBuilder json, IndexInfo info, Format format) {
+        if (format == Format.TEXT) {
+            pw.println(info.getIndexPath());
+        }
+        addJsonKey(json, info.getIndexPath());
+        startJsonObject(json);
+
+        keyValue("    Type                    ", info.getType(), pw, json, format);
         if (info.getAsyncLaneName() != null) {
-            pw.printf("    Async                   : true%n");
-            pw.printf("    Async lane name         : %s%n", info.getAsyncLaneName());
+            keyValue("    Async                    ", true, pw, json, format);
+            keyValue("    Async lane name          ", info.getAsyncLaneName(), pw, json, format);
         }
 
         if (info.getIndexedUpToTime() > 0){
-            pw.printf("    Last indexed up to      : %s%n", formatTime(info.getIndexedUpToTime()));
+            keyValue("    Last indexed up to       ", formatTime(info.getIndexedUpToTime()), pw, json, format);
         }
 
         if (info.getLastUpdatedTime() > 0){
-            pw.printf("    Last updated time       : %s%n", formatTime(info.getLastUpdatedTime()));
+            keyValue("     Last updated time       ", formatTime(info.getLastUpdatedTime()), pw, json, format);
+        }
+
+        if (info.getCreationTimestamp() > 0){
+            keyValue("     Creation time           ", formatTime(info.getCreationTimestamp()), pw, json, format);
+        }
+
+        if (info.getReindexCompletionTimestamp() > 0){
+            keyValue("     Reindex completion time ", formatTime(info.getReindexCompletionTimestamp()), pw, json, format);
         }
 
         if (info.getSizeInBytes() >= 0){
-            pw.printf("    Size                    : %s%n", IOUtils.humanReadableByteCount(info.getSizeInBytes()));
+            keyValue("    Size                     ", IOUtils.humanReadableByteCount(info.getSizeInBytes()), pw, json, format);

Review comment:
       @thomasmueller  - I disagree a bit here. Since this is human readable format (that would not be consumed by any code for calculations/alerting ), so I think, 1 B makes more sense than 0.000001 GB. 
   
   If we want to use these for some calculations/alerting - then I agree with your point that they should be in the same unit (and in which case we would have to change the formatting even a bit more ), because here the o/p would be string - 10B, 10MB, 10GB and like that.




-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: dev-unsubscribe@jackrabbit.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [jackrabbit-oak] nit0906 commented on a change in pull request #372: OAK-9566 | Improve index stats

Posted by GitBox <gi...@apache.org>.
nit0906 commented on a change in pull request #372:
URL: https://github.com/apache/jackrabbit-oak/pull/372#discussion_r712767085



##########
File path: oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/inventory/IndexPrinter.java
##########
@@ -66,97 +71,200 @@ public IndexPrinter(IndexInfoService indexInfoService, AsyncIndexInfoService asy
 
     @Override
     public void print(PrintWriter pw, Format format, boolean isZip) {
-        //TODO Highlight if failing
-        printAsyncIndexInfo(pw);
-        printIndexInfo(pw);
+
+        if (format == Format.JSON) {
+            JsopBuilder json = new JsopBuilder();
+            startJsonObject(json);
+            printAsyncIndexInfo(pw, json, format);
+            printIndexInfo(pw, json, format);
+            endJsonObject(json);
+            pw.print(JsopBuilder.prettyPrint(json.toString()));
+        } else {
+            //TODO Highlight if failing
+            printAsyncIndexInfo(pw, null, format);
+            printIndexInfo(pw, null, format);
+        }
     }
 
-    private void printAsyncIndexInfo(PrintWriter pw) {
+    private void printAsyncIndexInfo(PrintWriter pw, JsopBuilder json, Format format) {
         List<String> asyncLanes = ImmutableList.copyOf(asyncIndexInfoService.getAsyncLanes());
         String title = "Async Indexers State";
-        printTitle(pw, title);
-        pw.printf("Number of async indexer lanes : %d%n", asyncLanes.size());
-        pw.println();
+        printTitle(pw, title, format);
+        addJsonKey(json, title);
+        startJsonObject(json);
+        keyValue("Number of async indexer lanes ", asyncLanes.size(), pw, json, format);
+        printWithNewLine(pw, "", format);
+
         for (String lane : asyncLanes) {
-            pw.println(lane);
+            printWithNewLine(pw, lane, format);
+            addJsonKey(json, lane);
             AsyncIndexInfo info = asyncIndexInfoService.getInfo(lane);
+            startJsonObject(json);
             if (info != null) {
-                        pw.printf("    Last indexed to      : %s%n", formatTime(info.getLastIndexedTo()));
+                keyValue("    Last indexed to      ", formatTime(info.getLastIndexedTo()), pw, json, format);
                 IndexStatsMBean stats = info.getStatsMBean();
                 if (stats != null) {
-                        pw.printf("    Status              : %s%n", stats.getStatus());
-                        pw.printf("    Failing             : %s%n", stats.isFailing());
-                        pw.printf("    Paused              : %s%n", stats.isPaused());
+                    keyValue("    Status              ", stats.getStatus(), pw, json, format);
+                    keyValue("    Failing             ", stats.isFailing(), pw, json, format);
+                    keyValue("    Paused              ", stats.isPaused(), pw, json, format);
                     if (stats.isFailing()) {
-                        pw.printf("    Failing since       : %s%n", stats.getFailingSince());
-                        pw.printf("    Latest error        : %s%n", stats.getLatestError());
+                        keyValue("    Failing since       ", stats.getFailingSince(), pw, json, format);
+                        keyValue("    Latest error        ", stats.getLatestError(), pw, json, format);
                     }
                 }
-                pw.println();
+                printWithNewLine(pw, "", format);
             }
+            endJsonObject(json);
         }
+        endJsonObject(json);
     }
 
-    private static void printTitle(PrintWriter pw, String title) {
-        pw.println(title);
-        pw.println(Strings.repeat("=", title.length()));
+    private static void printTitle(PrintWriter pw, String title, Format format) {
+        if (format == Format.TEXT) {
+            pw.println(title);
+            pw.println(Strings.repeat("=", title.length()));
+            pw.println();
+        }
     }
 
-    private void printIndexInfo(PrintWriter pw) {
+    private static void printWithNewLine(PrintWriter pw, String printLine, Format format) {
+        if (format == Format.TEXT) {
+            pw.println(printLine);
+        }
+    }
+
+    private void printIndexInfo(PrintWriter pw, JsopBuilder json, Format format) {
         ListMultimap<String, IndexInfo> infos = ArrayListMultimap.create();
         for (IndexInfo info : indexInfoService.getAllIndexInfo()) {
             infos.put(info.getType(), info);
         }
 
-        pw.printf("Total number of indexes : %d%n", infos.size());
+        keyValue("Total number of indexes ", infos.size(), pw, json, format);
+
         for (String type : infos.keySet()){
             List<IndexInfo> typedInfo = infos.get(type);
             String title = String.format("%s(%d)", type, typedInfo.size());
-            printTitle(pw, title);
-            pw.println();
+            printTitle(pw, title, format);
+            addJsonKey(json, type);
+            startJsonObject(json);
             for (IndexInfo info : typedInfo){
-                printIndexInfo(pw, info);
+                printIndexInfo(pw, json, info, format);
             }
+            endJsonObject(json);
         }
     }
 
-    private static void printIndexInfo(PrintWriter pw, IndexInfo info) {
-        pw.println(info.getIndexPath());
-        pw.printf("    Type                    : %s%n", info.getType());
+
+    private static void printIndexInfo(PrintWriter pw, JsopBuilder json, IndexInfo info, Format format) {
+        if (format == Format.TEXT) {
+            pw.println(info.getIndexPath());
+        }
+        addJsonKey(json, info.getIndexPath());
+        startJsonObject(json);
+
+        keyValue("    Type                    ", info.getType(), pw, json, format);
         if (info.getAsyncLaneName() != null) {
-            pw.printf("    Async                   : true%n");
-            pw.printf("    Async lane name         : %s%n", info.getAsyncLaneName());
+            keyValue("    Async                    ", true, pw, json, format);
+            keyValue("    Async lane name          ", info.getAsyncLaneName(), pw, json, format);
         }
 
         if (info.getIndexedUpToTime() > 0){
-            pw.printf("    Last indexed up to      : %s%n", formatTime(info.getIndexedUpToTime()));
+            keyValue("    Last indexed up to       ", formatTime(info.getIndexedUpToTime()), pw, json, format);
         }
 
         if (info.getLastUpdatedTime() > 0){
-            pw.printf("    Last updated time       : %s%n", formatTime(info.getLastUpdatedTime()));
+            keyValue("     Last updated time       ", formatTime(info.getLastUpdatedTime()), pw, json, format);
+        }
+
+        if (info.getCreationTimestamp() > 0){
+            keyValue("     Creation time           ", formatTime(info.getCreationTimestamp()), pw, json, format);
+        }
+
+        if (info.getReindexCompletionTimestamp() > 0){
+            keyValue("     Reindex completion time ", formatTime(info.getReindexCompletionTimestamp()), pw, json, format);
         }
 
         if (info.getSizeInBytes() >= 0){
-            pw.printf("    Size                    : %s%n", IOUtils.humanReadableByteCount(info.getSizeInBytes()));
+            keyValue("    Size                     ", IOUtils.humanReadableByteCount(info.getSizeInBytes()), pw, json, format);
+            keyValue("    Size (in Bytes)          ", info.getSizeInBytes(), pw, json, format);
+        }
+
+        if (info.getSuggestSizeInBytes() >= 0){
+            keyValue("    Suggest size             ", IOUtils.humanReadableByteCount(info.getSuggestSizeInBytes()), pw, json, format);
+            keyValue("    Suggest size (in Bytes)  ", info.getSuggestSizeInBytes(), pw, json, format);
         }
 
         if (info.getEstimatedEntryCount() >= 0){
-            pw.printf("    Estimated entry count   : %d%n", info.getEstimatedEntryCount());
+            keyValue("    Estimated entry count    ", info.getEstimatedEntryCount(), pw, json, format);
+        }
+
+        if ("lucene".equals(info.getType())) {
+            // Only valid for lucene type indexes, for others it will simply show false.
+            keyValue("    Has hidden oak mount     ", info.hasHiddenOakLibsMount(), pw, json, format);
+            keyValue("    Has property index       ", info.hasPropertyIndexNode(), pw, json, format);
         }
 
         if (info.hasIndexDefinitionChangedWithoutReindexing()) {
-            pw.println("    Index definition changed without reindexing");
             String diff = info.getIndexDefinitionDiff();
             if (diff != null) {
-                pw.println("    "+diff);
+                keyValue("    Index definition changed without reindexing ", diff, pw, json, format);
+                printWithNewLine(pw, "", format);
             }
         }
-        pw.println();
+        endJsonObject(json);
     }
 
     private static String formatTime(long time){
         Calendar cal = Calendar.getInstance();
         cal.setTimeInMillis(time);
-        return ISO8601.format(cal);
+        Date date = cal.getTime();
+        SimpleDateFormat outputFmt = new SimpleDateFormat("yyyy-mm-dd'T'HH:mm:ss.s z");
+        outputFmt.setTimeZone(TimeZone.getTimeZone("UTC"));
+        return outputFmt.format(date);
+    }
+
+    private static void keyValue(String key, Object value, PrintWriter pw, JsopBuilder json, Format format) {
+        // In case the key is null or an emppty String or value is null,
+        // throw an IllegalArgumentException.
+        if (value == null || key == null || key.equals("")) {

Review comment:
       @thomasmueller 
   I actually added the check post your comment earlier on - 
   
   > I would probably handle "null" separately at the beginning (if value == null). Could throw an exception.
   
   I can remove it .




-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: dev-unsubscribe@jackrabbit.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [jackrabbit-oak] fabriziofortino commented on a change in pull request #372: OAK-9566 | Improve index stats

Posted by GitBox <gi...@apache.org>.
fabriziofortino commented on a change in pull request #372:
URL: https://github.com/apache/jackrabbit-oak/pull/372#discussion_r711923411



##########
File path: oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/inventory/IndexPrinter.java
##########
@@ -46,7 +47,8 @@
         property = {
             "felix.inventory.printer.name=oak-index-stats",
             "felix.inventory.printer.title=Oak Index Stats",
-            "felix.inventory.printer.format=TEXT"
+            "felix.inventory.printer.format=TEXT",
+                "felix.inventory.printer.format=JSON"

Review comment:
       minor: align formatting

##########
File path: oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/inventory/IndexPrinter.java
##########
@@ -66,97 +68,193 @@ public IndexPrinter(IndexInfoService indexInfoService, AsyncIndexInfoService asy
 
     @Override
     public void print(PrintWriter pw, Format format, boolean isZip) {
-        //TODO Highlight if failing
-        printAsyncIndexInfo(pw);
-        printIndexInfo(pw);
+
+        if (format == Format.JSON) {
+            JsopBuilder json = new JsopBuilder();
+            startJsonObject(json);
+            printAsyncIndexInfo(pw, json, format);
+            printIndexInfo(pw, json, format);
+            endJsonObject(json);
+            pw.print(JsopBuilder.prettyPrint(json.toString()));
+        } else {
+            //TODO Highlight if failing
+            printAsyncIndexInfo(pw, null, format);
+            printIndexInfo(pw, null, format);
+        }
     }
 
-    private void printAsyncIndexInfo(PrintWriter pw) {
+    private void printAsyncIndexInfo(PrintWriter pw, JsopBuilder json, Format format) {
         List<String> asyncLanes = ImmutableList.copyOf(asyncIndexInfoService.getAsyncLanes());
         String title = "Async Indexers State";
-        printTitle(pw, title);
-        pw.printf("Number of async indexer lanes : %d%n", asyncLanes.size());
-        pw.println();
+        printTitle(pw, title, format);
+        addJsonKey(json, title);
+        startJsonObject(json);
+        keyValue("Number of async indexer lanes ", asyncLanes.size(), pw, json, format);
+        printWithNewLine(pw, "", format);
+
         for (String lane : asyncLanes) {
-            pw.println(lane);
+            printWithNewLine(pw, lane, format);
+            addJsonKey(json, lane);
             AsyncIndexInfo info = asyncIndexInfoService.getInfo(lane);
             if (info != null) {
-                        pw.printf("    Last indexed to      : %s%n", formatTime(info.getLastIndexedTo()));
+                startJsonObject(json);
+                keyValue("    Last indexed to      ", formatTime(info.getLastIndexedTo()), pw, json, format);
                 IndexStatsMBean stats = info.getStatsMBean();
                 if (stats != null) {
-                        pw.printf("    Status              : %s%n", stats.getStatus());
-                        pw.printf("    Failing             : %s%n", stats.isFailing());
-                        pw.printf("    Paused              : %s%n", stats.isPaused());
+                    keyValue("    Status              ", stats.getStatus(), pw, json, format);
+                    keyValue("    Failing             ", stats.isFailing(), pw, json, format);
+                    keyValue("    Paused              ", stats.isPaused(), pw, json, format);
                     if (stats.isFailing()) {
-                        pw.printf("    Failing since       : %s%n", stats.getFailingSince());
-                        pw.printf("    Latest error        : %s%n", stats.getLatestError());
+                        keyValue("    Failing since       ", stats.getFailingSince(), pw, json, format);
+                        keyValue("    Latest error        ", stats.getLatestError(), pw, json, format);
                     }
                 }
-                pw.println();
+                printWithNewLine(pw, "", format);
+                endJsonObject(json);
+            } else {
+                startJsonObject(json);
+                endJsonObject(json);
             }
         }
+        endJsonObject(json);
     }
 
-    private static void printTitle(PrintWriter pw, String title) {
-        pw.println(title);
-        pw.println(Strings.repeat("=", title.length()));
+    private static void printTitle(PrintWriter pw, String title, Format format) {
+        if (format == Format.TEXT) {
+            pw.println(title);
+            pw.println(Strings.repeat("=", title.length()));
+            pw.println();
+        }
     }
 
-    private void printIndexInfo(PrintWriter pw) {
+    private static void printWithNewLine(PrintWriter pw, String printLine, Format format) {
+        if (format == Format.TEXT) {
+            pw.println(printLine);
+        }
+    }
+
+    private void printIndexInfo(PrintWriter pw, JsopBuilder json, Format format) {
         ListMultimap<String, IndexInfo> infos = ArrayListMultimap.create();
         for (IndexInfo info : indexInfoService.getAllIndexInfo()) {
             infos.put(info.getType(), info);
         }
 
-        pw.printf("Total number of indexes : %d%n", infos.size());
+        keyValue("Total number of indexes ", infos.size(), pw, json, format);
+
         for (String type : infos.keySet()){
             List<IndexInfo> typedInfo = infos.get(type);
             String title = String.format("%s(%d)", type, typedInfo.size());
-            printTitle(pw, title);
-            pw.println();
+            printTitle(pw, title, format);
+            addJsonKey(json, type);
+            startJsonObject(json);
             for (IndexInfo info : typedInfo){
-                printIndexInfo(pw, info);
+                printIndexInfo(pw, json, info, format);
+                if (format == Format.TEXT) {
+                    if (info.hasIndexDefinitionChangedWithoutReindexing()) {
+                        pw.println("    Index definition changed without reindexing");
+                        String diff = info.getIndexDefinitionDiff();
+                        if (diff != null) {
+                            pw.println("    "+diff);
+                        }
+                    }
+                    pw.println();
+                }
             }
+            endJsonObject(json);
         }
     }
 
-    private static void printIndexInfo(PrintWriter pw, IndexInfo info) {
-        pw.println(info.getIndexPath());
-        pw.printf("    Type                    : %s%n", info.getType());
+
+    private static void printIndexInfo(PrintWriter pw, JsopBuilder json, IndexInfo info, Format format) {
+        if (format == Format.TEXT) {
+            pw.println(info.getIndexPath());
+        }
+        addJsonKey(json, info.getIndexPath());
+        startJsonObject(json);
+
+        keyValue("    Type                    ", info.getType(), pw, json, format);
         if (info.getAsyncLaneName() != null) {
-            pw.printf("    Async                   : true%n");
-            pw.printf("    Async lane name         : %s%n", info.getAsyncLaneName());
+            keyValue("    Async                    ", true, pw, json, format);
+            keyValue("    Async lane name          ", info.getAsyncLaneName(), pw, json, format);
         }
 
         if (info.getIndexedUpToTime() > 0){
-            pw.printf("    Last indexed up to      : %s%n", formatTime(info.getIndexedUpToTime()));
+            keyValue("    Last indexed up to       ", formatTime(info.getIndexedUpToTime()), pw, json, format);
         }
 
         if (info.getLastUpdatedTime() > 0){
-            pw.printf("    Last updated time       : %s%n", formatTime(info.getLastUpdatedTime()));
+            keyValue("     Last updated time       ", formatTime(info.getLastUpdatedTime()), pw, json, format);
+        }
+
+        if (info.getCreationTimestamp() > 0){
+            keyValue("     Creation time           ", formatTime(info.getCreationTimestamp()), pw, json, format);
+        }
+
+        if (info.getReindexCompletionTimestamp() > 0){
+            keyValue("     Reindex completion time ", formatTime(info.getReindexCompletionTimestamp()), pw, json, format);
         }
 
         if (info.getSizeInBytes() >= 0){
-            pw.printf("    Size                    : %s%n", IOUtils.humanReadableByteCount(info.getSizeInBytes()));
+            keyValue("    Size                     ", IOUtils.humanReadableByteCount(info.getSizeInBytes()), pw, json, format);
+        }
+
+        if (info.getSuggestSizeInBytes() >= 0){
+            keyValue("    Suggest size             ", IOUtils.humanReadableByteCount(info.getSuggestSizeInBytes()), pw, json, format);
         }
 
         if (info.getEstimatedEntryCount() >= 0){
-            pw.printf("    Estimated entry count   : %d%n", info.getEstimatedEntryCount());
+            keyValue("    Estimated entry count    ", info.getEstimatedEntryCount(), pw, json, format);
         }
 
-        if (info.hasIndexDefinitionChangedWithoutReindexing()) {
-            pw.println("    Index definition changed without reindexing");
-            String diff = info.getIndexDefinitionDiff();
-            if (diff != null) {
-                pw.println("    "+diff);
-            }
+        if (info.getType() == "lucene") {

Review comment:
       use `equals` instead of `==`

##########
File path: oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/index/inventory/IndexPrinterTest.java
##########
@@ -49,11 +53,30 @@ public void asyncIndexInfo() throws Exception {
         when(asyncInfo.getInfo("foo-async"))
                 .thenReturn(new AsyncIndexInfo("foo-async", 0, 0, false, null));
 
-        String output = getPrintOutput();
+        String output = getPrintOutput(Format.TEXT);
 
         assertThat(output, containsString("foo-async"));
     }
 
+    @Test
+    public void asyncIndexInfoJson() throws Exception {
+        when(indexInfo.getAllIndexInfo()).thenReturn(emptyList());
+        when(asyncInfo.getAsyncLanes()).thenReturn(asList("foo-async", "bar-async"));
+        when(asyncInfo.getInfo("foo-async"))
+                .thenReturn(new AsyncIndexInfo("foo-async", 0, 0, false, null));
+
+        String output = getPrintOutput(Format.JSON);
+
+        JsonObject json = JsonObject.fromJson(output, true);
+        Map<String, JsonObject> jsonMap = json.getChildren();
+        assertTrue(jsonMap.keySet().contains("Async Indexers State"));
+        int size  = Integer.parseInt(jsonMap.get("Async Indexers State").getProperties().get("Number of async indexer lanes"));
+        assertTrue(size == 2);

Review comment:
       ```suggestion
           assertEquals(2, size);
   ```

##########
File path: oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/inventory/IndexPrinter.java
##########
@@ -66,97 +68,193 @@ public IndexPrinter(IndexInfoService indexInfoService, AsyncIndexInfoService asy
 
     @Override
     public void print(PrintWriter pw, Format format, boolean isZip) {
-        //TODO Highlight if failing
-        printAsyncIndexInfo(pw);
-        printIndexInfo(pw);
+
+        if (format == Format.JSON) {
+            JsopBuilder json = new JsopBuilder();
+            startJsonObject(json);
+            printAsyncIndexInfo(pw, json, format);
+            printIndexInfo(pw, json, format);
+            endJsonObject(json);
+            pw.print(JsopBuilder.prettyPrint(json.toString()));
+        } else {
+            //TODO Highlight if failing
+            printAsyncIndexInfo(pw, null, format);
+            printIndexInfo(pw, null, format);
+        }
     }
 
-    private void printAsyncIndexInfo(PrintWriter pw) {
+    private void printAsyncIndexInfo(PrintWriter pw, JsopBuilder json, Format format) {
         List<String> asyncLanes = ImmutableList.copyOf(asyncIndexInfoService.getAsyncLanes());
         String title = "Async Indexers State";
-        printTitle(pw, title);
-        pw.printf("Number of async indexer lanes : %d%n", asyncLanes.size());
-        pw.println();
+        printTitle(pw, title, format);
+        addJsonKey(json, title);
+        startJsonObject(json);
+        keyValue("Number of async indexer lanes ", asyncLanes.size(), pw, json, format);
+        printWithNewLine(pw, "", format);
+
         for (String lane : asyncLanes) {
-            pw.println(lane);
+            printWithNewLine(pw, lane, format);
+            addJsonKey(json, lane);
             AsyncIndexInfo info = asyncIndexInfoService.getInfo(lane);
             if (info != null) {
-                        pw.printf("    Last indexed to      : %s%n", formatTime(info.getLastIndexedTo()));
+                startJsonObject(json);

Review comment:
       `startJsonObject(json);` is called in both `if` and `else` blocks. You can remove from both an move it before the `if` block.

##########
File path: oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/inventory/IndexPrinter.java
##########
@@ -66,97 +68,193 @@ public IndexPrinter(IndexInfoService indexInfoService, AsyncIndexInfoService asy
 
     @Override
     public void print(PrintWriter pw, Format format, boolean isZip) {
-        //TODO Highlight if failing
-        printAsyncIndexInfo(pw);
-        printIndexInfo(pw);
+
+        if (format == Format.JSON) {
+            JsopBuilder json = new JsopBuilder();
+            startJsonObject(json);
+            printAsyncIndexInfo(pw, json, format);
+            printIndexInfo(pw, json, format);
+            endJsonObject(json);
+            pw.print(JsopBuilder.prettyPrint(json.toString()));
+        } else {
+            //TODO Highlight if failing
+            printAsyncIndexInfo(pw, null, format);
+            printIndexInfo(pw, null, format);
+        }
     }
 
-    private void printAsyncIndexInfo(PrintWriter pw) {
+    private void printAsyncIndexInfo(PrintWriter pw, JsopBuilder json, Format format) {
         List<String> asyncLanes = ImmutableList.copyOf(asyncIndexInfoService.getAsyncLanes());
         String title = "Async Indexers State";
-        printTitle(pw, title);
-        pw.printf("Number of async indexer lanes : %d%n", asyncLanes.size());
-        pw.println();
+        printTitle(pw, title, format);
+        addJsonKey(json, title);
+        startJsonObject(json);
+        keyValue("Number of async indexer lanes ", asyncLanes.size(), pw, json, format);
+        printWithNewLine(pw, "", format);
+
         for (String lane : asyncLanes) {
-            pw.println(lane);
+            printWithNewLine(pw, lane, format);
+            addJsonKey(json, lane);
             AsyncIndexInfo info = asyncIndexInfoService.getInfo(lane);
             if (info != null) {
-                        pw.printf("    Last indexed to      : %s%n", formatTime(info.getLastIndexedTo()));
+                startJsonObject(json);
+                keyValue("    Last indexed to      ", formatTime(info.getLastIndexedTo()), pw, json, format);
                 IndexStatsMBean stats = info.getStatsMBean();
                 if (stats != null) {
-                        pw.printf("    Status              : %s%n", stats.getStatus());
-                        pw.printf("    Failing             : %s%n", stats.isFailing());
-                        pw.printf("    Paused              : %s%n", stats.isPaused());
+                    keyValue("    Status              ", stats.getStatus(), pw, json, format);
+                    keyValue("    Failing             ", stats.isFailing(), pw, json, format);
+                    keyValue("    Paused              ", stats.isPaused(), pw, json, format);
                     if (stats.isFailing()) {
-                        pw.printf("    Failing since       : %s%n", stats.getFailingSince());
-                        pw.printf("    Latest error        : %s%n", stats.getLatestError());
+                        keyValue("    Failing since       ", stats.getFailingSince(), pw, json, format);
+                        keyValue("    Latest error        ", stats.getLatestError(), pw, json, format);
                     }
                 }
-                pw.println();
+                printWithNewLine(pw, "", format);
+                endJsonObject(json);
+            } else {
+                startJsonObject(json);
+                endJsonObject(json);
             }
         }
+        endJsonObject(json);
     }
 
-    private static void printTitle(PrintWriter pw, String title) {
-        pw.println(title);
-        pw.println(Strings.repeat("=", title.length()));
+    private static void printTitle(PrintWriter pw, String title, Format format) {
+        if (format == Format.TEXT) {
+            pw.println(title);
+            pw.println(Strings.repeat("=", title.length()));
+            pw.println();
+        }
     }
 
-    private void printIndexInfo(PrintWriter pw) {
+    private static void printWithNewLine(PrintWriter pw, String printLine, Format format) {
+        if (format == Format.TEXT) {
+            pw.println(printLine);
+        }
+    }
+
+    private void printIndexInfo(PrintWriter pw, JsopBuilder json, Format format) {
         ListMultimap<String, IndexInfo> infos = ArrayListMultimap.create();
         for (IndexInfo info : indexInfoService.getAllIndexInfo()) {
             infos.put(info.getType(), info);
         }
 
-        pw.printf("Total number of indexes : %d%n", infos.size());
+        keyValue("Total number of indexes ", infos.size(), pw, json, format);
+
         for (String type : infos.keySet()){
             List<IndexInfo> typedInfo = infos.get(type);
             String title = String.format("%s(%d)", type, typedInfo.size());
-            printTitle(pw, title);
-            pw.println();
+            printTitle(pw, title, format);
+            addJsonKey(json, type);
+            startJsonObject(json);
             for (IndexInfo info : typedInfo){
-                printIndexInfo(pw, info);
+                printIndexInfo(pw, json, info, format);
+                if (format == Format.TEXT) {
+                    if (info.hasIndexDefinitionChangedWithoutReindexing()) {
+                        pw.println("    Index definition changed without reindexing");
+                        String diff = info.getIndexDefinitionDiff();
+                        if (diff != null) {
+                            pw.println("    "+diff);
+                        }
+                    }
+                    pw.println();
+                }
             }
+            endJsonObject(json);
         }
     }
 
-    private static void printIndexInfo(PrintWriter pw, IndexInfo info) {
-        pw.println(info.getIndexPath());
-        pw.printf("    Type                    : %s%n", info.getType());
+
+    private static void printIndexInfo(PrintWriter pw, JsopBuilder json, IndexInfo info, Format format) {
+        if (format == Format.TEXT) {
+            pw.println(info.getIndexPath());
+        }
+        addJsonKey(json, info.getIndexPath());
+        startJsonObject(json);
+
+        keyValue("    Type                    ", info.getType(), pw, json, format);
         if (info.getAsyncLaneName() != null) {
-            pw.printf("    Async                   : true%n");
-            pw.printf("    Async lane name         : %s%n", info.getAsyncLaneName());
+            keyValue("    Async                    ", true, pw, json, format);
+            keyValue("    Async lane name          ", info.getAsyncLaneName(), pw, json, format);
         }
 
         if (info.getIndexedUpToTime() > 0){
-            pw.printf("    Last indexed up to      : %s%n", formatTime(info.getIndexedUpToTime()));
+            keyValue("    Last indexed up to       ", formatTime(info.getIndexedUpToTime()), pw, json, format);
         }
 
         if (info.getLastUpdatedTime() > 0){
-            pw.printf("    Last updated time       : %s%n", formatTime(info.getLastUpdatedTime()));
+            keyValue("     Last updated time       ", formatTime(info.getLastUpdatedTime()), pw, json, format);
+        }
+
+        if (info.getCreationTimestamp() > 0){
+            keyValue("     Creation time           ", formatTime(info.getCreationTimestamp()), pw, json, format);
+        }
+
+        if (info.getReindexCompletionTimestamp() > 0){
+            keyValue("     Reindex completion time ", formatTime(info.getReindexCompletionTimestamp()), pw, json, format);
         }
 
         if (info.getSizeInBytes() >= 0){
-            pw.printf("    Size                    : %s%n", IOUtils.humanReadableByteCount(info.getSizeInBytes()));
+            keyValue("    Size                     ", IOUtils.humanReadableByteCount(info.getSizeInBytes()), pw, json, format);
+        }
+
+        if (info.getSuggestSizeInBytes() >= 0){
+            keyValue("    Suggest size             ", IOUtils.humanReadableByteCount(info.getSuggestSizeInBytes()), pw, json, format);
         }
 
         if (info.getEstimatedEntryCount() >= 0){
-            pw.printf("    Estimated entry count   : %d%n", info.getEstimatedEntryCount());
+            keyValue("    Estimated entry count    ", info.getEstimatedEntryCount(), pw, json, format);
         }
 
-        if (info.hasIndexDefinitionChangedWithoutReindexing()) {
-            pw.println("    Index definition changed without reindexing");
-            String diff = info.getIndexDefinitionDiff();
-            if (diff != null) {
-                pw.println("    "+diff);
-            }
+        if (info.getType() == "lucene") {
+            // Only valid for lucene type indexes, for others it will simply show false.
+            keyValue("    Has hidden oak mount     ", info.hasHiddenOakLibsMount(), pw, json, format);
+            keyValue("    Has property index       ", info.hasPropertyIndexNode(), pw, json, format);
         }
-        pw.println();
+        endJsonObject(json);
     }
 
     private static String formatTime(long time){
         Calendar cal = Calendar.getInstance();
         cal.setTimeInMillis(time);
         return ISO8601.format(cal);
     }
+
+    private static void keyValue(String key, Object value, PrintWriter pw, JsopBuilder json, Format format) {
+
+        if (format == Format.JSON) {
+            json.key(key.trim());
+            if (value instanceof  String) {
+                json.value((String)value);
+            } else if (value instanceof  Long) {
+                json.value((Long)value);
+            } else if (value instanceof  Boolean) {
+                json.value((Boolean)value);
+            } else if (value instanceof Integer) {
+                json.value((Integer) value);
+            }
+        } else if (format == Format.TEXT) {
+            pw.printf(key+":%s%n",value);
+        }
+    }
+
+    // Wrappers around JsonBuilder that will result in NOOP if builder is null -
+    // These are just to avoid the mulitple if/else check while handling for both TEXT and JSON formats

Review comment:
       typo
   ```suggestion
       // These are just to avoid the multiple if/else check while handling for both TEXT and JSON formats
   ```




-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: dev-unsubscribe@jackrabbit.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [jackrabbit-oak] nit0906 commented on a change in pull request #372: OAK-9566 | Improve index stats

Posted by GitBox <gi...@apache.org>.
nit0906 commented on a change in pull request #372:
URL: https://github.com/apache/jackrabbit-oak/pull/372#discussion_r711988676



##########
File path: oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/inventory/IndexPrinter.java
##########
@@ -66,97 +68,190 @@ public IndexPrinter(IndexInfoService indexInfoService, AsyncIndexInfoService asy
 
     @Override
     public void print(PrintWriter pw, Format format, boolean isZip) {
-        //TODO Highlight if failing
-        printAsyncIndexInfo(pw);
-        printIndexInfo(pw);
+
+        if (format == Format.JSON) {
+            JsopBuilder json = new JsopBuilder();
+            startJsonObject(json);
+            printAsyncIndexInfo(pw, json, format);
+            printIndexInfo(pw, json, format);
+            endJsonObject(json);
+            pw.print(JsopBuilder.prettyPrint(json.toString()));
+        } else {
+            //TODO Highlight if failing
+            printAsyncIndexInfo(pw, null, format);
+            printIndexInfo(pw, null, format);
+        }
     }
 
-    private void printAsyncIndexInfo(PrintWriter pw) {
+    private void printAsyncIndexInfo(PrintWriter pw, JsopBuilder json, Format format) {
         List<String> asyncLanes = ImmutableList.copyOf(asyncIndexInfoService.getAsyncLanes());
         String title = "Async Indexers State";
-        printTitle(pw, title);
-        pw.printf("Number of async indexer lanes : %d%n", asyncLanes.size());
-        pw.println();
+        printTitle(pw, title, format);
+        addJsonKey(json, title);
+        startJsonObject(json);
+        keyValue("Number of async indexer lanes ", asyncLanes.size(), pw, json, format);
+        printWithNewLine(pw, "", format);
+
         for (String lane : asyncLanes) {
-            pw.println(lane);
+            printWithNewLine(pw, lane, format);
+            addJsonKey(json, lane);
             AsyncIndexInfo info = asyncIndexInfoService.getInfo(lane);
+            startJsonObject(json);
             if (info != null) {
-                        pw.printf("    Last indexed to      : %s%n", formatTime(info.getLastIndexedTo()));
+                keyValue("    Last indexed to      ", formatTime(info.getLastIndexedTo()), pw, json, format);
                 IndexStatsMBean stats = info.getStatsMBean();
                 if (stats != null) {
-                        pw.printf("    Status              : %s%n", stats.getStatus());
-                        pw.printf("    Failing             : %s%n", stats.isFailing());
-                        pw.printf("    Paused              : %s%n", stats.isPaused());
+                    keyValue("    Status              ", stats.getStatus(), pw, json, format);
+                    keyValue("    Failing             ", stats.isFailing(), pw, json, format);
+                    keyValue("    Paused              ", stats.isPaused(), pw, json, format);
                     if (stats.isFailing()) {
-                        pw.printf("    Failing since       : %s%n", stats.getFailingSince());
-                        pw.printf("    Latest error        : %s%n", stats.getLatestError());
+                        keyValue("    Failing since       ", stats.getFailingSince(), pw, json, format);
+                        keyValue("    Latest error        ", stats.getLatestError(), pw, json, format);
                     }
                 }
-                pw.println();
+                printWithNewLine(pw, "", format);
             }
+            endJsonObject(json);
         }
+        endJsonObject(json);
     }
 
-    private static void printTitle(PrintWriter pw, String title) {
-        pw.println(title);
-        pw.println(Strings.repeat("=", title.length()));
+    private static void printTitle(PrintWriter pw, String title, Format format) {
+        if (format == Format.TEXT) {
+            pw.println(title);
+            pw.println(Strings.repeat("=", title.length()));
+            pw.println();
+        }
     }
 
-    private void printIndexInfo(PrintWriter pw) {
+    private static void printWithNewLine(PrintWriter pw, String printLine, Format format) {
+        if (format == Format.TEXT) {
+            pw.println(printLine);
+        }
+    }
+
+    private void printIndexInfo(PrintWriter pw, JsopBuilder json, Format format) {
         ListMultimap<String, IndexInfo> infos = ArrayListMultimap.create();
         for (IndexInfo info : indexInfoService.getAllIndexInfo()) {
             infos.put(info.getType(), info);
         }
 
-        pw.printf("Total number of indexes : %d%n", infos.size());
+        keyValue("Total number of indexes ", infos.size(), pw, json, format);
+
         for (String type : infos.keySet()){
             List<IndexInfo> typedInfo = infos.get(type);
             String title = String.format("%s(%d)", type, typedInfo.size());
-            printTitle(pw, title);
-            pw.println();
+            printTitle(pw, title, format);
+            addJsonKey(json, type);
+            startJsonObject(json);
             for (IndexInfo info : typedInfo){
-                printIndexInfo(pw, info);
+                printIndexInfo(pw, json, info, format);
+                if (format == Format.TEXT) {
+                    if (info.hasIndexDefinitionChangedWithoutReindexing()) {
+                        pw.println("    Index definition changed without reindexing");
+                        String diff = info.getIndexDefinitionDiff();
+                        if (diff != null) {
+                            pw.println("    "+diff);
+                        }
+                    }
+                    pw.println();
+                }
             }
+            endJsonObject(json);
         }
     }
 
-    private static void printIndexInfo(PrintWriter pw, IndexInfo info) {
-        pw.println(info.getIndexPath());
-        pw.printf("    Type                    : %s%n", info.getType());
+
+    private static void printIndexInfo(PrintWriter pw, JsopBuilder json, IndexInfo info, Format format) {
+        if (format == Format.TEXT) {
+            pw.println(info.getIndexPath());
+        }
+        addJsonKey(json, info.getIndexPath());
+        startJsonObject(json);
+
+        keyValue("    Type                    ", info.getType(), pw, json, format);
         if (info.getAsyncLaneName() != null) {
-            pw.printf("    Async                   : true%n");
-            pw.printf("    Async lane name         : %s%n", info.getAsyncLaneName());
+            keyValue("    Async                    ", true, pw, json, format);
+            keyValue("    Async lane name          ", info.getAsyncLaneName(), pw, json, format);
         }
 
         if (info.getIndexedUpToTime() > 0){
-            pw.printf("    Last indexed up to      : %s%n", formatTime(info.getIndexedUpToTime()));
+            keyValue("    Last indexed up to       ", formatTime(info.getIndexedUpToTime()), pw, json, format);
         }
 
         if (info.getLastUpdatedTime() > 0){
-            pw.printf("    Last updated time       : %s%n", formatTime(info.getLastUpdatedTime()));
+            keyValue("     Last updated time       ", formatTime(info.getLastUpdatedTime()), pw, json, format);
+        }
+
+        if (info.getCreationTimestamp() > 0){
+            keyValue("     Creation time           ", formatTime(info.getCreationTimestamp()), pw, json, format);
+        }
+
+        if (info.getReindexCompletionTimestamp() > 0){
+            keyValue("     Reindex completion time ", formatTime(info.getReindexCompletionTimestamp()), pw, json, format);
         }
 
         if (info.getSizeInBytes() >= 0){
-            pw.printf("    Size                    : %s%n", IOUtils.humanReadableByteCount(info.getSizeInBytes()));
+            keyValue("    Size                     ", IOUtils.humanReadableByteCount(info.getSizeInBytes()), pw, json, format);
+        }
+
+        if (info.getSuggestSizeInBytes() >= 0){
+            keyValue("    Suggest size             ", IOUtils.humanReadableByteCount(info.getSuggestSizeInBytes()), pw, json, format);
         }
 
         if (info.getEstimatedEntryCount() >= 0){
-            pw.printf("    Estimated entry count   : %d%n", info.getEstimatedEntryCount());
+            keyValue("    Estimated entry count    ", info.getEstimatedEntryCount(), pw, json, format);
         }
 
-        if (info.hasIndexDefinitionChangedWithoutReindexing()) {
-            pw.println("    Index definition changed without reindexing");
-            String diff = info.getIndexDefinitionDiff();
-            if (diff != null) {
-                pw.println("    "+diff);
-            }
+        if (info.getType().equals("lucene")) {
+            // Only valid for lucene type indexes, for others it will simply show false.
+            keyValue("    Has hidden oak mount     ", info.hasHiddenOakLibsMount(), pw, json, format);
+            keyValue("    Has property index       ", info.hasPropertyIndexNode(), pw, json, format);
         }
-        pw.println();
+        endJsonObject(json);
     }
 
     private static String formatTime(long time){
         Calendar cal = Calendar.getInstance();
         cal.setTimeInMillis(time);
         return ISO8601.format(cal);
     }
+
+    private static void keyValue(String key, Object value, PrintWriter pw, JsopBuilder json, Format format) {
+
+        if (format == Format.JSON) {
+            json.key(key.trim());
+            if (value instanceof  String) {
+                json.value((String)value);
+            } else if (value instanceof  Long) {
+                json.value((Long)value);
+            } else if (value instanceof  Boolean) {
+                json.value((Boolean)value);
+            } else if (value instanceof Integer) {
+                json.value((Integer) value);
+            }

Review comment:
       done




-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: dev-unsubscribe@jackrabbit.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [jackrabbit-oak] thomasmueller commented on a change in pull request #372: OAK-9566 | Improve index stats

Posted by GitBox <gi...@apache.org>.
thomasmueller commented on a change in pull request #372:
URL: https://github.com/apache/jackrabbit-oak/pull/372#discussion_r711959732



##########
File path: oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/inventory/IndexPrinter.java
##########
@@ -66,97 +68,190 @@ public IndexPrinter(IndexInfoService indexInfoService, AsyncIndexInfoService asy
 
     @Override
     public void print(PrintWriter pw, Format format, boolean isZip) {
-        //TODO Highlight if failing
-        printAsyncIndexInfo(pw);
-        printIndexInfo(pw);
+
+        if (format == Format.JSON) {
+            JsopBuilder json = new JsopBuilder();
+            startJsonObject(json);
+            printAsyncIndexInfo(pw, json, format);
+            printIndexInfo(pw, json, format);
+            endJsonObject(json);
+            pw.print(JsopBuilder.prettyPrint(json.toString()));
+        } else {
+            //TODO Highlight if failing
+            printAsyncIndexInfo(pw, null, format);
+            printIndexInfo(pw, null, format);
+        }
     }
 
-    private void printAsyncIndexInfo(PrintWriter pw) {
+    private void printAsyncIndexInfo(PrintWriter pw, JsopBuilder json, Format format) {
         List<String> asyncLanes = ImmutableList.copyOf(asyncIndexInfoService.getAsyncLanes());
         String title = "Async Indexers State";
-        printTitle(pw, title);
-        pw.printf("Number of async indexer lanes : %d%n", asyncLanes.size());
-        pw.println();
+        printTitle(pw, title, format);
+        addJsonKey(json, title);
+        startJsonObject(json);
+        keyValue("Number of async indexer lanes ", asyncLanes.size(), pw, json, format);
+        printWithNewLine(pw, "", format);
+
         for (String lane : asyncLanes) {
-            pw.println(lane);
+            printWithNewLine(pw, lane, format);
+            addJsonKey(json, lane);
             AsyncIndexInfo info = asyncIndexInfoService.getInfo(lane);
+            startJsonObject(json);
             if (info != null) {
-                        pw.printf("    Last indexed to      : %s%n", formatTime(info.getLastIndexedTo()));
+                keyValue("    Last indexed to      ", formatTime(info.getLastIndexedTo()), pw, json, format);
                 IndexStatsMBean stats = info.getStatsMBean();
                 if (stats != null) {
-                        pw.printf("    Status              : %s%n", stats.getStatus());
-                        pw.printf("    Failing             : %s%n", stats.isFailing());
-                        pw.printf("    Paused              : %s%n", stats.isPaused());
+                    keyValue("    Status              ", stats.getStatus(), pw, json, format);
+                    keyValue("    Failing             ", stats.isFailing(), pw, json, format);
+                    keyValue("    Paused              ", stats.isPaused(), pw, json, format);
                     if (stats.isFailing()) {
-                        pw.printf("    Failing since       : %s%n", stats.getFailingSince());
-                        pw.printf("    Latest error        : %s%n", stats.getLatestError());
+                        keyValue("    Failing since       ", stats.getFailingSince(), pw, json, format);
+                        keyValue("    Latest error        ", stats.getLatestError(), pw, json, format);
                     }
                 }
-                pw.println();
+                printWithNewLine(pw, "", format);
             }
+            endJsonObject(json);
         }
+        endJsonObject(json);
     }
 
-    private static void printTitle(PrintWriter pw, String title) {
-        pw.println(title);
-        pw.println(Strings.repeat("=", title.length()));
+    private static void printTitle(PrintWriter pw, String title, Format format) {
+        if (format == Format.TEXT) {
+            pw.println(title);
+            pw.println(Strings.repeat("=", title.length()));
+            pw.println();
+        }
     }
 
-    private void printIndexInfo(PrintWriter pw) {
+    private static void printWithNewLine(PrintWriter pw, String printLine, Format format) {
+        if (format == Format.TEXT) {
+            pw.println(printLine);
+        }
+    }
+
+    private void printIndexInfo(PrintWriter pw, JsopBuilder json, Format format) {
         ListMultimap<String, IndexInfo> infos = ArrayListMultimap.create();
         for (IndexInfo info : indexInfoService.getAllIndexInfo()) {
             infos.put(info.getType(), info);
         }
 
-        pw.printf("Total number of indexes : %d%n", infos.size());
+        keyValue("Total number of indexes ", infos.size(), pw, json, format);
+
         for (String type : infos.keySet()){
             List<IndexInfo> typedInfo = infos.get(type);
             String title = String.format("%s(%d)", type, typedInfo.size());
-            printTitle(pw, title);
-            pw.println();
+            printTitle(pw, title, format);
+            addJsonKey(json, type);
+            startJsonObject(json);
             for (IndexInfo info : typedInfo){
-                printIndexInfo(pw, info);
+                printIndexInfo(pw, json, info, format);
+                if (format == Format.TEXT) {
+                    if (info.hasIndexDefinitionChangedWithoutReindexing()) {
+                        pw.println("    Index definition changed without reindexing");
+                        String diff = info.getIndexDefinitionDiff();
+                        if (diff != null) {
+                            pw.println("    "+diff);
+                        }
+                    }
+                    pw.println();
+                }
             }
+            endJsonObject(json);
         }
     }
 
-    private static void printIndexInfo(PrintWriter pw, IndexInfo info) {
-        pw.println(info.getIndexPath());
-        pw.printf("    Type                    : %s%n", info.getType());
+
+    private static void printIndexInfo(PrintWriter pw, JsopBuilder json, IndexInfo info, Format format) {
+        if (format == Format.TEXT) {
+            pw.println(info.getIndexPath());
+        }
+        addJsonKey(json, info.getIndexPath());
+        startJsonObject(json);
+
+        keyValue("    Type                    ", info.getType(), pw, json, format);
         if (info.getAsyncLaneName() != null) {
-            pw.printf("    Async                   : true%n");
-            pw.printf("    Async lane name         : %s%n", info.getAsyncLaneName());
+            keyValue("    Async                    ", true, pw, json, format);
+            keyValue("    Async lane name          ", info.getAsyncLaneName(), pw, json, format);
         }
 
         if (info.getIndexedUpToTime() > 0){
-            pw.printf("    Last indexed up to      : %s%n", formatTime(info.getIndexedUpToTime()));
+            keyValue("    Last indexed up to       ", formatTime(info.getIndexedUpToTime()), pw, json, format);
         }
 
         if (info.getLastUpdatedTime() > 0){
-            pw.printf("    Last updated time       : %s%n", formatTime(info.getLastUpdatedTime()));
+            keyValue("     Last updated time       ", formatTime(info.getLastUpdatedTime()), pw, json, format);
+        }
+
+        if (info.getCreationTimestamp() > 0){
+            keyValue("     Creation time           ", formatTime(info.getCreationTimestamp()), pw, json, format);
+        }
+
+        if (info.getReindexCompletionTimestamp() > 0){
+            keyValue("     Reindex completion time ", formatTime(info.getReindexCompletionTimestamp()), pw, json, format);
         }
 
         if (info.getSizeInBytes() >= 0){
-            pw.printf("    Size                    : %s%n", IOUtils.humanReadableByteCount(info.getSizeInBytes()));
+            keyValue("    Size                     ", IOUtils.humanReadableByteCount(info.getSizeInBytes()), pw, json, format);
+        }
+
+        if (info.getSuggestSizeInBytes() >= 0){
+            keyValue("    Suggest size             ", IOUtils.humanReadableByteCount(info.getSuggestSizeInBytes()), pw, json, format);
         }
 
         if (info.getEstimatedEntryCount() >= 0){
-            pw.printf("    Estimated entry count   : %d%n", info.getEstimatedEntryCount());
+            keyValue("    Estimated entry count    ", info.getEstimatedEntryCount(), pw, json, format);
         }
 
-        if (info.hasIndexDefinitionChangedWithoutReindexing()) {
-            pw.println("    Index definition changed without reindexing");
-            String diff = info.getIndexDefinitionDiff();
-            if (diff != null) {
-                pw.println("    "+diff);
-            }
+        if (info.getType().equals("lucene")) {
+            // Only valid for lucene type indexes, for others it will simply show false.
+            keyValue("    Has hidden oak mount     ", info.hasHiddenOakLibsMount(), pw, json, format);
+            keyValue("    Has property index       ", info.hasPropertyIndexNode(), pw, json, format);
         }
-        pw.println();
+        endJsonObject(json);
     }
 
     private static String formatTime(long time){
         Calendar cal = Calendar.getInstance();
         cal.setTimeInMillis(time);
         return ISO8601.format(cal);
     }
+
+    private static void keyValue(String key, Object value, PrintWriter pw, JsopBuilder json, Format format) {
+
+        if (format == Format.JSON) {
+            json.key(key.trim());
+            if (value instanceof  String) {
+                json.value((String)value);
+            } else if (value instanceof  Long) {
+                json.value((Long)value);
+            } else if (value instanceof  Boolean) {
+                json.value((Boolean)value);
+            } else if (value instanceof Integer) {
+                json.value((Integer) value);
+            }

Review comment:
       I would probably handle "null" separately at the beginning (if value == null). Could throw an exception.
   Also, "else" for all other cases is missing (could e.g. throw an exception)

##########
File path: oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/inventory/IndexPrinter.java
##########
@@ -66,97 +68,190 @@ public IndexPrinter(IndexInfoService indexInfoService, AsyncIndexInfoService asy
 
     @Override
     public void print(PrintWriter pw, Format format, boolean isZip) {
-        //TODO Highlight if failing
-        printAsyncIndexInfo(pw);
-        printIndexInfo(pw);
+
+        if (format == Format.JSON) {
+            JsopBuilder json = new JsopBuilder();
+            startJsonObject(json);
+            printAsyncIndexInfo(pw, json, format);
+            printIndexInfo(pw, json, format);
+            endJsonObject(json);
+            pw.print(JsopBuilder.prettyPrint(json.toString()));
+        } else {
+            //TODO Highlight if failing
+            printAsyncIndexInfo(pw, null, format);
+            printIndexInfo(pw, null, format);
+        }
     }
 
-    private void printAsyncIndexInfo(PrintWriter pw) {
+    private void printAsyncIndexInfo(PrintWriter pw, JsopBuilder json, Format format) {
         List<String> asyncLanes = ImmutableList.copyOf(asyncIndexInfoService.getAsyncLanes());
         String title = "Async Indexers State";
-        printTitle(pw, title);
-        pw.printf("Number of async indexer lanes : %d%n", asyncLanes.size());
-        pw.println();
+        printTitle(pw, title, format);
+        addJsonKey(json, title);
+        startJsonObject(json);
+        keyValue("Number of async indexer lanes ", asyncLanes.size(), pw, json, format);
+        printWithNewLine(pw, "", format);
+
         for (String lane : asyncLanes) {
-            pw.println(lane);
+            printWithNewLine(pw, lane, format);
+            addJsonKey(json, lane);
             AsyncIndexInfo info = asyncIndexInfoService.getInfo(lane);
+            startJsonObject(json);
             if (info != null) {
-                        pw.printf("    Last indexed to      : %s%n", formatTime(info.getLastIndexedTo()));
+                keyValue("    Last indexed to      ", formatTime(info.getLastIndexedTo()), pw, json, format);
                 IndexStatsMBean stats = info.getStatsMBean();
                 if (stats != null) {
-                        pw.printf("    Status              : %s%n", stats.getStatus());
-                        pw.printf("    Failing             : %s%n", stats.isFailing());
-                        pw.printf("    Paused              : %s%n", stats.isPaused());
+                    keyValue("    Status              ", stats.getStatus(), pw, json, format);
+                    keyValue("    Failing             ", stats.isFailing(), pw, json, format);
+                    keyValue("    Paused              ", stats.isPaused(), pw, json, format);
                     if (stats.isFailing()) {
-                        pw.printf("    Failing since       : %s%n", stats.getFailingSince());
-                        pw.printf("    Latest error        : %s%n", stats.getLatestError());
+                        keyValue("    Failing since       ", stats.getFailingSince(), pw, json, format);
+                        keyValue("    Latest error        ", stats.getLatestError(), pw, json, format);
                     }
                 }
-                pw.println();
+                printWithNewLine(pw, "", format);
             }
+            endJsonObject(json);
         }
+        endJsonObject(json);
     }
 
-    private static void printTitle(PrintWriter pw, String title) {
-        pw.println(title);
-        pw.println(Strings.repeat("=", title.length()));
+    private static void printTitle(PrintWriter pw, String title, Format format) {
+        if (format == Format.TEXT) {
+            pw.println(title);
+            pw.println(Strings.repeat("=", title.length()));
+            pw.println();
+        }
     }
 
-    private void printIndexInfo(PrintWriter pw) {
+    private static void printWithNewLine(PrintWriter pw, String printLine, Format format) {
+        if (format == Format.TEXT) {
+            pw.println(printLine);
+        }
+    }
+
+    private void printIndexInfo(PrintWriter pw, JsopBuilder json, Format format) {
         ListMultimap<String, IndexInfo> infos = ArrayListMultimap.create();
         for (IndexInfo info : indexInfoService.getAllIndexInfo()) {
             infos.put(info.getType(), info);
         }
 
-        pw.printf("Total number of indexes : %d%n", infos.size());
+        keyValue("Total number of indexes ", infos.size(), pw, json, format);
+
         for (String type : infos.keySet()){
             List<IndexInfo> typedInfo = infos.get(type);
             String title = String.format("%s(%d)", type, typedInfo.size());
-            printTitle(pw, title);
-            pw.println();
+            printTitle(pw, title, format);
+            addJsonKey(json, type);
+            startJsonObject(json);
             for (IndexInfo info : typedInfo){
-                printIndexInfo(pw, info);
+                printIndexInfo(pw, json, info, format);
+                if (format == Format.TEXT) {
+                    if (info.hasIndexDefinitionChangedWithoutReindexing()) {

Review comment:
       The json output could also have this info I assume, right?

##########
File path: oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/inventory/IndexPrinter.java
##########
@@ -66,97 +68,190 @@ public IndexPrinter(IndexInfoService indexInfoService, AsyncIndexInfoService asy
 
     @Override
     public void print(PrintWriter pw, Format format, boolean isZip) {
-        //TODO Highlight if failing
-        printAsyncIndexInfo(pw);
-        printIndexInfo(pw);
+
+        if (format == Format.JSON) {
+            JsopBuilder json = new JsopBuilder();
+            startJsonObject(json);
+            printAsyncIndexInfo(pw, json, format);
+            printIndexInfo(pw, json, format);
+            endJsonObject(json);
+            pw.print(JsopBuilder.prettyPrint(json.toString()));
+        } else {
+            //TODO Highlight if failing
+            printAsyncIndexInfo(pw, null, format);
+            printIndexInfo(pw, null, format);
+        }
     }
 
-    private void printAsyncIndexInfo(PrintWriter pw) {
+    private void printAsyncIndexInfo(PrintWriter pw, JsopBuilder json, Format format) {
         List<String> asyncLanes = ImmutableList.copyOf(asyncIndexInfoService.getAsyncLanes());
         String title = "Async Indexers State";
-        printTitle(pw, title);
-        pw.printf("Number of async indexer lanes : %d%n", asyncLanes.size());
-        pw.println();
+        printTitle(pw, title, format);
+        addJsonKey(json, title);
+        startJsonObject(json);
+        keyValue("Number of async indexer lanes ", asyncLanes.size(), pw, json, format);
+        printWithNewLine(pw, "", format);
+
         for (String lane : asyncLanes) {
-            pw.println(lane);
+            printWithNewLine(pw, lane, format);
+            addJsonKey(json, lane);
             AsyncIndexInfo info = asyncIndexInfoService.getInfo(lane);
+            startJsonObject(json);
             if (info != null) {
-                        pw.printf("    Last indexed to      : %s%n", formatTime(info.getLastIndexedTo()));
+                keyValue("    Last indexed to      ", formatTime(info.getLastIndexedTo()), pw, json, format);
                 IndexStatsMBean stats = info.getStatsMBean();
                 if (stats != null) {
-                        pw.printf("    Status              : %s%n", stats.getStatus());
-                        pw.printf("    Failing             : %s%n", stats.isFailing());
-                        pw.printf("    Paused              : %s%n", stats.isPaused());
+                    keyValue("    Status              ", stats.getStatus(), pw, json, format);
+                    keyValue("    Failing             ", stats.isFailing(), pw, json, format);
+                    keyValue("    Paused              ", stats.isPaused(), pw, json, format);
                     if (stats.isFailing()) {
-                        pw.printf("    Failing since       : %s%n", stats.getFailingSince());
-                        pw.printf("    Latest error        : %s%n", stats.getLatestError());
+                        keyValue("    Failing since       ", stats.getFailingSince(), pw, json, format);
+                        keyValue("    Latest error        ", stats.getLatestError(), pw, json, format);
                     }
                 }
-                pw.println();
+                printWithNewLine(pw, "", format);
             }
+            endJsonObject(json);
         }
+        endJsonObject(json);
     }
 
-    private static void printTitle(PrintWriter pw, String title) {
-        pw.println(title);
-        pw.println(Strings.repeat("=", title.length()));
+    private static void printTitle(PrintWriter pw, String title, Format format) {
+        if (format == Format.TEXT) {
+            pw.println(title);
+            pw.println(Strings.repeat("=", title.length()));
+            pw.println();
+        }
     }
 
-    private void printIndexInfo(PrintWriter pw) {
+    private static void printWithNewLine(PrintWriter pw, String printLine, Format format) {
+        if (format == Format.TEXT) {
+            pw.println(printLine);
+        }
+    }
+
+    private void printIndexInfo(PrintWriter pw, JsopBuilder json, Format format) {
         ListMultimap<String, IndexInfo> infos = ArrayListMultimap.create();
         for (IndexInfo info : indexInfoService.getAllIndexInfo()) {
             infos.put(info.getType(), info);
         }
 
-        pw.printf("Total number of indexes : %d%n", infos.size());
+        keyValue("Total number of indexes ", infos.size(), pw, json, format);
+
         for (String type : infos.keySet()){
             List<IndexInfo> typedInfo = infos.get(type);
             String title = String.format("%s(%d)", type, typedInfo.size());
-            printTitle(pw, title);
-            pw.println();
+            printTitle(pw, title, format);
+            addJsonKey(json, type);
+            startJsonObject(json);
             for (IndexInfo info : typedInfo){
-                printIndexInfo(pw, info);
+                printIndexInfo(pw, json, info, format);
+                if (format == Format.TEXT) {
+                    if (info.hasIndexDefinitionChangedWithoutReindexing()) {
+                        pw.println("    Index definition changed without reindexing");
+                        String diff = info.getIndexDefinitionDiff();
+                        if (diff != null) {
+                            pw.println("    "+diff);
+                        }
+                    }
+                    pw.println();
+                }
             }
+            endJsonObject(json);
         }
     }
 
-    private static void printIndexInfo(PrintWriter pw, IndexInfo info) {
-        pw.println(info.getIndexPath());
-        pw.printf("    Type                    : %s%n", info.getType());
+
+    private static void printIndexInfo(PrintWriter pw, JsopBuilder json, IndexInfo info, Format format) {
+        if (format == Format.TEXT) {
+            pw.println(info.getIndexPath());
+        }
+        addJsonKey(json, info.getIndexPath());
+        startJsonObject(json);
+
+        keyValue("    Type                    ", info.getType(), pw, json, format);
         if (info.getAsyncLaneName() != null) {
-            pw.printf("    Async                   : true%n");
-            pw.printf("    Async lane name         : %s%n", info.getAsyncLaneName());
+            keyValue("    Async                    ", true, pw, json, format);
+            keyValue("    Async lane name          ", info.getAsyncLaneName(), pw, json, format);
         }
 
         if (info.getIndexedUpToTime() > 0){
-            pw.printf("    Last indexed up to      : %s%n", formatTime(info.getIndexedUpToTime()));
+            keyValue("    Last indexed up to       ", formatTime(info.getIndexedUpToTime()), pw, json, format);
         }
 
         if (info.getLastUpdatedTime() > 0){
-            pw.printf("    Last updated time       : %s%n", formatTime(info.getLastUpdatedTime()));
+            keyValue("     Last updated time       ", formatTime(info.getLastUpdatedTime()), pw, json, format);
+        }
+
+        if (info.getCreationTimestamp() > 0){
+            keyValue("     Creation time           ", formatTime(info.getCreationTimestamp()), pw, json, format);
+        }
+
+        if (info.getReindexCompletionTimestamp() > 0){
+            keyValue("     Reindex completion time ", formatTime(info.getReindexCompletionTimestamp()), pw, json, format);
         }
 
         if (info.getSizeInBytes() >= 0){
-            pw.printf("    Size                    : %s%n", IOUtils.humanReadableByteCount(info.getSizeInBytes()));
+            keyValue("    Size                     ", IOUtils.humanReadableByteCount(info.getSizeInBytes()), pw, json, format);

Review comment:
       My personal opinion is that we should list all size data in the same way, e.g. all in GB. Examples:
   * 1000 (= 1 TB)
   * 1 (= 1 GB)
   * 0.001 (= 1 MB)
   * 0.000001 (= 1 B)




-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: dev-unsubscribe@jackrabbit.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [jackrabbit-oak] nit0906 edited a comment on pull request #372: OAK-9566 | Improve index stats

Posted by GitBox <gi...@apache.org>.
nit0906 edited a comment on pull request #372:
URL: https://github.com/apache/jackrabbit-oak/pull/372#issuecomment-923107955


   @thomasmueller 
   >>> I wonder if the timestamps would be better listed in UTC?
   
   Sure - I transformed them in UTC now. And also added another property to show the sized in bytes (numeric) that can be used for alerts etc. Added a new sample json here - https://issues.apache.org/jira/browse/OAK-9566?focusedCommentId=17417733&page=com.atlassian.jira.plugin.system.issuetabpanels%3Acomment-tabpanel#comment-17417733 . 


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: dev-unsubscribe@jackrabbit.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [jackrabbit-oak] nit0906 commented on a change in pull request #372: OAK-9566 | Improve index stats

Posted by GitBox <gi...@apache.org>.
nit0906 commented on a change in pull request #372:
URL: https://github.com/apache/jackrabbit-oak/pull/372#discussion_r711962833



##########
File path: oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/inventory/IndexPrinter.java
##########
@@ -66,97 +68,190 @@ public IndexPrinter(IndexInfoService indexInfoService, AsyncIndexInfoService asy
 
     @Override
     public void print(PrintWriter pw, Format format, boolean isZip) {
-        //TODO Highlight if failing
-        printAsyncIndexInfo(pw);
-        printIndexInfo(pw);
+
+        if (format == Format.JSON) {
+            JsopBuilder json = new JsopBuilder();
+            startJsonObject(json);
+            printAsyncIndexInfo(pw, json, format);
+            printIndexInfo(pw, json, format);
+            endJsonObject(json);
+            pw.print(JsopBuilder.prettyPrint(json.toString()));
+        } else {
+            //TODO Highlight if failing
+            printAsyncIndexInfo(pw, null, format);
+            printIndexInfo(pw, null, format);
+        }
     }
 
-    private void printAsyncIndexInfo(PrintWriter pw) {
+    private void printAsyncIndexInfo(PrintWriter pw, JsopBuilder json, Format format) {
         List<String> asyncLanes = ImmutableList.copyOf(asyncIndexInfoService.getAsyncLanes());
         String title = "Async Indexers State";
-        printTitle(pw, title);
-        pw.printf("Number of async indexer lanes : %d%n", asyncLanes.size());
-        pw.println();
+        printTitle(pw, title, format);
+        addJsonKey(json, title);
+        startJsonObject(json);
+        keyValue("Number of async indexer lanes ", asyncLanes.size(), pw, json, format);
+        printWithNewLine(pw, "", format);
+
         for (String lane : asyncLanes) {
-            pw.println(lane);
+            printWithNewLine(pw, lane, format);
+            addJsonKey(json, lane);
             AsyncIndexInfo info = asyncIndexInfoService.getInfo(lane);
+            startJsonObject(json);
             if (info != null) {
-                        pw.printf("    Last indexed to      : %s%n", formatTime(info.getLastIndexedTo()));
+                keyValue("    Last indexed to      ", formatTime(info.getLastIndexedTo()), pw, json, format);
                 IndexStatsMBean stats = info.getStatsMBean();
                 if (stats != null) {
-                        pw.printf("    Status              : %s%n", stats.getStatus());
-                        pw.printf("    Failing             : %s%n", stats.isFailing());
-                        pw.printf("    Paused              : %s%n", stats.isPaused());
+                    keyValue("    Status              ", stats.getStatus(), pw, json, format);
+                    keyValue("    Failing             ", stats.isFailing(), pw, json, format);
+                    keyValue("    Paused              ", stats.isPaused(), pw, json, format);
                     if (stats.isFailing()) {
-                        pw.printf("    Failing since       : %s%n", stats.getFailingSince());
-                        pw.printf("    Latest error        : %s%n", stats.getLatestError());
+                        keyValue("    Failing since       ", stats.getFailingSince(), pw, json, format);
+                        keyValue("    Latest error        ", stats.getLatestError(), pw, json, format);
                     }
                 }
-                pw.println();
+                printWithNewLine(pw, "", format);
             }
+            endJsonObject(json);
         }
+        endJsonObject(json);
     }
 
-    private static void printTitle(PrintWriter pw, String title) {
-        pw.println(title);
-        pw.println(Strings.repeat("=", title.length()));
+    private static void printTitle(PrintWriter pw, String title, Format format) {
+        if (format == Format.TEXT) {
+            pw.println(title);
+            pw.println(Strings.repeat("=", title.length()));
+            pw.println();
+        }
     }
 
-    private void printIndexInfo(PrintWriter pw) {
+    private static void printWithNewLine(PrintWriter pw, String printLine, Format format) {
+        if (format == Format.TEXT) {
+            pw.println(printLine);
+        }
+    }
+
+    private void printIndexInfo(PrintWriter pw, JsopBuilder json, Format format) {
         ListMultimap<String, IndexInfo> infos = ArrayListMultimap.create();
         for (IndexInfo info : indexInfoService.getAllIndexInfo()) {
             infos.put(info.getType(), info);
         }
 
-        pw.printf("Total number of indexes : %d%n", infos.size());
+        keyValue("Total number of indexes ", infos.size(), pw, json, format);
+
         for (String type : infos.keySet()){
             List<IndexInfo> typedInfo = infos.get(type);
             String title = String.format("%s(%d)", type, typedInfo.size());
-            printTitle(pw, title);
-            pw.println();
+            printTitle(pw, title, format);
+            addJsonKey(json, type);
+            startJsonObject(json);
             for (IndexInfo info : typedInfo){
-                printIndexInfo(pw, info);
+                printIndexInfo(pw, json, info, format);
+                if (format == Format.TEXT) {
+                    if (info.hasIndexDefinitionChangedWithoutReindexing()) {
+                        pw.println("    Index definition changed without reindexing");
+                        String diff = info.getIndexDefinitionDiff();
+                        if (diff != null) {
+                            pw.println("    "+diff);
+                        }
+                    }
+                    pw.println();
+                }
             }
+            endJsonObject(json);
         }
     }
 
-    private static void printIndexInfo(PrintWriter pw, IndexInfo info) {
-        pw.println(info.getIndexPath());
-        pw.printf("    Type                    : %s%n", info.getType());
+
+    private static void printIndexInfo(PrintWriter pw, JsopBuilder json, IndexInfo info, Format format) {
+        if (format == Format.TEXT) {
+            pw.println(info.getIndexPath());
+        }
+        addJsonKey(json, info.getIndexPath());
+        startJsonObject(json);
+
+        keyValue("    Type                    ", info.getType(), pw, json, format);
         if (info.getAsyncLaneName() != null) {
-            pw.printf("    Async                   : true%n");
-            pw.printf("    Async lane name         : %s%n", info.getAsyncLaneName());
+            keyValue("    Async                    ", true, pw, json, format);
+            keyValue("    Async lane name          ", info.getAsyncLaneName(), pw, json, format);
         }
 
         if (info.getIndexedUpToTime() > 0){
-            pw.printf("    Last indexed up to      : %s%n", formatTime(info.getIndexedUpToTime()));
+            keyValue("    Last indexed up to       ", formatTime(info.getIndexedUpToTime()), pw, json, format);
         }
 
         if (info.getLastUpdatedTime() > 0){
-            pw.printf("    Last updated time       : %s%n", formatTime(info.getLastUpdatedTime()));
+            keyValue("     Last updated time       ", formatTime(info.getLastUpdatedTime()), pw, json, format);
+        }
+
+        if (info.getCreationTimestamp() > 0){
+            keyValue("     Creation time           ", formatTime(info.getCreationTimestamp()), pw, json, format);
+        }
+
+        if (info.getReindexCompletionTimestamp() > 0){
+            keyValue("     Reindex completion time ", formatTime(info.getReindexCompletionTimestamp()), pw, json, format);
         }
 
         if (info.getSizeInBytes() >= 0){
-            pw.printf("    Size                    : %s%n", IOUtils.humanReadableByteCount(info.getSizeInBytes()));
+            keyValue("    Size                     ", IOUtils.humanReadableByteCount(info.getSizeInBytes()), pw, json, format);
+        }
+
+        if (info.getSuggestSizeInBytes() >= 0){
+            keyValue("    Suggest size             ", IOUtils.humanReadableByteCount(info.getSuggestSizeInBytes()), pw, json, format);
         }
 
         if (info.getEstimatedEntryCount() >= 0){
-            pw.printf("    Estimated entry count   : %d%n", info.getEstimatedEntryCount());
+            keyValue("    Estimated entry count    ", info.getEstimatedEntryCount(), pw, json, format);
         }
 
-        if (info.hasIndexDefinitionChangedWithoutReindexing()) {
-            pw.println("    Index definition changed without reindexing");
-            String diff = info.getIndexDefinitionDiff();
-            if (diff != null) {
-                pw.println("    "+diff);
-            }
+        if (info.getType().equals("lucene")) {

Review comment:
       done




-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: dev-unsubscribe@jackrabbit.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [jackrabbit-oak] nit0906 commented on a change in pull request #372: OAK-9566 | Improve index stats

Posted by GitBox <gi...@apache.org>.
nit0906 commented on a change in pull request #372:
URL: https://github.com/apache/jackrabbit-oak/pull/372#discussion_r712348983



##########
File path: oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/inventory/IndexPrinter.java
##########
@@ -66,97 +68,190 @@ public IndexPrinter(IndexInfoService indexInfoService, AsyncIndexInfoService asy
 
     @Override
     public void print(PrintWriter pw, Format format, boolean isZip) {
-        //TODO Highlight if failing
-        printAsyncIndexInfo(pw);
-        printIndexInfo(pw);
+
+        if (format == Format.JSON) {
+            JsopBuilder json = new JsopBuilder();
+            startJsonObject(json);
+            printAsyncIndexInfo(pw, json, format);
+            printIndexInfo(pw, json, format);
+            endJsonObject(json);
+            pw.print(JsopBuilder.prettyPrint(json.toString()));
+        } else {
+            //TODO Highlight if failing
+            printAsyncIndexInfo(pw, null, format);
+            printIndexInfo(pw, null, format);
+        }
     }
 
-    private void printAsyncIndexInfo(PrintWriter pw) {
+    private void printAsyncIndexInfo(PrintWriter pw, JsopBuilder json, Format format) {
         List<String> asyncLanes = ImmutableList.copyOf(asyncIndexInfoService.getAsyncLanes());
         String title = "Async Indexers State";
-        printTitle(pw, title);
-        pw.printf("Number of async indexer lanes : %d%n", asyncLanes.size());
-        pw.println();
+        printTitle(pw, title, format);
+        addJsonKey(json, title);
+        startJsonObject(json);
+        keyValue("Number of async indexer lanes ", asyncLanes.size(), pw, json, format);
+        printWithNewLine(pw, "", format);
+
         for (String lane : asyncLanes) {
-            pw.println(lane);
+            printWithNewLine(pw, lane, format);
+            addJsonKey(json, lane);
             AsyncIndexInfo info = asyncIndexInfoService.getInfo(lane);
+            startJsonObject(json);
             if (info != null) {
-                        pw.printf("    Last indexed to      : %s%n", formatTime(info.getLastIndexedTo()));
+                keyValue("    Last indexed to      ", formatTime(info.getLastIndexedTo()), pw, json, format);
                 IndexStatsMBean stats = info.getStatsMBean();
                 if (stats != null) {
-                        pw.printf("    Status              : %s%n", stats.getStatus());
-                        pw.printf("    Failing             : %s%n", stats.isFailing());
-                        pw.printf("    Paused              : %s%n", stats.isPaused());
+                    keyValue("    Status              ", stats.getStatus(), pw, json, format);
+                    keyValue("    Failing             ", stats.isFailing(), pw, json, format);
+                    keyValue("    Paused              ", stats.isPaused(), pw, json, format);
                     if (stats.isFailing()) {
-                        pw.printf("    Failing since       : %s%n", stats.getFailingSince());
-                        pw.printf("    Latest error        : %s%n", stats.getLatestError());
+                        keyValue("    Failing since       ", stats.getFailingSince(), pw, json, format);
+                        keyValue("    Latest error        ", stats.getLatestError(), pw, json, format);
                     }
                 }
-                pw.println();
+                printWithNewLine(pw, "", format);
             }
+            endJsonObject(json);
         }
+        endJsonObject(json);
     }
 
-    private static void printTitle(PrintWriter pw, String title) {
-        pw.println(title);
-        pw.println(Strings.repeat("=", title.length()));
+    private static void printTitle(PrintWriter pw, String title, Format format) {
+        if (format == Format.TEXT) {
+            pw.println(title);
+            pw.println(Strings.repeat("=", title.length()));
+            pw.println();
+        }
     }
 
-    private void printIndexInfo(PrintWriter pw) {
+    private static void printWithNewLine(PrintWriter pw, String printLine, Format format) {
+        if (format == Format.TEXT) {
+            pw.println(printLine);
+        }
+    }
+
+    private void printIndexInfo(PrintWriter pw, JsopBuilder json, Format format) {
         ListMultimap<String, IndexInfo> infos = ArrayListMultimap.create();
         for (IndexInfo info : indexInfoService.getAllIndexInfo()) {
             infos.put(info.getType(), info);
         }
 
-        pw.printf("Total number of indexes : %d%n", infos.size());
+        keyValue("Total number of indexes ", infos.size(), pw, json, format);
+
         for (String type : infos.keySet()){
             List<IndexInfo> typedInfo = infos.get(type);
             String title = String.format("%s(%d)", type, typedInfo.size());
-            printTitle(pw, title);
-            pw.println();
+            printTitle(pw, title, format);
+            addJsonKey(json, type);
+            startJsonObject(json);
             for (IndexInfo info : typedInfo){
-                printIndexInfo(pw, info);
+                printIndexInfo(pw, json, info, format);
+                if (format == Format.TEXT) {
+                    if (info.hasIndexDefinitionChangedWithoutReindexing()) {
+                        pw.println("    Index definition changed without reindexing");
+                        String diff = info.getIndexDefinitionDiff();
+                        if (diff != null) {
+                            pw.println("    "+diff);
+                        }
+                    }
+                    pw.println();
+                }
             }
+            endJsonObject(json);
         }
     }
 
-    private static void printIndexInfo(PrintWriter pw, IndexInfo info) {
-        pw.println(info.getIndexPath());
-        pw.printf("    Type                    : %s%n", info.getType());
+
+    private static void printIndexInfo(PrintWriter pw, JsopBuilder json, IndexInfo info, Format format) {
+        if (format == Format.TEXT) {
+            pw.println(info.getIndexPath());
+        }
+        addJsonKey(json, info.getIndexPath());
+        startJsonObject(json);
+
+        keyValue("    Type                    ", info.getType(), pw, json, format);
         if (info.getAsyncLaneName() != null) {
-            pw.printf("    Async                   : true%n");
-            pw.printf("    Async lane name         : %s%n", info.getAsyncLaneName());
+            keyValue("    Async                    ", true, pw, json, format);
+            keyValue("    Async lane name          ", info.getAsyncLaneName(), pw, json, format);
         }
 
         if (info.getIndexedUpToTime() > 0){
-            pw.printf("    Last indexed up to      : %s%n", formatTime(info.getIndexedUpToTime()));
+            keyValue("    Last indexed up to       ", formatTime(info.getIndexedUpToTime()), pw, json, format);
         }
 
         if (info.getLastUpdatedTime() > 0){
-            pw.printf("    Last updated time       : %s%n", formatTime(info.getLastUpdatedTime()));
+            keyValue("     Last updated time       ", formatTime(info.getLastUpdatedTime()), pw, json, format);
+        }
+
+        if (info.getCreationTimestamp() > 0){
+            keyValue("     Creation time           ", formatTime(info.getCreationTimestamp()), pw, json, format);
+        }
+
+        if (info.getReindexCompletionTimestamp() > 0){
+            keyValue("     Reindex completion time ", formatTime(info.getReindexCompletionTimestamp()), pw, json, format);
         }
 
         if (info.getSizeInBytes() >= 0){
-            pw.printf("    Size                    : %s%n", IOUtils.humanReadableByteCount(info.getSizeInBytes()));
+            keyValue("    Size                     ", IOUtils.humanReadableByteCount(info.getSizeInBytes()), pw, json, format);

Review comment:
       Makes sense. I will add both the String format (that appends  B, MB, GB  accordingly) and the numeric one (in bytes).




-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: dev-unsubscribe@jackrabbit.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [jackrabbit-oak] nit0906 commented on pull request #372: OAK-9566 | Improve index stats

Posted by GitBox <gi...@apache.org>.
nit0906 commented on pull request #372:
URL: https://github.com/apache/jackrabbit-oak/pull/372#issuecomment-922720268


   @thomasmueller -
   >> Could you add an example output, in Json format, to https://issues.apache.org/jira/browse/OAK-9566 ?
   
   Attached a sample o/p to the jira. Please note that the values in it are not correct, since It's from an earlier revision and was not run on composite node store - but the format is same so it'll give an idea about how it's structured.
   
    >> Or (might be easier) add a test case with Json output... anyway having a test case would be good.
   
   I added a couple of tests cases. See IndexPrinterTest#asyncIndexInfoJson and  IndexPrinterTest#indexInfoJson


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: dev-unsubscribe@jackrabbit.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [jackrabbit-oak] nit0906 commented on a change in pull request #372: OAK-9566 | Improve index stats

Posted by GitBox <gi...@apache.org>.
nit0906 commented on a change in pull request #372:
URL: https://github.com/apache/jackrabbit-oak/pull/372#discussion_r711989590



##########
File path: oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/inventory/IndexPrinter.java
##########
@@ -66,97 +68,190 @@ public IndexPrinter(IndexInfoService indexInfoService, AsyncIndexInfoService asy
 
     @Override
     public void print(PrintWriter pw, Format format, boolean isZip) {
-        //TODO Highlight if failing
-        printAsyncIndexInfo(pw);
-        printIndexInfo(pw);
+
+        if (format == Format.JSON) {
+            JsopBuilder json = new JsopBuilder();
+            startJsonObject(json);
+            printAsyncIndexInfo(pw, json, format);
+            printIndexInfo(pw, json, format);
+            endJsonObject(json);
+            pw.print(JsopBuilder.prettyPrint(json.toString()));
+        } else {
+            //TODO Highlight if failing
+            printAsyncIndexInfo(pw, null, format);
+            printIndexInfo(pw, null, format);
+        }
     }
 
-    private void printAsyncIndexInfo(PrintWriter pw) {
+    private void printAsyncIndexInfo(PrintWriter pw, JsopBuilder json, Format format) {
         List<String> asyncLanes = ImmutableList.copyOf(asyncIndexInfoService.getAsyncLanes());
         String title = "Async Indexers State";
-        printTitle(pw, title);
-        pw.printf("Number of async indexer lanes : %d%n", asyncLanes.size());
-        pw.println();
+        printTitle(pw, title, format);
+        addJsonKey(json, title);
+        startJsonObject(json);
+        keyValue("Number of async indexer lanes ", asyncLanes.size(), pw, json, format);
+        printWithNewLine(pw, "", format);
+
         for (String lane : asyncLanes) {
-            pw.println(lane);
+            printWithNewLine(pw, lane, format);
+            addJsonKey(json, lane);
             AsyncIndexInfo info = asyncIndexInfoService.getInfo(lane);
+            startJsonObject(json);
             if (info != null) {
-                        pw.printf("    Last indexed to      : %s%n", formatTime(info.getLastIndexedTo()));
+                keyValue("    Last indexed to      ", formatTime(info.getLastIndexedTo()), pw, json, format);
                 IndexStatsMBean stats = info.getStatsMBean();
                 if (stats != null) {
-                        pw.printf("    Status              : %s%n", stats.getStatus());
-                        pw.printf("    Failing             : %s%n", stats.isFailing());
-                        pw.printf("    Paused              : %s%n", stats.isPaused());
+                    keyValue("    Status              ", stats.getStatus(), pw, json, format);
+                    keyValue("    Failing             ", stats.isFailing(), pw, json, format);
+                    keyValue("    Paused              ", stats.isPaused(), pw, json, format);
                     if (stats.isFailing()) {
-                        pw.printf("    Failing since       : %s%n", stats.getFailingSince());
-                        pw.printf("    Latest error        : %s%n", stats.getLatestError());
+                        keyValue("    Failing since       ", stats.getFailingSince(), pw, json, format);
+                        keyValue("    Latest error        ", stats.getLatestError(), pw, json, format);
                     }
                 }
-                pw.println();
+                printWithNewLine(pw, "", format);
             }
+            endJsonObject(json);
         }
+        endJsonObject(json);
     }
 
-    private static void printTitle(PrintWriter pw, String title) {
-        pw.println(title);
-        pw.println(Strings.repeat("=", title.length()));
+    private static void printTitle(PrintWriter pw, String title, Format format) {
+        if (format == Format.TEXT) {
+            pw.println(title);
+            pw.println(Strings.repeat("=", title.length()));
+            pw.println();
+        }
     }
 
-    private void printIndexInfo(PrintWriter pw) {
+    private static void printWithNewLine(PrintWriter pw, String printLine, Format format) {
+        if (format == Format.TEXT) {
+            pw.println(printLine);
+        }
+    }
+
+    private void printIndexInfo(PrintWriter pw, JsopBuilder json, Format format) {
         ListMultimap<String, IndexInfo> infos = ArrayListMultimap.create();
         for (IndexInfo info : indexInfoService.getAllIndexInfo()) {
             infos.put(info.getType(), info);
         }
 
-        pw.printf("Total number of indexes : %d%n", infos.size());
+        keyValue("Total number of indexes ", infos.size(), pw, json, format);
+
         for (String type : infos.keySet()){
             List<IndexInfo> typedInfo = infos.get(type);
             String title = String.format("%s(%d)", type, typedInfo.size());
-            printTitle(pw, title);
-            pw.println();
+            printTitle(pw, title, format);
+            addJsonKey(json, type);
+            startJsonObject(json);
             for (IndexInfo info : typedInfo){
-                printIndexInfo(pw, info);
+                printIndexInfo(pw, json, info, format);
+                if (format == Format.TEXT) {
+                    if (info.hasIndexDefinitionChangedWithoutReindexing()) {

Review comment:
       yes - I was thinking that this diff was also in json, and might cause formatting issues - but it's not in json. I have modified for the json stats also to include this




-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: dev-unsubscribe@jackrabbit.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [jackrabbit-oak] nit0906 commented on a change in pull request #372: OAK-9566 | Improve index stats

Posted by GitBox <gi...@apache.org>.
nit0906 commented on a change in pull request #372:
URL: https://github.com/apache/jackrabbit-oak/pull/372#discussion_r712776764



##########
File path: oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/inventory/IndexPrinter.java
##########
@@ -66,97 +71,200 @@ public IndexPrinter(IndexInfoService indexInfoService, AsyncIndexInfoService asy
 
     @Override
     public void print(PrintWriter pw, Format format, boolean isZip) {
-        //TODO Highlight if failing
-        printAsyncIndexInfo(pw);
-        printIndexInfo(pw);
+
+        if (format == Format.JSON) {
+            JsopBuilder json = new JsopBuilder();
+            startJsonObject(json);
+            printAsyncIndexInfo(pw, json, format);
+            printIndexInfo(pw, json, format);
+            endJsonObject(json);
+            pw.print(JsopBuilder.prettyPrint(json.toString()));
+        } else {
+            //TODO Highlight if failing
+            printAsyncIndexInfo(pw, null, format);
+            printIndexInfo(pw, null, format);
+        }
     }
 
-    private void printAsyncIndexInfo(PrintWriter pw) {
+    private void printAsyncIndexInfo(PrintWriter pw, JsopBuilder json, Format format) {
         List<String> asyncLanes = ImmutableList.copyOf(asyncIndexInfoService.getAsyncLanes());
         String title = "Async Indexers State";
-        printTitle(pw, title);
-        pw.printf("Number of async indexer lanes : %d%n", asyncLanes.size());
-        pw.println();
+        printTitle(pw, title, format);
+        addJsonKey(json, title);
+        startJsonObject(json);
+        keyValue("Number of async indexer lanes ", asyncLanes.size(), pw, json, format);
+        printWithNewLine(pw, "", format);
+
         for (String lane : asyncLanes) {
-            pw.println(lane);
+            printWithNewLine(pw, lane, format);
+            addJsonKey(json, lane);
             AsyncIndexInfo info = asyncIndexInfoService.getInfo(lane);
+            startJsonObject(json);
             if (info != null) {
-                        pw.printf("    Last indexed to      : %s%n", formatTime(info.getLastIndexedTo()));
+                keyValue("    Last indexed to      ", formatTime(info.getLastIndexedTo()), pw, json, format);
                 IndexStatsMBean stats = info.getStatsMBean();
                 if (stats != null) {
-                        pw.printf("    Status              : %s%n", stats.getStatus());
-                        pw.printf("    Failing             : %s%n", stats.isFailing());
-                        pw.printf("    Paused              : %s%n", stats.isPaused());
+                    keyValue("    Status              ", stats.getStatus(), pw, json, format);
+                    keyValue("    Failing             ", stats.isFailing(), pw, json, format);
+                    keyValue("    Paused              ", stats.isPaused(), pw, json, format);
                     if (stats.isFailing()) {
-                        pw.printf("    Failing since       : %s%n", stats.getFailingSince());
-                        pw.printf("    Latest error        : %s%n", stats.getLatestError());
+                        keyValue("    Failing since       ", stats.getFailingSince(), pw, json, format);
+                        keyValue("    Latest error        ", stats.getLatestError(), pw, json, format);
                     }
                 }
-                pw.println();
+                printWithNewLine(pw, "", format);
             }
+            endJsonObject(json);
         }
+        endJsonObject(json);
     }
 
-    private static void printTitle(PrintWriter pw, String title) {
-        pw.println(title);
-        pw.println(Strings.repeat("=", title.length()));
+    private static void printTitle(PrintWriter pw, String title, Format format) {
+        if (format == Format.TEXT) {
+            pw.println(title);
+            pw.println(Strings.repeat("=", title.length()));
+            pw.println();
+        }
     }
 
-    private void printIndexInfo(PrintWriter pw) {
+    private static void printWithNewLine(PrintWriter pw, String printLine, Format format) {
+        if (format == Format.TEXT) {
+            pw.println(printLine);
+        }
+    }
+
+    private void printIndexInfo(PrintWriter pw, JsopBuilder json, Format format) {
         ListMultimap<String, IndexInfo> infos = ArrayListMultimap.create();
         for (IndexInfo info : indexInfoService.getAllIndexInfo()) {
             infos.put(info.getType(), info);
         }
 
-        pw.printf("Total number of indexes : %d%n", infos.size());
+        keyValue("Total number of indexes ", infos.size(), pw, json, format);
+
         for (String type : infos.keySet()){
             List<IndexInfo> typedInfo = infos.get(type);
             String title = String.format("%s(%d)", type, typedInfo.size());
-            printTitle(pw, title);
-            pw.println();
+            printTitle(pw, title, format);
+            addJsonKey(json, type);
+            startJsonObject(json);
             for (IndexInfo info : typedInfo){
-                printIndexInfo(pw, info);
+                printIndexInfo(pw, json, info, format);
             }
+            endJsonObject(json);
         }
     }
 
-    private static void printIndexInfo(PrintWriter pw, IndexInfo info) {
-        pw.println(info.getIndexPath());
-        pw.printf("    Type                    : %s%n", info.getType());
+
+    private static void printIndexInfo(PrintWriter pw, JsopBuilder json, IndexInfo info, Format format) {
+        if (format == Format.TEXT) {
+            pw.println(info.getIndexPath());
+        }
+        addJsonKey(json, info.getIndexPath());
+        startJsonObject(json);
+
+        keyValue("    Type                    ", info.getType(), pw, json, format);
         if (info.getAsyncLaneName() != null) {
-            pw.printf("    Async                   : true%n");
-            pw.printf("    Async lane name         : %s%n", info.getAsyncLaneName());
+            keyValue("    Async                    ", true, pw, json, format);
+            keyValue("    Async lane name          ", info.getAsyncLaneName(), pw, json, format);
         }
 
         if (info.getIndexedUpToTime() > 0){
-            pw.printf("    Last indexed up to      : %s%n", formatTime(info.getIndexedUpToTime()));
+            keyValue("    Last indexed up to       ", formatTime(info.getIndexedUpToTime()), pw, json, format);
         }
 
         if (info.getLastUpdatedTime() > 0){
-            pw.printf("    Last updated time       : %s%n", formatTime(info.getLastUpdatedTime()));
+            keyValue("     Last updated time       ", formatTime(info.getLastUpdatedTime()), pw, json, format);
+        }
+
+        if (info.getCreationTimestamp() > 0){
+            keyValue("     Creation time           ", formatTime(info.getCreationTimestamp()), pw, json, format);
+        }
+
+        if (info.getReindexCompletionTimestamp() > 0){
+            keyValue("     Reindex completion time ", formatTime(info.getReindexCompletionTimestamp()), pw, json, format);
         }
 
         if (info.getSizeInBytes() >= 0){
-            pw.printf("    Size                    : %s%n", IOUtils.humanReadableByteCount(info.getSizeInBytes()));
+            keyValue("    Size                     ", IOUtils.humanReadableByteCount(info.getSizeInBytes()), pw, json, format);
+            keyValue("    Size (in Bytes)          ", info.getSizeInBytes(), pw, json, format);
+        }
+
+        if (info.getSuggestSizeInBytes() >= 0){
+            keyValue("    Suggest size             ", IOUtils.humanReadableByteCount(info.getSuggestSizeInBytes()), pw, json, format);
+            keyValue("    Suggest size (in Bytes)  ", info.getSuggestSizeInBytes(), pw, json, format);
         }
 
         if (info.getEstimatedEntryCount() >= 0){
-            pw.printf("    Estimated entry count   : %d%n", info.getEstimatedEntryCount());
+            keyValue("    Estimated entry count    ", info.getEstimatedEntryCount(), pw, json, format);
+        }
+
+        if ("lucene".equals(info.getType())) {
+            // Only valid for lucene type indexes, for others it will simply show false.
+            keyValue("    Has hidden oak mount     ", info.hasHiddenOakLibsMount(), pw, json, format);
+            keyValue("    Has property index       ", info.hasPropertyIndexNode(), pw, json, format);
         }
 
         if (info.hasIndexDefinitionChangedWithoutReindexing()) {
-            pw.println("    Index definition changed without reindexing");
             String diff = info.getIndexDefinitionDiff();
             if (diff != null) {
-                pw.println("    "+diff);
+                keyValue("    Index definition changed without reindexing ", diff, pw, json, format);
+                printWithNewLine(pw, "", format);
             }
         }
-        pw.println();
+        endJsonObject(json);
     }
 
     private static String formatTime(long time){
         Calendar cal = Calendar.getInstance();
         cal.setTimeInMillis(time);
-        return ISO8601.format(cal);
+        Date date = cal.getTime();
+        SimpleDateFormat outputFmt = new SimpleDateFormat("yyyy-mm-dd'T'HH:mm:ss.s z");

Review comment:
       `2021-09-21T07:16:53Z` Set format to 
   `SimpleDateFormat outputFmt = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'");`




-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: dev-unsubscribe@jackrabbit.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [jackrabbit-oak] nit0906 merged pull request #372: OAK-9566 | Improve index stats

Posted by GitBox <gi...@apache.org>.
nit0906 merged pull request #372:
URL: https://github.com/apache/jackrabbit-oak/pull/372


   


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: dev-unsubscribe@jackrabbit.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [jackrabbit-oak] nit0906 commented on pull request #372: OAK-9566 | Improve index stats

Posted by GitBox <gi...@apache.org>.
nit0906 commented on pull request #372:
URL: https://github.com/apache/jackrabbit-oak/pull/372#issuecomment-923107955


   @thomasmueller 
   >>> I wonder if the timestamps would be better listed in UTC?
   Sure - I transformed them in UTC now.


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: dev-unsubscribe@jackrabbit.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [jackrabbit-oak] fabriziofortino commented on a change in pull request #372: OAK-9566 | Improve index stats

Posted by GitBox <gi...@apache.org>.
fabriziofortino commented on a change in pull request #372:
URL: https://github.com/apache/jackrabbit-oak/pull/372#discussion_r711959192



##########
File path: oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/inventory/IndexPrinter.java
##########
@@ -66,97 +68,190 @@ public IndexPrinter(IndexInfoService indexInfoService, AsyncIndexInfoService asy
 
     @Override
     public void print(PrintWriter pw, Format format, boolean isZip) {
-        //TODO Highlight if failing
-        printAsyncIndexInfo(pw);
-        printIndexInfo(pw);
+
+        if (format == Format.JSON) {
+            JsopBuilder json = new JsopBuilder();
+            startJsonObject(json);
+            printAsyncIndexInfo(pw, json, format);
+            printIndexInfo(pw, json, format);
+            endJsonObject(json);
+            pw.print(JsopBuilder.prettyPrint(json.toString()));
+        } else {
+            //TODO Highlight if failing
+            printAsyncIndexInfo(pw, null, format);
+            printIndexInfo(pw, null, format);
+        }
     }
 
-    private void printAsyncIndexInfo(PrintWriter pw) {
+    private void printAsyncIndexInfo(PrintWriter pw, JsopBuilder json, Format format) {
         List<String> asyncLanes = ImmutableList.copyOf(asyncIndexInfoService.getAsyncLanes());
         String title = "Async Indexers State";
-        printTitle(pw, title);
-        pw.printf("Number of async indexer lanes : %d%n", asyncLanes.size());
-        pw.println();
+        printTitle(pw, title, format);
+        addJsonKey(json, title);
+        startJsonObject(json);
+        keyValue("Number of async indexer lanes ", asyncLanes.size(), pw, json, format);
+        printWithNewLine(pw, "", format);
+
         for (String lane : asyncLanes) {
-            pw.println(lane);
+            printWithNewLine(pw, lane, format);
+            addJsonKey(json, lane);
             AsyncIndexInfo info = asyncIndexInfoService.getInfo(lane);
+            startJsonObject(json);
             if (info != null) {
-                        pw.printf("    Last indexed to      : %s%n", formatTime(info.getLastIndexedTo()));
+                keyValue("    Last indexed to      ", formatTime(info.getLastIndexedTo()), pw, json, format);
                 IndexStatsMBean stats = info.getStatsMBean();
                 if (stats != null) {
-                        pw.printf("    Status              : %s%n", stats.getStatus());
-                        pw.printf("    Failing             : %s%n", stats.isFailing());
-                        pw.printf("    Paused              : %s%n", stats.isPaused());
+                    keyValue("    Status              ", stats.getStatus(), pw, json, format);
+                    keyValue("    Failing             ", stats.isFailing(), pw, json, format);
+                    keyValue("    Paused              ", stats.isPaused(), pw, json, format);
                     if (stats.isFailing()) {
-                        pw.printf("    Failing since       : %s%n", stats.getFailingSince());
-                        pw.printf("    Latest error        : %s%n", stats.getLatestError());
+                        keyValue("    Failing since       ", stats.getFailingSince(), pw, json, format);
+                        keyValue("    Latest error        ", stats.getLatestError(), pw, json, format);
                     }
                 }
-                pw.println();
+                printWithNewLine(pw, "", format);
             }
+            endJsonObject(json);
         }
+        endJsonObject(json);
     }
 
-    private static void printTitle(PrintWriter pw, String title) {
-        pw.println(title);
-        pw.println(Strings.repeat("=", title.length()));
+    private static void printTitle(PrintWriter pw, String title, Format format) {
+        if (format == Format.TEXT) {
+            pw.println(title);
+            pw.println(Strings.repeat("=", title.length()));
+            pw.println();
+        }
     }
 
-    private void printIndexInfo(PrintWriter pw) {
+    private static void printWithNewLine(PrintWriter pw, String printLine, Format format) {
+        if (format == Format.TEXT) {
+            pw.println(printLine);
+        }
+    }
+
+    private void printIndexInfo(PrintWriter pw, JsopBuilder json, Format format) {
         ListMultimap<String, IndexInfo> infos = ArrayListMultimap.create();
         for (IndexInfo info : indexInfoService.getAllIndexInfo()) {
             infos.put(info.getType(), info);
         }
 
-        pw.printf("Total number of indexes : %d%n", infos.size());
+        keyValue("Total number of indexes ", infos.size(), pw, json, format);
+
         for (String type : infos.keySet()){
             List<IndexInfo> typedInfo = infos.get(type);
             String title = String.format("%s(%d)", type, typedInfo.size());
-            printTitle(pw, title);
-            pw.println();
+            printTitle(pw, title, format);
+            addJsonKey(json, type);
+            startJsonObject(json);
             for (IndexInfo info : typedInfo){
-                printIndexInfo(pw, info);
+                printIndexInfo(pw, json, info, format);
+                if (format == Format.TEXT) {
+                    if (info.hasIndexDefinitionChangedWithoutReindexing()) {
+                        pw.println("    Index definition changed without reindexing");
+                        String diff = info.getIndexDefinitionDiff();
+                        if (diff != null) {
+                            pw.println("    "+diff);
+                        }
+                    }
+                    pw.println();
+                }
             }
+            endJsonObject(json);
         }
     }
 
-    private static void printIndexInfo(PrintWriter pw, IndexInfo info) {
-        pw.println(info.getIndexPath());
-        pw.printf("    Type                    : %s%n", info.getType());
+
+    private static void printIndexInfo(PrintWriter pw, JsopBuilder json, IndexInfo info, Format format) {
+        if (format == Format.TEXT) {
+            pw.println(info.getIndexPath());
+        }
+        addJsonKey(json, info.getIndexPath());
+        startJsonObject(json);
+
+        keyValue("    Type                    ", info.getType(), pw, json, format);
         if (info.getAsyncLaneName() != null) {
-            pw.printf("    Async                   : true%n");
-            pw.printf("    Async lane name         : %s%n", info.getAsyncLaneName());
+            keyValue("    Async                    ", true, pw, json, format);
+            keyValue("    Async lane name          ", info.getAsyncLaneName(), pw, json, format);
         }
 
         if (info.getIndexedUpToTime() > 0){
-            pw.printf("    Last indexed up to      : %s%n", formatTime(info.getIndexedUpToTime()));
+            keyValue("    Last indexed up to       ", formatTime(info.getIndexedUpToTime()), pw, json, format);
         }
 
         if (info.getLastUpdatedTime() > 0){
-            pw.printf("    Last updated time       : %s%n", formatTime(info.getLastUpdatedTime()));
+            keyValue("     Last updated time       ", formatTime(info.getLastUpdatedTime()), pw, json, format);
+        }
+
+        if (info.getCreationTimestamp() > 0){
+            keyValue("     Creation time           ", formatTime(info.getCreationTimestamp()), pw, json, format);
+        }
+
+        if (info.getReindexCompletionTimestamp() > 0){
+            keyValue("     Reindex completion time ", formatTime(info.getReindexCompletionTimestamp()), pw, json, format);
         }
 
         if (info.getSizeInBytes() >= 0){
-            pw.printf("    Size                    : %s%n", IOUtils.humanReadableByteCount(info.getSizeInBytes()));
+            keyValue("    Size                     ", IOUtils.humanReadableByteCount(info.getSizeInBytes()), pw, json, format);
+        }
+
+        if (info.getSuggestSizeInBytes() >= 0){
+            keyValue("    Suggest size             ", IOUtils.humanReadableByteCount(info.getSuggestSizeInBytes()), pw, json, format);
         }
 
         if (info.getEstimatedEntryCount() >= 0){
-            pw.printf("    Estimated entry count   : %d%n", info.getEstimatedEntryCount());
+            keyValue("    Estimated entry count    ", info.getEstimatedEntryCount(), pw, json, format);
         }
 
-        if (info.hasIndexDefinitionChangedWithoutReindexing()) {
-            pw.println("    Index definition changed without reindexing");
-            String diff = info.getIndexDefinitionDiff();
-            if (diff != null) {
-                pw.println("    "+diff);
-            }
+        if (info.getType().equals("lucene")) {

Review comment:
       just to avoid npe in case the type is not specified
   ```suggestion
           if ("lucene".equals(info.getType())) {
   ```




-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: dev-unsubscribe@jackrabbit.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [jackrabbit-oak] nit0906 commented on a change in pull request #372: OAK-9566 | Improve index stats

Posted by GitBox <gi...@apache.org>.
nit0906 commented on a change in pull request #372:
URL: https://github.com/apache/jackrabbit-oak/pull/372#discussion_r711942743



##########
File path: oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/inventory/IndexPrinter.java
##########
@@ -66,97 +68,193 @@ public IndexPrinter(IndexInfoService indexInfoService, AsyncIndexInfoService asy
 
     @Override
     public void print(PrintWriter pw, Format format, boolean isZip) {
-        //TODO Highlight if failing
-        printAsyncIndexInfo(pw);
-        printIndexInfo(pw);
+
+        if (format == Format.JSON) {
+            JsopBuilder json = new JsopBuilder();
+            startJsonObject(json);
+            printAsyncIndexInfo(pw, json, format);
+            printIndexInfo(pw, json, format);
+            endJsonObject(json);
+            pw.print(JsopBuilder.prettyPrint(json.toString()));
+        } else {
+            //TODO Highlight if failing
+            printAsyncIndexInfo(pw, null, format);
+            printIndexInfo(pw, null, format);
+        }
     }
 
-    private void printAsyncIndexInfo(PrintWriter pw) {
+    private void printAsyncIndexInfo(PrintWriter pw, JsopBuilder json, Format format) {
         List<String> asyncLanes = ImmutableList.copyOf(asyncIndexInfoService.getAsyncLanes());
         String title = "Async Indexers State";
-        printTitle(pw, title);
-        pw.printf("Number of async indexer lanes : %d%n", asyncLanes.size());
-        pw.println();
+        printTitle(pw, title, format);
+        addJsonKey(json, title);
+        startJsonObject(json);
+        keyValue("Number of async indexer lanes ", asyncLanes.size(), pw, json, format);
+        printWithNewLine(pw, "", format);
+
         for (String lane : asyncLanes) {
-            pw.println(lane);
+            printWithNewLine(pw, lane, format);
+            addJsonKey(json, lane);
             AsyncIndexInfo info = asyncIndexInfoService.getInfo(lane);
             if (info != null) {
-                        pw.printf("    Last indexed to      : %s%n", formatTime(info.getLastIndexedTo()));
+                startJsonObject(json);
+                keyValue("    Last indexed to      ", formatTime(info.getLastIndexedTo()), pw, json, format);
                 IndexStatsMBean stats = info.getStatsMBean();
                 if (stats != null) {
-                        pw.printf("    Status              : %s%n", stats.getStatus());
-                        pw.printf("    Failing             : %s%n", stats.isFailing());
-                        pw.printf("    Paused              : %s%n", stats.isPaused());
+                    keyValue("    Status              ", stats.getStatus(), pw, json, format);
+                    keyValue("    Failing             ", stats.isFailing(), pw, json, format);
+                    keyValue("    Paused              ", stats.isPaused(), pw, json, format);
                     if (stats.isFailing()) {
-                        pw.printf("    Failing since       : %s%n", stats.getFailingSince());
-                        pw.printf("    Latest error        : %s%n", stats.getLatestError());
+                        keyValue("    Failing since       ", stats.getFailingSince(), pw, json, format);
+                        keyValue("    Latest error        ", stats.getLatestError(), pw, json, format);
                     }
                 }
-                pw.println();
+                printWithNewLine(pw, "", format);
+                endJsonObject(json);
+            } else {
+                startJsonObject(json);
+                endJsonObject(json);
             }
         }
+        endJsonObject(json);
     }
 
-    private static void printTitle(PrintWriter pw, String title) {
-        pw.println(title);
-        pw.println(Strings.repeat("=", title.length()));
+    private static void printTitle(PrintWriter pw, String title, Format format) {
+        if (format == Format.TEXT) {
+            pw.println(title);
+            pw.println(Strings.repeat("=", title.length()));
+            pw.println();
+        }
     }
 
-    private void printIndexInfo(PrintWriter pw) {
+    private static void printWithNewLine(PrintWriter pw, String printLine, Format format) {
+        if (format == Format.TEXT) {
+            pw.println(printLine);
+        }
+    }
+
+    private void printIndexInfo(PrintWriter pw, JsopBuilder json, Format format) {
         ListMultimap<String, IndexInfo> infos = ArrayListMultimap.create();
         for (IndexInfo info : indexInfoService.getAllIndexInfo()) {
             infos.put(info.getType(), info);
         }
 
-        pw.printf("Total number of indexes : %d%n", infos.size());
+        keyValue("Total number of indexes ", infos.size(), pw, json, format);
+
         for (String type : infos.keySet()){
             List<IndexInfo> typedInfo = infos.get(type);
             String title = String.format("%s(%d)", type, typedInfo.size());
-            printTitle(pw, title);
-            pw.println();
+            printTitle(pw, title, format);
+            addJsonKey(json, type);
+            startJsonObject(json);
             for (IndexInfo info : typedInfo){
-                printIndexInfo(pw, info);
+                printIndexInfo(pw, json, info, format);
+                if (format == Format.TEXT) {
+                    if (info.hasIndexDefinitionChangedWithoutReindexing()) {
+                        pw.println("    Index definition changed without reindexing");
+                        String diff = info.getIndexDefinitionDiff();
+                        if (diff != null) {
+                            pw.println("    "+diff);
+                        }
+                    }
+                    pw.println();
+                }
             }
+            endJsonObject(json);
         }
     }
 
-    private static void printIndexInfo(PrintWriter pw, IndexInfo info) {
-        pw.println(info.getIndexPath());
-        pw.printf("    Type                    : %s%n", info.getType());
+
+    private static void printIndexInfo(PrintWriter pw, JsopBuilder json, IndexInfo info, Format format) {
+        if (format == Format.TEXT) {
+            pw.println(info.getIndexPath());
+        }
+        addJsonKey(json, info.getIndexPath());
+        startJsonObject(json);
+
+        keyValue("    Type                    ", info.getType(), pw, json, format);
         if (info.getAsyncLaneName() != null) {
-            pw.printf("    Async                   : true%n");
-            pw.printf("    Async lane name         : %s%n", info.getAsyncLaneName());
+            keyValue("    Async                    ", true, pw, json, format);
+            keyValue("    Async lane name          ", info.getAsyncLaneName(), pw, json, format);
         }
 
         if (info.getIndexedUpToTime() > 0){
-            pw.printf("    Last indexed up to      : %s%n", formatTime(info.getIndexedUpToTime()));
+            keyValue("    Last indexed up to       ", formatTime(info.getIndexedUpToTime()), pw, json, format);
         }
 
         if (info.getLastUpdatedTime() > 0){
-            pw.printf("    Last updated time       : %s%n", formatTime(info.getLastUpdatedTime()));
+            keyValue("     Last updated time       ", formatTime(info.getLastUpdatedTime()), pw, json, format);
+        }
+
+        if (info.getCreationTimestamp() > 0){
+            keyValue("     Creation time           ", formatTime(info.getCreationTimestamp()), pw, json, format);
+        }
+
+        if (info.getReindexCompletionTimestamp() > 0){
+            keyValue("     Reindex completion time ", formatTime(info.getReindexCompletionTimestamp()), pw, json, format);
         }
 
         if (info.getSizeInBytes() >= 0){
-            pw.printf("    Size                    : %s%n", IOUtils.humanReadableByteCount(info.getSizeInBytes()));
+            keyValue("    Size                     ", IOUtils.humanReadableByteCount(info.getSizeInBytes()), pw, json, format);
+        }
+
+        if (info.getSuggestSizeInBytes() >= 0){
+            keyValue("    Suggest size             ", IOUtils.humanReadableByteCount(info.getSuggestSizeInBytes()), pw, json, format);
         }
 
         if (info.getEstimatedEntryCount() >= 0){
-            pw.printf("    Estimated entry count   : %d%n", info.getEstimatedEntryCount());
+            keyValue("    Estimated entry count    ", info.getEstimatedEntryCount(), pw, json, format);
         }
 
-        if (info.hasIndexDefinitionChangedWithoutReindexing()) {
-            pw.println("    Index definition changed without reindexing");
-            String diff = info.getIndexDefinitionDiff();
-            if (diff != null) {
-                pw.println("    "+diff);
-            }
+        if (info.getType() == "lucene") {
+            // Only valid for lucene type indexes, for others it will simply show false.
+            keyValue("    Has hidden oak mount     ", info.hasHiddenOakLibsMount(), pw, json, format);
+            keyValue("    Has property index       ", info.hasPropertyIndexNode(), pw, json, format);
         }
-        pw.println();
+        endJsonObject(json);
     }
 
     private static String formatTime(long time){
         Calendar cal = Calendar.getInstance();
         cal.setTimeInMillis(time);
         return ISO8601.format(cal);
     }
+
+    private static void keyValue(String key, Object value, PrintWriter pw, JsopBuilder json, Format format) {
+
+        if (format == Format.JSON) {
+            json.key(key.trim());
+            if (value instanceof  String) {
+                json.value((String)value);
+            } else if (value instanceof  Long) {
+                json.value((Long)value);
+            } else if (value instanceof  Boolean) {
+                json.value((Boolean)value);
+            } else if (value instanceof Integer) {
+                json.value((Integer) value);
+            }
+        } else if (format == Format.TEXT) {
+            pw.printf(key+":%s%n",value);
+        }
+    }
+
+    // Wrappers around JsonBuilder that will result in NOOP if builder is null -
+    // These are just to avoid the mulitple if/else check while handling for both TEXT and JSON formats

Review comment:
       done

##########
File path: oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/inventory/IndexPrinter.java
##########
@@ -66,97 +68,193 @@ public IndexPrinter(IndexInfoService indexInfoService, AsyncIndexInfoService asy
 
     @Override
     public void print(PrintWriter pw, Format format, boolean isZip) {
-        //TODO Highlight if failing
-        printAsyncIndexInfo(pw);
-        printIndexInfo(pw);
+
+        if (format == Format.JSON) {
+            JsopBuilder json = new JsopBuilder();
+            startJsonObject(json);
+            printAsyncIndexInfo(pw, json, format);
+            printIndexInfo(pw, json, format);
+            endJsonObject(json);
+            pw.print(JsopBuilder.prettyPrint(json.toString()));
+        } else {
+            //TODO Highlight if failing
+            printAsyncIndexInfo(pw, null, format);
+            printIndexInfo(pw, null, format);
+        }
     }
 
-    private void printAsyncIndexInfo(PrintWriter pw) {
+    private void printAsyncIndexInfo(PrintWriter pw, JsopBuilder json, Format format) {
         List<String> asyncLanes = ImmutableList.copyOf(asyncIndexInfoService.getAsyncLanes());
         String title = "Async Indexers State";
-        printTitle(pw, title);
-        pw.printf("Number of async indexer lanes : %d%n", asyncLanes.size());
-        pw.println();
+        printTitle(pw, title, format);
+        addJsonKey(json, title);
+        startJsonObject(json);
+        keyValue("Number of async indexer lanes ", asyncLanes.size(), pw, json, format);
+        printWithNewLine(pw, "", format);
+
         for (String lane : asyncLanes) {
-            pw.println(lane);
+            printWithNewLine(pw, lane, format);
+            addJsonKey(json, lane);
             AsyncIndexInfo info = asyncIndexInfoService.getInfo(lane);
             if (info != null) {
-                        pw.printf("    Last indexed to      : %s%n", formatTime(info.getLastIndexedTo()));
+                startJsonObject(json);
+                keyValue("    Last indexed to      ", formatTime(info.getLastIndexedTo()), pw, json, format);
                 IndexStatsMBean stats = info.getStatsMBean();
                 if (stats != null) {
-                        pw.printf("    Status              : %s%n", stats.getStatus());
-                        pw.printf("    Failing             : %s%n", stats.isFailing());
-                        pw.printf("    Paused              : %s%n", stats.isPaused());
+                    keyValue("    Status              ", stats.getStatus(), pw, json, format);
+                    keyValue("    Failing             ", stats.isFailing(), pw, json, format);
+                    keyValue("    Paused              ", stats.isPaused(), pw, json, format);
                     if (stats.isFailing()) {
-                        pw.printf("    Failing since       : %s%n", stats.getFailingSince());
-                        pw.printf("    Latest error        : %s%n", stats.getLatestError());
+                        keyValue("    Failing since       ", stats.getFailingSince(), pw, json, format);
+                        keyValue("    Latest error        ", stats.getLatestError(), pw, json, format);
                     }
                 }
-                pw.println();
+                printWithNewLine(pw, "", format);
+                endJsonObject(json);
+            } else {
+                startJsonObject(json);
+                endJsonObject(json);
             }
         }
+        endJsonObject(json);
     }
 
-    private static void printTitle(PrintWriter pw, String title) {
-        pw.println(title);
-        pw.println(Strings.repeat("=", title.length()));
+    private static void printTitle(PrintWriter pw, String title, Format format) {
+        if (format == Format.TEXT) {
+            pw.println(title);
+            pw.println(Strings.repeat("=", title.length()));
+            pw.println();
+        }
     }
 
-    private void printIndexInfo(PrintWriter pw) {
+    private static void printWithNewLine(PrintWriter pw, String printLine, Format format) {
+        if (format == Format.TEXT) {
+            pw.println(printLine);
+        }
+    }
+
+    private void printIndexInfo(PrintWriter pw, JsopBuilder json, Format format) {
         ListMultimap<String, IndexInfo> infos = ArrayListMultimap.create();
         for (IndexInfo info : indexInfoService.getAllIndexInfo()) {
             infos.put(info.getType(), info);
         }
 
-        pw.printf("Total number of indexes : %d%n", infos.size());
+        keyValue("Total number of indexes ", infos.size(), pw, json, format);
+
         for (String type : infos.keySet()){
             List<IndexInfo> typedInfo = infos.get(type);
             String title = String.format("%s(%d)", type, typedInfo.size());
-            printTitle(pw, title);
-            pw.println();
+            printTitle(pw, title, format);
+            addJsonKey(json, type);
+            startJsonObject(json);
             for (IndexInfo info : typedInfo){
-                printIndexInfo(pw, info);
+                printIndexInfo(pw, json, info, format);
+                if (format == Format.TEXT) {
+                    if (info.hasIndexDefinitionChangedWithoutReindexing()) {
+                        pw.println("    Index definition changed without reindexing");
+                        String diff = info.getIndexDefinitionDiff();
+                        if (diff != null) {
+                            pw.println("    "+diff);
+                        }
+                    }
+                    pw.println();
+                }
             }
+            endJsonObject(json);
         }
     }
 
-    private static void printIndexInfo(PrintWriter pw, IndexInfo info) {
-        pw.println(info.getIndexPath());
-        pw.printf("    Type                    : %s%n", info.getType());
+
+    private static void printIndexInfo(PrintWriter pw, JsopBuilder json, IndexInfo info, Format format) {
+        if (format == Format.TEXT) {
+            pw.println(info.getIndexPath());
+        }
+        addJsonKey(json, info.getIndexPath());
+        startJsonObject(json);
+
+        keyValue("    Type                    ", info.getType(), pw, json, format);
         if (info.getAsyncLaneName() != null) {
-            pw.printf("    Async                   : true%n");
-            pw.printf("    Async lane name         : %s%n", info.getAsyncLaneName());
+            keyValue("    Async                    ", true, pw, json, format);
+            keyValue("    Async lane name          ", info.getAsyncLaneName(), pw, json, format);
         }
 
         if (info.getIndexedUpToTime() > 0){
-            pw.printf("    Last indexed up to      : %s%n", formatTime(info.getIndexedUpToTime()));
+            keyValue("    Last indexed up to       ", formatTime(info.getIndexedUpToTime()), pw, json, format);
         }
 
         if (info.getLastUpdatedTime() > 0){
-            pw.printf("    Last updated time       : %s%n", formatTime(info.getLastUpdatedTime()));
+            keyValue("     Last updated time       ", formatTime(info.getLastUpdatedTime()), pw, json, format);
+        }
+
+        if (info.getCreationTimestamp() > 0){
+            keyValue("     Creation time           ", formatTime(info.getCreationTimestamp()), pw, json, format);
+        }
+
+        if (info.getReindexCompletionTimestamp() > 0){
+            keyValue("     Reindex completion time ", formatTime(info.getReindexCompletionTimestamp()), pw, json, format);
         }
 
         if (info.getSizeInBytes() >= 0){
-            pw.printf("    Size                    : %s%n", IOUtils.humanReadableByteCount(info.getSizeInBytes()));
+            keyValue("    Size                     ", IOUtils.humanReadableByteCount(info.getSizeInBytes()), pw, json, format);
+        }
+
+        if (info.getSuggestSizeInBytes() >= 0){
+            keyValue("    Suggest size             ", IOUtils.humanReadableByteCount(info.getSuggestSizeInBytes()), pw, json, format);
         }
 
         if (info.getEstimatedEntryCount() >= 0){
-            pw.printf("    Estimated entry count   : %d%n", info.getEstimatedEntryCount());
+            keyValue("    Estimated entry count    ", info.getEstimatedEntryCount(), pw, json, format);
         }
 
-        if (info.hasIndexDefinitionChangedWithoutReindexing()) {
-            pw.println("    Index definition changed without reindexing");
-            String diff = info.getIndexDefinitionDiff();
-            if (diff != null) {
-                pw.println("    "+diff);
-            }
+        if (info.getType() == "lucene") {

Review comment:
       done

##########
File path: oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/index/inventory/IndexPrinterTest.java
##########
@@ -49,11 +53,30 @@ public void asyncIndexInfo() throws Exception {
         when(asyncInfo.getInfo("foo-async"))
                 .thenReturn(new AsyncIndexInfo("foo-async", 0, 0, false, null));
 
-        String output = getPrintOutput();
+        String output = getPrintOutput(Format.TEXT);
 
         assertThat(output, containsString("foo-async"));
     }
 
+    @Test
+    public void asyncIndexInfoJson() throws Exception {
+        when(indexInfo.getAllIndexInfo()).thenReturn(emptyList());
+        when(asyncInfo.getAsyncLanes()).thenReturn(asList("foo-async", "bar-async"));
+        when(asyncInfo.getInfo("foo-async"))
+                .thenReturn(new AsyncIndexInfo("foo-async", 0, 0, false, null));
+
+        String output = getPrintOutput(Format.JSON);
+
+        JsonObject json = JsonObject.fromJson(output, true);
+        Map<String, JsonObject> jsonMap = json.getChildren();
+        assertTrue(jsonMap.keySet().contains("Async Indexers State"));
+        int size  = Integer.parseInt(jsonMap.get("Async Indexers State").getProperties().get("Number of async indexer lanes"));
+        assertTrue(size == 2);

Review comment:
       done

##########
File path: oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/inventory/IndexPrinter.java
##########
@@ -66,97 +68,193 @@ public IndexPrinter(IndexInfoService indexInfoService, AsyncIndexInfoService asy
 
     @Override
     public void print(PrintWriter pw, Format format, boolean isZip) {
-        //TODO Highlight if failing
-        printAsyncIndexInfo(pw);
-        printIndexInfo(pw);
+
+        if (format == Format.JSON) {
+            JsopBuilder json = new JsopBuilder();
+            startJsonObject(json);
+            printAsyncIndexInfo(pw, json, format);
+            printIndexInfo(pw, json, format);
+            endJsonObject(json);
+            pw.print(JsopBuilder.prettyPrint(json.toString()));
+        } else {
+            //TODO Highlight if failing
+            printAsyncIndexInfo(pw, null, format);
+            printIndexInfo(pw, null, format);
+        }
     }
 
-    private void printAsyncIndexInfo(PrintWriter pw) {
+    private void printAsyncIndexInfo(PrintWriter pw, JsopBuilder json, Format format) {
         List<String> asyncLanes = ImmutableList.copyOf(asyncIndexInfoService.getAsyncLanes());
         String title = "Async Indexers State";
-        printTitle(pw, title);
-        pw.printf("Number of async indexer lanes : %d%n", asyncLanes.size());
-        pw.println();
+        printTitle(pw, title, format);
+        addJsonKey(json, title);
+        startJsonObject(json);
+        keyValue("Number of async indexer lanes ", asyncLanes.size(), pw, json, format);
+        printWithNewLine(pw, "", format);
+
         for (String lane : asyncLanes) {
-            pw.println(lane);
+            printWithNewLine(pw, lane, format);
+            addJsonKey(json, lane);
             AsyncIndexInfo info = asyncIndexInfoService.getInfo(lane);
             if (info != null) {
-                        pw.printf("    Last indexed to      : %s%n", formatTime(info.getLastIndexedTo()));
+                startJsonObject(json);

Review comment:
       done




-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: dev-unsubscribe@jackrabbit.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [jackrabbit-oak] nit0906 commented on a change in pull request #372: OAK-9566 | Improve index stats

Posted by GitBox <gi...@apache.org>.
nit0906 commented on a change in pull request #372:
URL: https://github.com/apache/jackrabbit-oak/pull/372#discussion_r711942663



##########
File path: oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/inventory/IndexPrinter.java
##########
@@ -46,7 +47,8 @@
         property = {
             "felix.inventory.printer.name=oak-index-stats",
             "felix.inventory.printer.title=Oak Index Stats",
-            "felix.inventory.printer.format=TEXT"
+            "felix.inventory.printer.format=TEXT",
+                "felix.inventory.printer.format=JSON"

Review comment:
       done




-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: dev-unsubscribe@jackrabbit.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [jackrabbit-oak] thomasmueller commented on pull request #372: OAK-9566 | Improve index stats

Posted by GitBox <gi...@apache.org>.
thomasmueller commented on pull request #372:
URL: https://github.com/apache/jackrabbit-oak/pull/372#issuecomment-922948588


   I wonder if the timestamps would be better listed in UTC? Right now we have
   
       "Last indexed up to": "2021-09-17T12:52:02.619+05:30",
   
   That would become
   
       "Last indexed up to": "2021-09-17T07:52:02.619Z",
   
   Where the "Z" is from here: https://www.w3.org/TR/NOTE-datetime


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: dev-unsubscribe@jackrabbit.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [jackrabbit-oak] nit0906 commented on a change in pull request #372: OAK-9566 | Improve index stats

Posted by GitBox <gi...@apache.org>.
nit0906 commented on a change in pull request #372:
URL: https://github.com/apache/jackrabbit-oak/pull/372#discussion_r712773801



##########
File path: oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/inventory/IndexPrinter.java
##########
@@ -66,97 +71,200 @@ public IndexPrinter(IndexInfoService indexInfoService, AsyncIndexInfoService asy
 
     @Override
     public void print(PrintWriter pw, Format format, boolean isZip) {
-        //TODO Highlight if failing
-        printAsyncIndexInfo(pw);
-        printIndexInfo(pw);
+
+        if (format == Format.JSON) {
+            JsopBuilder json = new JsopBuilder();
+            startJsonObject(json);
+            printAsyncIndexInfo(pw, json, format);
+            printIndexInfo(pw, json, format);
+            endJsonObject(json);
+            pw.print(JsopBuilder.prettyPrint(json.toString()));
+        } else {
+            //TODO Highlight if failing
+            printAsyncIndexInfo(pw, null, format);
+            printIndexInfo(pw, null, format);
+        }
     }
 
-    private void printAsyncIndexInfo(PrintWriter pw) {
+    private void printAsyncIndexInfo(PrintWriter pw, JsopBuilder json, Format format) {
         List<String> asyncLanes = ImmutableList.copyOf(asyncIndexInfoService.getAsyncLanes());
         String title = "Async Indexers State";
-        printTitle(pw, title);
-        pw.printf("Number of async indexer lanes : %d%n", asyncLanes.size());
-        pw.println();
+        printTitle(pw, title, format);
+        addJsonKey(json, title);
+        startJsonObject(json);
+        keyValue("Number of async indexer lanes ", asyncLanes.size(), pw, json, format);
+        printWithNewLine(pw, "", format);
+
         for (String lane : asyncLanes) {
-            pw.println(lane);
+            printWithNewLine(pw, lane, format);
+            addJsonKey(json, lane);
             AsyncIndexInfo info = asyncIndexInfoService.getInfo(lane);
+            startJsonObject(json);
             if (info != null) {
-                        pw.printf("    Last indexed to      : %s%n", formatTime(info.getLastIndexedTo()));
+                keyValue("    Last indexed to      ", formatTime(info.getLastIndexedTo()), pw, json, format);
                 IndexStatsMBean stats = info.getStatsMBean();
                 if (stats != null) {
-                        pw.printf("    Status              : %s%n", stats.getStatus());
-                        pw.printf("    Failing             : %s%n", stats.isFailing());
-                        pw.printf("    Paused              : %s%n", stats.isPaused());
+                    keyValue("    Status              ", stats.getStatus(), pw, json, format);
+                    keyValue("    Failing             ", stats.isFailing(), pw, json, format);
+                    keyValue("    Paused              ", stats.isPaused(), pw, json, format);
                     if (stats.isFailing()) {
-                        pw.printf("    Failing since       : %s%n", stats.getFailingSince());
-                        pw.printf("    Latest error        : %s%n", stats.getLatestError());
+                        keyValue("    Failing since       ", stats.getFailingSince(), pw, json, format);
+                        keyValue("    Latest error        ", stats.getLatestError(), pw, json, format);
                     }
                 }
-                pw.println();
+                printWithNewLine(pw, "", format);
             }
+            endJsonObject(json);
         }
+        endJsonObject(json);
     }
 
-    private static void printTitle(PrintWriter pw, String title) {
-        pw.println(title);
-        pw.println(Strings.repeat("=", title.length()));
+    private static void printTitle(PrintWriter pw, String title, Format format) {
+        if (format == Format.TEXT) {
+            pw.println(title);
+            pw.println(Strings.repeat("=", title.length()));
+            pw.println();
+        }
     }
 
-    private void printIndexInfo(PrintWriter pw) {
+    private static void printWithNewLine(PrintWriter pw, String printLine, Format format) {
+        if (format == Format.TEXT) {
+            pw.println(printLine);
+        }
+    }
+
+    private void printIndexInfo(PrintWriter pw, JsopBuilder json, Format format) {
         ListMultimap<String, IndexInfo> infos = ArrayListMultimap.create();
         for (IndexInfo info : indexInfoService.getAllIndexInfo()) {
             infos.put(info.getType(), info);
         }
 
-        pw.printf("Total number of indexes : %d%n", infos.size());
+        keyValue("Total number of indexes ", infos.size(), pw, json, format);
+
         for (String type : infos.keySet()){
             List<IndexInfo> typedInfo = infos.get(type);
             String title = String.format("%s(%d)", type, typedInfo.size());
-            printTitle(pw, title);
-            pw.println();
+            printTitle(pw, title, format);
+            addJsonKey(json, type);
+            startJsonObject(json);
             for (IndexInfo info : typedInfo){
-                printIndexInfo(pw, info);
+                printIndexInfo(pw, json, info, format);
             }
+            endJsonObject(json);
         }
     }
 
-    private static void printIndexInfo(PrintWriter pw, IndexInfo info) {
-        pw.println(info.getIndexPath());
-        pw.printf("    Type                    : %s%n", info.getType());
+
+    private static void printIndexInfo(PrintWriter pw, JsopBuilder json, IndexInfo info, Format format) {
+        if (format == Format.TEXT) {
+            pw.println(info.getIndexPath());
+        }
+        addJsonKey(json, info.getIndexPath());
+        startJsonObject(json);
+
+        keyValue("    Type                    ", info.getType(), pw, json, format);
         if (info.getAsyncLaneName() != null) {
-            pw.printf("    Async                   : true%n");
-            pw.printf("    Async lane name         : %s%n", info.getAsyncLaneName());
+            keyValue("    Async                    ", true, pw, json, format);
+            keyValue("    Async lane name          ", info.getAsyncLaneName(), pw, json, format);
         }
 
         if (info.getIndexedUpToTime() > 0){
-            pw.printf("    Last indexed up to      : %s%n", formatTime(info.getIndexedUpToTime()));
+            keyValue("    Last indexed up to       ", formatTime(info.getIndexedUpToTime()), pw, json, format);
         }
 
         if (info.getLastUpdatedTime() > 0){
-            pw.printf("    Last updated time       : %s%n", formatTime(info.getLastUpdatedTime()));
+            keyValue("     Last updated time       ", formatTime(info.getLastUpdatedTime()), pw, json, format);
+        }
+
+        if (info.getCreationTimestamp() > 0){
+            keyValue("     Creation time           ", formatTime(info.getCreationTimestamp()), pw, json, format);
+        }
+
+        if (info.getReindexCompletionTimestamp() > 0){
+            keyValue("     Reindex completion time ", formatTime(info.getReindexCompletionTimestamp()), pw, json, format);
         }
 
         if (info.getSizeInBytes() >= 0){
-            pw.printf("    Size                    : %s%n", IOUtils.humanReadableByteCount(info.getSizeInBytes()));
+            keyValue("    Size                     ", IOUtils.humanReadableByteCount(info.getSizeInBytes()), pw, json, format);
+            keyValue("    Size (in Bytes)          ", info.getSizeInBytes(), pw, json, format);
+        }
+
+        if (info.getSuggestSizeInBytes() >= 0){
+            keyValue("    Suggest size             ", IOUtils.humanReadableByteCount(info.getSuggestSizeInBytes()), pw, json, format);
+            keyValue("    Suggest size (in Bytes)  ", info.getSuggestSizeInBytes(), pw, json, format);
         }
 
         if (info.getEstimatedEntryCount() >= 0){
-            pw.printf("    Estimated entry count   : %d%n", info.getEstimatedEntryCount());
+            keyValue("    Estimated entry count    ", info.getEstimatedEntryCount(), pw, json, format);
+        }
+
+        if ("lucene".equals(info.getType())) {
+            // Only valid for lucene type indexes, for others it will simply show false.
+            keyValue("    Has hidden oak mount     ", info.hasHiddenOakLibsMount(), pw, json, format);
+            keyValue("    Has property index       ", info.hasPropertyIndexNode(), pw, json, format);
         }
 
         if (info.hasIndexDefinitionChangedWithoutReindexing()) {
-            pw.println("    Index definition changed without reindexing");
             String diff = info.getIndexDefinitionDiff();
             if (diff != null) {
-                pw.println("    "+diff);
+                keyValue("    Index definition changed without reindexing ", diff, pw, json, format);
+                printWithNewLine(pw, "", format);
             }
         }
-        pw.println();
+        endJsonObject(json);
     }
 
     private static String formatTime(long time){
         Calendar cal = Calendar.getInstance();
         cal.setTimeInMillis(time);
-        return ISO8601.format(cal);
+        Date date = cal.getTime();
+        SimpleDateFormat outputFmt = new SimpleDateFormat("yyyy-mm-dd'T'HH:mm:ss.s z");

Review comment:
       Changed the format to look like this now 
   `2021-09-21T07:16:53 UTC`
   




-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: dev-unsubscribe@jackrabbit.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org