Skip to content

Commit fdb37c3

Browse files
authored
Add last breadcrumb id to native report attributes (#98)
1 parent 6999a11 commit fdb37c3

File tree

5 files changed

+89
-5
lines changed

5 files changed

+89
-5
lines changed

backtrace-library/src/androidTest/java/backtraceio/library/BacktraceClientBreadcrumbsTest.java

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,14 @@
11
package backtraceio.library;
22

3+
import static junit.framework.TestCase.assertTrue;
34
import static junit.framework.TestCase.fail;
45
import static org.junit.Assert.assertEquals;
56
import static org.junit.Assert.assertNotEquals;
67
import static org.junit.Assert.assertNotNull;
78
import static org.junit.Assert.assertNull;
89

910
import android.content.Context;
11+
1012
import androidx.test.platform.app.InstrumentationRegistry;
1113
import androidx.test.ext.junit.runners.AndroidJUnit4;
1214

@@ -30,6 +32,7 @@
3032
import backtraceio.library.breadcrumbs.BacktraceBreadcrumbs;
3133
import backtraceio.library.events.OnServerResponseEventListener;
3234
import backtraceio.library.events.RequestHandler;
35+
import backtraceio.library.interfaces.Breadcrumbs;
3336
import backtraceio.library.models.BacktraceData;
3437
import backtraceio.library.models.BacktraceResult;
3538
import backtraceio.library.models.types.BacktraceResultStatus;
@@ -308,6 +311,19 @@ public void onEvent(BacktraceResult backtraceResult) {
308311
}
309312
}
310313

314+
@Test
315+
public void verifyBreadcrumbCallbackInvocation() {
316+
backtraceClient.enableBreadcrumbs(context);
317+
Breadcrumbs breadcrumbs = backtraceClient.database.getBreadcrumbs();
318+
319+
breadcrumbs.setOnSuccessfulBreadcrumbAddEventListener(breadcrumbId -> {
320+
assertEquals(breadcrumbs.getCurrentBreadcrumbId(), breadcrumbId);
321+
return;
322+
});
323+
324+
breadcrumbs.addBreadcrumb("test");
325+
}
326+
311327
public List<String> readBreadcrumbLogFile() throws IOException {
312328
BacktraceBreadcrumbs breadcrumbs = new BacktraceBreadcrumbs(context.getFilesDir().getAbsolutePath());
313329
File breadcrumbLogFile = new File(breadcrumbs.getBreadcrumbLogPath());

backtrace-library/src/main/java/backtraceio/library/BacktraceDatabase.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -213,6 +213,12 @@ public Boolean setupNativeIntegration(BacktraceBase client, BacktraceCredentials
213213
enableClientSideUnwinding,
214214
unwindingMode
215215
);
216+
217+
if (initialized && this.breadcrumbs.isEnabled()) {
218+
this.breadcrumbs.setOnSuccessfulBreadcrumbAddEventListener(breadcrumbId -> {
219+
this.addAttribute("breadcrumbs.lastId", Long.toString((breadcrumbId)));
220+
});
221+
}
216222
return initialized;
217223
}
218224

backtrace-library/src/main/java/backtraceio/library/breadcrumbs/BacktraceBreadcrumbs.java

Lines changed: 29 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99

1010
import backtraceio.library.enums.BacktraceBreadcrumbLevel;
1111
import backtraceio.library.enums.BacktraceBreadcrumbType;
12+
import backtraceio.library.events.OnSuccessfulBreadcrumbAddEventListener;
1213
import backtraceio.library.interfaces.Breadcrumbs;
1314
import backtraceio.library.logger.BacktraceLogger;
1415
import backtraceio.library.models.json.BacktraceReport;
@@ -17,6 +18,11 @@ public class BacktraceBreadcrumbs implements Breadcrumbs {
1718

1819
private static final transient String LOG_TAG = BacktraceBreadcrumbs.class.getSimpleName();
1920

21+
/**
22+
* Event which will be executed after storing successfully breadcurmbs
23+
*/
24+
private OnSuccessfulBreadcrumbAddEventListener onSuccessfulBreadcrumbAddEventListener = null;
25+
2026
/**
2127
* Which breadcrumb types are enabled?
2228
*/
@@ -54,6 +60,15 @@ public BacktraceBreadcrumbs(String breadcrumbLogDirectory) {
5460
this.breadcrumbLogDirectory = breadcrumbLogDirectory;
5561
}
5662

63+
/**
64+
* Set event executed after adding a breadcrumb to the file
65+
*
66+
* @param eventListener object with method which will be executed
67+
*/
68+
public void setOnSuccessfulBreadcrumbAddEventListener(OnSuccessfulBreadcrumbAddEventListener eventListener) {
69+
this.onSuccessfulBreadcrumbAddEventListener = eventListener;
70+
}
71+
5772
private void unregisterAutomaticBreadcrumbReceivers() {
5873
// Unregister old receivers
5974
if (backtraceBroadcastReceiver != null) {
@@ -272,10 +287,15 @@ public boolean addBreadcrumb(String message, Map<String, Object> attributes, Bac
272287
*/
273288
@Override
274289
public boolean addBreadcrumb(String message, Map<String, Object> attributes, BacktraceBreadcrumbType type, BacktraceBreadcrumbLevel level) {
275-
if (this.isBreadcrumbsEnabled() && backtraceBreadcrumbsLogManager != null) {
276-
return backtraceBreadcrumbsLogManager.addBreadcrumb(message, attributes, type, level);
290+
if (!this.isEnabled() || backtraceBreadcrumbsLogManager == null) {
291+
return false;
292+
}
293+
boolean addResult = backtraceBreadcrumbsLogManager.addBreadcrumb(message, attributes, type, level);
294+
if (addResult && this.onSuccessfulBreadcrumbAddEventListener != null) {
295+
this.onSuccessfulBreadcrumbAddEventListener.onSuccessfulAdd(this.getCurrentBreadcrumbId());
277296
}
278-
return false;
297+
298+
return addResult;
279299
}
280300

281301
/**
@@ -285,7 +305,7 @@ public boolean addBreadcrumb(String message, Map<String, Object> attributes, Bac
285305
*/
286306
@Override
287307
public void processReportBreadcrumbs(BacktraceReport backtraceReport) {
288-
if (!this.isBreadcrumbsEnabled()) {
308+
if (!this.isEnabled()) {
289309
return;
290310
}
291311

@@ -325,7 +345,11 @@ private boolean addConfigurationBreadcrumb() {
325345
BacktraceBreadcrumbLevel.INFO);
326346
}
327347

328-
private boolean isBreadcrumbsEnabled() {
348+
/**
349+
* Determinate if Breadcrumbs are enabled.
350+
* @return true if breadcrumbs are enabled.
351+
*/
352+
public boolean isEnabled() {
329353
return enabledBreadcrumbTypes != null && !enabledBreadcrumbTypes.isEmpty();
330354
}
331355

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
package backtraceio.library.events;
2+
3+
/**
4+
* Interface definition for a callback to be invoked after successfully storing a new breadcrumb.
5+
*/
6+
public interface OnSuccessfulBreadcrumbAddEventListener {
7+
/**
8+
* Event which will be executed after successfully storing a new breadcrumb.
9+
*
10+
* @param breadcrumbId the new breadcrumb id.
11+
*/
12+
void onSuccessfulAdd(long breadcrumbId);
13+
}

backtrace-library/src/main/java/backtraceio/library/interfaces/Breadcrumbs.java

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77

88
import backtraceio.library.enums.BacktraceBreadcrumbLevel;
99
import backtraceio.library.enums.BacktraceBreadcrumbType;
10+
import backtraceio.library.events.OnSuccessfulBreadcrumbAddEventListener;
1011
import backtraceio.library.models.json.BacktraceReport;
1112

1213
public interface Breadcrumbs {
@@ -163,4 +164,28 @@ boolean enableBreadcrumbs(Context context,
163164
* @param breadcrumbId Will force set the current breadcrumb ID
164165
*/
165166
void setCurrentBreadcrumbId(long breadcrumbId);
167+
168+
/**
169+
* Get the current breadcrumb ID (exclusive). This is useful when breadcrumbs are queued and
170+
* posted to an API because in the meantime before the breadcrumbs are finally posted we might
171+
* get more breadcrumbs which are not relevant (because they occur after queueing up the
172+
* breadcrumb sender). Therefore it is useful to mark the breadcrumb sender with the most
173+
* current breadcrumb ID at the time of queuing up the request to post the breadcrumbs.
174+
*
175+
* @return current breadcrumb ID (exclusive)
176+
*/
177+
long getCurrentBreadcrumbId();
178+
179+
/**
180+
* Determinate if Breadcrumbs are enabled.
181+
* @return true if breadcrumbs are enabled.
182+
*/
183+
boolean isEnabled();
184+
185+
/**
186+
* Set event executed after adding a breadcrumb to the breadcrumb storage.
187+
*
188+
* @param eventListener object with method which will be executed.
189+
*/
190+
void setOnSuccessfulBreadcrumbAddEventListener(OnSuccessfulBreadcrumbAddEventListener eventListener);
166191
}

0 commit comments

Comments
 (0)