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:
Piotr Kiełkowicz 2023-05-10 21:05:08 +02:00 committed by GitHub
parent 12381ceac9
commit a290429994
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 72 additions and 32 deletions

View File

@ -9,6 +9,10 @@ This component adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.h
### 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
### Deprecated

View File

@ -20,6 +20,7 @@ with environment variables taking precedence over `App.config` or `Web.config` f
- `OTEL_DOTNET_AUTO_HOME`
- `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]_{INSTRUMENTATION_ID}_INSTRUMENTATION_ENABLED`
- `OTEL_DOTNET_AUTO_LOG_DIRECTORY`
@ -52,11 +53,16 @@ However, if given setting supports it, then:
## Global settings
| 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_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_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) |
| 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_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_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
@ -99,15 +105,15 @@ the `OTEL_DOTNET_AUTO_{SIGNAL}_{0}_INSTRUMENTATION_ENABLED`
environment variable to `false`, where `{SIGNAL}` is the type of signal,
for example `TRACES`, and `{0}` is the case-sensitive name of the instrumentation.
| 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_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_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_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) |
| 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_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_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_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) |
### Traces instrumentations

View File

@ -15,7 +15,6 @@
// </copyright>
using System.Reflection;
using System.Runtime.Versioning;
using OpenTelemetry.AutoInstrumentation.Logging;
using OpenTelemetry.AutoInstrumentation.RulesEngine;
@ -35,6 +34,8 @@ internal class StartupHook
/// </summary>
public static void Initialize()
{
bool.TryParse(Environment.GetEnvironmentVariable("OTEL_DOTNET_AUTO_FAIL_FAST_ENABLED"), out var failFast);
try
{
LoaderAssemblyLocation = GetLoaderAssemblyLocation();
@ -42,20 +43,22 @@ internal class StartupHook
var ruleEngine = new RuleEngine();
if (!ruleEngine.ValidateRules())
{
Logger.Error("Rule Engine Failure: One or more rules failed validation. Automatic Instrumentation won't be loaded.");
return;
throw new Exception("Rule Engine Failure: One or more rules failed validation. Automatic Instrumentation won't be loaded.");
}
Logger.Information("Initialization.");
// Creating an instance of OpenTelemetry.AutoInstrumentation.Loader.Startup
// will initialize Instrumentation through its static constructor.
string loaderFilePath = Path.Combine(LoaderAssemblyLocation, "OpenTelemetry.AutoInstrumentation.Loader.dll");
Assembly loaderAssembly = Assembly.LoadFrom(loaderFilePath);
var loaderFilePath = Path.Combine(LoaderAssemblyLocation, "OpenTelemetry.AutoInstrumentation.Loader.dll");
var loaderAssembly = Assembly.LoadFrom(loaderFilePath);
var loaderInstance = loaderAssembly.CreateInstance("OpenTelemetry.AutoInstrumentation.Loader.Loader");
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
{
@ -64,8 +67,11 @@ internal class StartupHook
}
catch (Exception ex)
{
Logger.Error($"Error in StartupHook initialization: LoaderFolderLocation: {LoaderAssemblyLocation}, Error: {ex}");
throw;
Logger.Error(ex, $"Error in StartupHook initialization: LoaderFolderLocation: {LoaderAssemblyLocation}");
if (failFast)
{
throw;
}
}
}

View File

@ -17,7 +17,7 @@
namespace OpenTelemetry.AutoInstrumentation.Configurations;
/// <summary>
/// Represents the configration taken from one or more configuration sources.
/// Represents the configuration taken from one or more configuration sources.
/// </summary>
internal class Configuration
{

View File

@ -32,14 +32,6 @@ internal static class ConfigurationKeys
/// </summary>
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>
/// Configuration key for enabling the flushing of telemetry data when an unhandled exception occurs.
/// </summary>

View File

@ -15,12 +15,12 @@
// </copyright>
using System.Reflection;
using FluentAssertions;
using IntegrationTests.Helpers;
using Xunit.Abstractions;
#if NETFRAMEWORK
using System.Net;
using FluentAssertions;
using FluentAssertions.Extensions;
using IntegrationTests.Helpers.Compatibility;
#endif
@ -348,6 +348,38 @@ public class SmokeTests : TestHelper
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()
{
using var collector = new MockSpansCollector(Output);