Skip to content

Commit 54cede9

Browse files
authored
feat: Add support for capturing events with local scopes (#1248)
* wip: local scopes * merge breadcrumbs * add sentry_scope_set_trace * add sentry_scope_set_fingerprints() * check fingerprints value type * document sentry_scope_set_fingerprints() expected type * Revert sentry_scope_set_trace/transaction > Transactions/spans do not make sense in this setup since they aren't > cloned and cannot be retrieved to create children. * sentry_malloc -> SENTRY_MAKE * fix comparing null timestamps when merging breadcrumbs * take ownership * update example * partial revert of unit test changes in a48fea don't assume any specific order for breadcrumbs with missing breadcrumbs * warn once if any breadcrumbs were missing timestamps * error handling for sentry_value_append()
1 parent 31a8ee3 commit 54cede9

File tree

14 files changed

+1008
-133
lines changed

14 files changed

+1008
-133
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
**Features**:
1111

1212
- Provide `before_send_transaction` callback. ([#1236](https://github.com/getsentry/sentry-native/pull/1236))
13+
- Add support for capturing events with local scopes. ([#1248](https://github.com/getsentry/sentry-native/pull/1248))
1314

1415
**Fixes**:
1516

CONTRIBUTING.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -184,6 +184,7 @@ The example currently supports the following commands:
184184
- `attach-view-hierarchy`: Adds a `view-hierarchy.json` attachment file, giving it the proper `attachment_type` and `content_type`.
185185
This file can be found in `./tests/fixtures/view-hierachy.json`.
186186
- `set-trace`: Sets the scope `propagation_context`'s trace data to the given `trace_id="aaaabbbbccccddddeeeeffff00001111"` and `parent_span_id=""f0f0f0f0f0f0f0f0"`.
187+
- `capture-with-scope`: Captures an event with a local scope.
187188

188189
Only on Linux using crashpad:
189190
- `crashpad-wait-for-upload`: Couples application shutdown to complete the upload in the `crashpad_handler`.

examples/example.c

Lines changed: 41 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -220,6 +220,30 @@ trigger_stack_overflow()
220220
trigger_stack_overflow();
221221
}
222222

223+
static sentry_value_t
224+
create_debug_crumb(const char *message)
225+
{
226+
sentry_value_t debug_crumb = sentry_value_new_breadcrumb("http", message);
227+
sentry_value_set_by_key(
228+
debug_crumb, "category", sentry_value_new_string("example!"));
229+
sentry_value_set_by_key(
230+
debug_crumb, "level", sentry_value_new_string("debug"));
231+
232+
// extend the `http` crumb with (optional) data properties as documented
233+
// here:
234+
// https://develop.sentry.dev/sdk/event-payloads/breadcrumbs/#breadcrumb-types
235+
sentry_value_t http_data = sentry_value_new_object();
236+
sentry_value_set_by_key(http_data, "url",
237+
sentry_value_new_string("https://example.com/api/1.0/users"));
238+
sentry_value_set_by_key(
239+
http_data, "method", sentry_value_new_string("GET"));
240+
sentry_value_set_by_key(
241+
http_data, "status_code", sentry_value_new_int32(200));
242+
sentry_value_set_by_key(http_data, "reason", sentry_value_new_string("OK"));
243+
sentry_value_set_by_key(debug_crumb, "data", http_data);
244+
return debug_crumb;
245+
}
246+
223247
int
224248
main(int argc, char **argv)
225249
{
@@ -359,27 +383,7 @@ main(int argc, char **argv)
359383
= sentry_value_new_breadcrumb(NULL, "default level is info");
360384
sentry_add_breadcrumb(default_crumb);
361385

362-
sentry_value_t debug_crumb
363-
= sentry_value_new_breadcrumb("http", "debug crumb");
364-
sentry_value_set_by_key(
365-
debug_crumb, "category", sentry_value_new_string("example!"));
366-
sentry_value_set_by_key(
367-
debug_crumb, "level", sentry_value_new_string("debug"));
368-
369-
// extend the `http` crumb with (optional) data properties as documented
370-
// here:
371-
// https://develop.sentry.dev/sdk/event-payloads/breadcrumbs/#breadcrumb-types
372-
sentry_value_t http_data = sentry_value_new_object();
373-
sentry_value_set_by_key(http_data, "url",
374-
sentry_value_new_string("https://example.com/api/1.0/users"));
375-
sentry_value_set_by_key(
376-
http_data, "method", sentry_value_new_string("GET"));
377-
sentry_value_set_by_key(
378-
http_data, "status_code", sentry_value_new_int32(200));
379-
sentry_value_set_by_key(
380-
http_data, "reason", sentry_value_new_string("OK"));
381-
sentry_value_set_by_key(debug_crumb, "data", http_data);
382-
386+
sentry_value_t debug_crumb = create_debug_crumb("debug crumb");
383387
sentry_add_breadcrumb(debug_crumb);
384388

385389
sentry_value_t nl_crumb
@@ -407,6 +411,22 @@ main(int argc, char **argv)
407411
}
408412
}
409413

414+
if (has_arg(argc, argv, "capture-with-scope")) {
415+
sentry_scope_t *scope = sentry_local_scope_new();
416+
417+
sentry_value_t event = sentry_value_new_message_event(
418+
SENTRY_LEVEL_INFO, NULL, "Hello Scope!");
419+
420+
sentry_value_t default_crumb
421+
= sentry_value_new_breadcrumb(NULL, "default level is info");
422+
sentry_scope_add_breadcrumb(scope, default_crumb);
423+
424+
sentry_value_t debug_crumb = create_debug_crumb("scoped crumb");
425+
sentry_scope_add_breadcrumb(scope, debug_crumb);
426+
427+
sentry_capture_event_with_scope(event, scope);
428+
}
429+
410430
if (has_arg(argc, argv, "capture-multiple")) {
411431
for (size_t i = 0; i < 10; i++) {
412432
char buffer[10];

include/sentry.h

Lines changed: 52 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1402,7 +1402,7 @@ SENTRY_API uint64_t sentry_options_get_shutdown_timeout(sentry_options_t *opts);
14021402
SENTRY_API void sentry_options_set_backend(
14031403
sentry_options_t *opts, sentry_backend_t *backend);
14041404

1405-
/* -- Global APIs -- */
1405+
/* -- Global/Scope APIs -- */
14061406

14071407
/**
14081408
* Initializes the Sentry SDK with the specified options.
@@ -1502,6 +1502,19 @@ SENTRY_API void sentry_user_consent_reset(void);
15021502
*/
15031503
SENTRY_API sentry_user_consent_t sentry_user_consent_get(void);
15041504

1505+
/**
1506+
* A sentry Scope.
1507+
*
1508+
* See https://develop.sentry.dev/sdk/telemetry/scopes/
1509+
*/
1510+
struct sentry_scope_s;
1511+
typedef struct sentry_scope_s sentry_scope_t;
1512+
1513+
/**
1514+
* Creates a local scope.
1515+
*/
1516+
SENTRY_API sentry_scope_t *sentry_local_scope_new(void);
1517+
15051518
/**
15061519
* Sends a sentry event.
15071520
*
@@ -1511,6 +1524,14 @@ SENTRY_API sentry_user_consent_t sentry_user_consent_get(void);
15111524
*/
15121525
SENTRY_API sentry_uuid_t sentry_capture_event(sentry_value_t event);
15131526

1527+
/**
1528+
* Sends a sentry event with a local scope.
1529+
*
1530+
* Takes ownership of `scope`.
1531+
*/
1532+
SENTRY_API sentry_uuid_t sentry_capture_event_with_scope(
1533+
sentry_value_t event, sentry_scope_t *scope);
1534+
15141535
/**
15151536
* Allows capturing independently created minidumps.
15161537
*
@@ -1555,11 +1576,15 @@ SENTRY_EXPERIMENTAL_API void sentry_handle_exception(
15551576
* Adds the breadcrumb to be sent in case of an event.
15561577
*/
15571578
SENTRY_API void sentry_add_breadcrumb(sentry_value_t breadcrumb);
1579+
SENTRY_API void sentry_scope_add_breadcrumb(
1580+
sentry_scope_t *scope, sentry_value_t breadcrumb);
15581581

15591582
/**
15601583
* Sets the specified user.
15611584
*/
15621585
SENTRY_API void sentry_set_user(sentry_value_t user);
1586+
SENTRY_API void sentry_scope_set_user(
1587+
sentry_scope_t *scope, sentry_value_t user);
15631588

15641589
/**
15651590
* Removes a user.
@@ -1572,6 +1597,10 @@ SENTRY_API void sentry_remove_user(void);
15721597
SENTRY_API void sentry_set_tag(const char *key, const char *value);
15731598
SENTRY_API void sentry_set_tag_n(
15741599
const char *key, size_t key_len, const char *value, size_t value_len);
1600+
SENTRY_API void sentry_scope_set_tag(
1601+
sentry_scope_t *scope, const char *key, const char *value);
1602+
SENTRY_API void sentry_scope_set_tag_n(sentry_scope_t *scope, const char *key,
1603+
size_t key_len, const char *value, size_t value_len);
15751604

15761605
/**
15771606
* Removes the tag with the specified key.
@@ -1585,6 +1614,10 @@ SENTRY_API void sentry_remove_tag_n(const char *key, size_t key_len);
15851614
SENTRY_API void sentry_set_extra(const char *key, sentry_value_t value);
15861615
SENTRY_API void sentry_set_extra_n(
15871616
const char *key, size_t key_len, sentry_value_t value);
1617+
SENTRY_API void sentry_scope_set_extra(
1618+
sentry_scope_t *scope, const char *key, sentry_value_t value);
1619+
SENTRY_API void sentry_scope_set_extra_n(sentry_scope_t *scope, const char *key,
1620+
size_t key_len, sentry_value_t value);
15881621

15891622
/**
15901623
* Removes the extra with the specified key.
@@ -1598,6 +1631,10 @@ SENTRY_API void sentry_remove_extra_n(const char *key, size_t key_len);
15981631
SENTRY_API void sentry_set_context(const char *key, sentry_value_t value);
15991632
SENTRY_API void sentry_set_context_n(
16001633
const char *key, size_t key_len, sentry_value_t value);
1634+
SENTRY_API void sentry_scope_set_context(
1635+
sentry_scope_t *scope, const char *key, sentry_value_t value);
1636+
SENTRY_API void sentry_scope_set_context_n(sentry_scope_t *scope,
1637+
const char *key, size_t key_len, sentry_value_t value);
16011638

16021639
/**
16031640
* Removes the context object with the specified key.
@@ -1614,6 +1651,18 @@ SENTRY_API void sentry_remove_context_n(const char *key, size_t key_len);
16141651
SENTRY_API void sentry_set_fingerprint(const char *fingerprint, ...);
16151652
SENTRY_API void sentry_set_fingerprint_n(
16161653
const char *fingerprint, size_t fingerprint_len, ...);
1654+
SENTRY_API void sentry_scope_set_fingerprint(
1655+
sentry_scope_t *scope, const char *fingerprint, ...);
1656+
SENTRY_API void sentry_scope_set_fingerprint_n(sentry_scope_t *scope,
1657+
const char *fingerprint, size_t fingerprint_len, ...);
1658+
1659+
/**
1660+
* Sets the event fingerprints.
1661+
*
1662+
* This accepts a list of fingerprints created with `sentry_value_new_list`.
1663+
*/
1664+
SENTRY_API void sentry_scope_set_fingerprints(
1665+
sentry_scope_t *scope, sentry_value_t fingerprints);
16171666

16181667
/**
16191668
* Removes the fingerprint.
@@ -1640,6 +1689,8 @@ SENTRY_API void sentry_set_transaction_n(
16401689
* Sets the event level.
16411690
*/
16421691
SENTRY_API void sentry_set_level(sentry_level_t level);
1692+
SENTRY_API void sentry_scope_set_level(
1693+
sentry_scope_t *scope, sentry_level_t level);
16431694

16441695
/**
16451696
* Sets the maximum number of spans that can be attached to a

src/backends/sentry_backend_breakpad.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -143,7 +143,7 @@ breakpad_backend_callback(const google_breakpad::MinidumpDescriptor &descriptor,
143143

144144
if (should_handle) {
145145
sentry_envelope_t *envelope = sentry__prepare_event(
146-
options, event, nullptr, !options->on_crash_func);
146+
options, event, nullptr, !options->on_crash_func, NULL);
147147
sentry_session_t *session = sentry__end_current_session_with_status(
148148
SENTRY_SESSION_STATUS_CRASHED);
149149
sentry__envelope_add_session(envelope, session);

src/backends/sentry_backend_inproc.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -589,7 +589,7 @@ handle_ucontext(const sentry_ucontext_t *uctx)
589589

590590
if (should_handle) {
591591
sentry_envelope_t *envelope = sentry__prepare_event(
592-
options, event, NULL, !options->on_crash_func);
592+
options, event, NULL, !options->on_crash_func, NULL);
593593
// TODO(tracing): Revisit when investigating transaction flushing
594594
// during hard crashes.
595595

0 commit comments

Comments
 (0)