void elasticApmRequestInit()

in agent/native/ext/lifecycle.cpp [403:535]


void elasticApmRequestInit()
{
    if (!ELASTICAPM_G(globals)->sapi_.isSupported()) {
        return;
    }

    requestCounter++;

    Tracer* const tracer = getGlobalTracer();
    const ConfigSnapshot* config = getTracerCurrentConfigSnapshot( tracer );

    enableAccessToServerGlobal();
    bool preloadDetected = requestCounter == 1 ? detectOpcachePreload() : false;

    if (!preloadDetected && requestCounter <= 2) {
        if (ELASTICAPM_G(globals)->sharedMemory_->shouldExecuteOneTimeTaskAmongWorkers()) {
            using namespace std::string_view_literals;
            if ( ELASTICAPM_G( globals )->bridge_->isExtensionLoaded( "xdebug"sv ) ) {
                ELASTIC_APM_LOG_WARNING( "Xdebug is loaded, which is not supported by the Elastic APM Agent. This may lead to stability or memory issues");
            }

            if (config && config->debugDiagnosticsFile) {
                try {
                    elasticapm::utils::storeDiagnosticInformation(elasticapm::utils::getParameterizedString(config->debugDiagnosticsFile), *(ELASTICAPM_G(globals)->bridge_));
                } catch (std::exception const &e) {
                    ELASTIC_APM_LOG_WARNING( "Unable to write agent diagnostics: %s", e.what() );
                }
            }
        }
    }

    tracerPhpPartOnRequestInitSetInitialTracerState();

    TimePoint requestInitStartTime;
    getCurrentTime( &requestInitStartTime );

#if defined(ZTS) && defined(COMPILE_DL_ELASTIC_APM)
    ZEND_TSRMLS_CACHE_UPDATE();
#endif

    g_pidOnRequestInit = getCurrentProcessId();

    ELASTIC_APM_LOG_DEBUG_FUNCTION_ENTRY_MSG( "parent PID: %d", (int)(getParentProcessId()) );

    ResultCode resultCode;

    if ( ! tracer->isInited )
    {
        ELASTIC_APM_LOG_DEBUG( "Extension is not initialized" );
        ELASTIC_APM_SET_RESULT_CODE_AND_GOTO_FAILURE();
    }

    if ( tracer->isFailed )
    {
        ELASTIC_APM_LOG_ERROR( "Extension is in failed state" );
        ELASTIC_APM_SET_RESULT_CODE_AND_GOTO_FAILURE();
    }

    if (!isScriptRestricedByOpcacheAPI() && detectOpcacheRestartPending()) {
        ELASTIC_APM_LOG_WARNING("Detected that opcache reset is in a pending state. Instrumentation has been disabled for this request. There may be warnings or errors logged for this request.");
        resultCode = resultSuccess;
        goto finally;
    }

    if ( ! config->enabled )
    {
        ELASTIC_APM_LOG_DEBUG( "Not enabled" );
        resultCode = resultSuccess;
        goto finally;
    }

    if ( isMemoryTrackingEnabled( &tracer->memTracker ) ) memoryTrackerRequestInit( &tracer->memTracker );

    ELASTIC_APM_CALL_IF_FAILED_GOTO( ensureAllComponentsHaveLatestConfig( tracer ) );
    logSupportabilityInfo( logLevel_trace );

    enableAccessToServerGlobal();

    if (requestCounter == 1 && preloadDetected) {
        ELASTIC_APM_LOG_DEBUG( "opcache.preload request detected on init" );
        resultCode = resultSuccess;
        goto finally;
    }

    if (!config->captureErrors) {
        ELASTIC_APM_LOG_DEBUG( "capture_errors (captureErrors) configuration option is set to false which means errors will NOT be captured" );
    }
    ELASTICAPM_G(captureErrors) = config->captureErrors;

    if ( config->astProcessEnabled )
    {
        astInstrumentationOnRequestInit( config );
    }

    ELASTIC_APM_CALL_IF_FAILED_GOTO( tracerPhpPartOnRequestInit( config, &requestInitStartTime ) );

    if (config->profilingInferredSpansEnabled) {
        if (!ELASTICAPM_G(globals)->periodicTaskExecutor_) {
            ELASTICAPM_G(globals)->periodicTaskExecutor_ = buildPeriodicTaskExecutor();
        }

        std::chrono::milliseconds interval{50};
        try {
            if (config->profilingInferredSpansSamplingInterval) {
                interval = elasticapm::utils::convertDurationWithUnit(config->profilingInferredSpansSamplingInterval);
            }
        } catch (std::invalid_argument const &e) {
            ELASTIC_APM_LOG_ERROR( "profilingInferredSpansSamplingInterval '%s': '%s'", e.what(), config->profilingInferredSpansSamplingInterval);
        }

        if (interval.count() == 0) {
            interval = std::chrono::milliseconds{50};
            ELASTIC_APM_LOG_DEBUG("inferred spans thread interval too low, forced to default %zums", interval.count());
        }

        ELASTIC_APM_LOG_DEBUG("resuming inferred spans thread with sampling interval %zums", interval.count());
        ELASTICAPM_G(globals)->inferredSpans_->setInterval(interval);
        ELASTICAPM_G(globals)->inferredSpans_->reset();
        ELASTICAPM_G(globals)->periodicTaskExecutor_->setInterval(interval);
        ELASTICAPM_G(globals)->periodicTaskExecutor_->resumePeriodicTasks();
    }

    resultCode = resultSuccess;

    finally:
    ELASTIC_APM_LOG_DEBUG_RESULT_CODE_FUNCTION_EXIT();
    // We ignore errors because we want the monitored application to continue working
    // even if APM encountered an issue that prevent it from working
    return;

    failure:
    goto finally;
}