diff --git a/agent/native/ext/ConfigManager.cpp b/agent/native/ext/ConfigManager.cpp index b27ed5998..9256e2d4c 100644 --- a/agent/native/ext/ConfigManager.cpp +++ b/agent/native/ext/ConfigManager.cpp @@ -27,12 +27,14 @@ #ifndef ELASTIC_APM_MOCK_PHP_DEPS # include #endif +#include #include "elastic_apm_assert.h" #include "log.h" #include "util.h" #include "TextOutputStream.h" #include "elastic_apm_alloc.h" #include "time_util.h" +#include "basic_macros.h" #define ELASTIC_APM_CURRENT_LOG_CATEGORY ELASTIC_APM_LOG_CATEGORY_CONFIG @@ -136,6 +138,8 @@ typedef String (* StreamParsedValueFunc )( const OptionMetadata* optMeta, Parsed typedef void (* SetConfigSnapshotFieldFunc )( const OptionMetadata* optMeta, ParsedOptionValue parsedValue, ConfigSnapshot* dst ); typedef ParsedOptionValue (* GetConfigSnapshotFieldFunc )( const OptionMetadata* optMeta, const ConfigSnapshot* src ); typedef void (* ParsedOptionValueToZvalFunc )( const OptionMetadata* optMeta, ParsedOptionValue parsedValue, zval* return_value ); +typedef bool (* AreEqualParsedValuesFunc )( const OptionMetadata* optMeta, ParsedOptionValue parsedValue1, ParsedOptionValue parsedValue2 ); + struct OptionMetadata { String name = nullptr; @@ -150,6 +154,7 @@ struct OptionMetadata SetConfigSnapshotFieldFunc setField = nullptr; GetConfigSnapshotFieldFunc getField = nullptr; ParsedOptionValueToZvalFunc parsedValueToZval = nullptr; + AreEqualParsedValuesFunc areEqualParsedValues = nullptr; OptionAdditionalMetadata additionalData = {}; }; @@ -279,6 +284,14 @@ static void parsedStringValueToZval( const OptionMetadata* optMeta, ParsedOption RETURN_STRING( parsedValue.u.stringValue ); } +static bool areEqualParsedStringValues( const OptionMetadata* optMeta, ParsedOptionValue parsedValue1, ParsedOptionValue parsedValue2 ) +{ + return + (parsedValue1.u.stringValue == nullptr || parsedValue2.u.stringValue == nullptr) + ? (parsedValue1.u.stringValue == parsedValue2.u.stringValue) + : strcmp(parsedValue1.u.stringValue, parsedValue2.u.stringValue) == 0; +} + static ResultCode parseBoolValueImpl( const OptionMetadata* optMeta, ParsedOptionValueType expectedType, String rawValue, /* out */ ParsedOptionValue* parsedValue ) { ELASTIC_APM_ASSERT_VALID_PTR( optMeta ); @@ -335,6 +348,11 @@ static void parsedBoolValueToZval( const OptionMetadata* optMeta, ParsedOptionVa RETURN_BOOL( parsedValue.u.boolValue ); } +static bool areEqualParsedBoolValues( const OptionMetadata* optMeta, ParsedOptionValue parsedValue1, ParsedOptionValue parsedValue2 ) +{ + return parsedValue1.u.boolValue == parsedValue2.u.boolValue; +} + static ResultCode parseOptionalBoolValue( const OptionMetadata* optMeta, String rawValue, /* out */ ParsedOptionValue* parsedValue ) { ParsedOptionValue tempParsedValue; @@ -368,6 +386,14 @@ static void parsedOptionalBoolValueToZval( const OptionMetadata* optMeta, Parsed RETURN_STRING( optionalBoolToString( parsedValue.u.optionalBoolValue ) ); } +static bool areEqualParsedOptionalBoolValues( const OptionMetadata* optMeta, ParsedOptionValue parsedValue1, ParsedOptionValue parsedValue2 ) +{ + return + (parsedValue1.u.optionalBoolValue.isSet && parsedValue2.u.optionalBoolValue.isSet) + ? (parsedValue1.u.optionalBoolValue.value == parsedValue2.u.optionalBoolValue.value) + : (parsedValue1.u.optionalBoolValue.isSet == parsedValue2.u.optionalBoolValue.isSet); +} + static ResultCode parseDurationValue( const OptionMetadata* optMeta, String rawValue, /* out */ ParsedOptionValue* parsedValue ) { ELASTIC_APM_ASSERT_VALID_PTR( optMeta ); @@ -412,6 +438,11 @@ static void parsedDurationValueToZval( const OptionMetadata* optMeta, ParsedOpti RETURN_DOUBLE( durationToMilliseconds( parsedValue.u.durationValue ) ); } +static bool areEqualParsedDurationValues( const OptionMetadata* optMeta, ParsedOptionValue parsedValue1, ParsedOptionValue parsedValue2 ) +{ + return durationToMilliseconds(parsedValue1.u.durationValue) == durationToMilliseconds(parsedValue2.u.durationValue); +} + static ResultCode parseSizeValue( const OptionMetadata* optMeta, String rawValue, /* out */ ParsedOptionValue* parsedValue ) { ELASTIC_APM_ASSERT_VALID_PTR( optMeta ); @@ -448,6 +479,11 @@ static void parsedSizeValueToZval( const OptionMetadata* optMeta, ParsedOptionVa RETURN_DOUBLE( sizeToBytes( parsedValue.u.sizeValue ) ); } +static bool areEqualParsedSizeValues( const OptionMetadata* optMeta, ParsedOptionValue parsedValue1, ParsedOptionValue parsedValue2 ) +{ + return sizeToBytes(parsedValue1.u.sizeValue) == sizeToBytes(parsedValue2.u.sizeValue); +} + static ResultCode parseEnumValue( const OptionMetadata* optMeta, String rawValue, /* out */ ParsedOptionValue* parsedValue ) { @@ -512,6 +548,11 @@ static void parsedEnumValueToZval( const OptionMetadata* optMeta, ParsedOptionVa RETURN_LONG( (long)( parsedValue.u.intValue ) ); } +static bool areEqualParsedEnumValues( const OptionMetadata* optMeta, ParsedOptionValue parsedValue1, ParsedOptionValue parsedValue2 ) +{ + return parsedValue1.u.intValue == parsedValue2.u.intValue; +} + static String streamParsedLogLevel( const OptionMetadata* optMeta, ParsedOptionValue parsedValue, TextOutputStream* txtOutStream ) { ELASTIC_APM_ASSERT_VALID_PTR( optMeta ); @@ -546,6 +587,7 @@ static OptionMetadata buildStringOptionMetadata( .setField = setFieldFunc, .getField = getFieldFunc, .parsedValueToZval = &parsedStringValueToZval, + .areEqualParsedValues = &areEqualParsedStringValues, .additionalData = {} }; } @@ -574,6 +616,7 @@ static OptionMetadata buildLoggingRelatedStringOptionMetadata( .setField = setFieldFunc, .getField = getFieldFunc, .parsedValueToZval = &parsedStringValueToZval, + .areEqualParsedValues = &areEqualParsedStringValues, .additionalData = {} }; } @@ -602,6 +645,7 @@ static OptionMetadata buildBoolOptionMetadata( .setField = setFieldFunc, .getField = getFieldFunc, .parsedValueToZval = &parsedBoolValueToZval, + .areEqualParsedValues = &areEqualParsedBoolValues, .additionalData = {} }; } @@ -630,6 +674,7 @@ static OptionMetadata buildOptionalBoolOptionMetadata( .setField = setFieldFunc, .getField = getFieldFunc, .parsedValueToZval = &parsedOptionalBoolValueToZval, + .areEqualParsedValues = &areEqualParsedOptionalBoolValues, .additionalData = {} }; } @@ -659,6 +704,7 @@ static OptionMetadata buildDurationOptionMetadata( .setField = setFieldFunc, .getField = getFieldFunc, .parsedValueToZval = &parsedDurationValueToZval, + .areEqualParsedValues = &areEqualParsedDurationValues, .additionalData = (OptionAdditionalMetadata){ .durationData = (DurationOptionAdditionalMetadata){ .defaultUnits = defaultUnits, .isNegativeValid = isNegativeValid } } }; } @@ -688,6 +734,7 @@ static OptionMetadata buildDurationOptionMetadata( .setField = setFieldFunc, .getField = getFieldFunc, .parsedValueToZval = &parsedSizeValueToZval, + .areEqualParsedValues = &areEqualParsedSizeValues, .additionalData = (OptionAdditionalMetadata){ .sizeData = (SizeOptionAdditionalMetadata){ .defaultUnits = defaultUnits } } }; } @@ -720,6 +767,7 @@ static OptionMetadata buildEnumOptionMetadata( .setField = setFieldFunc, .getField = getFieldFunc, .parsedValueToZval = &parsedEnumValueToZval, + .areEqualParsedValues = &areEqualParsedEnumValues, .additionalData = (OptionAdditionalMetadata){ .enumData = additionalMetadata } }; } @@ -803,6 +851,9 @@ ELASTIC_APM_DEFINE_FIELD_ACCESS_FUNCS( boolValue, breakdownMetrics ) ELASTIC_APM_DEFINE_FIELD_ACCESS_FUNCS( boolValue, captureErrors ) ELASTIC_APM_DEFINE_FIELD_ACCESS_FUNCS( stringValue, devInternal ) ELASTIC_APM_DEFINE_FIELD_ACCESS_FUNCS( boolValue, devInternalBackendCommLogVerbose ) +ELASTIC_APM_DEFINE_FIELD_ACCESS_FUNCS( boolValue, devInternalConfigOnCallStack ) +ELASTIC_APM_DEFINE_FIELD_ACCESS_FUNCS( boolValue, devInternalCurlInstrumCallCurl ) +ELASTIC_APM_DEFINE_FIELD_ACCESS_FUNCS( boolValue, devInternalCurlInstrumCreateSpan ) ELASTIC_APM_DEFINE_FIELD_ACCESS_FUNCS( stringValue, disableInstrumentations ) ELASTIC_APM_DEFINE_FIELD_ACCESS_FUNCS( boolValue, disableSend ) ELASTIC_APM_DEFINE_FIELD_ACCESS_FUNCS( boolValue, enabled ) @@ -1020,6 +1071,24 @@ static void initOptionsMetadata( OptionMetadata* optsMeta ) ELASTIC_APM_CFG_OPT_NAME_DEV_INTERNAL_BACKEND_COMM_LOG_VERBOSE, /* defaultValue: */ false ); + ELASTIC_APM_INIT_METADATA( + buildBoolOptionMetadata, + devInternalConfigOnCallStack, + ELASTIC_APM_CFG_OPT_NAME_DEV_INTERNAL_CONFIG_ON_CALL_STACK, + /* defaultValue: */ false ); + + ELASTIC_APM_INIT_METADATA( + buildBoolOptionMetadata, + devInternalCurlInstrumCallCurl, + ELASTIC_APM_CFG_OPT_NAME_DEV_INTERNAL_CURL_INSTRUM_CALL_CURL, + /* defaultValue: */ true ); + + ELASTIC_APM_INIT_METADATA( + buildBoolOptionMetadata, + devInternalCurlInstrumCreateSpan, + ELASTIC_APM_CFG_OPT_NAME_DEV_INTERNAL_CURL_INSTRUM_CREATE_SPAN, + /* defaultValue: */ true ); + ELASTIC_APM_INIT_METADATA( buildStringOptionMetadata, disableInstrumentations, @@ -1834,3 +1903,67 @@ ResultCode newConfigManager( ConfigManager** pNewCfgManager, bool isLoggingRelat deleteConfigManagerAndSetToNull( /* in,out */ &cfgManager ); goto finally; } + +bool isOptionValueSameAsDefault(const ConfigManager* cfgManager, OptionId optId) +{ + const OptionMetadata* optMeta = &(cfgManager->meta.optionsMeta[optId]); + return optMeta->areEqualParsedValues(optMeta, optMeta->defaultValue, optMeta->getField(optMeta, &(cfgManager->current.snapshot))); +} + +struct ConfigMarkerFunc +{ + using FuncType = bool (*)(const ConfigManager* configManager, std::span configMarkerFuncs, AddConfigToCallStackContinuation continuation); + + FuncType value; +}; + +#define ELASTIC_APM_MAKE_CONFIG_MARKER_FUNC_NAME(optSnapFieldName) ELASTIC_APM_PP_CONCAT(config_, optSnapFieldName) + +static void callFirstMatchingOrContinuation(const ConfigManager* configManager, std::span configMarkerFuncs, AddConfigToCallStackContinuation continuation) +{ + ELASTIC_APM_FOR_EACH_INDEX(i, configMarkerFuncs.size()) + { + if (configMarkerFuncs[i].value(configManager, configMarkerFuncs.last(configMarkerFuncs.size() - (i + 1)), continuation)) + { + return; + } + } + + continuation(); +} + +static bool configMarkerFuncImpl(OptionId optId, const ConfigManager* configManager, std::span configMarkerFuncs, AddConfigToCallStackContinuation continuation) +{ + if (isOptionValueSameAsDefault(configManager, optId)) + { + return false; + } + + callFirstMatchingOrContinuation(configManager, configMarkerFuncs, continuation); + return true; +} + +#define ELASTIC_APM_DEFINE_CONFIG_MARKER_FUNC(optSnapFieldName) \ + bool ELASTIC_APM_MAKE_CONFIG_MARKER_FUNC_NAME(optSnapFieldName)(const ConfigManager* configManager, std::span configMarkerFuncs, AddConfigToCallStackContinuation continuation) \ + { \ + return configMarkerFuncImpl(ELASTIC_APM_PP_CONCAT(optionId_, optSnapFieldName), configManager, configMarkerFuncs, continuation); \ + } \ + /**/ + +ELASTIC_APM_DEFINE_CONFIG_MARKER_FUNC(devInternalCurlInstrumCallCurl) +ELASTIC_APM_DEFINE_CONFIG_MARKER_FUNC(devInternalCurlInstrumCreateSpan) +ELASTIC_APM_DEFINE_CONFIG_MARKER_FUNC(disableSend) + +static std::array g_configMarkerFuncs{ + ConfigMarkerFunc{ &( ELASTIC_APM_MAKE_CONFIG_MARKER_FUNC_NAME(devInternalCurlInstrumCallCurl) ) }, + ConfigMarkerFunc{ &( ELASTIC_APM_MAKE_CONFIG_MARKER_FUNC_NAME(devInternalCurlInstrumCreateSpan) ) }, + ConfigMarkerFunc{ &( ELASTIC_APM_MAKE_CONFIG_MARKER_FUNC_NAME(disableSend) ) } +}; + +#undef ELASTIC_APM_MAKE_CONFIG_MARKER_FUNC_NAME + +void addConfigToCallStack(const ConfigManager* configManager, AddConfigToCallStackContinuation continuation) +{ + callFirstMatchingOrContinuation(configManager, g_configMarkerFuncs, continuation); +} + diff --git a/agent/native/ext/ConfigManager.h b/agent/native/ext/ConfigManager.h index fc27fde09..1b2f9032f 100644 --- a/agent/native/ext/ConfigManager.h +++ b/agent/native/ext/ConfigManager.h @@ -76,6 +76,9 @@ enum OptionId optionId_captureErrors, optionId_devInternal, optionId_devInternalBackendCommLogVerbose, + optionId_devInternalConfigOnCallStack, + optionId_devInternalCurlInstrumCallCurl, + optionId_devInternalCurlInstrumCreateSpan, optionId_disableInstrumentations, optionId_disableSend, optionId_enabled, @@ -212,6 +215,11 @@ void getConfigManagerRawData( const ConfigSnapshot* getGlobalCurrentConfigSnapshot(); +bool isOptionValueSameAsDefault(const ConfigManager* cfgManager, OptionId optId); + +typedef void (* AddConfigToCallStackContinuation)(); +void addConfigToCallStack(const ConfigManager* configManager, AddConfigToCallStackContinuation continuation); + #define ELASTIC_APM_CFG_OPT_HAS_NO_VALUE "no value" /** @@ -267,6 +275,9 @@ const ConfigSnapshot* getGlobalCurrentConfigSnapshot(); */ #define ELASTIC_APM_CFG_OPT_NAME_DEV_INTERNAL "dev_internal" #define ELASTIC_APM_CFG_OPT_NAME_DEV_INTERNAL_BACKEND_COMM_LOG_VERBOSE "dev_internal_backend_comm_log_verbose" +#define ELASTIC_APM_CFG_OPT_NAME_DEV_INTERNAL_CONFIG_ON_CALL_STACK "dev_internal_config_on_call_stack" +#define ELASTIC_APM_CFG_OPT_NAME_DEV_INTERNAL_CURL_INSTRUM_CALL_CURL "dev_internal_curl_instrum_call_curl" +#define ELASTIC_APM_CFG_OPT_NAME_DEV_INTERNAL_CURL_INSTRUM_CREATE_SPAN "dev_internal_curl_instrum_create_span" #define ELASTIC_APM_CFG_OPT_NAME_DISABLE_INSTRUMENTATIONS "disable_instrumentations" #define ELASTIC_APM_CFG_OPT_NAME_DISABLE_SEND "disable_send" diff --git a/agent/native/ext/ConfigSnapshot.h b/agent/native/ext/ConfigSnapshot.h index 9c96a58fd..e74cf3268 100644 --- a/agent/native/ext/ConfigSnapshot.h +++ b/agent/native/ext/ConfigSnapshot.h @@ -47,6 +47,9 @@ struct ConfigSnapshot bool captureErrors = false; String devInternal = nullptr; bool devInternalBackendCommLogVerbose = false; + bool devInternalConfigOnCallStack = false; + bool devInternalCurlInstrumCallCurl = true; + bool devInternalCurlInstrumCreateSpan = true; String disableInstrumentations = nullptr; bool disableSend = false; bool enabled = false; diff --git a/agent/native/ext/elastic_apm.cpp b/agent/native/ext/elastic_apm.cpp index 66c03feaa..04d417f2c 100644 --- a/agent/native/ext/elastic_apm.cpp +++ b/agent/native/ext/elastic_apm.cpp @@ -153,6 +153,9 @@ PHP_INI_BEGIN() ELASTIC_APM_INI_ENTRY( ELASTIC_APM_CFG_OPT_NAME_CAPTURE_ERRORS ) ELASTIC_APM_INI_ENTRY( ELASTIC_APM_CFG_OPT_NAME_DEV_INTERNAL ) ELASTIC_APM_INI_ENTRY( ELASTIC_APM_CFG_OPT_NAME_DEV_INTERNAL_BACKEND_COMM_LOG_VERBOSE ) + ELASTIC_APM_INI_ENTRY( ELASTIC_APM_CFG_OPT_NAME_DEV_INTERNAL_CONFIG_ON_CALL_STACK ) + ELASTIC_APM_INI_ENTRY( ELASTIC_APM_CFG_OPT_NAME_DEV_INTERNAL_CURL_INSTRUM_CALL_CURL ) + ELASTIC_APM_INI_ENTRY( ELASTIC_APM_CFG_OPT_NAME_DEV_INTERNAL_CURL_INSTRUM_CREATE_SPAN ) ELASTIC_APM_INI_ENTRY( ELASTIC_APM_CFG_OPT_NAME_DISABLE_INSTRUMENTATIONS ) ELASTIC_APM_INI_ENTRY( ELASTIC_APM_CFG_OPT_NAME_DISABLE_SEND ) ELASTIC_APM_NOT_RELOADABLE_INI_ENTRY( ELASTIC_APM_CFG_OPT_NAME_ENABLED ) diff --git a/agent/native/ext/lifecycle.cpp b/agent/native/ext/lifecycle.cpp index 0291c2f1a..2fc028a1c 100644 --- a/agent/native/ext/lifecycle.cpp +++ b/agent/native/ext/lifecycle.cpp @@ -400,12 +400,8 @@ auto buildPeriodicTaskExecutor() { return periodicTaskExecutor; } -void elasticApmRequestInit() +void elasticApmRequestInitImpl() { - if (!ELASTICAPM_G(globals)->sapi_.isSupported()) { - return; - } - requestCounter++; Tracer* const tracer = getGlobalTracer(); @@ -547,6 +543,23 @@ void elasticApmRequestInit() // , timePointToEpochMicroseconds( currentTime ) ); // } +void elasticApmRequestInit() +{ + if (!ELASTICAPM_G(globals)->sapi_.isSupported()) { + return; + } + + const ConfigSnapshot* config = getTracerCurrentConfigSnapshot( getGlobalTracer() ); + if ( config->devInternalConfigOnCallStack ) + { + addConfigToCallStack( getGlobalTracer()->configManager, &elasticApmRequestInitImpl ); + } + else + { + elasticApmRequestInitImpl(); + } +} + void elasticApmRequestShutdown() { if (!ELASTICAPM_G(globals)->sapi_.isSupported()) { diff --git a/agent/php/ElasticApm/Impl/AutoInstrument/CurlHandleTracker.php b/agent/php/ElasticApm/Impl/AutoInstrument/CurlHandleTracker.php index a4c6fbbe2..84efa6341 100644 --- a/agent/php/ElasticApm/Impl/AutoInstrument/CurlHandleTracker.php +++ b/agent/php/ElasticApm/Impl/AutoInstrument/CurlHandleTracker.php @@ -33,6 +33,7 @@ use Elastic\Apm\Impl\Log\LoggableInterface; use Elastic\Apm\Impl\Log\LoggableTrait; use Elastic\Apm\Impl\Log\Logger; +use Elastic\Apm\Impl\NoopSpan; use Elastic\Apm\Impl\Tracer; use Elastic\Apm\Impl\Util\ArrayUtil; use Elastic\Apm\Impl\Util\Assert; @@ -424,13 +425,20 @@ private function curlExecPreHook(): void $spanName = $httpMethod . ' ' . $host; $isHttp = ($this->url !== null) && UrlUtil::isHttp($this->url); - $this->span = AutoInstrumentationUtil::beginCurrentSpan($spanName, Constants::SPAN_TYPE_EXTERNAL, /* subtype: */ $isHttp ? Constants::SPAN_SUBTYPE_HTTP : null); + if ($this->tracer->getConfig()->devInternalCurlInstrumCreateSpan()) { + $this->span = AutoInstrumentationUtil::beginCurrentSpan($spanName, Constants::SPAN_TYPE_EXTERNAL, /* subtype: */ $isHttp ? Constants::SPAN_SUBTYPE_HTTP : null); + } else { + ($loggerProxy = $this->logger->ifDebugLevelEnabled(__LINE__, __FUNCTION__)) + && $loggerProxy->log('dev_internal_curl_instrum_create_span (devInternalCurlInstrumCreateSpan) is set to false - creating no-op span'); + $this->span = NoopSpan::singletonInstance(); + } $this->setContextPreHook(); if ($isHttp) { $headersToInjectFormattedLines = []; - $this->span->injectDistributedTracingHeaders( + $execSeg = $this->span->isNoop() ? $this->tracer->getCurrentTransaction() : $this->span; + $execSeg->injectDistributedTracingHeaders( function (string $headerName, string $headerValue) use (&$headersToInjectFormattedLines): void { $headersToInjectFormattedLines[] = $headerName . ': ' . $headerValue; } @@ -585,7 +593,12 @@ private function setContextPostHook(): void */ private function curlExecPostHook(int $numberOfStackFramesToSkip, $returnValue): void { - $this->setContextPostHook(); + if ($this->tracer->getConfig()->devInternalCurlInstrumCallCurl()) { + $this->setContextPostHook(); + } else { + ($loggerProxy = $this->logger->ifDebugLevelEnabled(__LINE__, __FUNCTION__)) + && $loggerProxy->log('dev_internal_curl_instrum_call_curl (devInternalCurlInstrumCallCurl) is set to false - skipping setContextPostHook'); + } AutoInstrumentationUtil::endSpan($numberOfStackFramesToSkip + 1, $this->span, /* hasExitedByException */ false, $returnValue); } @@ -607,13 +620,18 @@ private function injectDistributedTracingHeaders(array $headersToInjectFormatted ($loggerProxy = $logger->ifTraceLevelEnabled(__LINE__, __FUNCTION__)) && $loggerProxy->log('Injecting outgoing HTTP request headers for distributed tracing...'); - $setOptRetVal = $this->curlHandle->setOpt(CURLOPT_HTTPHEADER, $headers); - if ($setOptRetVal) { - ($loggerProxy = $logger->ifTraceLevelEnabled(__LINE__, __FUNCTION__)) - && $loggerProxy->log('Successfully injected outgoing HTTP request headers for distributed tracing'); + if ($this->tracer->getConfig()->devInternalCurlInstrumCallCurl()) { + $setOptRetVal = $this->curlHandle->setOpt(CURLOPT_HTTPHEADER, $headers); + if ($setOptRetVal) { + ($loggerProxy = $logger->ifTraceLevelEnabled(__LINE__, __FUNCTION__)) + && $loggerProxy->log('Successfully injected outgoing HTTP request headers for distributed tracing'); + } else { + ($loggerProxy = $logger->ifErrorLevelEnabled(__LINE__, __FUNCTION__)) + && $loggerProxy->log('Failed to inject outgoing HTTP request headers for distributed tracing'); + } } else { - ($loggerProxy = $logger->ifErrorLevelEnabled(__LINE__, __FUNCTION__)) - && $loggerProxy->log('Failed to inject outgoing HTTP request headers for distributed tracing'); + ($loggerProxy = $this->logger->ifDebugLevelEnabled(__LINE__, __FUNCTION__)) + && $loggerProxy->log('dev_internal_curl_instrum_call_curl (devInternalCurlInstrumCallCurl) is set to false - NOT injecting outgoing HTTP request headers for distributed tracing'); } } diff --git a/agent/php/ElasticApm/Impl/Config/AllOptionsMetadata.php b/agent/php/ElasticApm/Impl/Config/AllOptionsMetadata.php index e3bd9ecd3..9fb6ad8a7 100644 --- a/agent/php/ElasticApm/Impl/Config/AllOptionsMetadata.php +++ b/agent/php/ElasticApm/Impl/Config/AllOptionsMetadata.php @@ -91,6 +91,8 @@ public static function get(): array OptionNames::BREAKDOWN_METRICS => new BoolOptionMetadata(/* default */ true), OptionNames::CAPTURE_ERRORS => new BoolOptionMetadata(/* default */ true), OptionNames::DEV_INTERNAL => new NullableWildcardListOptionMetadata(), + OptionNames::DEV_INTERNAL_CURL_INSTRUM_CALL_CURL => new BoolOptionMetadata(/* default */ true), + OptionNames::DEV_INTERNAL_CURL_INSTRUM_CREATE_SPAN => new BoolOptionMetadata(/* default */ true), OptionNames::DISABLE_INSTRUMENTATIONS => new NullableWildcardListOptionMetadata(), OptionNames::DISABLE_SEND => new BoolOptionMetadata(/* default */ false), OptionNames::ENABLED => new BoolOptionMetadata(/* default */ true), diff --git a/agent/php/ElasticApm/Impl/Config/OptionNames.php b/agent/php/ElasticApm/Impl/Config/OptionNames.php index 7c9ca7be6..db6725374 100644 --- a/agent/php/ElasticApm/Impl/Config/OptionNames.php +++ b/agent/php/ElasticApm/Impl/Config/OptionNames.php @@ -43,6 +43,8 @@ final class OptionNames public const BREAKDOWN_METRICS = 'breakdown_metrics'; public const CAPTURE_ERRORS = 'capture_errors'; public const DEV_INTERNAL = 'dev_internal'; + public const DEV_INTERNAL_CURL_INSTRUM_CALL_CURL = 'dev_internal_curl_instrum_call_curl'; + public const DEV_INTERNAL_CURL_INSTRUM_CREATE_SPAN = 'dev_internal_curl_instrum_create_span'; public const DISABLE_INSTRUMENTATIONS = 'disable_instrumentations'; public const DISABLE_SEND = 'disable_send'; public const ENABLED = 'enabled'; diff --git a/agent/php/ElasticApm/Impl/Config/Snapshot.php b/agent/php/ElasticApm/Impl/Config/Snapshot.php index a6aab762b..890003a19 100644 --- a/agent/php/ElasticApm/Impl/Config/Snapshot.php +++ b/agent/php/ElasticApm/Impl/Config/Snapshot.php @@ -125,6 +125,12 @@ final class Snapshot implements LoggableInterface /** @var SnapshotDevInternal */ private $devInternalParsed; + /** @var bool */ + private $devInternalCurlInstrumCallCurl; + + /** @var bool */ + private $devInternalCurlInstrumCreateSpan; + /** @var ?WildcardListMatcher */ private $disableInstrumentations; @@ -287,6 +293,16 @@ public function devInternal(): SnapshotDevInternal return $this->devInternalParsed; } + public function devInternalCurlInstrumCallCurl(): bool + { + return $this->devInternalCurlInstrumCallCurl; + } + + public function devInternalCurlInstrumCreateSpan(): bool + { + return $this->devInternalCurlInstrumCreateSpan; + } + public function disableInstrumentations(): ?WildcardListMatcher { return $this->disableInstrumentations; diff --git a/tests/ElasticApmTests/ComponentTests/ConfigSettingTest.php b/tests/ElasticApmTests/ComponentTests/ConfigSettingTest.php index a7b553b45..96404e491 100644 --- a/tests/ElasticApmTests/ComponentTests/ConfigSettingTest.php +++ b/tests/ElasticApmTests/ComponentTests/ConfigSettingTest.php @@ -140,6 +140,10 @@ private static function buildOptionNameToRawToValue(): array OptionNames::CAPTURE_ERRORS => $boolRawToParsedValues(), OptionNames::ENABLED => $boolRawToParsedValues(/* valueToExclude: */ false), OptionNames::DEV_INTERNAL => $wildcardListRawToParsedValues, + OptionNames::DEV_INTERNAL_CURL_INSTRUM_CALL_CURL + => $boolRawToParsedValues(), + OptionNames::DEV_INTERNAL_CURL_INSTRUM_CREATE_SPAN + => $boolRawToParsedValues(), OptionNames::DISABLE_INSTRUMENTATIONS => $wildcardListRawToParsedValues, OptionNames::DISABLE_SEND => $boolRawToParsedValues(/* valueToExclude: */ true), OptionNames::ENVIRONMENT => $stringRawToParsedValues([" my_environment \t "]),