@@ -61,8 +61,6 @@ public final class CrashUploader {
6161
6262 private static final MediaType APPLICATION_JSON =
6363 MediaType .get ("application/json; charset=utf-8" );
64- private static final MediaType APPLICATION_OCTET_STREAM =
65- MediaType .parse ("application/octet-stream" );
6664
6765 private final Config config ;
6866 private final ConfigManager .StoredConfig storedConfig ;
@@ -114,10 +112,34 @@ public CrashUploader(@Nonnull final ConfigManager.StoredConfig storedConfig) {
114112 CRASH_TRACKING_UPLOAD_TIMEOUT , CRASH_TRACKING_UPLOAD_TIMEOUT_DEFAULT )));
115113 }
116114
115+ public void notifyCrashStarted (String error ) {
116+ // send a ping message to the telemetry to notify that the crash report started
117+ try (Buffer buf = new Buffer ();
118+ JsonWriter writer = JsonWriter .of (buf )) {
119+ writer .beginObject ();
120+ writer .name ("crash_uuid" ).value (storedConfig .reportUUID );
121+ writer .name ("kind" ).value ("Crash ping" );
122+ writer .name ("current_schema_version" ).value ("1.0" );
123+ writer
124+ .name ("message" )
125+ .value (
126+ "Crashtracker crash ping: " + (error != null ? error : "crash processing started" ));
127+ writer .endObject ();
128+ handleCall (makeTelemetryRequest (makeTelemetryRequestBody (buf .readUtf8 (), true )), "ping" );
129+
130+ } catch (Throwable t ) {
131+ log .error ("Failed to send crash ping" , t );
132+ }
133+ }
134+
117135 public void upload (@ Nonnull List <Path > files ) throws IOException {
136+ String uuid = storedConfig .reportUUID ;
118137 for (Path file : files ) {
119138 uploadToLogs (file );
120- uploadToTelemetry (file );
139+ uploadToTelemetry (file , uuid );
140+ // if we send more than 1 file via the CLI, let's make sure we have unique uuid (will be
141+ // generated if null)
142+ uuid = null ;
121143 }
122144 }
123145
@@ -236,24 +258,23 @@ private String extractErrorStackTrace(String fileContent, boolean redact) {
236258 return "" ;
237259 }
238260
239- private String extractErrorStackTrace (String fileContent ) {
240- return extractErrorStackTrace (fileContent , true );
241- }
242-
243- boolean uploadToTelemetry (@ Nonnull Path file ) {
261+ boolean uploadToTelemetry (@ Nonnull Path file , String uuid ) {
244262 try {
245263 String content = new String (Files .readAllBytes (file ), Charset .defaultCharset ());
246- handleCall (makeTelemetryRequest (content ));
247- } catch (IOException e ) {
248- log .error ("Failed to upload crash file: {}" , file , e );
264+ CrashLog crashLog = CrashLogParser .fromHotspotCrashLog (uuid , content );
265+ if (crashLog == null ) {
266+ log .error ("Failed to parse crash log" );
267+ return false ;
268+ }
269+ handleCall (makeTelemetryRequest (makeTelemetryRequestBody (crashLog .toJson (), false )), "crash" );
270+ } catch (Throwable t ) {
271+ log .error ("Failed to upload crash file: {}" , file , t );
249272 return false ;
250273 }
251274 return true ;
252275 }
253276
254- private Call makeTelemetryRequest (@ Nonnull String content ) throws IOException {
255- final RequestBody requestBody = makeTelemetryRequestBody (content );
256-
277+ private Call makeTelemetryRequest (@ Nonnull RequestBody requestBody ) throws IOException {
257278 final Map <String , String > headers = new HashMap <>();
258279 // Set chunked transfer
259280 MediaType contentType = requestBody .contentType ();
@@ -273,11 +294,9 @@ private Call makeTelemetryRequest(@Nonnull String content) throws IOException {
273294 .build ());
274295 }
275296
276- private RequestBody makeTelemetryRequestBody (@ Nonnull String content ) throws IOException {
277- CrashLog crashLog = CrashLogParser .fromHotspotCrashLog (content );
278- if (crashLog == null ) {
279- throw new IOException ("Failed to parse crash log" );
280- }
297+ private RequestBody makeTelemetryRequestBody (@ Nonnull String payload , boolean isPing )
298+ throws IOException {
299+
281300 try (Buffer buf = new Buffer ()) {
282301 try (JsonWriter writer = JsonWriter .of (buf )) {
283302 writer .beginObject ();
@@ -291,11 +310,17 @@ private RequestBody makeTelemetryRequestBody(@Nonnull String content) throws IOE
291310 writer .name ("payload" );
292311 writer .beginArray ();
293312 writer .beginObject ();
294- writer .name ("message" ).value (crashLog .toJson ());
295- writer .name ("level" ).value ("ERROR" );
296- writer .name ("tags" ).value ("severity:crash" );
297- writer .name ("is_sensitive" ).value (true );
298- writer .name ("is_crash" ).value (true );
313+ writer .name ("message" ).value (payload );
314+ if (isPing ) {
315+ writer .name ("level" ).value ("DEBUG" );
316+ writer .name ("is_sensitive" ).value (false );
317+ writer .name ("is_crash_ping" ).value (true );
318+ } else {
319+ writer .name ("level" ).value ("ERROR" );
320+ writer .name ("tags" ).value ("severity:crash" );
321+ writer .name ("is_sensitive" ).value (true );
322+ writer .name ("is_crash" ).value (true );
323+ }
299324 writer .endObject ();
300325 writer .endArray ();
301326 writer .name ("application" );
@@ -327,32 +352,35 @@ private RequestBody makeTelemetryRequestBody(@Nonnull String content) throws IOE
327352 }
328353 }
329354
330- private void handleCall (final Call call ) {
355+ private void handleCall (final Call call , String kind ) {
331356 try (Response response = call .execute ()) {
332- handleSuccess (call , response );
333- } catch (IOException e ) {
334- handleFailure (e );
357+ handleSuccess (call , response , kind );
358+ } catch (Throwable t ) {
359+ handleFailure (t , kind );
335360 }
336361 }
337362
338- private void handleSuccess (final Call call , final Response response ) throws IOException {
363+ private void handleSuccess (final Call call , final Response response , String kind )
364+ throws IOException {
339365 if (response .isSuccessful ()) {
340366 log .info (
341- "Successfully uploaded the crash files to {}, code = {} \" {}\" " ,
367+ "Successfully uploaded the crash {} to {}, code = {} \" {}\" " ,
368+ kind ,
342369 call .request ().url (),
343370 response .code (),
344371 response .message ());
345372 } else {
346373 log .error (
347- "Failed to upload crash files to {}, code = {} \" {}\" , body = \" {}\" " ,
374+ "Failed to upload crash {} to {}, code = {} \" {}\" , body = \" {}\" " ,
375+ kind ,
348376 call .request ().url (),
349377 response .code (),
350378 response .message (),
351379 response .body () != null ? response .body ().string ().trim () : "<null>" );
352380 }
353381 }
354382
355- private void handleFailure (final IOException exception ) {
356- log .error ("Failed to upload crash files , got exception" , exception );
383+ private void handleFailure (final Throwable exception , String kind ) {
384+ log .error ("Failed to upload crash {} , got exception" , kind , exception );
357385 }
358386}
0 commit comments