Merge pull request #482 from RedBrogdon/logging

diff --git a/lib/services_gae.dart b/lib/services_gae.dart
index f0f5f48..104ace9 100644
--- a/lib/services_gae.dart
+++ b/lib/services_gae.dart
@@ -65,6 +65,8 @@
 
   GaeServer(this.sdkPath, this.redisServerUri) {
     hierarchicalLoggingEnabled = true;
+    recordStackTraceAtLevel = Level.SEVERE;
+
     _logger.level = Level.ALL;
 
     discoveryEnabled = false;
@@ -120,7 +122,13 @@
   }
 
   Future _processReadynessRequest(io.HttpRequest request) async {
-    request.response.statusCode = io.HttpStatus.ok;
+    if (commonServer.running) {
+      request.response.statusCode = io.HttpStatus.ok;
+    } else {
+      request.response.statusCode = io.HttpStatus.internalServerError;
+      _logger.info('CommonServer not running - failing readiness check.');
+    }
+
     await request.response.close();
   }
 
diff --git a/lib/src/common_server.dart b/lib/src/common_server.dart
index 00744b6..a951f84 100644
--- a/lib/src/common_server.dart
+++ b/lib/src/common_server.dart
@@ -47,10 +47,12 @@
   AnalysisServerWrapper analysisServer;
   AnalysisServerWrapper flutterAnalysisServer;
 
-  bool get analysisServersRunning => analysisServer.analysisServer != null &&
-    flutterAnalysisServer.analysisServer != null;
+  bool get analysisServersRunning =>
+      analysisServer.analysisServer != null &&
+      flutterAnalysisServer.analysisServer != null;
 
   bool _running = false;
+
   bool get running => _running;
 
   CommonServer(
@@ -91,6 +93,8 @@
         exit(code);
       }
     }));
+
+    _running = true;
   }
 
   Future<void> warmup({bool useHtml = false}) async {
@@ -98,7 +102,6 @@
     await compiler.warmup(useHtml: useHtml);
     await analysisServer.warmup(useHtml: useHtml);
     await flutterAnalysisServer.warmup(useHtml: useHtml);
-    _running = true;
   }
 
   Future<void> restart() async {
@@ -119,7 +122,7 @@
       flutterAnalysisServer.shutdown(),
       compiler.dispose(),
       Future<dynamic>.sync(cache.shutdown)
-    ]);
+    ]).timeout(Duration(minutes: 1));
   }
 
   @ApiMethod(
diff --git a/tool/warmup.dart b/tool/warmup.dart
index 2f042eb..ea53118 100644
--- a/tool/warmup.dart
+++ b/tool/warmup.dart
@@ -4,10 +4,11 @@
 
 import 'dart:async';
 import 'dart:convert' as convert;
+import 'dart:io';
 
 import 'package:http/http.dart' as http;
 
-const BASE_URI = 'dart-services.appspot.com/api/dartservices/v1/';
+const BASE_PATH = '/api/dartservices/v1/';
 
 const count = 200;
 
@@ -35,17 +36,25 @@
 String uri;
 
 Future<void> main(List<String> args) async {
-  String appPrefix;
+  String appHost;
 
   if (args.isNotEmpty) {
-    appPrefix = '${args[0]}.';
+    appHost = '${args[0]}';
   } else {
-    appPrefix = '';
+    print('''Pass the fully qualified dart-services hostname (no protocol, no
+path) as the first argument when invoking this script.
+
+For example:
+
+dart warmup.dart 20200124t152413-dot-dart-services-0.appspot.com
+''');
+
+    exit(1);
   }
 
   // Use an insecure connection for test driving to avoid cert problems
   // with the prefixed app version.
-  uri = 'http://$appPrefix$BASE_URI';
+  uri = 'http://$appHost$BASE_PATH';
 
   print('Target URI\n$uri');