[CFE] Remove crash data posting to some local service
Change-Id: I305f2d2e5ae85b17c99c29fc6e2816943d68e46c Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/497540 Reviewed-by: Johnni Winther <johnniwinther@google.com> Commit-Queue: Jens Johansen <jensj@google.com>
This commit is contained in:
committed by
dart-scoped@luci-project-accounts.iam.gserviceaccount.com
parent
1d8d507384
commit
8e166e93d3
@@ -2,15 +2,9 @@
|
||||
// for details. All rights reserved. Use of this source code is governed by a
|
||||
// BSD-style license that can be found in the LICENSE file.
|
||||
|
||||
import 'dart:convert' show jsonEncode;
|
||||
import 'dart:io'
|
||||
show ContentType, HttpClient, HttpClientRequest, SocketException, stderr;
|
||||
|
||||
import 'problems.dart' show DebugAbort;
|
||||
import 'uri_offset.dart';
|
||||
|
||||
const String defaultServerAddress = "http://127.0.0.1:59410/";
|
||||
|
||||
/// Tracks if there has been a crash reported through [reportCrash]. Should be
|
||||
/// reset between each compilation by calling [resetCrashReporting].
|
||||
bool hasCrashed = false;
|
||||
@@ -57,18 +51,7 @@ void resetCrashReporting() {
|
||||
hasCrashed = false;
|
||||
}
|
||||
|
||||
Future<T> reportCrash<T>(
|
||||
error,
|
||||
StackTrace trace, [
|
||||
Uri? uri,
|
||||
int? charOffset,
|
||||
]) async {
|
||||
// Coverage-ignore(suite): Not run.
|
||||
Future<void> note(String note) async {
|
||||
stderr.write(note);
|
||||
await stderr.flush();
|
||||
}
|
||||
|
||||
Future<T> reportCrash<T>(error, StackTrace trace, [Uri? uri, int? charOffset]) {
|
||||
if (hasCrashed) {
|
||||
// Coverage-ignore-block(suite): Not run.
|
||||
return new Future<T>.error(error, trace);
|
||||
@@ -83,61 +66,17 @@ Future<T> reportCrash<T>(
|
||||
}
|
||||
uri ??= firstSourceUri;
|
||||
hasCrashed = true;
|
||||
Map<String, dynamic> data = <String, dynamic>{};
|
||||
data["type"] = "crash";
|
||||
data["client"] = "package:cfe";
|
||||
if (uri != null) data["uri"] = "$uri";
|
||||
if (charOffset != null) data["offset"] = charOffset;
|
||||
data["error"] = safeToString(error);
|
||||
data["trace"] = "$trace";
|
||||
String json = jsonEncode(data);
|
||||
if (!const bool.fromEnvironment('dart.library.io')) {
|
||||
// Coverage-ignore-block(suite): Not run.
|
||||
// Don't create HttpClient when dart:io is unavailable.
|
||||
return new Future<T>.error(error, trace);
|
||||
}
|
||||
HttpClient client = new HttpClient();
|
||||
try {
|
||||
Uri serverUri = Uri.parse(defaultServerAddress);
|
||||
HttpClientRequest request;
|
||||
try {
|
||||
request = await client.postUrl(serverUri);
|
||||
} on SocketException {
|
||||
// Assume the crash logger isn't running.
|
||||
client.close(force: true);
|
||||
return new Future<T>.error(
|
||||
new Crash(uri, charOffset, error, trace).._hasBeenReported = true,
|
||||
trace,
|
||||
);
|
||||
}
|
||||
// Coverage-ignore-block(suite): Not run.
|
||||
await note("\nSending crash report data");
|
||||
request.persistentConnection = false;
|
||||
request.bufferOutput = false;
|
||||
String? host = request.connectionInfo?.remoteAddress.host;
|
||||
int? port = request.connectionInfo?.remotePort;
|
||||
await note(" to $host:$port");
|
||||
await request
|
||||
..headers.contentType = ContentType.json
|
||||
..write(json);
|
||||
await request.close();
|
||||
await note(".");
|
||||
} catch (e, s) {
|
||||
// Coverage-ignore-block(suite): Not run.
|
||||
await note("\n${safeToString(e)}\n$s\n");
|
||||
await note("\n\n\nFE::ERROR::$json\n\n\n");
|
||||
}
|
||||
// Coverage-ignore-block(suite): Not run.
|
||||
client.close(force: true);
|
||||
await note("\n");
|
||||
return new Future<T>.error(error, trace);
|
||||
return new Future<T>.error(
|
||||
new Crash(uri, charOffset, error, trace).._hasBeenReported = true,
|
||||
trace,
|
||||
);
|
||||
}
|
||||
|
||||
// Coverage-ignore(suite): Not run.
|
||||
String safeToString(Object object) {
|
||||
try {
|
||||
return "$object";
|
||||
} catch (e) {
|
||||
// Coverage-ignore-block(suite): Not run.
|
||||
return "Error when converting ${object.runtimeType} to string.";
|
||||
}
|
||||
}
|
||||
|
||||
@@ -515,7 +515,6 @@ llc
|
||||
ln
|
||||
locale
|
||||
locating
|
||||
logd
|
||||
logs
|
||||
loo
|
||||
lookahead
|
||||
|
||||
@@ -17,7 +17,6 @@ const List<String> subtools = const <String>[
|
||||
"compile",
|
||||
"compile-platform",
|
||||
"log",
|
||||
"logd",
|
||||
"outline",
|
||||
"parser",
|
||||
"scanner",
|
||||
@@ -34,10 +33,6 @@ const List<String> unsafeTools = const <String>[
|
||||
// messages.yaml.
|
||||
"generate-messages",
|
||||
|
||||
// This is a daemon process that never terminates. It's not currently tested
|
||||
// directly.
|
||||
"logd",
|
||||
|
||||
// This would eventually run this test again, recursively, and never
|
||||
// finish. As this tool is part of the workflow for testing Fasta, we assume
|
||||
// is exercised sufficiently.
|
||||
|
||||
@@ -33,7 +33,6 @@ case "${1//_/-}" in
|
||||
compile) SCRIPT="${TOOL_DIR}/compile.dart";;
|
||||
compile-platform) SCRIPT="${TOOL_DIR}/compile_platform.dart";;
|
||||
log) SCRIPT="${TOOL_DIR}/log_analyzer.dart";;
|
||||
logd) SCRIPT="${TOOL_DIR}/log_collector.dart";;
|
||||
outline) SCRIPT="${TOOL_DIR}/outline.dart";;
|
||||
parser) SCRIPT="${TOOL_DIR}/parser.dart";;
|
||||
scanner) SCRIPT="${TOOL_DIR}/scanner.dart";;
|
||||
|
||||
@@ -14,7 +14,6 @@ import 'compile_platform.dart' as compile_platform;
|
||||
import 'generate_experimental_flags.dart' as generate_experimental_flags;
|
||||
import 'generate_messages.dart' as generate_messages;
|
||||
import 'log_analyzer.dart' as log_analyzer;
|
||||
import 'log_collector.dart' as log_collector;
|
||||
import 'outline.dart' as outline;
|
||||
import 'parser.dart' as parser;
|
||||
import 'scanner.dart' as scanner;
|
||||
@@ -67,10 +66,6 @@ Future<void> main(List<String> args) async {
|
||||
mainFunction = log_analyzer.main;
|
||||
script = '${toolDir}/log_analyzer.dart';
|
||||
break;
|
||||
case 'logd':
|
||||
mainFunction = log_collector.main;
|
||||
script = '${toolDir}/log_collector.dart';
|
||||
break;
|
||||
case 'outline':
|
||||
mainFunction = outline.main;
|
||||
script = '${toolDir}/outline.dart';
|
||||
|
||||
@@ -1,118 +0,0 @@
|
||||
// Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file
|
||||
// for details. All rights reserved. Use of this source code is governed by a
|
||||
// BSD-style license that can be found in the LICENSE file.
|
||||
|
||||
import 'dart:convert' show jsonDecode, utf8;
|
||||
import 'dart:io';
|
||||
import 'dart:isolate' show RawReceivePort;
|
||||
|
||||
import 'package:front_end/src/base/crash.dart' show defaultServerAddress;
|
||||
|
||||
void badRequest(HttpRequest request, int status, String message) {
|
||||
request.response.statusCode = status;
|
||||
request.response.write('''
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>$message</title>
|
||||
</head>
|
||||
<body>
|
||||
<h1>$message</h1>
|
||||
</body>
|
||||
</html>
|
||||
''');
|
||||
request.response.close().catchError((e, s) {
|
||||
print("Request error: $e.");
|
||||
});
|
||||
print("${request.uri}: $message");
|
||||
}
|
||||
|
||||
Future<void> collectLog(DateTime time, HttpRequest request) async {
|
||||
String json = await request.cast<List<int>>().transform(utf8.decoder).join();
|
||||
var data;
|
||||
try {
|
||||
data = jsonDecode(json);
|
||||
} on FormatException catch (e) {
|
||||
print(e);
|
||||
return badRequest(
|
||||
request,
|
||||
HttpStatus.badRequest,
|
||||
"Malformed JSON data: ${e.message}.",
|
||||
);
|
||||
}
|
||||
if (data is! Map) {
|
||||
return badRequest(
|
||||
request,
|
||||
HttpStatus.badRequest,
|
||||
"Malformed JSON data: not a map.",
|
||||
);
|
||||
}
|
||||
if (data["type"] != "crash") {
|
||||
return badRequest(
|
||||
request,
|
||||
HttpStatus.badRequest,
|
||||
"Malformed JSON data: type should be 'crash'.",
|
||||
);
|
||||
}
|
||||
await request.response.close();
|
||||
String year = "${time.year}".padLeft(4, "0");
|
||||
String month = "${time.month}".padLeft(2, "0");
|
||||
String day = "${time.day}".padLeft(2, "0");
|
||||
String us = "${time.microsecondsSinceEpoch}".padLeft(19, '0');
|
||||
Uri? uri = Uri.base.resolve(
|
||||
"crash_logs/${data['client']}/$year-$month-$day/$us.log",
|
||||
);
|
||||
File file = new File.fromUri(uri);
|
||||
await file.parent.create(recursive: true);
|
||||
await file.writeAsString(json);
|
||||
print("Wrote ${uri.toFilePath()}");
|
||||
|
||||
String type = data["type"];
|
||||
String? text = data["uri"];
|
||||
uri = text == null ? null : Uri.parse(text);
|
||||
int charOffset = data["offset"];
|
||||
var error = data["error"];
|
||||
text = data["trace"];
|
||||
StackTrace? trace = text == null ? null : new StackTrace.fromString(text);
|
||||
String client = data["client"];
|
||||
print("""
|
||||
date: ${time}
|
||||
type: $type
|
||||
client: $client
|
||||
uri: $uri
|
||||
offset: $charOffset
|
||||
error:
|
||||
$error
|
||||
trace:
|
||||
$trace
|
||||
""");
|
||||
}
|
||||
|
||||
Future<void> main(List<String> arguments) async {
|
||||
RawReceivePort keepAlive = new RawReceivePort();
|
||||
Uri uri;
|
||||
if (arguments.length == 1) {
|
||||
uri = Uri.base.resolve(arguments.single);
|
||||
} else if (arguments.length == 0) {
|
||||
uri = Uri.parse(defaultServerAddress);
|
||||
} else {
|
||||
throw "Unexpected arguments: ${arguments.join(' ')}.";
|
||||
}
|
||||
int port = uri.hasPort ? uri.port : 0;
|
||||
var host = uri.host.isEmpty ? InternetAddress.loopbackIPv4 : uri.host;
|
||||
HttpServer server = await HttpServer.bind(host, port);
|
||||
print("Listening on http://${server.address.host}:${server.port}/");
|
||||
await for (HttpRequest request in server) {
|
||||
if (request.method != "POST") {
|
||||
badRequest(request, HttpStatus.methodNotAllowed, "Not allowed.");
|
||||
continue;
|
||||
}
|
||||
if (request.uri.path != "/") {
|
||||
badRequest(request, HttpStatus.notFound, "Not found.");
|
||||
continue;
|
||||
}
|
||||
await collectLog(new DateTime.now(), request);
|
||||
}
|
||||
keepAlive.close();
|
||||
}
|
||||
Reference in New Issue
Block a user