Skip to content

Commit

Permalink
Add Telemetry support. Bump to MSbuild 17+ (#15)
Browse files Browse the repository at this point in the history
* Add Telemetry support. Bump to MSbuild 17+

IBuildEngine5 added support for sending Telemetry data https://learn.microsoft.com/en-us/dotnet/api/microsoft.build.framework.ibuildengine5.logtelemetry?view=msbuild-17-netcore. We need to expose a helper method in the AsyncTask so that tasks using it can log telemetry.

We have to use the same pattern as we do for other logging event, the data should be queue'd and then disapatched on the main UI thread so that we can prevent locking.
  • Loading branch information
dellis1972 authored Jun 4, 2024
1 parent 166fbe8 commit db4ce14
Show file tree
Hide file tree
Showing 6 changed files with 47 additions and 13 deletions.
5 changes: 3 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,13 +23,14 @@ If you're creating an inline task that wants to inherit from AsyncTask, use the
as a template:

```xml
<UsingTask TaskName="MyAsyncTask" TaskFactory="CodeTaskFactory" AssemblyFile="$(MSBuildToolsPath)\Microsoft.Build.Tasks.Core.dll">
<UsingTask TaskName="MyAsyncTask" TaskFactory="RoslynCodeTaskFactory" AssemblyFile="$(MSBuildToolsPath)\Microsoft.Build.Tasks.Core.dll">
<ParameterGroup>
<!-- TODO: your task parameters -->
</ParameterGroup>
<Task>
<Reference Include="$(AsyncTask)" />
<Reference Include="System.Threading.Tasks"/>
<Reference Include="$(MSBuildToolsPath)\Microsoft.Build.Tasks.Core.dll"/>
<Reference Include="$(MSBuildToolsPath)\Microsoft.Build.Utilities.Core.dll"/>
<Code Type="Class" Language="cs">
<![CDATA[
public class MyAsyncTask : Xamarin.Build.AsyncTask
Expand Down
27 changes: 27 additions & 0 deletions Xamarin.Build.AsyncTask/AsyncTask.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
using Microsoft.Build.Framework;
using System.Threading;
using System.Collections;
using System.Collections.Generic;
using System.Reflection;

[assembly:AssemblyKeyFileAttribute ("product.snk")]
Expand All @@ -21,10 +22,12 @@ public class AsyncTask : Task, ICancelableTask
readonly Queue warningMessageQueue = new Queue();
readonly Queue errorMessageQueue = new Queue();
readonly Queue customMessageQueue = new Queue();
readonly Queue telemetryMessageQueue = new Queue ();
readonly ManualResetEvent logDataAvailable = new ManualResetEvent(false);
readonly ManualResetEvent errorDataAvailable = new ManualResetEvent(false);
readonly ManualResetEvent warningDataAvailable = new ManualResetEvent(false);
readonly ManualResetEvent customDataAvailable = new ManualResetEvent(false);
readonly ManualResetEvent telemetryDataAvailable = new ManualResetEvent(false);
readonly ManualResetEvent taskCancelled = new ManualResetEvent(false);
readonly ManualResetEvent completed = new ManualResetEvent(false);
bool isRunning = true;
Expand Down Expand Up @@ -96,6 +99,23 @@ public void LogDebugTaskItems(string message, ITaskItem[] items)
LogDebugMessage(" {0}", item.ItemSpec);
}

public void LogTelemetry(string eventName, IDictionary<string, string> properties)
{
if (uiThreadId == Thread.CurrentThread.ManagedThreadId)
{
#pragma warning disable 618
Log.LogTelemetry(eventName, properties);
return;
#pragma warning restore 618
}

var data = new TelemetryEventArgs() {
EventName = eventName,
Properties = properties
};
EnqueueMessage(telemetryMessageQueue, data, telemetryDataAvailable);
}

public void LogMessage(string message) => LogMessage(message, importance: MessageImportance.Normal);

public void LogMessage(string message, params object[] messageArgs) => LogMessage(string.Format(message, messageArgs));
Expand Down Expand Up @@ -277,6 +297,7 @@ protected void WaitForCompletion()
errorDataAvailable,
warningDataAvailable,
customDataAvailable,
telemetryDataAvailable,
taskCancelled,
completed,
};
Expand Down Expand Up @@ -333,6 +354,11 @@ protected void WaitForCompletion()
BuildEngine.LogCustomEvent(e);
}, customDataAvailable);
break;
case WaitHandleIndex.TelemetryDataAvailable:
LogInternal<TelemetryEventArgs>(telemetryMessageQueue, (e) => {
BuildEngine5.LogTelemetry(e.EventName, e.Properties);
}, telemetryDataAvailable);
break;
case WaitHandleIndex.TaskCancelled:
Cancel();
cts.Cancel();
Expand All @@ -357,6 +383,7 @@ private enum WaitHandleIndex
ErrorDataAvailable,
WarningDataAvailable,
CustomDataAvailable,
TelemetryDataAvailable,
TaskCancelled,
Completed,
}
Expand Down
5 changes: 3 additions & 2 deletions Xamarin.Build.AsyncTask/Readme.txt
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,14 @@ If you're creating a custom task library, just inherit from Xamarin.Build.AsyncT
If you're creating an inline task that wants to inherit from AsyncTask, use the following
as a template:

<UsingTask TaskName="MyAsyncTask" TaskFactory="CodeTaskFactory" AssemblyFile="$(MSBuildToolsPath)\Microsoft.Build.Tasks.Core.dll">
<UsingTask TaskName="MyAsyncTask" TaskFactory="RoslynCodeTaskFactory" AssemblyFile="$(MSBuildToolsPath)\Microsoft.Build.Tasks.Core.dll">
<ParameterGroup>
<!-- TODO: your task parameters -->
</ParameterGroup>
<Task>
<Reference Include="$(AsyncTask)" />
<Reference Include="System.Threading.Tasks"/>
<Reference Include="$(MSBuildToolsPath)\Microsoft.Build.Tasks.Core.dll"/>
<Reference Include="$(MSBuildToolsPath)\Microsoft.Build.Utilities.Core.dll"/>
<Code Type="Class" Language="cs">
<![CDATA[
public class MyAsyncTask : Xamarin.Build.AsyncTask
Expand Down
11 changes: 6 additions & 5 deletions Xamarin.Build.AsyncTask/Test.targets
Original file line number Diff line number Diff line change
Expand Up @@ -9,15 +9,14 @@
<AsyncMessage Text="Hello Async World!" />
</Target>

<UsingTask TaskName="AsyncMessage" TaskFactory="CodeTaskFactory" AssemblyFile="$(MSBuildToolsPath)\Microsoft.Build.Tasks.Core.dll">
<UsingTask TaskName="AsyncMessage" TaskFactory="RoslynCodeTaskFactory" AssemblyFile="$(MSBuildToolsPath)/Microsoft.Build.Tasks.Core.dll">
<ParameterGroup>
<Text Required="true" />
</ParameterGroup>
<Task>
<Reference Include="$(OutputPath)$(AssemblyName).dll" />
<Reference Include="$(MSBuildToolsPath)\Microsoft.Build.Tasks.Core.dll"/>
<Reference Include="$(MSBuildToolsPath)\Microsoft.Build.Utilities.Core.dll"/>
<Reference Include="System.Threading.Tasks"/>
<Reference Include="$(MSBuildToolsPath)/Microsoft.Build.Tasks.Core.dll"/>
<Reference Include="$(MSBuildToolsPath)/Microsoft.Build.Utilities.Core.dll"/>
<Code Type="Class" Language="cs">
<![CDATA[
public class AsyncMessage : Xamarin.Build.AsyncTask
Expand All @@ -31,7 +30,9 @@
await System.Threading.Tasks.Task.Delay(5000);
LogMessage(Text);
Complete();
});
});
LogTelemetry("Test", new System.Collections.Generic.Dictionary<string, string> () {{"Property", "Value"}});
return base.Execute();
}
Expand Down
8 changes: 4 additions & 4 deletions Xamarin.Build.AsyncTask/Xamarin.Build.AsyncTask.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@

<Title>$(PackageId)</Title>
<Description>$(PackageId)</Description>
<Summary>Supports MSBuild 14+.</Summary>
<Summary>Supports MSBuild 17+.</Summary>
<Authors>Microsoft</Authors>
<Owners>microsoft xamarin</Owners>
<PackageReleaseNotes>$([System.IO.File]::ReadAllText('$(MSBuildThisFileDirectory)Readme.txt'))</PackageReleaseNotes>
Expand All @@ -29,8 +29,8 @@
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Microsoft.Build.Tasks.Core" Version="15.6.82" />
<PackageReference Include="Microsoft.Build.Utilities.Core" Version="15.6.82" />
<PackageReference Include="Microsoft.Build.Tasks.Core" Version="17.9.5" />
<PackageReference Include="Microsoft.Build.Utilities.Core" Version="17.9.5" />

<PackageReference Include="ThisAssembly.Metadata" Version="1.4.0">
<PrivateAssets>all</PrivateAssets>
Expand All @@ -47,7 +47,7 @@
<PackageFile Include="$(OutputPath)$(AssemblyName).pdb" Kind="lib" />
<PackageFile Include="$(OutputPath)$(AssemblyName).xml" Kind="lib" />
<PackageFile Include="Readme.txt" />
<PackageFile Include="Microsoft.Build.Tasks.Core;Microsoft.Build.Utilities.Core" Version="14.3.0" Kind="Dependency" Visible="false" />
<PackageFile Include="Microsoft.Build.Tasks.Core;Microsoft.Build.Utilities.Core" Version="17.0.0" Kind="Dependency" Visible="false" />
</ItemGroup>

<Import Project="Version.targets" />
Expand Down
4 changes: 4 additions & 0 deletions azure-pipelines.yml
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,10 @@ extends:
& dotnet build Xamarin.Build.AsyncTask\Xamarin.Build.AsyncTask.csproj -c Release -bl:$(LogDirectory)\Release.binlog
displayName: build libraries
errorActionPreference: stop
- powershell: |
& dotnet build Xamarin.Build.AsyncTask\Xamarin.Build.AsyncTask.csproj -c Release -t:Test -bl:$(LogDirectory)\Test.binlog
displayName: test libraries
errorActionPreference: stop
- powershell: |
& dotnet pack Xamarin.Build.AsyncTask\Xamarin.Build.AsyncTask.csproj -c Release -bl:$(LogDirectory)\PackRelease.binlog
displayName: pack NuGet
Expand Down

0 comments on commit db4ce14

Please sign in to comment.