Skip to content

Commit

Permalink
Fix analytics.event override (#2409)
Browse files Browse the repository at this point in the history
* fix: Explicitly check for true !(case sensitive) when overriding analytics event

* Mimics Go's `strconv.ParseBool` & add tests

* style: Refactor

* Don't set the '_dd1.sr.eausr' on parsing failure

* Don't set the '_dd1.sr.eausr' on parsing failure
  • Loading branch information
PROFeNoM authored Dec 19, 2023
1 parent 1af839d commit f8f6d29
Show file tree
Hide file tree
Showing 2 changed files with 94 additions and 3 deletions.
51 changes: 48 additions & 3 deletions ext/serializer.c
Original file line number Diff line number Diff line change
Expand Up @@ -1150,6 +1150,46 @@ void ddtrace_shutdown_span_sampling_limiter(void) {
zend_hash_destroy(&dd_span_sampling_limiters);
}

// ParseBool returns the boolean value represented by the string.
// It accepts 1, t, T, TRUE, true, True, 0, f, F, FALSE, false, False.
// Any other value returns -1.
static zend_always_inline double strconv_parse_bool(zend_string *str) {
// See Go's strconv.ParseBool
// https://cs.opensource.google/go/go/+/refs/tags/go1.21.5:src/strconv/atob.go;drc=1f137052e4a20dbd302f947b1cf34cdf4b427d65;l=10
size_t len = ZSTR_LEN(str);
if (len == 0) {
return -1;
}

char *s = ZSTR_VAL(str);
switch (len) {
case 1:
switch (s[0]) {
case '1':
case 't':
case 'T':
return 1;
case '0':
case 'f':
case 'F':
return 0;
}
break;
case 4:
if (strcmp(s, "TRUE") == 0 || strcmp(s, "True") == 0 || strcmp(s, "true") == 0) {
return 1;
}
break;
case 5:
if (strcmp(s, "FALSE") == 0 || strcmp(s, "False") == 0 || strcmp(s, "false") == 0) {
return 0;
}
break;
}

return -1;
}

void ddtrace_serialize_span_to_array(ddtrace_span_data *span, zval *array) {
bool is_root_span = span->std.ce == ddtrace_ce_root_span_data;

Expand Down Expand Up @@ -1273,12 +1313,17 @@ void ddtrace_serialize_span_to_array(ddtrace_span_data *span, zval *array) {
if (analytics_event) {
zval analytics_event_as_double;
if (Z_TYPE_P(analytics_event) == IS_STRING) {
ZVAL_DOUBLE(&analytics_event_as_double, zend_is_true(analytics_event)); // 'true' => 1.0, false => 0.0
double parsed_analytics_event = strconv_parse_bool(Z_STR_P(analytics_event));
if (parsed_analytics_event >= 0) {
ZVAL_DOUBLE(&analytics_event_as_double, parsed_analytics_event);
zend_array *metrics = ddtrace_property_array(&span->property_metrics);
zend_hash_str_add_new(metrics, ZEND_STRL("_dd1.sr.eausr"), &analytics_event_as_double);
}
} else {
ZVAL_DOUBLE(&analytics_event_as_double, zval_get_double(analytics_event));
zend_array *metrics = ddtrace_property_array(&span->property_metrics);
zend_hash_str_add_new(metrics, ZEND_STRL("_dd1.sr.eausr"), &analytics_event_as_double);
}
zend_array *metrics = ddtrace_property_array(&span->property_metrics);
zend_hash_str_add_new(metrics, ZEND_STRL("_dd1.sr.eausr"), &analytics_event_as_double);
zend_hash_str_del(meta, ZEND_STRL("analytics.event"));
}

Expand Down
46 changes: 46 additions & 0 deletions tests/OpenTelemetry/Integration/API/TracerTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -336,6 +336,52 @@ public function providerSpanKind()
];
}

public function providerAnalyticsEvent()
{
return [
["true", 1],
["TRUE", 1],
["True", 1],
["false", 0],
["False", 0],
["FALSE", 0],
["something-else", null],
[True, 1],
[False, 0],
['t', 1],
['T', 1],
['f', 0],
['F', 0],
['1', 1],
['0', 0],
['fAlse', null],
['trUe', null]
];
}

/**
* @dataProvider providerAnalyticsEvent
*/
public function testReservedAttributesOverridesAnalyticsEvent($analyticsEventValue, $expectedMetricValue)
{
$traces = $this->isolateTracer(function () use ($analyticsEventValue) {
$tracer = self::getTracer();
$span = $tracer->spanBuilder('operation')
->setSpanKind(SpanKind::KIND_SERVER)
->startSpan();
$span->setAttribute('analytics.event', $analyticsEventValue);
$span->end();
});

$span = $traces[0][0];
if ($expectedMetricValue !== null) {
$actualMetricValue = $span['metrics']['_dd1.sr.eausr'];
$this->assertEquals($expectedMetricValue, $actualMetricValue);
} else {
$this->assertArrayNotHasKey('_dd1.sr.eausr', $span['metrics']);
}
}

public function testSpanErrorStatus()
{
$traces = $this->isolateTracer(function () {
Expand Down

0 comments on commit f8f6d29

Please sign in to comment.