diff --git a/shared/src/Datadog.Trace.ClrProfiler.Native/EnvironmentVariables.h b/shared/src/Datadog.Trace.ClrProfiler.Native/EnvironmentVariables.h index 27d276305ff1..9cf201c3c45f 100644 --- a/shared/src/Datadog.Trace.ClrProfiler.Native/EnvironmentVariables.h +++ b/shared/src/Datadog.Trace.ClrProfiler.Native/EnvironmentVariables.h @@ -19,4 +19,26 @@ class EnvironmentVariables final inline static const shared::WSTRING SingleStepInstrumentationEnabled = WStr("DD_INJECTION_ENABLED"); inline static const shared::WSTRING ForceEolInstrumentation = WStr("DD_INJECT_FORCE"); inline static const shared::WSTRING SingleStepInstrumentationTelemetryForwarderPath = WStr("DD_TELEMETRY_FORWARDER_PATH"); + + // Sets whether the current process must run in CI Visibility mode or not. + inline static const shared::WSTRING CiVisibilityEnabled = WStr("DD_CIVISIBILITY_ENABLED"); + + // Indicates whether the CLR profiler is running from + // the Azure App Services site extension + inline static const shared::WSTRING IsAzureAppServicesExtension = WStr("DD_AZURE_APP_SERVICES"); + + // The app_pool_id in the context of azure app services + inline static const shared::WSTRING AzureAppServicesAppPoolId = WStr("APP_POOL_ID"); + + // The DOTNET_CLI_TELEMETRY_PROFILE in the context of azure app services + inline static const shared::WSTRING AzureAppServicesCliTelemetryProfilerValue = WStr("DOTNET_CLI_TELEMETRY_PROFILE"); + + // The FUNCTIONS_WORKER_RUNTIME in Azure Functions. + // Valid values: "dotnet" (in-process functions) or "dotnet-isolated" (isolated functions). + // Used as a flag to determine that we are running within a functions app. + inline static const shared::WSTRING AzureAppServicesFunctionsWorkerRuntime = WStr("FUNCTIONS_WORKER_RUNTIME"); + + // Determine whether to instrument within azure functions. + // Default is true. + inline static const shared::WSTRING AzureFunctionsInstrumentationEnabled = WStr("DD_TRACE_AZURE_FUNCTIONS_ENABLED"); }; \ No newline at end of file diff --git a/shared/src/Datadog.Trace.ClrProfiler.Native/cor_profiler.cpp b/shared/src/Datadog.Trace.ClrProfiler.Native/cor_profiler.cpp index bfc31aae2fff..fb659fb731fb 100644 --- a/shared/src/Datadog.Trace.ClrProfiler.Native/cor_profiler.cpp +++ b/shared/src/Datadog.Trace.ClrProfiler.Native/cor_profiler.cpp @@ -121,6 +121,9 @@ namespace datadog::shared::nativeloader const auto process_name = ::shared::GetCurrentProcessName(); Log::Debug("ProcessName: ", process_name); + const auto [process_command_line , tokenized_command_line] = GetCurrentProcessCommandLine(); + Log::Info("Process CommandLine: ", process_command_line); + const auto& include_process_names = GetEnvironmentValues(EnvironmentVariables::IncludeProcessNames); // if there is a process inclusion list, attach clrprofiler only if this @@ -158,9 +161,6 @@ namespace datadog::shared::nativeloader // don't give useful information, add latency, and risk triggering bugs in the runtime, // particularly around shutdown, like this one: https://github.com/dotnet/runtime/issues/55441 // Note that you should also consider adding to the SSI tracer/build/artifacts/requirements.json file - const auto [process_command_line , tokenized_command_line] = GetCurrentProcessCommandLine(); - Log::Info("Process CommandLine: ", process_command_line); - if (!process_command_line.empty()) { const auto isDotNetProcess = process_name == WStr("dotnet") || process_name == WStr("dotnet.exe"); @@ -228,6 +228,68 @@ namespace datadog::shared::nativeloader "but an unsupported command was detected"); return CORPROF_E_PROFILER_CANCEL_ACTIVATION; } + + // Additional Special case CI Visibility checks + bool is_ci_visibility_enabled = false; + if (TryParseBooleanEnvironmentValue(GetEnvironmentValue(EnvironmentVariables::CiVisibilityEnabled), is_ci_visibility_enabled) + && is_ci_visibility_enabled) + { + if (tokenized_command_line[1] != WStr("test") && + process_command_line.find(WStr("testhost")) == WSTRING::npos && + process_command_line.find(WStr("exec")) == WSTRING::npos && + process_command_line.find(WStr("datacollector")) == WSTRING::npos && + process_command_line.find(WStr("vstest.console.dll")) == WSTRING::npos) + { + Log::Info("The Tracer Profiler has been disabled because the process is running in CI Visibility " + "mode, the name is 'dotnet' but the commandline doesn't contain 'testhost' or 'datacollector' or 'vstest.console.dll' or 'exec'"); + return CORPROF_E_PROFILER_CANCEL_ACTIVATION; + } + } + } + } + } + + // AAS checks + bool isRunningInAas; + if (TryParseBooleanEnvironmentValue(GetEnvironmentValue(EnvironmentVariables::IsAzureAppServicesExtension), + isRunningInAas) && isRunningInAas) + { + Log::Info("Azure App Services detected."); + + const auto& app_pool_id_value = GetEnvironmentValue(EnvironmentVariables::AzureAppServicesAppPoolId); + + if (app_pool_id_value.size() > 1 && app_pool_id_value.at(0) == '~') + { + Log::Info( + "DATADOG TRACER DIAGNOSTICS - ClrProfiler disabled: ", EnvironmentVariables::AzureAppServicesAppPoolId, " ", + app_pool_id_value, " is an Azure App Services infrastructure process."); + return CORPROF_E_PROFILER_CANCEL_ACTIVATION; + } + + const auto& cli_telemetry_profile_value = + GetEnvironmentValue(EnvironmentVariables::AzureAppServicesCliTelemetryProfilerValue); + + if (cli_telemetry_profile_value == WStr("AzureKudu")) + { + Log::Info("DATADOG TRACER DIAGNOSTICS - ClrProfiler disabled: ", app_pool_id_value, + " is Kudu, an Azure App Services reserved process."); + return CORPROF_E_PROFILER_CANCEL_ACTIVATION; + } + + const auto& functions_worker_runtime_value = + GetEnvironmentValue(EnvironmentVariables::AzureAppServicesFunctionsWorkerRuntime); + + if (!functions_worker_runtime_value.empty()) + { + // enabled by default + bool azure_functions_enabled; + if (TryParseBooleanEnvironmentValue( + GetEnvironmentValue( + EnvironmentVariables::AzureFunctionsInstrumentationEnabled), + azure_functions_enabled) && !azure_functions_enabled) + { + Log::Info("DATADOG TRACER DIAGNOSTICS - ClrProfiler explicitly disabled for Azure Functions."); + return CORPROF_E_PROFILER_CANCEL_ACTIVATION; } } } diff --git a/tracer/src/Datadog.Tracer.Native/cor_profiler.cpp b/tracer/src/Datadog.Tracer.Native/cor_profiler.cpp index 173559e5a95c..a29aba925dfc 100644 --- a/tracer/src/Datadog.Tracer.Native/cor_profiler.cpp +++ b/tracer/src/Datadog.Tracer.Native/cor_profiler.cpp @@ -75,34 +75,6 @@ HRESULT STDMETHODCALLTYPE CorProfiler::Initialize(IUnknown* cor_profiler_info_un const auto process_name = shared::GetCurrentProcessName(); Logger::Info("ProcessName: ", process_name); - const auto [process_command_line , tokenized_command_line ] = GetCurrentProcessCommandLine(); - Logger::Info("Process CommandLine: ", process_command_line); - - // CI visibility checks - if (!process_command_line.empty()) - { - bool is_ci_visibility_enabled = false; - if (shared::TryParseBooleanEnvironmentValue(shared::GetEnvironmentValue(environment::ci_visibility_enabled), - is_ci_visibility_enabled) && - is_ci_visibility_enabled) - { - const auto isDotNetProcess = process_name == WStr("dotnet") || process_name == WStr("dotnet.exe"); - const auto token_count = tokenized_command_line.size(); - if (isDotNetProcess && - token_count > 1 && - tokenized_command_line[1] != WStr("test") && - process_command_line.find(WStr("testhost")) == WSTRING::npos && - process_command_line.find(WStr("exec")) == WSTRING::npos && - process_command_line.find(WStr("datacollector")) == WSTRING::npos && - process_command_line.find(WStr("vstest.console.dll")) == WSTRING::npos) - { - Logger::Info("The Tracer Profiler has been disabled because the process is running in CI Visibility " - "mode, the name is 'dotnet' but the commandline doesn't contain 'testhost' or 'datacollector' or 'vstest.console.dll' or 'exec'"); - return CORPROF_E_PROFILER_CANCEL_ACTIVATION; - } - } - } - #if !defined(_WIN32) && (defined(ARM64) || defined(ARM)) // // In ARM64 and ARM, complete ReJIT support is only available from .NET 5.0 (on .NET Core) @@ -129,39 +101,6 @@ HRESULT STDMETHODCALLTYPE CorProfiler::Initialize(IUnknown* cor_profiler_info_un return E_FAIL; } - const auto& include_process_names = shared::GetEnvironmentValues(environment::include_process_names); - - // if there is a process inclusion list, attach clrprofiler only if this - // process's name is on the list - if (!include_process_names.empty() && !shared::Contains(include_process_names, process_name)) - { - Logger::Info("DATADOG TRACER DIAGNOSTICS - ClrProfiler disabled: ", process_name, " not found in ", - environment::include_process_names, "."); - return CORPROF_E_PROFILER_CANCEL_ACTIVATION; - } - - // if we were on the explicit include list, don't check the block list - if (include_process_names.empty()) - { - // attach clrprofiler only if this process's name is NOT on the blocklists - const auto& exclude_process_names = shared::GetEnvironmentValues(environment::exclude_process_names); - if (!exclude_process_names.empty() && shared::Contains(exclude_process_names, process_name)) - { - Logger::Info("DATADOG TRACER DIAGNOSTICS - ClrProfiler disabled: ", process_name, " found in ", - environment::exclude_process_names, "."); - return CORPROF_E_PROFILER_CANCEL_ACTIVATION; - } - - for (auto&& exclude_assembly : default_exclude_assemblies) - { - if (process_name == exclude_assembly) - { - Logger::Info("DATADOG TRACER DIAGNOSTICS - ClrProfiler disabled: ", process_name," found in default exclude list"); - return CORPROF_E_PROFILER_CANCEL_ACTIVATION; - } - } - } - Logger::Info("Environment variables:"); for (auto&& env_var : env_vars_to_display) { @@ -172,40 +111,6 @@ HRESULT STDMETHODCALLTYPE CorProfiler::Initialize(IUnknown* cor_profiler_info_un } } - if (isRunningInAas) - { - Logger::Info("Profiler is operating within Azure App Services context."); - - const auto& app_pool_id_value = shared::GetEnvironmentValue(environment::azure_app_services_app_pool_id); - - if (app_pool_id_value.size() > 1 && app_pool_id_value.at(0) == '~') - { - Logger::Info( - "DATADOG TRACER DIAGNOSTICS - Profiler disabled: ", environment::azure_app_services_app_pool_id, " ", - app_pool_id_value, " is recognized as an Azure App Services infrastructure process."); - return CORPROF_E_PROFILER_CANCEL_ACTIVATION; - } - - const auto& cli_telemetry_profile_value = - shared::GetEnvironmentValue(environment::azure_app_services_cli_telemetry_profile_value); - - if (cli_telemetry_profile_value == WStr("AzureKudu")) - { - Logger::Info("DATADOG TRACER DIAGNOSTICS - Profiler disabled: ", app_pool_id_value, - " is recognized as Kudu, an Azure App Services reserved process."); - return CORPROF_E_PROFILER_CANCEL_ACTIVATION; - } - - const auto& functions_worker_runtime_value = - shared::GetEnvironmentValue(environment::azure_app_services_functions_worker_runtime); - - if (!functions_worker_runtime_value.empty() && !IsAzureFunctionsEnabled()) - { - Logger::Info("DATADOG TRACER DIAGNOSTICS - Profiler explicitly disabled for Azure Functions."); - return CORPROF_E_PROFILER_CANCEL_ACTIVATION; - } - } - trace_annotations_enabled = IsTraceAnnotationEnabled(); // get ICorProfilerInfo10 for >= .NET Core 3.0 diff --git a/tracer/src/Datadog.Tracer.Native/environment_variables.h b/tracer/src/Datadog.Tracer.Native/environment_variables.h index 19df5a5f01bb..0a43d39a7847 100644 --- a/tracer/src/Datadog.Tracer.Native/environment_variables.h +++ b/tracer/src/Datadog.Tracer.Native/environment_variables.h @@ -89,17 +89,9 @@ namespace environment // The DOTNET_CLI_TELEMETRY_PROFILE in the context of azure app services const shared::WSTRING azure_app_services_cli_telemetry_profile_value = WStr("DOTNET_CLI_TELEMETRY_PROFILE"); - // The FUNCTIONS_WORKER_RUNTIME in the context of azure app services - // Used as a flag to determine that we are running within a functions app. - const shared::WSTRING azure_app_services_functions_worker_runtime = WStr("FUNCTIONS_WORKER_RUNTIME"); - // Sets whether the Tracer will automatically instrument methods that are decorated with a recognized trace attribute const shared::WSTRING trace_annotations_enabled = WStr("DD_TRACE_ANNOTATIONS_ENABLED"); - // Determine whether to instrument within azure functions. - // Default is true. - const shared::WSTRING azure_functions_enabled = WStr("DD_TRACE_AZURE_FUNCTIONS_ENABLED"); - // Enable the profiler to dump the IL original code and modification to the log. const shared::WSTRING dump_il_rewrite_enabled = WStr("DD_DUMP_ILREWRITE_ENABLED"); diff --git a/tracer/src/Datadog.Tracer.Native/environment_variables_util.cpp b/tracer/src/Datadog.Tracer.Native/environment_variables_util.cpp index 4a04309e1ac6..c47e599a275f 100644 --- a/tracer/src/Datadog.Tracer.Native/environment_variables_util.cpp +++ b/tracer/src/Datadog.Tracer.Native/environment_variables_util.cpp @@ -38,11 +38,6 @@ bool IsTraceAnnotationEnabled() ToBooleanWithDefault(shared::GetEnvironmentValue(environment::trace_annotations_enabled), true); } -bool IsAzureFunctionsEnabled() -{ - ToBooleanWithDefault(shared::GetEnvironmentValue(environment::azure_functions_enabled), true); -} - bool IsVersionCompatibilityEnabled() { ToBooleanWithDefault(shared::GetEnvironmentValue(environment::internal_version_compatibility), true); diff --git a/tracer/src/Datadog.Tracer.Native/environment_variables_util.h b/tracer/src/Datadog.Tracer.Native/environment_variables_util.h index ae02915767e2..ad0f82f2762f 100644 --- a/tracer/src/Datadog.Tracer.Native/environment_variables_util.h +++ b/tracer/src/Datadog.Tracer.Native/environment_variables_util.h @@ -56,7 +56,6 @@ bool IsDebugEnabled(); bool IsDumpILRewriteEnabled(); bool IsAzureAppServices(); bool IsTraceAnnotationEnabled(); -bool IsAzureFunctionsEnabled(); bool IsVersionCompatibilityEnabled(); bool IsIastEnabled(); bool IsRaspEnabled();