public static void LogDistroPreamble()

in src/Elastic.OpenTelemetry.Core/Diagnostics/LoggerMessages.cs [150:307]


	public static void LogDistroPreamble(this ILogger logger, SdkActivationMethod activationMethod, ElasticOpenTelemetryComponents components)
	{
		// This occurs once per initialisation, so we don't use `LoggerMessage`s.

		logger.LogInformation("Elastic Distribution of OpenTelemetry (EDOT) .NET: {AgentInformationalVersion}", VersionHelper.InformationalVersion);

		if (components.Logger.LogFileEnabled)
		{
			logger.LogInformation("EDOT log file: {LogFilePath}", components.Logger.LogFilePath);
		}
		else
		{
			logger.LogInformation("EDOT log file: <disabled>");
		}

		logger.LogDebug("Activation method: {ActivationMethod}", activationMethod.ToString());

#if NET8_0
		logger.LogDebug("Matched TFM: {TargetFrameworkMoniker}", "net8.0");
#elif NET9_0
		logger.LogDebug("Matched TFM: {TargetFrameworkMoniker}", "net9.0");
#elif NETSTANDARD2_0
		logger.LogDebug("Matched TFM: {TargetFrameworkMoniker}", "netstandard2.0");
#elif NETSTANDARD2_1
		logger.LogDebug("Matched TFM: {TargetFrameworkMoniker}", "netstandard2.1");
#elif NET462
		logger.LogDebug("Matched TFM: {TargetFrameworkMoniker}", "net462");
#else
		logger.LogDebug("Matched TFM: {TargetFrameworkMoniker}", "<unknown>");
#endif

		try
		{
			var process = Process.GetCurrentProcess();

			logger.LogDebug("Process ID: {ProcessId}", process.Id);
			logger.LogDebug("Process name: {ProcessName}", process.ProcessName);

			logger.LogDebug("Process started: {ProcessStartTime:yyyy-MM-dd HH:mm:ss.fff}", process.StartTime.ToUniversalTime());
		}
		catch
		{
			// GetCurrentProcess can throw PlatformNotSupportedException
		}

#if NET
		logger.LogDebug("Process path: {ProcessPath}", Environment.ProcessPath);
#elif NETSTANDARD
		logger.LogDebug("Process path: {ProcessPath}", "<Not available on .NET Standard>");
#elif NETFRAMEWORK
		logger.LogDebug("Process path: {ProcessPath}", "<Not available on .NET Framework>");
#endif

		logger.LogDebug("Machine name: {MachineName}", Environment.MachineName);
		logger.LogDebug("Process username: {UserName}", Environment.UserName);
		logger.LogDebug("User domain name: {UserDomainName}", Environment.UserDomainName);
		logger.LogDebug("Command current directory: {CurrentDirectory}", Environment.CurrentDirectory);
		logger.LogDebug("Processor count: {ProcessorCount}", Environment.ProcessorCount);
		logger.LogDebug("OS version: {OSVersion}", Environment.OSVersion);
		logger.LogDebug("CLR version: {CLRVersion}", Environment.Version);

		string[] environmentVariables =
		[
			EnvironmentVariables.OTEL_DOTNET_AUTO_LOG_DIRECTORY,
			EnvironmentVariables.OTEL_LOG_LEVEL,
			EnvironmentVariables.ELASTIC_OTEL_LOG_TARGETS,
			EnvironmentVariables.DOTNET_RUNNING_IN_CONTAINER,
			EnvironmentVariables.ELASTIC_OTEL_SKIP_OTLP_EXPORTER,
			EnvironmentVariables.OTEL_EXPORTER_OTLP_ENDPOINT,
			EnvironmentVariables.OTEL_EXPORTER_OTLP_TRACES_ENDPOINT,
			EnvironmentVariables.OTEL_EXPORTER_OTLP_METRICS_ENDPOINT,
			EnvironmentVariables.OTEL_EXPORTER_OTLP_LOGS_ENDPOINT,
			EnvironmentVariables.OTEL_EXPORTER_OTLP_TIMEOUT,
			EnvironmentVariables.OTEL_EXPORTER_OTLP_TRACES_TIMEOUT,
			EnvironmentVariables.OTEL_EXPORTER_OTLP_METRICS_TIMEOUT,
			EnvironmentVariables.OTEL_EXPORTER_OTLP_LOGS_TIMEOUT,
			EnvironmentVariables.OTEL_EXPORTER_OTLP_PROTOCOL,
			EnvironmentVariables.OTEL_EXPORTER_OTLP_TRACES_PROTOCOL,
			EnvironmentVariables.OTEL_EXPORTER_OTLP_METRICS_PROTOCOL,
			EnvironmentVariables.OTEL_EXPORTER_OTLP_LOGS_PROTOCOL,
		];

		foreach (var variable in environmentVariables)
		{
			var envVarValue = Environment.GetEnvironmentVariable(variable);

			if (string.IsNullOrEmpty(envVarValue))
			{
				logger.LogDebug("Environment variable '{EnvironmentVariable}' is not configured.", variable);
			}
			else
			{
				logger.LogDebug("Environment variable '{EnvironmentVariable}' = '{EnvironmentVariableValue}'.", variable, envVarValue);
			}
		}

		// This next set of env vars might include sensitive information, so we redact the values.
		string[] headerEnvironmentVariables =
		[
			EnvironmentVariables.OTEL_EXPORTER_OTLP_HEADERS,
			EnvironmentVariables.OTEL_EXPORTER_OTLP_TRACES_HEADERS,
			EnvironmentVariables.OTEL_EXPORTER_OTLP_METRICS_HEADERS,
			EnvironmentVariables.OTEL_EXPORTER_OTLP_LOGS_HEADERS,
		];

		foreach (var variable in headerEnvironmentVariables)
		{
			var envVarValue = Environment.GetEnvironmentVariable(variable);

			const string redacted = "=<redacted>";

			if (string.IsNullOrEmpty(envVarValue))
			{
				logger.LogDebug("Environment variable '{EnvironmentVariable}' is not configured.", variable);
			}
			else
			{
				var valueSpan = envVarValue.AsSpan();
				var buffer = ArrayPool<char>.Shared.Rent(1024);
				var bufferSpan = buffer.AsSpan();
				var position = 0;
				var count = 0;

				while (true)
				{
					var indexOfComma = valueSpan.IndexOf(',');
					var header = valueSpan.Slice(0, indexOfComma > 0 ? indexOfComma : valueSpan.Length);

					var indexOfEquals = valueSpan.IndexOf('=');

					if (indexOfEquals > 0)
					{
						var key = header.Slice(0, indexOfEquals);
						var value = header.Slice(indexOfEquals + 1);

						if (count++ > 0)
							bufferSpan[position++] = ',';

						key.CopyTo(bufferSpan.Slice(position));
						position += key.Length;
						redacted.AsSpan().CopyTo(bufferSpan.Slice(position));
						position += redacted.Length;
					}

					if (indexOfComma <= 0)
						break;

					valueSpan = valueSpan.Slice(indexOfComma + 1);
				}

				logger.LogDebug("Environment variable '{EnvironmentVariable}' = '{EnvironmentVariableValue}'.", variable, bufferSpan.Slice(0, position).ToString());

				ArrayPool<char>.Shared.Return(buffer);
			}
		}

		components.Options.LogConfigSources(logger);
	}