浏览代码

Don't dump a stacktrace for invalid patterns when executing elasticsearch-croneval (#49744)

bellengao 5 年之前
父节点
当前提交
f0bfe78d58

+ 5 - 1
docs/reference/commands/croneval.asciidoc

@@ -30,7 +30,11 @@ This command is provided in the `$ES_HOME/bin` directory.
 `-c, --count` <Integer>::
   The number of future times this expression will be triggered. The default
   value is `10`.
-  
+
+`-d, --detail`::
+  Shows detail for invalid cron expression. It will print the stacktrace if the
+  expression is not valid.
+
 `-h, --help`::
   Returns all of the command parameters.
 

+ 55 - 35
x-pack/plugin/watcher/src/main/java/org/elasticsearch/xpack/watcher/trigger/schedule/tool/CronEvalTool.java

@@ -37,13 +37,16 @@ public class CronEvalTool extends LoggingAwareCommand {
 
     private final OptionSpec<Integer> countOption;
     private final OptionSpec<String> arguments;
+    private final OptionSpec<Void> detailOption;
 
     CronEvalTool() {
         super("Validates and evaluates a cron expression");
-        this.countOption = parser.acceptsAll(Arrays.asList("c", "count"),
-            "The number of future times this expression will be triggered")
-            .withRequiredArg().ofType(Integer.class).defaultsTo(10);
+        this.countOption = parser.acceptsAll(Arrays.asList("c", "count"), "The number of future times this expression will be triggered")
+            .withRequiredArg()
+            .ofType(Integer.class)
+            .defaultsTo(10);
         this.arguments = parser.nonOptions("expression");
+        this.detailOption = parser.acceptsAll(Arrays.asList("d", "detail"), "Show detail for invalid cron expression");
 
         parser.accepts("E", "Unused. Only for compatibility with other CLI tools.").withRequiredArg();
     }
@@ -55,46 +58,63 @@ public class CronEvalTool extends LoggingAwareCommand {
         if (args.size() != 1) {
             throw new UserException(ExitCodes.USAGE, "expecting a single argument that is the cron expression to evaluate");
         }
-        execute(terminal, args.get(0), count);
+        boolean printDetail = options.has(detailOption);
+        execute(terminal, args.get(0), count, printDetail);
     }
 
-    private void execute(Terminal terminal, String expression, int count) throws Exception {
-        Cron.validate(expression);
-        terminal.println("Valid!");
+    private void execute(Terminal terminal, String expression, int count, boolean printDetail) throws Exception {
+        try {
+            Cron.validate(expression);
+            terminal.println("Valid!");
 
-        final ZonedDateTime date = ZonedDateTime.now(ZoneOffset.UTC);
-        final boolean isLocalTimeUTC = UTC_FORMATTER.zone().equals(LOCAL_FORMATTER.zone());
-        if (isLocalTimeUTC) {
-            terminal.println("Now is [" + UTC_FORMATTER.format(date) + "] in UTC");
-        } else {
-            terminal.println("Now is [" + UTC_FORMATTER.format(date) + "] in UTC, local time is [" + LOCAL_FORMATTER.format(date) + "]");
+            final ZonedDateTime date = ZonedDateTime.now(ZoneOffset.UTC);
+            final boolean isLocalTimeUTC = UTC_FORMATTER.zone().equals(LOCAL_FORMATTER.zone());
+            if (isLocalTimeUTC) {
+                terminal.println("Now is [" + UTC_FORMATTER.format(date) + "] in UTC");
+            } else {
+                terminal.println(
+                    "Now is [" + UTC_FORMATTER.format(date) + "] in UTC, local time is [" + LOCAL_FORMATTER.format(date) + "]"
+                );
 
-        }
-        terminal.println("Here are the next " + count + " times this cron expression will trigger:");
-
-        Cron cron = new Cron(expression);
-        long time = date.toInstant().toEpochMilli();
-
-        for (int i = 0; i < count; i++) {
-            long prevTime = time;
-            time = cron.getNextValidTimeAfter(time);
-            if (time < 0) {
-                if (i == 0) {
-                    throw new UserException(ExitCodes.OK, "Could not compute future times since ["
-                            + UTC_FORMATTER.format(Instant.ofEpochMilli(prevTime)) + "] " + "(perhaps the cron expression only points to " +
-                        "times in the" +
-                        " " +
-                        "past?)");
-                }
-                break;
             }
+            terminal.println("Here are the next " + count + " times this cron expression will trigger:");
+
+            Cron cron = new Cron(expression);
+            long time = date.toInstant().toEpochMilli();
+
+            for (int i = 0; i < count; i++) {
+                long prevTime = time;
+                time = cron.getNextValidTimeAfter(time);
+                if (time < 0) {
+                    if (i == 0) {
+                        throw new UserException(
+                            ExitCodes.OK,
+                            "Could not compute future times since ["
+                                + UTC_FORMATTER.format(Instant.ofEpochMilli(prevTime))
+                                + "] "
+                                + "(perhaps the cron expression only points to "
+                                + "times in the"
+                                + " "
+                                + "past?)"
+                        );
+                    }
+                    break;
+                }
 
-            if (isLocalTimeUTC) {
-                terminal.println((i + 1) + ".\t" + UTC_FORMATTER.format(Instant.ofEpochMilli(time)));
+                if (isLocalTimeUTC) {
+                    terminal.println((i + 1) + ".\t" + UTC_FORMATTER.format(Instant.ofEpochMilli(time)));
+                } else {
+                    terminal.println((i + 1) + ".\t" + UTC_FORMATTER.format(Instant.ofEpochMilli(time)));
+                    terminal.println("\t" + LOCAL_FORMATTER.format(Instant.ofEpochMilli(time)));
+                }
+            }
+        } catch (Exception e) {
+            if (printDetail) {
+                throw e;
             } else {
-                terminal.println((i + 1) + ".\t" + UTC_FORMATTER.format(Instant.ofEpochMilli(time)));
-                terminal.println("\t" + LOCAL_FORMATTER.format(Instant.ofEpochMilli(time)));
+                throw new UserException(ExitCodes.OK, e.getMessage() + (e.getCause() == null ? "" : ": " + e.getCause().getMessage()));
             }
+
         }
     }
 }