From 9bf828cb15bac703ebd04f1d04c7d7422472a88e Mon Sep 17 00:00:00 2001 From: Maximo Bautista Date: Mon, 21 Oct 2024 16:18:19 -0400 Subject: [PATCH 01/29] Updating to not run redact code if value is empty --- ext/serializer.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/ext/serializer.c b/ext/serializer.c index 173a87dd3b..fad71b7998 100644 --- a/ext/serializer.c +++ b/ext/serializer.c @@ -407,8 +407,9 @@ static void dd_add_post_fields_to_meta_recursive(zend_array *meta, const char *t zend_string *postvalconcat = zend_strpprintf(0, "%s=%s", ZSTR_VAL(postkey), ZSTR_VAL(postvalstr)); zend_string_release(postvalstr); - // Match it with the regex to redact if needed - if (zai_match_regex(get_DD_TRACE_OBFUSCATION_QUERY_STRING_REGEXP(), postvalconcat)) { + // Match it with the regex to redact if needed and value is not an empty string + zend_string *regex_pattern = get_DD_TRACE_OBFUSCATION_QUERY_STRING_REGEXP(); + if (strlen(regex_pattern) > 0 && zai_match_regex(regex_pattern, postvalconcat)) { zend_string *replacement = zend_string_init(ZEND_STRL(""), 0); dd_add_post_fields_to_meta(meta, type, postkey, replacement); zend_string_release(replacement); From f6f1fd64f8594451a7d3abdd0783c7fa4b1c4c59 Mon Sep 17 00:00:00 2001 From: Maximo Bautista Date: Tue, 22 Oct 2024 18:20:30 -0400 Subject: [PATCH 02/29] Removed old attempt, added new and testing --- ext/serializer.c | 4 +-- src/DDTrace/Util/Normalizer.php | 12 +++++---- tests/Unit/Util/Normalizer/UriTest.php | 36 ++++++++++++++++++++++++++ 3 files changed, 44 insertions(+), 8 deletions(-) diff --git a/ext/serializer.c b/ext/serializer.c index fad71b7998..c4f43661af 100644 --- a/ext/serializer.c +++ b/ext/serializer.c @@ -407,9 +407,7 @@ static void dd_add_post_fields_to_meta_recursive(zend_array *meta, const char *t zend_string *postvalconcat = zend_strpprintf(0, "%s=%s", ZSTR_VAL(postkey), ZSTR_VAL(postvalstr)); zend_string_release(postvalstr); - // Match it with the regex to redact if needed and value is not an empty string - zend_string *regex_pattern = get_DD_TRACE_OBFUSCATION_QUERY_STRING_REGEXP(); - if (strlen(regex_pattern) > 0 && zai_match_regex(regex_pattern, postvalconcat)) { + if (zai_match_regex(get_DD_TRACE_OBFUSCATION_QUERY_STRING_REGEXP(), postvalconcat)) { zend_string *replacement = zend_string_init(ZEND_STRL(""), 0); dd_add_post_fields_to_meta(meta, type, postkey, replacement); zend_string_release(replacement); diff --git a/src/DDTrace/Util/Normalizer.php b/src/DDTrace/Util/Normalizer.php index 2c3f67ec4a..042865a2fa 100644 --- a/src/DDTrace/Util/Normalizer.php +++ b/src/DDTrace/Util/Normalizer.php @@ -218,11 +218,13 @@ private static function generateFilteredPostFields($postKey, $postVal, array $wh // Match it with the regex to redact if needed $obfuscationRegex = \ini_get('datadog.trace.obfuscation_query_string_regexp'); - $obfuscationRegex = '(' . $obfuscationRegex . ')'; - if (preg_match($obfuscationRegex, $postField)) { - return [$postKey => '']; - } else { - return [$postKey => $postVal]; + if ($obfuscationRegex !== "") { + $obfuscationRegex = '(' . $obfuscationRegex . ')'; + if (preg_match($obfuscationRegex, $postField)) { + return [$postKey => '']; + } else { + return [$postKey => $postVal]; + } } } else { // The postkey is not in the whitelist, and no wildcard set, then always use diff --git a/tests/Unit/Util/Normalizer/UriTest.php b/tests/Unit/Util/Normalizer/UriTest.php index 2e0b427102..b1014043a7 100644 --- a/tests/Unit/Util/Normalizer/UriTest.php +++ b/tests/Unit/Util/Normalizer/UriTest.php @@ -13,6 +13,7 @@ protected function ddSetUp() 'DD_TRACE_RESOURCE_URI_MAPPING_INCOMING', 'DD_TRACE_RESOURCE_URI_MAPPING_OUTGOING', 'DD_TRACE_RESOURCE_URI_QUERY_PARAM_ALLOWED', + 'DD_TRACE_OBFUSCATION_QUERY_STRING_REGEXP', ]); parent::ddSetUp(); } @@ -25,6 +26,7 @@ protected function ddTearDown() 'DD_TRACE_RESOURCE_URI_MAPPING_INCOMING', 'DD_TRACE_RESOURCE_URI_MAPPING_OUTGOING', 'DD_TRACE_RESOURCE_URI_QUERY_PARAM_ALLOWED', + 'DD_TRACE_OBFUSCATION_QUERY_STRING_REGEXP', ]); } @@ -486,6 +488,40 @@ public function testQueryParamPreserveWildcard() ); } + public function testObfuscationQueryStringConfigured() + { + $this->putEnvAndReloadConfig([ + 'DD_TRACE_OBFUSCATION_QUERY_STRING_REGEXP=\d{3}-\d{2}-\d{4}', + ]); + + $this->assertSame( + '/?', + \DDTrace\Util\Normalizer::uriNormalizeIncomingPath('/?ssn=123-45-6789') + ); + + $this->assertSame( + '/?', + \DDTrace\Util\Normalizer::uriNormalizeOutgoingPath('/?ssn=123-45-6789') + ); + } + + public function testObfuscationQueryStringWithEmptyRegex() + { + $this->putEnvAndReloadConfig([ + 'DD_TRACE_OBFUSCATION_QUERY_STRING_REGEXP=""', + ]); + + $this->assertSame( + '/?application_key=123', + \DDTrace\Util\Normalizer::uriNormalizeIncomingPath('/?application_key=123') + ); + + $this->assertSame( + '/?application_key=123', + \DDTrace\Util\Normalizer::uriNormalizeOutgoingPath('/?application_key=123') + ); + } + /** * @dataProvider dataProviderSanitizeNoDropUserinfo * @param string $url From 5f1f193bd1c5672272cff6a96952c631ac1adb57 Mon Sep 17 00:00:00 2001 From: Maximo Bautista Date: Wed, 23 Oct 2024 14:01:00 -0400 Subject: [PATCH 03/29] Updating test and removing fix attempt --- src/DDTrace/Util/Normalizer.php | 12 +++++----- tests/Unit/Util/Normalizer/UriTest.php | 20 ----------------- ...l_with_query_params_obfuscation_empty.phpt | 22 +++++++++++++++++++ 3 files changed, 27 insertions(+), 27 deletions(-) create mode 100644 tests/ext/root_span_url_with_query_params_obfuscation_empty.phpt diff --git a/src/DDTrace/Util/Normalizer.php b/src/DDTrace/Util/Normalizer.php index 042865a2fa..2c3f67ec4a 100644 --- a/src/DDTrace/Util/Normalizer.php +++ b/src/DDTrace/Util/Normalizer.php @@ -218,13 +218,11 @@ private static function generateFilteredPostFields($postKey, $postVal, array $wh // Match it with the regex to redact if needed $obfuscationRegex = \ini_get('datadog.trace.obfuscation_query_string_regexp'); - if ($obfuscationRegex !== "") { - $obfuscationRegex = '(' . $obfuscationRegex . ')'; - if (preg_match($obfuscationRegex, $postField)) { - return [$postKey => '']; - } else { - return [$postKey => $postVal]; - } + $obfuscationRegex = '(' . $obfuscationRegex . ')'; + if (preg_match($obfuscationRegex, $postField)) { + return [$postKey => '']; + } else { + return [$postKey => $postVal]; } } else { // The postkey is not in the whitelist, and no wildcard set, then always use diff --git a/tests/Unit/Util/Normalizer/UriTest.php b/tests/Unit/Util/Normalizer/UriTest.php index b1014043a7..59e09358e3 100644 --- a/tests/Unit/Util/Normalizer/UriTest.php +++ b/tests/Unit/Util/Normalizer/UriTest.php @@ -13,7 +13,6 @@ protected function ddSetUp() 'DD_TRACE_RESOURCE_URI_MAPPING_INCOMING', 'DD_TRACE_RESOURCE_URI_MAPPING_OUTGOING', 'DD_TRACE_RESOURCE_URI_QUERY_PARAM_ALLOWED', - 'DD_TRACE_OBFUSCATION_QUERY_STRING_REGEXP', ]); parent::ddSetUp(); } @@ -26,7 +25,6 @@ protected function ddTearDown() 'DD_TRACE_RESOURCE_URI_MAPPING_INCOMING', 'DD_TRACE_RESOURCE_URI_MAPPING_OUTGOING', 'DD_TRACE_RESOURCE_URI_QUERY_PARAM_ALLOWED', - 'DD_TRACE_OBFUSCATION_QUERY_STRING_REGEXP', ]); } @@ -74,24 +72,6 @@ public function testWrongOutgoingConfigurationResultsInMissedPathNormalizationBu ); } - public function testMixingFragmentRegexAndPatternMatchingIncoming() - { - $this->putEnvAndReloadConfig(['DD_TRACE_RESOURCE_URI_MAPPING_INCOMING=name/*']); - $this->assertSame( - '/numeric/?/name/?', - \DDTrace\Util\Normalizer::uriNormalizeIncomingPath('/numeric/123/name/some_name') - ); - } - - public function testMixingFragmentRegexAndPatternMatchingOutgoing() - { - $this->putEnvAndReloadConfig(['DD_TRACE_RESOURCE_URI_MAPPING_OUTGOING=name/*']); - $this->assertSame( - '/numeric/?/name/?', - \DDTrace\Util\Normalizer::uriNormalizeOutgoingPath('/numeric/123/name/some_name') - ); - } - /** * @dataProvider defaultPathNormalizationScenarios */ diff --git a/tests/ext/root_span_url_with_query_params_obfuscation_empty.phpt b/tests/ext/root_span_url_with_query_params_obfuscation_empty.phpt new file mode 100644 index 0000000000..34ba57827a --- /dev/null +++ b/tests/ext/root_span_url_with_query_params_obfuscation_empty.phpt @@ -0,0 +1,22 @@ +--TEST-- +Root span with http.url and unobfuscated query string with empty regex +--ENV-- +DD_TRACE_GENERATE_ROOT_SPAN=0 +DD_TRACE_OBFUSCATION_QUERY_STRING_REGEXP='' +HTTPS=off +HTTP_HOST=localhost:9999 +SCRIPT_NAME=/foo.php +REQUEST_URI=/users?application_key=123 +QUERY_STRING=application_key=123 +METHOD=GET +--GET-- +application_key=123 +--FILE-- + +--EXPECT-- +string(48) "https://localhost:9999/users?application_key=123" From b06f8a7f2abac6f9bd080613a71021ddcdc11057 Mon Sep 17 00:00:00 2001 From: Maximo Bautista Date: Wed, 23 Oct 2024 14:04:19 -0400 Subject: [PATCH 04/29] Fixing previous commit --- tests/Unit/Util/Normalizer/UriTest.php | 52 +++++++++----------------- 1 file changed, 18 insertions(+), 34 deletions(-) diff --git a/tests/Unit/Util/Normalizer/UriTest.php b/tests/Unit/Util/Normalizer/UriTest.php index 59e09358e3..2e0b427102 100644 --- a/tests/Unit/Util/Normalizer/UriTest.php +++ b/tests/Unit/Util/Normalizer/UriTest.php @@ -72,6 +72,24 @@ public function testWrongOutgoingConfigurationResultsInMissedPathNormalizationBu ); } + public function testMixingFragmentRegexAndPatternMatchingIncoming() + { + $this->putEnvAndReloadConfig(['DD_TRACE_RESOURCE_URI_MAPPING_INCOMING=name/*']); + $this->assertSame( + '/numeric/?/name/?', + \DDTrace\Util\Normalizer::uriNormalizeIncomingPath('/numeric/123/name/some_name') + ); + } + + public function testMixingFragmentRegexAndPatternMatchingOutgoing() + { + $this->putEnvAndReloadConfig(['DD_TRACE_RESOURCE_URI_MAPPING_OUTGOING=name/*']); + $this->assertSame( + '/numeric/?/name/?', + \DDTrace\Util\Normalizer::uriNormalizeOutgoingPath('/numeric/123/name/some_name') + ); + } + /** * @dataProvider defaultPathNormalizationScenarios */ @@ -468,40 +486,6 @@ public function testQueryParamPreserveWildcard() ); } - public function testObfuscationQueryStringConfigured() - { - $this->putEnvAndReloadConfig([ - 'DD_TRACE_OBFUSCATION_QUERY_STRING_REGEXP=\d{3}-\d{2}-\d{4}', - ]); - - $this->assertSame( - '/?', - \DDTrace\Util\Normalizer::uriNormalizeIncomingPath('/?ssn=123-45-6789') - ); - - $this->assertSame( - '/?', - \DDTrace\Util\Normalizer::uriNormalizeOutgoingPath('/?ssn=123-45-6789') - ); - } - - public function testObfuscationQueryStringWithEmptyRegex() - { - $this->putEnvAndReloadConfig([ - 'DD_TRACE_OBFUSCATION_QUERY_STRING_REGEXP=""', - ]); - - $this->assertSame( - '/?application_key=123', - \DDTrace\Util\Normalizer::uriNormalizeIncomingPath('/?application_key=123') - ); - - $this->assertSame( - '/?application_key=123', - \DDTrace\Util\Normalizer::uriNormalizeOutgoingPath('/?application_key=123') - ); - } - /** * @dataProvider dataProviderSanitizeNoDropUserinfo * @param string $url From 45f1ffdcb8d1d40ef95d368e1bd687187c8dcfc7 Mon Sep 17 00:00:00 2001 From: Maximo Bautista Date: Wed, 23 Oct 2024 14:05:55 -0400 Subject: [PATCH 05/29] Adding comment back --- ext/serializer.c | 1 + 1 file changed, 1 insertion(+) diff --git a/ext/serializer.c b/ext/serializer.c index c4f43661af..173a87dd3b 100644 --- a/ext/serializer.c +++ b/ext/serializer.c @@ -407,6 +407,7 @@ static void dd_add_post_fields_to_meta_recursive(zend_array *meta, const char *t zend_string *postvalconcat = zend_strpprintf(0, "%s=%s", ZSTR_VAL(postkey), ZSTR_VAL(postvalstr)); zend_string_release(postvalstr); + // Match it with the regex to redact if needed if (zai_match_regex(get_DD_TRACE_OBFUSCATION_QUERY_STRING_REGEXP(), postvalconcat)) { zend_string *replacement = zend_string_init(ZEND_STRL(""), 0); dd_add_post_fields_to_meta(meta, type, postkey, replacement); From 40754f2c6ad2a76e32c17d23bc26cc68b9605b7d Mon Sep 17 00:00:00 2001 From: Maximo Bautista Date: Wed, 23 Oct 2024 15:04:45 -0400 Subject: [PATCH 06/29] Updating test and adding fix --- .../ext/root_span_url_with_query_params_obfuscation_empty.phpt | 3 ++- zend_abstract_interface/uri_normalization/uri_normalization.c | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/tests/ext/root_span_url_with_query_params_obfuscation_empty.phpt b/tests/ext/root_span_url_with_query_params_obfuscation_empty.phpt index 34ba57827a..fd83693e72 100644 --- a/tests/ext/root_span_url_with_query_params_obfuscation_empty.phpt +++ b/tests/ext/root_span_url_with_query_params_obfuscation_empty.phpt @@ -1,8 +1,9 @@ --TEST-- Root span with http.url and unobfuscated query string with empty regex +--INI-- +datadog.trace.obfuscation_query_string_regexp= --ENV-- DD_TRACE_GENERATE_ROOT_SPAN=0 -DD_TRACE_OBFUSCATION_QUERY_STRING_REGEXP='' HTTPS=off HTTP_HOST=localhost:9999 SCRIPT_NAME=/foo.php diff --git a/zend_abstract_interface/uri_normalization/uri_normalization.c b/zend_abstract_interface/uri_normalization/uri_normalization.c index 40e0666db1..6bf2508181 100644 --- a/zend_abstract_interface/uri_normalization/uri_normalization.c +++ b/zend_abstract_interface/uri_normalization/uri_normalization.c @@ -157,7 +157,7 @@ zend_string *zai_filter_query_string(zai_str queryString, zend_array *whitelist, zend_hash_get_current_key(whitelist, &str, &numkey); if (zend_string_equals_literal(str, "*")) { zend_string *qs = zend_string_init(queryString.ptr, queryString.len, 0); - if (pattern) { + if (ZSTR_LEN(pattern)) { zend_string *replacement = zend_string_init(ZEND_STRL(""), 0); smart_str regex = {0}; From 4055e6bf0ef8afad18c8d37df26f300b0f8b7da3 Mon Sep 17 00:00:00 2001 From: Maximo Bautista Date: Wed, 23 Oct 2024 15:38:06 -0400 Subject: [PATCH 07/29] Adding check for empty string in Normalizer as well --- src/DDTrace/Util/Normalizer.php | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/DDTrace/Util/Normalizer.php b/src/DDTrace/Util/Normalizer.php index 2c3f67ec4a..70fe823b31 100644 --- a/src/DDTrace/Util/Normalizer.php +++ b/src/DDTrace/Util/Normalizer.php @@ -216,10 +216,9 @@ private static function generateFilteredPostFields($postKey, $postVal, array $wh // Concatenate the postkey and postval into '=' $postField = "$postKey=$postVal"; - // Match it with the regex to redact if needed + // Match it with the regex to redact if needed and regex is not empty $obfuscationRegex = \ini_get('datadog.trace.obfuscation_query_string_regexp'); - $obfuscationRegex = '(' . $obfuscationRegex . ')'; - if (preg_match($obfuscationRegex, $postField)) { + if ($obfuscationRegex != "" && preg_match('(' . $obfuscationRegex . ')', $postField)) { return [$postKey => '']; } else { return [$postKey => $postVal]; From 2933281a8bbc33c7d699537a2a3637ec13ce1f1c Mon Sep 17 00:00:00 2001 From: Maximo Bautista Date: Thu, 31 Oct 2024 16:22:04 -0400 Subject: [PATCH 08/29] Adding test to base behavior from --- .../dd_trace_serialize_header_to_meta.phpt | 20 +++++++++++++++++++ 1 file changed, 20 insertions(+) create mode 100644 tests/ext/dd_trace_serialize_header_to_meta.phpt diff --git a/tests/ext/dd_trace_serialize_header_to_meta.phpt b/tests/ext/dd_trace_serialize_header_to_meta.phpt new file mode 100644 index 0000000000..9146210e58 --- /dev/null +++ b/tests/ext/dd_trace_serialize_header_to_meta.phpt @@ -0,0 +1,20 @@ +--TEST-- +Headers values are mapped to expected tag key +--ENV-- +HTTP_CONTENT_TYPE=text/plain +HTTP_CUSTOM_HEADER=custom-header-value +DD_TRACE_GENERATE_ROOT_SPAN=0 +DD_TRACE_HEADER_TAGS=Content-Type,Custom-Header:custom-header-key +--GET-- +application_key=123 +--FILE-- + +--EXPECT-- +string(10) "text/plain" +string(13) "custom-header-value" From 352d3babf9588fcfbc9726232f0a2594b17dede8 Mon Sep 17 00:00:00 2001 From: Ayan Khan Date: Mon, 4 Nov 2024 11:48:32 -0500 Subject: [PATCH 09/29] Implement UST Consistency (#2896) * Make changes such that iff a span has service name set by DD_SERVICE, it also gets the version specified in DD_VERSION --------- Co-authored-by: Bob Weinand --- ext/ddtrace.c | 13 ++++++ libdatadog | 2 +- tests/ext/ust.phpt | 113 +++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 127 insertions(+), 1 deletion(-) create mode 100644 tests/ext/ust.phpt diff --git a/ext/ddtrace.c b/ext/ddtrace.c index dce2a30a28..0ec0fbae7a 100644 --- a/ext/ddtrace.c +++ b/ext/ddtrace.c @@ -1049,6 +1049,19 @@ static zval *ddtrace_span_data_readonly(zend_object *object, zend_string *member #endif } + ddtrace_span_data *span = OBJ_SPANDATA(obj); + // As per unified service tagging spec if a span is created with a service name different from the global + // service name it will not inherit the global version value + if (zend_string_equals_literal(prop_name, "service")) { + cache_slot = NULL; + if (ZSTR_LEN(get_DD_SERVICE()) || !ddtrace_span_is_entrypoint_root(span)) { + if (!zend_is_identical(&span->property_service, value)) { + zval_ptr_dtor(&span->property_version); + ZVAL_EMPTY_STRING(&span->property_version); + } + } + } + #if PHP_VERSION_ID >= 70400 return zend_std_write_property(object, member, value, cache_slot); #else diff --git a/libdatadog b/libdatadog index 085a91abb8..356f76a818 160000 --- a/libdatadog +++ b/libdatadog @@ -1 +1 @@ -Subproject commit 085a91abb8fe6700a6faa528314ada665bc36852 +Subproject commit 356f76a818d164c954d2a09e54e2e8c41537a053 diff --git a/tests/ext/ust.phpt b/tests/ext/ust.phpt new file mode 100644 index 0000000000..bfcbb2c3ec --- /dev/null +++ b/tests/ext/ust.phpt @@ -0,0 +1,113 @@ +--TEST-- +Foo +--ENV-- +DD_SERVICE=version_test +DD_VERSION=5.2.0 +DD_TRACE_AUTO_FLUSH_ENABLED=0 +DD_TRACE_GENERATE_ROOT_SPAN=0 +--FILE-- +name = "s1"; +\DDTrace\close_span(); + +$s2 = \DDTrace\start_trace_span(); +$s2->name = "s2"; +$s2->service = "no dd_service"; +\DDTrace\close_span(); + +var_dump(dd_trace_serialize_closed_spans()); + +?> +--EXPECTF-- +array(2) { + [0]=> + array(%d) { + ["trace_id"]=> + string(%d) "%s" + ["span_id"]=> + string(%d) "%s" + ["start"]=> + int(%d) + ["duration"]=> + int(%d) + ["name"]=> + string(2) "s2" + ["resource"]=> + string(2) "s2" + ["service"]=> + string(13) "no dd_service" + ["type"]=> + string(3) "cli" + ["meta"]=> + array(%d) { + ["runtime-id"]=> + string(36) "%s" + ["_dd.p.dm"]=> + string(2) "-0" + ["_dd.p.tid"]=> + string(16) "%s" + } + ["metrics"]=> + array(%d) { + ["process_id"]=> + float(%f) + ["_dd.agent_psr"]=> + float(1) + ["_sampling_priority_v1"]=> + float(1) + ["php.compilation.total_time_ms"]=> + float(%f) + ["php.memory.peak_usage_bytes"]=> + float(%f) + ["php.memory.peak_real_usage_bytes"]=> + float(%f) + } + } + [1]=> + array(%d) { + ["trace_id"]=> + string(%d) "%s" + ["span_id"]=> + string(%d) "%s" + ["start"]=> + int(%d) + ["duration"]=> + int(%d) + ["name"]=> + string(2) "s1" + ["resource"]=> + string(2) "s1" + ["service"]=> + string(12) "version_test" + ["type"]=> + string(3) "cli" + ["meta"]=> + array(%d) { + ["runtime-id"]=> + string(36) "%s" + ["_dd.p.dm"]=> + string(2) "-0" + ["version"]=> + string(5) "5.2.0" + ["_dd.p.tid"]=> + string(16) "%s" + } + ["metrics"]=> + array(%d) { + ["process_id"]=> + float(%f) + ["_dd.agent_psr"]=> + float(1) + ["_sampling_priority_v1"]=> + float(1) + ["php.compilation.total_time_ms"]=> + float(%f) + ["php.memory.peak_usage_bytes"]=> + float(%f) + ["php.memory.peak_real_usage_bytes"]=> + float(%f) + } + } +} From a1939a29172c5d6a0e9bbc2406729a8ca05a552b Mon Sep 17 00:00:00 2001 From: Maximo Bautista Date: Mon, 4 Nov 2024 19:17:46 -0500 Subject: [PATCH 10/29] Using MAP_LOWERCASE and updating current zai_config_decode_map method --- ext/configuration.h | 4 +- ext/serializer.c | 18 +++-- tests/Unit/ConfigurationTest.php | 7 +- .../dd_trace_serialize_header_to_meta.phpt | 6 +- .../config/config_decode.c | 76 ++++++++++++++----- .../config/config_decode.h | 1 + 6 files changed, 78 insertions(+), 34 deletions(-) diff --git a/ext/configuration.h b/ext/configuration.h index 57dd53cc7e..ccc4f549e6 100644 --- a/ext/configuration.h +++ b/ext/configuration.h @@ -156,7 +156,7 @@ enum ddtrace_sampling_rules_format { CONFIG(CUSTOM(INT), DD_TRACE_SAMPLING_RULES_FORMAT, "glob", .parser = dd_parse_sampling_rules_format) \ CONFIG(JSON, DD_SPAN_SAMPLING_RULES, "[]") \ CONFIG(STRING, DD_SPAN_SAMPLING_RULES_FILE, "", .ini_change = ddtrace_alter_sampling_rules_file_config) \ - CONFIG(SET_LOWERCASE, DD_TRACE_HEADER_TAGS, "", .ini_change = ddtrace_alter_DD_TRACE_HEADER_TAGS) \ + CONFIG(MAP_LOWERCASE, DD_TRACE_HEADER_TAGS, "", .ini_change = ddtrace_alter_DD_TRACE_HEADER_TAGS) \ CONFIG(INT, DD_TRACE_X_DATADOG_TAGS_MAX_LENGTH, "512") \ CONFIG(MAP, DD_TRACE_PEER_SERVICE_MAPPING, "") \ CONFIG(BOOL, DD_TRACE_PEER_SERVICE_DEFAULTS_ENABLED, "false") \ @@ -274,6 +274,7 @@ typedef enum { DD_CONFIGURATION } ddtrace_config_id; } #define SET MAP #define SET_LOWERCASE MAP +#define MAP_LOWERCASE MAP #define JSON MAP #define MAP(id) \ static inline zend_array *get_##id(void) { return Z_ARR_P(zai_config_get_value(DDTRACE_CONFIG_##id)); } \ @@ -292,6 +293,7 @@ static inline bool get_global_DD_TRACE_SIDECAR_TRACE_SENDER(void) { return true; #undef STRING #undef MAP +#undef MAP_LOWERCASE #undef SET #undef SET_LOWERCASE #undef JSON diff --git a/ext/serializer.c b/ext/serializer.c index 173a87dd3b..705c944559 100644 --- a/ext/serializer.c +++ b/ext/serializer.c @@ -324,14 +324,20 @@ static zend_result dd_add_meta_array(void *context, ddtrace_string key, ddtrace_ static void dd_add_header_to_meta(zend_array *meta, const char *type, zend_string *lowerheader, zend_string *headerval) { - if (zend_hash_exists(get_DD_TRACE_HEADER_TAGS(), lowerheader)) { - for (char *ptr = ZSTR_VAL(lowerheader); *ptr; ++ptr) { - if ((*ptr < 'a' || *ptr > 'z') && *ptr != '-' && (*ptr < '0' || *ptr > '9')) { - *ptr = '_'; + zval *header_config = zend_hash_find(get_DD_TRACE_HEADER_TAGS(), lowerheader); + if (header_config != NULL && Z_TYPE_P(header_config) == IS_STRING) { + zend_string *header_config_str = Z_STR_P(header_config); + zend_string *headertag; + if (zend_string_equals(header_config_str, lowerheader)) { + for (char *ptr = ZSTR_VAL(header_config_str); *ptr; ++ptr) { + if ((*ptr < 'a' || *ptr > 'z') && *ptr != '-' && (*ptr < '0' || *ptr > '9')) { + *ptr = '_'; + } } + headertag = zend_strpprintf(0, "http.%s.headers.%s", type, ZSTR_VAL(header_config_str)); + } else { + headertag = zend_string_copy(header_config_str); } - - zend_string *headertag = zend_strpprintf(0, "http.%s.headers.%s", type, ZSTR_VAL(lowerheader)); zval headerzv; ZVAL_STR_COPY(&headerzv, headerval); zend_hash_update(meta, headertag, &headerzv); diff --git a/tests/Unit/ConfigurationTest.php b/tests/Unit/ConfigurationTest.php index 6fb10e4568..b810e5cb81 100644 --- a/tests/Unit/ConfigurationTest.php +++ b/tests/Unit/ConfigurationTest.php @@ -260,7 +260,7 @@ public function testGlobalTags() public function testGlobalTagsWrongValueJustResultsInNoTags() { $this->putEnvAndReloadConfig(['DD_TAGS=wrong_key_value']); - $this->assertEquals([], \dd_trace_env_config("DD_TAGS")); + $this->assertEquals(['wrong_key_value' => 'wrong_key_value'], \dd_trace_env_config("DD_TAGS")); } public function testHttpHeadersDefaultsToEmpty() @@ -279,10 +279,11 @@ public function testHttpHeadersCanSetOne() public function testHttpHeadersCanSetMultiple() { $this->putEnvAndReloadConfig([ - 'DD_TRACE_HEADER_TAGS=A-Header ,Any-Name , cOn7aining-!spe_cial?:ch/ars ', + 'DD_TRACE_HEADER_TAGS=A-Header ,Any-Name , cOn7aining-!spe_cial?:ch/ars , Some-Heather:with-colon-Key', ]); // Same behavior as python tracer: // https://github.com/DataDog/dd-trace-py/blob/f1298cb8100f146059f978b58c88641bd7424af8/ddtrace/http/headers.py - $this->assertSame(['a-header', 'any-name', 'con7aining-!spe_cial?:ch/ars'], array_keys(\dd_trace_env_config("DD_TRACE_HEADER_TAGS"))); + $this->assertSame(['a-header', 'any-name', 'con7aining-!spe_cial?', 'some-heather'], array_keys(\dd_trace_env_config("DD_TRACE_HEADER_TAGS"))); + $this->assertEquals(['a-header' => 'a-header', 'any-name' => 'any-name', 'con7aining-!spe_cial?' => 'ch/ars', 'some-heather' => 'with-colon-Key'], \dd_trace_env_config("DD_TRACE_HEADER_TAGS")); } } diff --git a/tests/ext/dd_trace_serialize_header_to_meta.phpt b/tests/ext/dd_trace_serialize_header_to_meta.phpt index 9146210e58..f9e92f26f4 100644 --- a/tests/ext/dd_trace_serialize_header_to_meta.phpt +++ b/tests/ext/dd_trace_serialize_header_to_meta.phpt @@ -4,7 +4,7 @@ Headers values are mapped to expected tag key HTTP_CONTENT_TYPE=text/plain HTTP_CUSTOM_HEADER=custom-header-value DD_TRACE_GENERATE_ROOT_SPAN=0 -DD_TRACE_HEADER_TAGS=Content-Type,Custom-Header:custom-header-key +DD_TRACE_HEADER_TAGS=Content-Type,Custom-Header:custom-HeaderKey --GET-- application_key=123 --FILE-- @@ -13,8 +13,8 @@ DDTrace\start_span(); DDTrace\close_span(); $spans = dd_trace_serialize_closed_spans(); var_dump($spans[0]['meta']['http.request.headers.content-type']); -var_dump($spans[0]['meta']['custom-header-key']); +var_dump($spans[0]['meta']['custom-HeaderKey']); ?> --EXPECT-- string(10) "text/plain" -string(13) "custom-header-value" +string(19) "custom-header-value" diff --git a/zend_abstract_interface/config/config_decode.c b/zend_abstract_interface/config/config_decode.c index 6daa3bb5f0..926567e1ca 100644 --- a/zend_abstract_interface/config/config_decode.c +++ b/zend_abstract_interface/config/config_decode.c @@ -105,7 +105,7 @@ static bool zai_config_decode_int(zai_str value, zval *decoded_value) { return true; } -static bool zai_config_decode_map(zai_str value, zval *decoded_value, bool persistent) { +static bool zai_config_decode_map(zai_str value, zval *decoded_value, bool persistent, bool lowercase) { zval tmp; ZVAL_ARR(&tmp, pemalloc(sizeof(HashTable), persistent)); zend_hash_init(Z_ARRVAL(tmp), 8, NULL, persistent ? ZVAL_INTERNAL_PTR_DTOR : ZVAL_PTR_DTOR, persistent); @@ -113,38 +113,70 @@ static bool zai_config_decode_map(zai_str value, zval *decoded_value, bool persi char *data = (char *)value.ptr; if (data && *data) { // non-empty const char *key_start, *key_end, *value_start, *value_end; + do { - if (*data != ',' && *data != ' ' && *data != '\t' && *data != '\n') { - key_start = key_end = data; - while (*++data) { + while (*data == ',' || *data == ' ' || *data == '\t' || *data == '\n') { + data++; + } + + if (*data) { + key_start = data; + key_end = NULL; + bool has_colon = false; + + while (*data && *data != ',') { if (*data == ':') { - while (*++data && (*data == ' ' || *data == '\t' || *data == '\n')) - ; - - value_start = value_end = data; - if (!*data || *data == ',') { - --value_end; // empty string instead of single char - } else { - while (*++data && *data != ',') { - if (*data != ' ' && *data != '\t' && *data != '\n') { - value_end = data; - } + has_colon = true; + + data++; + while (*data == ' ' || *data == '\t' || *data == '\n') data++; + + value_start = data; + value_end = value_start; + + while (*data && *data != ',') { + if (*data != ' ' && *data != '\t' && *data != '\n') { + value_end = data; } + data++; } size_t key_len = key_end - key_start + 1; size_t value_len = value_end - value_start + 1; - zval val; - ZVAL_NEW_STR(&val, zend_string_init(value_start, value_len, persistent)); - zend_hash_str_update(Z_ARRVAL(tmp), key_start, key_len, &val); + + if (key_len > 0 && value_len > 0) { + zend_string *key = zend_string_init(key_start, key_len, persistent); + if (lowercase) { + zend_str_tolower(ZSTR_VAL(key), ZSTR_LEN(key)); + } + + zval val; + ZVAL_NEW_STR(&val, zend_string_init(value_start, value_len, persistent)); + zend_hash_update(Z_ARRVAL(tmp), key, &val); + zend_string_release(key); + } break; } + if (*data != ' ' && *data != '\t' && *data != '\n') { key_end = data; } + data++; + } + + // Handle case without a colon (standalone key) + if (!has_colon && key_end) { + size_t key_len = key_end - key_start + 1; + zend_string *key = zend_string_init(key_start, key_len, persistent); + if (lowercase) { + zend_str_tolower(ZSTR_VAL(key), ZSTR_LEN(key)); + } + + zval val; + ZVAL_NEW_STR(&val, zend_string_copy(key)); + zend_hash_update(Z_ARRVAL(tmp), key, &val); + zend_string_release(key); } - } else { - ++data; } } while (*data); @@ -232,7 +264,9 @@ bool zai_config_decode_value(zai_str value, zai_config_type type, zai_custom_par case ZAI_CONFIG_TYPE_INT: return zai_config_decode_int(value, decoded_value); case ZAI_CONFIG_TYPE_MAP: - return zai_config_decode_map(value, decoded_value, persistent); + return zai_config_decode_map(value, decoded_value, persistent, false); + case ZAI_CONFIG_TYPE_MAP_LOWERCASE: + return zai_config_decode_map(value, decoded_value, persistent, true); case ZAI_CONFIG_TYPE_SET: return zai_config_decode_set(value, decoded_value, persistent, false); case ZAI_CONFIG_TYPE_SET_LOWERCASE: diff --git a/zend_abstract_interface/config/config_decode.h b/zend_abstract_interface/config/config_decode.h index 754bb43a01..95a12d8db6 100644 --- a/zend_abstract_interface/config/config_decode.h +++ b/zend_abstract_interface/config/config_decode.h @@ -11,6 +11,7 @@ typedef enum { ZAI_CONFIG_TYPE_DOUBLE, ZAI_CONFIG_TYPE_INT, ZAI_CONFIG_TYPE_MAP, + ZAI_CONFIG_TYPE_MAP_LOWERCASE, ZAI_CONFIG_TYPE_SET, ZAI_CONFIG_TYPE_SET_LOWERCASE, ZAI_CONFIG_TYPE_JSON, From 1b401372685525ede0f1163fc2cf76416efbe542 Mon Sep 17 00:00:00 2001 From: Gustavo Lopes Date: Tue, 5 Nov 2024 11:51:42 +0000 Subject: [PATCH 11/29] Update spdlog so it works with recent musls (#2921) https://github.com/gabime/spdlog/commit/287a00d364990edbb621fe5e392aeb550135fb96 --- appsec/src/helper/client.cpp | 3 -- appsec/src/helper/engine_settings.hpp | 28 ++++++++++-------- appsec/src/helper/json_helper.cpp | 6 ++-- appsec/src/helper/remote_config/config.hpp | 14 +++++---- appsec/src/helper/remote_config/product.hpp | 18 ++++++++---- appsec/src/helper/remote_config/settings.hpp | 15 ++++++++-- appsec/src/helper/service_config.hpp | 31 +++++++++++++++++--- appsec/src/helper/subscriber/waf.cpp | 3 +- appsec/third_party/CMakeLists.txt | 2 +- 9 files changed, 84 insertions(+), 36 deletions(-) diff --git a/appsec/src/helper/client.cpp b/appsec/src/helper/client.cpp index 545c6005bb..4e98218bb6 100644 --- a/appsec/src/helper/client.cpp +++ b/appsec/src/helper/client.cpp @@ -9,12 +9,9 @@ #include #include #include -#include #include "action.hpp" -#include "base64.h" #include "client.hpp" -#include "compression.hpp" #include "exception.hpp" #include "network/broker.hpp" #include "network/proto.hpp" diff --git a/appsec/src/helper/engine_settings.hpp b/appsec/src/helper/engine_settings.hpp index b61fc52b41..c22df8e8d0 100644 --- a/appsec/src/helper/engine_settings.hpp +++ b/appsec/src/helper/engine_settings.hpp @@ -9,7 +9,7 @@ #include "utils.hpp" #include #include -#include +#include #include namespace dds { @@ -71,21 +71,25 @@ struct engine_settings { schema_extraction.sample_rate == oth.schema_extraction.sample_rate; } +}; + +} // namespace dds - friend auto &operator<<(std::ostream &os, const engine_settings &c) +template <> struct fmt::formatter { + constexpr auto parse(format_parse_context &ctx) { return ctx.begin(); } + + template + auto format(const dds::engine_settings &c, FormatContext &ctx) const { - return os << "{rules_file=" << c.rules_file - << ", waf_timeout_us=" << c.waf_timeout_us - << ", trace_rate_limit=" << c.trace_rate_limit - << ", obfuscator_key_regex=" << c.obfuscator_key_regex - << ", obfuscator_value_regex=" << c.obfuscator_value_regex - << ", schema_extraction.enabled=" - << c.schema_extraction.enabled - << ", schema_extraction.sample_rate=" << std::fixed - << c.schema_extraction.sample_rate << "}"; + return format_to(ctx.out(), + "{{rules_file={}, waf_timeout_us={}, trace_rate_limit={}, " + "obfuscator_key_regex={}, obfuscator_value_regex={}, " + "schema_extraction.enabled={}, schema_extraction.sample_rate={}}}", + c.rules_file, c.waf_timeout_us, c.trace_rate_limit, + c.obfuscator_key_regex, c.obfuscator_value_regex, + c.schema_extraction.enabled, c.schema_extraction.sample_rate); } }; -} // namespace dds namespace std { template <> struct hash { diff --git a/appsec/src/helper/json_helper.cpp b/appsec/src/helper/json_helper.cpp index 9a785ddc7e..a9c8bc7851 100644 --- a/appsec/src/helper/json_helper.cpp +++ b/appsec/src/helper/json_helper.cpp @@ -13,6 +13,7 @@ #include #include #include +#include using namespace std::literals; @@ -176,8 +177,9 @@ json_helper::get_field_of_type(const rapidjson::Value &parent_field, } if (type != output_itr->value.GetType()) { - SPDLOG_DEBUG("Field {} is not of type {}. Instead {}", key, type, - output_itr->value.GetType()); + SPDLOG_DEBUG("Field {} is not of type {}. Instead {}", key, + fmt::underlying(type), + fmt::underlying(output_itr->value.GetType())); return std::nullopt; } diff --git a/appsec/src/helper/remote_config/config.hpp b/appsec/src/helper/remote_config/config.hpp index 05e5e226c7..d9a5707008 100644 --- a/appsec/src/helper/remote_config/config.hpp +++ b/appsec/src/helper/remote_config/config.hpp @@ -7,9 +7,9 @@ #include "../utils.hpp" #include "product.hpp" +#include #include #include -#include extern "C" { #include @@ -70,15 +70,19 @@ struct config { { return shm_path == b.shm_path && rc_path == b.rc_path; } +}; + +} // namespace dds::remote_config - friend std::ostream &operator<<(std::ostream &os, const config &c) +template <> struct fmt::formatter { + constexpr auto parse(format_parse_context &ctx) { return ctx.begin(); } + + auto format(const dds::remote_config::config &c, format_context &ctx) const { - return os << c.shm_path << ":" << c.rc_path; + return fmt::format_to(ctx.out(), "{}:{}", c.shm_path, c.rc_path); } }; -} // namespace dds::remote_config - namespace std { template <> struct hash { std::size_t operator()(const dds::remote_config::config &key) const diff --git a/appsec/src/helper/remote_config/product.hpp b/appsec/src/helper/remote_config/product.hpp index a9b70fe60f..80aeb24831 100644 --- a/appsec/src/helper/remote_config/product.hpp +++ b/appsec/src/helper/remote_config/product.hpp @@ -5,8 +5,8 @@ // (https://www.datadoghq.com/). Copyright 2021 Datadog, Inc. #pragma once -#include "../config.hpp" #include "../utils.hpp" +#include #include namespace dds::remote_config { @@ -19,11 +19,6 @@ class product { bool operator==(const product &other) const { return name_ == other.name_; } - friend std::ostream &operator<<(std::ostream &os, const product &p) - { - return os << p.name_; - } - private: std::string_view name_; }; @@ -56,6 +51,17 @@ struct known_products { }; } // namespace dds::remote_config +template <> +struct fmt::formatter + : fmt::formatter { + + auto format(const dds::remote_config::product &p, format_context &ctx) const + { + auto name = p.name(); + return formatter::format(name, ctx); + } +}; + namespace std { template <> struct hash { std::size_t operator()(const dds::remote_config::product &product) const diff --git a/appsec/src/helper/remote_config/settings.hpp b/appsec/src/helper/remote_config/settings.hpp index 43a7b8340d..5d66ff16a5 100644 --- a/appsec/src/helper/remote_config/settings.hpp +++ b/appsec/src/helper/remote_config/settings.hpp @@ -7,10 +7,9 @@ #pragma once #include "../utils.hpp" -#include -#include #include #include +#include #include namespace dds::remote_config { @@ -32,8 +31,20 @@ struct settings { MSGPACK_DEFINE_MAP(enabled, shmem_path); }; + } // namespace dds::remote_config +template <> struct fmt::formatter { + constexpr auto parse(fmt::format_parse_context &ctx) { return ctx.begin(); } + + template + auto format(const dds::remote_config::settings &s, FormatContext &ctx) const + { + return fmt::format_to(ctx.out(), "{{enabled={}, shmem_path={}}}", + s.enabled, s.shmem_path); + } +}; + namespace std { template <> struct hash { std::size_t operator()(const dds::remote_config::settings &s) const noexcept diff --git a/appsec/src/helper/service_config.hpp b/appsec/src/helper/service_config.hpp index 50f277fb45..7e2684e779 100644 --- a/appsec/src/helper/service_config.hpp +++ b/appsec/src/helper/service_config.hpp @@ -6,14 +6,37 @@ #pragma once #include -#include -#include #include -#include namespace dds { - enum class enable_asm_status : unsigned { NOT_SET = 0, ENABLED, DISABLED }; +} // namespace dds + +template <> +struct fmt::formatter> + : fmt::formatter { + auto format(const std::atomic &status, + format_context &ctx) const + { + auto val = status.load(); + std::string_view name{"UNKNOWN"}; + switch (val) { + case dds::enable_asm_status::NOT_SET: + name = "NOT_SET"; + break; + case dds::enable_asm_status::ENABLED: + name = "ENABLED"; + break; + case dds::enable_asm_status::DISABLED: + name = "DISABLED"; + break; + } + + return fmt::formatter::format(name, ctx); + } +}; + +namespace dds { inline std::string_view to_string_view(enable_asm_status status) { diff --git a/appsec/src/helper/subscriber/waf.cpp b/appsec/src/helper/subscriber/waf.cpp index 0b843f63a7..edffb4691e 100644 --- a/appsec/src/helper/subscriber/waf.cpp +++ b/appsec/src/helper/subscriber/waf.cpp @@ -218,7 +218,8 @@ void instance::listener::call(dds::parameter_view &data, event &event) parameter_to_json(parameter_view{res.events}), res.total_runtime / millis); SPDLOG_DEBUG("Waf response: code {} - actions {} - derivatives {}", - code, parameter_to_json(parameter_view{res.actions}), + fmt::underlying(code), + parameter_to_json(parameter_view{res.actions}), parameter_to_json(parameter_view{res.derivatives})); } else { diff --git a/appsec/third_party/CMakeLists.txt b/appsec/third_party/CMakeLists.txt index d925ea6a5f..5a7a5c9faa 100644 --- a/appsec/third_party/CMakeLists.txt +++ b/appsec/third_party/CMakeLists.txt @@ -45,7 +45,7 @@ endif() FetchContent_Declare( spdlog GIT_REPOSITORY https://github.com/gabime/spdlog.git - GIT_TAG eb3220622e73a4889eee355ffa37972b3cac3df5) + GIT_TAG 5fd32e1a70871e2f6a52734e36bc33cb7ac022a5) FetchContent_MakeAvailable(spdlog) set_target_properties(spdlog PROPERTIES POSITION_INDEPENDENT_CODE 1) From 7b3c423294d283340e9f781ca7ce7138be8e9f1c Mon Sep 17 00:00:00 2001 From: Maximo Bautista Date: Tue, 5 Nov 2024 13:44:19 -0500 Subject: [PATCH 12/29] Using lowercase condition for new map and empty value for keyless header --- ext/serializer.c | 6 +++--- tests/Unit/ConfigurationTest.php | 4 ++-- zend_abstract_interface/config/config_decode.c | 6 +++--- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/ext/serializer.c b/ext/serializer.c index 705c944559..328e140ed8 100644 --- a/ext/serializer.c +++ b/ext/serializer.c @@ -328,13 +328,13 @@ static void dd_add_header_to_meta(zend_array *meta, const char *type, zend_strin if (header_config != NULL && Z_TYPE_P(header_config) == IS_STRING) { zend_string *header_config_str = Z_STR_P(header_config); zend_string *headertag; - if (zend_string_equals(header_config_str, lowerheader)) { - for (char *ptr = ZSTR_VAL(header_config_str); *ptr; ++ptr) { + if (ZSTR_LEN(header_config_str) == 0) { + for (char *ptr = ZSTR_VAL(lowerheader); *ptr; ++ptr) { if ((*ptr < 'a' || *ptr > 'z') && *ptr != '-' && (*ptr < '0' || *ptr > '9')) { *ptr = '_'; } } - headertag = zend_strpprintf(0, "http.%s.headers.%s", type, ZSTR_VAL(header_config_str)); + headertag = zend_strpprintf(0, "http.%s.headers.%s", type, ZSTR_VAL(lowerheader)); } else { headertag = zend_string_copy(header_config_str); } diff --git a/tests/Unit/ConfigurationTest.php b/tests/Unit/ConfigurationTest.php index b810e5cb81..eb0100c353 100644 --- a/tests/Unit/ConfigurationTest.php +++ b/tests/Unit/ConfigurationTest.php @@ -260,7 +260,7 @@ public function testGlobalTags() public function testGlobalTagsWrongValueJustResultsInNoTags() { $this->putEnvAndReloadConfig(['DD_TAGS=wrong_key_value']); - $this->assertEquals(['wrong_key_value' => 'wrong_key_value'], \dd_trace_env_config("DD_TAGS")); + $this->assertEquals([], \dd_trace_env_config("DD_TAGS")); } public function testHttpHeadersDefaultsToEmpty() @@ -284,6 +284,6 @@ public function testHttpHeadersCanSetMultiple() // Same behavior as python tracer: // https://github.com/DataDog/dd-trace-py/blob/f1298cb8100f146059f978b58c88641bd7424af8/ddtrace/http/headers.py $this->assertSame(['a-header', 'any-name', 'con7aining-!spe_cial?', 'some-heather'], array_keys(\dd_trace_env_config("DD_TRACE_HEADER_TAGS"))); - $this->assertEquals(['a-header' => 'a-header', 'any-name' => 'any-name', 'con7aining-!spe_cial?' => 'ch/ars', 'some-heather' => 'with-colon-Key'], \dd_trace_env_config("DD_TRACE_HEADER_TAGS")); + $this->assertEquals(['a-header' => '', 'any-name' => '', 'con7aining-!spe_cial?' => 'ch/ars', 'some-heather' => 'with-colon-Key'], \dd_trace_env_config("DD_TRACE_HEADER_TAGS")); } } diff --git a/zend_abstract_interface/config/config_decode.c b/zend_abstract_interface/config/config_decode.c index 926567e1ca..6a56a96adc 100644 --- a/zend_abstract_interface/config/config_decode.c +++ b/zend_abstract_interface/config/config_decode.c @@ -164,8 +164,8 @@ static bool zai_config_decode_map(zai_str value, zval *decoded_value, bool persi data++; } - // Handle case without a colon (standalone key) - if (!has_colon && key_end) { + // Handle case without a colon (standalone key) only when lowercase is true which is current use case + if (lowercase && !has_colon && key_end) { size_t key_len = key_end - key_start + 1; zend_string *key = zend_string_init(key_start, key_len, persistent); if (lowercase) { @@ -173,7 +173,7 @@ static bool zai_config_decode_map(zai_str value, zval *decoded_value, bool persi } zval val; - ZVAL_NEW_STR(&val, zend_string_copy(key)); + ZVAL_EMPTY_STRING(&val); zend_hash_update(Z_ARRVAL(tmp), key, &val); zend_string_release(key); } From adf82cea48e276f37dc628118e5497da0ecb5869 Mon Sep 17 00:00:00 2001 From: Gustavo Lopes Date: Tue, 5 Nov 2024 18:50:21 +0000 Subject: [PATCH 13/29] Fix heap corruption after apache reloads (appsec) --- appsec/src/extension/ddtrace.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/appsec/src/extension/ddtrace.c b/appsec/src/extension/ddtrace.c index f26927803b..deff440f7e 100644 --- a/appsec/src/extension/ddtrace.c +++ b/appsec/src/extension/ddtrace.c @@ -157,7 +157,7 @@ static zend_module_entry *_find_ddtrace_module() void dd_trace_shutdown() { zend_module_entry *mod = _find_ddtrace_module(); - if (mod) { + if (mod && _orig_ddtrace_shutdown) { mod->request_shutdown_func = _orig_ddtrace_shutdown; } _orig_ddtrace_shutdown = NULL; From 92dac2b66ac4bc4fb1717a65a4d30e5aba291162 Mon Sep 17 00:00:00 2001 From: Maximo Bautista Date: Fri, 25 Oct 2024 17:51:32 -0400 Subject: [PATCH 14/29] updating default and depending on sample rate --- ext/configuration.h | 2 +- ext/limiter/limiter.c | 4 ++++ tests/ext/limiter/001-limiter-disabled.phpt | 1 + tests/ext/limiter/002-limiter-reached.phpt | 1 + 4 files changed, 7 insertions(+), 1 deletion(-) diff --git a/ext/configuration.h b/ext/configuration.h index 57dd53cc7e..1208433253 100644 --- a/ext/configuration.h +++ b/ext/configuration.h @@ -149,7 +149,7 @@ enum ddtrace_sampling_rules_format { CONFIG(SET, DD_TRACE_RESOURCE_URI_QUERY_PARAM_ALLOWED, "") \ CONFIG(SET, DD_TRACE_HTTP_URL_QUERY_PARAM_ALLOWED, "*") \ CONFIG(SET, DD_TRACE_HTTP_POST_DATA_PARAM_ALLOWED, "") \ - CONFIG(INT, DD_TRACE_RATE_LIMIT, "0", .ini_change = zai_config_system_ini_change) \ + CONFIG(INT, DD_TRACE_RATE_LIMIT, "100", .ini_change = zai_config_system_ini_change) \ CONFIG(DOUBLE, DD_TRACE_SAMPLE_RATE, "-1", .ini_change = ddtrace_alter_DD_TRACE_SAMPLE_RATE, \ .env_config_fallback = ddtrace_conf_otel_sample_rate) \ CONFIG(JSON, DD_TRACE_SAMPLING_RULES, "[]") \ diff --git a/ext/limiter/limiter.c b/ext/limiter/limiter.c index 389a16bf60..cc6db08a1c 100644 --- a/ext/limiter/limiter.c +++ b/ext/limiter/limiter.c @@ -27,6 +27,10 @@ static ddtrace_limiter* dd_limiter; void ddtrace_limiter_create() { + if (zai_config_memoized_entries[DDTRACE_CONFIG_DD_TRACE_SAMPLE_RATE].name_index < 0) { + return; + } + uint32_t limit = (uint32_t) get_global_DD_TRACE_RATE_LIMIT(); if (!limit) { diff --git a/tests/ext/limiter/001-limiter-disabled.phpt b/tests/ext/limiter/001-limiter-disabled.phpt index bfa5f0d2d6..652e677f98 100644 --- a/tests/ext/limiter/001-limiter-disabled.phpt +++ b/tests/ext/limiter/001-limiter-disabled.phpt @@ -3,6 +3,7 @@ rate limiter disabled --ENV-- DD_TRACE_GENERATE_ROOT_SPAN=1 DD_TRACE_RATE_LIMIT=0 +DD_TRACE_SAMPLE_RATE=1 --FILE-- Date: Tue, 5 Nov 2024 20:21:03 +0100 Subject: [PATCH 15/29] Update zend_abstract_interface/uri_normalization/uri_normalization.c --- zend_abstract_interface/uri_normalization/uri_normalization.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/zend_abstract_interface/uri_normalization/uri_normalization.c b/zend_abstract_interface/uri_normalization/uri_normalization.c index 6bf2508181..09e25e172f 100644 --- a/zend_abstract_interface/uri_normalization/uri_normalization.c +++ b/zend_abstract_interface/uri_normalization/uri_normalization.c @@ -157,7 +157,7 @@ zend_string *zai_filter_query_string(zai_str queryString, zend_array *whitelist, zend_hash_get_current_key(whitelist, &str, &numkey); if (zend_string_equals_literal(str, "*")) { zend_string *qs = zend_string_init(queryString.ptr, queryString.len, 0); - if (ZSTR_LEN(pattern)) { + if (pattern && ZSTR_LEN(pattern)) { zend_string *replacement = zend_string_init(ZEND_STRL(""), 0); smart_str regex = {0}; From e1d305bd50041f9ce1cbc0bed0595988add35321 Mon Sep 17 00:00:00 2001 From: Maximo Bautista Date: Tue, 5 Nov 2024 17:16:13 -0500 Subject: [PATCH 16/29] Adding easy nits --- ext/configuration.h | 6 +++--- zend_abstract_interface/config/config_decode.c | 10 +++++----- zend_abstract_interface/config/config_decode.h | 2 +- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/ext/configuration.h b/ext/configuration.h index ccc4f549e6..e94d885b7a 100644 --- a/ext/configuration.h +++ b/ext/configuration.h @@ -156,7 +156,7 @@ enum ddtrace_sampling_rules_format { CONFIG(CUSTOM(INT), DD_TRACE_SAMPLING_RULES_FORMAT, "glob", .parser = dd_parse_sampling_rules_format) \ CONFIG(JSON, DD_SPAN_SAMPLING_RULES, "[]") \ CONFIG(STRING, DD_SPAN_SAMPLING_RULES_FILE, "", .ini_change = ddtrace_alter_sampling_rules_file_config) \ - CONFIG(MAP_LOWERCASE, DD_TRACE_HEADER_TAGS, "", .ini_change = ddtrace_alter_DD_TRACE_HEADER_TAGS) \ + CONFIG(SET_OR_MAP_LOWERCASE, DD_TRACE_HEADER_TAGS, "", .ini_change = ddtrace_alter_DD_TRACE_HEADER_TAGS) \ CONFIG(INT, DD_TRACE_X_DATADOG_TAGS_MAX_LENGTH, "512") \ CONFIG(MAP, DD_TRACE_PEER_SERVICE_MAPPING, "") \ CONFIG(BOOL, DD_TRACE_PEER_SERVICE_DEFAULTS_ENABLED, "false") \ @@ -274,7 +274,7 @@ typedef enum { DD_CONFIGURATION } ddtrace_config_id; } #define SET MAP #define SET_LOWERCASE MAP -#define MAP_LOWERCASE MAP +#define SET_OR_MAP_LOWERCASE MAP #define JSON MAP #define MAP(id) \ static inline zend_array *get_##id(void) { return Z_ARR_P(zai_config_get_value(DDTRACE_CONFIG_##id)); } \ @@ -293,9 +293,9 @@ static inline bool get_global_DD_TRACE_SIDECAR_TRACE_SENDER(void) { return true; #undef STRING #undef MAP -#undef MAP_LOWERCASE #undef SET #undef SET_LOWERCASE +#undef SET_OR_MAP_LOWERCASE #undef JSON #undef BOOL #undef INT diff --git a/zend_abstract_interface/config/config_decode.c b/zend_abstract_interface/config/config_decode.c index 6a56a96adc..b94156d3e0 100644 --- a/zend_abstract_interface/config/config_decode.c +++ b/zend_abstract_interface/config/config_decode.c @@ -105,7 +105,7 @@ static bool zai_config_decode_int(zai_str value, zval *decoded_value) { return true; } -static bool zai_config_decode_map(zai_str value, zval *decoded_value, bool persistent, bool lowercase) { +static bool zai_config_decode_map(zai_str value, zval *decoded_value, bool persistent, bool lowercase, bool map_keyless) { zval tmp; ZVAL_ARR(&tmp, pemalloc(sizeof(HashTable), persistent)); zend_hash_init(Z_ARRVAL(tmp), 8, NULL, persistent ? ZVAL_INTERNAL_PTR_DTOR : ZVAL_PTR_DTOR, persistent); @@ -165,7 +165,7 @@ static bool zai_config_decode_map(zai_str value, zval *decoded_value, bool persi } // Handle case without a colon (standalone key) only when lowercase is true which is current use case - if (lowercase && !has_colon && key_end) { + if (map_keyless && !has_colon && key_end) { size_t key_len = key_end - key_start + 1; zend_string *key = zend_string_init(key_start, key_len, persistent); if (lowercase) { @@ -264,9 +264,9 @@ bool zai_config_decode_value(zai_str value, zai_config_type type, zai_custom_par case ZAI_CONFIG_TYPE_INT: return zai_config_decode_int(value, decoded_value); case ZAI_CONFIG_TYPE_MAP: - return zai_config_decode_map(value, decoded_value, persistent, false); - case ZAI_CONFIG_TYPE_MAP_LOWERCASE: - return zai_config_decode_map(value, decoded_value, persistent, true); + return zai_config_decode_map(value, decoded_value, persistent, false, false); + case ZAI_CONFIG_TYPE_SET_OR_MAP_LOWERCASE: + return zai_config_decode_map(value, decoded_value, persistent, true, true); case ZAI_CONFIG_TYPE_SET: return zai_config_decode_set(value, decoded_value, persistent, false); case ZAI_CONFIG_TYPE_SET_LOWERCASE: diff --git a/zend_abstract_interface/config/config_decode.h b/zend_abstract_interface/config/config_decode.h index 95a12d8db6..c811b37df2 100644 --- a/zend_abstract_interface/config/config_decode.h +++ b/zend_abstract_interface/config/config_decode.h @@ -11,9 +11,9 @@ typedef enum { ZAI_CONFIG_TYPE_DOUBLE, ZAI_CONFIG_TYPE_INT, ZAI_CONFIG_TYPE_MAP, - ZAI_CONFIG_TYPE_MAP_LOWERCASE, ZAI_CONFIG_TYPE_SET, ZAI_CONFIG_TYPE_SET_LOWERCASE, + ZAI_CONFIG_TYPE_SET_OR_MAP_LOWERCASE, ZAI_CONFIG_TYPE_JSON, ZAI_CONFIG_TYPE_STRING, ZAI_CONFIG_TYPE_CUSTOM, From ea54b0ed35e6d57da4057583551a871261b6d34a Mon Sep 17 00:00:00 2001 From: Maximo Bautista Date: Tue, 5 Nov 2024 20:16:20 -0500 Subject: [PATCH 17/29] Updated to take into account empty string after colon and safer use of ZVAL methods --- tests/Unit/ConfigurationTest.php | 8 ++- .../config/config_decode.c | 51 +++++++++++++------ 2 files changed, 38 insertions(+), 21 deletions(-) diff --git a/tests/Unit/ConfigurationTest.php b/tests/Unit/ConfigurationTest.php index eb0100c353..c96ceaacb3 100644 --- a/tests/Unit/ConfigurationTest.php +++ b/tests/Unit/ConfigurationTest.php @@ -279,11 +279,9 @@ public function testHttpHeadersCanSetOne() public function testHttpHeadersCanSetMultiple() { $this->putEnvAndReloadConfig([ - 'DD_TRACE_HEADER_TAGS=A-Header ,Any-Name , cOn7aining-!spe_cial?:ch/ars , Some-Heather:with-colon-Key', + 'DD_TRACE_HEADER_TAGS=A-Header ,Any-Name , cOn7aining-!spe_cial?:ch/ars , valueless:, Some-Header:with-colon-Key', ]); - // Same behavior as python tracer: - // https://github.com/DataDog/dd-trace-py/blob/f1298cb8100f146059f978b58c88641bd7424af8/ddtrace/http/headers.py - $this->assertSame(['a-header', 'any-name', 'con7aining-!spe_cial?', 'some-heather'], array_keys(\dd_trace_env_config("DD_TRACE_HEADER_TAGS"))); - $this->assertEquals(['a-header' => '', 'any-name' => '', 'con7aining-!spe_cial?' => 'ch/ars', 'some-heather' => 'with-colon-Key'], \dd_trace_env_config("DD_TRACE_HEADER_TAGS")); + $this->assertSame(['a-header', 'any-name', 'con7aining-!spe_cial?', 'valueless', 'some-header'], array_keys(\dd_trace_env_config("DD_TRACE_HEADER_TAGS"))); + $this->assertEquals(['a-header' => '', 'any-name' => '', 'con7aining-!spe_cial?' => 'ch/ars', 'valueless' => '', 'some-header' => 'with-colon-Key'], \dd_trace_env_config("DD_TRACE_HEADER_TAGS")); } } diff --git a/zend_abstract_interface/config/config_decode.c b/zend_abstract_interface/config/config_decode.c index b94156d3e0..aa2080bfec 100644 --- a/zend_abstract_interface/config/config_decode.c +++ b/zend_abstract_interface/config/config_decode.c @@ -113,7 +113,7 @@ static bool zai_config_decode_map(zai_str value, zval *decoded_value, bool persi char *data = (char *)value.ptr; if (data && *data) { // non-empty const char *key_start, *key_end, *value_start, *value_end; - + do { while (*data == ',' || *data == ' ' || *data == '\t' || *data == '\n') { data++; @@ -127,45 +127,59 @@ static bool zai_config_decode_map(zai_str value, zval *decoded_value, bool persi while (*data && *data != ',') { if (*data == ':') { has_colon = true; - data++; + while (*data == ' ' || *data == '\t' || *data == '\n') data++; - value_start = data; - value_end = value_start; - - while (*data && *data != ',') { - if (*data != ' ' && *data != '\t' && *data != '\n') { - value_end = data; + if (*data == ',' || *data == '\0') { + value_start = value_end = NULL; + } else { + value_start = data; + value_end = value_start; + + while (*data && *data != ',') { + if (*data != ' ' && *data != '\t' && *data != '\n') { + value_end = data; + } + data++; } - data++; } - size_t key_len = key_end - key_start + 1; - size_t value_len = value_end - value_start + 1; + if (key_end && key_start) { + size_t key_len = key_end - key_start + 1; + size_t value_len = (value_end && value_start) ? (value_end - value_start + 1) : 0; - if (key_len > 0 && value_len > 0) { zend_string *key = zend_string_init(key_start, key_len, persistent); if (lowercase) { zend_str_tolower(ZSTR_VAL(key), ZSTR_LEN(key)); } zval val; - ZVAL_NEW_STR(&val, zend_string_init(value_start, value_len, persistent)); + if (value_len > 0) { + ZVAL_NEW_STR(&val, zend_string_init(value_start, value_len, persistent)); + } else { + if (persistent) { + ZVAL_EMPTY_PSTRING(&val); + } else { + ZVAL_EMPTY_STRING(&val); + } + } zend_hash_update(Z_ARRVAL(tmp), key, &val); zend_string_release(key); } + break; } + // Set key_end to the last valid non-whitespace character of the key if (*data != ' ' && *data != '\t' && *data != '\n') { key_end = data; } data++; } - // Handle case without a colon (standalone key) only when lowercase is true which is current use case - if (map_keyless && !has_colon && key_end) { + // Handle standalone keys (without a colon) if map_keyless is enabled + if (map_keyless && !has_colon && key_end && key_start) { size_t key_len = key_end - key_start + 1; zend_string *key = zend_string_init(key_start, key_len, persistent); if (lowercase) { @@ -173,13 +187,18 @@ static bool zai_config_decode_map(zai_str value, zval *decoded_value, bool persi } zval val; - ZVAL_EMPTY_STRING(&val); + if (persistent) { + ZVAL_EMPTY_PSTRING(&val); + } else { + ZVAL_EMPTY_STRING(&val); + } zend_hash_update(Z_ARRVAL(tmp), key, &val); zend_string_release(key); } } } while (*data); + // Check if the array has any elements; if not, cleanup if (zend_hash_num_elements(Z_ARRVAL(tmp)) == 0) { zend_hash_destroy(Z_ARRVAL(tmp)); pefree(Z_ARRVAL(tmp), persistent); From 0e77db06bd7b8765552d45996b6e23af48a6ba74 Mon Sep 17 00:00:00 2001 From: Alexandre Choura <42672104+PROFeNoM@users.noreply.github.com> Date: Wed, 6 Nov 2024 13:48:43 +0100 Subject: [PATCH 18/29] tests: Remove version from OpenAI snapshots child spans (#2929) * tests: Remove version from OpenAI snapshots child spans * tests: Remove version from one OpenAI metric snapshot * tests: Remove version from one OpenAI snapshot * tests: Remove version from one OpenAI logs snapshot --- ...tions.open_ai.open_ai_test.test_open_ai_service.txt | 2 +- ...tions.open_ai.open_ai_test.test_open_ai_service.txt | 10 +++++----- ...ons.open_ai.open_ai_test.test_cancel_fine_tune.json | 3 +-- ...en_ai.open_ai_test.test_create_chat_completion.json | 3 +-- ...pen_ai_test.test_create_chat_completion_stream.json | 3 +-- ....test_create_chat_completion_stream_with_error.json | 3 +-- ...est.test_create_chat_completion_with_functions.json | 3 +-- ...t.test_create_chat_completion_with_image_input.json | 3 +-- ...est_create_chat_completion_with_multiple_roles.json | 3 +-- ...ns.open_ai.open_ai_test.test_create_completion.json | 3 +-- ..._ai.open_ai_test.test_create_completion_stream.json | 3 +-- ...reate_completions_with_multiple_error_messages.json | 3 +-- ...ons.open_ai.open_ai_test.test_create_embedding.json | 3 +-- ...est.test_create_embedding_with_multiple_inputs.json | 3 +-- ...grations.open_ai.open_ai_test.test_create_file.json | 3 +-- ...rations.open_ai.open_ai_test.test_create_image.json | 3 +-- ...ns.open_ai.open_ai_test.test_create_image_edit.json | 3 +-- ...en_ai.open_ai_test.test_create_image_variation.json | 3 +-- ...ns.open_ai.open_ai_test.test_create_moderation.json | 3 +-- ...open_ai_test.test_create_transcription_to_json.json | 3 +-- ...open_ai_test.test_create_transcription_to_text.json | 3 +-- ...test.test_create_transcription_to_verbose_json.json | 3 +-- ...i.open_ai_test.test_create_translation_to_json.json | 3 +-- ...i.open_ai_test.test_create_translation_to_text.json | 3 +-- ...i_test.test_create_translation_to_verbose_json.json | 3 +-- ...grations.open_ai.open_ai_test.test_delete_file.json | 3 +-- ...rations.open_ai.open_ai_test.test_delete_model.json | 3 +-- ...ations.open_ai.open_ai_test.test_download_file.json | 3 +-- ...egrations.open_ai.open_ai_test.test_list_files.json | 3 +-- ...pen_ai.open_ai_test.test_list_fine_tune_events.json | 3 +-- ...open_ai_test.test_list_fine_tune_events_stream.json | 3 +-- ...grations.open_ai.open_ai_test.test_list_models.json | 3 +-- ...en_ai.open_ai_test.test_list_models_with_error.json | 3 +-- ..._ai_test.test_list_models_with_null_error_type.json | 3 +-- ...ai_test.test_log_prompt_completion_sample_rate.json | 3 +-- ...ations.open_ai.open_ai_test.test_logs_disabled.json | 3 +-- ...ons.open_ai.open_ai_test.test_metrics_disabled.json | 3 +-- ...ions.open_ai.open_ai_test.test_open_ai_service.json | 6 ++---- ...ations.open_ai.open_ai_test.test_retrieve_file.json | 3 +-- ...s.open_ai.open_ai_test.test_retrieve_fine_tune.json | 3 +-- ...tions.open_ai.open_ai_test.test_retrieve_model.json | 3 +-- ...ions.open_ai.open_ai_test.test_span_char_limit.json | 3 +-- ...i_test.test_span_prompt_completion_sample_rate.json | 3 +-- 43 files changed, 48 insertions(+), 90 deletions(-) diff --git a/tests/snapshots/logs/tests.integrations.open_ai.open_ai_test.test_open_ai_service.txt b/tests/snapshots/logs/tests.integrations.open_ai.open_ai_test.test_open_ai_service.txt index d79ca1a1c9..a8caede28c 100644 --- a/tests/snapshots/logs/tests.integrations.open_ai.open_ai_test.test_open_ai_service.txt +++ b/tests/snapshots/logs/tests.integrations.open_ai.open_ai_test.test_open_ai_service.txt @@ -1 +1 @@ -{"message":"sampled listModels","status":"info","timestamp":"2024-07-18T07:58:56.301000+00:00","env":"test","version":"1.0","service":"openai","openai.request.method":"GET","openai.request.endpoint":"\/v1\/models","openai.organization.name":"org-1234","openai.user.api_key":"sk-...9d5d","dd.trace_id":"7579939180383610820","dd.span_id":"7579939180383610820"} \ No newline at end of file +{"message":"sampled listModels","status":"info","timestamp":"2024-07-18T07:58:56.301000+00:00","env":"test","service":"openai","openai.request.method":"GET","openai.request.endpoint":"\/v1\/models","openai.organization.name":"org-1234","openai.user.api_key":"sk-...9d5d","dd.trace_id":"7579939180383610820","dd.span_id":"7579939180383610820"} diff --git a/tests/snapshots/metrics/tests.integrations.open_ai.open_ai_test.test_open_ai_service.txt b/tests/snapshots/metrics/tests.integrations.open_ai.open_ai_test.test_open_ai_service.txt index 13f79afb8c..ea00470453 100644 --- a/tests/snapshots/metrics/tests.integrations.open_ai.open_ai_test.test_open_ai_service.txt +++ b/tests/snapshots/metrics/tests.integrations.open_ai.open_ai_test.test_open_ai_service.txt @@ -1,5 +1,5 @@ -openai.request.duration:205208|d|#env:test,service:openai,version:1.0,env:test,service:openai,version:1.0,openai.organization.name:org-1234,openai.user.api_key:sk-...9d5d,openai.request.endpoint:/v1/models -openai.ratelimit.requests:3000|g|#env:test,service:openai,version:1.0,env:test,service:openai,version:1.0,openai.organization.name:org-1234,openai.user.api_key:sk-...9d5d,openai.request.endpoint:/v1/models -openai.ratelimit.tokens:250000|g|#env:test,service:openai,version:1.0,env:test,service:openai,version:1.0,openai.organization.name:org-1234,openai.user.api_key:sk-...9d5d,openai.request.endpoint:/v1/models -openai.ratelimit.remaining.requests:2999|g|#env:test,service:openai,version:1.0,env:test,service:openai,version:1.0,openai.organization.name:org-1234,openai.user.api_key:sk-...9d5d,openai.request.endpoint:/v1/models -openai.ratelimit.remaining.tokens:249989|g|#env:test,service:openai,version:1.0,env:test,service:openai,version:1.0,openai.organization.name:org-1234,openai.user.api_key:sk-...9d5d,openai.request.endpoint:/v1/models +openai.request.duration:205208|d|#env:test,service:openai,env:test,service:openai,openai.organization.name:org-1234,openai.user.api_key:sk-...9d5d,openai.request.endpoint:/v1/models +openai.ratelimit.requests:3000|g|#env:test,service:openai,env:test,service:openai,openai.organization.name:org-1234,openai.user.api_key:sk-...9d5d,openai.request.endpoint:/v1/models +openai.ratelimit.tokens:250000|g|#env:test,service:openai,env:test,service:openai,openai.organization.name:org-1234,openai.user.api_key:sk-...9d5d,openai.request.endpoint:/v1/models +openai.ratelimit.remaining.requests:2999|g|#env:test,service:openai,env:test,service:openai,openai.organization.name:org-1234,openai.user.api_key:sk-...9d5d,openai.request.endpoint:/v1/models +openai.ratelimit.remaining.tokens:249989|g|#env:test,service:openai,env:test,service:openai,openai.organization.name:org-1234,openai.user.api_key:sk-...9d5d,openai.request.endpoint:/v1/models diff --git a/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_cancel_fine_tune.json b/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_cancel_fine_tune.json index b8d8cc6998..136e6937fb 100644 --- a/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_cancel_fine_tune.json +++ b/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_cancel_fine_tune.json @@ -59,7 +59,6 @@ "http.status_code": "200", "http.url": "https://api.openai.com/v1/fine-tunes/ftjob-AF1WoRqd3aJAHsqc9NY7iL8F/cancel?foo=bar", "network.destination.name": "api.openai.com", - "span.kind": "client", - "version": "1.0" + "span.kind": "client" } }]] diff --git a/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_create_chat_completion.json b/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_create_chat_completion.json index 63bb9fc77b..72c9094bcb 100644 --- a/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_create_chat_completion.json +++ b/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_create_chat_completion.json @@ -56,7 +56,6 @@ "http.status_code": "200", "http.url": "https://api.openai.com/v1/chat/completions?foo=bar", "network.destination.name": "api.openai.com", - "span.kind": "client", - "version": "1.0" + "span.kind": "client" } }]] diff --git a/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_create_chat_completion_stream.json b/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_create_chat_completion_stream.json index 8fce4d8bbb..b6e7c27d60 100644 --- a/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_create_chat_completion_stream.json +++ b/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_create_chat_completion_stream.json @@ -52,7 +52,6 @@ "http.status_code": "200", "http.url": "https://api.openai.com/v1/chat/completions?foo=bar", "network.destination.name": "api.openai.com", - "span.kind": "client", - "version": "1.0" + "span.kind": "client" } }]] diff --git a/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_create_chat_completion_stream_with_error.json b/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_create_chat_completion_stream_with_error.json index 948c7b2782..d184ae3142 100644 --- a/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_create_chat_completion_stream_with_error.json +++ b/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_create_chat_completion_stream_with_error.json @@ -53,7 +53,6 @@ "http.status_code": "200", "http.url": "https://api.openai.com/v1/chat/completions?foo=bar", "network.destination.name": "api.openai.com", - "span.kind": "client", - "version": "1.0" + "span.kind": "client" } }]] diff --git a/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_create_chat_completion_with_functions.json b/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_create_chat_completion_with_functions.json index ded6a74cb3..518404b54c 100644 --- a/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_create_chat_completion_with_functions.json +++ b/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_create_chat_completion_with_functions.json @@ -55,7 +55,6 @@ "http.status_code": "200", "http.url": "https://api.openai.com/v1/chat/completions?foo=bar", "network.destination.name": "api.openai.com", - "span.kind": "client", - "version": "1.0" + "span.kind": "client" } }]] diff --git a/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_create_chat_completion_with_image_input.json b/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_create_chat_completion_with_image_input.json index c91a34df88..63f6eb739f 100644 --- a/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_create_chat_completion_with_image_input.json +++ b/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_create_chat_completion_with_image_input.json @@ -57,7 +57,6 @@ "http.status_code": "200", "http.url": "https://api.openai.com/v1/chat/completions?foo=bar", "network.destination.name": "api.openai.com", - "span.kind": "client", - "version": "1.0" + "span.kind": "client" } }]] diff --git a/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_create_chat_completion_with_multiple_roles.json b/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_create_chat_completion_with_multiple_roles.json index 3b616a32f3..09c532c79a 100644 --- a/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_create_chat_completion_with_multiple_roles.json +++ b/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_create_chat_completion_with_multiple_roles.json @@ -58,7 +58,6 @@ "http.status_code": "200", "http.url": "https://api.openai.com/v1/chat/completions?foo=bar", "network.destination.name": "api.openai.com", - "span.kind": "client", - "version": "1.0" + "span.kind": "client" } }]] diff --git a/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_create_completion.json b/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_create_completion.json index 2597592cc7..7ec60a75d4 100644 --- a/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_create_completion.json +++ b/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_create_completion.json @@ -56,7 +56,6 @@ "http.status_code": "200", "http.url": "https://api.openai.com/v1/completions?foo=bar", "network.destination.name": "api.openai.com", - "span.kind": "client", - "version": "1.0" + "span.kind": "client" } }]] diff --git a/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_create_completion_stream.json b/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_create_completion_stream.json index 2cb0e09ae9..ea4741afd8 100644 --- a/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_create_completion_stream.json +++ b/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_create_completion_stream.json @@ -52,7 +52,6 @@ "http.status_code": "200", "http.url": "https://api.openai.com/v1/completions?foo=bar", "network.destination.name": "api.openai.com", - "span.kind": "client", - "version": "1.0" + "span.kind": "client" } }]] diff --git a/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_create_completions_with_multiple_error_messages.json b/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_create_completions_with_multiple_error_messages.json index e5f86487cd..2257b15781 100644 --- a/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_create_completions_with_multiple_error_messages.json +++ b/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_create_completions_with_multiple_error_messages.json @@ -46,7 +46,6 @@ "http.status_code": "404", "http.url": "https://api.openai.com/v1/completions?foo=bar", "network.destination.name": "api.openai.com", - "span.kind": "client", - "version": "1.0" + "span.kind": "client" } }]] diff --git a/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_create_embedding.json b/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_create_embedding.json index 94ba4f0d53..46ff1160b2 100644 --- a/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_create_embedding.json +++ b/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_create_embedding.json @@ -52,7 +52,6 @@ "http.status_code": "200", "http.url": "https://api.openai.com/v1/embeddings?foo=bar", "network.destination.name": "api.openai.com", - "span.kind": "client", - "version": "1.0" + "span.kind": "client" } }]] diff --git a/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_create_embedding_with_multiple_inputs.json b/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_create_embedding_with_multiple_inputs.json index 668232b82f..3c3bc2447b 100644 --- a/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_create_embedding_with_multiple_inputs.json +++ b/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_create_embedding_with_multiple_inputs.json @@ -53,7 +53,6 @@ "http.status_code": "200", "http.url": "https://api.openai.com/v1/embeddings?foo=bar", "network.destination.name": "api.openai.com", - "span.kind": "client", - "version": "1.0" + "span.kind": "client" } }]] diff --git a/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_create_file.json b/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_create_file.json index a42bbeeed1..684ac5cfa7 100644 --- a/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_create_file.json +++ b/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_create_file.json @@ -52,7 +52,6 @@ "http.status_code": "200", "http.url": "https://api.openai.com/v1/files?foo=bar", "network.destination.name": "api.openai.com", - "span.kind": "client", - "version": "1.0" + "span.kind": "client" } }]] diff --git a/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_create_image.json b/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_create_image.json index 86d1a298d0..a6361491f3 100644 --- a/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_create_image.json +++ b/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_create_image.json @@ -51,7 +51,6 @@ "http.status_code": "200", "http.url": "https://api.openai.com/v1/images/generations?foo=bar", "network.destination.name": "api.openai.com", - "span.kind": "client", - "version": "1.0" + "span.kind": "client" } }]] diff --git a/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_create_image_edit.json b/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_create_image_edit.json index 13dd799139..086211b07d 100644 --- a/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_create_image_edit.json +++ b/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_create_image_edit.json @@ -52,7 +52,6 @@ "http.status_code": "200", "http.url": "https://api.openai.com/v1/images/edits?foo=bar", "network.destination.name": "api.openai.com", - "span.kind": "client", - "version": "1.0" + "span.kind": "client" } }]] diff --git a/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_create_image_variation.json b/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_create_image_variation.json index 9b852a66a9..23afc4dd12 100644 --- a/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_create_image_variation.json +++ b/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_create_image_variation.json @@ -50,7 +50,6 @@ "http.status_code": "200", "http.url": "https://api.openai.com/v1/images/variations?foo=bar", "network.destination.name": "api.openai.com", - "span.kind": "client", - "version": "1.0" + "span.kind": "client" } }]] diff --git a/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_create_moderation.json b/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_create_moderation.json index 55689db1ad..be4923056e 100644 --- a/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_create_moderation.json +++ b/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_create_moderation.json @@ -69,7 +69,6 @@ "http.status_code": "200", "http.url": "https://api.openai.com/v1/moderations?foo=bar", "network.destination.name": "api.openai.com", - "span.kind": "client", - "version": "1.0" + "span.kind": "client" } }]] diff --git a/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_create_transcription_to_json.json b/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_create_transcription_to_json.json index 484aae9ad0..96fe23a901 100644 --- a/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_create_transcription_to_json.json +++ b/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_create_transcription_to_json.json @@ -49,7 +49,6 @@ "http.status_code": "200", "http.url": "https://api.openai.com/v1/audio/transcriptions?foo=bar", "network.destination.name": "api.openai.com", - "span.kind": "client", - "version": "1.0" + "span.kind": "client" } }]] diff --git a/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_create_transcription_to_text.json b/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_create_transcription_to_text.json index cc8f0d75bf..70fbd3e6c4 100644 --- a/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_create_transcription_to_text.json +++ b/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_create_transcription_to_text.json @@ -51,7 +51,6 @@ "http.status_code": "200", "http.url": "https://api.openai.com/v1/audio/transcriptions?foo=bar", "network.destination.name": "api.openai.com", - "span.kind": "client", - "version": "1.0" + "span.kind": "client" } }]] diff --git a/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_create_transcription_to_verbose_json.json b/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_create_transcription_to_verbose_json.json index 2c682f2f5e..34653aeff1 100644 --- a/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_create_transcription_to_verbose_json.json +++ b/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_create_transcription_to_verbose_json.json @@ -51,7 +51,6 @@ "http.status_code": "200", "http.url": "https://api.openai.com/v1/audio/transcriptions?foo=bar", "network.destination.name": "api.openai.com", - "span.kind": "client", - "version": "1.0" + "span.kind": "client" } }]] diff --git a/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_create_translation_to_json.json b/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_create_translation_to_json.json index f7ebf8cae7..b380eb022b 100644 --- a/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_create_translation_to_json.json +++ b/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_create_translation_to_json.json @@ -49,7 +49,6 @@ "http.status_code": "200", "http.url": "https://api.openai.com/v1/audio/translations?foo=bar", "network.destination.name": "api.openai.com", - "span.kind": "client", - "version": "1.0" + "span.kind": "client" } }]] diff --git a/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_create_translation_to_text.json b/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_create_translation_to_text.json index 6e45609fab..0e772afec9 100644 --- a/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_create_translation_to_text.json +++ b/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_create_translation_to_text.json @@ -51,7 +51,6 @@ "http.status_code": "200", "http.url": "https://api.openai.com/v1/audio/translations?foo=bar", "network.destination.name": "api.openai.com", - "span.kind": "client", - "version": "1.0" + "span.kind": "client" } }]] diff --git a/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_create_translation_to_verbose_json.json b/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_create_translation_to_verbose_json.json index 7188e4127a..8d01bd44e9 100644 --- a/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_create_translation_to_verbose_json.json +++ b/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_create_translation_to_verbose_json.json @@ -51,7 +51,6 @@ "http.status_code": "200", "http.url": "https://api.openai.com/v1/audio/translations?foo=bar", "network.destination.name": "api.openai.com", - "span.kind": "client", - "version": "1.0" + "span.kind": "client" } }]] diff --git a/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_delete_file.json b/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_delete_file.json index e1c000068a..cd21ae389d 100644 --- a/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_delete_file.json +++ b/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_delete_file.json @@ -47,7 +47,6 @@ "http.status_code": "200", "http.url": "https://api.openai.com/v1/files/file-XjGxS3KTG0uNmNOK362iJua3?foo=bar", "network.destination.name": "api.openai.com", - "span.kind": "client", - "version": "1.0" + "span.kind": "client" } }]] diff --git a/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_delete_model.json b/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_delete_model.json index ed3269246a..b952a142c8 100644 --- a/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_delete_model.json +++ b/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_delete_model.json @@ -47,7 +47,6 @@ "http.status_code": "200", "http.url": "https://api.openai.com/v1/models/curie:ft-acmeco-2021-03-03-21-44-20?foo=bar", "network.destination.name": "api.openai.com", - "span.kind": "client", - "version": "1.0" + "span.kind": "client" } }]] diff --git a/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_download_file.json b/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_download_file.json index 565b413a99..e387894582 100644 --- a/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_download_file.json +++ b/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_download_file.json @@ -43,7 +43,6 @@ "http.status_code": "200", "http.url": "https://api.openai.com/v1/files/file-XjGxS3KTG0uNmNOK362iJua3/content?foo=bar", "network.destination.name": "api.openai.com", - "span.kind": "client", - "version": "1.0" + "span.kind": "client" } }]] diff --git a/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_list_files.json b/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_list_files.json index a9e8b9339a..c1ac253839 100644 --- a/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_list_files.json +++ b/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_list_files.json @@ -46,7 +46,6 @@ "http.status_code": "200", "http.url": "https://api.openai.com/v1/files?foo=bar", "network.destination.name": "api.openai.com", - "span.kind": "client", - "version": "1.0" + "span.kind": "client" } }]] diff --git a/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_list_fine_tune_events.json b/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_list_fine_tune_events.json index b7db554516..a01d3f6b9a 100644 --- a/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_list_fine_tune_events.json +++ b/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_list_fine_tune_events.json @@ -47,7 +47,6 @@ "http.status_code": "200", "http.url": "https://api.openai.com/v1/fine-tunes/ftjob-AF1WoRqd3aJAHsqc9NY7iL8F/events?foo=bar", "network.destination.name": "api.openai.com", - "span.kind": "client", - "version": "1.0" + "span.kind": "client" } }]] diff --git a/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_list_fine_tune_events_stream.json b/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_list_fine_tune_events_stream.json index ddbb0eea45..b72d516465 100644 --- a/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_list_fine_tune_events_stream.json +++ b/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_list_fine_tune_events_stream.json @@ -45,7 +45,6 @@ "http.status_code": "200", "http.url": "https://api.openai.com/v1/fine-tunes/ft-MaoEAULREoazpupm8uB7qoIl/events?stream=true?foo=bar", "network.destination.name": "api.openai.com", - "span.kind": "client", - "version": "1.0" + "span.kind": "client" } }]] diff --git a/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_list_models.json b/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_list_models.json index 39dccfd9c1..494a3ae2af 100644 --- a/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_list_models.json +++ b/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_list_models.json @@ -46,7 +46,6 @@ "http.status_code": "200", "http.url": "https://api.openai.com/v1/models?foo=bar", "network.destination.name": "api.openai.com", - "span.kind": "client", - "version": "1.0" + "span.kind": "client" } }]] diff --git a/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_list_models_with_error.json b/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_list_models_with_error.json index c76b32e0a0..7663d968df 100644 --- a/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_list_models_with_error.json +++ b/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_list_models_with_error.json @@ -45,7 +45,6 @@ "http.status_code": "401", "http.url": "https://api.openai.com/v1/models?foo=bar", "network.destination.name": "api.openai.com", - "span.kind": "client", - "version": "1.0" + "span.kind": "client" } }]] diff --git a/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_list_models_with_null_error_type.json b/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_list_models_with_null_error_type.json index 891c75a521..293a32a64e 100644 --- a/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_list_models_with_null_error_type.json +++ b/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_list_models_with_null_error_type.json @@ -45,7 +45,6 @@ "http.status_code": "429", "http.url": "https://api.openai.com/v1/models?foo=bar", "network.destination.name": "api.openai.com", - "span.kind": "client", - "version": "1.0" + "span.kind": "client" } }]] diff --git a/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_log_prompt_completion_sample_rate.json b/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_log_prompt_completion_sample_rate.json index 0931fb64fd..b20195f451 100644 --- a/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_log_prompt_completion_sample_rate.json +++ b/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_log_prompt_completion_sample_rate.json @@ -56,7 +56,6 @@ "http.status_code": "200", "http.url": "https://api.openai.com/v1/completions?foo=bar", "network.destination.name": "api.openai.com", - "span.kind": "client", - "version": "1.0" + "span.kind": "client" } }]] diff --git a/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_logs_disabled.json b/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_logs_disabled.json index b0837e96a2..39588732c0 100644 --- a/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_logs_disabled.json +++ b/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_logs_disabled.json @@ -46,7 +46,6 @@ "http.status_code": "200", "http.url": "https://api.openai.com/v1/models?foo=bar", "network.destination.name": "api.openai.com", - "span.kind": "client", - "version": "1.0" + "span.kind": "client" } }]] diff --git a/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_metrics_disabled.json b/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_metrics_disabled.json index 488ab56da7..fd99245b57 100644 --- a/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_metrics_disabled.json +++ b/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_metrics_disabled.json @@ -46,7 +46,6 @@ "http.status_code": "200", "http.url": "https://api.openai.com/v1/models?foo=bar", "network.destination.name": "api.openai.com", - "span.kind": "client", - "version": "1.0" + "span.kind": "client" } }]] diff --git a/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_open_ai_service.json b/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_open_ai_service.json index d691df3984..c67f625ba9 100644 --- a/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_open_ai_service.json +++ b/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_open_ai_service.json @@ -19,8 +19,7 @@ "openai.response.object": "list", "openai.user.api_key": "sk-...9d5d", "runtime-id": "0a784015-fb27-4c52-9df3-dedf7130fbcb", - "span.kind": "client", - "version": "1.0" + "span.kind": "client" }, "metrics": { "_dd.agent_psr": 1, @@ -46,7 +45,6 @@ "http.status_code": "200", "http.url": "https://api.openai.com/v1/models?foo=bar", "network.destination.name": "api.openai.com", - "span.kind": "client", - "version": "1.0" + "span.kind": "client" } }]] diff --git a/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_retrieve_file.json b/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_retrieve_file.json index a193464263..2192100b9b 100644 --- a/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_retrieve_file.json +++ b/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_retrieve_file.json @@ -51,7 +51,6 @@ "http.status_code": "200", "http.url": "https://api.openai.com/v1/files/file-XjGxS3KTG0uNmNOK362iJua3?foo=bar", "network.destination.name": "api.openai.com", - "span.kind": "client", - "version": "1.0" + "span.kind": "client" } }]] diff --git a/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_retrieve_fine_tune.json b/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_retrieve_fine_tune.json index a6b5d56d56..057715cb72 100644 --- a/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_retrieve_fine_tune.json +++ b/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_retrieve_fine_tune.json @@ -51,7 +51,6 @@ "http.status_code": "200", "http.url": "https://api.openai.com/v1/fine_tuning/jobs/ftjob-AF1WoRqd3aJAHsqc9NY7iL8F?foo=bar", "network.destination.name": "api.openai.com", - "span.kind": "client", - "version": "1.0" + "span.kind": "client" } }]] diff --git a/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_retrieve_model.json b/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_retrieve_model.json index 27742d0965..4b5e96fed6 100644 --- a/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_retrieve_model.json +++ b/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_retrieve_model.json @@ -48,7 +48,6 @@ "http.status_code": "200", "http.url": "https://api.openai.com/v1/models/da-vince?foo=bar", "network.destination.name": "api.openai.com", - "span.kind": "client", - "version": "1.0" + "span.kind": "client" } }]] diff --git a/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_span_char_limit.json b/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_span_char_limit.json index 869da8612e..11d9a2da1c 100644 --- a/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_span_char_limit.json +++ b/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_span_char_limit.json @@ -56,7 +56,6 @@ "http.status_code": "200", "http.url": "https://api.openai.com/v1/completions?foo=bar", "network.destination.name": "api.openai.com", - "span.kind": "client", - "version": "1.0" + "span.kind": "client" } }]] diff --git a/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_span_prompt_completion_sample_rate.json b/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_span_prompt_completion_sample_rate.json index b0eace0670..1bd498affa 100644 --- a/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_span_prompt_completion_sample_rate.json +++ b/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_span_prompt_completion_sample_rate.json @@ -54,7 +54,6 @@ "http.status_code": "200", "http.url": "https://api.openai.com/v1/completions?foo=bar", "network.destination.name": "api.openai.com", - "span.kind": "client", - "version": "1.0" + "span.kind": "client" } }]] From 1fcf62330f7163c54fc54490a4192d18514fa88d Mon Sep 17 00:00:00 2001 From: Florian Engelhardt Date: Wed, 6 Nov 2024 14:39:52 +0100 Subject: [PATCH 19/29] ci(profiling) fix profiling ASAN tests (#2924) --- .github/workflows/prof_asan.yml | 10 ++-- docker-compose.yml | 4 +- dockerfiles/ci/bookworm/Dockerfile | 55 ++++++++++++++++++--- dockerfiles/ci/bookworm/build-extensions.sh | 7 ++- dockerfiles/ci/bookworm/build-php.sh | 13 ++++- 5 files changed, 74 insertions(+), 15 deletions(-) diff --git a/.github/workflows/prof_asan.yml b/.github/workflows/prof_asan.yml index 8d39889edb..8b7ce23b3e 100644 --- a/.github/workflows/prof_asan.yml +++ b/.github/workflows/prof_asan.yml @@ -6,8 +6,11 @@ on: jobs: prof-asan: runs-on: ubuntu-latest + strategy: + matrix: + php-version: [8.3, 8.4] container: - image: datadog/dd-trace-ci:php-8.3_bookworm-4 + image: datadog/dd-trace-ci:php-${{matrix.php-version}}_bookworm-5 # https://docs.github.com/en/actions/creating-actions/dockerfile-support-for-github-actions#user options: --user root --privileged @@ -33,14 +36,15 @@ jobs: run: | set -eux switch-php nts-asan + rm $(php-config --ini-dir)/sqlsrv.ini #sqlsrv leaks memory and triggers asan cd profiling export CARGO_TARGET_DIR=/tmp/build-cargo export CC=clang-17 export CFLAGS='-fsanitize=address -fno-omit-frame-pointer' - export LDFLAGS='-fsanitize=address' + export LDFLAGS='-fsanitize=address -shared-libasan' export RUSTC_LINKER=lld-17 triplet=$(uname -m)-unknown-linux-gnu - RUST_NIGHTLY_VERSION="-2024-02-27" + RUST_NIGHTLY_VERSION="-2024-11-04" RUSTFLAGS='-Zsanitizer=address' cargo +nightly${RUST_NIGHTLY_VERSION} build -Zbuild-std --target $triplet --release cp -v "$CARGO_TARGET_DIR/$triplet/release/libdatadog_php_profiling.so" "$(php-config --extension-dir)/datadog-profiling.so" diff --git a/docker-compose.yml b/docker-compose.yml index 877c9e4445..41b7c3a1db 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -85,8 +85,8 @@ services: '8.4-buster': { <<: *linux_php_service, image: 'datadog/dd-trace-ci:php-8.4_buster' } 'php-master-buster': { <<: *linux_php_service, image: 'datadog/dd-trace-ci:php-master_buster' } # --- Bookworm --- - '8.2-bookworm': { <<: *linux_php_service, image: 'datadog/dd-trace-ci:php-8.2_bookworm-3' } - '8.3-bookworm': { <<: *linux_php_service, image: 'datadog/dd-trace-ci:php-8.3_bookworm-3' } + '8.2-bookworm': { <<: *linux_php_service, image: 'datadog/dd-trace-ci:php-8.2_bookworm-5' } + '8.3-bookworm': { <<: *linux_php_service, image: 'datadog/dd-trace-ci:php-8.3_bookworm-5' } # --- CentOS 6 --- '7.0-centos7': { <<: *linux_php_service, image: 'datadog/dd-trace-ci:php-7.0_centos-7' } '7.1-centos7': { <<: *linux_php_service, image: 'datadog/dd-trace-ci:php-7.1_centos-7' } diff --git a/dockerfiles/ci/bookworm/Dockerfile b/dockerfiles/ci/bookworm/Dockerfile index 5508d9fe81..dd7fa1d902 100644 --- a/dockerfiles/ci/bookworm/Dockerfile +++ b/dockerfiles/ci/bookworm/Dockerfile @@ -68,10 +68,7 @@ ENV PHPIZE_DEPS \ clang-17 \ cmake \ dpkg-dev \ - g++ \ - gcc \ file \ - lcov \ libc-dev \ make \ pkg-config \ @@ -128,7 +125,54 @@ RUN set -eux; \ echo 'Defaults env_keep += "DEBIAN_FRONTEND"' >> /etc/sudoers.d/env_keep; \ \ # Allow nginx to be run as non-root for tests - chown -R circleci:circleci /var/log/nginx/ /var/lib/nginx/; + chown -R circleci:circleci /var/log/nginx/ /var/lib/nginx/; \ + \ +# Make clang the default compiler + update-alternatives --install /usr/bin/cc cc /usr/bin/clang-17 100; \ + update-alternatives --install /usr/bin/c++ c++ /usr/bin/clang++-17 100; \ + update-alternatives --install /usr/bin/clang clang /usr/bin/clang-17 100; \ + update-alternatives --install /usr/bin/clang++ clang++ /usr/bin/clang++-17 100; \ + update-alternatives --install /usr/bin/ld ld /usr/bin/ld.lld-17 100; \ + echo "-L /usr/lib/llvm-17/lib/clang/17/lib/linux" > /usr/lib/llvm-17/bin/clang.cfg; \ +# Include libasan library path + echo /usr/lib/llvm-17/lib/clang/17/lib/linux > /etc/ld.so.conf.d/libasan.conf && ldconfig + +# Install lcov +RUN set -eux; \ + LCOV_VERSION="1.15"; \ + LCOV_SHA256="c1cda2fa33bec9aa2c2c73c87226cfe97de0831887176b45ee523c5e30f8053a"; \ + cd /tmp && curl -OL https://github.com/linux-test-project/lcov/releases/download/v${LCOV_VERSION}/lcov-${LCOV_VERSION}.tar.gz; \ + (echo "${LCOV_SHA256} lcov-${LCOV_VERSION}.tar.gz" | sha256sum -c -); \ + mkdir lcov && cd lcov; \ + tar -xf ../lcov-${LCOV_VERSION}.tar.gz --strip 1; \ + make install; \ + lcov --version; \ + rm -rfv /tmp/* + +# Install gdb +RUN set -eux; \ + apt install -y libmpfr-dev libgmp-dev; \ + GDB_VERSION="15.2"; \ + GDB_SHA256="9d16bc2539a2a20dc3ef99b48b8414d51c51305c8577eb7a1da00996f6dea223";\ + cd /tmp && curl -OL https://ftp.gnu.org/gnu/gdb/gdb-${GDB_VERSION}.tar.gz; \ + (echo "${GDB_SHA256} gdb-${GDB_VERSION}.tar.gz" | sha256sum -c -); \ + mkdir gdb && cd gdb; \ + tar -xf ../gdb-${GDB_VERSION}.tar.gz --strip 1;\ + ./configure; \ + make -j "$((`nproc`+1))"; \ + make install + +# Install valgrind +RUN set -eux; \ + VALGRIND_VERSION="3.23.0"; \ + VALGRIND_SHA1="ec410c75d3920d4f9249a5cfa2cac31e1bf6d586"; \ + cd /tmp && curl -OL https://sourceware.org/pub/valgrind/valgrind-${VALGRIND_VERSION}.tar.bz2; \ + (echo "${VALGRIND_SHA1}" valgrind-${VALGRIND_VERSION}.tar.bz2 | sha1sum -c -); \ + mkdir valgrind && cd valgrind; \ + tar -xjf ../valgrind-${VALGRIND_VERSION}.tar.bz2 --strip 1;\ + ./configure; \ + make -j "$((`nproc`+1))"; \ + make install # Install SqlServer PHP Driver # https://learn.microsoft.com/en-us/sql/connect/odbc/linux-mac/installing-the-microsoft-odbc-driver-for-sql-server @@ -217,8 +261,7 @@ RUN set -eux; \ chown -R circleci:circleci /opt; ARG RUST_VERSION="1.76.0" -# Need a nightly that is at least 1.71.1 -ARG RUST_NIGHTLY_VERSION="-2024-02-27" +ARG RUST_NIGHTLY_VERSION="-2024-11-04" # Mount a cache into /rust/cargo if you want to pre-fetch packages or something ENV CARGO_HOME=/rust/cargo ENV RUSTUP_HOME=/rust/rustup diff --git a/dockerfiles/ci/bookworm/build-extensions.sh b/dockerfiles/ci/bookworm/build-extensions.sh index 01328c10c5..6a3f123ade 100755 --- a/dockerfiles/ci/bookworm/build-extensions.sh +++ b/dockerfiles/ci/bookworm/build-extensions.sh @@ -6,6 +6,9 @@ SHARED_BUILD=$(if php -i | grep -q enable-pcntl=shared; then echo 1; else echo 0 PHP_VERSION_ID=$(php -r 'echo PHP_MAJOR_VERSION . PHP_MINOR_VERSION;') PHP_ZTS=$(php -r 'echo PHP_ZTS;') +# This make `pecl install` use all available cores +export MAKEFLAGS="-j $(nproc)" + XDEBUG_VERSIONS=(-3.1.2) if [[ $PHP_VERSION_ID -le 70 ]]; then XDEBUG_VERSIONS=(-2.7.2) @@ -56,8 +59,8 @@ fi HOST_ARCH=$(if [[ $(file $(readlink -f $(which php))) == *aarch64* ]]; then echo "aarch64"; else echo "x86_64"; fi) export PKG_CONFIG=/usr/bin/$HOST_ARCH-linux-gnu-pkg-config -export CC=$HOST_ARCH-linux-gnu-gcc -export CXX=$HOST_ARCH-linux-gnu-g++ +# export CC=$HOST_ARCH-linux-gnu-gcc +# export CXX=$HOST_ARCH-linux-gnu-g++ iniDir=$(php -i | awk -F"=> " '/Scan this dir for additional .ini files/ {print $2}'); diff --git a/dockerfiles/ci/bookworm/build-php.sh b/dockerfiles/ci/bookworm/build-php.sh index a15800e999..57a841df98 100755 --- a/dockerfiles/ci/bookworm/build-php.sh +++ b/dockerfiles/ci/bookworm/build-php.sh @@ -13,7 +13,16 @@ INSTALL_DIR=$BASE_INSTALL_DIR/$INSTALL_VERSION if [[ ${INSTALL_VERSION} == *asan* ]]; then export CFLAGS='-fsanitize=address -DZEND_TRACK_ARENA_ALLOC' - export LDFLAGS='-fsanitize=address' + # GCC has `-shared-libasan` default, clang has '-static-libasan' default + export LDFLAGS='-fsanitize=address -shared-libasan' +fi + +if [[ ${PHP_VERSION_ID} -le 73 ]]; then + if [[ -z "${CFLAGS:-}" ]]; then + export CFLAGS="-Wno-implicit-function-declaration -DHAVE_POSIX_READDIR_R=1 -DHAVE_OLD_READDIR_R=0" + else + export CFLAGS="${CFLAGS} -Wno-implicit-function-declaration -DHAVE_POSIX_READDIR_R=1 -DHAVE_OLD_READDIR_R=0" + fi fi mkdir -p /tmp/build-php && cd /tmp/build-php @@ -23,7 +32,7 @@ mkdir -p ${INSTALL_DIR}/conf.d HOST_ARCH=$(if [[ $TARGETPLATFORM == "linux/arm64" ]]; then echo "aarch64"; else echo "x86_64"; fi) PKG_CONFIG=/usr/bin/$HOST_ARCH-linux-gnu-pkg-config \ -CC=$HOST_ARCH-linux-gnu-gcc \ +# CC=$HOST_ARCH-linux-gnu-gcc \ LIBS=-ldl \ ${PHP_SRC_DIR}/configure \ $(if [[ $SHARED_BUILD -ne 0 ]]; then echo \ From b3fd817475b69849922445914587522feeb4ddaa Mon Sep 17 00:00:00 2001 From: Petr Levtonov Date: Wed, 6 Nov 2024 15:06:31 +0100 Subject: [PATCH 20/29] #2926: Do not overwrite service in PSR18 integration (#2927) * Do not overwrite service in PSR18 integration For consistency and correctness, do not hardcode the service for this integration otherwise there is no way to control it and it forces that everyone has a service on their service map that is actually just a component. * tests: Update psr-related test failures * tests: Add version metadata where applicable * fix: typo --------- Co-authored-by: Alexandre Choura --- src/DDTrace/Integrations/Psr18/Psr18Integration.php | 1 - tests/Integrations/Guzzle/V7/GuzzleIntegrationTest.php | 4 ++-- ...grations.open_ai.open_ai_test.test_cancel_fine_tune.json | 6 +++--- ...ns.open_ai.open_ai_test.test_create_chat_completion.json | 6 +++--- ..._ai.open_ai_test.test_create_chat_completion_stream.json | 6 +++--- ..._test.test_create_chat_completion_stream_with_error.json | 6 +++--- ..._ai_test.test_create_chat_completion_with_functions.json | 6 +++--- ...i_test.test_create_chat_completion_with_image_input.json | 6 +++--- ...est.test_create_chat_completion_with_multiple_roles.json | 6 +++--- ...rations.open_ai.open_ai_test.test_create_completion.json | 6 +++--- ....open_ai.open_ai_test.test_create_completion_stream.json | 6 +++--- ...est_create_completions_with_multiple_error_messages.json | 6 +++--- ...grations.open_ai.open_ai_test.test_create_embedding.json | 6 +++--- ..._ai_test.test_create_embedding_with_multiple_inputs.json | 6 +++--- ....integrations.open_ai.open_ai_test.test_create_file.json | 6 +++--- ...integrations.open_ai.open_ai_test.test_create_image.json | 6 +++--- ...rations.open_ai.open_ai_test.test_create_image_edit.json | 6 +++--- ...ns.open_ai.open_ai_test.test_create_image_variation.json | 6 +++--- ...rations.open_ai.open_ai_test.test_create_moderation.json | 6 +++--- ...n_ai.open_ai_test.test_create_transcription_to_json.json | 6 +++--- ...n_ai.open_ai_test.test_create_transcription_to_text.json | 6 +++--- ...n_ai_test.test_create_transcription_to_verbose_json.json | 6 +++--- ...pen_ai.open_ai_test.test_create_translation_to_json.json | 6 +++--- ...pen_ai.open_ai_test.test_create_translation_to_text.json | 6 +++--- ...pen_ai_test.test_create_translation_to_verbose_json.json | 6 +++--- ....integrations.open_ai.open_ai_test.test_delete_file.json | 6 +++--- ...integrations.open_ai.open_ai_test.test_delete_model.json | 6 +++--- ...ntegrations.open_ai.open_ai_test.test_download_file.json | 6 +++--- ...s.integrations.open_ai.open_ai_test.test_list_files.json | 6 +++--- ...ons.open_ai.open_ai_test.test_list_fine_tune_events.json | 6 +++--- ...n_ai.open_ai_test.test_list_fine_tune_events_stream.json | 6 +++--- ....integrations.open_ai.open_ai_test.test_list_models.json | 6 +++--- ...ns.open_ai.open_ai_test.test_list_models_with_error.json | 6 +++--- ....open_ai_test.test_list_models_with_null_error_type.json | 6 +++--- ...open_ai_test.test_log_prompt_completion_sample_rate.json | 6 +++--- ...ntegrations.open_ai.open_ai_test.test_logs_disabled.json | 6 +++--- ...grations.open_ai.open_ai_test.test_metrics_disabled.json | 6 +++--- ...egrations.open_ai.open_ai_test.test_open_ai_service.json | 3 +-- ...ntegrations.open_ai.open_ai_test.test_retrieve_file.json | 6 +++--- ...ations.open_ai.open_ai_test.test_retrieve_fine_tune.json | 6 +++--- ...tegrations.open_ai.open_ai_test.test_retrieve_model.json | 6 +++--- ...egrations.open_ai.open_ai_test.test_span_char_limit.json | 6 +++--- ...pen_ai_test.test_span_prompt_completion_sample_rate.json | 6 +++--- 43 files changed, 123 insertions(+), 125 deletions(-) diff --git a/src/DDTrace/Integrations/Psr18/Psr18Integration.php b/src/DDTrace/Integrations/Psr18/Psr18Integration.php index 31df56741a..2287036bbb 100644 --- a/src/DDTrace/Integrations/Psr18/Psr18Integration.php +++ b/src/DDTrace/Integrations/Psr18/Psr18Integration.php @@ -27,7 +27,6 @@ public function init(): int function (SpanData $span, $args, $retval) use ($integration) { $span->resource = 'sendRequest'; $span->name = 'Psr\Http\Client\ClientInterface.sendRequest'; - $span->service = 'psr18'; $span->type = Type::HTTP_CLIENT; $span->meta[Tag::SPAN_KIND] = 'client'; $span->meta[Tag::COMPONENT] = Psr18Integration::NAME; diff --git a/tests/Integrations/Guzzle/V7/GuzzleIntegrationTest.php b/tests/Integrations/Guzzle/V7/GuzzleIntegrationTest.php index 4d6a93c09c..2debc547a6 100644 --- a/tests/Integrations/Guzzle/V7/GuzzleIntegrationTest.php +++ b/tests/Integrations/Guzzle/V7/GuzzleIntegrationTest.php @@ -18,7 +18,7 @@ public function testSendRequest() $this->getMockedClient()->sendRequest($request); }); $this->assertFlameGraph($traces, [ - SpanAssertion::build('Psr\Http\Client\ClientInterface.sendRequest', 'psr18', 'http', 'sendRequest') + SpanAssertion::build('Psr\Http\Client\ClientInterface.sendRequest', 'phpunit', 'http', 'sendRequest') ->withExactTags([ 'http.method' => 'PUT', 'http.url' => 'http://example.com', @@ -36,7 +36,7 @@ public function testSendRequest() 'network.destination.name' => 'example.com', TAG::SPAN_KIND => 'client', Tag::COMPONENT => 'guzzle', - '_dd.base_service' => 'psr18' + '_dd.base_service' => 'phpunit' ]), ]) ]); diff --git a/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_cancel_fine_tune.json b/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_cancel_fine_tune.json index 136e6937fb..c51939620a 100644 --- a/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_cancel_fine_tune.json +++ b/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_cancel_fine_tune.json @@ -45,20 +45,20 @@ }, { "name": "Psr\\Http\\Client\\ClientInterface.sendRequest", - "service": "psr18", + "service": "openai-test", "resource": "sendRequest", "trace_id": 0, "span_id": 2, "parent_id": 1, "type": "http", "meta": { - "_dd.base_service": "openai-test", "component": "psr18", "env": "test", "http.method": "POST", "http.status_code": "200", "http.url": "https://api.openai.com/v1/fine-tunes/ftjob-AF1WoRqd3aJAHsqc9NY7iL8F/cancel?foo=bar", "network.destination.name": "api.openai.com", - "span.kind": "client" + "span.kind": "client", + "version": "1.0" } }]] diff --git a/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_create_chat_completion.json b/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_create_chat_completion.json index 72c9094bcb..73a8b8df71 100644 --- a/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_create_chat_completion.json +++ b/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_create_chat_completion.json @@ -42,20 +42,20 @@ }, { "name": "Psr\\Http\\Client\\ClientInterface.sendRequest", - "service": "psr18", + "service": "openai-test", "resource": "sendRequest", "trace_id": 0, "span_id": 2, "parent_id": 1, "type": "http", "meta": { - "_dd.base_service": "openai-test", "component": "psr18", "env": "test", "http.method": "POST", "http.status_code": "200", "http.url": "https://api.openai.com/v1/chat/completions?foo=bar", "network.destination.name": "api.openai.com", - "span.kind": "client" + "span.kind": "client", + "version": "1.0" } }]] diff --git a/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_create_chat_completion_stream.json b/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_create_chat_completion_stream.json index b6e7c27d60..16e07a4296 100644 --- a/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_create_chat_completion_stream.json +++ b/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_create_chat_completion_stream.json @@ -38,20 +38,20 @@ }, { "name": "Psr\\Http\\Client\\ClientInterface.sendRequest", - "service": "psr18", + "service": "openai-test", "resource": "sendRequest", "trace_id": 0, "span_id": 2, "parent_id": 1, "type": "http", "meta": { - "_dd.base_service": "openai-test", "component": "psr18", "env": "test", "http.method": "POST", "http.status_code": "200", "http.url": "https://api.openai.com/v1/chat/completions?foo=bar", "network.destination.name": "api.openai.com", - "span.kind": "client" + "span.kind": "client", + "version": "1.0" } }]] diff --git a/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_create_chat_completion_stream_with_error.json b/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_create_chat_completion_stream_with_error.json index d184ae3142..dd561dfaa9 100644 --- a/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_create_chat_completion_stream_with_error.json +++ b/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_create_chat_completion_stream_with_error.json @@ -39,20 +39,20 @@ }, { "name": "Psr\\Http\\Client\\ClientInterface.sendRequest", - "service": "psr18", + "service": "openai-test", "resource": "sendRequest", "trace_id": 0, "span_id": 2, "parent_id": 1, "type": "http", "meta": { - "_dd.base_service": "openai-test", "component": "psr18", "env": "test", "http.method": "POST", "http.status_code": "200", "http.url": "https://api.openai.com/v1/chat/completions?foo=bar", "network.destination.name": "api.openai.com", - "span.kind": "client" + "span.kind": "client", + "version": "1.0" } }]] diff --git a/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_create_chat_completion_with_functions.json b/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_create_chat_completion_with_functions.json index 518404b54c..e4dda927bc 100644 --- a/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_create_chat_completion_with_functions.json +++ b/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_create_chat_completion_with_functions.json @@ -41,20 +41,20 @@ }, { "name": "Psr\\Http\\Client\\ClientInterface.sendRequest", - "service": "psr18", + "service": "openai-test", "resource": "sendRequest", "trace_id": 0, "span_id": 2, "parent_id": 1, "type": "http", "meta": { - "_dd.base_service": "openai-test", "component": "psr18", "env": "test", "http.method": "POST", "http.status_code": "200", "http.url": "https://api.openai.com/v1/chat/completions?foo=bar", "network.destination.name": "api.openai.com", - "span.kind": "client" + "span.kind": "client", + "version": "1.0" } }]] diff --git a/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_create_chat_completion_with_image_input.json b/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_create_chat_completion_with_image_input.json index 63f6eb739f..af01f39a98 100644 --- a/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_create_chat_completion_with_image_input.json +++ b/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_create_chat_completion_with_image_input.json @@ -43,20 +43,20 @@ }, { "name": "Psr\\Http\\Client\\ClientInterface.sendRequest", - "service": "psr18", + "service": "openai-test", "resource": "sendRequest", "trace_id": 0, "span_id": 2, "parent_id": 1, "type": "http", "meta": { - "_dd.base_service": "openai-test", "component": "psr18", "env": "test", "http.method": "POST", "http.status_code": "200", "http.url": "https://api.openai.com/v1/chat/completions?foo=bar", "network.destination.name": "api.openai.com", - "span.kind": "client" + "span.kind": "client", + "version": "1.0" } }]] diff --git a/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_create_chat_completion_with_multiple_roles.json b/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_create_chat_completion_with_multiple_roles.json index 09c532c79a..32eefe633c 100644 --- a/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_create_chat_completion_with_multiple_roles.json +++ b/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_create_chat_completion_with_multiple_roles.json @@ -44,20 +44,20 @@ }, { "name": "Psr\\Http\\Client\\ClientInterface.sendRequest", - "service": "psr18", + "service": "openai-test", "resource": "sendRequest", "trace_id": 0, "span_id": 2, "parent_id": 1, "type": "http", "meta": { - "_dd.base_service": "openai-test", "component": "psr18", "env": "test", "http.method": "POST", "http.status_code": "200", "http.url": "https://api.openai.com/v1/chat/completions?foo=bar", "network.destination.name": "api.openai.com", - "span.kind": "client" + "span.kind": "client", + "version": "1.0" } }]] diff --git a/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_create_completion.json b/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_create_completion.json index 7ec60a75d4..37a2ddf02f 100644 --- a/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_create_completion.json +++ b/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_create_completion.json @@ -42,20 +42,20 @@ }, { "name": "Psr\\Http\\Client\\ClientInterface.sendRequest", - "service": "psr18", + "service": "openai-test", "resource": "sendRequest", "trace_id": 0, "span_id": 2, "parent_id": 1, "type": "http", "meta": { - "_dd.base_service": "openai-test", "component": "psr18", "env": "test", "http.method": "POST", "http.status_code": "200", "http.url": "https://api.openai.com/v1/completions?foo=bar", "network.destination.name": "api.openai.com", - "span.kind": "client" + "span.kind": "client", + "version": "1.0" } }]] diff --git a/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_create_completion_stream.json b/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_create_completion_stream.json index ea4741afd8..1980a7da44 100644 --- a/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_create_completion_stream.json +++ b/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_create_completion_stream.json @@ -38,20 +38,20 @@ }, { "name": "Psr\\Http\\Client\\ClientInterface.sendRequest", - "service": "psr18", + "service": "openai-test", "resource": "sendRequest", "trace_id": 0, "span_id": 2, "parent_id": 1, "type": "http", "meta": { - "_dd.base_service": "openai-test", "component": "psr18", "env": "test", "http.method": "POST", "http.status_code": "200", "http.url": "https://api.openai.com/v1/completions?foo=bar", "network.destination.name": "api.openai.com", - "span.kind": "client" + "span.kind": "client", + "version": "1.0" } }]] diff --git a/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_create_completions_with_multiple_error_messages.json b/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_create_completions_with_multiple_error_messages.json index 2257b15781..91a25ee447 100644 --- a/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_create_completions_with_multiple_error_messages.json +++ b/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_create_completions_with_multiple_error_messages.json @@ -32,20 +32,20 @@ }, { "name": "Psr\\Http\\Client\\ClientInterface.sendRequest", - "service": "psr18", + "service": "openai-test", "resource": "sendRequest", "trace_id": 0, "span_id": 2, "parent_id": 1, "type": "http", "meta": { - "_dd.base_service": "openai-test", "component": "psr18", "env": "test", "http.method": "POST", "http.status_code": "404", "http.url": "https://api.openai.com/v1/completions?foo=bar", "network.destination.name": "api.openai.com", - "span.kind": "client" + "span.kind": "client", + "version": "1.0" } }]] diff --git a/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_create_embedding.json b/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_create_embedding.json index 46ff1160b2..7758a3f010 100644 --- a/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_create_embedding.json +++ b/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_create_embedding.json @@ -38,20 +38,20 @@ }, { "name": "Psr\\Http\\Client\\ClientInterface.sendRequest", - "service": "psr18", + "service": "openai-test", "resource": "sendRequest", "trace_id": 0, "span_id": 2, "parent_id": 1, "type": "http", "meta": { - "_dd.base_service": "openai-test", "component": "psr18", "env": "test", "http.method": "POST", "http.status_code": "200", "http.url": "https://api.openai.com/v1/embeddings?foo=bar", "network.destination.name": "api.openai.com", - "span.kind": "client" + "span.kind": "client", + "version": "1.0" } }]] diff --git a/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_create_embedding_with_multiple_inputs.json b/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_create_embedding_with_multiple_inputs.json index 3c3bc2447b..0e5a4ea7b8 100644 --- a/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_create_embedding_with_multiple_inputs.json +++ b/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_create_embedding_with_multiple_inputs.json @@ -39,20 +39,20 @@ }, { "name": "Psr\\Http\\Client\\ClientInterface.sendRequest", - "service": "psr18", + "service": "openai-test", "resource": "sendRequest", "trace_id": 0, "span_id": 2, "parent_id": 1, "type": "http", "meta": { - "_dd.base_service": "openai-test", "component": "psr18", "env": "test", "http.method": "POST", "http.status_code": "200", "http.url": "https://api.openai.com/v1/embeddings?foo=bar", "network.destination.name": "api.openai.com", - "span.kind": "client" + "span.kind": "client", + "version": "1.0" } }]] diff --git a/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_create_file.json b/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_create_file.json index 684ac5cfa7..d139d78c5a 100644 --- a/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_create_file.json +++ b/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_create_file.json @@ -38,20 +38,20 @@ }, { "name": "Psr\\Http\\Client\\ClientInterface.sendRequest", - "service": "psr18", + "service": "openai-test", "resource": "sendRequest", "trace_id": 0, "span_id": 2, "parent_id": 1, "type": "http", "meta": { - "_dd.base_service": "openai-test", "component": "psr18", "env": "test", "http.method": "POST", "http.status_code": "200", "http.url": "https://api.openai.com/v1/files?foo=bar", "network.destination.name": "api.openai.com", - "span.kind": "client" + "span.kind": "client", + "version": "1.0" } }]] diff --git a/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_create_image.json b/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_create_image.json index a6361491f3..1627add52f 100644 --- a/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_create_image.json +++ b/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_create_image.json @@ -37,20 +37,20 @@ }, { "name": "Psr\\Http\\Client\\ClientInterface.sendRequest", - "service": "psr18", + "service": "openai-test", "resource": "sendRequest", "trace_id": 0, "span_id": 2, "parent_id": 1, "type": "http", "meta": { - "_dd.base_service": "openai-test", "component": "psr18", "env": "test", "http.method": "POST", "http.status_code": "200", "http.url": "https://api.openai.com/v1/images/generations?foo=bar", "network.destination.name": "api.openai.com", - "span.kind": "client" + "span.kind": "client", + "version": "1.0" } }]] diff --git a/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_create_image_edit.json b/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_create_image_edit.json index 086211b07d..751b7e5f85 100644 --- a/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_create_image_edit.json +++ b/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_create_image_edit.json @@ -38,20 +38,20 @@ }, { "name": "Psr\\Http\\Client\\ClientInterface.sendRequest", - "service": "psr18", + "service": "openai-test", "resource": "sendRequest", "trace_id": 0, "span_id": 2, "parent_id": 1, "type": "http", "meta": { - "_dd.base_service": "openai-test", "component": "psr18", "env": "test", "http.method": "POST", "http.status_code": "200", "http.url": "https://api.openai.com/v1/images/edits?foo=bar", "network.destination.name": "api.openai.com", - "span.kind": "client" + "span.kind": "client", + "version": "1.0" } }]] diff --git a/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_create_image_variation.json b/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_create_image_variation.json index 23afc4dd12..02d774ef3c 100644 --- a/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_create_image_variation.json +++ b/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_create_image_variation.json @@ -36,20 +36,20 @@ }, { "name": "Psr\\Http\\Client\\ClientInterface.sendRequest", - "service": "psr18", + "service": "openai-test", "resource": "sendRequest", "trace_id": 0, "span_id": 2, "parent_id": 1, "type": "http", "meta": { - "_dd.base_service": "openai-test", "component": "psr18", "env": "test", "http.method": "POST", "http.status_code": "200", "http.url": "https://api.openai.com/v1/images/variations?foo=bar", "network.destination.name": "api.openai.com", - "span.kind": "client" + "span.kind": "client", + "version": "1.0" } }]] diff --git a/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_create_moderation.json b/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_create_moderation.json index be4923056e..cd1ada7adc 100644 --- a/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_create_moderation.json +++ b/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_create_moderation.json @@ -55,20 +55,20 @@ }, { "name": "Psr\\Http\\Client\\ClientInterface.sendRequest", - "service": "psr18", + "service": "openai-test", "resource": "sendRequest", "trace_id": 0, "span_id": 2, "parent_id": 1, "type": "http", "meta": { - "_dd.base_service": "openai-test", "component": "psr18", "env": "test", "http.method": "POST", "http.status_code": "200", "http.url": "https://api.openai.com/v1/moderations?foo=bar", "network.destination.name": "api.openai.com", - "span.kind": "client" + "span.kind": "client", + "version": "1.0" } }]] diff --git a/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_create_transcription_to_json.json b/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_create_transcription_to_json.json index 96fe23a901..16337b676e 100644 --- a/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_create_transcription_to_json.json +++ b/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_create_transcription_to_json.json @@ -35,20 +35,20 @@ }, { "name": "Psr\\Http\\Client\\ClientInterface.sendRequest", - "service": "psr18", + "service": "openai-test", "resource": "sendRequest", "trace_id": 0, "span_id": 2, "parent_id": 1, "type": "http", "meta": { - "_dd.base_service": "openai-test", "component": "psr18", "env": "test", "http.method": "POST", "http.status_code": "200", "http.url": "https://api.openai.com/v1/audio/transcriptions?foo=bar", "network.destination.name": "api.openai.com", - "span.kind": "client" + "span.kind": "client", + "version": "1.0" } }]] diff --git a/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_create_transcription_to_text.json b/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_create_transcription_to_text.json index 70fbd3e6c4..9418de82ad 100644 --- a/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_create_transcription_to_text.json +++ b/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_create_transcription_to_text.json @@ -37,20 +37,20 @@ }, { "name": "Psr\\Http\\Client\\ClientInterface.sendRequest", - "service": "psr18", + "service": "openai-test", "resource": "sendRequest", "trace_id": 0, "span_id": 2, "parent_id": 1, "type": "http", "meta": { - "_dd.base_service": "openai-test", "component": "psr18", "env": "test", "http.method": "POST", "http.status_code": "200", "http.url": "https://api.openai.com/v1/audio/transcriptions?foo=bar", "network.destination.name": "api.openai.com", - "span.kind": "client" + "span.kind": "client", + "version": "1.0" } }]] diff --git a/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_create_transcription_to_verbose_json.json b/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_create_transcription_to_verbose_json.json index 34653aeff1..210faa0a9b 100644 --- a/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_create_transcription_to_verbose_json.json +++ b/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_create_transcription_to_verbose_json.json @@ -37,20 +37,20 @@ }, { "name": "Psr\\Http\\Client\\ClientInterface.sendRequest", - "service": "psr18", + "service": "openai-test", "resource": "sendRequest", "trace_id": 0, "span_id": 2, "parent_id": 1, "type": "http", "meta": { - "_dd.base_service": "openai-test", "component": "psr18", "env": "test", "http.method": "POST", "http.status_code": "200", "http.url": "https://api.openai.com/v1/audio/transcriptions?foo=bar", "network.destination.name": "api.openai.com", - "span.kind": "client" + "span.kind": "client", + "version": "1.0" } }]] diff --git a/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_create_translation_to_json.json b/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_create_translation_to_json.json index b380eb022b..ab40075f97 100644 --- a/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_create_translation_to_json.json +++ b/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_create_translation_to_json.json @@ -35,20 +35,20 @@ }, { "name": "Psr\\Http\\Client\\ClientInterface.sendRequest", - "service": "psr18", + "service": "openai-test", "resource": "sendRequest", "trace_id": 0, "span_id": 2, "parent_id": 1, "type": "http", "meta": { - "_dd.base_service": "openai-test", "component": "psr18", "env": "test", "http.method": "POST", "http.status_code": "200", "http.url": "https://api.openai.com/v1/audio/translations?foo=bar", "network.destination.name": "api.openai.com", - "span.kind": "client" + "span.kind": "client", + "version": "1.0" } }]] diff --git a/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_create_translation_to_text.json b/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_create_translation_to_text.json index 0e772afec9..532e43f7bd 100644 --- a/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_create_translation_to_text.json +++ b/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_create_translation_to_text.json @@ -37,20 +37,20 @@ }, { "name": "Psr\\Http\\Client\\ClientInterface.sendRequest", - "service": "psr18", + "service": "openai-test", "resource": "sendRequest", "trace_id": 0, "span_id": 2, "parent_id": 1, "type": "http", "meta": { - "_dd.base_service": "openai-test", "component": "psr18", "env": "test", "http.method": "POST", "http.status_code": "200", "http.url": "https://api.openai.com/v1/audio/translations?foo=bar", "network.destination.name": "api.openai.com", - "span.kind": "client" + "span.kind": "client", + "version": "1.0" } }]] diff --git a/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_create_translation_to_verbose_json.json b/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_create_translation_to_verbose_json.json index 8d01bd44e9..38bfed3260 100644 --- a/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_create_translation_to_verbose_json.json +++ b/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_create_translation_to_verbose_json.json @@ -37,20 +37,20 @@ }, { "name": "Psr\\Http\\Client\\ClientInterface.sendRequest", - "service": "psr18", + "service": "openai-test", "resource": "sendRequest", "trace_id": 0, "span_id": 2, "parent_id": 1, "type": "http", "meta": { - "_dd.base_service": "openai-test", "component": "psr18", "env": "test", "http.method": "POST", "http.status_code": "200", "http.url": "https://api.openai.com/v1/audio/translations?foo=bar", "network.destination.name": "api.openai.com", - "span.kind": "client" + "span.kind": "client", + "version": "1.0" } }]] diff --git a/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_delete_file.json b/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_delete_file.json index cd21ae389d..95683507b4 100644 --- a/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_delete_file.json +++ b/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_delete_file.json @@ -33,20 +33,20 @@ }, { "name": "Psr\\Http\\Client\\ClientInterface.sendRequest", - "service": "psr18", + "service": "openai-test", "resource": "sendRequest", "trace_id": 0, "span_id": 2, "parent_id": 1, "type": "http", "meta": { - "_dd.base_service": "openai-test", "component": "psr18", "env": "test", "http.method": "DELETE", "http.status_code": "200", "http.url": "https://api.openai.com/v1/files/file-XjGxS3KTG0uNmNOK362iJua3?foo=bar", "network.destination.name": "api.openai.com", - "span.kind": "client" + "span.kind": "client", + "version": "1.0" } }]] diff --git a/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_delete_model.json b/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_delete_model.json index b952a142c8..f1d96dc23c 100644 --- a/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_delete_model.json +++ b/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_delete_model.json @@ -33,20 +33,20 @@ }, { "name": "Psr\\Http\\Client\\ClientInterface.sendRequest", - "service": "psr18", + "service": "openai-test", "resource": "sendRequest", "trace_id": 0, "span_id": 2, "parent_id": 1, "type": "http", "meta": { - "_dd.base_service": "openai-test", "component": "psr18", "env": "test", "http.method": "DELETE", "http.status_code": "200", "http.url": "https://api.openai.com/v1/models/curie:ft-acmeco-2021-03-03-21-44-20?foo=bar", "network.destination.name": "api.openai.com", - "span.kind": "client" + "span.kind": "client", + "version": "1.0" } }]] diff --git a/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_download_file.json b/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_download_file.json index e387894582..9042f57928 100644 --- a/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_download_file.json +++ b/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_download_file.json @@ -29,20 +29,20 @@ }, { "name": "Psr\\Http\\Client\\ClientInterface.sendRequest", - "service": "psr18", + "service": "openai-test", "resource": "sendRequest", "trace_id": 0, "span_id": 2, "parent_id": 1, "type": "http", "meta": { - "_dd.base_service": "openai-test", "component": "psr18", "env": "test", "http.method": "GET", "http.status_code": "200", "http.url": "https://api.openai.com/v1/files/file-XjGxS3KTG0uNmNOK362iJua3/content?foo=bar", "network.destination.name": "api.openai.com", - "span.kind": "client" + "span.kind": "client", + "version": "1.0" } }]] diff --git a/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_list_files.json b/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_list_files.json index c1ac253839..78deb6466f 100644 --- a/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_list_files.json +++ b/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_list_files.json @@ -32,20 +32,20 @@ }, { "name": "Psr\\Http\\Client\\ClientInterface.sendRequest", - "service": "psr18", + "service": "openai-test", "resource": "sendRequest", "trace_id": 0, "span_id": 2, "parent_id": 1, "type": "http", "meta": { - "_dd.base_service": "openai-test", "component": "psr18", "env": "test", "http.method": "GET", "http.status_code": "200", "http.url": "https://api.openai.com/v1/files?foo=bar", "network.destination.name": "api.openai.com", - "span.kind": "client" + "span.kind": "client", + "version": "1.0" } }]] diff --git a/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_list_fine_tune_events.json b/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_list_fine_tune_events.json index a01d3f6b9a..007d8b9e05 100644 --- a/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_list_fine_tune_events.json +++ b/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_list_fine_tune_events.json @@ -33,20 +33,20 @@ }, { "name": "Psr\\Http\\Client\\ClientInterface.sendRequest", - "service": "psr18", + "service": "openai-test", "resource": "sendRequest", "trace_id": 0, "span_id": 2, "parent_id": 1, "type": "http", "meta": { - "_dd.base_service": "openai-test", "component": "psr18", "env": "test", "http.method": "GET", "http.status_code": "200", "http.url": "https://api.openai.com/v1/fine-tunes/ftjob-AF1WoRqd3aJAHsqc9NY7iL8F/events?foo=bar", "network.destination.name": "api.openai.com", - "span.kind": "client" + "span.kind": "client", + "version": "1.0" } }]] diff --git a/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_list_fine_tune_events_stream.json b/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_list_fine_tune_events_stream.json index b72d516465..328997f5cb 100644 --- a/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_list_fine_tune_events_stream.json +++ b/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_list_fine_tune_events_stream.json @@ -31,20 +31,20 @@ }, { "name": "Psr\\Http\\Client\\ClientInterface.sendRequest", - "service": "psr18", + "service": "openai-test", "resource": "sendRequest", "trace_id": 0, "span_id": 2, "parent_id": 1, "type": "http", "meta": { - "_dd.base_service": "openai-test", "component": "psr18", "env": "test", "http.method": "GET", "http.status_code": "200", "http.url": "https://api.openai.com/v1/fine-tunes/ft-MaoEAULREoazpupm8uB7qoIl/events?stream=true?foo=bar", "network.destination.name": "api.openai.com", - "span.kind": "client" + "span.kind": "client", + "version": "1.0" } }]] diff --git a/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_list_models.json b/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_list_models.json index 494a3ae2af..39a08b8714 100644 --- a/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_list_models.json +++ b/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_list_models.json @@ -32,20 +32,20 @@ }, { "name": "Psr\\Http\\Client\\ClientInterface.sendRequest", - "service": "psr18", + "service": "openai-test", "resource": "sendRequest", "trace_id": 0, "span_id": 2, "parent_id": 1, "type": "http", "meta": { - "_dd.base_service": "openai-test", "component": "psr18", "env": "test", "http.method": "GET", "http.status_code": "200", "http.url": "https://api.openai.com/v1/models?foo=bar", "network.destination.name": "api.openai.com", - "span.kind": "client" + "span.kind": "client", + "version": "1.0" } }]] diff --git a/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_list_models_with_error.json b/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_list_models_with_error.json index 7663d968df..12f8f02c2e 100644 --- a/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_list_models_with_error.json +++ b/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_list_models_with_error.json @@ -31,20 +31,20 @@ }, { "name": "Psr\\Http\\Client\\ClientInterface.sendRequest", - "service": "psr18", + "service": "openai-test", "resource": "sendRequest", "trace_id": 0, "span_id": 2, "parent_id": 1, "type": "http", "meta": { - "_dd.base_service": "openai-test", "component": "psr18", "env": "test", "http.method": "GET", "http.status_code": "401", "http.url": "https://api.openai.com/v1/models?foo=bar", "network.destination.name": "api.openai.com", - "span.kind": "client" + "span.kind": "client", + "version": "1.0" } }]] diff --git a/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_list_models_with_null_error_type.json b/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_list_models_with_null_error_type.json index 293a32a64e..261aba3bab 100644 --- a/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_list_models_with_null_error_type.json +++ b/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_list_models_with_null_error_type.json @@ -31,20 +31,20 @@ }, { "name": "Psr\\Http\\Client\\ClientInterface.sendRequest", - "service": "psr18", + "service": "openai-test", "resource": "sendRequest", "trace_id": 0, "span_id": 2, "parent_id": 1, "type": "http", "meta": { - "_dd.base_service": "openai-test", "component": "psr18", "env": "test", "http.method": "GET", "http.status_code": "429", "http.url": "https://api.openai.com/v1/models?foo=bar", "network.destination.name": "api.openai.com", - "span.kind": "client" + "span.kind": "client", + "version": "1.0" } }]] diff --git a/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_log_prompt_completion_sample_rate.json b/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_log_prompt_completion_sample_rate.json index b20195f451..e696dcf82b 100644 --- a/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_log_prompt_completion_sample_rate.json +++ b/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_log_prompt_completion_sample_rate.json @@ -42,20 +42,20 @@ }, { "name": "Psr\\Http\\Client\\ClientInterface.sendRequest", - "service": "psr18", + "service": "openai-test", "resource": "sendRequest", "trace_id": 0, "span_id": 2, "parent_id": 1, "type": "http", "meta": { - "_dd.base_service": "openai-test", "component": "psr18", "env": "test", "http.method": "POST", "http.status_code": "200", "http.url": "https://api.openai.com/v1/completions?foo=bar", "network.destination.name": "api.openai.com", - "span.kind": "client" + "span.kind": "client", + "version": "1.0" } }]] diff --git a/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_logs_disabled.json b/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_logs_disabled.json index 39588732c0..5c639e7fa0 100644 --- a/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_logs_disabled.json +++ b/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_logs_disabled.json @@ -32,20 +32,20 @@ }, { "name": "Psr\\Http\\Client\\ClientInterface.sendRequest", - "service": "psr18", + "service": "openai-test", "resource": "sendRequest", "trace_id": 0, "span_id": 2, "parent_id": 1, "type": "http", "meta": { - "_dd.base_service": "openai-test", "component": "psr18", "env": "test", "http.method": "GET", "http.status_code": "200", "http.url": "https://api.openai.com/v1/models?foo=bar", "network.destination.name": "api.openai.com", - "span.kind": "client" + "span.kind": "client", + "version": "1.0" } }]] diff --git a/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_metrics_disabled.json b/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_metrics_disabled.json index fd99245b57..1f4d8b3226 100644 --- a/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_metrics_disabled.json +++ b/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_metrics_disabled.json @@ -32,20 +32,20 @@ }, { "name": "Psr\\Http\\Client\\ClientInterface.sendRequest", - "service": "psr18", + "service": "openai-test", "resource": "sendRequest", "trace_id": 0, "span_id": 2, "parent_id": 1, "type": "http", "meta": { - "_dd.base_service": "openai-test", "component": "psr18", "env": "test", "http.method": "GET", "http.status_code": "200", "http.url": "https://api.openai.com/v1/models?foo=bar", "network.destination.name": "api.openai.com", - "span.kind": "client" + "span.kind": "client", + "version": "1.0" } }]] diff --git a/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_open_ai_service.json b/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_open_ai_service.json index c67f625ba9..66e9f2c5ac 100644 --- a/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_open_ai_service.json +++ b/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_open_ai_service.json @@ -31,14 +31,13 @@ }, { "name": "Psr\\Http\\Client\\ClientInterface.sendRequest", - "service": "psr18", + "service": "openai", "resource": "sendRequest", "trace_id": 0, "span_id": 2, "parent_id": 1, "type": "http", "meta": { - "_dd.base_service": "openai", "component": "psr18", "env": "test", "http.method": "GET", diff --git a/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_retrieve_file.json b/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_retrieve_file.json index 2192100b9b..e01b9c8e50 100644 --- a/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_retrieve_file.json +++ b/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_retrieve_file.json @@ -37,20 +37,20 @@ }, { "name": "Psr\\Http\\Client\\ClientInterface.sendRequest", - "service": "psr18", + "service": "openai-test", "resource": "sendRequest", "trace_id": 0, "span_id": 2, "parent_id": 1, "type": "http", "meta": { - "_dd.base_service": "openai-test", "component": "psr18", "env": "test", "http.method": "GET", "http.status_code": "200", "http.url": "https://api.openai.com/v1/files/file-XjGxS3KTG0uNmNOK362iJua3?foo=bar", "network.destination.name": "api.openai.com", - "span.kind": "client" + "span.kind": "client", + "version": "1.0" } }]] diff --git a/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_retrieve_fine_tune.json b/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_retrieve_fine_tune.json index 057715cb72..61c1f8e863 100644 --- a/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_retrieve_fine_tune.json +++ b/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_retrieve_fine_tune.json @@ -37,20 +37,20 @@ }, { "name": "Psr\\Http\\Client\\ClientInterface.sendRequest", - "service": "psr18", + "service": "openai-test", "resource": "sendRequest", "trace_id": 0, "span_id": 2, "parent_id": 1, "type": "http", "meta": { - "_dd.base_service": "openai-test", "component": "psr18", "env": "test", "http.method": "GET", "http.status_code": "200", "http.url": "https://api.openai.com/v1/fine_tuning/jobs/ftjob-AF1WoRqd3aJAHsqc9NY7iL8F?foo=bar", "network.destination.name": "api.openai.com", - "span.kind": "client" + "span.kind": "client", + "version": "1.0" } }]] diff --git a/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_retrieve_model.json b/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_retrieve_model.json index 4b5e96fed6..9ed5291b04 100644 --- a/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_retrieve_model.json +++ b/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_retrieve_model.json @@ -34,20 +34,20 @@ }, { "name": "Psr\\Http\\Client\\ClientInterface.sendRequest", - "service": "psr18", + "service": "openai-test", "resource": "sendRequest", "trace_id": 0, "span_id": 2, "parent_id": 1, "type": "http", "meta": { - "_dd.base_service": "openai-test", "component": "psr18", "env": "test", "http.method": "GET", "http.status_code": "200", "http.url": "https://api.openai.com/v1/models/da-vince?foo=bar", "network.destination.name": "api.openai.com", - "span.kind": "client" + "span.kind": "client", + "version": "1.0" } }]] diff --git a/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_span_char_limit.json b/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_span_char_limit.json index 11d9a2da1c..c9b977009b 100644 --- a/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_span_char_limit.json +++ b/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_span_char_limit.json @@ -42,20 +42,20 @@ }, { "name": "Psr\\Http\\Client\\ClientInterface.sendRequest", - "service": "psr18", + "service": "openai-test", "resource": "sendRequest", "trace_id": 0, "span_id": 2, "parent_id": 1, "type": "http", "meta": { - "_dd.base_service": "openai-test", "component": "psr18", "env": "test", "http.method": "POST", "http.status_code": "200", "http.url": "https://api.openai.com/v1/completions?foo=bar", "network.destination.name": "api.openai.com", - "span.kind": "client" + "span.kind": "client", + "version": "1.0" } }]] diff --git a/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_span_prompt_completion_sample_rate.json b/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_span_prompt_completion_sample_rate.json index 1bd498affa..cc3d9685d7 100644 --- a/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_span_prompt_completion_sample_rate.json +++ b/tests/snapshots/tests.integrations.open_ai.open_ai_test.test_span_prompt_completion_sample_rate.json @@ -40,20 +40,20 @@ }, { "name": "Psr\\Http\\Client\\ClientInterface.sendRequest", - "service": "psr18", + "service": "openai-test", "resource": "sendRequest", "trace_id": 0, "span_id": 2, "parent_id": 1, "type": "http", "meta": { - "_dd.base_service": "openai-test", "component": "psr18", "env": "test", "http.method": "POST", "http.status_code": "200", "http.url": "https://api.openai.com/v1/completions?foo=bar", "network.destination.name": "api.openai.com", - "span.kind": "client" + "span.kind": "client", + "version": "1.0" } }]] From 0de558f64ef4a156ba377c3ea35f7a69017bad86 Mon Sep 17 00:00:00 2001 From: Maximo Bautista Date: Wed, 6 Nov 2024 12:25:17 -0500 Subject: [PATCH 21/29] Applying nits changes --- zend_abstract_interface/config/config_decode.c | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/zend_abstract_interface/config/config_decode.c b/zend_abstract_interface/config/config_decode.c index aa2080bfec..c95a971d6b 100644 --- a/zend_abstract_interface/config/config_decode.c +++ b/zend_abstract_interface/config/config_decode.c @@ -131,23 +131,20 @@ static bool zai_config_decode_map(zai_str value, zval *decoded_value, bool persi while (*data == ' ' || *data == '\t' || *data == '\n') data++; - if (*data == ',' || *data == '\0') { - value_start = value_end = NULL; + if (*data == ',' || !*data) { + value_end = NULL; } else { - value_start = data; - value_end = value_start; - - while (*data && *data != ',') { + value_start = value_end = data; + do { if (*data != ' ' && *data != '\t' && *data != '\n') { value_end = data; } data++; - } + } while (*data && *data != ','); } if (key_end && key_start) { size_t key_len = key_end - key_start + 1; - size_t value_len = (value_end && value_start) ? (value_end - value_start + 1) : 0; zend_string *key = zend_string_init(key_start, key_len, persistent); if (lowercase) { @@ -155,7 +152,8 @@ static bool zai_config_decode_map(zai_str value, zval *decoded_value, bool persi } zval val; - if (value_len > 0) { + if (value_end) { + size_t value_len = value_end ? (value_end - value_start + 1) : 0; ZVAL_NEW_STR(&val, zend_string_init(value_start, value_len, persistent)); } else { if (persistent) { @@ -179,7 +177,7 @@ static bool zai_config_decode_map(zai_str value, zval *decoded_value, bool persi } // Handle standalone keys (without a colon) if map_keyless is enabled - if (map_keyless && !has_colon && key_end && key_start) { + if (map_keyless && !has_colon && key_end) { size_t key_len = key_end - key_start + 1; zend_string *key = zend_string_init(key_start, key_len, persistent); if (lowercase) { From c26eda07250b1b29c8e4c3dcf1a5b85b8c0ae6cd Mon Sep 17 00:00:00 2001 From: Maximo Bautista Date: Wed, 6 Nov 2024 12:37:01 -0500 Subject: [PATCH 22/29] Adding spacing tests based on system-test examples --- tests/ext/dd_trace_serialize_header_to_meta.phpt | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/tests/ext/dd_trace_serialize_header_to_meta.phpt b/tests/ext/dd_trace_serialize_header_to_meta.phpt index f9e92f26f4..f8e548765a 100644 --- a/tests/ext/dd_trace_serialize_header_to_meta.phpt +++ b/tests/ext/dd_trace_serialize_header_to_meta.phpt @@ -3,8 +3,10 @@ Headers values are mapped to expected tag key --ENV-- HTTP_CONTENT_TYPE=text/plain HTTP_CUSTOM_HEADER=custom-header-value +HTTP_HEADER1=val +HTTP_HEADER2=v a l DD_TRACE_GENERATE_ROOT_SPAN=0 -DD_TRACE_HEADER_TAGS=Content-Type,Custom-Header:custom-HeaderKey +DD_TRACE_HEADER_TAGS=Content-Type,Custom-Header:custom-HeaderKey,header1: t a g ,header2:tag --GET-- application_key=123 --FILE-- @@ -14,7 +16,11 @@ DDTrace\close_span(); $spans = dd_trace_serialize_closed_spans(); var_dump($spans[0]['meta']['http.request.headers.content-type']); var_dump($spans[0]['meta']['custom-HeaderKey']); +var_dump($spans[0]['meta']['t a g']); +var_dump($spans[0]['meta']['tag']); ?> --EXPECT-- string(10) "text/plain" string(19) "custom-header-value" +string(3) "val" +string(5) "v a l" From 2f104b2484299e5d02cf979a9a3c3ae39bdf2ee6 Mon Sep 17 00:00:00 2001 From: Maximo Bautista Date: Wed, 6 Nov 2024 13:55:00 -0500 Subject: [PATCH 23/29] Removing redundant check --- zend_abstract_interface/config/config_decode.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/zend_abstract_interface/config/config_decode.c b/zend_abstract_interface/config/config_decode.c index c95a971d6b..552360f657 100644 --- a/zend_abstract_interface/config/config_decode.c +++ b/zend_abstract_interface/config/config_decode.c @@ -153,7 +153,7 @@ static bool zai_config_decode_map(zai_str value, zval *decoded_value, bool persi zval val; if (value_end) { - size_t value_len = value_end ? (value_end - value_start + 1) : 0; + size_t value_len = value_end - value_start + 1; ZVAL_NEW_STR(&val, zend_string_init(value_start, value_len, persistent)); } else { if (persistent) { From a987853d3e7e2bcc0099be5ab1bc23c8a7dac2a8 Mon Sep 17 00:00:00 2001 From: Florian Engelhardt Date: Thu, 7 Nov 2024 09:18:38 +0100 Subject: [PATCH 24/29] feat(profiling): Add fatals and thread start/end events to timeline (#2820) --- profiling/build.rs | 32 ++++++++- profiling/src/bindings/mod.rs | 13 ++++ profiling/src/lib.rs | 29 ++++++++ profiling/src/php_ffi.h | 6 ++ profiling/src/profiling/mod.rs | 74 +++++++++++++++++++++ profiling/src/timeline.rs | 117 +++++++++++++++++++++++++++++++++ 6 files changed, 268 insertions(+), 3 deletions(-) diff --git a/profiling/build.rs b/profiling/build.rs index b5b35294ea..a87476a460 100644 --- a/profiling/build.rs +++ b/profiling/build.rs @@ -30,8 +30,9 @@ fn main() { let fibers = cfg_fibers(vernum); let run_time_cache = cfg_run_time_cache(vernum); let trigger_time_sample = cfg_trigger_time_sample(); + let zend_error_observer = cfg_zend_error_observer(vernum); - generate_bindings(php_config_includes, fibers); + generate_bindings(php_config_includes, fibers, zend_error_observer); build_zend_php_ffis( php_config_includes, post_startup_cb, @@ -39,6 +40,7 @@ fn main() { run_time_cache, fibers, trigger_time_sample, + zend_error_observer, vernum, ); @@ -83,6 +85,7 @@ const ZAI_H_FILES: &[&str] = &[ "../zend_abstract_interface/json/json.h", ]; +#[allow(clippy::too_many_arguments)] fn build_zend_php_ffis( php_config_includes: &str, post_startup_cb: bool, @@ -90,6 +93,7 @@ fn build_zend_php_ffis( run_time_cache: bool, fibers: bool, trigger_time_sample: bool, + zend_error_observer: bool, vernum: u64, ) { println!("cargo:rerun-if-changed=src/php_ffi.h"); @@ -135,6 +139,7 @@ fn build_zend_php_ffis( let fibers = if fibers { "1" } else { "0" }; let run_time_cache = if run_time_cache { "1" } else { "0" }; let trigger_time_sample = if trigger_time_sample { "1" } else { "0" }; + let zend_error_observer = if zend_error_observer { "1" } else { "0" }; #[cfg(feature = "stack_walking_tests")] let stack_walking_tests = "1"; @@ -150,6 +155,7 @@ fn build_zend_php_ffis( .define("CFG_RUN_TIME_CACHE", run_time_cache) .define("CFG_STACK_WALKING_TESTS", stack_walking_tests) .define("CFG_TRIGGER_TIME_SAMPLE", trigger_time_sample) + .define("CFG_ZEND_ERROR_OBSERVER", zend_error_observer) .includes([Path::new("../ext")]) .includes( str::replace(php_config_includes, "-I", "") @@ -190,7 +196,7 @@ impl bindgen::callbacks::ParseCallbacks for IgnoreMacros { } } -fn generate_bindings(php_config_includes: &str, fibers: bool) { +fn generate_bindings(php_config_includes: &str, fibers: bool, zend_error_observer: bool) { println!("cargo:rerun-if-changed=src/php_ffi.h"); println!("cargo:rerun-if-changed=../ext/handlers_api.h"); let ignored_macros = IgnoreMacros( @@ -206,12 +212,20 @@ fn generate_bindings(php_config_includes: &str, fibers: bool) { .collect(), ); - let clang_args = if fibers { + let mut clang_args = if fibers { vec!["-D", "CFG_FIBERS=1"] } else { vec!["-D", "CFG_FIBERS=0"] }; + if zend_error_observer { + clang_args.push("-D"); + clang_args.push("CFG_ZEND_ERROR_OBSERVER=1"); + } else { + clang_args.push("-D"); + clang_args.push("CFG_ZEND_ERROR_OBSERVER=0"); + } + let bindings = bindgen::Builder::default() .ctypes_prefix("libc") .clang_args(clang_args) @@ -296,6 +310,18 @@ fn cfg_trigger_time_sample() -> bool { env::var("CARGO_FEATURE_TRIGGER_TIME_SAMPLE").is_ok() } +fn cfg_zend_error_observer(vernum: u64) -> bool { + if vernum >= 80000 { + println!("cargo:rustc-cfg=zend_error_observer"); + if vernum < 80100 { + println!("cargo:rustc-cfg=zend_error_observer_80"); + } + true + } else { + false + } +} + fn cfg_php_major_version(vernum: u64) { let major_version = match vernum { 70000..=79999 => 7, diff --git a/profiling/src/bindings/mod.rs b/profiling/src/bindings/mod.rs index b4b9fe0814..b1734cc87c 100644 --- a/profiling/src/bindings/mod.rs +++ b/profiling/src/bindings/mod.rs @@ -169,12 +169,25 @@ pub struct ModuleEntry { Option ZendResult>, pub info_func: Option, pub version: *const u8, + /// Size of the module globals in bytes. In ZTS this will be the size TSRM will allocate per + /// thread for module globals. The function pointers in [`ModuleEntry::globals_ctor`] and + /// [`ModuleEntry::globals_dtor`] will only be called if this is a non-zero. pub globals_size: size_t, #[cfg(php_zts)] + /// Pointer to a `ts_rsrc_id` (which is a [`i32`]). For C-Extension this is created using the + /// `ZEND_DECLARE_MODULE_GLOBALS(module_name)` macro. + /// See pub globals_id_ptr: *mut ts_rsrc_id, #[cfg(not(php_zts))] + /// Pointer to the module globals struct in NTS mode pub globals_ptr: *mut c_void, + /// Constructor for module globals. + /// Be aware this will only be called in case [`ModuleEntry::globals_size`] is non-zero and for + /// ZTS you need to make sure [`ModuleEntry::globals_id_ptr`] is a valid, non-null pointer. pub globals_ctor: Option, + /// Destructor for module globals. + /// Be aware this will only be called in case [`ModuleEntry::globals_size`] is non-zero and for + /// ZTS you need to make sure [`ModuleEntry::globals_id_ptr`] is a valid, non-null pointer. pub globals_dtor: Option, pub post_deactivate_func: Option ZendResult>, pub module_started: c_int, diff --git a/profiling/src/lib.rs b/profiling/src/lib.rs index 02cb66a8e8..d3232c2898 100644 --- a/profiling/src/lib.rs +++ b/profiling/src/lib.rs @@ -31,6 +31,8 @@ use core::ptr; use ddcommon::{cstr, tag, tag::Tag}; use lazy_static::lazy_static; use libc::c_char; +#[cfg(php_zts)] +use libc::c_void; use log::{debug, error, info, trace, warn}; use once_cell::sync::{Lazy, OnceCell}; use profiling::{LocalRootSpanResourceMessage, Profiler, VmInterrupt}; @@ -128,6 +130,13 @@ extern "C" { pub static ddtrace_runtime_id: *const Uuid; } +/// We do not have any globals, but we need TSRM to call into GINIT and GSHUTDOWN to observe +/// spawning and joining threads. This will be pointed to by the [`ModuleEntry::globals_id_ptr`] in +/// the `zend_module_entry` and the TSRM will store it's thread-safe-resource id here. +/// See: +#[cfg(php_zts)] +static mut GLOBALS_ID_PTR: i32 = 0; + /// The function `get_module` is what makes this a PHP module. Please do not /// call this directly; only let it be called by the engine. Generally it is /// only called once, but if someone accidentally loads the module twice then @@ -160,6 +169,14 @@ pub extern "C" fn get_module() -> &'static mut zend::ModuleEntry { version: PROFILER_VERSION.as_ptr(), post_deactivate_func: Some(prshutdown), deps: DEPS.as_ptr(), + #[cfg(php_zts)] + globals_ctor: Some(ginit), + #[cfg(php_zts)] + globals_dtor: Some(gshutdown), + #[cfg(php_zts)] + globals_size: 1, + #[cfg(php_zts)] + globals_id_ptr: unsafe { &mut GLOBALS_ID_PTR }, ..Default::default() }); @@ -167,6 +184,18 @@ pub extern "C" fn get_module() -> &'static mut zend::ModuleEntry { unsafe { &mut *ptr::addr_of_mut!(MODULE) } } +#[cfg(php_zts)] +unsafe extern "C" fn ginit(_globals_ptr: *mut c_void) { + #[cfg(all(feature = "timeline", php_zts))] + timeline::timeline_ginit(); +} + +#[cfg(php_zts)] +unsafe extern "C" fn gshutdown(_globals_ptr: *mut c_void) { + #[cfg(all(feature = "timeline", php_zts))] + timeline::timeline_gshutdown(); +} + /* Important note on the PHP lifecycle: * Based on how some SAPIs work and the documentation, one might expect that * MINIT is called once per process, but this is only sort-of true. Some SAPIs diff --git a/profiling/src/php_ffi.h b/profiling/src/php_ffi.h index d2c1123e9b..15de64ec0a 100644 --- a/profiling/src/php_ffi.h +++ b/profiling/src/php_ffi.h @@ -16,6 +16,12 @@ #include +// Needed for `zend_observer_error_register` starting from PHP 8 +#if CFG_ZEND_ERROR_OBSERVER // defined by build.rs +#include +#include +#endif + // Profiling needs ZAI config for INI support. #include // And json to cleanup json state for graceful restart diff --git a/profiling/src/profiling/mod.rs b/profiling/src/profiling/mod.rs index f98fee3484..9b59d4fd9c 100644 --- a/profiling/src/profiling/mod.rs +++ b/profiling/src/profiling/mod.rs @@ -976,6 +976,80 @@ impl Profiler { } } + /// This function will collect a thread start or stop timeline event + #[cfg(all(feature = "timeline", php_zts))] + pub fn collect_thread_start_end(&self, now: i64, event: &'static str) { + let mut labels = Profiler::common_labels(1); + + labels.push(Label { + key: "event", + value: LabelValue::Str(std::borrow::Cow::Borrowed(event)), + }); + + let n_labels = labels.len(); + + match self.prepare_and_send_message( + vec![ZendFrame { + function: format!("[{event}]").into(), + file: None, + line: 0, + }], + SampleValues { + timeline: 1, + ..Default::default() + }, + labels, + now, + ) { + Ok(_) => { + trace!("Sent event '{event}' with {n_labels} labels to profiler.") + } + Err(err) => { + warn!("Failed to send event '{event}' with {n_labels} labels to profiler: {err}") + } + } + } + + /// This function can be called to collect any fatal errors + #[cfg(feature = "timeline")] + pub fn collect_fatal(&self, now: i64, file: String, line: u32, message: String) { + let mut labels = Profiler::common_labels(2); + + labels.push(Label { + key: "event", + value: LabelValue::Str("fatal".into()), + }); + labels.push(Label { + key: "message", + value: LabelValue::Str(message.into()), + }); + + let n_labels = labels.len(); + + match self.prepare_and_send_message( + vec![ZendFrame { + function: "[fatal]".into(), + file: Some(file), + line, + }], + SampleValues { + timeline: 1, + ..Default::default() + }, + labels, + now, + ) { + Ok(_) => { + trace!("Sent event 'fatal error' with {n_labels} labels to profiler.") + } + Err(err) => { + warn!( + "Failed to send event 'fatal error' with {n_labels} labels to profiler: {err}" + ) + } + } + } + /// This function can be called to collect any kind of inactivity that is happening #[cfg(feature = "timeline")] pub fn collect_idle(&self, now: i64, duration: i64, reason: &'static str) { diff --git a/profiling/src/timeline.rs b/profiling/src/timeline.rs index 596c887a14..ab69528ca1 100644 --- a/profiling/src/timeline.rs +++ b/profiling/src/timeline.rs @@ -6,6 +6,8 @@ use crate::zend::{ use crate::REQUEST_LOCALS; use libc::c_char; use log::{error, trace}; +#[cfg(php_zts)] +use std::cell::Cell; use std::cell::RefCell; use std::ffi::CStr; use std::ptr; @@ -30,11 +32,17 @@ static mut FRANKENPHP_HANDLE_REQUEST_HANDLER: InternalFunctionHandler = None; thread_local! { static IDLE_SINCE: RefCell = RefCell::new(Instant::now()); + #[cfg(php_zts)] + static IS_NEW_THREAD: Cell = const { Cell::new(false) }; } enum State { Idle, Sleeping, + #[cfg(php_zts)] + ThreadStart, + #[cfg(php_zts)] + ThreadStop, } impl State { @@ -42,6 +50,10 @@ impl State { match self { State::Idle => "idle", State::Sleeping => "sleeping", + #[cfg(php_zts)] + State::ThreadStart => "thread start", + #[cfg(php_zts)] + State::ThreadStop => "thread stop", } } } @@ -144,9 +156,48 @@ unsafe extern "C" fn ddog_php_prof_frankenphp_handle_request( } } +/// Will be called by the ZendEngine on all errors happening. This is a PHP 8 API +#[cfg(zend_error_observer)] +unsafe extern "C" fn ddog_php_prof_zend_error_observer( + _type: i32, + #[cfg(zend_error_observer_80)] file: *const c_char, + #[cfg(not(zend_error_observer_80))] file: *mut zend::ZendString, + line: u32, + message: *mut zend::ZendString, +) { + // we are only interested in FATAL errors + + if _type & zend::E_FATAL_ERRORS as i32 == 0 { + return; + } + + #[cfg(zend_error_observer_80)] + let file = unsafe { + let mut len = 0; + let file = file as *const u8; + while *file.add(len) != 0 { + len += 1; + } + std::str::from_utf8_unchecked(std::slice::from_raw_parts(file, len)).to_string() + }; + #[cfg(not(zend_error_observer_80))] + let file = unsafe { zend::zai_str_from_zstr(file.as_mut()).into_string() }; + + let now = SystemTime::now().duration_since(UNIX_EPOCH).unwrap(); + if let Some(profiler) = Profiler::get() { + let now = now.as_nanos() as i64; + profiler.collect_fatal(now, file, line, unsafe { + zend::zai_str_from_zstr(message.as_mut()).into_string() + }); + } +} + /// This functions needs to be called in MINIT of the module pub fn timeline_minit() { unsafe { + #[cfg(zend_error_observer)] + zend::zend_observer_error_register(Some(ddog_php_prof_zend_error_observer)); + // register our function in the `gc_collect_cycles` pointer PREV_GC_COLLECT_CYCLES = zend::gc_collect_cycles; zend::gc_collect_cycles = Some(ddog_php_prof_gc_collect_cycles); @@ -231,6 +282,35 @@ pub unsafe fn timeline_rinit() { } }); }); + + #[cfg(php_zts)] + IS_NEW_THREAD.with(|cell| { + if !cell.get() { + return; + } + cell.set(false); + REQUEST_LOCALS.with(|cell| { + let is_timeline_enabled = cell + .try_borrow() + .map(|locals| locals.system_settings().profiling_timeline_enabled) + .unwrap_or(false); + + if !is_timeline_enabled { + return; + } + + if let Some(profiler) = Profiler::get() { + profiler.collect_thread_start_end( + // Safety: checked for `is_err()` above + SystemTime::now() + .duration_since(UNIX_EPOCH) + .unwrap() + .as_nanos() as i64, + State::ThreadStart.as_str(), + ); + } + }); + }); } /// This function is run during the P-RSHUTDOWN phase and resets the `IDLE_SINCE` thread local to @@ -290,6 +370,43 @@ pub(crate) unsafe fn timeline_mshutdown() { } }); }); + #[cfg(php_zts)] + timeline_gshutdown(); +} + +#[cfg(php_zts)] +pub(crate) fn timeline_ginit() { + // During GINIT in "this" thread, the request locals are not initialized, which happens in + // RINIT, so we currently do not know if profile is enabled at all and if, if timeline is + // enabled. That's why we raise this flag here and read it in RINIT. + IS_NEW_THREAD.with(|cell| { + cell.set(true); + }); +} + +#[cfg(php_zts)] +pub(crate) fn timeline_gshutdown() { + REQUEST_LOCALS.with(|cell| { + let is_timeline_enabled = cell + .try_borrow() + .map(|locals| locals.system_settings().profiling_timeline_enabled) + .unwrap_or(false); + + if !is_timeline_enabled { + return; + } + + if let Some(profiler) = Profiler::get() { + profiler.collect_thread_start_end( + // Safety: checked for `is_err()` above + SystemTime::now() + .duration_since(UNIX_EPOCH) + .unwrap() + .as_nanos() as i64, + State::ThreadStop.as_str(), + ); + } + }); } /// This function gets called when a `eval()` is being called. This is done by letting the From 1adda6c11362d95dab1b86fcf3bda628d108b4ba Mon Sep 17 00:00:00 2001 From: Bob Weinand Date: Thu, 7 Nov 2024 13:28:19 +0100 Subject: [PATCH 25/29] Handle hooks on trampoline fake closures (#2925) It may not be perfect, but we cannot trivially check for zend_closure_call_magic being the internal method due to that one being static. I assume it to be good enough unless proven otherwise. Signed-off-by: Bob Weinand --- ext/hook/uhook.c | 24 +++++++++--- .../trampoline_install_fake_closure_hook.phpt | 39 +++++++++++++++++++ 2 files changed, 57 insertions(+), 6 deletions(-) create mode 100644 tests/ext/sandbox-regression/trampoline_install_fake_closure_hook.phpt diff --git a/ext/hook/uhook.c b/ext/hook/uhook.c index 039e60f02c..e186583ecc 100644 --- a/ext/hook/uhook.c +++ b/ext/hook/uhook.c @@ -491,7 +491,7 @@ static void dd_uhook_dtor(void *data) { #define _error_code error_code #endif -/* {{{ proto int DDTrace\install_hook(string|Closure|Generator target, ?Closure begin = null, ?Closure end = null) */ +/* {{{ proto int DDTrace\install_hook(string|Closure|Generator target, ?Closure begin = null, ?Closure end = null, int flags = 0) */ PHP_FUNCTION(DDTrace_install_hook) { zend_string *name = NULL; zend_function *resolved = NULL; @@ -583,17 +583,29 @@ PHP_FUNCTION(DDTrace_install_hook) { def->function = NULL; // Fetch the base function for fake closures: we need to do fake closure operations on the proper original function: - // - inheritance handling requires having an op_array which stays alive for the whole remainder of the rquest + // - inheritance handling requires having an op_array which stays alive for the whole remainder of the request // - internal functions are referenced by their zend_internal_function, not the closure copy if ((resolved->common.fn_flags & ZEND_ACC_FAKE_CLOSURE) && !(flags & HOOK_INSTANCE)) { - HashTable *baseTable = resolved->common.scope ? &resolved->common.scope->function_table : EG(function_table); + zend_class_entry *resolved_ce = resolved->common.scope; + HashTable *baseTable = resolved_ce ? &resolved_ce->function_table : EG(function_table); zend_function *original = zend_hash_find_ptr(baseTable, resolved->common.function_name); + if (!ZEND_USER_CODE(resolved->type)) { + if (original && original->type != resolved->type /* check for trampoline */) { + original = NULL; // this may happen with e.g. __call() where the function is defined as private + } + if (!original && resolved_ce) { + // Assume it's a __call or __callStatic trampoline + // Execute logic from zend_closure_call_magic here. + original = (resolved->common.fn_flags & ZEND_ACC_STATIC) ? resolved_ce->__callstatic : resolved_ce->__call; + } + } if (!original) { - LOG(ERROR, - "Could not find original function for fake closure ", + LOG(WARN, + "Could not find original function for fake closure %s%s%s at %s:%d", resolved->common.scope ? ZSTR_VAL(resolved->common.scope->name) : "", resolved->common.scope ? "::" : "", - ZSTR_VAL(resolved->common.function_name)); + ZSTR_VAL(resolved->common.function_name), + zend_get_executed_filename(), zend_get_executed_lineno()); goto error; } resolved = original; diff --git a/tests/ext/sandbox-regression/trampoline_install_fake_closure_hook.phpt b/tests/ext/sandbox-regression/trampoline_install_fake_closure_hook.phpt new file mode 100644 index 0000000000..08d96482e8 --- /dev/null +++ b/tests/ext/sandbox-regression/trampoline_install_fake_closure_hook.phpt @@ -0,0 +1,39 @@ +--TEST-- +Test installing hook on trampoline fake closure +--SKIPIF-- + +--FILE-- +test(...); +DDTrace\install_hook($x, function($hook) { + echo "Hooked\n"; +}); + +$x(); +(new A)->test(); + +DDTrace\install_hook((new A)->shadow(...), function($hook) { + echo "Shadow hooked\n"; +}); +(new A)->shadow(); + +?> +--EXPECT-- +Hooked +Invoked test +Hooked +Invoked test +Hooked +Shadow hooked +Invoked shadow From a9d427486fed49053b3bd7351c57dc6c4214d3b8 Mon Sep 17 00:00:00 2001 From: Bob Weinand Date: Thu, 7 Nov 2024 13:28:37 +0100 Subject: [PATCH 26/29] Fix crash with locals collection in generator close sequence (#2932) Signed-off-by: Bob Weinand --- ext/collect_backtrace.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/ext/collect_backtrace.c b/ext/collect_backtrace.c index 4ea860a687..43cd3f3eef 100644 --- a/ext/collect_backtrace.c +++ b/ext/collect_backtrace.c @@ -12,6 +12,12 @@ void ddtrace_call_get_locals(zend_execute_data *call, zval *locals_array, bool skip_args) { zend_op_array *op_array = &call->func->op_array; +#if PHP_VERSION_ID >= 80000 // Pre-PHP 8 there was "safe destruction" of CVs, whereby they were ZVAL_NULL()'ed, avoiding the need for this handling. + if (UNEXPECTED((ZEND_CALL_INFO(call) & ZEND_CALL_GENERATOR) != 0) && ((zend_generator*)call->return_value)->execute_data == NULL) { + return; // Prevent locals collection in generator close, they may already be freed now. + } +#endif + #if PHP_VERSION_ID >= 70100 if (ZEND_CALL_INFO(call) & ZEND_CALL_HAS_SYMBOL_TABLE) #else From 330d8a408ea855f21d71441c81247392e3aa87a7 Mon Sep 17 00:00:00 2001 From: Bob Weinand Date: Thu, 7 Nov 2024 18:28:53 +0100 Subject: [PATCH 27/29] Fix macos build where ld will break with -Wl,--undefined-version (#2936) It's clang, but a different clang. It's better to do actual checks for the functionailty than checking for a specific compiler. Signed-off-by: Bob Weinand --- config.m4 | 38 ++++++++++++++++++-------------------- 1 file changed, 18 insertions(+), 20 deletions(-) diff --git a/config.m4 b/config.m4 index 21b6e597a0..88ea035020 100644 --- a/config.m4 +++ b/config.m4 @@ -14,7 +14,7 @@ PHP_ARG_WITH(ddtrace-cargo, where cargo is located for rust code compilation, [ --with-ddtrace-cargo Location to cargo binary for rust compilation], cargo, not found) PHP_ARG_ENABLE(ddtrace-rust-debug, whether to compile rust in debug mode, - [ --enable-ddtrace-rust-debug Build rust code in debug mode (significantly slower)], [[$($GREP -q "ZEND_DEBUG 1" $("$PHP_CONFIG" --include-dir)/main/php_config.h && echo yes || echo no)]], [no]) + [ --enable-ddtrace-rust-debug Build rust code in debug mode (significantly slower)], [[$( (if test x"$ext_shared" = x"yes"; then $GREP -q "ZEND_DEBUG 1" $("$PHP_CONFIG" --include-dir)/main/php_config.h; else test x"$PHP_DEBUG" = x"yes"; fi) && echo yes || echo no)]], [no]) PHP_ARG_ENABLE(ddtrace-rust-library-split, whether to not link the rust library against the extension at compile time, [ --enable-ddtrace-rust-library-split Do not build nor link against the rust code], no, no) @@ -78,25 +78,23 @@ if test "$PHP_DDTRACE" != "no"; then CFLAGS="$CFLAGS -fms-extensions" EXTRA_CFLAGS="$EXTRA_CFLAGS -fms-extensions" - AC_MSG_CHECKING([whether the compiler is LLVM]) - - - AC_RUN_IFELSE([AC_LANG_SOURCE([[int main(void) { -#ifdef __clang__ - return 0; -#else - return 1; -#endif -}]])],[llvm=yes],[llvm=no],[llvm=yes]) - - if test "$llvm" = "yes"; then - AC_MSG_RESULT([yes]) - CFLAGS="$CFLAGS -Wno-microsoft-anon-tag" - EXTRA_CFLAGS="$EXTRA_CFLAGS -Wno-microsoft-anon-tag" - LDFLAGS="$LDFLAGS -Wl,--undefined-version" - else - AC_MSG_RESULT([no]) - fi + rm="rm -f" + lt_simple_link_test_code='int main(void){return(0);}' + AC_MSG_CHECKING([whether --undefined-version is a valid linker argument]) + AC_LIBTOOL_LINKER_OPTION([whether --undefined-version is a valid linker argument], + lt_cv_ddtrace_undefined_version, + [-Wl,--undefined-version], + [LDFLAGS="$LDFLAGS -Wl,--undefined-version"]) + + lt_simple_compile_test_code="int some_variable = 0;" + Xsed="$SED -e 1s/^X//" + AC_LIBTOOL_COMPILER_OPTION([whether -Wno-microsoft-anon-tag is a valid compiler argument], + lt_cv_ddtrace_no_microsoft_anon_tag, + [-Wno-microsoft-anon-tag], [], + [ + CFLAGS="$CFLAGS -Wno-microsoft-anon-tag" + EXTRA_CFLAGS="$EXTRA_CFLAGS -Wno-microsoft-anon-tag" + ]) DD_TRACE_VENDOR_SOURCES="\ ext/vendor/mpack/mpack.c \ From 68f8558f639e6171e7b958e8832d41c30cdf0e14 Mon Sep 17 00:00:00 2001 From: Bob Weinand Date: Fri, 8 Nov 2024 12:47:56 +0100 Subject: [PATCH 28/29] Avoid the hook frame in mysqli connection error tracking (#2937) Otherwise the error stems from "Mysqli/MysqliIntegration.php:379" which may be confusing and seemingly hint at a problem in our integrations. --- src/DDTrace/Integrations/Mysqli/MysqliIntegration.php | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/DDTrace/Integrations/Mysqli/MysqliIntegration.php b/src/DDTrace/Integrations/Mysqli/MysqliIntegration.php index a6a603b7fe..e1b374e725 100644 --- a/src/DDTrace/Integrations/Mysqli/MysqliIntegration.php +++ b/src/DDTrace/Integrations/Mysqli/MysqliIntegration.php @@ -376,7 +376,9 @@ public function trackPotentialError(SpanData $span) { $errorCode = mysqli_connect_errno(); if ($errorCode > 0) { - $span->exception = new \Exception(mysqli_connect_error()); + $span->meta[Tag::ERROR_MSG] = mysqli_connect_error(); + $span->meta[Tag::ERROR_TYPE] = 'mysqli error'; + $span->meta[Tag::ERROR_STACK] = \DDTrace\get_sanitized_exception_trace(new \Exception, 2); } } } From 84f7fa87d1f61d52447003f44ecf585ef3971c9d Mon Sep 17 00:00:00 2001 From: Florian Engelhardt Date: Fri, 8 Nov 2024 14:00:24 +0100 Subject: [PATCH 29/29] ci: update PHP 8.4 to rc4 (#2938) * update PHP 8.4 RC3 -> RC4 * images are debian, not ubuntu --- .gitlab/ci-images.yml | 6 +++--- dockerfiles/ci/alpine_compile_extension/docker-compose.yml | 4 ++-- dockerfiles/ci/bookworm/docker-compose.yml | 4 ++-- dockerfiles/ci/buster/docker-compose.yml | 4 ++-- dockerfiles/ci/centos/7/docker-compose.yml | 4 ++-- dockerfiles/ci/windows/docker-compose.yml | 4 ++-- 6 files changed, 13 insertions(+), 13 deletions(-) diff --git a/.gitlab/ci-images.yml b/.gitlab/ci-images.yml index b2130f42ce..8b76d3952f 100644 --- a/.gitlab/ci-images.yml +++ b/.gitlab/ci-images.yml @@ -35,7 +35,7 @@ CentOS: - docker login -u "$CI_REGISTRY_USER" -p "$CI_REGISTRY_TOKEN" $CI_REGISTRY - docker buildx bake --no-cache --pull --push $PHP_VERSION -Alpine Compile Extension: +Alpine: stage: ci-build rules: - when: manual @@ -62,7 +62,7 @@ Alpine Compile Extension: - docker login -u "$CI_REGISTRY_USER" -p "$CI_REGISTRY_TOKEN" $CI_REGISTRY - docker buildx bake --no-cache --pull --push $PHP_VERSION -Ubuntu Bookworm: +Bookworm: stage: ci-build rules: - when: manual @@ -91,7 +91,7 @@ Ubuntu Bookworm: - docker login -u "$CI_REGISTRY_USER" -p "$CI_REGISTRY_TOKEN" $CI_REGISTRY - docker buildx bake --no-cache --pull --push $PHP_VERSION -Ubuntu Buster: +Buster: stage: ci-build rules: - when: manual diff --git a/dockerfiles/ci/alpine_compile_extension/docker-compose.yml b/dockerfiles/ci/alpine_compile_extension/docker-compose.yml index 026aedf606..840f43f519 100644 --- a/dockerfiles/ci/alpine_compile_extension/docker-compose.yml +++ b/dockerfiles/ci/alpine_compile_extension/docker-compose.yml @@ -129,8 +129,8 @@ services: x-bake: *bake args: php_version: 8.4.0 - php_url: https://downloads.php.net/~saki/php-8.4.0RC1.tar.gz - php_sha: ff924ce24493cd546c7227c2cedf75c32d23815b0a6e5c1658d9b005837631ff + php_url: https://downloads.php.net/~calvinb/php-8.4.0RC4.tar.gz + php_sha: 3964fee49465e6fcae77ad030ae31aa720ade0a51c53df6e255e36eb867fd4b2 php_api: 20240924 volumes: - ../../:/app diff --git a/dockerfiles/ci/bookworm/docker-compose.yml b/dockerfiles/ci/bookworm/docker-compose.yml index 1f3f3b1e60..dc980743ef 100644 --- a/dockerfiles/ci/bookworm/docker-compose.yml +++ b/dockerfiles/ci/bookworm/docker-compose.yml @@ -22,8 +22,8 @@ services: args: <<: *build-base phpVersion: "8.4" - phpTarGzUrl: https://downloads.php.net/~saki/php-8.4.0RC3.tar.gz - phpSha256Hash: "1937d125c9bb42bc4d8dcd3b8bb25d377814aea50be492bbc64b3554b73af371" + phpTarGzUrl: https://downloads.php.net/~calvinb/php-8.4.0RC4.tar.gz + phpSha256Hash: "3964fee49465e6fcae77ad030ae31aa720ade0a51c53df6e255e36eb867fd4b2" php-8.3: image: datadog/dd-trace-ci:php-8.3_bookworm-$BOOKWORM_NEXT_VERSION diff --git a/dockerfiles/ci/buster/docker-compose.yml b/dockerfiles/ci/buster/docker-compose.yml index 8a553367e5..b900ee38f5 100644 --- a/dockerfiles/ci/buster/docker-compose.yml +++ b/dockerfiles/ci/buster/docker-compose.yml @@ -17,8 +17,8 @@ services: x-bake: *bake args: phpVersion: "8.4" - phpTarGzUrl: https://downloads.php.net/~saki/php-8.4.0RC3.tar.gz - phpSha256Hash: "1937d125c9bb42bc4d8dcd3b8bb25d377814aea50be492bbc64b3554b73af371" + phpTarGzUrl: https://downloads.php.net/~calvinb/php-8.4.0RC4.tar.gz + phpSha256Hash: "3964fee49465e6fcae77ad030ae31aa720ade0a51c53df6e255e36eb867fd4b2" php-8.3: image: datadog/dd-trace-ci:php-8.3_buster diff --git a/dockerfiles/ci/centos/7/docker-compose.yml b/dockerfiles/ci/centos/7/docker-compose.yml index 20e9a2a83a..d37da8a6c8 100644 --- a/dockerfiles/ci/centos/7/docker-compose.yml +++ b/dockerfiles/ci/centos/7/docker-compose.yml @@ -117,6 +117,6 @@ services: x-bake: *bake args: phpVersion: "8.4" - phpTarGzUrl: https://downloads.php.net/~saki/php-8.4.0RC3.tar.gz - phpSha256Hash: "1937d125c9bb42bc4d8dcd3b8bb25d377814aea50be492bbc64b3554b73af371" + phpTarGzUrl: https://downloads.php.net/~calvinb/php-8.4.0RC4.tar.gz + phpSha256Hash: "3964fee49465e6fcae77ad030ae31aa720ade0a51c53df6e255e36eb867fd4b2" image: 'datadog/dd-trace-ci:php-8.4_centos-7' diff --git a/dockerfiles/ci/windows/docker-compose.yml b/dockerfiles/ci/windows/docker-compose.yml index db9d073d47..3e7bfb0e37 100644 --- a/dockerfiles/ci/windows/docker-compose.yml +++ b/dockerfiles/ci/windows/docker-compose.yml @@ -87,8 +87,8 @@ services: args: phpVersion: "8.4.0RC3" vsVersion: "vs17" - phpTarGzUrl: https://downloads.php.net/~saki/php-8.4.0RC3.tar.gz - phpSha256Hash: "1937d125c9bb42bc4d8dcd3b8bb25d377814aea50be492bbc64b3554b73af371" + phpTarGzUrl: https://downloads.php.net/~calvinb/php-8.4.0RC4.tar.gz + phpSha256Hash: "3964fee49465e6fcae77ad030ae31aa720ade0a51c53df6e255e36eb867fd4b2" php-8.3: image: datadog/dd-trace-ci:php-8.3_windows