Skip to content

Commit da49790

Browse files
FeikoEllerbach
andauthored
Add telemetry to application (#251)
Co-authored-by: Laurent Ellerbach <[email protected]>
1 parent 7822dfb commit da49790

File tree

8 files changed

+531
-18
lines changed

8 files changed

+531
-18
lines changed

README.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -462,6 +462,12 @@ nanoff --clearcache
462462

463463
The exit codes can be checked in [this source file](https://github.com/nanoframework/nanoFirmwareFlasher/blob/main/nanoFirmwareFlasher.Library/ExitCodes.cs).
464464

465+
## Telemetry
466+
467+
This tool is using anonymous telemetry to help us improve the usage. You can opt out by setting up an environment variable `NANOFRAMEWORK_TELEMETRY_OPTOUT` to 1.
468+
469+
The telemetry information is mainly related to the command line arguments, the firmware versions installed and any issue that can occurs during the code execution.
470+
465471
## Feedback and documentation
466472

467473
To provide feedback, report issues and finding out how to contribute please refer to the [Home repo](https://github.com/nanoframework/Home).

azure-pipelines.yml

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -327,6 +327,17 @@ jobs:
327327
eq(variables['UPDATE_DEPENDENTS'], 'false')
328328
)
329329
330+
# Replace the intrument key
331+
- powershell: |
332+
. ./common.ps1
333+
$fileToReplace = "$(System.DefaultWorkingDirectory)/nanoFirmwareFlasher.Library/appsettings.json"
334+
$sourceString = "INTRUMENT_KEY"
335+
$instrumentKey = "$(InstrumentKey)"
336+
337+
Find-ReplaceInFile -filePath $fileToReplace -sourceString $sourceString -targetString $instrumentKey
338+
displayName: Replace intrument key
339+
condition: succeeded()
340+
330341
- task: CopyFiles@1
331342
condition: >-
332343
and(

common.ps1

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
2+
# Common functions used by the other scripts
3+
4+
function Check-DirectoryExists {
5+
param (
6+
[string]$rootDirectory
7+
)
8+
9+
return Test-Path -Path $rootDirectory -PathType Container
10+
}
11+
12+
function Find-ReplaceInFiles {
13+
param (
14+
[string]$rootDirectory,
15+
[string]$sourceString,
16+
[string]$targetString
17+
)
18+
19+
Get-ChildItem -Recurse -File $rootDirectory | ForEach-Object {
20+
$filePath = $_.FullName
21+
22+
Find-ReplaceInFile -filePath $filePath -sourceString $sourceString -targetString $targetString
23+
}
24+
25+
Write-Host "String replacement completed."
26+
}
27+
28+
function Find-ReplaceInFile {
29+
param (
30+
[string]$filePath,
31+
[string]$sourceString,
32+
[string]$targetString
33+
)
34+
35+
# Get the original encoding of the file
36+
$sr = New-Object System.IO.StreamReader($filePath, $true)
37+
[char[]] $buffer = new-object char[] 3
38+
$sr.Read($buffer, 0, 3)
39+
$originalEncoding = $sr.CurrentEncoding
40+
$sr.Close()
41+
42+
# Making it simple as we only want to preserve UTF8 encoding
43+
if ( $originalEncoding.BodyName -eq "utf-8" ) {
44+
$fileEncoding = "UTF8"
45+
}
46+
else {
47+
$fileEncoding = "ASCII"
48+
}
49+
50+
# Read the content of the file using the original encoding
51+
$content = Get-Content -Path $filePath -Raw -Encoding $fileEncoding
52+
53+
# Perform the replacement
54+
$newContent = $content -replace [regex]::Escape($sourceString), $targetString
55+
56+
if ($content -ne $newContent) {
57+
Write-Host "Replacing in $filePath"
58+
59+
# Save the modified content back to the file using the original encoding
60+
Set-Content -Path $filePath -Value $newContent -Encoding $fileEncoding
61+
}
62+
}

nanoFirmwareFlasher.Library/FirmwarePackage.cs

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,11 @@
1414
using System.Net.Http;
1515
using System.Text.RegularExpressions;
1616
using System.Threading.Tasks;
17+
using Microsoft.ApplicationInsights;
18+
using Microsoft.ApplicationInsights.DataContracts;
19+
using Microsoft.Extensions.Configuration;
20+
using Microsoft.Extensions.Configuration.Json;
21+
using System.Reflection;
1722

1823
namespace nanoFramework.Tools.FirmwareFlasher
1924
{
@@ -34,6 +39,8 @@ public abstract class FirmwarePackage : IDisposable
3439

3540
private const string _readmeContent = "This folder contains nanoFramework firmware files. Can safely be removed.";
3641

42+
private static IConfigurationRoot _configuration;
43+
3744
/// <summary>
3845
/// Path with the base location for firmware packages.
3946
/// </summary>
@@ -97,13 +104,25 @@ public static string LocationPathBase
97104
/// </summary>
98105
public object BooterStartAddress { get; internal set; }
99106

107+
108+
100109
static FirmwarePackage()
101110
{
102111
_cloudsmithClient = new HttpClient
103112
{
104113
BaseAddress = new Uri("https://api.cloudsmith.io/v1/packages/net-nanoframework/")
105114
};
106115
_cloudsmithClient.DefaultRequestHeaders.Add("Accept", "*/*");
116+
117+
if (_configuration == null)
118+
{
119+
120+
var builder = new ConfigurationBuilder()
121+
.SetBasePath(Directory.GetCurrentDirectory())
122+
.AddJsonFile("appsettings.json");
123+
124+
_configuration = builder.Build();
125+
}
107126
}
108127

109128
/// <summary>
@@ -342,7 +361,42 @@ internal async Task<ExitCodes> DownloadAndExtractAsync()
342361
Console.ForegroundColor = ConsoleColor.White;
343362
}
344363

364+
//send app insight on successful download
365+
366+
string insightConnectionString = _configuration["iConnectionString"];
367+
string optOut = Environment.GetEnvironmentVariable("NANOFRAMEWORK_TELEMETRY_OPTOUT");
368+
345369
stepSuccessful = true;
370+
371+
if (!string.IsNullOrEmpty(insightConnectionString) && optOut != "1")
372+
{
373+
TelemetryClient telemetryClient = new TelemetryClient(new Microsoft.ApplicationInsights.Extensibility.TelemetryConfiguration()
374+
{
375+
ConnectionString = insightConnectionString
376+
});
377+
AssemblyInformationalVersionAttribute nanoffVersion = null;
378+
379+
try
380+
{
381+
nanoffVersion = Attribute.GetCustomAttribute(
382+
Assembly.GetEntryAssembly()!,
383+
typeof(AssemblyInformationalVersionAttribute))
384+
as AssemblyInformationalVersionAttribute;
385+
}
386+
catch
387+
{
388+
389+
}
390+
var packageTelemetry = new EventTelemetry("PackageDownloaded");
391+
packageTelemetry.Properties.Add("TargetName", _targetName);
392+
packageTelemetry.Properties.Add("Version", Version);
393+
packageTelemetry.Properties.Add("nanoffVersion", nanoffVersion == null ? "unknown" : nanoffVersion.InformationalVersion);
394+
telemetryClient.TrackEvent(packageTelemetry);
395+
telemetryClient.Flush();
396+
397+
}
398+
399+
346400
}
347401
catch
348402
{
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
{
2+
"iConnectionString": "INTRUMENT_KEY"
3+
4+
}

nanoFirmwareFlasher.Library/nanoFirmwareFlasher.Library.csproj

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,9 @@
5858
</ItemGroup>
5959

6060
<ItemGroup>
61+
<PackageReference Include="Microsoft.ApplicationInsights" Version="2.22.0" />
62+
<PackageReference Include="Microsoft.Extensions.Configuration" Version="8.0.0" />
63+
<PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="8.0.0" />
6164
<PackageReference Include="nanoFramework.Tools.Debugger.Net" Version="2.4.36" />
6265
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
6366
<PackageReference Include="Nerdbank.GitVersioning" Version="3.6.133" PrivateAssets="All" />
@@ -124,5 +127,10 @@
124127
<None Include="..\lib\uniflash\**" Link="uniflash\%(RecursiveDir)%(Filename)%(Extension)">
125128
</None>
126129
</ItemGroup>
130+
<ItemGroup>
131+
<None Update="appsettings.json">
132+
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
133+
</None>
134+
</ItemGroup>
127135

128136
</Project>

0 commit comments

Comments
 (0)