diff --git a/src/CodingWithCalvin.ProjectRenamifier/CodingWithCalvin.ProjectRenamifier.csproj b/src/CodingWithCalvin.ProjectRenamifier/CodingWithCalvin.ProjectRenamifier.csproj
index 7ee50f9..4f1186c 100644
--- a/src/CodingWithCalvin.ProjectRenamifier/CodingWithCalvin.ProjectRenamifier.csproj
+++ b/src/CodingWithCalvin.ProjectRenamifier/CodingWithCalvin.ProjectRenamifier.csproj
@@ -1,4 +1,4 @@
-
+
net48
@@ -9,11 +9,8 @@
true
-
- True
-
-
+
@@ -29,4 +26,4 @@
-
+
\ No newline at end of file
diff --git a/src/CodingWithCalvin.ProjectRenamifier/Commands/RenamifyProjectCommand.cs b/src/CodingWithCalvin.ProjectRenamifier/Commands/RenamifyProjectCommand.cs
index 9d02678..f1fc5b5 100644
--- a/src/CodingWithCalvin.ProjectRenamifier/Commands/RenamifyProjectCommand.cs
+++ b/src/CodingWithCalvin.ProjectRenamifier/Commands/RenamifyProjectCommand.cs
@@ -1,9 +1,11 @@
+using System.Collections.Generic;
using System.ComponentModel.Design;
using System.IO;
using System.Windows.Interop;
using System.Windows.Threading;
using CodingWithCalvin.ProjectRenamifier.Dialogs;
using CodingWithCalvin.ProjectRenamifier.Services;
+using CodingWithCalvin.Otel4Vsix;
using EnvDTE;
using EnvDTE80;
@@ -44,6 +46,8 @@ private void Execute(object sender, EventArgs e)
{
ThreadHelper.ThrowIfNotOnUIThread();
+ using var activity = VsixTelemetry.StartCommandActivity("ProjectRenamifier.Execute");
+
if (!(ServiceProvider.GetService(typeof(DTE)) is DTE2 dte))
{
return;
@@ -63,9 +67,10 @@ private void RenameProject(Project project, DTE2 dte)
{
ThreadHelper.ThrowIfNotOnUIThread();
- var currentName = Path.GetFileNameWithoutExtension(project.FullName);
+ using var activity = VsixTelemetry.StartCommandActivity("ProjectRenamifier.RenameProject");
- var dialog = new RenameProjectDialog(currentName);
+ var currentName = Path.GetFileNameWithoutExtension(project.FullName);
+ var dialog = new RenameProjectDialog(currentName);
// Set the owner to the VS main window for proper modal behavior
var helper = new WindowInteropHelper(dialog)
@@ -75,6 +80,7 @@ private void RenameProject(Project project, DTE2 dte)
if (dialog.ShowDialog() != true)
{
+ VsixTelemetry.LogInformation("Rename cancelled by user");
return;
}
@@ -82,6 +88,8 @@ private void RenameProject(Project project, DTE2 dte)
var projectFilePath = project.FullName;
var originalProjectFilePath = projectFilePath;
+ VsixTelemetry.LogInformation("Renaming project");
+
// Show progress dialog
var progressDialog = new RenameProgressDialog(currentName);
var progressHelper = new WindowInteropHelper(progressDialog)
@@ -93,7 +101,7 @@ private void RenameProject(Project project, DTE2 dte)
var stepIndex = 0;
var projectRemovedFromSolution = false;
var projectReaddedToSolution = false;
- System.Collections.Generic.List referencingProjects = null;
+ List referencingProjects = null;
Project parentSolutionFolder = null;
try
@@ -172,6 +180,10 @@ private void RenameProject(Project project, DTE2 dte)
DoEvents();
System.Threading.Thread.Sleep(500);
progressDialog.Close();
+
+ activity?.SetTag("rename.success", true);
+ activity?.SetTag("rename.steps_completed", stepIndex);
+ VsixTelemetry.LogInformation("Successfully renamed project");
}
catch (Exception ex)
{
@@ -179,6 +191,16 @@ private void RenameProject(Project project, DTE2 dte)
progressDialog.FailStep(stepIndex, ex.Message);
DoEvents();
+ activity?.RecordError(ex);
+ activity?.SetTag("rename.success", false);
+ activity?.SetTag("rename.failed_step", stepIndex);
+
+ VsixTelemetry.TrackException(ex, new Dictionary
+ {
+ { "operation.name", "RenameProject" },
+ { "step.index", stepIndex }
+ });
+
// Attempt rollback if project was removed but not re-added
if (projectRemovedFromSolution && !projectReaddedToSolution)
{
@@ -187,13 +209,16 @@ private void RenameProject(Project project, DTE2 dte)
// Try to re-add the project at its current location
var currentProjectPath = File.Exists(projectFilePath) ? projectFilePath : originalProjectFilePath;
if (File.Exists(currentProjectPath))
- {
- SolutionFolderService.AddProjectToSolution(dte.Solution, currentProjectPath, parentSolutionFolder);
+ { SolutionFolderService.AddProjectToSolution(dte.Solution, currentProjectPath, parentSolutionFolder);
+ VsixTelemetry.LogInformation("Rollback: Re-added project");
}
}
- catch
+ catch (Exception rollbackEx)
{
- // Rollback failed, nothing more we can do
+ VsixTelemetry.TrackException(rollbackEx, new Dictionary
+ {
+ { "operation.name", "RenameProject.Rollback" }
+ });
}
}
diff --git a/src/CodingWithCalvin.ProjectRenamifier/HoneycombConfig.cs b/src/CodingWithCalvin.ProjectRenamifier/HoneycombConfig.cs
new file mode 100644
index 0000000..6c0725c
--- /dev/null
+++ b/src/CodingWithCalvin.ProjectRenamifier/HoneycombConfig.cs
@@ -0,0 +1,7 @@
+namespace CodingWithCalvin.ProjectRenamifier
+{
+ internal static class HoneycombConfig
+ {
+ public const string ApiKey = "PLACEHOLDER";
+ }
+}
diff --git a/src/CodingWithCalvin.ProjectRenamifier/ProjectRenamifierPackage.cs b/src/CodingWithCalvin.ProjectRenamifier/ProjectRenamifierPackage.cs
index e01cc7a..c5f6713 100644
--- a/src/CodingWithCalvin.ProjectRenamifier/ProjectRenamifierPackage.cs
+++ b/src/CodingWithCalvin.ProjectRenamifier/ProjectRenamifierPackage.cs
@@ -3,6 +3,7 @@
global using Task = System.Threading.Tasks.Task;
using System.Runtime.InteropServices;
using System.Threading;
+using CodingWithCalvin.Otel4Vsix;
namespace CodingWithCalvin.ProjectRenamifier
{
@@ -14,10 +15,38 @@ public sealed class ProjectRenamifierPackage : AsyncPackage
{
protected override async Task InitializeAsync(CancellationToken cancellationToken, IProgress progress)
{
+ await JoinableTaskFactory.SwitchToMainThreadAsync(cancellationToken);
+
+ var builder = VsixTelemetry.Configure()
+ .WithServiceName(VsixInfo.DisplayName)
+ .WithServiceVersion(VsixInfo.Version)
+ .WithVisualStudioAttributes(this)
+ .WithEnvironmentAttributes();
+
+#if !DEBUG
+ builder
+ .WithOtlpHttp("https://api.honeycomb.io")
+ .WithHeader("x-honeycomb-team", HoneycombConfig.ApiKey);
+#endif
+
+ builder.Initialize();
+
await Task.Run(() =>
{
RenamifyProjectCommand.Initialize(this);
});
+
+ VsixTelemetry.LogInformation("Project Renamifier initialized successfully");
+ }
+
+ protected override void Dispose(bool disposing)
+ {
+ if (disposing)
+ {
+ VsixTelemetry.Shutdown();
+ }
+
+ base.Dispose(disposing);
}
}
}
\ No newline at end of file