Skip to content

Commit f88e606

Browse files
authored
feat(telemetry): add Otel4Vsix integration (#23)
* feat(telemetry): add Otel4Vsix integration - Add CodingWithCalvin.Otel4Vsix package reference - Configure telemetry in OpenBinFolderPackage with Honeycomb export - Add HoneycombConfig.cs for API key placeholder - Instrument OpenPath and OpenProjectBinFolder with activities - Add proper telemetry shutdown in Dispose - Remove explicit DeployExtension (VsixSdk handles this) * fix(telemetry): remove sensitive data from telemetry Remove project names and file paths from telemetry tags and logs to avoid sending potentially sensitive information.
1 parent 3735768 commit f88e606

4 files changed

Lines changed: 91 additions & 33 deletions

File tree

src/CodingWithCalvin.OpenBinFolder/CodingWithCalvin.OpenBinFolder.csproj

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,8 @@
88
<OutputPath>bin/$(Configuration)/</OutputPath>
99
</PropertyGroup>
1010

11-
<PropertyGroup Condition="'$(Configuration)' == 'Debug'">
12-
<DeployExtension>True</DeployExtension>
13-
</PropertyGroup>
14-
1511
<ItemGroup>
12+
<PackageReference Include="CodingWithCalvin.Otel4Vsix" Version="0.2.2" />
1613
<PackageReference Include="Microsoft.VisualStudio.SDK" Version="17.14.40265" />
1714
</ItemGroup>
1815

src/CodingWithCalvin.OpenBinFolder/Commands/OpenBinFolderCommand.cs

Lines changed: 57 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
1-
using System;
1+
using System;
2+
using System.Collections.Generic;
23
using System.ComponentModel.Design;
34
using System.IO;
45
using System.Windows.Forms;
6+
using CodingWithCalvin.Otel4Vsix;
57
using EnvDTE;
68
using EnvDTE80;
79
using Microsoft.VisualStudio.Shell;
@@ -44,39 +46,48 @@ private void OpenPath(object sender, EventArgs e)
4446
{
4547
ThreadHelper.ThrowIfNotOnUIThread();
4648

47-
if (!(ServiceProvider.GetService(typeof(DTE)) is DTE2 dte))
48-
{
49-
throw new ArgumentNullException(nameof(dte));
50-
}
49+
using var activity = VsixTelemetry.StartCommandActivity("OpenBinFolder.OpenPath");
5150

52-
foreach (
53-
UIHierarchyItem selectedItem in (Array)
54-
dte.ToolWindows.SolutionExplorer.SelectedItems
55-
)
51+
try
5652
{
57-
switch (selectedItem.Object)
53+
if (!(ServiceProvider.GetService(typeof(DTE)) is DTE2 dte))
54+
{
55+
throw new ArgumentNullException(nameof(dte));
56+
}
57+
58+
foreach (
59+
UIHierarchyItem selectedItem in (Array)
60+
dte.ToolWindows.SolutionExplorer.SelectedItems
61+
)
5862
{
59-
case Project project:
60-
try
61-
{
63+
switch (selectedItem.Object)
64+
{
65+
case Project project:
6266
OpenProjectBinFolder(project);
63-
}
64-
catch (Exception ex)
65-
{
66-
MessageBox.Show(
67-
$@"
68-
Unable to determine output path for selected project
69-
{Environment.NewLine}
70-
{Environment.NewLine}
71-
Exception: {ex.Message}"
72-
);
73-
}
74-
75-
break;
67+
break;
68+
}
7669
}
70+
71+
VsixTelemetry.LogInformation("Bin folder opened successfully");
7772
}
73+
catch (Exception ex)
74+
{
75+
activity?.RecordError(ex);
76+
VsixTelemetry.TrackException(ex, new Dictionary<string, object>
77+
{
78+
{ "operation.name", "OpenPath" }
79+
});
80+
throw;
81+
}
82+
}
7883

79-
void OpenProjectBinFolder(Project project)
84+
private void OpenProjectBinFolder(Project project)
85+
{
86+
ThreadHelper.ThrowIfNotOnUIThread();
87+
88+
using var activity = VsixTelemetry.StartCommandActivity("OpenBinFolder.OpenProjectBinFolder");
89+
90+
try
8091
{
8192
var projectPath =
8293
Path.GetDirectoryName(project.FullName)
@@ -88,9 +99,27 @@ void OpenProjectBinFolder(Project project)
8899

89100
var projectBinPath = Path.Combine(projectPath, projectOutputPath);
90101

91-
System.Diagnostics.Process.Start(
102+
System.Diagnostics.Process.Start(
92103
Directory.Exists(projectBinPath) ? projectBinPath : projectPath
93104
);
105+
106+
VsixTelemetry.LogInformation("Opened bin folder for project");
107+
}
108+
catch (Exception ex)
109+
{
110+
activity?.RecordError(ex);
111+
VsixTelemetry.TrackException(ex, new Dictionary<string, object>
112+
{
113+
{ "operation.name", "OpenProjectBinFolder" },
114+
});
115+
116+
MessageBox.Show(
117+
$@"
118+
Unable to determine output path for selected project
119+
{Environment.NewLine}
120+
{Environment.NewLine}
121+
Exception: {ex.Message}"
122+
);
94123
}
95124
}
96125
}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
namespace CodingWithCalvin.OpenBinFolder
2+
{
3+
internal static class HoneycombConfig
4+
{
5+
public const string ApiKey = "PLACEHOLDER";
6+
}
7+
}

src/CodingWithCalvin.OpenBinFolder/OpenBinFolderPackage.cs

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
1-
using System;
1+
using System;
22
using System.Runtime.InteropServices;
33
using System.Threading;
44
using CodingWithCalvin.OpenBinFolder.Commands;
5+
using CodingWithCalvin.Otel4Vsix;
56
using Microsoft.VisualStudio.Shell;
67
using Task = System.Threading.Tasks.Task;
78

@@ -20,7 +21,31 @@ IProgress<ServiceProgressData> progress
2021
{
2122
await JoinableTaskFactory.SwitchToMainThreadAsync(cancellationToken);
2223

24+
var builder = VsixTelemetry.Configure()
25+
.WithServiceName(VsixInfo.DisplayName)
26+
.WithServiceVersion(VsixInfo.Version)
27+
.WithVisualStudioAttributes(this)
28+
.WithEnvironmentAttributes();
29+
30+
#if !DEBUG
31+
builder
32+
.WithOtlpHttp("https://api.honeycomb.io")
33+
.WithHeader("x-honeycomb-team", HoneycombConfig.ApiKey);
34+
#endif
35+
36+
builder.Initialize();
37+
2338
OpenBinFolderCommand.Initialize(this);
2439
}
40+
41+
protected override void Dispose(bool disposing)
42+
{
43+
if (disposing)
44+
{
45+
VsixTelemetry.Shutdown();
46+
}
47+
48+
base.Dispose(disposing);
49+
}
2550
}
2651
}

0 commit comments

Comments
 (0)