Skip to content
Open
Show file tree
Hide file tree
Changes from 8 commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
21f579b
1) Remove `[EventSourceAutoGenerate]`, we rely on just [EventSource] …
EgorBo Oct 29, 2025
c4cf897
Merge branch 'main' into ES-cleanup
EgorBo Oct 29, 2025
f5dbdd2
fix build
EgorBo Oct 30, 2025
c702892
Merge branch 'ES-cleanup' of github.com:EgorBo/runtime-1 into ES-cleanup
EgorBo Oct 30, 2025
62433fe
cleanup
EgorBo Oct 30, 2025
637e6c1
Merge branch 'main' of https://github.com/dotnet/runtime into ES-cleanup
EgorBo Nov 4, 2025
4ccefa9
Address feedback
EgorBo Nov 4, 2025
20d7953
Introduce a warning
EgorBo Nov 4, 2025
2f30603
feedback
EgorBo Nov 4, 2025
e97c786
Merge branch 'main' of https://github.com/dotnet/runtime into ES-cleanup
EgorBo Nov 4, 2025
67fbf31
Merge branch 'main' of https://github.com/dotnet/runtime into ES-cleanup
EgorBo Nov 8, 2025
0e83207
Address feedback
EgorBo Nov 8, 2025
e072e4b
Add a comment
EgorBo Nov 9, 2025
c5b09c7
cleanup
EgorBo Nov 9, 2025
01e1199
Feedback
EgorBo Nov 9, 2025
4f2b250
Merge branch 'main' of https://github.com/dotnet/runtime into ES-cleanup
EgorBo Nov 9, 2025
6e8f918
feedback
EgorBo Nov 9, 2025
4255dc8
Apply suggestions from code review
jkotas Nov 9, 2025
91c8465
Apply suggestions from code review
jkotas Nov 9, 2025
28dee99
Apply suggestions from code review
jkotas Nov 9, 2025
b2fd587
Apply suggestions from code review
jkotas Nov 9, 2025
cbf9825
Update src/libraries/System.Private.CoreLib/src/System/Diagnostics/Tr…
jkotas Nov 9, 2025
b544605
Update LoggingEventSource.cs
EgorBo Nov 9, 2025
c31708e
Update src/libraries/System.Diagnostics.Tracing/ref/System.Diagnostic…
jkotas Nov 10, 2025
e85c9f7
Update System.Diagnostics.Tracing.cs
EgorBo Nov 10, 2025
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
4 changes: 4 additions & 0 deletions Directory.Build.props
Original file line number Diff line number Diff line change
Expand Up @@ -319,6 +319,8 @@
<NoWarn>$(NoWarn);CS8625</NoWarn>
<!-- We dont need to add null annotation within the ref for explicit interface methods. -->
<NoWarn>$(NoWarn);CS8617</NoWarn>
<!-- don't warn about explicit ctors in classes with [EventSource] -->
<NoWarn>$(NoWarn);ESGEN001</NoWarn>
<!-- No symbols are produced for ref assemblies, but some parts of the SDK still expect pdbs, so we explicitly tell it there are none. -->
<!-- Must be set after importing Arcade to override its defaults. -->
<DebugType>none</DebugType>
Expand Down Expand Up @@ -360,6 +362,8 @@
<NoWarn>$(NoWarn);SYSLIB0011;SYSLIB0050;SYSLIB0051</NoWarn>
<!-- don't warn about unnecessary trim warning suppressions. can be removed with preview 6. -->
<NoWarn>$(NoWarn);IL2121</NoWarn>
<!-- don't warn about explicit ctors in classes with [EventSource] -->
<NoWarn>$(NoWarn);ESGEN001</NoWarn>
<!-- allow nullable annotated files to be incorporated into tests without warning -->
<Nullable Condition="'$(Nullable)' == '' and '$(Language)' == 'C#'">annotations</Nullable>
</PropertyGroup>
Expand Down
11 changes: 11 additions & 0 deletions eng/generators.targets
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,12 @@
'$(DisableImplicitFrameworkReferences)' == 'true' and
'@(ProjectReference->AnyHaveMetadataValue('Filename', 'System.Runtime.InteropServices'))' == 'true'
)" />

<EnabledGenerators Include="EventSourceGenerator"
Condition="'$(IsSourceProject)' == 'true' and
'$(MSBuildProjectExtension)' == '.csproj' and
'$(DisableImplicitFrameworkReferences)' == 'true'
" />
</ItemGroup>

<ItemGroup Condition="'@(EnabledGenerators)' != '' and
Expand Down Expand Up @@ -70,6 +76,11 @@
OutputItemType="Analyzer"
SetConfiguration="Configuration=$(LibrariesConfiguration)"
Condition="@(EnabledGenerators->AnyHaveMetadataValue('Identity', 'ComInterfaceGenerator'))" />
<ProjectReference Include="$(LibrariesProjectRoot)System.Private.CoreLib\gen\EventSourceGenerator.csproj"
ReferenceOutputAssembly="false"
OutputItemType="Analyzer"
SetConfiguration="Configuration=$(LibrariesConfiguration)"
Condition="@(EnabledGenerators->AnyHaveMetadataValue('Identity', 'EventSourceGenerator'))" />
</ItemGroup>

<Target Name="ConfigureGenerators"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,8 @@
namespace ILCompiler.DependencyAnalysisFramework
{
[EventSource(Name = "Microsoft-ILCompiler-Graph-Perf")]
public class PerfEventSource : EventSource
public partial class PerfEventSource : EventSource
{
private PerfEventSource() { }

public static PerfEventSource Log = new PerfEventSource();

public struct StartStopEvents : IDisposable
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,8 @@
namespace ILCompiler
{
[EventSource(Name = "Microsoft-ILCompiler-Perf")]
public class PerfEventSource : EventSource
public partial class PerfEventSource : EventSource
{
private PerfEventSource() { }

public static PerfEventSource Log = new PerfEventSource();

public struct StartStopEvents : IDisposable
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,11 @@ public static class Keywords

private readonly List<WeakReference<ServiceProvider>> _providers = new();

#pragma warning disable ESGEN001 // EventSource classes should not declare constructors.
private DependencyInjectionEventSource() : base(EventSourceSettings.EtwSelfDescribingEventFormat)
{
}
#pragma warning restore ESGEN001 // EventSource classes should not declare constructors.

// There is a risk that each ServiceProviderBuilt call only finds one entry to remove, and the next call will clean the list again and spend O(n) time on that.
// So instead of tying the cleaning to the resizing, it might be better to have a separate counter.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -126,9 +126,11 @@ public static class Keywords
private static readonly char[] s_semicolon = new[] { ';' };
private static readonly char[] s_colon = new[] { ':' };

#pragma warning disable ESGEN001 // EventSource classes should not declare constructors.
private LoggingEventSource() : base(EventSourceSettings.EtwSelfDescribingEventFormat)
{
}
#pragma warning restore ESGEN001 // EventSource classes should not declare constructors.

/// <summary>
/// FormattedMessage() is called when ILogger.Log() is called. and the FormattedMessage keyword is active
Expand Down
1 change: 1 addition & 0 deletions src/libraries/NetCoreAppLibrary.props
Original file line number Diff line number Diff line change
Expand Up @@ -181,6 +181,7 @@
<!-- List .NETCoreApp shared framework generator project names below. -->
<NetCoreAppLibraryGenerator>
ComInterfaceGenerator;
EventSourceGenerator;
LibraryImportGenerator;
JSImportGenerator;
Microsoft.Interop.SourceGeneration;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,15 +19,13 @@ namespace System.Collections.Concurrent
Name = "System.Collections.Concurrent.ConcurrentCollectionsEventSource",
Guid = "35167F8E-49B2-4b96-AB86-435B59336B5E"
)]
internal sealed class CDSCollectionETWBCLProvider : EventSource
internal sealed partial class CDSCollectionETWBCLProvider : EventSource
{
/// <summary>
/// Defines the singleton instance for the collection ETW provider.
/// The collection provider GUID is {35167F8E-49B2-4b96-AB86-435B59336B5E}.
/// </summary>
public static readonly CDSCollectionETWBCLProvider Log = new CDSCollectionETWBCLProvider();
/// <summary>Prevent external instantiation. All logging should go through the Log instance.</summary>
private CDSCollectionETWBCLProvider() { }

/// <summary>Enabled for all keywords.</summary>
private const EventKeywords ALL_KEYWORDS = (EventKeywords)(-1);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
namespace System.Data
{
[EventSource(Name = "System.Data.DataCommonEventSource")]
internal sealed class DataCommonEventSource : EventSource
internal sealed partial class DataCommonEventSource : EventSource
{
internal static readonly DataCommonEventSource Log = new DataCommonEventSource();
private static long s_nextScopeId;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
namespace System.Data
{
[EventSource(Name = "System.Data.DataCommonEventSource")]
internal sealed class DataCommonEventSource : EventSource
internal sealed partial class DataCommonEventSource : EventSource
{
internal static readonly DataCommonEventSource Log = new DataCommonEventSource();
private const int TraceEventId = 1;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -404,12 +404,14 @@ protected override void OnEventCommand(EventCommandEventArgs command)
}

#region private
#pragma warning disable ESGEN001 // EventSource classes should not declare constructors.
private DiagnosticSourceEventSource()
// This constructor uses EventSourceSettings which is only available on V4.6 and above
// Use the EventSourceSettings to turn on support for complex types, if available (v4.6 and above).
: base(DiagnosticSourceEventSourceName, EventSourceSettings.EtwSelfDescribingEventFormat)
{
}
#pragma warning restore ESGEN001 // EventSource classes should not declare constructors.

// trivial helper to allow you to join two strings the first of which can be null.
private static string NewLineSeparate(string? str1, string str2)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,11 +48,9 @@ namespace System.Diagnostics.Metrics
/// not counting the special zero bucket. The default value is 160.
/// o reportDeltas - If true, the histogram will report deltas instead of whole accumulated values. The default value is false.
/// </summary>
[EventSource(Name = MetricsEventSourceName)]
internal sealed class MetricsEventSource : EventSource
[EventSource(Name = "System.Diagnostics.Metrics")]
internal sealed partial class MetricsEventSource : EventSource
{
private const string MetricsEventSourceName = "System.Diagnostics.Metrics";

public static readonly MetricsEventSource Log = new();

// Although this API isn't public, it is invoked via reflection from System.Private.CoreLib and needs the same back-compat
Expand Down Expand Up @@ -98,11 +96,6 @@ private CommandHandler Handler
}
}

private MetricsEventSource()
: base(MetricsEventSourceName, EventSourceSettings.EtwManifestEventFormat)
{
}

/// <summary>
/// Used to send ad-hoc diagnostics to humans.
/// </summary>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,9 @@ protected EventSource(System.Diagnostics.Tracing.EventSourceSettings settings, p
public EventSource(string eventSourceName) { }
public EventSource(string eventSourceName, System.Diagnostics.Tracing.EventSourceSettings config) { }
public EventSource(string eventSourceName, System.Diagnostics.Tracing.EventSourceSettings config, params string[]? traits) { }
public EventSource(string eventSourceName, Guid eventSourceGuid) { }
public EventSource(string eventSourceName, Guid eventSourceGuid, System.Diagnostics.Tracing.EventSourceSettings settings, params string[]? traits) { }
Copy link
Member

Choose a reason for hiding this comment

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

The approved API shape (and the implementation) has default null value for traits, but this has params and no null value. Which one is correct?

Do we need to add a test to validate that the new constructor works as expected?

Copy link
Member Author

Choose a reason for hiding this comment

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

@jkotas sorry, I am not following - what that test is expected to cover?

PS: added = null and removed params to match exactly the approved shape. Presumably, this particular API is mostly for the SG.

Copy link
Member Author

@EgorBo EgorBo Nov 10, 2025

Choose a reason for hiding this comment

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

Although, isn't params string[] x and string[] x = null are the same thing? 🤔
I guess adding params (but not removing) shouldn't be a breaking change. However, feels like collections literals effectively made params redundant

Copy link
Member

Choose a reason for hiding this comment

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

Although, isn't params string[] x and string[] x = null are the same thing?

No, if you don't pass an argument for the latter, x will be null, but if you don't pass an argument for the former, x will be Array.Empty<string>().

Copy link
Member Author

Choose a reason for hiding this comment

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

Ah, indeed

Copy link
Member

Choose a reason for hiding this comment

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

what that test is expected to cover?

The tests for the existing APIs are in https://github.com/dotnet/runtime/blob/5bceb8184fcde55143d2102a65c72bd6233e950b/src/libraries/System.Diagnostics.Tracing/tests/BasicEventSourceTest/TestsTraits.cs and related files.

Add some tests like that for the new APIs?


public System.Exception? ConstructionException { get { throw null; } }
public static System.Guid CurrentThreadActivityId { get { throw null; } }
public System.Guid Guid { get { throw null; } }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,8 @@ public async Task SetCurrentActivityIdAfterEventDoesNotFlowAsync()
[EventSource(Name = "ActivityEventSource")]
class ActivityEventSource : EventSource
{
public ActivityEventSource() { }

[Event(1)]
public void ExampleStart() => WriteEvent(1);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,15 +22,13 @@ namespace System.Linq.Parallel
[EventSource(
Name = "System.Linq.Parallel.PlinqEventSource",
Guid = "159eeeec-4a14-4418-a8fe-faabcd987887")]
internal sealed class PlinqEtwProvider : EventSource
internal sealed partial class PlinqEtwProvider : EventSource
{
/// <summary>
/// Defines the singleton instance for the PLINQ ETW provider.
/// The PLINQ Event provider GUID is {159eeeec-4a14-4418-a8fe-faabcd987887}.
/// </summary>
internal static readonly PlinqEtwProvider Log = new PlinqEtwProvider();
/// <summary>Prevent external instantiation. All logging should go through the Log instance.</summary>
private PlinqEtwProvider() { }

/// <summary>Cached id for the default scheduler.</summary>
/// <remarks>If PLINQ ever supports other schedulers, that information will need to be passed into the query events.</remarks>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,8 @@

namespace System.Net
{
[EventSource(Name = NetEventSourceName)]
[EventSource(Name = "Private.InternalDiagnostics.System.Net.Http.WinHttpHandler")]
internal sealed partial class NetEventSource
{
private const string NetEventSourceName = "Private.InternalDiagnostics.System.Net.Http.WinHttpHandler";

public NetEventSource() : base(NetEventSourceName, EventSourceSettings.EtwManifestEventFormat) { }
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,16 +9,9 @@

namespace System.Net.Http
{
[EventSource(Name = HttpTelemetryName)]
[EventSource(Name = "System.Net.Http")]
internal sealed partial class HttpTelemetry : EventSource
{
private const string HttpTelemetryName = "System.Net.Http";

public HttpTelemetry()
: base(HttpTelemetryName, EventSourceSettings.EtwManifestEventFormat)
{
}

public static readonly HttpTelemetry Log = new HttpTelemetry();

public static class Keywords
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,9 @@

namespace System.Net
{
[EventSource(Name = NetEventSourceName)]
[EventSource(Name = "Private.InternalDiagnostics.System.Net.Http")]
internal sealed partial class NetEventSource
{
private const string NetEventSourceName = "Private.InternalDiagnostics.System.Net.Http";

public NetEventSource() : base(NetEventSourceName, EventSourceSettings.EtwManifestEventFormat) { }

private const int UriBaseAddressId = NextAvailableEventId;
private const int ContentNullId = UriBaseAddressId + 1;
private const int HeadersInvalidValueId = ContentNullId + 1;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,8 @@

namespace System.Net
{
[EventSource(Name = NetEventSourceName)]
[EventSource(Name = "Private.InternalDiagnostics.System.Net.HttpListener")]
internal sealed partial class NetEventSource
{
private const string NetEventSourceName = "Private.InternalDiagnostics.System.Net.HttpListener";

public NetEventSource() : base(NetEventSourceName, EventSourceSettings.EtwManifestEventFormat) { }
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,8 @@

namespace System.Net
{
[EventSource(Name = NetEventSourceName)]
[EventSource(Name = "Private.InternalDiagnostics.System.Net.Mail")]
internal sealed partial class NetEventSource
{
private const string NetEventSourceName = "Private.InternalDiagnostics.System.Net.Mail";

public NetEventSource() : base(NetEventSourceName, EventSourceSettings.EtwManifestEventFormat) { }
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,16 +9,9 @@

namespace System.Net
{
[EventSource(Name = NameResolutionTelemetryName)]
internal sealed class NameResolutionTelemetry : EventSource
[EventSource(Name = "System.Net.NameResolution")]
internal sealed partial class NameResolutionTelemetry : EventSource
{
private const string NameResolutionTelemetryName = "System.Net.NameResolution";

public NameResolutionTelemetry()
: base(NameResolutionTelemetryName, EventSourceSettings.EtwManifestEventFormat)
{
}

public static readonly NameResolutionTelemetry Log = new NameResolutionTelemetry();

private const int ResolutionStartEventId = 1;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,8 @@

namespace System.Net
{
[EventSource(Name = NetEventSourceName)]
[EventSource(Name = "Private.InternalDiagnostics.System.Net.NameResolution")]
internal sealed partial class NetEventSource
{
private const string NetEventSourceName = "Private.InternalDiagnostics.System.Net.NameResolution";

public NetEventSource() : base(NetEventSourceName, EventSourceSettings.EtwManifestEventFormat) { }
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,9 @@

namespace System.Net
{
[EventSource(Name = NetEventSourceName)]
internal sealed class NetEventSource : EventSource
[EventSource(Name = "Private.InternalDiagnostics.System.Net.NetworkInformation")]
internal sealed partial class NetEventSource : EventSource
{
private const string NetEventSourceName = "Private.InternalDiagnostics.System.Net.NetworkInformation";

public NetEventSource() : base(NetEventSourceName, EventSourceSettings.EtwManifestEventFormat) { }

public static readonly NetEventSource Log = new NetEventSource();

private const int ErrorEventId = 2;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,8 @@

namespace System.Net
{
[EventSource(Name = NetEventSourceName)]
[EventSource(Name = "Private.InternalDiagnostics.System.Net.Primitives")]
internal sealed partial class NetEventSource
{
private const string NetEventSourceName = "Private.InternalDiagnostics.System.Net.Primitives";

public NetEventSource() : base(NetEventSourceName, EventSourceSettings.EtwManifestEventFormat) { }
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,9 @@

namespace System.Net
{
[EventSource(Name = NetEventSourceName)]
[EventSource(Name = "Private.InternalDiagnostics.System.Net.Quic")]
internal sealed partial class NetEventSource
{
private const string NetEventSourceName = "Private.InternalDiagnostics.System.Net.Quic";

public NetEventSource() : base(NetEventSourceName, EventSourceSettings.EtwManifestEventFormat) { }

static partial void AdditionalCustomizedToString(object value, ref string? result)
{
if (value is MsQuicSafeHandle safeHandle)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,8 @@

namespace System.Net
{
[EventSource(Name = NetEventSourceName)]
[EventSource(Name = "Private.InternalDiagnostics.System.Net.Requests")]
internal sealed partial class NetEventSource
{
private const string NetEventSourceName = "Private.InternalDiagnostics.System.Net.Requests";

public NetEventSource() : base(NetEventSourceName, EventSourceSettings.EtwManifestEventFormat) { }
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,9 @@

namespace System.Net
{
[EventSource(Name = NetEventSourceName)]
[EventSource(Name = "Private.InternalDiagnostics.System.Net.Security")]
internal sealed partial class NetEventSource
{
private const string NetEventSourceName = "Private.InternalDiagnostics.System.Net.Security";

public NetEventSource() : base(NetEventSourceName, EventSourceSettings.EtwManifestEventFormat) { }

#if WINDOWS
// More events are defined in NetEventSource.Security.Windows.cs
private const int LocatingPrivateKeyId = OperationReturnedSomethingId + 1;
Expand Down
Loading
Loading