1818import java .net .InetSocketAddress ;
1919import java .net .SocketAddress ;
2020import java .nio .channels .SocketChannel ;
21+ import java .nio .file .Files ;
2122import java .nio .file .Path ;
2223import java .nio .file .Paths ;
2324import java .util .ArrayList ;
3536 * Server Runner
3637 */
3738public class NatsServerRunner implements AutoCloseable {
39+ public static final String ERROR_NOTE_PART_1 = "Make sure that the nats-server is installed and in your PATH." ;
40+ public static final String ERROR_NOTE_PART_2 = "See https://github.com/nats-io/nats-server for information on installation" ;
3841 public static long DEFAULT_PROCESS_CHECK_WAIT = 100 ;
3942 public static int DEFAULT_PROCESS_CHECK_TRIES = 10 ;
4043 public static long DEFAULT_RUN_CHECK_WAIT = 100 ;
@@ -310,8 +313,16 @@ protected NatsServerRunner(Builder b) throws IOException {
310313 _executablePath = b .executablePath == null ? getResolvedServerPath () : b .executablePath .toString ();
311314 _port = b .port == null || b .port <= 0 ? nextPort () : b .port ;
312315
313- _displayOut = b .output == null ? DefaultOutputSupplier .get () : b .output ;
314- _displayOut .setLevel (b .outputLevel == null ? DefaultOutputLevel : b .outputLevel );
316+ if (b .output == null ) {
317+ _displayOut = DefaultOutputSupplier .get ();
318+ _displayOut .setLevel (DefaultOutputLevel );
319+ }
320+ else {
321+ _displayOut = b .output ;
322+ if (b .outputLevel != null ) {
323+ _displayOut .setLevel (b .outputLevel );
324+ }
325+ }
315326
316327 long procCheckWait = b .processCheckWait == null ? DEFAULT_PROCESS_CHECK_WAIT : b .processCheckWait ;
317328 int procCheckTries = b .processCheckTries == null ? DEFAULT_PROCESS_CHECK_TRIES : b .processCheckTries ;
@@ -361,6 +372,7 @@ protected NatsServerRunner(Builder b) throws IOException {
361372
362373 _cmdLine = String .join (" " , cmd );
363374
375+ NatsOutputLogger nol = null ;
364376 try {
365377 ProcessBuilder pb = new ProcessBuilder (cmd );
366378 pb .redirectErrorStream (true );
@@ -369,8 +381,7 @@ protected NatsServerRunner(Builder b) throws IOException {
369381 _displayOut .info ("%%% Starting [" + _cmdLine + "] with redirected IO" );
370382
371383 process = pb .start ();
372-
373- NatsOutputLogger .logOutput (_displayOut , process , DEFAULT_NATS_SERVER );
384+ nol = NatsOutputLogger .logOutput (_displayOut , process , DEFAULT_NATS_SERVER );
374385
375386 int tries = procCheckTries ;
376387 do {
@@ -401,15 +412,51 @@ protected NatsServerRunner(Builder b) throws IOException {
401412 }
402413
403414 _displayOut .info ("%%% Started [" + _cmdLine + "]" );
415+ nol .endStartupPhase ();
404416 }
405417 catch (IOException ex ) {
406- _displayOut .info ("%%% Failed to start [" + _cmdLine + "] with message:" );
407- _displayOut .info ("\t " + ex .getMessage ());
408- _displayOut .info ("%%% Make sure that the nats-server is installed and in your PATH." );
409- _displayOut .info ("%%% See https://github.com/nats-io/nats-server for information on installation" );
418+ _displayOut .error ("%%% Failed to run [" + _cmdLine + "]" );
419+ String exMsg = ex .getMessage ();
420+ if (exMsg != null ) {
421+ _displayOut .error (" " + ex .getMessage ());
422+ }
423+ _displayOut .error ("%%% " + ERROR_NOTE_PART_1 );
424+ _displayOut .error ("%%% " + ERROR_NOTE_PART_2 );
425+ StringBuilder exMessage = new StringBuilder ("Failed to run [" ).append (_cmdLine ).append ("]" );
426+ if (b .fullErrorReportOnStartup ) {
427+ if (nol != null ) {
428+ for (String line : nol .getStartupLines ()) {
429+ exMessage .append (System .lineSeparator ()).append (line );
430+ }
431+ }
432+ if (_cmdLine .contains (CONFIG_FILE_OPTION_NAME )) {
433+ String configPath = _configFile .getAbsolutePath ();
434+ String configSep = getConfigSep (configPath );
435+ exMessage .append (System .lineSeparator ()).append (configSep );
436+ exMessage .append (System .lineSeparator ()).append (configPath );
437+ exMessage .append (System .lineSeparator ()).append (configSep );
438+ try {
439+ List <String > lines = Files .readAllLines (_configFile .toPath ());
440+ for (String line : lines ) {
441+ exMessage .append (System .lineSeparator ()).append (line );
442+ }
443+ }
444+ catch (Exception ignore ) {
445+ }
446+ exMessage .append (System .lineSeparator ()).append (configSep );
447+ }
448+ }
449+ throw new IllegalStateException (exMessage .toString ());
450+ }
451+ }
410452
411- throw new IllegalStateException ("Failed to run [" + _cmdLine + "]" );
453+ private String getConfigSep (String configPath ) {
454+ StringBuilder sep = new StringBuilder ("------------------------------" );
455+ int len = configPath .length ();
456+ while (sep .length () < len ) {
457+ sep .append (sep );
412458 }
459+ return sep .substring (0 , len );
413460 }
414461
415462 // ----------------------------------------------------------------------------------------------------
@@ -552,6 +599,7 @@ public static class Builder {
552599 Integer processCheckTries ;
553600 Long connectCheckWait ;
554601 Integer connectCheckTries ;
602+ boolean fullErrorReportOnStartup = true ;
555603
556604 public Builder port (Integer port ) {
557605 this .port = port ;
@@ -653,6 +701,11 @@ public Builder connectCheckTries(Integer connectCheckTries) {
653701 return this ;
654702 }
655703
704+ public Builder fullErrorReportOnStartup (boolean expandedError ) {
705+ this .fullErrorReportOnStartup = expandedError ;
706+ return this ;
707+ }
708+
656709 public Builder runnerOptions (NatsServerRunnerOptions nsro ) {
657710 port (nsro .port ())
658711 .debugLevel (nsro .debugLevel ())
0 commit comments