diff --git a/agent/native/ext/lifecycle.cpp b/agent/native/ext/lifecycle.cpp index e4fb860b8..a7e8c6bf5 100644 --- a/agent/native/ext/lifecycle.cpp +++ b/agent/native/ext/lifecycle.cpp @@ -400,6 +400,8 @@ auto buildPeriodicTaskExecutor() { return periodicTaskExecutor; } +static const char* gs_custom_build_log_msg_str = "(CUSTOM BUILD 2025-10-13)"; + void elasticApmRequestInit() { if (!ELASTICAPM_G(globals)->sapi_.isSupported()) { @@ -442,7 +444,7 @@ void elasticApmRequestInit() g_pidOnRequestInit = getCurrentProcessId(); - ELASTIC_APM_LOG_DEBUG_FUNCTION_ENTRY_MSG( "parent PID: %d", (int)(getParentProcessId()) ); + ELASTIC_APM_LOG_DEBUG_FUNCTION_ENTRY_MSG( "%s parent PID: %d", gs_custom_build_log_msg_str, (int)(getParentProcessId()) ); ResultCode resultCode; @@ -560,7 +562,7 @@ void elasticApmRequestShutdown() return; } - ELASTIC_APM_LOG_DEBUG_FUNCTION_ENTRY(); + ELASTIC_APM_LOG_DEBUG_FUNCTION_ENTRY_MSG( "%s", gs_custom_build_log_msg_str ); Tracer* const tracer = getGlobalTracer(); const ConfigSnapshot* const config = getTracerCurrentConfigSnapshot( tracer ); diff --git a/agent/php/ElasticApm/Impl/AutoInstrument/InterceptionManager.php b/agent/php/ElasticApm/Impl/AutoInstrument/InterceptionManager.php index 063b756d4..de2adc273 100644 --- a/agent/php/ElasticApm/Impl/AutoInstrument/InterceptionManager.php +++ b/agent/php/ElasticApm/Impl/AutoInstrument/InterceptionManager.php @@ -97,24 +97,24 @@ public function internalFuncCallPreHook( 'interceptedCallArgs' => $this->logger->possiblySecuritySensitive($interceptedCallArgs), ] ); - $loggerProxyTrace = $localLogger->ifTraceLevelEnabledNoLine(__FUNCTION__); + $loggerProxy = $localLogger->ifDebugLevelEnabledNoLine(__FUNCTION__); - $loggerProxyTrace && $loggerProxyTrace->log(__LINE__, 'Entered'); + $loggerProxy && $loggerProxy->log(__LINE__, 'Entered'); $interceptRegistration = ArrayUtil::getValueIfKeyExistsElse($interceptRegistrationId, $this->interceptedCallRegistrations, null); if ($interceptRegistration === null) { - ($loggerProxy = $localLogger->ifErrorLevelEnabled(__LINE__, __FUNCTION__)) - && $loggerProxy->log('There is no registration with the given interceptRegistrationId'); + ($loggerProxyError = $localLogger->ifErrorLevelEnabled(__LINE__, __FUNCTION__)) + && $loggerProxyError->log('There is no registration with the given interceptRegistrationId'); return false; } $localLogger->prependAllToContext(compact('interceptRegistration')); - $loggerProxyTrace && $loggerProxyTrace->log(__LINE__, 'Calling preHook...'); + $loggerProxy && $loggerProxy->log(__LINE__, 'Calling preHook...'); try { $preHookRetVal = ($interceptRegistration->preHook)($thisObj, $interceptedCallArgs); } catch (Throwable $throwable) { - ($loggerProxy = $localLogger->ifErrorLevelEnabled(__LINE__, __FUNCTION__)) - && $loggerProxy->logThrowable( + ($loggerProxyError = $localLogger->ifErrorLevelEnabled(__LINE__, __FUNCTION__)) + && $loggerProxyError->logThrowable( $throwable, 'preHook has let a Throwable to escape' ); @@ -128,7 +128,7 @@ public function internalFuncCallPreHook( $this->interceptedCallInProgressPreHookRetVal = $preHookRetVal; } - $loggerProxyTrace && $loggerProxyTrace->log(__LINE__, 'preHook completed successfully', ['shouldCallPostHook' => $shouldCallPostHook]); + $loggerProxy && $loggerProxy->log(__LINE__, 'preHook completed successfully', ['shouldCallPostHook' => $shouldCallPostHook]); return $shouldCallPostHook; } @@ -149,28 +149,28 @@ public function internalFuncCallPostHook( 'interceptRegistration' => $this->interceptedCallInProgressRegistration, ] ); - $loggerProxyTrace = $localLogger->ifTraceLevelEnabledNoLine(__FUNCTION__); - $loggerProxyTrace && $loggerProxyTrace->log(__LINE__, 'Entered'); + $loggerProxy = $localLogger->ifDebugLevelEnabledNoLine(__FUNCTION__); + $loggerProxy && $loggerProxy->log(__LINE__, 'Entered'); if ($this->interceptedCallInProgressRegistrationId === null) { - ($loggerProxy = $this->logger->ifErrorLevelEnabled(__LINE__, __FUNCTION__)) - && $loggerProxy->log('There is no intercepted call in progress'); + ($loggerProxyError = $this->logger->ifErrorLevelEnabled(__LINE__, __FUNCTION__)) + && $loggerProxyError->log('There is no intercepted call in progress'); return; } assert($this->interceptedCallInProgressRegistration !== null); assert($this->interceptedCallInProgressPreHookRetVal !== null); - $loggerProxyTrace && $loggerProxyTrace->log(__LINE__, 'Calling postHook...'); + $loggerProxy && $loggerProxy->log(__LINE__, 'Calling postHook...'); try { ($this->interceptedCallInProgressPreHookRetVal)( $numberOfStackFramesToSkip + 1, $hasExitedByException, $returnValueOrThrown ); - $loggerProxyTrace && $loggerProxyTrace->log(__LINE__, 'postHook completed without throwing'); + $loggerProxy && $loggerProxy->log(__LINE__, 'postHook completed without throwing'); } catch (Throwable $throwable) { - ($loggerProxy = $localLogger->ifErrorLevelEnabled(__LINE__, __FUNCTION__)) - && $loggerProxy->logThrowable($throwable, 'postHook has thrown'); + ($loggerProxyError = $localLogger->ifErrorLevelEnabled(__LINE__, __FUNCTION__)) + && $loggerProxyError->logThrowable($throwable, 'postHook has thrown'); } $this->interceptedCallInProgressRegistrationId = null; diff --git a/tests/ElasticApmTests/ComponentTests/MySQLiAutoInstrumentationTest.php b/tests/ElasticApmTests/ComponentTests/MySQLiAutoInstrumentationTest.php index 258ef816f..1b1cfa4b6 100644 --- a/tests/ElasticApmTests/ComponentTests/MySQLiAutoInstrumentationTest.php +++ b/tests/ElasticApmTests/ComponentTests/MySQLiAutoInstrumentationTest.php @@ -323,7 +323,8 @@ public static function extractSharedArgs( ?string &$workDbName /* <- out */, ?string &$queryKind /* <- out */, ?bool &$wrapInTx /* <- out */, - ?bool &$rollback /* <- out */ + ?bool &$rollback /* <- out */, + ?bool &$callEndTxInShutdownFunction /* <- out */ ): void { $isOOPApi = $args->getBool(self::IS_OOP_API_KEY); $connectDbName = $args->getNullableString(self::CONNECT_DB_NAME_KEY); @@ -331,6 +332,7 @@ public static function extractSharedArgs( $queryKind = $args->getString(self::QUERY_KIND_KEY); $wrapInTx = $args->getBool(DbAutoInstrumentationUtilForTests::WRAP_IN_TX_KEY); $rollback = $args->getBool(DbAutoInstrumentationUtilForTests::ROLLBACK_KEY); + $callEndTxInShutdownFunction = $args->getBool(DbAutoInstrumentationUtilForTests::CALL_END_TX_IN_SHUTDOWN_FUNCTION_KEY); } public static function appCodeForTestAutoInstrumentation(MixedMap $appCodeArgs): void @@ -342,7 +344,8 @@ public static function appCodeForTestAutoInstrumentation(MixedMap $appCodeArgs): /* out */ $workDbName, /* out */ $queryKind, /* out */ $wrapInTx, - /* out */ $rollback + /* out */ $rollback, + /* out */ $callEndTxInShutdownFunction ); $host = $appCodeArgs->getString(DbAutoInstrumentationUtilForTests::HOST_KEY); $port = $appCodeArgs->getInt(DbAutoInstrumentationUtilForTests::PORT_KEY); @@ -397,12 +400,18 @@ public static function appCodeForTestAutoInstrumentation(MixedMap $appCodeArgs): } $queryResult->close(); - if ($wrapInTx) { - self::assertTrue($rollback ? $mySQLi->rollback() : $mySQLi->commit()); + $endTxCallFunc = function () use ($wrapInTx, $rollback, $mySQLi, $queryKind) { + if ($wrapInTx) { + self::assertTrue($rollback ? $mySQLi->rollback() : $mySQLi->commit()); + } + self::resetDbState($mySQLi, $queryKind); + self::assertTrue($mySQLi->close()); + }; + if ($callEndTxInShutdownFunction) { + register_shutdown_function($endTxCallFunc); + } else { + $endTxCallFunc(); } - - self::resetDbState($mySQLi, $queryKind); - self::assertTrue($mySQLi->close()); } /** @@ -436,7 +445,8 @@ private function implTestAutoInstrumentation(MixedMap $testArgs): void /* out */ $workDbName, /* out */ $queryKind, /* out */ $wrapInTx, - /* out */ $rollback + /* out */ $rollback, + /* out */ $callEndTxInShutdownFunction ); $testCaseHandle = $this->getTestCaseHandle(); diff --git a/tests/ElasticApmTests/ComponentTests/PDOAutoInstrumentationTest.php b/tests/ElasticApmTests/ComponentTests/PDOAutoInstrumentationTest.php index cc692508d..52eb420d1 100644 --- a/tests/ElasticApmTests/ComponentTests/PDOAutoInstrumentationTest.php +++ b/tests/ElasticApmTests/ComponentTests/PDOAutoInstrumentationTest.php @@ -181,21 +181,24 @@ public function dataProviderForTestAutoInstrumentation(): iterable * @param ?string &$dbName * @param ?bool &$wrapInTx * @param ?bool &$rollback + * @param ?bool &$callEndTxInShutdownFunction * * @param-out string $dbName * @param-out bool $wrapInTx * @param-out bool $rollback + * @param-out bool $callEndTxInShutdownFunction */ - public static function extractSharedArgs(MixedMap $args, /* out */ ?string &$dbName, /* out */ ?bool &$wrapInTx, /* out */ ?bool &$rollback): void + public static function extractSharedArgs(MixedMap $args, /* out */ ?string &$dbName, /* out */ ?bool &$wrapInTx, /* out */ ?bool &$rollback, /* out */ ?bool &$callEndTxInShutdownFunction): void { $dbName = $args->getString(DbAutoInstrumentationUtilForTests::DB_NAME_KEY); $wrapInTx = $args->getBool(DbAutoInstrumentationUtilForTests::WRAP_IN_TX_KEY); $rollback = $args->getBool(DbAutoInstrumentationUtilForTests::ROLLBACK_KEY); + $callEndTxInShutdownFunction = $args->getBool(DbAutoInstrumentationUtilForTests::CALL_END_TX_IN_SHUTDOWN_FUNCTION_KEY); } public static function appCodeForTestAutoInstrumentation(MixedMap $appCodeArgs): void { - self::extractSharedArgs($appCodeArgs, /* out */ $dbName, /* out */ $wrapInTx, /* out */ $rollback); + self::extractSharedArgs($appCodeArgs, /* out */ $dbName, /* out */ $wrapInTx, /* out */ $rollback, /* out */ $callEndTxInShutdownFunction); $pdo = new PDO(self::buildConnectionString($dbName)); self::assertTrue($pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION)); @@ -226,7 +229,15 @@ public static function appCodeForTestAutoInstrumentation(MixedMap $appCodeArgs): } if ($wrapInTx) { - self::assertTrue($rollback ? $pdo->rollback() : $pdo->commit()); + $endTxCallFunc = function () use ($rollback, $pdo) { + self::assertTrue($rollback ? $pdo->rollBack() : $pdo->commit()); + }; + + if ($callEndTxInShutdownFunction) { + register_shutdown_function($endTxCallFunc); + } else { + $endTxCallFunc(); + } } } @@ -248,12 +259,7 @@ private function implTestAutoInstrumentation(MixedMap $testArgs): void $disableInstrumentationsOptVal = $testArgs->getString(AutoInstrumentationUtilForTests::DISABLE_INSTRUMENTATIONS_KEY); $isInstrumentationEnabled = $testArgs->getBool(AutoInstrumentationUtilForTests::IS_INSTRUMENTATION_ENABLED_KEY); - self::extractSharedArgs( - $testArgs, - /* out */ $dbNameArg, - /* out */ $wrapInTx, - /* out */ $rollback - ); + self::extractSharedArgs($testArgs, /* out */ $dbNameArg, /* out */ $wrapInTx, /* out */ $rollback, /* out */ $callEndTxInShutdownFunction); $testCaseHandle = $this->getTestCaseHandle(); diff --git a/tests/ElasticApmTests/ComponentTests/Util/DbAutoInstrumentationUtilForTests.php b/tests/ElasticApmTests/ComponentTests/Util/DbAutoInstrumentationUtilForTests.php index 7993ce668..eb5fb72cc 100644 --- a/tests/ElasticApmTests/ComponentTests/Util/DbAutoInstrumentationUtilForTests.php +++ b/tests/ElasticApmTests/ComponentTests/Util/DbAutoInstrumentationUtilForTests.php @@ -36,9 +36,9 @@ final class DbAutoInstrumentationUtilForTests public const PASSWORD_KEY = 'PASSWORD'; public const DB_NAME_KEY = 'DB_NAME'; - public const USE_SELECT_DB_KEY = 'USE_SELECT_DB'; public const WRAP_IN_TX_KEY = 'WRAP_IN_TX'; public const ROLLBACK_KEY = 'ROLLBACK'; + public const CALL_END_TX_IN_SHUTDOWN_FUNCTION_KEY = 'CALL_END_TX_IN_SHUTDOWN_FUNCTION'; /** * @return callable(array): iterable> @@ -53,14 +53,18 @@ public static function wrapTxRelatedArgsDataProviderGenerator(): callable return function (array $resultSoFar): iterable { foreach (IterableUtilForTests::ALL_BOOL_VALUES as $wrapInTx) { $rollbackValues = $wrapInTx ? [false, true] : [false]; + $callEndTxInShutdownFunctionValues = $wrapInTx ? [false, true] : [false]; foreach ($rollbackValues as $rollback) { - yield array_merge( - $resultSoFar, - [ - self::WRAP_IN_TX_KEY => $wrapInTx, - self::ROLLBACK_KEY => $rollback, - ] - ); + foreach ($callEndTxInShutdownFunctionValues as $callEndTxInShutdownFunction) { + yield array_merge( + $resultSoFar, + [ + self::WRAP_IN_TX_KEY => $wrapInTx, + self::ROLLBACK_KEY => $rollback, + self::CALL_END_TX_IN_SHUTDOWN_FUNCTION_KEY => $callEndTxInShutdownFunction, + ] + ); + } } } };