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(())
}