Skip to content

Commit

Permalink
[release/9.0] [DiagnosticSource] Add version event to EventSources us…
Browse files Browse the repository at this point in the history
…ed for out-of-proc monitoring (#107748)

* Add a version event to DS event sources.

* Tweaks.

* Code review.

* Code review, bug fixes, and tests.

* Fix GenerateFileFromTemplate and make it work with incremental build

* Test fixes and code review.

* Apply suggestions from code review

---------

Co-authored-by: Mikel Blanchard <mblanchard@macrosssoftware.com>
Co-authored-by: Eric StJohn <ericstj@microsoft.com>
Co-authored-by: Tarek Mahmoud Sayed <10833894+tarekgh@users.noreply.github.com>
  • Loading branch information
4 people authored Sep 12, 2024
1 parent db5dcbf commit a1f25d8
Show file tree
Hide file tree
Showing 6 changed files with 139 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,10 @@ System.Diagnostics.DiagnosticSource</PackageDescription>

<None Include="DiagnosticSourceUsersGuide.md" />
<None Include="ActivityUserGuide.md" />
<None Include="FlatRequestId.md" />
<None Include="HierarchicalRequestId.md" />
<None Include="HttpCorrelationProtocol.md" />
<None Include="ThisAssembly.cs.in" />
</ItemGroup>

<ItemGroup Condition="'$(TargetFrameworkIdentifier)' == '.NETCoreApp'">
Expand Down Expand Up @@ -154,4 +158,23 @@ System.Diagnostics.DiagnosticSource</PackageDescription>
<PackageReference Include="System.Runtime.CompilerServices.Unsafe" Version="$(SystemRuntimeCompilerServicesUnsafeVersion)" />
</ItemGroup>

<ItemGroup>
<PackageReference Include="Microsoft.DotNet.Build.Tasks.Templating" Version="$(MicrosoftDotNetBuildTasksTemplatingVersion)" PrivateAssets="All" IsImplicitlyDefined="true" />
</ItemGroup>

<Target Name="_GenerateThisAssemblyInfo"
BeforeTargets="CoreCompile"
Inputs="ThisAssembly.cs.in"
Outputs="$(IntermediateOutputPath)ThisAssembly.cs">
<GenerateFileFromTemplate
TemplateFile="ThisAssembly.cs.in"
Properties="AssemblyVersion=$(AssemblyVersion);AssemblyFileVersion=$(FileVersion)"
OutputPath="$(IntermediateOutputPath)ThisAssembly.cs" />

<ItemGroup>
<Compile Include="$(IntermediateOutputPath)ThisAssembly.cs" />
<FileWrites Include="$(IntermediateOutputPath)ThisAssembly.cs" />
</ItemGroup>
</Target>

</Project>
Original file line number Diff line number Diff line change
Expand Up @@ -349,12 +349,29 @@ public void ActivityStart(string SourceName, string ActivityName, IEnumerable<Ke
public void ActivityStop(string SourceName, string ActivityName, IEnumerable<KeyValuePair<string, string?>> Arguments) =>
WriteEvent(12, SourceName, ActivityName, Arguments);

/// <summary>
/// Used to send version information.
/// </summary>
[Event(13, Keywords = Keywords.Messages)]
public void Version(int Major, int Minor, int Patch)
{
WriteEvent(13, Major, Minor, Patch);
}

/// <summary>
/// Called when the EventSource gets a command from a EventListener or ETW.
/// </summary>
[NonEvent]
protected override void OnEventCommand(EventCommandEventArgs command)
{
if (command.Command == EventCommand.Enable)
{
Version(
ThisAssembly.AssemblyFileVersion.Major,
ThisAssembly.AssemblyFileVersion.Minor,
ThisAssembly.AssemblyFileVersion.Build);
}

// On every command (which the debugger can force by turning on this EventSource with ETW)
// call a function that the debugger can hook to do an arbitrary func evaluation.
BreakPointWithDebuggerFuncEval();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -277,12 +277,29 @@ public void MultipleSessionsConfiguredIncorrectlyError(string clientId, string e
WriteEvent(17, clientId, expectedMaxHistograms, actualMaxHistograms, expectedMaxTimeSeries, actualMaxTimeSeries, expectedRefreshInterval, actualRefreshInterval);
}

/// <summary>
/// Used to send version information.
/// </summary>
[Event(18, Keywords = Keywords.Messages)]
public void Version(int Major, int Minor, int Patch)
{
WriteEvent(18, Major, Minor, Patch);
}

/// <summary>
/// Called when the EventSource gets a command from a EventListener or ETW.
/// </summary>
[NonEvent]
protected override void OnEventCommand(EventCommandEventArgs command)
{
if (command.Command == EventCommand.Enable)
{
Version(
ThisAssembly.AssemblyFileVersion.Major,
ThisAssembly.AssemblyFileVersion.Minor,
ThisAssembly.AssemblyFileVersion.Build);
}

lock (this)
{
Handler.OnEventCommand(command);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

namespace System.Diagnostics;

internal static class ThisAssembly
{
private const string BuildAssemblyFileVersion = "${AssemblyFileVersion}";

public static Version AssemblyFileVersion { get; } = new(BuildAssemblyFileVersion);
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

using System.Collections.Generic;
using System.Diagnostics.Tracing;
using System.Reflection;
using System.Text;
using System.Threading;
using Microsoft.DotNet.RemoteExecutor;
Expand Down Expand Up @@ -959,6 +960,42 @@ public void TestMessages()
}).Dispose();
}

// Tests that version event from DiagnosticSourceEventSource is fired.
[ConditionalFact(typeof(RemoteExecutor), nameof(RemoteExecutor.IsSupported))]
public void TestVersion()
{
RemoteExecutor.Invoke(static () =>
{
Activity a = new Activity("test"); // we need this to ensure DiagnosticSourceEventSource.Logger creation.
using (var eventSourceListener = new TestDiagnosticSourceEventListener())
{
Assert.Equal(0, eventSourceListener.EventCount);
Version? version = null;
eventSourceListener.OtherEventWritten += delegate (EventWrittenEventArgs evnt)
{
if (evnt.EventName == "Version")
{
version = new(
(int)evnt.Payload[0],
(int)evnt.Payload[1],
(int)evnt.Payload[2]);
}
};
eventSourceListener.Enable("");
Assert.Equal(0, eventSourceListener.EventCount);
Assert.NotNull(version);
Assert.Equal(
new Version(typeof(Activity).Assembly.GetCustomAttribute<AssemblyFileVersionAttribute>()?.Version ?? "0.0.0").ToString(3),
version.ToString());
}
}).Dispose();
}

/// <summary>
/// Tests the feature to send the messages as EventSource Activities.
/// </summary>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,35 @@ public void GetInstanceMethodIsReflectable()
Assert.True(o is EventSource, "Expected object returned from MetricsEventSource.GetInstance() to be assignable to EventSource");
}

// Tests that version event from MetricsEventSource is fired.
[ConditionalFact(typeof(RemoteExecutor), nameof(RemoteExecutor.IsSupported))]
public void TestVersion()
{
RemoteExecutor.Invoke(static () =>
{
using var meter = new Meter("test"); // we need this to ensure MetricsEventSource.Logger creation.
using (var eventSourceListener = new MetricsEventListener(NullTestOutputHelper.Instance, EventKeywords.All, 60))
{
var versionEvents = eventSourceListener.Events.Where(e => e.EventName == "Version");
Assert.Single(versionEvents);
var versionEvent = versionEvents.First();
var version = new Version(
(int)versionEvent.Payload[0],
(int)versionEvent.Payload[1],
(int)versionEvent.Payload[2]);
Assert.NotNull(version);
Assert.Equal(
new Version(typeof(Meter).Assembly.GetCustomAttribute<AssemblyFileVersionAttribute>()?.Version ?? "0.0.0").ToString(3),
version.ToString());
}
}).Dispose();
}

[ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsNotBrowser))]
[OuterLoop("Slow and has lots of console spew")]
public void MultipleListeners_DifferentCounters()
Expand Down Expand Up @@ -2102,7 +2131,11 @@ public override void Dispose()
protected override void OnEventWritten(EventWrittenEventArgs eventData)
{
string sessionId = eventData.Payload[0].ToString();
if (eventData.EventName != "MultipleSessionsNotSupportedError" && eventData.EventName != "MultipleSessionsConfiguredIncorrectlyError" && sessionId != "" && sessionId != _sessionId)
if (eventData.EventName != "MultipleSessionsNotSupportedError"
&& eventData.EventName != "MultipleSessionsConfiguredIncorrectlyError"
&& eventData.EventName != "Version"
&& sessionId != ""
&& sessionId != _sessionId)
{
return;
}
Expand Down

0 comments on commit a1f25d8

Please sign in to comment.