Skip to content

Generated Output

Kieron Lanning edited this page Feb 18, 2025 · 16 revisions

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 Purview.Telemetry.Activities;
using Purview.Telemetry.Logging;
using Purview.Telemetry.Metrics;
using System.Diagnostics;

[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>
    /// A scoped logging method.
    /// </summary>
    [Log]
    IDisposable AScopedLogEntry(int parentEntityId);

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

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

    /// <summary>
    /// Generates a structured log message using an ILogger, specifically defined as Error.
    /// </summary>
    [Error(""An explicit error message. The entity Id is {EntityId}, and the error is {Exception}."")]
    void ExplicitErrorMessage(int entityId, Exception exception);

    /// <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 {Scrubbed}.
//
//    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

sealed partial class EntityStoreTelemetryCore : global::IEntityStoreTelemetry
{
 readonly static global::System.Diagnostics.ActivitySource _activitySource = new("purview.telemetry.sourcegenerator");

 [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Purview.Telemetry.SourceGenerator", "0.1.0.0")]
 [global::System.Runtime.CompilerServices.MethodImpl(global::System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)]
 static void RecordExceptionInternal(global::System.Diagnostics.Activity? activity, global::System.Exception? exception, bool escape)
 {
    if (activity == null || exception == null)
    {
     return;
    }

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

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

    activity.AddEvent(recordExceptionEvent);
 }

 [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Purview.Telemetry.SourceGenerator", "0.1.0.0")]
 [global::System.Runtime.CompilerServices.MethodImpl(global::System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)]
 public System.Diagnostics.Activity? GettingEntityFromStore(int entityId, string serviceUrl)
 {
    if (!_activitySource.HasListeners())
    {
     return null;
    }

    global::System.Diagnostics.Activity? activityGettingEntityFromStore = _activitySource.StartActivity(name: "GettingEntityFromStore", kind: global::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;
 }

 [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Purview.Telemetry.SourceGenerator", "0.1.0.0")]
 [global::System.Runtime.CompilerServices.MethodImpl(global::System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)]
 public void GetDuration(System.Diagnostics.Activity? activity, int durationInMS)
 {
    if (!_activitySource.HasListeners())
    {
     return;
    }

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

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

     activity.AddEvent(activityEventGetDuration);
    }
 }

 [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Purview.Telemetry.SourceGenerator", "0.1.0.0")]
 [global::System.Runtime.CompilerServices.MethodImpl(global::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

Generation v2

//------------------------------------------------------------------------------
// <auto-generated>
//    This code was generated by the Purview.Telemetry.SourceGenerator
//    on {Scrubbed}.
//
//    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

sealed partial class EntityStoreTelemetryCore : global::IEntityStoreTelemetry
{
 readonly global::Microsoft.Extensions.Logging.ILogger<global::IEntityStoreTelemetry> _logger;

 [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Purview.Telemetry.SourceGenerator", "0.1.0.0")]
 [global::System.Runtime.CompilerServices.MethodImpl(global::System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)]
 public global::System.IDisposable? AScopedLogEntry(int parentEntityId)
 {
    var state = global::Microsoft.Extensions.Logging.LoggerMessageHelper.ThreadLocalState;
    state.ReserveTagSpace(2);

    state.TagArray[0] = new("{OriginalFormat}", "AScopedLogEntry: ParentEntityId = {ParentEntityId}");
    state.TagArray[1] = new("parentEntityId", parentEntityId);

    var v0 = state.TagArray[1].Value ?? "(null)";

    var formattedMessage =
#if NET
     string.Create(global::System.Globalization.CultureInfo.InvariantCulture, $"AScopedLogEntry: ParentEntityId = {v0}");
#else
     global::System.FormattableString.Invariant($"AScopedLogEntry: ParentEntityId = {v0}");
#endif
    ;

    state.AddTag("FormattedMessage", formattedMessage);

    return _logger.BeginScope(state);
 }


 [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Purview.Telemetry.SourceGenerator", "0.1.0.0")]
 [global::System.Runtime.CompilerServices.MethodImpl(global::System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)]
 public void LogMessage(int entityId, string updateState)
 {
    if (!_logger.IsEnabled(global::Microsoft.Extensions.Logging.LogLevel.Information))
    {
     return;
    }

    var state = global::Microsoft.Extensions.Logging.LoggerMessageHelper.ThreadLocalState;
    state.ReserveTagSpace(3);

    state.TagArray[0] = new("{OriginalFormat}", "LogMessage: EntityId = {EntityId}, UpdateState = {UpdateState}");
    state.TagArray[1] = new("entityId", entityId);
    state.TagArray[2] = new("updateState", updateState);

    _logger.Log(
     global::Microsoft.Extensions.Logging.LogLevel.Information,
     new (1180592680, nameof(LogMessage)),
     state,
     null,
     [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Purview.Telemetry.SourceGenerator", "0.1.0.0")]
     static string (s, _) =>
     {
    var v0 = s.TagArray[1].Value ?? "(null)";
    var v1 = s.TagArray[2].Value ?? "(null)";

#if NET
    return string.Create(global::System.Globalization.CultureInfo.InvariantCulture, $"LogMessage: EntityId = {v0}, UpdateState = {v1}");
#else
    return global::System.FormattableString.Invariant($"LogMessage: EntityId = {v0}, UpdateState = {v1}");
#endif
     }
    );

    state.Clear();
 }


 [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Purview.Telemetry.SourceGenerator", "0.1.0.0")]
 [global::System.Runtime.CompilerServices.MethodImpl(global::System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)]
 public void ExplicitInfoMessage(int entityId, string updateState)
 {
    if (!_logger.IsEnabled(global::Microsoft.Extensions.Logging.LogLevel.Information))
    {
     return;
    }

    var state = global::Microsoft.Extensions.Logging.LoggerMessageHelper.ThreadLocalState;
    state.ReserveTagSpace(3);

    state.TagArray[0] = new("{OriginalFormat}", "ExplicitInfoMessage: EntityId = {EntityId}, UpdateState = {UpdateState}");
    state.TagArray[1] = new("entityId", entityId);
    state.TagArray[2] = new("updateState", updateState);

    _logger.Log(
     global::Microsoft.Extensions.Logging.LogLevel.Information,
     new (1861353128, nameof(ExplicitInfoMessage)),
     state,
     null,
     [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Purview.Telemetry.SourceGenerator", "0.1.0.0")]
     static string (s, _) =>
     {
    var v0 = s.TagArray[1].Value ?? "(null)";
    var v1 = s.TagArray[2].Value ?? "(null)";

#if NET
    return string.Create(global::System.Globalization.CultureInfo.InvariantCulture, $"ExplicitInfoMessage: EntityId = {v0}, UpdateState = {v1}");
#else
    return global::System.FormattableString.Invariant($"ExplicitInfoMessage: EntityId = {v0}, UpdateState = {v1}");
#endif
     }
    );

    state.Clear();
 }


 [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Purview.Telemetry.SourceGenerator", "0.1.0.0")]
 [global::System.Runtime.CompilerServices.MethodImpl(global::System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)]
 public void ExplicitErrorMessage(int entityId, global::System.Exception exception)
 {
    if (!_logger.IsEnabled(global::Microsoft.Extensions.Logging.LogLevel.Error))
    {
     return;
    }

    var state = global::Microsoft.Extensions.Logging.LoggerMessageHelper.ThreadLocalState;
    state.ReserveTagSpace(2);

    state.TagArray[0] = new("{OriginalFormat}", "An explicit error message. The entity Id is {EntityId}, and the error is {Exception}.");
    state.TagArray[1] = new("entityId", entityId);

    _logger.Log(
     global::Microsoft.Extensions.Logging.LogLevel.Error,
     new (1928434156, nameof(ExplicitErrorMessage)),
     state,
     exception,
     [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Purview.Telemetry.SourceGenerator", "0.1.0.0")]
     static string (s, e) =>
     {
    var v0 = s.TagArray[1].Value ?? "(null)";

#if NET
    return string.Create(global::System.Globalization.CultureInfo.InvariantCulture, $"An explicit error message. The entity Id is {v0}, and the error is {e}.");
#else
    return global::System.FormattableString.Invariant($"An explicit error message. The entity Id is {v0}, and the error is {e}.");
#endif
     }
    );

    state.Clear();
 }

}

Generation v1

//------------------------------------------------------------------------------
// <auto-generated>
//    This code was generated by the Purview.Telemetry.SourceGenerator
//    on {Scrubbed}.
//
//    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

sealed partial class EntityStoreTelemetryCore : global::IEntityStoreTelemetry
{
 readonly global::Microsoft.Extensions.Logging.ILogger<global::IEntityStoreTelemetry> _logger;

 static readonly global::System.Func<global::Microsoft.Extensions.Logging.ILogger, int, global::System.IDisposable?> _aScopedLogEntryAction = global::Microsoft.Extensions.Logging.LoggerMessage.DefineScope<int>("AScopedLogEntry: ParentEntityId = {ParentEntityId}");
 static readonly global::System.Action<global::Microsoft.Extensions.Logging.ILogger, int, string, global::System.Exception?> _logMessageAction = global::Microsoft.Extensions.Logging.LoggerMessage.Define<int, string>(global::Microsoft.Extensions.Logging.LogLevel.Information, new global::Microsoft.Extensions.Logging.EventId(1180592680, "LogMessage"), "LogMessage: EntityId = {EntityId}, UpdateState = {UpdateState}");
 static readonly global::System.Action<global::Microsoft.Extensions.Logging.ILogger, int, string, global::System.Exception?> _explicitInfoMessageAction = global::Microsoft.Extensions.Logging.LoggerMessage.Define<int, string>(global::Microsoft.Extensions.Logging.LogLevel.Information, new global::Microsoft.Extensions.Logging.EventId(1861353128, "ExplicitInfoMessage"), "ExplicitInfoMessage: EntityId = {EntityId}, UpdateState = {UpdateState}");
 static readonly global::System.Action<global::Microsoft.Extensions.Logging.ILogger, int, global::System.Exception?> _explicitErrorMessageAction = global::Microsoft.Extensions.Logging.LoggerMessage.Define<int>(global::Microsoft.Extensions.Logging.LogLevel.Error, new global::Microsoft.Extensions.Logging.EventId(1928434156, "ExplicitErrorMessage"), "An explicit error message. The entity Id is {EntityId}, and the error is {Exception}.");

 [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Purview.Telemetry.SourceGenerator", "0.1.0.0")]
 [global::System.Runtime.CompilerServices.MethodImpl(global::System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)]
 public global::System.IDisposable? AScopedLogEntry(int parentEntityId)
 {
    return _aScopedLogEntryAction(_logger, parentEntityId);
 }


 [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Purview.Telemetry.SourceGenerator", "0.1.0.0")]
 [global::System.Runtime.CompilerServices.MethodImpl(global::System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)]
 public void LogMessage(int entityId, string updateState)
 {
    if (!_logger.IsEnabled(global::Microsoft.Extensions.Logging.LogLevel.Information))
    {
     return;
    }

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


 [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Purview.Telemetry.SourceGenerator", "0.1.0.0")]
 [global::System.Runtime.CompilerServices.MethodImpl(global::System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)]
 public void ExplicitInfoMessage(int entityId, string updateState)
 {
    if (!_logger.IsEnabled(global::Microsoft.Extensions.Logging.LogLevel.Information))
    {
     return;
    }

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


 [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Purview.Telemetry.SourceGenerator", "0.1.0.0")]
 [global::System.Runtime.CompilerServices.MethodImpl(global::System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)]
 public void ExplicitErrorMessage(int entityId, System.Exception exception)
 {
    if (!_logger.IsEnabled(global::Microsoft.Extensions.Logging.LogLevel.Error))
    {
     return;
    }

    _explicitErrorMessageAction(_logger, entityId, exception);
 }

}

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 {Scrubbed}.
//
//    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

[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Purview.Telemetry.SourceGenerator", "0.1.0.0")]
sealed partial class EntityStoreTelemetryCore : global::IEntityStoreTelemetry
{
 global::System.Diagnostics.Metrics.Meter _meter = default!;

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

 [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Purview.Telemetry.SourceGenerator", "0.1.0.0")]
 public EntityStoreTelemetryCore(global::Microsoft.Extensions.Logging.ILogger<global::IEntityStoreTelemetry> logger, global::System.Diagnostics.Metrics.IMeterFactory meterFactory)
 {
    _logger = logger;
    InitializeMeters(meterFactory);
 }

 [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Purview.Telemetry.SourceGenerator", "0.1.0.0")]
 [global::System.Runtime.CompilerServices.MethodImpl(global::System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)]
 void InitializeMeters(global::System.Diagnostics.Metrics.IMeterFactory meterFactory)
 {
    if (_meter != null)
    {
     throw new global::System.Exception("The meters have already been initialized.");
    }

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

    PopulateMeterTags(meterTags);

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

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

    PopulateRetrievingEntityTags(retrievingEntityTags);

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

 [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Purview.Telemetry.SourceGenerator", "0.1.0.0")]
 partial void PopulateMeterTags(global::System.Collections.Generic.Dictionary<string, object?> meterTags);

 [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Purview.Telemetry.SourceGenerator", "0.1.0.0")]
 partial void PopulateRetrievingEntityTags(global::System.Collections.Generic.Dictionary<string, object?> instrumentTags);

 [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Purview.Telemetry.SourceGenerator", "0.1.0.0")]
 [global::System.Runtime.CompilerServices.MethodImpl(global::System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)]
 public void RetrievingEntity(int entityId)
 {
    if (_retrievingEntityInstrument == null)
    {
     return;
    }

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

    retrievingEntityTagList.Add("entityid", entityId);

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

Dependency Injection Output

//------------------------------------------------------------------------------
// <auto-generated>
//    This code was generated by the Purview.Telemetry.SourceGenerator
//    on {Scrubbed}.
//
//    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
{
 [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Purview.Telemetry.SourceGenerator", "0.1.0.0")]
 [global::System.ComponentModel.EditorBrowsable(global::System.ComponentModel.EditorBrowsableState.Never)]
 static class EntityStoreTelemetryCoreDIExtension
 {
    [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Purview.Telemetry.SourceGenerator", "0.1.0.0")]
    [global::System.Runtime.CompilerServices.MethodImpl(global::System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)]
    public static global::Microsoft.Extensions.DependencyInjection.IServiceCollection AddEntityStoreTelemetry(this global::Microsoft.Extensions.DependencyInjection.IServiceCollection services)
    {
     return services.AddSingleton<global::IEntityStoreTelemetry, global::EntityStoreTelemetryCore>();
    }
 }
}

Clone this wiki locally