Support OTEL_DOTNET_AUTO_FAIL_FAST_ENABLED for StartupHook (#2524)
* Documentation * StartupHook - FailFast * Remove unused const * Typo fix * Smoke test for FastFail * Add test for FailFast disabled * better documentation * typo fix
This commit is contained in:
		
							parent
							
								
									12381ceac9
								
							
						
					
					
						commit
						a290429994
					
				|  | @ -9,6 +9,10 @@ This component adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.h | ||||||
| 
 | 
 | ||||||
| ### Added | ### Added | ||||||
| 
 | 
 | ||||||
|  | - The environment variable `OTEL_DOTNET_AUTO_FAIL_FAST_ENABLED` could be | ||||||
|  |   used to enable or disable the failing process when | ||||||
|  |   automatic instrumentation cannot be executed. | ||||||
|  | 
 | ||||||
| ### Changed | ### Changed | ||||||
| 
 | 
 | ||||||
| ### Deprecated | ### Deprecated | ||||||
|  |  | ||||||
|  | @ -20,6 +20,7 @@ with environment variables taking precedence over `App.config` or `Web.config` f | ||||||
| 
 | 
 | ||||||
|     - `OTEL_DOTNET_AUTO_HOME` |     - `OTEL_DOTNET_AUTO_HOME` | ||||||
|     - `OTEL_DOTNET_AUTO_EXCLUDE_PROCESSES` |     - `OTEL_DOTNET_AUTO_EXCLUDE_PROCESSES` | ||||||
|  |     - `OTEL_DOTNET_AUTO_FAIL_FAST_ENABLED` | ||||||
|     - `OTEL_DOTNET_AUTO_[TRACES|METRICS|LOGS]_INSTRUMENTATIONS_ENABLED` |     - `OTEL_DOTNET_AUTO_[TRACES|METRICS|LOGS]_INSTRUMENTATIONS_ENABLED` | ||||||
|     - `OTEL_DOTNET_AUTO_[TRACES|METRICS|LOGS]_{INSTRUMENTATION_ID}_INSTRUMENTATION_ENABLED` |     - `OTEL_DOTNET_AUTO_[TRACES|METRICS|LOGS]_{INSTRUMENTATION_ID}_INSTRUMENTATION_ENABLED` | ||||||
|     - `OTEL_DOTNET_AUTO_LOG_DIRECTORY` |     - `OTEL_DOTNET_AUTO_LOG_DIRECTORY` | ||||||
|  | @ -52,11 +53,16 @@ However, if given setting supports it, then: | ||||||
| 
 | 
 | ||||||
| ## Global settings | ## Global settings | ||||||
| 
 | 
 | ||||||
| | Environment variable                 | Description                                                                                                                                                                                                                  | Default value | Status                                                                                                                            | | | Environment variable                 | Description                                                                                                                                                                                                                        | Default value | Status                                                                                                                            | | ||||||
| |--------------------------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|---------------|-----------------------------------------------------------------------------------------------------------------------------------| | |--------------------------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|---------------|-----------------------------------------------------------------------------------------------------------------------------------| | ||||||
| | `OTEL_DOTNET_AUTO_HOME`              | Installation location.                                                                                                                                                                                                       |               | [Experimental](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/versioning-and-stability.md) | | | `OTEL_DOTNET_AUTO_HOME`              | Installation location.                                                                                                                                                                                                             |               | [Experimental](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/versioning-and-stability.md) | | ||||||
| | `OTEL_DOTNET_AUTO_EXCLUDE_PROCESSES` | Names of the executable files that the profiler cannot instrument. Supports multiple comma-separated values, for example: `ReservedProcess.exe,powershell.exe`. If unset, the profiler attaches to all processes by default. |               | [Experimental](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/versioning-and-stability.md) | | | `OTEL_DOTNET_AUTO_EXCLUDE_PROCESSES` | Names of the executable files that the profiler cannot instrument. Supports multiple comma-separated values, for example: `ReservedProcess.exe,powershell.exe`. If unset, the profiler attaches to all processes by default. \[1\] |               | [Experimental](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/versioning-and-stability.md) | | ||||||
| | `OTEL_LOG_LEVEL`                     | SDK log level. (supported values: `none`,`error`,`warn`,`info`,`debug`)                                                                                                                                                      | `info`        | [Stable](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/versioning-and-stability.md)       | | | `OTEL_DOTNET_AUTO_FAIL_FAST_ENABLED` | Enables possibility to fail process when automatic instrumentation cannot be executed. It is designed for debugging purposes. It should not be used in production environment. \[1\]                                               | `false`       | [Experimental](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/versioning-and-stability.md) | | ||||||
|  | | `OTEL_LOG_LEVEL`                     | SDK log level. (supported values: `none`,`error`,`warn`,`info`,`debug`)                                                                                                                                                            | `info`        | [Stable](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/versioning-and-stability.md)       | | ||||||
|  | 
 | ||||||
|  | \[1\] If `OTEL_DOTNET_AUTO_FAIL_FAST_ENABLED` is set to `true` then processes | ||||||
|  | excluded from instrumentation by `OTEL_DOTNET_AUTO_EXCLUDE_PROCESSES` will fail | ||||||
|  | instead of silently continue. | ||||||
| 
 | 
 | ||||||
| ## Resources | ## Resources | ||||||
| 
 | 
 | ||||||
|  | @ -99,15 +105,15 @@ the `OTEL_DOTNET_AUTO_{SIGNAL}_{0}_INSTRUMENTATION_ENABLED` | ||||||
| environment variable to `false`, where `{SIGNAL}` is the type of signal, | environment variable to `false`, where `{SIGNAL}` is the type of signal, | ||||||
| for example `TRACES`, and `{0}` is the case-sensitive name of the instrumentation. | for example `TRACES`, and `{0}` is the case-sensitive name of the instrumentation. | ||||||
| 
 | 
 | ||||||
| | Environment variable                                   | Description                                                                                                                                                                                                                                                     | Default value                                                                          | Status                                                                                                                            | | | Environment variable                                   | Description                                                                                                                                                                                                    | Default value                                                                          | Status                                                                                                                            | | ||||||
| |--------------------------------------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|----------------------------------------------------------------------------------------|-----------------------------------------------------------------------------------------------------------------------------------| | |--------------------------------------------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|----------------------------------------------------------------------------------------|-----------------------------------------------------------------------------------------------------------------------------------| | ||||||
| | `OTEL_DOTNET_AUTO_INSTRUMENTATION_ENABLED`             | Enables all instrumentations.                                                                                                                                                                                                                                   | `true`                                                                                 | [Experimental](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/versioning-and-stability.md) | | | `OTEL_DOTNET_AUTO_INSTRUMENTATION_ENABLED`             | Enables all instrumentations.                                                                                                                                                                                  | `true`                                                                                 | [Experimental](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/versioning-and-stability.md) | | ||||||
| | `OTEL_DOTNET_AUTO_TRACES_INSTRUMENTATION_ENABLED`      | Enables all trace instrumentations. Overrides `OTEL_DOTNET_AUTO_INSTRUMENTATION_ENABLED`.                                                                                                                                                                       | Inherited from the current value of `OTEL_DOTNET_AUTO_INSTRUMENTATION_ENABLED`         | [Experimental](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/versioning-and-stability.md) | | | `OTEL_DOTNET_AUTO_TRACES_INSTRUMENTATION_ENABLED`      | Enables all trace instrumentations. Overrides `OTEL_DOTNET_AUTO_INSTRUMENTATION_ENABLED`.                                                                                                                      | Inherited from the current value of `OTEL_DOTNET_AUTO_INSTRUMENTATION_ENABLED`         | [Experimental](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/versioning-and-stability.md) | | ||||||
| | `OTEL_DOTNET_AUTO_TRACES_{0}_INSTRUMENTATION_ENABLED`  | Configuration pattern for enabling a specific trace instrumentation, where `{0}` is the uppercase id of the instrumentation you want to enable. Overrides `OTEL_DOTNET_AUTO_TRACES_INSTRUMENTATION_ENABLED`.                                                    | Inherited from the current value of `OTEL_DOTNET_AUTO_TRACES_INSTRUMENTATION_ENABLED`  | [Experimental](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/versioning-and-stability.md) | | | `OTEL_DOTNET_AUTO_TRACES_{0}_INSTRUMENTATION_ENABLED`  | Configuration pattern for enabling a specific trace instrumentation, where `{0}` is the uppercase id of the instrumentation you want to enable. Overrides `OTEL_DOTNET_AUTO_TRACES_INSTRUMENTATION_ENABLED`.   | Inherited from the current value of `OTEL_DOTNET_AUTO_TRACES_INSTRUMENTATION_ENABLED`  | [Experimental](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/versioning-and-stability.md) | | ||||||
| | `OTEL_DOTNET_AUTO_METRICS_INSTRUMENTATION_ENABLED`     | Disables all metric instrumentations. Overrides `OTEL_DOTNET_AUTO_INSTRUMENTATION_ENABLED`.                                                                                                                                                                     | Inherited from the current value of `OTEL_DOTNET_AUTO_INSTRUMENTATION_ENABLED`         | [Experimental](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/versioning-and-stability.md) | | | `OTEL_DOTNET_AUTO_METRICS_INSTRUMENTATION_ENABLED`     | Disables all metric instrumentations. Overrides `OTEL_DOTNET_AUTO_INSTRUMENTATION_ENABLED`.                                                                                                                    | Inherited from the current value of `OTEL_DOTNET_AUTO_INSTRUMENTATION_ENABLED`         | [Experimental](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/versioning-and-stability.md) | | ||||||
| | `OTEL_DOTNET_AUTO_METRICS_{0}_INSTRUMENTATION_ENABLED` | Configuration pattern for enabling a specific metric instrumentation, where `{0}` is the uppercase id of the instrumentation you want to enable. Overrides `OTEL_DOTNET_AUTO_METRICS_INSTRUMENTATION_ENABLED`.                                                  | Inherited from the current value of `OTEL_DOTNET_AUTO_METRICS_INSTRUMENTATION_ENABLED` | [Experimental](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/versioning-and-stability.md) | | | `OTEL_DOTNET_AUTO_METRICS_{0}_INSTRUMENTATION_ENABLED` | Configuration pattern for enabling a specific metric instrumentation, where `{0}` is the uppercase id of the instrumentation you want to enable. Overrides `OTEL_DOTNET_AUTO_METRICS_INSTRUMENTATION_ENABLED`. | Inherited from the current value of `OTEL_DOTNET_AUTO_METRICS_INSTRUMENTATION_ENABLED` | [Experimental](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/versioning-and-stability.md) | | ||||||
| | `OTEL_DOTNET_AUTO_LOGS_INSTRUMENTATION_ENABLED`        | Disables all log instrumentations. Overrides `OTEL_DOTNET_AUTO_INSTRUMENTATION_ENABLED`.                                                                                                                                                                        | Inherited from the current value of `OTEL_DOTNET_AUTO_INSTRUMENTATION_ENABLED`         | [Experimental](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/versioning-and-stability.md) | | | `OTEL_DOTNET_AUTO_LOGS_INSTRUMENTATION_ENABLED`        | Disables all log instrumentations. Overrides `OTEL_DOTNET_AUTO_INSTRUMENTATION_ENABLED`.                                                                                                                       | Inherited from the current value of `OTEL_DOTNET_AUTO_INSTRUMENTATION_ENABLED`         | [Experimental](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/versioning-and-stability.md) | | ||||||
| | `OTEL_DOTNET_AUTO_LOGS_{0}_INSTRUMENTATION_ENABLED`    | Configuration pattern for enabling a specific log instrumentation, where `{0}` is the uppercase id of the instrumentation you want to enable. Overrides `OTEL_DOTNET_AUTO_LOGS_INSTRUMENTATION_ENABLED`.                                                        | Inherited from the current value of `OTEL_DOTNET_AUTO_LOGS_INSTRUMENTATION_ENABLED`    | [Experimental](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/versioning-and-stability.md) | | | `OTEL_DOTNET_AUTO_LOGS_{0}_INSTRUMENTATION_ENABLED`    | Configuration pattern for enabling a specific log instrumentation, where `{0}` is the uppercase id of the instrumentation you want to enable. Overrides `OTEL_DOTNET_AUTO_LOGS_INSTRUMENTATION_ENABLED`.       | Inherited from the current value of `OTEL_DOTNET_AUTO_LOGS_INSTRUMENTATION_ENABLED`    | [Experimental](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/versioning-and-stability.md) | | ||||||
| 
 | 
 | ||||||
| ### Traces instrumentations | ### Traces instrumentations | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -15,7 +15,6 @@ | ||||||
| // </copyright> | // </copyright> | ||||||
| 
 | 
 | ||||||
| using System.Reflection; | using System.Reflection; | ||||||
| using System.Runtime.Versioning; |  | ||||||
| using OpenTelemetry.AutoInstrumentation.Logging; | using OpenTelemetry.AutoInstrumentation.Logging; | ||||||
| using OpenTelemetry.AutoInstrumentation.RulesEngine; | using OpenTelemetry.AutoInstrumentation.RulesEngine; | ||||||
| 
 | 
 | ||||||
|  | @ -35,6 +34,8 @@ internal class StartupHook | ||||||
|     /// </summary> |     /// </summary> | ||||||
|     public static void Initialize() |     public static void Initialize() | ||||||
|     { |     { | ||||||
|  |         bool.TryParse(Environment.GetEnvironmentVariable("OTEL_DOTNET_AUTO_FAIL_FAST_ENABLED"), out var failFast); | ||||||
|  | 
 | ||||||
|         try |         try | ||||||
|         { |         { | ||||||
|             LoaderAssemblyLocation = GetLoaderAssemblyLocation(); |             LoaderAssemblyLocation = GetLoaderAssemblyLocation(); | ||||||
|  | @ -42,20 +43,22 @@ internal class StartupHook | ||||||
|             var ruleEngine = new RuleEngine(); |             var ruleEngine = new RuleEngine(); | ||||||
|             if (!ruleEngine.ValidateRules()) |             if (!ruleEngine.ValidateRules()) | ||||||
|             { |             { | ||||||
|                 Logger.Error("Rule Engine Failure: One or more rules failed validation. Automatic Instrumentation won't be loaded."); |                 throw new Exception("Rule Engine Failure: One or more rules failed validation. Automatic Instrumentation won't be loaded."); | ||||||
|                 return; |  | ||||||
|             } |             } | ||||||
| 
 | 
 | ||||||
|             Logger.Information("Initialization."); |             Logger.Information("Initialization."); | ||||||
| 
 | 
 | ||||||
|             // Creating an instance of OpenTelemetry.AutoInstrumentation.Loader.Startup |             // Creating an instance of OpenTelemetry.AutoInstrumentation.Loader.Startup | ||||||
|             // will initialize Instrumentation through its static constructor. |             // will initialize Instrumentation through its static constructor. | ||||||
|             string loaderFilePath = Path.Combine(LoaderAssemblyLocation, "OpenTelemetry.AutoInstrumentation.Loader.dll"); |             var loaderFilePath = Path.Combine(LoaderAssemblyLocation, "OpenTelemetry.AutoInstrumentation.Loader.dll"); | ||||||
|             Assembly loaderAssembly = Assembly.LoadFrom(loaderFilePath); |             var loaderAssembly = Assembly.LoadFrom(loaderFilePath); | ||||||
|             var loaderInstance = loaderAssembly.CreateInstance("OpenTelemetry.AutoInstrumentation.Loader.Loader"); |             var loaderInstance = loaderAssembly.CreateInstance("OpenTelemetry.AutoInstrumentation.Loader.Loader"); | ||||||
|             if (loaderInstance is null) |             if (loaderInstance is null) | ||||||
|             { |             { | ||||||
|                 Logger.Error("StartupHook failed to create an instance of the Loader"); |                 if (failFast) | ||||||
|  |                 { | ||||||
|  |                     throw new Exception("StartupHook failed to create an instance of the Loader"); | ||||||
|  |                 } | ||||||
|             } |             } | ||||||
|             else |             else | ||||||
|             { |             { | ||||||
|  | @ -64,8 +67,11 @@ internal class StartupHook | ||||||
|         } |         } | ||||||
|         catch (Exception ex) |         catch (Exception ex) | ||||||
|         { |         { | ||||||
|             Logger.Error($"Error in StartupHook initialization: LoaderFolderLocation: {LoaderAssemblyLocation}, Error: {ex}"); |             Logger.Error(ex, $"Error in StartupHook initialization: LoaderFolderLocation: {LoaderAssemblyLocation}"); | ||||||
|             throw; |             if (failFast) | ||||||
|  |             { | ||||||
|  |                 throw; | ||||||
|  |             } | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -17,7 +17,7 @@ | ||||||
| namespace OpenTelemetry.AutoInstrumentation.Configurations; | namespace OpenTelemetry.AutoInstrumentation.Configurations; | ||||||
| 
 | 
 | ||||||
| /// <summary> | /// <summary> | ||||||
| /// Represents the configration taken from one or more configuration sources. | /// Represents the configuration taken from one or more configuration sources. | ||||||
| /// </summary> | /// </summary> | ||||||
| internal class Configuration | internal class Configuration | ||||||
| { | { | ||||||
|  |  | ||||||
|  | @ -32,14 +32,6 @@ internal static class ConfigurationKeys | ||||||
|     /// </summary> |     /// </summary> | ||||||
|     public const string ExporterOtlpProtocol = "OTEL_EXPORTER_OTLP_PROTOCOL"; |     public const string ExporterOtlpProtocol = "OTEL_EXPORTER_OTLP_PROTOCOL"; | ||||||
| 
 | 
 | ||||||
|     /// <summary> |  | ||||||
|     /// Configuration key for setting the directory for the profiler's log files. |  | ||||||
|     /// If not set, default is |  | ||||||
|     /// "%ProgramData%"\OpenTelemetry .NET AutoInstrumentation\logs\" on Windows or |  | ||||||
|     /// "/var/log/opentelemetry/dotnet/" on Linux. |  | ||||||
|     /// </summary> |  | ||||||
|     public const string LogDirectory = "OTEL_DOTNET_AUTO_LOG_DIRECTORY"; |  | ||||||
| 
 |  | ||||||
|     /// <summary> |     /// <summary> | ||||||
|     /// Configuration key for enabling the flushing of telemetry data when an unhandled exception occurs. |     /// Configuration key for enabling the flushing of telemetry data when an unhandled exception occurs. | ||||||
|     /// </summary> |     /// </summary> | ||||||
|  |  | ||||||
|  | @ -15,12 +15,12 @@ | ||||||
| // </copyright> | // </copyright> | ||||||
| 
 | 
 | ||||||
| using System.Reflection; | using System.Reflection; | ||||||
|  | using FluentAssertions; | ||||||
| using IntegrationTests.Helpers; | using IntegrationTests.Helpers; | ||||||
| using Xunit.Abstractions; | using Xunit.Abstractions; | ||||||
| 
 | 
 | ||||||
| #if NETFRAMEWORK | #if NETFRAMEWORK | ||||||
| using System.Net; | using System.Net; | ||||||
| using FluentAssertions; |  | ||||||
| using FluentAssertions.Extensions; | using FluentAssertions.Extensions; | ||||||
| using IntegrationTests.Helpers.Compatibility; | using IntegrationTests.Helpers.Compatibility; | ||||||
| #endif | #endif | ||||||
|  | @ -348,6 +348,38 @@ public class SmokeTests : TestHelper | ||||||
|         collector.AssertEmpty(); |         collector.AssertEmpty(); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  |     [Fact] | ||||||
|  |     [Trait("Category", "EndToEnd")] | ||||||
|  |     public void ApplicationFailFastDisabled() | ||||||
|  |     { | ||||||
|  |         SetEnvironmentVariable("OTEL_DOTNET_AUTO_EXCLUDE_PROCESSES", $"dotnet,dotnet.exe,{EnvironmentHelper.FullTestApplicationName},{EnvironmentHelper.FullTestApplicationName}.exe"); | ||||||
|  |         SetEnvironmentVariable("OTEL_DOTNET_AUTO_FAIL_FAST_ENABLED", "false"); | ||||||
|  | 
 | ||||||
|  |         VerifyTestApplicationNotInstrumented(); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  | #if NET6_0_OR_GREATER | ||||||
|  |     [Fact] | ||||||
|  |     [Trait("Category", "EndToEnd")] | ||||||
|  |     public void ApplicationFailFastEnabled() | ||||||
|  |     { | ||||||
|  |         SetEnvironmentVariable("OTEL_DOTNET_AUTO_EXCLUDE_PROCESSES", $"dotnet,dotnet.exe,{EnvironmentHelper.FullTestApplicationName},{EnvironmentHelper.FullTestApplicationName}.exe"); | ||||||
|  |         SetEnvironmentVariable("OTEL_DOTNET_AUTO_FAIL_FAST_ENABLED", "true"); | ||||||
|  |         var process = StartTestApplication(); | ||||||
|  | 
 | ||||||
|  |         process.Should().NotBeNull(); | ||||||
|  |         var processTimeout = !process!.WaitForExit((int)TestTimeout.ProcessExit.TotalMilliseconds); | ||||||
|  |         if (processTimeout) | ||||||
|  |         { | ||||||
|  |             process.Kill(); | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         processTimeout.Should().BeFalse(); | ||||||
|  | 
 | ||||||
|  |         process!.ExitCode.Should().NotBe(0); | ||||||
|  |     } | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
|     private void VerifyTestApplicationInstrumented() |     private void VerifyTestApplicationInstrumented() | ||||||
|     { |     { | ||||||
|         using var collector = new MockSpansCollector(Output); |         using var collector = new MockSpansCollector(Output); | ||||||
|  |  | ||||||
		Loading…
	
		Reference in New Issue