agent/native/ext/Tracer.cpp (182 lines of code) (raw):

/* * Licensed to Elasticsearch B.V. under one or more contributor * license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright * ownership. Elasticsearch B.V. licenses this file to you under * the Apache License, Version 2.0 (the "License"); you may * not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ #include "Tracer.h" #include "elastic_apm_version.h" #include "elastic_apm_alloc.h" #include "ConfigSnapshot.h" #define ELASTIC_APM_CURRENT_LOG_CATEGORY ELASTIC_APM_LOG_CATEGORY_EXT_INFRA #if ( ELASTIC_APM_ASSERT_ENABLED_01 != 0 ) AssertLevel getGlobalAssertLevel() { return getGlobalTracer()->currentAssertLevel; } #endif #if ( ELASTIC_APM_MEMORY_TRACKING_ENABLED_01 != 0 ) MemoryTracker* getGlobalMemoryTracker() { return &getGlobalTracer()->memTracker; } #endif InternalChecksLevel getGlobalInternalChecksLevel() { return getGlobalTracer()->currentInternalChecksLevel; } const ConfigSnapshot* getGlobalCurrentConfigSnapshot() { return getConfigManagerCurrentSnapshot( getGlobalTracer()->configManager ); } static ResultCode ensureLoggerHasLatestConfig( Logger* logger, const ConfigSnapshot* config ) { ResultCode resultCode; LoggerConfig loggerConfig; ELASTIC_APM_ZERO_STRUCT(&loggerConfig); loggerConfig.levelPerSinkType[ logSink_stderr ] = config->logLevelStderr; loggerConfig.levelPerSinkType[ logSink_file ] = config->logLevelFile; #ifndef PHP_WIN32 loggerConfig.levelPerSinkType[ logSink_syslog ] = config->logLevelSyslog; #endif #ifdef PHP_WIN32 loggerConfig.levelPerSinkType[ logSink_winSysDebug ] = config->logLevelWinSysDebug; #endif ELASTIC_APM_CALL_IF_FAILED_GOTO( reconfigureLogger( logger, &loggerConfig, config->logLevel ) ); resultCode = resultSuccess; finally: return resultCode; failure: goto finally; } #if ( ELASTIC_APM_MEMORY_TRACKING_ENABLED_01 != 0 ) static void ensureMemoryTrackerHasLatestConfig( MemoryTracker* memTracker, const ConfigSnapshot* config ) { MemoryTrackingLevel levelsDescendingPrecedence[] = { config->memoryTrackingLevel, internalChecksToMemoryTrackingLevel( config->internalChecksLevel ) }; MemoryTrackingLevel newLevel = ELASTIC_APM_MEMORY_TRACKING_DEFAULT_LEVEL; ELASTIC_APM_FOR_EACH_INDEX( i, ELASTIC_APM_STATIC_ARRAY_SIZE( levelsDescendingPrecedence ) ) { if ( levelsDescendingPrecedence[ i ] == memoryTrackingLevel_not_set ) continue; newLevel = levelsDescendingPrecedence[ i ]; break; } reconfigureMemoryTracker( memTracker, newLevel, config->abortOnMemoryLeak ); } #endif // #if ( ELASTIC_APM_MEMORY_TRACKING_ENABLED_01 != 0 ) #if ( ELASTIC_APM_ASSERT_ENABLED_01 != 0 ) static void ensureAssertHasLatestConfig( Tracer* tracer, const ConfigSnapshot* config ) { AssertLevel levelsDescendingPrecedence[] = { config->assertLevel, internalChecksToAssertLevel( config->internalChecksLevel ) }; AssertLevel newLevel = ELASTIC_APM_ASSERT_DEFAULT_LEVEL; ELASTIC_APM_FOR_EACH_INDEX( i, ELASTIC_APM_STATIC_ARRAY_SIZE( levelsDescendingPrecedence ) ) { if ( levelsDescendingPrecedence[ i ] == assertLevel_not_set ) continue; newLevel = levelsDescendingPrecedence[ i ]; break; } tracer->currentAssertLevel = newLevel; } #endif // #if ( ELASTIC_APM_ASSERT_ENABLED_01 != 0 ) static void ensureInternalChecksLevelHasLatestConfig( Tracer* tracer, const ConfigSnapshot* config ) { tracer->currentInternalChecksLevel = ( config->internalChecksLevel == internalChecksLevel_not_set ) ? ELASTIC_APM_INTERNAL_CHECKS_DEFAULT_LEVEL : config->internalChecksLevel; } ResultCode ensureLoggerInitialConfigIsLatest( Tracer* tracer ) { ELASTIC_APM_ASSERT_VALID_PTR( tracer ); ResultCode resultCode; ConfigManager* loggingRelatedOnlyConfigManager = NULL; bool didConfigChange = false; ELASTIC_APM_CALL_IF_FAILED_GOTO( newConfigManager( &loggingRelatedOnlyConfigManager, /* isLoggingRelatedOnly */ true ) ); ELASTIC_APM_CALL_IF_FAILED_GOTO( ensureConfigManagerHasLatestConfig( loggingRelatedOnlyConfigManager, &didConfigChange ) ); ELASTIC_APM_CALL_IF_FAILED_GOTO( ensureLoggerHasLatestConfig( &tracer->logger, getConfigManagerCurrentSnapshot( loggingRelatedOnlyConfigManager ) ) ); resultCode = resultSuccess; finally: if ( loggingRelatedOnlyConfigManager != NULL ) { deleteConfigManagerAndSetToNull( &loggingRelatedOnlyConfigManager ); } return resultCode; failure: goto finally; } ResultCode ensureAllComponentsHaveLatestConfig( Tracer* tracer ) { ELASTIC_APM_ASSERT_VALID_PTR( tracer ); ResultCode resultCode; const ConfigSnapshot* config = NULL; bool didConfigChange; ELASTIC_APM_CALL_IF_FAILED_GOTO( ensureConfigManagerHasLatestConfig( tracer->configManager, &didConfigChange ) ); if ( ! didConfigChange ) { resultCode = resultSuccess; goto finally; } resultCode = resultSuccess; config = getTracerCurrentConfigSnapshot( tracer ); ensureInternalChecksLevelHasLatestConfig( tracer, config ); ELASTIC_APM_CALL_IF_FAILED_GOTO( ensureLoggerHasLatestConfig( &tracer->logger, config ) ); #if ( ELASTIC_APM_MEMORY_TRACKING_ENABLED_01 != 0 ) ensureMemoryTrackerHasLatestConfig( &tracer->memTracker, config ); #endif #if ( ELASTIC_APM_ASSERT_ENABLED_01 != 0 ) ensureAssertHasLatestConfig( tracer, config ); #endif finally: return resultCode; failure: goto finally; } const ConfigSnapshot* getTracerCurrentConfigSnapshot( const Tracer* tracer ) { return getConfigManagerCurrentSnapshot( tracer->configManager ); } ResultCode constructTracer( Tracer* tracer ) { ELASTIC_APM_ASSERT_VALID_PTR( tracer ); ResultCode resultCode; ELASTIC_APM_ZERO_STRUCT( tracer ); #if ( ELASTIC_APM_ASSERT_ENABLED_01 != 0 ) tracer->currentAssertLevel = ELASTIC_APM_ASSERT_DEFAULT_LEVEL; #endif tracer->currentInternalChecksLevel = ELASTIC_APM_INTERNAL_CHECKS_DEFAULT_LEVEL; // // MemoryTracker needs Logger to report so Logger has to be constructed before MemoryTracker // ELASTIC_APM_CALL_IF_FAILED_GOTO( constructLogger( &tracer->logger ) ); #if ( ELASTIC_APM_MEMORY_TRACKING_ENABLED_01 != 0 ) constructMemoryTracker( &tracer->memTracker ); #endif ELASTIC_APM_CALL_IF_FAILED_GOTO( newConfigManager( &tracer->configManager, /* isLoggingRelatedOnly */ false ) ); resultCode = resultSuccess; tracer->isInited = true; tracer->isFailed = false; finally: return resultCode; failure: destructTracer( tracer ); goto finally; } void moveTracerToFailedState( Tracer* tracer ) { ELASTIC_APM_LOG_CRITICAL( "Moving tracer to failed state - Elastic APM will be DISABLED!" ); tracer->isFailed = true; } bool isTracerInFunctioningState( const Tracer* tracer ) { return tracer->isInited && getTracerCurrentConfigSnapshot( tracer )->enabled && ( ! tracer->isFailed ); } void destructTracer( Tracer* tracer ) { ELASTIC_APM_ASSERT_VALID_PTR( tracer ); deleteConfigManagerAndSetToNull( &tracer->configManager ); // // MemoryTracker needs Logger to report so Logger has to be destructed after MemoryTracker // #if ( ELASTIC_APM_MEMORY_TRACKING_ENABLED_01 != 0 ) destructMemoryTracker( &tracer->memTracker ); #endif destructLogger( &tracer->logger ); ELASTIC_APM_ZERO_STRUCT( tracer ); }