Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
92 changes: 63 additions & 29 deletions sentry.c
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,7 @@ static zend_string *sentry_str_end_time;
static zend_string *sentry_str_duration;
static zend_string *sentry_str_metadata;
static zend_string *sentry_str_exception;
static zend_string *sentry_str_attributes;

static bool sentry_array_is_list(const zend_array *array) {
#if PHP_VERSION_ID >= 80100
Expand Down Expand Up @@ -247,7 +248,7 @@ static void sentry_clear_pending_exception(void) {

static bool sentry_is_attribute_arg(zend_string *name, zval *value) {
return name != NULL
&& zend_string_equals_literal(name, "attributes")
&& zend_string_equals(name, sentry_str_attributes)
&& Z_TYPE_P(value) == IS_ARRAY;
}

Expand Down Expand Up @@ -554,17 +555,51 @@ static zend_string *sentry_build_key(zend_string *class_name, zend_string *funct
return sentry_join_class_function(class_name, function_name, /* lowercase */ true);
}

static void sentry_set_processing_callback(
zval *target,
zval *argument,
const char *argument_name,
zend_string *class_name,
zend_string *function_name
) {
if (argument == NULL || Z_TYPE_P(argument) == IS_NULL) {
return;
}

if (!zend_is_callable(argument, 0, NULL)) {
zend_string *display_name = sentry_build_display_name(class_name, function_name);
sentry_emit_logf(
SENTRY_LOG_WARNING,
"Sentry instrumentation argument \"%s\" for '%s' is not a valid callback and was ignored.",
argument_name,
ZSTR_VAL(display_name)
);
zend_string_release(display_name);
return;
}

ZVAL_COPY(target, argument);
}

ZEND_FUNCTION(Sentry_instrument) {
zend_string *class_name = NULL;
zend_string *function_name;

zval *preprocessing_arg = NULL;
zval *postprocessing_arg = NULL;
zval *attributes_arg = NULL;

zval *metadata_args = NULL;
uint32_t metadata_argc = 0;
HashTable *named_metadata = NULL;

ZEND_PARSE_PARAMETERS_START(2,-1)
Z_PARAM_STR_OR_NULL(class_name)
ZEND_PARSE_PARAMETERS_START(1,-1)
Z_PARAM_STR(function_name)
Z_PARAM_OPTIONAL
Z_PARAM_STR_OR_NULL(class_name)
Z_PARAM_ZVAL(preprocessing_arg)
Z_PARAM_ZVAL(postprocessing_arg)
Z_PARAM_ZVAL(attributes_arg)
Z_PARAM_VARIADIC_WITH_NAMED(metadata_args, metadata_argc, named_metadata)
ZEND_PARSE_PARAMETERS_END();

Expand Down Expand Up @@ -607,6 +642,30 @@ ZEND_FUNCTION(Sentry_instrument) {
zval attribute_list;
ZVAL_UNDEF(&attribute_list);

sentry_set_processing_callback(
&preprocessing_callback,
preprocessing_arg,
SENTRY_PREPROCESSING_ARG,
class_name,
function_name
);
sentry_set_processing_callback(
&postprocessing_callback,
postprocessing_arg,
SENTRY_POSTPROCESSING_ARG,
class_name,
function_name
);

if (attributes_arg != NULL) {
sentry_add_named_metadata_arg(
&metadata,
&attribute_list,
sentry_str_attributes,
attributes_arg
);
}

for (uint32_t i = 0; i < metadata_argc; i++) {
if (Z_TYPE(metadata_args[i]) == IS_ARRAY) {
sentry_merge_array(&metadata, &metadata_args[i]);
Expand All @@ -618,32 +677,6 @@ ZEND_FUNCTION(Sentry_instrument) {
zval *value;

ZEND_HASH_FOREACH_STR_KEY_VAL(named_metadata, name, value) {
zval *callback_target = NULL;

if (name != NULL) {
if (zend_string_equals_literal(name, SENTRY_PREPROCESSING_ARG)) {
callback_target = &preprocessing_callback;
} else if (zend_string_equals_literal(name, SENTRY_POSTPROCESSING_ARG)) {
callback_target = &postprocessing_callback;
}
}

if (callback_target != NULL) {
if (!zend_is_callable(value, 0, NULL)) {
zend_string *display_name = sentry_build_display_name(class_name, function_name);
sentry_emit_logf(
SENTRY_LOG_WARNING,
"Sentry instrumentation argument \"%s\" for '%s' is not a valid callback and was ignored.",
ZSTR_VAL(name),
ZSTR_VAL(display_name)
);
zend_string_release(display_name);
continue;
}
ZVAL_COPY(callback_target, value);
continue;
}

if (name != NULL) {
sentry_add_named_metadata_arg(
&metadata,
Expand Down Expand Up @@ -1237,6 +1270,7 @@ PHP_MINIT_FUNCTION(sentry) {
sentry_str_duration = zend_string_init_interned("duration", sizeof("duration") - 1, 1);
sentry_str_metadata = zend_string_init_interned("metadata", sizeof("metadata") - 1, 1);
sentry_str_exception = zend_string_init_interned("exception", sizeof("exception") - 1, 1);
sentry_str_attributes = zend_string_init_interned("attributes",sizeof("attributes") - 1,1);

sentry_register_log_constants(module_number);

Expand Down
12 changes: 10 additions & 2 deletions sentry.stub.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,17 @@
const LOG_WARNING = 300;
const LOG_ERROR = 400;

/**
* @phpstan-param callable(mixed...): mixed $preprocessing
* @phpstan-param callable(mixed): mixed $postprocessing
* @phpstan-param array<string, mixed> $attributes
*/
function instrument(
?string $className,
string $functionName,
string $function,
?string $class = null,
?callable $preprocessing = null,
?callable $postprocessing = null,
array $attributes = [],
mixed ...$metadata
): bool {}

Expand Down
13 changes: 8 additions & 5 deletions sentry_arginfo.h
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
/* This is a generated file, edit the .stub.php file instead.
* Stub hash: 9b2b12d671b0ee55aa239014f8d8c702e5b5e260 */

ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_Sentry_instrument, 0, 2, _IS_BOOL, 0)
ZEND_ARG_TYPE_INFO(0, className, IS_STRING, 1)
ZEND_ARG_TYPE_INFO(0, functionName, IS_STRING, 0)
* Stub hash: 472327fee6b02cd5e40ed2f0cddf6971d92514ce */

ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_Sentry_instrument, 0, 1, _IS_BOOL, 0)
ZEND_ARG_TYPE_INFO(0, function, IS_STRING, 0)
ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, class, IS_STRING, 1, "null")
ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, preprocessing, IS_CALLABLE, 1, "null")
ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, postprocessing, IS_CALLABLE, 1, "null")
ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, attributes, IS_ARRAY, 0, "[]")
ZEND_ARG_VARIADIC_TYPE_INFO(0, metadata, IS_MIXED, 0)
ZEND_END_ARG_INFO()

Expand Down
2 changes: 1 addition & 1 deletion tests/test_callback_return_value.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ function test_instrumented() {
echo $returnValue . PHP_EOL;
});

\Sentry\instrument(null, 'test_instrumented');
\Sentry\instrument('test_instrumented');
test_instrumented();

?>
Expand Down
2 changes: 1 addition & 1 deletion tests/test_case_insensitive.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ function work() {
echo "Duration: " . $data['duration'] . PHP_EOL;
});

\Sentry\instrument(null, 'WoRk');
\Sentry\instrument('WoRk');
work();

?>
Expand Down
4 changes: 2 additions & 2 deletions tests/test_cought_exceptions_do_not_leak.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,8 @@ function test_rethrow() {
}
});

\Sentry\instrument(null, 'test_throw');
\Sentry\instrument(null, 'test_rethrow');
\Sentry\instrument('test_throw');
\Sentry\instrument('test_rethrow');
try {
test_rethrow();
} catch (Throwable $t) {
Expand Down
4 changes: 2 additions & 2 deletions tests/test_duplicate_instrument.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,9 @@ function work() {
echo "Duration: " . $data['duration'] . PHP_EOL;
});

$result = \Sentry\instrument(null, 'work');
$result = \Sentry\instrument('work');
echo "First result: " . ($result ? "true" : "false") . PHP_EOL;
$result = \Sentry\instrument(null, 'work');
$result = \Sentry\instrument('work');
echo "Second result: " . ($result ? "true" : "false") . PHP_EOL;
work();

Expand Down
2 changes: 1 addition & 1 deletion tests/test_end_callback_can_be_overwritten.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ class Foo {
echo "Second callback" . PHP_EOL;
});

\Sentry\instrument("Foo", 'work', []);
\Sentry\instrument('work', class: "Foo", attributes: []);
(new Foo())->work();

?>
Expand Down
2 changes: 1 addition & 1 deletion tests/test_exception_in_end_callback.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ function work() {
throw new \RuntimeException("Does not break out");
});

\Sentry\instrument(null, 'work', ['sentry.op' => 'test']);
\Sentry\instrument('work', attributes: ['sentry.op' => 'test']);
work();

?>
Expand Down
2 changes: 1 addition & 1 deletion tests/test_exception_in_function_and_callback.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ function work() {
throw new \RuntimeException("callback boom");
});

\Sentry\instrument(null, 'work');
\Sentry\instrument('work');
try {
work();
} catch (Throwable $throwable) {
Expand Down
2 changes: 1 addition & 1 deletion tests/test_exception_in_instrumented.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ function work() {
echo "Metadata: " . ($data['metadata']['sentry.op'] ?? 'invalid') . PHP_EOL;
});

\Sentry\instrument(null, 'work', ['sentry.op' => 'test']);
\Sentry\instrument('work', attributes: ['sentry.op' => 'test']);
try {
work();
} catch (Throwable $t) {
Expand Down
2 changes: 1 addition & 1 deletion tests/test_exception_in_start_callback.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ function work() {
throw new \RuntimeException("Does not break out");
});

\Sentry\instrument(null, 'work', ['sentry.op' => 'test']);
\Sentry\instrument('work', attributes: ['sentry.op' => 'test']);
work();

?>
Expand Down
2 changes: 1 addition & 1 deletion tests/test_exception_set_in_end_callback.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ function test_throw() {
echo get_class($exception) . PHP_EOL;
});

\Sentry\instrument(null, 'test_throw');
\Sentry\instrument('test_throw');
try {
test_throw();
} catch (Throwable $t) {
Expand Down
2 changes: 1 addition & 1 deletion tests/test_fields_always_present.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ function test_instrumented() {
echo 'metadata: ' . get_debug_type($data['metadata']) . PHP_EOL;
});

\Sentry\instrument(null, 'test_instrumented');
\Sentry\instrument('test_instrumented');
test_instrumented();

?>
Expand Down
2 changes: 1 addition & 1 deletion tests/test_function_metadata.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ function test_instrumented() {
echo "End metadata: " . ($data['metadata']['sentry.op'] ?? 'invalid') . PHP_EOL;
});

\Sentry\instrument(null, 'test_instrumented', ['sentry.op' => 'test']);
\Sentry\instrument('test_instrumented', attributes: ['sentry.op' => 'test']);
test_instrumented();

?>
Expand Down
2 changes: 1 addition & 1 deletion tests/test_inheritance_correct_name.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ class B extends A {
echo "Duration: " . $data['duration'] . PHP_EOL;
});

\Sentry\instrument("B", "work");
\Sentry\instrument("work", class: "B");

(new B())->work();
(new A())->work();
Expand Down
2 changes: 1 addition & 1 deletion tests/test_instrument_after_first_call.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ function work() {

work();

\Sentry\instrument(null, 'work', ['source' => 'registration']);
\Sentry\instrument('work', attributes: ['source' => 'registration']);

work();

Expand Down
2 changes: 1 addition & 1 deletion tests/test_instrument_after_first_call_inherited.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ class B extends A {

(new B())->work();

\Sentry\instrument("B", "work", ['source' => 'registration']);
\Sentry\instrument("work", class: "B", attributes: ['source' => 'registration']);

(new B())->work();
(new A())->work();
Expand Down
32 changes: 32 additions & 0 deletions tests/test_instrument_tolerant_explicit_params.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
--TEST--
Tests that explicitly typed instrument options retain tolerant runtime behavior.
--EXTENSIONS--
sentry
--FILE--
<?php

function test_instrumented() {
}

\Sentry\setLogCallback(static function (int $level, string $message) {
echo $level . ':' . $message . PHP_EOL;
});

\Sentry\setEndCallback(static function (array $data) {
echo 'attributes=' . $data['metadata']['attributes'] . PHP_EOL;
});

\Sentry\instrument(
function: 'test_instrumented',
preprocessing: 'not-callable',
postprocessing: 42,
attributes: 'kept-as-metadata',
);

test_instrumented();

?>
--EXPECT--
300:Sentry instrumentation argument "preprocessing" for 'test_instrumented' is not a valid callback and was ignored.
300:Sentry instrumentation argument "postprocessing" for 'test_instrumented' is not a valid callback and was ignored.
attributes=kept-as-metadata
2 changes: 1 addition & 1 deletion tests/test_log_callback_can_be_overwritten.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ function test_instrumented() {
echo $level . ":" . $message . PHP_EOL;
});

\Sentry\instrument(null, 'test_instrumented', []);
\Sentry\instrument('test_instrumented', attributes: []);
test_instrumented();

\Sentry\setLogCallback(static function(int $level, string $message) {
Expand Down
2 changes: 1 addition & 1 deletion tests/test_log_callback_crash_doesnt_log.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ function test_instrumented() {
throw new \RuntimeException("log callback crashed");
});

\Sentry\instrument(null, 'test_instrumented', []);
\Sentry\instrument('test_instrumented', attributes: []);
test_instrumented();

?>
Expand Down
4 changes: 2 additions & 2 deletions tests/test_log_duplicate_instrument.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,8 @@ function test_instrumented() {
echo $level . ":" . $message . PHP_EOL;
});

var_dump(\Sentry\instrument(null, 'test_instrumented', []));
var_dump(\Sentry\instrument(null, 'test_instrumented', []));
var_dump(\Sentry\instrument('test_instrumented', attributes: []));
var_dump(\Sentry\instrument('test_instrumented', attributes: []));

?>
--EXPECTF--
Expand Down
2 changes: 1 addition & 1 deletion tests/test_log_end_callback_exception.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ function test_instrumented() {
echo $level . ":" . $message . PHP_EOL;
});

\Sentry\instrument(null, 'test_instrumented', []);
\Sentry\instrument('test_instrumented', attributes: []);
test_instrumented();

?>
Expand Down
Loading
Loading