fn initialize()

in src/profiler/elastic_apm_profiler/src/profiler/mod.rs [486:642]


    fn initialize(&self, unknown: IUnknown) -> Result<(), HRESULT> {
        unsafe {
            unknown.AddRef();
        }
        
        println!("hello world init");

        let process_path = std::env::current_exe().map_err(|e| {
            // logging hasn't yet been initialized so unable to log
            E_FAIL
        })?;

        let process_file_name = process_path
            .file_name()
            .unwrap()
            .to_string_lossy()
            .to_string();

        let process_name = process_path
            .file_stem()
            .unwrap()
            .to_string_lossy()
            .to_string();
        let logger = env::initialize_logging(&process_name);

        log::trace!(
            "Initialize: started. profiler package version {} (commit: {}) (anchor version: {})",
            PROFILER_PACKAGE_VERSION,
            GIT_HASH,
            *PROFILER_VERSION
        );

        if log::log_enabled!(Level::Debug) {
            log::debug!("Environment variables\n{}", env::get_env_vars());
        }

        if let Some(exclude_process_names) = env::get_exclude_processes() {
            for exclude_process_name in exclude_process_names {
                if process_file_name.to_lowercase() == exclude_process_name.to_lowercase() {
                    log::info!(
                        "Initialize: process name {} matches excluded name {}. Profiler disabled",
                        &process_file_name,
                        &exclude_process_name
                    );
                    return Err(E_FAIL);
                }
            }
        }

        if let Some(exclude_service_names) = env::get_exclude_service_names() {
            if let Some(service_name) = env::get_service_name() {
                for exclude_service_name in exclude_service_names {
                    if service_name.to_lowercase() == exclude_service_name.to_lowercase() {
                        log::info!(
                            "Initialize: service name {} matches excluded name {}. Profiler disabled",
                            &service_name,
                            &exclude_service_name);
                        return Err(E_FAIL);
                    }
                }
            }
        }

        env::check_if_running_in_azure_app_service()?;

        // get the ICorProfilerInfo4 interface, which will be available for all CLR versions targeted
        let profiler_info = unknown
            .query_interface::<ICorProfilerInfo4>()
            .ok_or_else(|| {
                log::error!("Initialize: could not get ICorProfilerInfo4 from IUnknown");
                E_FAIL
            })?;

        // get the integrations from file
        let integrations = env::load_integrations()?;
        let calltarget_enabled = *env::ELASTIC_APM_PROFILER_CALLTARGET_ENABLED;
        if calltarget_enabled {
            let rejit_handler = RejitHandler::new(profiler_info.clone());
            self.rejit_handler.replace(Some(rejit_handler));
        }

        let mut integration_methods = flatten_integrations(integrations, calltarget_enabled);

        if integration_methods.is_empty() {
            log::warn!("Initialize: no integrations. Profiler disabled.");
            return Err(E_FAIL);
        } else {
            log::debug!(
                "Initialize: loaded {} integration(s)",
                integration_methods.len()
            );
        }

        self.integration_methods
            .write()
            .unwrap()
            .append(&mut integration_methods);

        // Set the event mask for CLR events we're interested in
        let mut event_mask = COR_PRF_MONITOR::COR_PRF_MONITOR_JIT_COMPILATION
            | COR_PRF_MONITOR::COR_PRF_DISABLE_TRANSPARENCY_CHECKS_UNDER_FULL_TRUST
            | COR_PRF_MONITOR::COR_PRF_MONITOR_MODULE_LOADS
            | COR_PRF_MONITOR::COR_PRF_MONITOR_ASSEMBLY_LOADS
            | COR_PRF_MONITOR::COR_PRF_MONITOR_APPDOMAIN_LOADS
            | COR_PRF_MONITOR::COR_PRF_DISABLE_ALL_NGEN_IMAGES;

        if calltarget_enabled {
            log::info!("Initialize: CallTarget instrumentation is enabled");
            event_mask |= COR_PRF_MONITOR::COR_PRF_ENABLE_REJIT;
        } else {
            log::info!("Initialize: CallTarget instrumentation is disabled");
        }

        if !env::enable_inlining(calltarget_enabled) {
            log::info!("Initialize: JIT Inlining is disabled");
            event_mask |= COR_PRF_MONITOR::COR_PRF_DISABLE_INLINING;
        } else {
            log::info!("Initialize: JIT Inlining is enabled");
        }

        if env::disable_optimizations() {
            log::info!("Initialize: optimizations are disabled");
            event_mask |= COR_PRF_MONITOR::COR_PRF_DISABLE_OPTIMIZATIONS;
        }

        // if the runtime also supports ICorProfilerInfo5, set eventmask2
        if let Some(profiler_info5) = unknown.query_interface::<ICorProfilerInfo5>() {
            let event_mask2 = COR_PRF_HIGH_MONITOR::COR_PRF_HIGH_ADD_ASSEMBLY_REFERENCES;
            log::trace!(
                "Initialize: set event mask2 to {:?}, {:?}",
                &event_mask,
                &event_mask2
            );
            profiler_info5.set_event_mask2(event_mask, event_mask2)?;
        } else {
            log::trace!("Initialize: set event mask to {:?}", &event_mask);
            profiler_info.set_event_mask(event_mask)?;
        }

        // get the details for the runtime
        let runtime_info = profiler_info.get_runtime_information()?;
        let is_desktop_clr = runtime_info.is_desktop_clr();
        let process_name = process_path.file_name().unwrap();
        if process_name == "w3wp.exe" || process_name == "iisexpress.exe" {
            self.is_desktop_iis.store(is_desktop_clr, Ordering::SeqCst);
        }

        // Store the profiler and runtime info for later use
        self.profiler_info.replace(Some(profiler_info));
        self.runtime_info.replace(Some(runtime_info));
        self.logger.replace(logger);

        IS_ATTACHED.store(true, Ordering::SeqCst);
        IS_DESKTOP_CLR.store(is_desktop_clr, Ordering::SeqCst);

        Ok(())
    }