From 166ce57909e9ae0cf72ae2146073d332c57afb10 Mon Sep 17 00:00:00 2001 From: Delisa Mason Date: Fri, 15 Jul 2016 16:59:05 -0700 Subject: [PATCH 1/9] Use v2 format --- .../com/bugsnag/android/BreadcrumbsTest.java | 11 ++-- .../com/bugsnag/android/BreadcrumbType.java | 21 +++++++ .../java/com/bugsnag/android/Breadcrumbs.java | 62 ++++++++++++++++--- .../java/com/bugsnag/android/Bugsnag.java | 13 ++++ src/main/java/com/bugsnag/android/Client.java | 5 ++ 5 files changed, 97 insertions(+), 15 deletions(-) create mode 100644 src/main/java/com/bugsnag/android/BreadcrumbType.java diff --git a/src/androidTest/java/com/bugsnag/android/BreadcrumbsTest.java b/src/androidTest/java/com/bugsnag/android/BreadcrumbsTest.java index 3bbdbb3ff6..b4b589117c 100644 --- a/src/androidTest/java/com/bugsnag/android/BreadcrumbsTest.java +++ b/src/androidTest/java/com/bugsnag/android/BreadcrumbsTest.java @@ -4,6 +4,7 @@ import org.json.JSONException; import org.json.JSONArray; +import org.json.JSONObject; public class BreadcrumbsTest extends BugsnagTestCase { public void testSerialization() throws JSONException, IOException { @@ -14,7 +15,7 @@ public void testSerialization() throws JSONException, IOException { JSONArray breadcrumbsJson = streamableToJsonArray(breadcrumbs); assertEquals(3, breadcrumbsJson.length()); - assertEquals("Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim", breadcrumbsJson.getJSONArray(2).get(1)); + assertEquals("Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim", breadcrumbsJson.getJSONObject(2).getJSONObject("metadata").get("message")); } public void testSizeLimit() throws JSONException, IOException { @@ -29,8 +30,8 @@ public void testSizeLimit() throws JSONException, IOException { JSONArray breadcrumbsJson = streamableToJsonArray(breadcrumbs); assertEquals(5, breadcrumbsJson.length()); - assertEquals("2", breadcrumbsJson.getJSONArray(0).get(1)); - assertEquals("6", breadcrumbsJson.getJSONArray(4).get(1)); + assertEquals("2", breadcrumbsJson.getJSONObject(0).getJSONObject("metadata").get("message")); + assertEquals("6", breadcrumbsJson.getJSONObject(4).getJSONObject("metadata").get("message")); } public void testResize() throws JSONException, IOException { @@ -45,8 +46,8 @@ public void testResize() throws JSONException, IOException { JSONArray breadcrumbsJson = streamableToJsonArray(breadcrumbs); assertEquals(5, breadcrumbsJson.length()); - assertEquals("2", breadcrumbsJson.getJSONArray(0).get(1)); - assertEquals("6", breadcrumbsJson.getJSONArray(4).get(1)); + assertEquals("2", breadcrumbsJson.getJSONObject(0).getJSONObject("metadata").get("message")); + assertEquals("6", breadcrumbsJson.getJSONObject(4).getJSONObject("metadata").get("message")); } public void testClear() throws JSONException, IOException { diff --git a/src/main/java/com/bugsnag/android/BreadcrumbType.java b/src/main/java/com/bugsnag/android/BreadcrumbType.java new file mode 100644 index 0000000000..90bc3ba77b --- /dev/null +++ b/src/main/java/com/bugsnag/android/BreadcrumbType.java @@ -0,0 +1,21 @@ +package com.bugsnag.android; + +public enum BreadcrumbType { + CUSTOM ("custom"), + ERROR ("error"), + LOG ("log"), + NAVIGATION ("navigation"), + PROCESS ("process"), + REQUEST ("request"), + STATE ("state"), + USER ("user"); + + private final String type; + + BreadcrumbType(String type) { + this.type = type; + } + + String serialize() { return type; } +} + diff --git a/src/main/java/com/bugsnag/android/Breadcrumbs.java b/src/main/java/com/bugsnag/android/Breadcrumbs.java index 535658ae02..ee735779d6 100644 --- a/src/main/java/com/bugsnag/android/Breadcrumbs.java +++ b/src/main/java/com/bugsnag/android/Breadcrumbs.java @@ -5,43 +5,77 @@ import java.io.IOException; import java.util.Date; import java.util.Queue; +import java.util.HashMap; +import java.util.Map; import java.util.concurrent.ConcurrentLinkedQueue; + class Breadcrumbs implements JsonStream.Streamable { private static class Breadcrumb { private static final int MAX_MESSAGE_LENGTH = 140; + private static final String DEFAULT_NAME = "Custom"; + private static final String MESSAGE_METAKEY = "message"; final String timestamp; - final String message; + final String name; + final BreadcrumbType type; + final HashMap metadata; Breadcrumb(@NonNull String message) { this.timestamp = DateUtils.toISO8601(new Date()); - this.message = message.substring(0, Math.min(message.length(), MAX_MESSAGE_LENGTH)); + this.type = BreadcrumbType.CUSTOM; + HashMap metadata = new HashMap(); + metadata.put(MESSAGE_METAKEY, + message.substring(0, Math.min(message.length(), MAX_MESSAGE_LENGTH))); + this.metadata = metadata; + this.name = DEFAULT_NAME; + } + + Breadcrumb(@NonNull String name, BreadcrumbType type, HashMap metadata) { + this.timestamp = DateUtils.toISO8601(new Date()); + this.type = type; + this.metadata = metadata; + this.name = name; } } private static final int DEFAULT_MAX_SIZE = 20; private final Queue store = new ConcurrentLinkedQueue<>(); private int maxSize = DEFAULT_MAX_SIZE; + private final String TIMESTAMP_KEY = "timestamp"; + private final String NAME_KEY = "name"; + private final String METADATA_KEY = "metadata"; + private final String TYPE_KEY = "type"; public void toStream(@NonNull JsonStream writer) throws IOException { writer.beginArray(); for (Breadcrumb breadcrumb : store) { - writer.beginArray(); + writer.beginObject(); + writer.name(TIMESTAMP_KEY); writer.value(breadcrumb.timestamp); - writer.value(breadcrumb.message); - writer.endArray(); + writer.name(NAME_KEY); + writer.value(breadcrumb.name); + writer.name(TYPE_KEY); + writer.value(breadcrumb.type.serialize()); + writer.name(METADATA_KEY); + writer.beginObject(); + for (Map.Entry entry : breadcrumb.metadata.entrySet()) { + writer.name(entry.getKey()); + writer.value(entry.getValue()); + } + writer.endObject(); + writer.endObject(); } writer.endArray(); } void add(@NonNull String message) { - if (store.size() >= maxSize) { - // Remove oldest breadcrumb - store.poll(); - } - store.add(new Breadcrumb(message)); + addToStore(new Breadcrumb(message)); + } + + void add(@NonNull String name, BreadcrumbType type, HashMap metadata) { + addToStore(new Breadcrumb(name, type, metadata)); } void clear() { @@ -58,4 +92,12 @@ void setSize(int size) { } } } + + private void addToStore(Breadcrumb breadcrumb) { + if (store.size() >= maxSize) { + // Remove oldest breadcrumb + store.poll(); + } + store.add(breadcrumb); + } } diff --git a/src/main/java/com/bugsnag/android/Bugsnag.java b/src/main/java/com/bugsnag/android/Bugsnag.java index bad4668611..917f855f66 100644 --- a/src/main/java/com/bugsnag/android/Bugsnag.java +++ b/src/main/java/com/bugsnag/android/Bugsnag.java @@ -1,6 +1,7 @@ package com.bugsnag.android; import android.content.Context; +import java.util.HashMap; /** * Static access to a Bugsnag Client, the easiest way to use Bugsnag in your Android app. @@ -372,6 +373,18 @@ public static void leaveBreadcrumb(String message) { getClient().leaveBreadcrumb(message); } + /** + * Leave a "breadcrumb" log message representing an action or event which + * occurred in your app, to aid with debugging + * + * @param name A short label (max 32 chars) + * @param type A category for the breadcrumb + * @param metadata Additional diagnostic information about the app environment + */ + public static void leaveBreadcrumb(String name, BreadcrumbType type, HashMap metadata) { + getClient().leaveBreadcrumb(name, type, metadata); + } + /** * Set the maximum number of breadcrumbs to keep and sent to Bugsnag. * By default, we'll keep and send the 20 most recent breadcrumb log diff --git a/src/main/java/com/bugsnag/android/Client.java b/src/main/java/com/bugsnag/android/Client.java index 74166f2ab2..4c7b2af1fa 100644 --- a/src/main/java/com/bugsnag/android/Client.java +++ b/src/main/java/com/bugsnag/android/Client.java @@ -7,6 +7,7 @@ import android.support.annotation.Nullable; import android.text.TextUtils; import java.util.Locale; +import java.util.HashMap; /** * A Bugsnag Client instance allows you to use Bugsnag in your Android app. @@ -536,6 +537,10 @@ public void leaveBreadcrumb(String breadcrumb) { breadcrumbs.add(breadcrumb); } + public void leaveBreadcrumb(String name, BreadcrumbType type, HashMap metadata) { + breadcrumbs.add(name, type, metadata); + } + /** * Set the maximum number of breadcrumbs to keep and sent to Bugsnag. * By default, we'll keep and send the 20 most recent breadcrumb log From 958766cdba335b48fecb7b3e550e53d9c5e5cdd2 Mon Sep 17 00:00:00 2001 From: Delisa Mason Date: Tue, 19 Jul 2016 15:02:24 -0700 Subject: [PATCH 2/9] =?UTF-8?q?Use=20=E2=80=98manual=E2=80=99=20in=20place?= =?UTF-8?q?=20of=20custom?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/com/bugsnag/android/BreadcrumbsTest.java | 7 +++++++ src/main/java/com/bugsnag/android/BreadcrumbType.java | 2 +- src/main/java/com/bugsnag/android/Breadcrumbs.java | 4 ++-- 3 files changed, 10 insertions(+), 3 deletions(-) diff --git a/src/androidTest/java/com/bugsnag/android/BreadcrumbsTest.java b/src/androidTest/java/com/bugsnag/android/BreadcrumbsTest.java index b4b589117c..3c79231d40 100644 --- a/src/androidTest/java/com/bugsnag/android/BreadcrumbsTest.java +++ b/src/androidTest/java/com/bugsnag/android/BreadcrumbsTest.java @@ -60,4 +60,11 @@ public void testClear() throws JSONException, IOException { JSONArray breadcrumbsJson = streamableToJsonArray(breadcrumbs); assertEquals(0, breadcrumbsJson.length()); } + + public void testType() throws JSONException, IOException { + Breadcrumbs breadcrumbs = new Breadcrumbs(); + breadcrumbs.add("1"); + JSONArray breadcrumbsJson = streamableToJsonArray(breadcrumbs); + assertEquals("manual", breadcrumbsJson.getJSONObject(0).get("type")); + } } diff --git a/src/main/java/com/bugsnag/android/BreadcrumbType.java b/src/main/java/com/bugsnag/android/BreadcrumbType.java index 90bc3ba77b..d65fe6d188 100644 --- a/src/main/java/com/bugsnag/android/BreadcrumbType.java +++ b/src/main/java/com/bugsnag/android/BreadcrumbType.java @@ -1,9 +1,9 @@ package com.bugsnag.android; public enum BreadcrumbType { - CUSTOM ("custom"), ERROR ("error"), LOG ("log"), + MANUAL ("manual"), NAVIGATION ("navigation"), PROCESS ("process"), REQUEST ("request"), diff --git a/src/main/java/com/bugsnag/android/Breadcrumbs.java b/src/main/java/com/bugsnag/android/Breadcrumbs.java index ee735779d6..6dfd9f61ef 100644 --- a/src/main/java/com/bugsnag/android/Breadcrumbs.java +++ b/src/main/java/com/bugsnag/android/Breadcrumbs.java @@ -13,7 +13,7 @@ class Breadcrumbs implements JsonStream.Streamable { private static class Breadcrumb { private static final int MAX_MESSAGE_LENGTH = 140; - private static final String DEFAULT_NAME = "Custom"; + private static final String DEFAULT_NAME = "manual"; private static final String MESSAGE_METAKEY = "message"; final String timestamp; final String name; @@ -22,7 +22,7 @@ private static class Breadcrumb { Breadcrumb(@NonNull String message) { this.timestamp = DateUtils.toISO8601(new Date()); - this.type = BreadcrumbType.CUSTOM; + this.type = BreadcrumbType.MANUAL; HashMap metadata = new HashMap(); metadata.put(MESSAGE_METAKEY, message.substring(0, Math.min(message.length(), MAX_MESSAGE_LENGTH))); From 0f0c27a5bb950018a48be9445842dbf9dd233e03 Mon Sep 17 00:00:00 2001 From: Delisa Mason Date: Thu, 21 Jul 2016 13:24:04 -0700 Subject: [PATCH 3/9] Enforce size limit --- .../com/bugsnag/android/BreadcrumbsTest.java | 35 ++++++++-- .../java/com/bugsnag/android/Breadcrumbs.java | 66 ++++++++++++------- 2 files changed, 72 insertions(+), 29 deletions(-) diff --git a/src/androidTest/java/com/bugsnag/android/BreadcrumbsTest.java b/src/androidTest/java/com/bugsnag/android/BreadcrumbsTest.java index 3c79231d40..f1f28df0d2 100644 --- a/src/androidTest/java/com/bugsnag/android/BreadcrumbsTest.java +++ b/src/androidTest/java/com/bugsnag/android/BreadcrumbsTest.java @@ -1,6 +1,7 @@ package com.bugsnag.android; import java.io.IOException; +import java.util.HashMap; import org.json.JSONException; import org.json.JSONArray; @@ -15,7 +16,7 @@ public void testSerialization() throws JSONException, IOException { JSONArray breadcrumbsJson = streamableToJsonArray(breadcrumbs); assertEquals(3, breadcrumbsJson.length()); - assertEquals("Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim", breadcrumbsJson.getJSONObject(2).getJSONObject("metadata").get("message")); + assertEquals("Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim", breadcrumbsJson.getJSONObject(2).getJSONObject("metaData").get("message")); } public void testSizeLimit() throws JSONException, IOException { @@ -30,8 +31,8 @@ public void testSizeLimit() throws JSONException, IOException { JSONArray breadcrumbsJson = streamableToJsonArray(breadcrumbs); assertEquals(5, breadcrumbsJson.length()); - assertEquals("2", breadcrumbsJson.getJSONObject(0).getJSONObject("metadata").get("message")); - assertEquals("6", breadcrumbsJson.getJSONObject(4).getJSONObject("metadata").get("message")); + assertEquals("2", breadcrumbsJson.getJSONObject(0).getJSONObject("metaData").get("message")); + assertEquals("6", breadcrumbsJson.getJSONObject(4).getJSONObject("metaData").get("message")); } public void testResize() throws JSONException, IOException { @@ -46,8 +47,8 @@ public void testResize() throws JSONException, IOException { JSONArray breadcrumbsJson = streamableToJsonArray(breadcrumbs); assertEquals(5, breadcrumbsJson.length()); - assertEquals("2", breadcrumbsJson.getJSONObject(0).getJSONObject("metadata").get("message")); - assertEquals("6", breadcrumbsJson.getJSONObject(4).getJSONObject("metadata").get("message")); + assertEquals("2", breadcrumbsJson.getJSONObject(0).getJSONObject("metaData").get("message")); + assertEquals("6", breadcrumbsJson.getJSONObject(4).getJSONObject("metaData").get("message")); } public void testClear() throws JSONException, IOException { @@ -67,4 +68,28 @@ public void testType() throws JSONException, IOException { JSONArray breadcrumbsJson = streamableToJsonArray(breadcrumbs); assertEquals("manual", breadcrumbsJson.getJSONObject(0).get("type")); } + + public void testPayloadSizeLimit() throws JSONException, IOException { + Breadcrumbs breadcrumbs = new Breadcrumbs(); + HashMap metadata = new HashMap(); + for (int i = 0; i < 400; i++) { + metadata.put(String.format("%d", i), "!!"); + } + breadcrumbs.add("Rotated Menu", BreadcrumbType.STATE, metadata); + JSONArray breadcrumbsJson = streamableToJsonArray(breadcrumbs); + assertEquals(0, breadcrumbsJson.length()); + } + + public void testPayloadType() throws JSONException, IOException { + Breadcrumbs breadcrumbs = new Breadcrumbs(); + HashMap metadata = new HashMap(); + metadata.put("direction", "left"); + breadcrumbs.add("Rotated Menu", BreadcrumbType.STATE, metadata); + JSONArray breadcrumbsJson = streamableToJsonArray(breadcrumbs); + + assertEquals("Rotated Menu", breadcrumbsJson.getJSONObject(0).get("name")); + assertEquals("state", breadcrumbsJson.getJSONObject(0).get("type")); + assertEquals("left", breadcrumbsJson.getJSONObject(0).getJSONObject("metaData").get("direction")); + assertEquals(1, breadcrumbsJson.length()); + } } diff --git a/src/main/java/com/bugsnag/android/Breadcrumbs.java b/src/main/java/com/bugsnag/android/Breadcrumbs.java index 6dfd9f61ef..329291a23f 100644 --- a/src/main/java/com/bugsnag/android/Breadcrumbs.java +++ b/src/main/java/com/bugsnag/android/Breadcrumbs.java @@ -3,6 +3,7 @@ import android.support.annotation.NonNull; import java.io.IOException; +import java.io.StringWriter; import java.util.Date; import java.util.Queue; import java.util.HashMap; @@ -11,10 +12,14 @@ class Breadcrumbs implements JsonStream.Streamable { - private static class Breadcrumb { + private static class Breadcrumb implements JsonStream.Streamable { private static final int MAX_MESSAGE_LENGTH = 140; private static final String DEFAULT_NAME = "manual"; private static final String MESSAGE_METAKEY = "message"; + private final String TIMESTAMP_KEY = "timestamp"; + private final String NAME_KEY = "name"; + private final String METADATA_KEY = "metaData"; + private final String TYPE_KEY = "type"; final String timestamp; final String name; final BreadcrumbType type; @@ -36,35 +41,40 @@ private static class Breadcrumb { this.metadata = metadata; this.name = name; } + + public void toStream(@NonNull JsonStream writer) throws IOException { + writer.beginObject(); + writer.name(TIMESTAMP_KEY).value(this.timestamp); + writer.name(NAME_KEY).value(this.name); + writer.name(TYPE_KEY).value(this.type.serialize()); + writer.name(METADATA_KEY); + writer.beginObject(); + for (Map.Entry entry : this.metadata.entrySet()) { + writer.name(entry.getKey()).value(entry.getValue()); + } + writer.endObject(); + writer.endObject(); + } + + public int payloadSize() throws IOException { + StringWriter writer = new StringWriter(); + JsonStream jsonStream = new JsonStream(writer); + toStream(jsonStream); + + return writer.toString().length(); + } } private static final int DEFAULT_MAX_SIZE = 20; + private static final int MAX_PAYLOAD_SIZE = 4096; private final Queue store = new ConcurrentLinkedQueue<>(); private int maxSize = DEFAULT_MAX_SIZE; - private final String TIMESTAMP_KEY = "timestamp"; - private final String NAME_KEY = "name"; - private final String METADATA_KEY = "metadata"; - private final String TYPE_KEY = "type"; public void toStream(@NonNull JsonStream writer) throws IOException { writer.beginArray(); for (Breadcrumb breadcrumb : store) { - writer.beginObject(); - writer.name(TIMESTAMP_KEY); - writer.value(breadcrumb.timestamp); - writer.name(NAME_KEY); - writer.value(breadcrumb.name); - writer.name(TYPE_KEY); - writer.value(breadcrumb.type.serialize()); - writer.name(METADATA_KEY); - writer.beginObject(); - for (Map.Entry entry : breadcrumb.metadata.entrySet()) { - writer.name(entry.getKey()); - writer.value(entry.getValue()); - } - writer.endObject(); - writer.endObject(); + breadcrumb.toStream(writer); } writer.endArray(); @@ -94,10 +104,18 @@ void setSize(int size) { } private void addToStore(Breadcrumb breadcrumb) { - if (store.size() >= maxSize) { - // Remove oldest breadcrumb - store.poll(); + try { + if (breadcrumb.payloadSize() > MAX_PAYLOAD_SIZE) { + Logger.warn("Dropping breadcrumb because payload exceeds 4KB limit"); + return; + } + if (store.size() >= maxSize) { + // Remove oldest breadcrumb + store.poll(); + } + store.add(breadcrumb); + } catch (IOException ex) { + Logger.warn("Dropping breadcrumb because it could not be serialized", ex); } - store.add(breadcrumb); } } From 9f2108584b35dc8e250c428a5ff1c537863e653b Mon Sep 17 00:00:00 2001 From: Delisa Mason Date: Thu, 21 Jul 2016 19:00:51 -0700 Subject: [PATCH 4/9] Document breadcrumb types --- .../com/bugsnag/android/BreadcrumbType.java | 27 +++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/src/main/java/com/bugsnag/android/BreadcrumbType.java b/src/main/java/com/bugsnag/android/BreadcrumbType.java index d65fe6d188..487d625e85 100644 --- a/src/main/java/com/bugsnag/android/BreadcrumbType.java +++ b/src/main/java/com/bugsnag/android/BreadcrumbType.java @@ -1,13 +1,40 @@ package com.bugsnag.android; +/** + * Recognized types of breadcrumbs + */ public enum BreadcrumbType { + /** + * An error was sent to Bugsnag (internal use only) + */ ERROR ("error"), + /** + * A log message + */ LOG ("log"), + /** + * A manual invocation of `leaveBreadcrumb` (default) + */ MANUAL ("manual"), + /** + * A navigation event, such as a window opening or closing + */ NAVIGATION ("navigation"), + /** + * A background process such as a database query + */ PROCESS ("process"), + /** + * A network request + */ REQUEST ("request"), + /** + * A change in application state, such as launch or memory warning + */ STATE ("state"), + /** + * A user action, such as tapping a button + */ USER ("user"); private final String type; From bc6cbfee3964c47073ccff10b59656a666a7732a Mon Sep 17 00:00:00 2001 From: Delisa Mason Date: Thu, 21 Jul 2016 19:01:04 -0700 Subject: [PATCH 5/9] Update example --- .../main/java/com/bugsnag/android/example/ExampleActivity.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/example/src/main/java/com/bugsnag/android/example/ExampleActivity.java b/example/src/main/java/com/bugsnag/android/example/ExampleActivity.java index 4b24deff88..a3818e7305 100644 --- a/example/src/main/java/com/bugsnag/android/example/ExampleActivity.java +++ b/example/src/main/java/com/bugsnag/android/example/ExampleActivity.java @@ -10,6 +10,7 @@ import com.bugsnag.android.MetaData; import com.bugsnag.android.Severity; import com.bugsnag.android.other.Other; +import com.bugsnag.android.BreadcrumbType; import java.util.ArrayList; import java.util.Collection; import java.util.HashMap; @@ -47,7 +48,7 @@ public boolean run(Error error) { Bugsnag.addToTab("user", "age", 31); Bugsnag.addToTab("custom", "account", "something"); - Bugsnag.leaveBreadcrumb("onCreate"); + Bugsnag.leaveBreadcrumb("onCreate", BreadcrumbType.NAVIGATION, new HashMap()); new Thread(new Runnable() { public void run() { From a2c51bedc9f9c25c1ab9a0e6d2ccd91f9b931388 Mon Sep 17 00:00:00 2001 From: Delisa Mason Date: Thu, 21 Jul 2016 19:12:47 -0700 Subject: [PATCH 6/9] Add a breadcrumb when an error occurs --- src/main/java/com/bugsnag/android/Client.java | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/main/java/com/bugsnag/android/Client.java b/src/main/java/com/bugsnag/android/Client.java index 4c7b2af1fa..7b1aa29ad6 100644 --- a/src/main/java/com/bugsnag/android/Client.java +++ b/src/main/java/com/bugsnag/android/Client.java @@ -585,6 +585,11 @@ private void notify(final Error error, boolean blocking) { return; } + // Add a breadcrumb for this error occurring + HashMap breadcrumbMetadata = new HashMap(); + breadcrumbMetadata.put("message", error.getExceptionMessage()); + breadcrumbs.add(error.getExceptionName(), BreadcrumbType.ERROR, breadcrumbMetadata); + // Capture the state of the app and device and attach diagnostics to the error error.setAppData(appData); error.setDeviceData(deviceData); From 6f95a061233b5171109cfd48e70ee684cacf9b7d Mon Sep 17 00:00:00 2001 From: Delisa Mason Date: Thu, 21 Jul 2016 19:12:56 -0700 Subject: [PATCH 7/9] Add a Makefile --- Makefile | 12 ++++++++++++ 1 file changed, 12 insertions(+) create mode 100644 Makefile diff --git a/Makefile b/Makefile new file mode 100644 index 0000000000..c599d90386 --- /dev/null +++ b/Makefile @@ -0,0 +1,12 @@ +all: build + +.PHONY: build test clean + +build: + ./gradlew build + +clean: + ./gradlew clean + +test: + ./gradlew :connectedCheck From 44e2f857eff250029d5566d017255252c6b01de7 Mon Sep 17 00:00:00 2001 From: Delisa Mason Date: Thu, 21 Jul 2016 19:14:42 -0700 Subject: [PATCH 8/9] Update payload version --- src/androidTest/java/com/bugsnag/android/ErrorTest.java | 2 +- src/main/java/com/bugsnag/android/Error.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/androidTest/java/com/bugsnag/android/ErrorTest.java b/src/androidTest/java/com/bugsnag/android/ErrorTest.java index cb205240bd..b9522ddba2 100644 --- a/src/androidTest/java/com/bugsnag/android/ErrorTest.java +++ b/src/androidTest/java/com/bugsnag/android/ErrorTest.java @@ -39,7 +39,7 @@ public void testBasicSerialization() throws JSONException, IOException { JSONObject errorJson = streamableToJson(error); assertEquals("warning", errorJson.get("severity")); - assertEquals("2", errorJson.get("payloadVersion")); + assertEquals("3", errorJson.get("payloadVersion")); assertNotNull(errorJson.get("severity")); assertNotNull(errorJson.get("metaData")); assertNotNull(errorJson.get("threads")); diff --git a/src/main/java/com/bugsnag/android/Error.java b/src/main/java/com/bugsnag/android/Error.java index 131d727b05..9cfe227f0b 100644 --- a/src/main/java/com/bugsnag/android/Error.java +++ b/src/main/java/com/bugsnag/android/Error.java @@ -16,7 +16,7 @@ * @see BeforeNotify */ public class Error implements JsonStream.Streamable { - private static final String PAYLOAD_VERSION = "2"; + private static final String PAYLOAD_VERSION = "3"; private final Configuration config; private AppData appData; From 90a5568ed2af27a701b7addf5531c17787fb8b02 Mon Sep 17 00:00:00 2001 From: Delisa Mason Date: Thu, 21 Jul 2016 19:36:42 -0700 Subject: [PATCH 9/9] Cleanup types --- src/main/java/com/bugsnag/android/Breadcrumbs.java | 13 +++++-------- src/main/java/com/bugsnag/android/Bugsnag.java | 5 +++-- src/main/java/com/bugsnag/android/Client.java | 9 ++++----- 3 files changed, 12 insertions(+), 15 deletions(-) diff --git a/src/main/java/com/bugsnag/android/Breadcrumbs.java b/src/main/java/com/bugsnag/android/Breadcrumbs.java index 329291a23f..31e5b31a6f 100644 --- a/src/main/java/com/bugsnag/android/Breadcrumbs.java +++ b/src/main/java/com/bugsnag/android/Breadcrumbs.java @@ -6,8 +6,8 @@ import java.io.StringWriter; import java.util.Date; import java.util.Queue; -import java.util.HashMap; import java.util.Map; +import java.util.Collections; import java.util.concurrent.ConcurrentLinkedQueue; @@ -23,19 +23,16 @@ private static class Breadcrumb implements JsonStream.Streamable { final String timestamp; final String name; final BreadcrumbType type; - final HashMap metadata; + final Map metadata; Breadcrumb(@NonNull String message) { this.timestamp = DateUtils.toISO8601(new Date()); this.type = BreadcrumbType.MANUAL; - HashMap metadata = new HashMap(); - metadata.put(MESSAGE_METAKEY, - message.substring(0, Math.min(message.length(), MAX_MESSAGE_LENGTH))); - this.metadata = metadata; + this.metadata = Collections.singletonMap(MESSAGE_METAKEY, message.substring(0, Math.min(message.length(), MAX_MESSAGE_LENGTH))); this.name = DEFAULT_NAME; } - Breadcrumb(@NonNull String name, BreadcrumbType type, HashMap metadata) { + Breadcrumb(@NonNull String name, BreadcrumbType type, Map metadata) { this.timestamp = DateUtils.toISO8601(new Date()); this.type = type; this.metadata = metadata; @@ -84,7 +81,7 @@ void add(@NonNull String message) { addToStore(new Breadcrumb(message)); } - void add(@NonNull String name, BreadcrumbType type, HashMap metadata) { + void add(@NonNull String name, BreadcrumbType type, Map metadata) { addToStore(new Breadcrumb(name, type, metadata)); } diff --git a/src/main/java/com/bugsnag/android/Bugsnag.java b/src/main/java/com/bugsnag/android/Bugsnag.java index 917f855f66..da96226421 100644 --- a/src/main/java/com/bugsnag/android/Bugsnag.java +++ b/src/main/java/com/bugsnag/android/Bugsnag.java @@ -1,7 +1,8 @@ package com.bugsnag.android; +import java.util.Map; + import android.content.Context; -import java.util.HashMap; /** * Static access to a Bugsnag Client, the easiest way to use Bugsnag in your Android app. @@ -381,7 +382,7 @@ public static void leaveBreadcrumb(String message) { * @param type A category for the breadcrumb * @param metadata Additional diagnostic information about the app environment */ - public static void leaveBreadcrumb(String name, BreadcrumbType type, HashMap metadata) { + public static void leaveBreadcrumb(String name, BreadcrumbType type, Map metadata) { getClient().leaveBreadcrumb(name, type, metadata); } diff --git a/src/main/java/com/bugsnag/android/Client.java b/src/main/java/com/bugsnag/android/Client.java index 7b1aa29ad6..1ffb13f218 100644 --- a/src/main/java/com/bugsnag/android/Client.java +++ b/src/main/java/com/bugsnag/android/Client.java @@ -7,7 +7,8 @@ import android.support.annotation.Nullable; import android.text.TextUtils; import java.util.Locale; -import java.util.HashMap; +import java.util.Collections; +import java.util.Map; /** * A Bugsnag Client instance allows you to use Bugsnag in your Android app. @@ -537,7 +538,7 @@ public void leaveBreadcrumb(String breadcrumb) { breadcrumbs.add(breadcrumb); } - public void leaveBreadcrumb(String name, BreadcrumbType type, HashMap metadata) { + public void leaveBreadcrumb(String name, BreadcrumbType type, Map metadata) { breadcrumbs.add(name, type, metadata); } @@ -586,9 +587,7 @@ private void notify(final Error error, boolean blocking) { } // Add a breadcrumb for this error occurring - HashMap breadcrumbMetadata = new HashMap(); - breadcrumbMetadata.put("message", error.getExceptionMessage()); - breadcrumbs.add(error.getExceptionName(), BreadcrumbType.ERROR, breadcrumbMetadata); + breadcrumbs.add(error.getExceptionName(), BreadcrumbType.ERROR, Collections.singletonMap("message", error.getExceptionMessage())); // Capture the state of the app and device and attach diagnostics to the error error.setAppData(appData);