Skip to content

Generated Output

Kieron Lanning edited this page Feb 2, 2025 · 1 revision

Example Generated Output

Each generated target (Activity, Logging, Metrics) will produce a partial class implementing its part of the output, plus an additional class for the Dependency Injection integration.

If we take the example from the README.md:

using System.Diagnostics;
using Purview.Telemetry.Activities;
using Purview.Telemetry.Logging;
using Purview.Telemetry.Metrics;

namespace SampleApp.Host.Services;

[ActivitySource]
[Logger]
[Meter]
interface IEntityStoreTelemetry
{
  /// <summary>
  /// Creates and starts an Activity and adds the parameters as Tags and Baggage.
  /// </summary>
  [Activity]
  Activity? GettingEntityFromStore(int entityId, [Baggage] string serviceUrl);

  /// <summary>
  /// Adds an ActivityEvent to the Activity with the parameters as Tags.
  /// </summary>
  [Event]
  void GetDuration(Activity? activity, int durationInMS);

  /// <summary>
  /// Adds the parameters as Baggage to the Activity.
  /// </summary>
  [Context]
  void RetrievedEntity(Activity? activity, float totalValue, int lastUpdatedByUserId);

  /// <summary>
  /// Generates a structured log message using an ILogger - defaults to Informational.
  /// </summary>
  [Log]
  void ProcessingEntity(int entityId, string updateState);

  /// <summary>
  /// Generates a structured log message using an ILogger, specifically defined as Informational.
  /// </summary>
  [Info]
  void ProcessingAnotherEntity(int entityId, string updateState);

  /// <summary>
  /// Adds 1 to a Counter{T} with the entityId as a Tag.
  /// </summary>
  [AutoCounter]
  void RetrievingEntity(int entityId);
}

Activity Output

//------------------------------------------------------------------------------
// <auto-generated>
//     This code was generated by the Purview.Telemetry.SourceGenerator
//     on 2025-02-02 13:34:30 +00:00.
//
//     Changes to this file may cause incorrect behaviour and will be lost
//     when the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------

#pragma warning disable 1591 // publicly visible type or member must be documented

#nullable enable

namespace SampleApp.Host.Services
{
  sealed partial class EntityStoreTelemetryCore : SampleApp.Host.Services.IEntityStoreTelemetry
  {
    readonly static System.Diagnostics.ActivitySource _activitySource = new System.Diagnostics.ActivitySource("sample-weather-app");

    [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)]
    static void RecordExceptionInternal(System.Diagnostics.Activity? activity, System.Exception? exception, bool escape)
    {
      if (activity == null || exception == null)
      {
        return;
      }

      System.Diagnostics.ActivityTagsCollection tagsCollection = new System.Diagnostics.ActivityTagsCollection();
      tagsCollection.Add("exception.escaped", escape);
      tagsCollection.Add("exception.message", exception.Message);
      tagsCollection.Add("exception.type", exception.GetType().FullName);
      tagsCollection.Add("exception.stacktrace", exception.StackTrace);

      System.Diagnostics.ActivityEvent recordExceptionEvent = new System.Diagnostics.ActivityEvent(name: "exception", timestamp: default, tags: tagsCollection);

      activity.AddEvent(recordExceptionEvent);
    }

    [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)]
    public System.Diagnostics.Activity? GettingEntityFromStore(int entityId, string serviceUrl)
    {
      if (!_activitySource.HasListeners())
      {
        return null;
      }

      System.Diagnostics.Activity? activityGettingEntityFromStore = _activitySource.StartActivity(name: "GettingEntityFromStore", kind: System.Diagnostics.ActivityKind.Internal, parentId: default, tags: default, links: default, startTime: default);

      if (activityGettingEntityFromStore != null)
      {
        activityGettingEntityFromStore.SetTag("entityid", entityId);
      }

      if (activityGettingEntityFromStore != null)
      {
        activityGettingEntityFromStore.SetBaggage("serviceurl", serviceUrl);
      }

      return activityGettingEntityFromStore;
    }

    [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)]
    public void GetDuration(System.Diagnostics.Activity? activity, int durationInMS)
    {
      if (!_activitySource.HasListeners())
      {
        return;
      }

      if (activity != null)
      {
        System.Diagnostics.ActivityTagsCollection tagsCollectionGetDuration = new System.Diagnostics.ActivityTagsCollection();
        tagsCollectionGetDuration.Add("durationinms", durationInMS);

        System.Diagnostics.ActivityEvent activityEventGetDuration = new System.Diagnostics.ActivityEvent(name: "GetDuration", timestamp: default, tags: tagsCollectionGetDuration);

        activity.AddEvent(activityEventGetDuration);
      }
    }

    [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)]
    public void RetrievedEntity(System.Diagnostics.Activity? activity, float totalValue, int lastUpdatedByUserId)
    {
      if (!_activitySource.HasListeners())
      {
        return;
      }

      if (activity != null)
      {
        activity.SetTag("totalvalue", totalValue);
        activity.SetTag("lastupdatedbyuserid", lastUpdatedByUserId);
      }
    }

  }
}

Logging Output

//------------------------------------------------------------------------------
// <auto-generated>
//     This code was generated by the Purview.Telemetry.SourceGenerator
//     on 2025-02-02 13:34:30 +00:00.
//
//     Changes to this file may cause incorrect behaviour and will be lost
//     when the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------

#pragma warning disable 1591 // publicly visible type or member must be documented

#nullable enable

namespace SampleApp.Host.Services
{
  sealed partial class EntityStoreTelemetryCore : SampleApp.Host.Services.IEntityStoreTelemetry
  {
    readonly Microsoft.Extensions.Logging.ILogger<SampleApp.Host.Services.IEntityStoreTelemetry> _logger;

    static readonly System.Action<Microsoft.Extensions.Logging.ILogger, int, string, System.Exception?> _processingEntityAction = Microsoft.Extensions.Logging.LoggerMessage.Define<int, string>(Microsoft.Extensions.Logging.LogLevel.Information, default, "EntityStoreTelemetry.ProcessingEntity: entityId: {EntityId}, updateState: {UpdateState}");
    static readonly System.Action<Microsoft.Extensions.Logging.ILogger, int, string, System.Exception?> _processingAnotherEntityAction = Microsoft.Extensions.Logging.LoggerMessage.Define<int, string>(Microsoft.Extensions.Logging.LogLevel.Information, default, "EntityStoreTelemetry.ProcessingAnotherEntity: entityId: {EntityId}, updateState: {UpdateState}");

    [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)]
    public void ProcessingEntity(int entityId, string updateState)
    {
      if (!_logger.IsEnabled(Microsoft.Extensions.Logging.LogLevel.Information))
      {
        return;
      }

      _processingEntityAction(_logger, entityId, updateState, null);
    }


    [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)]
    public void ProcessingAnotherEntity(int entityId, string updateState)
    {
      if (!_logger.IsEnabled(Microsoft.Extensions.Logging.LogLevel.Information))
      {
        return;
      }

      _processingAnotherEntityAction(_logger, entityId, updateState, null);
    }

  }
}

Metrics Output

Note here the constructor, which accounts for both the IMeterFactory, and the ILogger.

//------------------------------------------------------------------------------
// <auto-generated>
//     This code was generated by the Purview.Telemetry.SourceGenerator
//     on 2025-02-02 13:34:30 +00:00.
//
//     Changes to this file may cause incorrect behaviour and will be lost
//     when the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------

#pragma warning disable 1591 // publicly visible type or member must be documented

#nullable enable

namespace SampleApp.Host.Services
{
  sealed partial class EntityStoreTelemetryCore : SampleApp.Host.Services.IEntityStoreTelemetry
  {
    System.Diagnostics.Metrics.Meter _meter = default!;

    System.Diagnostics.Metrics.Counter<int>? _retrievingEntityInstrument = null;

    public EntityStoreTelemetryCore(Microsoft.Extensions.Logging.ILogger<SampleApp.Host.Services.IEntityStoreTelemetry> logger, System.Diagnostics.Metrics.IMeterFactory meterFactory)
    {
      _logger = logger;
      InitializeMeters(meterFactory);
    }

    [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)]
    void InitializeMeters(System.Diagnostics.Metrics.IMeterFactory meterFactory)
    {
      if (_meter != null)
      {
        throw new System.Exception("The meters have already been initialized.");
      }

      System.Collections.Generic.Dictionary<string, object?> meterTags = new System.Collections.Generic.Dictionary<string, object?>();

      PopulateMeterTags(meterTags);

      _meter = meterFactory.Create(new System.Diagnostics.Metrics.MeterOptions("EntityStoreTelemetry")
      {
        Version = null,
        Tags = meterTags
      });

      System.Collections.Generic.Dictionary<string, object?> retrievingEntityTags = new System.Collections.Generic.Dictionary<string, object?>();

      PopulateRetrievingEntityTags(retrievingEntityTags);

      _retrievingEntityInstrument = _meter.CreateCounter<int>(name: "retrievingentity", unit: null, description: null, tags: retrievingEntityTags);
    }

    partial void PopulateMeterTags(System.Collections.Generic.Dictionary<string, object?> meterTags);

    partial void PopulateRetrievingEntityTags(System.Collections.Generic.Dictionary<string, object?> instrumentTags);

    [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)]
    public void RetrievingEntity(int entityId)
    {
      if (_retrievingEntityInstrument == null)
      {
        return;
      }

      System.Diagnostics.TagList retrievingEntityTagList = new System.Diagnostics.TagList();

      retrievingEntityTagList.Add("entityid", entityId);

      _retrievingEntityInstrument.Add(1, tagList: retrievingEntityTagList);
    }
  }
}

Dependency Injection Output

//------------------------------------------------------------------------------
// <auto-generated>
//     This code was generated by the Purview.Telemetry.SourceGenerator
//     on 2025-02-02 13:34:30 +00:00.
//
//     Changes to this file may cause incorrect behaviour and will be lost
//     when the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------

#pragma warning disable 1591 // publicly visible type or member must be documented

#nullable enable

namespace Microsoft.Extensions.DependencyInjection
{
  [System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Never)]
  static class EntityStoreTelemetryCoreDIExtension
  {
    [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)]
    static public Microsoft.Extensions.DependencyInjection.IServiceCollection AddEntityStoreTelemetry(this Microsoft.Extensions.DependencyInjection.IServiceCollection services)
    {
      return services.AddSingleton<SampleApp.Host.Services.IEntityStoreTelemetry, SampleApp.Host.Services.EntityStoreTelemetryCore>();
    }
  }
}
Clone this wiki locally