Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(tracing): Allow setting custom span status [NATIVE-441] #648

Merged
merged 12 commits into from
Jan 13, 2022
21 changes: 16 additions & 5 deletions examples/example.c
Original file line number Diff line number Diff line change
Expand Up @@ -229,14 +229,25 @@ main(int argc, char **argv)
}
sentry_transaction_t *tx = sentry_transaction_start(tx_ctx);

if (has_arg(argc, argv, "error-status")) {
sentry_transaction_set_status(
tx, SENTRY_SPAN_STATUS_INTERNAL_ERROR);
}

if (has_arg(argc, argv, "child-spans")) {
sentry_span_t *child_ctx
sentry_span_t *child
= sentry_transaction_start_child(tx, "littler.teapot", NULL);
sentry_span_t *grandchild_ctx
= sentry_span_start_child(child_ctx, "littlest.teapot", NULL);
sentry_span_t *grandchild
= sentry_span_start_child(child, "littlest.teapot", NULL);

if (has_arg(argc, argv, "error-status")) {
sentry_span_set_status(child, SENTRY_SPAN_STATUS_NOT_FOUND);
sentry_span_set_status(
grandchild, SENTRY_SPAN_STATUS_ALREADY_EXISTS);
}

sentry_span_finish(tx, grandchild_ctx);
sentry_span_finish(tx, child_ctx);
sentry_span_finish(tx, grandchild);
sentry_span_finish(tx, child);
}

sentry_transaction_finish(tx);
Expand Down
70 changes: 70 additions & 0 deletions include/sentry.h
Original file line number Diff line number Diff line change
Expand Up @@ -1483,6 +1483,76 @@ SENTRY_EXPERIMENTAL_API void sentry_span_remove_data(
SENTRY_EXPERIMENTAL_API void sentry_transaction_set_name(
sentry_transaction_t *transaction, const char *name);

/**
* The status of a span or transaction.
*
* See https://develop.sentry.dev/sdk/event-payloads/span/ for documentation.
*/
typedef enum {
// The operation completed successfully.
// HTTP status 100..299 + successful redirects from the 3xx range.
SENTRY_SPAN_STATUS_OK,
// The operation was cancelled (typically by the user).
SENTRY_SPAN_STATUS_CANCELLED,
// Unknown. Any non-standard HTTP status code.
// "We do not know whether the transaction failed or succeeded."
SENTRY_SPAN_STATUS_UNKNOWN,
// Client specified an invalid argument. 4xx.
// Note that this differs from FailedPrecondition. InvalidArgument
// indicates arguments that are problematic regardless of the
// state of the system.
SENTRY_SPAN_STATUS_INVALID_ARGUMENT,
// Deadline expired before operation could complete.
// For operations that change the state of the system, this error may be
// returned even if the operation has been completed successfully.
// HTTP redirect loops and 504 Gateway Timeout.
SENTRY_SPAN_STATUS_DEADLINE_EXCEEDED,
// 404 Not Found. Some requested entity (file or directory) was not found.
SENTRY_SPAN_STATUS_NOT_FOUND,
// Already exists (409)
// Some entity that we attempted to create already exists.
SENTRY_SPAN_STATUS_ALREADY_EXISTS,
// 403 Forbidden
// The caller does not have permission to execute the specified operation.
SENTRY_SPAN_STATUS_PERMISSION_DENIED,
// 429 Too Many Requests
// Some resource has been exhausted, perhaps a per-user quota or perhaps
// the entire file system is out of space.
SENTRY_SPAN_STATUS_RESOURCE_EXHAUSTED,
// Operation was rejected because the system is not in a state required for
// the operation's execution.
SENTRY_SPAN_STATUS_FAILED_PRECONDITION,
// The operation was aborted, typically due to a concurrency issue.
SENTRY_SPAN_STATUS_ABORTED,
// Operation was attempted past the valid range.
SENTRY_SPAN_STATUS_OUT_OF_RANGE,
// 501 Not Implemented
// Operation is not implemented or not enabled.
SENTRY_SPAN_STATUS_UNIMPLEMENTED,
// Other/generic 5xx
SENTRY_SPAN_STATUS_INTERNAL_ERROR,
// 503 Service Unavailable
SENTRY_SPAN_STATUS_UNAVAILABLE,
// Unrecoverable data loss or corruption
SENTRY_SPAN_STATUS_DATA_LOSS,
// 401 Unauthorized (actually does mean unauthenticated according to RFC
// 7235)
// Prefer PermissionDenied if a user is logged in.
SENTRY_SPAN_STATUS_UNAUTHENTICATED,
} sentry_span_status_t;

/**
* Sets a span's status.
*/
SENTRY_EXPERIMENTAL_API void sentry_span_set_status(
sentry_span_t *span, sentry_span_status_t status);

/**
* Sets a transaction's status.
*/
SENTRY_EXPERIMENTAL_API void sentry_transaction_set_status(
sentry_transaction_t *tx, sentry_span_status_t status);

#endif

#ifdef __cplusplus
Expand Down
2 changes: 1 addition & 1 deletion src/sentry_core.c
Original file line number Diff line number Diff line change
Expand Up @@ -714,7 +714,7 @@ sentry_set_transaction(const char *transaction)
scope->transaction = sentry__string_clone(transaction);

#ifdef SENTRY_PERFORMANCE_MONITORING
if (!sentry_value_is_null(scope->span)) {
if (scope->span) {
sentry_transaction_set_name(scope->span, transaction);
}
#endif
Expand Down
62 changes: 62 additions & 0 deletions src/sentry_tracing.c
Original file line number Diff line number Diff line change
Expand Up @@ -369,3 +369,65 @@ sentry_span_remove_data(sentry_span_t *span, const char *key)
{
remove_data(span->inner, key);
}

sentry_value_t
sentry_status_to_string(sentry_span_status_t status)
{
switch (status) {
case SENTRY_SPAN_STATUS_OK:
return sentry_value_new_string("ok");
case SENTRY_SPAN_STATUS_CANCELLED:
return sentry_value_new_string("cancelled");
case SENTRY_SPAN_STATUS_UNKNOWN:
return sentry_value_new_string("unknown");
case SENTRY_SPAN_STATUS_INVALID_ARGUMENT:
return sentry_value_new_string("invalid_argument");
case SENTRY_SPAN_STATUS_DEADLINE_EXCEEDED:
return sentry_value_new_string("deadline_exceeded");
case SENTRY_SPAN_STATUS_NOT_FOUND:
return sentry_value_new_string("not_found");
case SENTRY_SPAN_STATUS_ALREADY_EXISTS:
return sentry_value_new_string("already_exists");
case SENTRY_SPAN_STATUS_PERMISSION_DENIED:
return sentry_value_new_string("permission_denied");
case SENTRY_SPAN_STATUS_RESOURCE_EXHAUSTED:
return sentry_value_new_string("resource_exhausted");
case SENTRY_SPAN_STATUS_FAILED_PRECONDITION:
return sentry_value_new_string("failed_precondition");
case SENTRY_SPAN_STATUS_ABORTED:
return sentry_value_new_string("aborted");
case SENTRY_SPAN_STATUS_OUT_OF_RANGE:
return sentry_value_new_string("out_of_range");
case SENTRY_SPAN_STATUS_UNIMPLEMENTED:
return sentry_value_new_string("unimplemented");
case SENTRY_SPAN_STATUS_INTERNAL_ERROR:
return sentry_value_new_string("internal_error");
case SENTRY_SPAN_STATUS_UNAVAILABLE:
return sentry_value_new_string("unavailable");
case SENTRY_SPAN_STATUS_DATA_LOSS:
return sentry_value_new_string("data_loss");
case SENTRY_SPAN_STATUS_UNAUTHENTICATED:
return sentry_value_new_string("unauthenticated");
default:
return sentry_value_new_null();
}
}

void
set_status(sentry_value_t item, sentry_span_status_t status)
{
sentry_value_set_by_key(item, "status", sentry_status_to_string(status));
}

void
sentry_span_set_status(sentry_span_t *span, sentry_span_status_t status)
{
set_status(span->inner, status);
}

void
sentry_transaction_set_status(
sentry_transaction_t *tx, sentry_span_status_t status)
{
set_status(tx->inner, status);
}