Skip to content

Commit 1857f59

Browse files
Merge branch 'master' into dotnet10/UpdateToPreview
2 parents 64ca647 + ed3fd24 commit 1857f59

File tree

53 files changed

+524
-217
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

53 files changed

+524
-217
lines changed

tracer/build/_build/Build.Steps.cs

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -882,9 +882,9 @@ async Task DownloadWafVersion(string libddwafVersion = null, string uncompressFo
882882
.DependsOn(PublishNativeTracerUnix)
883883
.DependsOn(PublishNativeTracerOsx);
884884

885-
Target PublishFleetInstaller => _ => _
885+
Target BuildFleetInstaller => _ => _
886886
.Unlisted()
887-
.Description("Builds and publishes the fleet installer binary files as a zip")
887+
.Description("Builds and publishes the fleet installer binary files")
888888
.After(Clean, Restore, CompileManagedSrc)
889889
.Before(SignDlls)
890890
.OnlyWhenStatic(() => IsWin)
@@ -905,7 +905,17 @@ async Task DownloadWafVersion(string libddwafVersion = null, string uncompressFo
905905
.SetConfiguration(BuildConfiguration)
906906
.SetOutput(publishFolder)
907907
.CombineWith(tfms, (p, tfm) => p.SetFramework(tfm)));
908+
});
908909

910+
Target PublishFleetInstaller => _ => _
911+
.Unlisted()
912+
.Description("Publishes the fleet installer binary files as a zip")
913+
.DependsOn(BuildFleetInstaller)
914+
.After(SignDlls)
915+
.OnlyWhenStatic(() => IsWin)
916+
.Executes(() =>
917+
{
918+
var publishFolder = ArtifactsDirectory / "Datadog.FleetInstaller";
909919
CompressZip(publishFolder, ArtifactsDirectory / "fleet-installer.zip", fileMode: FileMode.Create);
910920
});
911921

tracer/src/Datadog.Trace/Configuration/TracerSettings.cs

Lines changed: 1 addition & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
using Datadog.Trace.ClrProfiler.ServerlessInstrumentation;
2121
using Datadog.Trace.Configuration.ConfigurationSources.Telemetry;
2222
using Datadog.Trace.Configuration.Telemetry;
23+
using Datadog.Trace.ContinuousProfiler;
2324
using Datadog.Trace.Logging;
2425
using Datadog.Trace.Logging.DirectSubmission;
2526
using Datadog.Trace.Processors;
@@ -139,28 +140,6 @@ internal TracerSettings(IConfigurationSource? source, IConfigurationTelemetry te
139140
AzureAppServiceMetadata = new ImmutableAzureAppServiceSettings(source, _telemetry);
140141
}
141142

142-
// With SSI, beyond ContinuousProfiler.ConfigurationKeys.ProfilingEnabled (true or auto vs false),
143-
// the profiler could be enabled via ContinuousProfiler.ConfigurationKeys.SsiDeployed:
144-
// - if it contains "profiler", the profiler is enabled after 30 seconds + at least 1 span
145-
// - if not, the profiler needed to be loaded by the CLR but no profiling will be done, only telemetry metrics will be sent
146-
// So, for the Tracer, the profiler should be seen as enabled if ContinuousProfiler.ConfigurationKeys.SsiDeployed has a value
147-
// (even without "profiler") so that spans will be sent to the profiler.
148-
ProfilingEnabledInternal = config
149-
.WithKeys(ContinuousProfiler.ConfigurationKeys.ProfilingEnabled)
150-
.GetAs(
151-
converter: x => x switch
152-
{
153-
"auto" => true,
154-
_ when x.ToBoolean() is { } boolean => boolean,
155-
_ => ParsingResult<bool>.Failure(),
156-
},
157-
getDefaultValue: () =>
158-
{
159-
var profilingSsiDeployed = config.WithKeys(ContinuousProfiler.ConfigurationKeys.SsiDeployed).AsString();
160-
return (profilingSsiDeployed != null);
161-
},
162-
validator: null);
163-
164143
var otelTags = config
165144
.WithKeys(ConfigurationKeys.OpenTelemetry.ResourceAttributes)
166145
.AsDictionaryResult(separator: '=');
@@ -890,13 +869,6 @@ static void RecordDisabledIntegrationsTelemetry(IntegrationSettingsCollection in
890869
/// <seealso cref="ConfigurationKeys.ApmTracingEnabled"/>
891870
internal bool ApmTracingEnabled => DynamicSettings.ApmTracingEnabled ?? _apmTracingEnabled;
892871

893-
/// <summary>
894-
/// Gets a value indicating whether profiling is enabled.
895-
/// Default is <c>false</c>.
896-
/// </summary>
897-
/// <seealso cref="ContinuousProfiler.ConfigurationKeys.ProfilingEnabled"/>
898-
internal bool ProfilingEnabledInternal { get; }
899-
900872
/// <summary>
901873
/// Gets the names of disabled integrations.
902874
/// </summary>

tracer/src/Datadog.Trace/ContinuousProfiler/ConfigurationKeys.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,5 +11,6 @@ internal static class ConfigurationKeys
1111
public const string CodeHotspotsEnabled = "DD_PROFILING_CODEHOTSPOTS_ENABLED";
1212
public const string EndpointProfilingEnabled = "DD_PROFILING_ENDPOINT_COLLECTION_ENABLED";
1313
public const string SsiDeployed = "DD_INJECTION_ENABLED";
14+
public const string ProfilerManagedActivationEnabled = "DD_PROFILER_MANAGED_ACTIVATION_ENABLED";
1415
}
1516
}

tracer/src/Datadog.Trace/ContinuousProfiler/Profiler.cs

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,24 +4,29 @@
44
// </copyright>
55

66
using System.Threading;
7+
using Datadog.Trace.Configuration;
8+
using Datadog.Trace.Telemetry;
79

810
namespace Datadog.Trace.ContinuousProfiler
911
{
1012
internal class Profiler
1113
{
1214
private static Profiler _instance;
1315

14-
internal Profiler(IContextTracker contextTracker, IProfilerStatus status)
16+
internal Profiler(IContextTracker contextTracker, IProfilerStatus status, ProfilerSettings settings)
1517
{
1618
ContextTracker = contextTracker;
1719
Status = status;
20+
Settings = settings;
1821
}
1922

2023
public static Profiler Instance
2124
{
2225
get { return LazyInitializer.EnsureInitialized(ref _instance, () => Create()); }
2326
}
2427

28+
public ProfilerSettings Settings { get; }
29+
2530
public IProfilerStatus Status { get; }
2631

2732
public IContextTracker ContextTracker { get; }
@@ -33,9 +38,10 @@ internal static void SetInstanceForTests(Profiler value)
3338

3439
private static Profiler Create()
3540
{
36-
var status = new ProfilerStatus();
41+
var settings = new ProfilerSettings(GlobalConfigurationSource.Instance, TelemetryFactory.Config);
42+
var status = new ProfilerStatus(settings);
3743
var contextTracker = new ContextTracker(status);
38-
return new Profiler(contextTracker, status);
44+
return new Profiler(contextTracker, status, settings);
3945
}
4046
}
4147
}
Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,106 @@
1+
// <copyright file="ProfilerSettings.cs" company="Datadog">
2+
// Unless explicitly stated otherwise all files in this repository are licensed under the Apache 2 License.
3+
// This product includes software developed at Datadog (https://www.datadoghq.com/). Copyright 2017 Datadog, Inc.
4+
// </copyright>
5+
6+
#nullable enable
7+
8+
using Datadog.Trace.Configuration;
9+
using Datadog.Trace.Configuration.ConfigurationSources.Telemetry;
10+
using Datadog.Trace.Configuration.Telemetry;
11+
12+
namespace Datadog.Trace.ContinuousProfiler;
13+
14+
internal class ProfilerSettings
15+
{
16+
public ProfilerSettings(IConfigurationSource config, IConfigurationTelemetry telemetry)
17+
: this(config, new EnvironmentConfigurationSource(), telemetry)
18+
{
19+
}
20+
21+
// Internal for testing only
22+
internal ProfilerSettings(IConfigurationSource config, IConfigurationSource envConfig, IConfigurationTelemetry telemetry)
23+
{
24+
if (!IsProfilingSupported)
25+
{
26+
ProfilerState = ProfilerState.Disabled;
27+
telemetry.Record(ConfigurationKeys.ProfilingEnabled, false, ConfigurationOrigins.Calculated);
28+
return;
29+
}
30+
31+
// If managed activation is enabled, we need to _just_ read from the environment variables,
32+
// as that's all that applies
33+
var envConfigBuilder = new ConfigurationBuilder(envConfig, telemetry);
34+
var managedActivationEnabled = envConfigBuilder
35+
.WithKeys(ConfigurationKeys.ProfilerManagedActivationEnabled)
36+
.AsBool(true);
37+
38+
// If we're using managed activation, we use the "full" config source set.
39+
// Otherwise we only read from the environment variables, to "match" the behavior of the profiler
40+
var profilingConfig = managedActivationEnabled
41+
? new ConfigurationBuilder(config, telemetry)
42+
: envConfigBuilder;
43+
44+
// With SSI, beyond ContinuousProfiler.ConfigurationKeys.ProfilingEnabled (true or auto vs false),
45+
// the profiler could be enabled via ContinuousProfiler.ConfigurationKeys.SsiDeployed. If it is non-empty, then the
46+
// profiler is "active", though won't begin profiling until 30 seconds have passed + at least 1 span has been generated.
47+
var profilingEnabled = profilingConfig
48+
.WithKeys(ConfigurationKeys.ProfilingEnabled)
49+
// We stick with strings here instead of using the `GetAs` method,
50+
// so that telemetry continues to store true/false/auto, instead of the enum values.
51+
.AsString(
52+
converter: x => x switch
53+
{
54+
"auto" => "auto",
55+
_ when x.ToBoolean() is { } boolean => boolean ? "true" : "false",
56+
_ => ParsingResult<string>.Failure(),
57+
},
58+
getDefaultValue: () =>
59+
{
60+
// If there's no explicit `DD_PROFILING_ENABLED` key,
61+
// we set the state based on the SSI value, only checking env vars (not the full stack)
62+
var isSsiDeployment = envConfigBuilder
63+
.WithKeys(ConfigurationKeys.SsiDeployed)
64+
.AsString();
65+
66+
return isSsiDeployment switch
67+
{
68+
{ Length: > 0 } => "auto",
69+
_ => "false",
70+
};
71+
},
72+
validator: null);
73+
74+
ProfilerState = profilingEnabled switch
75+
{
76+
"auto" => ProfilerState.Auto,
77+
"true" => ProfilerState.Enabled,
78+
_ => ProfilerState.Disabled,
79+
};
80+
}
81+
82+
// Internal for testing only
83+
internal ProfilerSettings(ProfilerState state)
84+
{
85+
ProfilerState = state;
86+
}
87+
88+
/// <summary>
89+
/// Gets a value indicating whether the profiler is supported on this platform at all.
90+
/// If it's not supported, we should not try to P/Invoke to it or do any context tracking.
91+
/// </summary>
92+
public static bool IsProfilingSupported
93+
{
94+
get
95+
{
96+
var fd = FrameworkDescription.Instance;
97+
return
98+
(fd.OSPlatform == OSPlatformName.Windows && fd.ProcessArchitecture is ProcessArchitecture.X64 or ProcessArchitecture.X86) ||
99+
(fd.OSPlatform == OSPlatformName.Linux && fd.ProcessArchitecture is ProcessArchitecture.X64);
100+
}
101+
}
102+
103+
public ProfilerState ProfilerState { get; }
104+
105+
public bool IsProfilerEnabled => ProfilerState != ProfilerState.Disabled;
106+
}
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
// <copyright file="ProfilerState.cs" company="Datadog">
2+
// Unless explicitly stated otherwise all files in this repository are licensed under the Apache 2 License.
3+
// This product includes software developed at Datadog (https://www.datadoghq.com/). Copyright 2017 Datadog, Inc.
4+
// </copyright>
5+
6+
#nullable enable
7+
8+
namespace Datadog.Trace.ContinuousProfiler;
9+
10+
internal enum ProfilerState
11+
{
12+
/// <summary>
13+
/// The profiler is explicitly disabled via configuration
14+
/// </summary>
15+
Disabled = 0,
16+
17+
/// <summary>
18+
/// The profiler is explicitly enabled via configuration
19+
/// </summary>
20+
Enabled = 1,
21+
22+
/// <summary>
23+
/// The profiler is in "auto" mode; i.e. will start after a delay and if traces are created
24+
/// </summary>
25+
Auto = 2,
26+
}

tracer/src/Datadog.Trace/ContinuousProfiler/ProfilerStatus.cs

Lines changed: 10 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -5,48 +5,30 @@
55

66
using System;
77
using System.Runtime.InteropServices;
8-
using Datadog.Trace.ExtensionMethods;
98
using Datadog.Trace.Logging;
10-
using Datadog.Trace.Util;
119

1210
namespace Datadog.Trace.ContinuousProfiler
1311
{
1412
internal class ProfilerStatus : IProfilerStatus
1513
{
1614
private static readonly IDatadogLogger Log = DatadogLogging.GetLoggerFor(typeof(ProfilerStatus));
1715

18-
private readonly bool _isProfilingEnabled;
16+
private readonly ProfilerState _profilerState;
1917
private readonly object _lockObj;
2018
private bool _isInitialized;
2119
private IntPtr _engineStatusPtr;
2220

23-
public ProfilerStatus()
21+
public ProfilerStatus(ProfilerSettings settings)
2422
{
25-
var fd = FrameworkDescription.Instance;
26-
var isSupported =
27-
(fd.OSPlatform == OSPlatformName.Windows && (fd.ProcessArchitecture == ProcessArchitecture.X64 || fd.ProcessArchitecture == ProcessArchitecture.X86)) ||
28-
(fd.OSPlatform == OSPlatformName.Linux && fd.ProcessArchitecture == ProcessArchitecture.X64);
29-
30-
_isProfilingEnabled = false;
31-
32-
if (isSupported)
23+
_profilerState = settings.ProfilerState;
24+
var state = _profilerState switch
3325
{
34-
var manualDeployement = EnvironmentHelpers.GetEnvironmentVariable(ConfigurationKeys.ProfilingEnabled);
35-
if (manualDeployement != null)
36-
{
37-
// it is possible that SSI installation script is setting the environment variable to "auto" to enable the profiler
38-
// instead of "true" to avoid starting the profiler immediately after the installation
39-
_isProfilingEnabled = manualDeployement.ToBoolean() ?? (manualDeployement == "auto");
40-
}
41-
else
42-
{
43-
// the profiler is declared "enabled" just if the SSI environment variable exists to be sure that telemetry metrics
44-
// will contain the right status (i.e. we need the tracer to send the spans even if the profiler is not started yet)
45-
_isProfilingEnabled = (EnvironmentHelpers.GetEnvironmentVariable(ConfigurationKeys.SsiDeployed) != null);
46-
}
47-
}
26+
ProfilerState.Enabled => "enabled",
27+
ProfilerState.Auto => "auto",
28+
_ => "disabled"
29+
};
4830

49-
Log.Information("Continuous Profiler is {IsEnabled}.", _isProfilingEnabled ? "enabled" : "disabled");
31+
Log.Information("Continuous Profiler mode = {ProfilerState}", state);
5032
_lockObj = new();
5133
_isInitialized = false;
5234
}
@@ -55,7 +37,7 @@ public bool IsProfilerReady
5537
{
5638
get
5739
{
58-
if (!_isProfilingEnabled)
40+
if (_profilerState == ProfilerState.Disabled)
5941
{
6042
return false;
6143
}

tracer/src/Datadog.Trace/DataStreamsMonitoring/Aggregation/DataStreamsMessagePackFormatter.cs

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
using System.Collections.Generic;
1010
using System.IO;
1111
using Datadog.Trace.Configuration;
12+
using Datadog.Trace.ContinuousProfiler;
1213
using Datadog.Trace.Vendors.Datadog.Sketches;
1314
using Datadog.Trace.Vendors.MessagePack;
1415

@@ -51,7 +52,7 @@ internal class DataStreamsMessagePackFormatter
5152
private readonly byte[] _productMaskBytes = StringEncoding.UTF8.GetBytes("ProductMask");
5253
private readonly byte[] _isInDefaultStateBytes = StringEncoding.UTF8.GetBytes("IsInDefaultState");
5354

54-
public DataStreamsMessagePackFormatter(TracerSettings tracerSettings, string defaultServiceName)
55+
public DataStreamsMessagePackFormatter(TracerSettings tracerSettings, ProfilerSettings profilerSettings, string defaultServiceName)
5556
{
5657
var env = tracerSettings.Environment;
5758
// .NET tracer doesn't yet support primary tag
@@ -60,7 +61,7 @@ public DataStreamsMessagePackFormatter(TracerSettings tracerSettings, string def
6061
? []
6162
: StringEncoding.UTF8.GetBytes(env);
6263
_serviceValueBytes = StringEncoding.UTF8.GetBytes(defaultServiceName);
63-
_productMask = GetProductsMask(tracerSettings);
64+
_productMask = GetProductsMask(tracerSettings, profilerSettings);
6465
_isInDefaultState = tracerSettings.IsDataStreamsMonitoringInDefaultState;
6566
}
6667

@@ -75,15 +76,15 @@ private enum Products : long
7576
Profiling = 1 << 3, // 00001000
7677
}
7778

78-
private static long GetProductsMask(TracerSettings tracerSettings)
79+
private static long GetProductsMask(TracerSettings tracerSettings, ProfilerSettings profilerSettings)
7980
{
8081
var productsMask = (long)Products.Apm;
8182
if (tracerSettings.IsDataStreamsMonitoringEnabled)
8283
{
8384
productsMask |= (long)Products.Dsm;
8485
}
8586

86-
if (tracerSettings.ProfilingEnabledInternal)
87+
if (profilerSettings.IsProfilerEnabled)
8788
{
8889
productsMask |= (long)Products.Profiling;
8990
}

tracer/src/Datadog.Trace/DataStreamsMonitoring/DataStreamsManager.cs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
using System.Threading.Tasks;
1111
using Datadog.Trace.Agent.DiscoveryService;
1212
using Datadog.Trace.Configuration;
13+
using Datadog.Trace.ContinuousProfiler;
1314
using Datadog.Trace.DataStreamsMonitoring.Aggregation;
1415
using Datadog.Trace.DataStreamsMonitoring.Hashes;
1516
using Datadog.Trace.Headers;
@@ -50,11 +51,12 @@ public DataStreamsManager(
5051

5152
public static DataStreamsManager Create(
5253
TracerSettings settings,
54+
ProfilerSettings profilerSettings,
5355
IDiscoveryService discoveryService,
5456
string defaultServiceName)
5557
{
5658
var writer = settings.IsDataStreamsMonitoringEnabled
57-
? DataStreamsWriter.Create(settings, discoveryService, defaultServiceName)
59+
? DataStreamsWriter.Create(settings, profilerSettings, discoveryService, defaultServiceName)
5860
: null;
5961

6062
return new DataStreamsManager(settings.Environment, defaultServiceName, writer, settings.IsDataStreamsMonitoringInDefaultState);

0 commit comments

Comments
 (0)