Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Make DirectLogSubmissionSettings properly immutable and remove ImmutableDirectLogSubmissionSettings #6400

Merged
merged 2 commits into from
Dec 10, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 0 additions & 30 deletions tracer/src/Datadog.Trace/Ci/CIVisibility.cs
Original file line number Diff line number Diff line change
Expand Up @@ -129,21 +129,6 @@ public static void Initialize()

var tracerSettings = settings.TracerSettings;
Log.Debug("Setting up the test session name to: {TestSessionName}", settings.TestSessionName);

// Set the service name if empty
if (string.IsNullOrEmpty(tracerSettings.ServiceName))
{
// Extract repository name from the git url and use it as a default service name.
tracerSettings.ServiceName = GetServiceNameFromRepository(CIEnvironmentValues.Instance.Repository);
tracerSettings.GlobalTags[CommonTags.UserProvidedTestServiceTag] = "false";
}
else
{
tracerSettings.GlobalTags[CommonTags.UserProvidedTestServiceTag] = "true";
}

// Normalize the service name
tracerSettings.ServiceName = NormalizerTraceProcessor.NormalizeService(tracerSettings.ServiceName);
Log.Debug("Setting up the service name to: {ServiceName}", tracerSettings.ServiceName);

// Initialize Tracer
Expand Down Expand Up @@ -203,21 +188,6 @@ internal static void InitializeFromRunner(CIVisibilitySettings settings, IDiscov

var tracerSettings = settings.TracerSettings;
Log.Debug("Setting up the test session name to: {TestSessionName}", settings.TestSessionName);

// Set the service name if empty
if (string.IsNullOrEmpty(tracerSettings.ServiceName))
{
// Extract repository name from the git url and use it as a default service name.
tracerSettings.ServiceName = GetServiceNameFromRepository(CIEnvironmentValues.Instance.Repository);
tracerSettings.GlobalTags[CommonTags.UserProvidedTestServiceTag] = "false";
}
else
{
tracerSettings.GlobalTags[CommonTags.UserProvidedTestServiceTag] = "true";
}

// Normalize the service name
tracerSettings.ServiceName = NormalizerTraceProcessor.NormalizeService(tracerSettings.ServiceName);
Log.Debug("Setting up the service name to: {ServiceName}", tracerSettings.ServiceName);

// Initialize Tracer
Expand Down
39 changes: 19 additions & 20 deletions tracer/src/Datadog.Trace/Ci/Configuration/CIVisibilitySettings.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
#nullable enable

using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Linq;
using System.Runtime.CompilerServices;
Expand Down Expand Up @@ -298,32 +299,30 @@ internal void SetDefaultManualInstrumentationSettings()
}

private TracerSettings InitializeTracerSettings()
{
var source = GlobalConfigurationSource.CreateDefaultConfigurationSource();
var defaultExcludedUrlSubstrings = string.Empty;
var configResult = source.GetString(ConfigurationKeys.HttpClientExcludedUrlSubstrings, NullConfigurationTelemetry.Instance, validator: null, recordValue: false);
if (configResult is { IsValid: true, Result: { } substrings } && !string.IsNullOrWhiteSpace(substrings))
{
defaultExcludedUrlSubstrings = substrings + ", ";
}
=> InitializeTracerSettings(GlobalConfigurationSource.CreateDefaultConfigurationSource());

source.Insert(0, new NameValueConfigurationSource(
new NameValueCollection
{
[ConfigurationKeys.HttpClientExcludedUrlSubstrings] = defaultExcludedUrlSubstrings + "/session/FakeSessionIdForPollingPurposes",
},
ConfigurationOrigins.Calculated));

var tracerSettings = new TracerSettings(source, new ConfigurationTelemetry(), new OverrideErrorLog());
// Internal for testing
internal TracerSettings InitializeTracerSettings(CompositeConfigurationSource source)
{
// This is a somewhat hacky way to "tell" TracerSettings that we're running in CI Visibility
// There's no doubt various other ways we could flag it based on values we're _already_ extracting,
// but we don't want to set up too much interdependence there.
var telemetry = new ConfigurationTelemetry();
var additionalSource = new Dictionary<string, object?> { { ConfigurationKeys.CIVisibility.IsRunningInCiVisMode, true } };

if (Logs)
{
// Enable the direct log submission
tracerSettings.LogSubmissionSettings.DirectLogSubmissionEnabledIntegrations.Add("XUnit");
tracerSettings.LogSubmissionSettings.DirectLogSubmissionBatchPeriod = TimeSpan.FromSeconds(1);
// fetch the "original" values, and update them with the CI Visibility settings
var enabledDirectLogSubmissionIntegrations = new ConfigurationBuilder(source, telemetry)
.WithKeys(ConfigurationKeys.DirectLogSubmission.EnabledIntegrations)
.AsString();
var logIntegrations = enabledDirectLogSubmissionIntegrations + ";XUnit";
additionalSource[ConfigurationKeys.DirectLogSubmission.EnabledIntegrations] = logIntegrations;
additionalSource[ConfigurationKeys.DirectLogSubmission.BatchPeriodSeconds] = 1;
}

return tracerSettings;
var newSource = new CompositeConfigurationSource([new DictionaryObjectConfigurationSource(additionalSource), source]);
return new TracerSettings(newSource, telemetry, new OverrideErrorLog());
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,21 +17,21 @@ internal static class DirectLogSubmission
/// Default is empty (direct log submission disabled).
/// Supports multiple values separated with semi-colons.
/// </summary>
/// <seealso cref="DirectLogSubmissionSettings.DirectLogSubmissionEnabledIntegrations"/>
/// <seealso cref="DirectLogSubmissionSettings.EnabledIntegrationNames"/>
public const string EnabledIntegrations = "DD_LOGS_DIRECT_SUBMISSION_INTEGRATIONS";

/// <summary>
/// Set the name of the originating host for direct logs submission.
/// Required for direct logs submission (default is machine name).
/// </summary>
/// <seealso cref="DirectLogSubmissionSettings.DirectLogSubmissionHost"/>
/// <seealso cref="DirectLogSubmissionSettings.Host"/>
public const string Host = "DD_LOGS_DIRECT_SUBMISSION_HOST";

/// <summary>
/// Set the originating source for direct logs submission.
/// Default is 'csharp'
/// </summary>
/// <seealso cref="DirectLogSubmissionSettings.DirectLogSubmissionSource"/>
/// <seealso cref="DirectLogSubmissionSettings.Source"/>
public const string Source = "DD_LOGS_DIRECT_SUBMISSION_SOURCE";

/// <summary>
Expand All @@ -40,44 +40,44 @@ internal static class DirectLogSubmission
/// value are colon-separated. For example Key1:Value1, Key2:Value2. If not provided,
/// <see cref="ConfigurationKeys.GlobalTags"/> are used instead
/// </summary>
/// <seealso cref="DirectLogSubmissionSettings.DirectLogSubmissionGlobalTags"/>
/// <seealso cref="DirectLogSubmissionSettings.GlobalTags"/>
public const string GlobalTags = "DD_LOGS_DIRECT_SUBMISSION_TAGS";

/// <summary>
/// Configuration key for the url to send logs to.
/// Default value uses the domain set in <see cref="ConfigurationKeys.Site"/>, so defaults to
/// <c>https://http-intake.logs.datadoghq.com:443</c>.
/// </summary>
/// <seealso cref="DirectLogSubmissionSettings.DirectLogSubmissionUrl"/>
/// <seealso cref="DirectLogSubmissionSettings.IntakeUrl"/>
public const string Url = "DD_LOGS_DIRECT_SUBMISSION_URL";

/// <summary>
/// Configuration key for the minimum level logs should have to be sent to the intake.
/// Default value is <c>Information</c>.
/// Should be one of <c>Verbose</c>,<c>Debug</c>,<c>Information</c>,<c>Warning</c>,<c>Error</c>,<c>Fatal</c>
/// </summary>
/// <seealso cref="DirectLogSubmissionSettings.DirectLogSubmissionMinimumLevel"/>
/// <seealso cref="DirectLogSubmissionSettings.MinimumLevel"/>
public const string MinimumLevel = "DD_LOGS_DIRECT_SUBMISSION_MINIMUM_LEVEL";

/// <summary>
/// Configuration key for the maximum number of logs to send at one time
/// Default value is <c>1,000</c>, the maximum accepted by the Datadog log API
/// </summary>
/// <seealso cref="DirectLogSubmissionSettings.DirectLogSubmissionBatchSizeLimit"/>
/// <seealso cref="DirectLogSubmissionSettings.BatchSizeLimit"/>
public const string BatchSizeLimit = "DD_LOGS_DIRECT_SUBMISSION_MAX_BATCH_SIZE";

/// <summary>
/// Configuration key for the maximum number of logs to hold in internal queue at any one time
/// Default value is <c>100,000</c>.
/// </summary>
/// <seealso cref="DirectLogSubmissionSettings.DirectLogSubmissionQueueSizeLimit"/>
/// <seealso cref="DirectLogSubmissionSettings.QueueSizeLimit"/>
public const string QueueSizeLimit = "DD_LOGS_DIRECT_SUBMISSION_MAX_QUEUE_SIZE";

/// <summary>
/// Configuration key for the time to wait between checking for batches
/// Default value is <c>2</c>s.
/// </summary>
/// <seealso cref="DirectLogSubmissionSettings.DirectLogSubmissionBatchPeriod"/>
/// <seealso cref="DirectLogSubmissionSettings.BatchPeriod"/>
public const string BatchPeriodSeconds = "DD_LOGS_DIRECT_SUBMISSION_BATCH_PERIOD_SECONDS";
}
}
Expand Down
5 changes: 5 additions & 0 deletions tracer/src/Datadog.Trace/Configuration/ConfigurationKeys.cs
Original file line number Diff line number Diff line change
Expand Up @@ -493,6 +493,11 @@ internal static partial class ConfigurationKeys
/// </summary>
public static class CIVisibility
{
/// <summary>
/// An internal key used to "tell" tracer settings that we're running in CI Visibility mode
/// </summary>
public const string IsRunningInCiVisMode = "_DD_INTERNAL_IS_RUNNING_IN_CIVISIBILITY";

/// <summary>
/// Configuration key for enabling or disabling CI Visibility.
/// Default value is false (disabled).
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -140,7 +140,7 @@ internal ImmutableTracerSettings(TracerSettings settings, bool unusedParamNotToU
_isDataStreamsMonitoringEnabled = settings.IsDataStreamsMonitoringEnabled;
IsRareSamplerEnabled = settings.IsRareSamplerEnabled;

LogSubmissionSettings = ImmutableDirectLogSubmissionSettings.Create(settings.LogSubmissionSettings);
LogSubmissionSettings = settings.LogSubmissionSettings;
_logsInjectionEnabled = settings.LogSubmissionSettings.LogsInjectionEnabled;

// we cached the static instance here, because is being used in the hotpath
Expand Down Expand Up @@ -460,7 +460,7 @@ internal ImmutableTracerSettings(TracerSettings settings, bool unusedParamNotToU
/// </summary>
internal int QueryStringReportingSize { get; }

internal ImmutableDirectLogSubmissionSettings LogSubmissionSettings { get; }
internal DirectLogSubmissionSettings LogSubmissionSettings { get; }

/// <summary>
/// Gets a value indicating whether to enable the updated WCF instrumentation that delays execution
Expand Down
50 changes: 48 additions & 2 deletions tracer/src/Datadog.Trace/Configuration/TracerSettings.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,15 @@
using System.Diagnostics.CodeAnalysis;
using System.Linq;
using System.Text.RegularExpressions;
using Datadog.Trace.Ci;
using Datadog.Trace.Ci.CiEnvironment;
using Datadog.Trace.ClrProfiler;
using Datadog.Trace.ClrProfiler.ServerlessInstrumentation;
using Datadog.Trace.Configuration.ConfigurationSources.Telemetry;
using Datadog.Trace.Configuration.Telemetry;
using Datadog.Trace.Logging;
using Datadog.Trace.Logging.DirectSubmission;
using Datadog.Trace.Processors;
using Datadog.Trace.Propagators;
using Datadog.Trace.Sampling;
using Datadog.Trace.SourceGenerators;
Expand Down Expand Up @@ -87,6 +90,11 @@ internal TracerSettings(IConfigurationSource? source, IConfigurationTelemetry te
GCPFunctionSettings = new ImmutableGCPFunctionSettings(source, _telemetry);
IsRunningInGCPFunctions = GCPFunctionSettings.IsGCPFunction;

// We don't want/need to record this value, so explicitly use null telemetry
var isRunningInCiVisibility = new ConfigurationBuilder(source, NullConfigurationTelemetry.Instance)
.WithKeys(ConfigurationKeys.CIVisibility.IsRunningInCiVisMode)
.AsBool(false);

LambdaMetadata = LambdaMetadata.Create();

IsRunningInAzureAppService = ImmutableAzureAppServiceSettings.GetIsAzureAppService(source, telemetry);
Expand Down Expand Up @@ -124,11 +132,34 @@ _ when x.ToBoolean() is { } boolean => boolean,
.AsString();

var otelServiceName = config.WithKeys(ConfigurationKeys.OpenTelemetry.ServiceName).AsStringResult();
ServiceName = config
var serviceName = config
.WithKeys(ConfigurationKeys.ServiceName, "DD_SERVICE_NAME")
.AsStringResult()
.OverrideWith(in otelServiceName, ErrorLog);

var isUserProvidedTestServiceTag = true;
if (isRunningInCiVisibility)
{
// Set the service name if not set
var ciVisServiceName = serviceName;
if (string.IsNullOrEmpty(serviceName))
{
// Extract repository name from the git url and use it as a default service name.
ciVisServiceName = CIVisibility.GetServiceNameFromRepository(CIEnvironmentValues.Instance.Repository);
isUserProvidedTestServiceTag = false;
}

// Normalize the service name
ciVisServiceName = NormalizerTraceProcessor.NormalizeService(ciVisServiceName);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe we should move the debug log somewhere around there

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

IMO not required. It gets logged by the tracer manager and in telemetry anyway 🤷‍♂️

if (ciVisServiceName != serviceName)
{
serviceName = ciVisServiceName;
telemetry.Record(ConfigurationKeys.ServiceName, serviceName, recordValue: true, ConfigurationOrigins.Calculated);
}
}

ServiceName = serviceName;

ServiceVersion = config
.WithKeys(ConfigurationKeys.ServiceVersion)
.AsString();
Expand Down Expand Up @@ -204,6 +235,11 @@ _ when x.ToBoolean() is { } boolean => boolean,
.Where(kvp => !string.IsNullOrWhiteSpace(kvp.Key) && !string.IsNullOrWhiteSpace(kvp.Value))
.ToDictionary(kvp => kvp.Key.Trim(), kvp => kvp.Value.Trim());

if (isRunningInCiVisibility)
{
GlobalTags[Ci.Tags.CommonTags.UserProvidedTestServiceTag] = isUserProvidedTestServiceTag ? "true" : "false";
}

var headerTagsNormalizationFixEnabled = config
.WithKeys(ConfigurationKeys.FeatureFlags.HeaderTagsNormalizationFixEnabled)
.AsBool(defaultValue: true);
Expand Down Expand Up @@ -477,9 +513,19 @@ _ when x.ToBoolean() is { } boolean => boolean,
IsRunningInAzureAppService ? ImmutableAzureAppServiceSettings.DefaultHttpClientExclusions :
LambdaMetadata is { IsRunningInLambda: true } m ? m.DefaultHttpClientExclusions : string.Empty);

if (isRunningInCiVisibility)
{
// always add the additional exclude in ci vis
const string fakeSessionEndpoint = "/session/FakeSessionIdForPollingPurposes";
urlSubstringSkips = string.IsNullOrEmpty(urlSubstringSkips)
? fakeSessionEndpoint
: $"{urlSubstringSkips},{fakeSessionEndpoint}";
telemetry.Record(ConfigurationKeys.HttpClientExcludedUrlSubstrings, urlSubstringSkips, recordValue: true, ConfigurationOrigins.Calculated);
}

HttpClientExcludedUrlSubstrings = !string.IsNullOrEmpty(urlSubstringSkips)
? TrimSplitString(urlSubstringSkips.ToUpperInvariant(), commaSeparator)
: Array.Empty<string>();
: [];

DbmPropagationMode = config
.WithKeys(ConfigurationKeys.DbmPropagationMode)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,14 +16,14 @@ internal class DirectLogSubmissionManager
{
private static readonly IDatadogLogger Logger = DatadogLogging.GetLoggerFor<DirectLogSubmissionManager>();

private DirectLogSubmissionManager(ImmutableDirectLogSubmissionSettings settings, IDirectSubmissionLogSink sink, LogFormatter formatter)
private DirectLogSubmissionManager(DirectLogSubmissionSettings settings, IDirectSubmissionLogSink sink, LogFormatter formatter)
{
Settings = settings;
Sink = sink;
Formatter = formatter;
}

public ImmutableDirectLogSubmissionSettings Settings { get; }
public DirectLogSubmissionSettings Settings { get; }

public IDirectSubmissionLogSink Sink { get; }

Expand All @@ -32,7 +32,7 @@ private DirectLogSubmissionManager(ImmutableDirectLogSubmissionSettings settings
public static DirectLogSubmissionManager Create(
DirectLogSubmissionManager? previous,
ImmutableTracerSettings settings,
ImmutableDirectLogSubmissionSettings directLogSettings,
DirectLogSubmissionSettings directLogSettings,
ImmutableAzureAppServiceSettings? azureAppServiceSettings,
string serviceName,
string env,
Expand All @@ -56,7 +56,7 @@ public static DirectLogSubmissionManager Create(
var apiFactory = LogsTransportStrategy.Get(directLogSettings);
var logsApi = new LogsApi(directLogSettings.ApiKey, apiFactory);

return new DirectLogSubmissionManager(directLogSettings, new DirectSubmissionLogSink(logsApi, formatter, directLogSettings.BatchingOptions), formatter);
return new DirectLogSubmissionManager(directLogSettings, new DirectSubmissionLogSink(logsApi, formatter, directLogSettings.CreateBatchingSinkOptions()), formatter);
}

public async Task DisposeAsync()
Expand Down
Loading
Loading