Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
e4e0491
feat(agent): handle additional args for newrelic_notice_error
hahuja2 Jul 18, 2024
addcdec
chore(axiom): add unit tests
hahuja2 Jul 18, 2024
b7fe442
chore(axiom): add integration tests
hahuja2 Jul 18, 2024
09648a4
chore(axiom): format function
hahuja2 Jul 18, 2024
449c525
chore(agent): remove unnecessary use of nr_strdup
hahuja2 Jul 24, 2024
a232371
chore(agent): add helper function for nr_error_create
hahuja2 Jul 24, 2024
382c5d9
chore(axiom): reduce code duplication
hahuja2 Jul 24, 2024
20b568b
chore(axiom): update description and remove option variable
hahuja2 Jul 24, 2024
3481c07
chore(axiom): remove unnecessary function
hahuja2 Jul 24, 2024
93d9f8b
Update axiom/tests/test_txn.c
hahuja2 Jul 26, 2024
08c4261
chore(axiom): add additional parameters as user attributes
hahuja2 Aug 15, 2024
2da5096
chore(agent): simplify if statement
hahuja2 Aug 16, 2024
524754d
chore(axiom): remove helper function and add if statements
hahuja2 Aug 21, 2024
2017e8e
chore(axiom): change usage of 0 to NULL
hahuja2 Aug 21, 2024
28b6f33
chore(axiom): remove if check
hahuja2 Aug 21, 2024
92b0d2d
chore(axiom): update comments
hahuja2 Aug 21, 2024
1ec5164
chore(axiom): remove helper function and add additional if statements
hahuja2 Aug 21, 2024
cbe1fa2
chore(axiom): fix duplication
hahuja2 Aug 21, 2024
604762c
chore(axiom): add comments
hahuja2 Aug 21, 2024
a7a519c
chore(axiom): allow NULL to be passed in as a parameter
hahuja2 Aug 21, 2024
9f44c72
chore(axiom): remove helper function and split up if statements
hahuja2 Aug 21, 2024
2c72637
chore(axiom): add description
hahuja2 Aug 21, 2024
8099059
chore(axiom): update unit tests
hahuja2 Aug 21, 2024
62afe8a
chore(axiom): update unit tests
hahuja2 Aug 21, 2024
785e83c
chore(axiom): modify unit tests
hahuja2 Aug 26, 2024
a47bf1d
chore(tests): add integration tests
hahuja2 Aug 26, 2024
8b6a0e3
chore(axiom): create nr_user_error_t struct
hahuja2 Sep 3, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
47 changes: 29 additions & 18 deletions agent/php_api.c
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
#include "php_hash.h"
#include "php_user_instrument.h"
#include "fw_drupal_common.h"
#include "nr_errors.h"
#include "nr_rum.h"
#include "util_logging.h"
#include "util_memory.h"
Expand Down Expand Up @@ -71,14 +72,17 @@ PHP_FUNCTION(newrelic_notice_error) {
const char* errclass = "NoticedError";
char* errormsgstr = NULL;
nr_string_len_t errormsglen = 0;
zend_long ignore1 = 0;
char* ignore2 = 0;
nr_string_len_t ignore3 = 0;
zend_long ignore4 = 0;
char* user_error_message = NULL;
nr_string_len_t user_error_message_len = 0;
zend_long user_error_number = 0;
char* user_error_file = NULL;
nr_string_len_t user_error_file_len = 0;
zend_long user_error_line = 0;
zval* exc = NULL;
zval* ignore5 = NULL;
nr_string_len_t user_error_context_len = 0;
char* user_error_context = NULL;
int priority = 0;
zval* ignore = NULL;
bool five_params = false;

NR_UNUSED_RETURN_VALUE;
NR_UNUSED_RETURN_VALUE_PTR;
Expand Down Expand Up @@ -132,24 +136,26 @@ PHP_FUNCTION(newrelic_notice_error) {
case 2:
if (FAILURE
== zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET,
ZEND_NUM_ARGS() TSRMLS_CC, "zo!", &ignore,
ZEND_NUM_ARGS() TSRMLS_CC, "s!o!", &user_error_message, &user_error_message_len,
&exc)) {
nrl_debug(NRL_API,
"newrelic_notice_error: invalid two arguments: expected "
"exception as second argument");
"string as first argument and exception as second argument");
RETURN_NULL();
}
break;

case 5:
if (FAILURE
== zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET,
ZEND_NUM_ARGS() TSRMLS_CC, "lsslz!",
&ignore1, &errormsgstr, &errormsglen,
&ignore2, &ignore3, &ignore4, &ignore5)) {
ZEND_NUM_ARGS() TSRMLS_CC, "ls!s!ls!",
&user_error_number, &user_error_message, &user_error_message_len,
&user_error_file, &user_error_file_len, &user_error_line,
&user_error_context, &user_error_context_len)) {
nrl_debug(NRL_API, "newrelic_notice_error: invalid five arguments");
RETURN_NULL();
}
five_params = true;
break;

default:
Expand All @@ -168,17 +174,22 @@ PHP_FUNCTION(newrelic_notice_error) {
}
}

{
char* buf = nr_strndup(errormsgstr, errormsglen);
if (five_params) {
nr_user_error_t* user_error = nr_user_error_create(
user_error_message, user_error_number, user_error_file, user_error_line,
user_error_context);
char* stack_json = nr_php_backtrace_to_json(NULL TSRMLS_CC);

nr_txn_record_error(NRPRG(txn), priority, true, buf, errclass, stack_json);

nr_free(buf);
nr_txn_record_error_with_additional_attributes(NRPRG(txn), priority, true,
user_error_message, errclass,
stack_json, user_error);
nr_free(stack_json);

RETURN_TRUE;
}
char* stack_json = nr_php_backtrace_to_json(NULL TSRMLS_CC);
nr_txn_record_error(NRPRG(txn), priority, true, errormsgstr, errclass,
stack_json);
nr_free(stack_json);
RETURN_TRUE;
}

/*
Expand Down
46 changes: 37 additions & 9 deletions axiom/nr_errors.c
Original file line number Diff line number Diff line change
Expand Up @@ -20,31 +20,58 @@ nr_error_t* nr_error_create(int priority,
const char* stacktrace_json,
const char* span_id,
nrtime_t when) {
nr_error_t* error;

if (0 == message) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why were these guards removed?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These were removed because these guards are being checked before this helper function is called. An example of this is in nr_error_create.

return 0;
}
if (0 == klass) {
if (NULL == message || NULL == klass || NULL == stacktrace_json) {
return 0;
}
if (0 == stacktrace_json) {
return nr_error_create_additional_params(priority, message, klass, NULL, stacktrace_json, span_id, when);
}

nr_error_t* nr_error_create_additional_params(int priority,
const char* message,
const char* klass,
nr_user_error_t* user_error,
const char* stacktrace_json,
const char* span_id,
nrtime_t when) {
nr_error_t* error;
if (NULL == klass || NULL == stacktrace_json) {
return 0;
}

error = (nr_error_t*)nr_zalloc(sizeof(nr_error_t));
error->priority = priority;
error->when = when;
error->message = nr_strdup(message);
error->klass = nr_strdup(klass);
error->stacktrace_json = nr_strdup(stacktrace_json);

error->user_error = user_error;
if (NULL != message) {
error->message = nr_strdup(message);
}
if (NULL != span_id) {
error->span_id = nr_strdup(span_id);
}
return error;
}

nr_user_error_t* nr_user_error_create(const char* user_error_message, int user_error_number, const char* user_error_file, int user_error_line, const char* user_error_context) {
nr_user_error_t* user_error = (nr_user_error_t*)nr_malloc(sizeof(nr_user_error_t));
user_error->user_error_message = nr_strdup(user_error_message);
user_error->user_error_number = user_error_number;
user_error->user_error_file = nr_strdup(user_error_file);
user_error->user_error_line = user_error_line;
user_error->user_error_context = nr_strdup(user_error_context);
return user_error;
}

void nr_user_error_destroy(nr_user_error_t* user_error) {
if (NULL != user_error) {
nr_free(user_error->user_error_message);
nr_free(user_error->user_error_file);
nr_free(user_error->user_error_context);
nr_free(user_error);
}
}

const char* nr_error_get_message(const nr_error_t* error) {
if (NULL == error) {
return NULL;
Expand Down Expand Up @@ -94,6 +121,7 @@ void nr_error_destroy(nr_error_t** error_ptr) {
nr_free(error->klass);
nr_free(error->span_id);
nr_free(error->stacktrace_json);
nr_user_error_destroy(error->user_error);
nr_realfree((void**)error_ptr);
}

Expand Down
58 changes: 53 additions & 5 deletions axiom/nr_errors.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,14 @@
*/
typedef struct _nr_error_t nr_error_t;

typedef struct _nr_user_error_t {
char* user_error_message; /* User error message */
char* user_error_file; /* User error file */
char* user_error_context; /* User error context */
int user_error_line; /* User error line */
int user_error_number; /* User error number */
} nr_user_error_t;

/*
* Purpose : Create a new error.
*
Expand All @@ -38,40 +46,80 @@ extern nr_error_t* nr_error_create(int priority,
const char* span_id,
nrtime_t when);

extern void nr_user_error_destroy(nr_user_error_t* user_error_ptr);

extern nr_user_error_t* nr_user_error_create(const char* user_error_message,
int user_error_number,
const char* user_error_file,
int user_error_line,
const char* user_error_context);

/*
* Purpose : Create a new error for the use case where additional parameters are
* passed in. The following parameters are required and can not be NULL: klass
* and stacktrace_json. If these are NULL, the function will return 0. The
* remaining parameters can be passed in as NULL if they are not needed.
*
* Params : 1. The importance of the error. Higher number is more important.
* 2. Message string.
* 3. Class string. This string is used to aggregate errors in RPM.
* RPM does not expect strings from a specific namespace.
* The PHP agent uses PHP's predefined error constant names.
* Examples are "E_ERROR" and "E_WARNING".
* 4. Error file provided by user.
* 5. Error line provided by user.
* 6. Error context provided by user.
* 7. Error number provided by user.
* 8. String containing stack trace in JSON format.
* 9. Span ID
* 10. When the error occurred.
*
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would be good to explain if all are required or if there are certain combinations allowed.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added: 9fad7fa

* Returns : A newly allocated error, or 0 on failure.
*/
extern nr_error_t* nr_error_create_additional_params(
int priority,
const char* message,
const char* klass,
nr_user_error_t* user_error,
const char* stacktrace_json,
const char* span_id,
nrtime_t when);

/*
* Purpose : Retrieve error fields for the purpose of creating attributes.
*/

/*
* Purpose : Get the message of an error.
*
* Returns : The message of the error or NULL on failure.
* Returns : The message of the error or NULL if not defined.
*/
extern const char* nr_error_get_message(const nr_error_t* error);
/*
* Purpose : Get the klass of an error.
*
* Returns : The klass of the error or NULL on failure.
* Returns : The klass of the error or NULL if not defined.
*/
extern const char* nr_error_get_klass(const nr_error_t* error);

/*
* Purpose : Get the span_id of an error.
*
* Returns : The span_id of the error or NULL on failure.
* Returns : The span_id of the error or NULL if not defined.
*/
extern const char* nr_error_get_span_id(const nr_error_t* error);

/*
* Purpose : Get the time of an error.
*
* Returns : The time of the error or 0 on failure.
* Returns : The time of the error or 0 if not defined.
*/
extern nrtime_t nr_error_get_time(const nr_error_t* error);

/*
* Purpose : Get the priority of an error.
*
* Returns : The priority of the error or 0 on failure.
* Returns : The priority of the error or 0 if not defined.
*/
extern int nr_error_priority(const nr_error_t* error);

Expand Down
1 change: 1 addition & 0 deletions axiom/nr_errors_private.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ struct _nr_error_t {
char* stacktrace_json; /* Stack trace in JSON format */
char* span_id; /* ID of the current executing span at the time the error
occurred */
nr_user_error_t* user_error;
};

#endif /* NR_ERRORS_PRIVATE_HDR */
17 changes: 15 additions & 2 deletions axiom/nr_segment.c
Original file line number Diff line number Diff line change
Expand Up @@ -1176,17 +1176,30 @@ void nr_segment_set_error(nr_segment_t* segment,
if ((NULL == segment) || (NULL == error_message && NULL == error_class)) {
return;
}
nr_segment_set_error_with_additional_params(segment, error_message, error_class, NULL);
}

void nr_segment_set_error_with_additional_params(nr_segment_t* segment,
const char* error_message,
const char* error_class,
nr_user_error_t* user_error) {
if (NULL == segment || NULL == error_class) {
return;
}

if (NULL == segment->error) {
segment->error = nr_zalloc(sizeof(nr_segment_error_t));
}

nr_free(segment->error->error_message);
nr_free(segment->error->error_class);
nr_free(segment->error->user_error);

segment->error->error_message
= error_message ? nr_strdup(error_message) : NULL;
if (NULL != error_message) {
segment->error->error_message = error_message ? nr_strdup(error_message) : NULL;
}
segment->error->error_class = error_class ? nr_strdup(error_class) : NULL;
segment->error->user_error = user_error;
}

bool nr_segment_attributes_user_add(nr_segment_t* segment,
Expand Down
18 changes: 18 additions & 0 deletions axiom/nr_segment.h
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,7 @@ typedef struct _nr_segment_metric_t {
typedef struct _nr_segment_error_t {
char* error_message; /* The error message that will appear on a span event. */
char* error_class; /* The error class that will appear on a span event. */
nr_user_error_t* user_error; /* The user error that will appear on a span event.*/
} nr_segment_error_t;

/*
Expand Down Expand Up @@ -649,6 +650,23 @@ extern void nr_segment_record_exception(nr_segment_t* segment,
const char* error_message,
const char* error_class);

/*
* Purpose : Set the error attributes on a segment.
*
* Params : 1. The pointer to the segment.
* 2. The error message that will be added.
* 3. The error class that will be added.
* 4. The error file that will be added.
* 5. The error line that will be added.
* 6. The error context that will be added.
* 7. The error number that will be added.
*/
extern void nr_segment_set_error_with_additional_params(
nr_segment_t* segment,
const char* error_message,
const char* error_class,
nr_user_error_t* user_error);

/*
* Purpose : Gets the child_ix of a segment.
*
Expand Down
2 changes: 2 additions & 0 deletions axiom/nr_segment_private.c
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@

#include "nr_axiom.h"

#include "nr_errors.h"
#include "nr_segment_private.h"
#include "nr_segment.h"
#include "nr_txn.h"
Expand Down Expand Up @@ -87,5 +88,6 @@ void nr_segment_error_destroy_fields(nr_segment_error_t* segment_error) {

nr_free(segment_error->error_message);
nr_free(segment_error->error_class);
nr_user_error_destroy(segment_error->user_error);
nr_free(segment_error);
}
Loading
Loading