Skip to content

Commit

Permalink
Merge pull request #115 from joshdholtz/bugfix-114
Browse files Browse the repository at this point in the history
Add breadcrumbs to uncaught exceptions
  • Loading branch information
marcomorain committed Feb 20, 2017
2 parents f239124 + edb70e9 commit 7b96566
Show file tree
Hide file tree
Showing 5 changed files with 47 additions and 11 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ table below shows an example of what the data will look like in Sentry.

Version | Changes
--- | ---
**1.5.4** | Ensure that breadcrumbs are added to all exceptions. [#115](https://github.com/joshdholtz/Sentry-Android/issues/115).
**1.5.3** | Fix thread-safety bug when serializing breadcrumbs. [#110](https://github.com/joshdholtz/Sentry-Android/issues/110) (thanks to [fab1an](https://github.com/fab1an)).
**1.5.2** | Send stack-frames to Sentry in the correct order. [#95](https://github.com/joshdholtz/Sentry-Android/pull/95).<br/> Use the [versionName](https://developer.android.com/studio/publish/versioning.html#appversioning), rather than versionCode, as the default value for the release field of events (thanks to [FelixBondarenko](https://github.com/FelixBondarenko)).
**1.5.1** | Revert accidental API removal of `captureException(Throwable, SentryEventLevel)`.
Expand Down
2 changes: 1 addition & 1 deletion sentry-android/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ plugins {
apply plugin: 'com.android.library'


def SentryAndroidVersion = "1.5.3"
def SentryAndroidVersion = "1.5.4"

android {
compileSdkVersion 24
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -122,4 +122,11 @@ public void testInternalPackageNameRegex() throws Exception {
assertFalse(c, c.matches(Sentry.SentryEventBuilder.isInternalPackage));
}
}
}

public void testMaxBreadcrumbs() {
Sentry.setMaxBreadcrumbs(-5);
assertEquals(0, Sentry.LazyHolder.instance.breadcrumbs.maxBreadcrumbs.get());
Sentry.setMaxBreadcrumbs(1000);
assertEquals(200, Sentry.LazyHolder.instance.breadcrumbs.maxBreadcrumbs.get());
}
}
37 changes: 29 additions & 8 deletions sentry-android/src/main/java/com/joshdholtz/sentry/Sentry.java
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicLong;
import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;
Expand All @@ -89,7 +90,6 @@ public class Sentry {
private static final String TAG = "Sentry";
private final static String sentryVersion = "7";
private static final int MAX_QUEUE_LENGTH = 50;
private static final int MAX_BREADCRUMBS = 10;

public static boolean debug = false;

Expand All @@ -101,7 +101,7 @@ public class Sentry {
private SentryEventCaptureListener captureListener;
private JSONObject contexts = new JSONObject();
private Executor executor;
private final Breadcrumbs breadcrumbs = new Breadcrumbs();
final Breadcrumbs breadcrumbs = new Breadcrumbs();

public enum SentryEventLevel {

Expand Down Expand Up @@ -131,8 +131,8 @@ private static Sentry getInstance() {
return LazyHolder.instance;
}

private static class LazyHolder {
private static final Sentry instance = new Sentry();
static class LazyHolder {
static final Sentry instance = new Sentry();
}

public static void init(Context context, String dsn) {
Expand Down Expand Up @@ -259,6 +259,16 @@ public static void setCaptureListener(SentryEventCaptureListener captureListener
Sentry.getInstance().captureListener = captureListener;
}

/**
* Set a limit on the number of breadcrumbs that will be stored by the client, and sent with
* exceptions.
*
* @param maxBreadcrumbs the maximum number of breadcrumbs to store and send.
*/
public static void setMaxBreadcrumbs(int maxBreadcrumbs) {
getInstance().breadcrumbs.setMaxBreadcrumbs(maxBreadcrumbs);
}

public static void captureMessage(String message) {
Sentry.captureMessage(message, SentryEventLevel.INFO);
}
Expand Down Expand Up @@ -519,6 +529,7 @@ public void uncaughtException(Thread thread, Throwable e) {
// Here you should have a more robust, permanent record of problems
SentryEventBuilder builder = new SentryEventBuilder(e, SentryEventLevel.FATAL);
builder.setRelease(sentry.appInfo.versionName);
builder.event.put("breadcrumbs", sentry.breadcrumbs.current());

if (sentry.captureListener != null) {
builder = sentry.captureListener.beforeCapture(builder);
Expand Down Expand Up @@ -656,18 +667,23 @@ enum Type {
}
}

private static class Breadcrumbs {
static class Breadcrumbs {

// The max number of breadcrumbs that will be tracked at any one time.
final AtomicInteger maxBreadcrumbs = new AtomicInteger(100);

// Access to this list must be thread-safe.
// See GitHub Issue #110
// This list is protected by the provided ReadWriteLock.
private final LinkedList<Breadcrumb> breadcrumbs = new LinkedList<>();
private final ReadWriteLock lock = new ReentrantReadWriteLock();
final LinkedList<Breadcrumb> breadcrumbs = new LinkedList<>();
final ReadWriteLock lock = new ReentrantReadWriteLock();

void push(Breadcrumb b) {
try {
lock.writeLock().lock();
while (breadcrumbs.size() >= MAX_BREADCRUMBS) {

final int toRemove = breadcrumbs.size() - maxBreadcrumbs.get() + 1;
for (int i = 0; i < toRemove; i++) {
breadcrumbs.removeFirst();
}
breadcrumbs.add(b);
Expand Down Expand Up @@ -698,6 +714,11 @@ JSONArray current() {
return crumbs;
}

void setMaxBreadcrumbs(int maxBreadcrumbs) {
maxBreadcrumbs = Math.min(200, Math.max(0, maxBreadcrumbs));
this.maxBreadcrumbs.set(maxBreadcrumbs);
}

}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,11 +25,18 @@ protected void onCreate(Bundle savedInstanceState) {
Sentry.init(this, yourDSN);
Sentry.debug = true;


Sentry.setMaxBreadcrumbs(8);
for (int i=0; i<15; i++) {
Sentry.addBreadcrumb("Limit Test", Integer.toString(i));
}
Sentry.captureMessage("8 breadcrumbs test.");

Sentry.addNavigationBreadcrumb("activity.main", "here", "there");
Sentry.addHttpBreadcrumb("http://example.com", "GET", 202);

Sentry.captureEvent(new Sentry.SentryEventBuilder()
.setMessage("OMG this works woooo")
.setMessage("This event has a message and a stacktrace.")
.setStackTrace(Thread.currentThread().getStackTrace())
);

Expand Down

0 comments on commit 7b96566

Please sign in to comment.