From 976dfd3462d5c67240c69e7ac755c3f3226cfeb4 Mon Sep 17 00:00:00 2001 From: Guilherme Souza <19gui94@gmail.com> Date: Wed, 15 Apr 2020 23:44:24 +0200 Subject: [PATCH] Implement newrelic_notice_error_with_stacktrace Similar to newrelic_notice_error, but takes the stacktrace as a parameter instead of generating it. --- include/error.h | 34 ++++++++++++++++++++++++++++++++++ include/libnewrelic.h | 22 ++++++++++++++++++++++ src/error.c | 40 +++++++++++++++++++++++++++++++++------- 3 files changed, 89 insertions(+), 7 deletions(-) create mode 100644 include/error.h diff --git a/include/error.h b/include/error.h new file mode 100644 index 00000000..25f03507 --- /dev/null +++ b/include/error.h @@ -0,0 +1,34 @@ +/*! + * @file error.h + * + * @brief Function declarations necessary to support noticing errors. + */ +#ifndef LIBNEWRELIC_ERROR_H +#define LIBNEWRELIC_ERROR_H + +#include "libnewrelic.h" + +/** + * @brief Record an error in a transaction, optionally passing a custom stacktrace + * + * Given an active transaction, this function records an error + * inside of the transaction. A custom stacktrace can be passed as a string + * in JSON format like: "[\"first line\",\"second line\",\"third line\"]". + * Otherwise, if NULL is given, a stacktrace will be generated (if configured to do so). + * + * @param [in] transaction An active transaction. + * @param [in] priority The error's priority. The C SDK sends up one error per + * transaction. If multiple calls to this function are made during + * a single transaction, the error with the highest priority is + * reported to New Relic. + * @param [in] errmsg A string comprising the error message. + * @param [in] errclass A string comprising the error class. + * @param [in] errstacktrace A string comprising the error stacktrace, in NewRelic's JSON format, or NULL + */ +void newrelic_do_notice_error(newrelic_txn_t* transaction, + int priority, + const char* errmsg, + const char* errclass, + const char* errstacktrace); + +#endif /* LIBNEWRELIC_ERROR_H */ diff --git a/include/libnewrelic.h b/include/libnewrelic.h index 80897469..9a01584e 100644 --- a/include/libnewrelic.h +++ b/include/libnewrelic.h @@ -824,6 +824,28 @@ void newrelic_notice_error(newrelic_txn_t* transaction, const char* errmsg, const char* errclass); +/** + * @brief Record an error in a transaction, passing a custom stacktrace + * + * Given an active transaction, this function records an error + * inside of the transaction. A custom stacktrace must be passed as a string + * in JSON format like: "[\"first line\",\"second line\",\"third line\"]" + * + * @param [in] transaction An active transaction. + * @param [in] priority The error's priority. The C SDK sends up one error per + * transaction. If multiple calls to this function are made during + * a single transaction, the error with the highest priority is + * reported to New Relic. + * @param [in] errmsg A string comprising the error message. + * @param [in] errclass A string comprising the error class. + * @param [in] errstacktrace A string comprising the error stacktrace, in NewRelic's JSON format. + */ +void newrelic_notice_error_with_stacktrace(newrelic_txn_t* transaction, + int priority, + const char* errmsg, + const char* errclass, + const char* errstacktrace); + /** * @brief A segment within a transaction. * diff --git a/src/error.c b/src/error.c index f5965844..d17acc79 100644 --- a/src/error.c +++ b/src/error.c @@ -1,3 +1,5 @@ +#include "error.h" + #include "libnewrelic.h" #include "stack.h" #include "transaction.h" @@ -10,6 +12,27 @@ void newrelic_notice_error(newrelic_txn_t* transaction, int priority, const char* errmsg, const char* errclass) { + newrelic_do_notice_error(transaction, priority, errmsg, errclass, NULL); +} + +void newrelic_notice_error_with_stacktrace(newrelic_txn_t* transaction, + int priority, + const char* errmsg, + const char* errclass, + const char* errstacktrace) { + if (NULL == errstacktrace) { + nrl_error(NRL_INSTRUMENT, "unable to add NULL/empty error stacktrace to transaction"); + return; + } + + newrelic_do_notice_error(transaction, priority, errmsg, errclass, errstacktrace); +} + +void newrelic_do_notice_error(newrelic_txn_t* transaction, + int priority, + const char* errmsg, + const char* errclass, + const char* errstacktrace) { if (NULL == transaction) { nrl_error(NRL_INSTRUMENT, "unable to add error to NULL transaction"); return; @@ -29,8 +52,6 @@ void newrelic_notice_error(newrelic_txn_t* transaction, nrt_mutex_lock(&transaction->lock); { - char* stacktrace_json; - if (0 == transaction->txn->options.err_enabled) { nrl_error(NRL_INSTRUMENT, "unable to add error to transaction when errors are disabled"); @@ -56,11 +77,16 @@ void newrelic_notice_error(newrelic_txn_t* transaction, goto end; } - stacktrace_json = newrelic_get_stack_trace_as_json(); - nr_txn_record_error(transaction->txn, priority, errmsg, errclass, - stacktrace_json); - nr_free(stacktrace_json); + if (NULL == errstacktrace) { + char* stacktrace_json = newrelic_get_stack_trace_as_json(); + nr_txn_record_error(transaction->txn, priority, errmsg, errclass, + stacktrace_json); + nr_free(stacktrace_json); + } else { + nr_txn_record_error(transaction->txn, priority, errmsg, errclass, + errstacktrace); + } } end: nrt_mutex_unlock(&transaction->lock); -} +} \ No newline at end of file