Skip to content

OpenTelemetry support library for Visual Studio 2022+ extensions. Add distributed tracing, metrics, logging, and exception tracking to your VSIX with minimal configuration.

License

Notifications You must be signed in to change notification settings

CodingWithCalvin/Otel4Vsix

Folders and files

NameName
Last commit message
Last commit date

Latest commit

ย 

History

18 Commits
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 

Otel4Vsix Logo

๐Ÿ”ญ Otel4Vsix

Build NuGet NuGet Downloads License: MIT

๐Ÿš€ Add OpenTelemetry observability to your Visual Studio extensions in minutes!

Otel4Vsix is a powerful yet simple library that brings distributed tracing, metrics, logging, and exception tracking to your VSIX extensions with minimal configuration. See exactly what's happening inside your extension! ๐Ÿ‘€


โœจ Features

Feature Description
๐Ÿ“Š Distributed Tracing Track operations across your extension with spans and activities
๐Ÿ“ˆ Metrics Counters, histograms, and gauges for performance monitoring
๐Ÿ“ Structured Logging OpenTelemetry-integrated logging via ILogger
๐Ÿ’ฅ Exception Tracking Automatic and manual exception capture with full context
๐Ÿ”Œ Multiple Export Modes OTLP (gRPC/HTTP) for production, Debug output for development
๐ŸŽฏ VS-Specific Helpers Pre-configured spans for commands, tool windows, and documents
๐Ÿ—๏ธ Fluent Builder API Clean, chainable configuration
๐Ÿ”ง Auto-Detection Automatically captures VS version, edition, OS, and architecture

๐Ÿ“ฆ Installation

Package Manager

Install-Package CodingWithCalvin.Otel4Vsix

.NET CLI

dotnet add package CodingWithCalvin.Otel4Vsix

PackageReference

<PackageReference Include="CodingWithCalvin.Otel4Vsix" Version="1.0.0" />

๐Ÿš€ Quick Start

1๏ธโƒฃ Initialize Telemetry

In your Visual Studio extension's InitializeAsync method:

using CodingWithCalvin.Otel4Vsix;

protected override async Task InitializeAsync(
    CancellationToken cancellationToken,
    IProgress<ServiceProgressData> progress)
{
    await JoinableTaskFactory.SwitchToMainThreadAsync();

    VsixTelemetry.Configure()
        .WithServiceName("MyAwesomeExtension")
        .WithServiceVersion("1.0.0")
        .WithVisualStudioAttributes(this)  // ๐Ÿช„ Auto-captures VS version & edition!
        .WithEnvironmentAttributes()        // ๐Ÿ–ฅ๏ธ Auto-captures OS & architecture!
        .WithOtlpHttp("https://api.honeycomb.io")
        .WithHeader("x-honeycomb-team", "your-api-key")
        .Initialize();
}

2๏ธโƒฃ Shutdown on Dispose

protected override void Dispose(bool disposing)
{
    if (disposing)
    {
        VsixTelemetry.Shutdown();
    }
    base.Dispose(disposing);
}

๐ŸŽ‰ That's it! Your extension is now observable!


๐ŸŽ›๏ธ Telemetry Modes

Otel4Vsix supports multiple telemetry modes to fit your workflow:

Mode Description
Auto ๐Ÿค– Default - Uses OTLP if endpoint configured, otherwise Debug output
Debug ๐Ÿ› Outputs to VS Output window (visible when debugging)
Otlp ๐Ÿ“ก Exports via OTLP protocol to your collector
Disabled ๐Ÿ”‡ No telemetry collection

๐Ÿ’ก Pro Tip: Development vs Production

var builder = VsixTelemetry.Configure()
    .WithServiceName(Vsix.Name)
    .WithServiceVersion(Vsix.Version)
    .WithVisualStudioAttributes(this)
    .WithEnvironmentAttributes();

#if !DEBUG
// ๐Ÿ“ก Only send to collector in Release builds
builder
    .WithOtlpHttp("https://api.honeycomb.io")
    .WithHeader("x-honeycomb-team", apiKey);
#endif

builder.Initialize();

In Debug builds, telemetry automatically outputs to the VS Output window! ๐Ÿ”


๐Ÿ“Š Usage

๐Ÿ” Tracing

Create spans to track operations and their duration:

// ๐ŸŽฏ Simple span
using var activity = VsixTelemetry.Tracer.StartActivity("ProcessFile");
activity?.SetTag("file.path", filePath);
activity?.SetTag("file.size", fileSize);

// โšก VS command span (with pre-configured attributes)
using var commandSpan = VsixTelemetry.StartCommandActivity("MyExtension.DoSomething");

// ๐Ÿช† Nested spans for detailed tracing
using var outer = VsixTelemetry.Tracer.StartActivity("LoadProject");
{
    using var inner = VsixTelemetry.Tracer.StartActivity("ParseProjectFile");
    // ... parse logic
}

โš ๏ธ Error Handling in Spans

using var activity = VsixTelemetry.StartActivity("RiskyOperation");
try
{
    // Your code here
}
catch (Exception ex)
{
    activity?.SetStatus(ActivityStatusCode.Error, ex.Message);
    activity?.RecordException(ex);
    throw;
}

๐Ÿ“ˆ Metrics

Record counters, histograms, and gauges:

// ๐Ÿ”ข Counter - track occurrences
var commandCounter = VsixTelemetry.GetOrCreateCounter<long>(
    "extension.commands.executed",
    "{command}",
    "Number of commands executed");

commandCounter?.Add(1,
    new KeyValuePair<string, object>("command.name", "FormatDocument"));

// ๐Ÿ“Š Histogram - track distributions (e.g., durations)
var durationHistogram = VsixTelemetry.GetOrCreateHistogram<double>(
    "extension.operation.duration",
    "ms",
    "Duration of operations in milliseconds");

var stopwatch = Stopwatch.StartNew();
// ... do work ...
stopwatch.Stop();
durationHistogram?.Record(stopwatch.ElapsedMilliseconds,
    new KeyValuePair<string, object>("operation.name", "BuildSolution"));

๐Ÿ“ Logging

Structured logging with OpenTelemetry integration:

// ๐Ÿ“ข Quick logging methods
VsixTelemetry.LogInformation("Processing file: {FilePath}", filePath);
VsixTelemetry.LogWarning("File not found, using default: {DefaultPath}", defaultPath);
VsixTelemetry.LogError(ex, "Failed to process {FileName}", fileName);

// ๐Ÿท๏ธ Create a typed logger for your class
public class MyToolWindow
{
    private readonly ILogger<MyToolWindow> _logger = VsixTelemetry.CreateLogger<MyToolWindow>();

    public void DoWork()
    {
        _logger.LogDebug("Starting work...");
        // ...
        _logger.LogInformation("Work completed successfully! ๐ŸŽ‰");
    }
}

๐Ÿ’ฅ Exception Tracking

Track exceptions with full context:

// ๐ŸŽฏ Manual exception tracking
try
{
    // risky operation
}
catch (Exception ex)
{
    VsixTelemetry.TrackException(ex);
    // Handle or rethrow
}

// ๐Ÿ“‹ With additional context
catch (Exception ex)
{
    VsixTelemetry.TrackException(ex, new Dictionary<string, object>
    {
        { "operation.name", "LoadProject" },
        { "project.path", projectPath },
        { "user.action", "OpenSolution" }
    });
    throw;
}

๐Ÿ’ก Note: Global unhandled exceptions are automatically captured when EnableGlobalExceptionHandler is true (default).


โš™๏ธ Configuration Options

๐Ÿ—๏ธ Fluent Builder Methods

Method Description
WithServiceName(name) Set the service name for identification
WithServiceVersion(version) Set the service version
WithVisualStudioAttributes(serviceProvider) ๐Ÿช„ Auto-capture VS version & edition
WithVisualStudioAttributes(version, edition) Manually set VS attributes
WithEnvironmentAttributes() ๐Ÿ–ฅ๏ธ Auto-capture OS version & architecture
WithResourceAttribute(key, value) Add custom resource attributes
WithOtlpHttp(endpoint) Configure OTLP HTTP export
WithOtlpGrpc(endpoint) Configure OTLP gRPC export
WithHeader(key, value) Add headers for OTLP requests
WithMode(mode) Set telemetry mode (Auto/Debug/Otlp/Disabled)
WithTracing(enabled) Enable/disable tracing
WithMetrics(enabled) Enable/disable metrics
WithLogging(enabled) Enable/disable logging
WithTraceSamplingRatio(ratio) Set trace sampling (0.0 - 1.0)
WithGlobalExceptionHandler(enabled) Enable/disable auto exception capture
WithExceptionFilter(filter) Filter which exceptions to track
WithExportTimeout(ms) Set export timeout in milliseconds
Initialize() ๐Ÿš€ Initialize telemetry

๐Ÿ“‹ Auto-Captured Attributes

When using the helper methods, these attributes are automatically captured:

Attribute Source Example
vs.version WithVisualStudioAttributes() "17.12.35521.163"
vs.edition WithVisualStudioAttributes() "Enterprise"
os.version WithEnvironmentAttributes() "10.0.22631.0"
host.arch WithEnvironmentAttributes() "X64" or "Arm64"

๐Ÿ”Œ Supported Backends

Otel4Vsix exports telemetry via OTLP, which is supported by:

Backend Link
๐Ÿ Honeycomb honeycomb.io
๐Ÿ”ต Azure Monitor Application Insights
๐Ÿ• Datadog datadoghq.com
๐ŸŸก Jaeger jaegertracing.io
๐Ÿ”ด Grafana Tempo grafana.com/oss/tempo
๐Ÿ“ฎ Zipkin zipkin.io
โ˜๏ธ AWS X-Ray aws.amazon.com/xray
๐ŸŒ Google Cloud Trace cloud.google.com/trace
๐Ÿ”ง Any OTLP-compatible collector โ€”

๐Ÿ“‹ Example: Full Production Setup

using CodingWithCalvin.Otel4Vsix;

public sealed class MyExtensionPackage : AsyncPackage
{
    protected override async Task InitializeAsync(
        CancellationToken cancellationToken,
        IProgress<ServiceProgressData> progress)
    {
        await JoinableTaskFactory.SwitchToMainThreadAsync();

        var builder = VsixTelemetry.Configure()
            .WithServiceName("MyExtension")
            .WithServiceVersion(Vsix.Version)
            .WithVisualStudioAttributes(this)
            .WithEnvironmentAttributes()
            .WithResourceAttribute("deployment.environment", "production")
            .WithTraceSamplingRatio(0.1)  // Sample 10% of traces
            .WithExceptionFilter(ex => ex is not OperationCanceledException);

#if !DEBUG
        builder
            .WithOtlpHttp("https://api.honeycomb.io")
            .WithHeader("x-honeycomb-team", Config.HoneycombApiKey);
#endif

        builder.Initialize();

        // ... rest of initialization
    }

    protected override void Dispose(bool disposing)
    {
        if (disposing)
        {
            VsixTelemetry.Shutdown();
        }
        base.Dispose(disposing);
    }
}

๐Ÿ“‹ Requirements

Requirement Version
.NET Framework 4.8
Visual Studio 2022 or later

๐Ÿค Contributing

Contributions are welcome! ๐ŸŽ‰

  1. ๐Ÿด Fork the repository
  2. ๐ŸŒฟ Create your feature branch (git checkout -b feature/AmazingFeature)
  3. ๐Ÿ’พ Commit your changes (git commit -m 'Add some AmazingFeature')
  4. ๐Ÿ“ค Push to the branch (git push origin feature/AmazingFeature)
  5. ๐Ÿ”ƒ Open a Pull Request

๐Ÿ‘ฅ Contributors

CalvinAllen


๐Ÿ“„ License

This project is licensed under the MIT License - see the LICENSE file for details.


๐Ÿ™ Acknowledgments

  • Built on top of OpenTelemetry .NET ๐Ÿ”ญ
  • Inspired by the need for better observability in Visual Studio extensions ๐Ÿ’ก
  • Made with โค๏ธ by Coding with Calvin

About

OpenTelemetry support library for Visual Studio 2022+ extensions. Add distributed tracing, metrics, logging, and exception tracking to your VSIX with minimal configuration.

Resources

License

Code of conduct

Contributing

Stars

Watchers

Forks

Sponsor this project

Contributors 2

  •  
  •  

Languages