RSCG – Microsoft.Extensions.Logging

RSCG – Microsoft.Extensions.Logging
 
 

name Microsoft.Extensions.Logging
nuget https://www.nuget.org/packages/Microsoft.Extensions.Logging/
link https://learn.microsoft.com/en-us/dotnet/core/extensions/logger-message-generator-generators/
author Microsoft

Logging defined and compiled

 

This is how you can use Microsoft.Extensions.Logging .

The code that you start with is


<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>
    <OutputType>Exe</OutputType>
    <TargetFramework>net7.0</TargetFramework>
    <ImplicitUsings>enable</ImplicitUsings>
    <Nullable>enable</Nullable>
  </PropertyGroup>
	<PropertyGroup>
        <EmitCompilerGeneratedFiles>true</EmitCompilerGeneratedFiles>
        <CompilerGeneratedFilesOutputPath>$(BaseIntermediateOutputPath)\GeneratedX</CompilerGeneratedFilesOutputPath>
    </PropertyGroup>
	<ItemGroup>
		<PackageReference Include="Microsoft.Extensions.Logging.Console" Version="7.0.0" />
	</ItemGroup>
</Project>


The code that you will use is


using System.Text.Json;
using Microsoft.Extensions.Logging;

using ILoggerFactory loggerFactory = LoggerFactory.Create(
    builder =>
    //https://learn.microsoft.com/en-us/dotnet/core/extensions/console-log-formatter
    builder.AddSimpleConsole()
    //builder.AddJsonConsole(
    //    options =>
    //    options.JsonWriterOptions = new JsonWriterOptions()
    //    {
    //        Indented = true
    //    })
    ) ;

ILogger<SampleObject> logger = loggerFactory.CreateLogger<SampleObject>();
logger.LogInformation("test");
//https://learn.microsoft.com/en-us/dotnet/core/extensions/logger-message-generator
(new LoggingSample(logger)).TestLogging();
file readonly record struct SampleObject { }



using Microsoft.Extensions.Logging;

public partial class LoggingSample
{
    private readonly ILogger _logger;

    public LoggingSample(ILogger logger)
    {
        _logger = logger;
    }

    [LoggerMessage(
        EventId = 20,
        Level = LogLevel.Critical,
        Message = "Value is {value:E}")]
    public static partial void UsingFormatSpecifier(
        ILogger logger, double value);

    [LoggerMessage(
        EventId = 9,
        Level = LogLevel.Trace,
        Message = "Fixed message",
        EventName = "CustomEventName")]
    public partial void LogWithCustomEventName();

    [LoggerMessage(
        EventId = 10,
        Message = "Welcome to {city} {province}!")]
    public partial void LogWithDynamicLogLevel(
        string city, LogLevel level, string province);

    public void  TestLogging()
    {
        LogWithCustomEventName();

        LogWithDynamicLogLevel("Vancouver", LogLevel.Warning, "BC");
        LogWithDynamicLogLevel("Vancouver", LogLevel.Information, "BC");

        UsingFormatSpecifier(_logger, 12345.6789);
    }
}

 

The code that is generated is

// <auto-generated/>
#nullable enable

    partial class LoggingSample
    {
        [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Extensions.Logging.Generators", "7.0.7.1805")]
        private static readonly global::System.Action<global::Microsoft.Extensions.Logging.ILogger, global::System.Double, global::System.Exception?> __UsingFormatSpecifierCallback =
            global::Microsoft.Extensions.Logging.LoggerMessage.Define<global::System.Double>(global::Microsoft.Extensions.Logging.LogLevel.Critical, new global::Microsoft.Extensions.Logging.EventId(20, nameof(UsingFormatSpecifier)), "Value is {value:E}", new global::Microsoft.Extensions.Logging.LogDefineOptions() { SkipEnabledCheck = true }); 

        [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Extensions.Logging.Generators", "7.0.7.1805")]
        public static partial void UsingFormatSpecifier(global::Microsoft.Extensions.Logging.ILogger logger, global::System.Double value)
        {
            if (logger.IsEnabled(global::Microsoft.Extensions.Logging.LogLevel.Critical))
            {
                __UsingFormatSpecifierCallback(logger, value, null);
            }
        }
        [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Extensions.Logging.Generators", "7.0.7.1805")]
        private static readonly global::System.Action<global::Microsoft.Extensions.Logging.ILogger, global::System.Exception?> __LogWithCustomEventNameCallback =
            global::Microsoft.Extensions.Logging.LoggerMessage.Define(global::Microsoft.Extensions.Logging.LogLevel.Trace, new global::Microsoft.Extensions.Logging.EventId(9, "CustomEventName"), "Fixed message", new global::Microsoft.Extensions.Logging.LogDefineOptions() { SkipEnabledCheck = true }); 

        [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Extensions.Logging.Generators", "7.0.7.1805")]
        public partial void LogWithCustomEventName()
        {
            if (_logger.IsEnabled(global::Microsoft.Extensions.Logging.LogLevel.Trace))
            {
                __LogWithCustomEventNameCallback(_logger, null);
            }
        }
        /// <summary> This API supports the logging infrastructure and is not intended to be used directly from your code. It is subject to change in the future. </summary>
        [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Extensions.Logging.Generators", "7.0.7.1805")]
        [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Never)]
        private readonly struct __LogWithDynamicLogLevelStruct : global::System.Collections.Generic.IReadOnlyList<global::System.Collections.Generic.KeyValuePair<string, object?>>
        {
            private readonly global::System.String _city;
            private readonly global::System.String _province;

            public __LogWithDynamicLogLevelStruct(global::System.String city, global::System.String province)
            {
                this._city = city;
                this._province = province;

            }

            public override string ToString()
            {
                var city = this._city;
                var province = this._province;

                return $"Welcome to {city} {province}!";
            }

            public static readonly global::System.Func<__LogWithDynamicLogLevelStruct, global::System.Exception?, string> Format = (state, ex) => state.ToString();

            public int Count => 3;

            public global::System.Collections.Generic.KeyValuePair<string, object?> this[int index]
            {
                get => index switch
                {
                    0 => new global::System.Collections.Generic.KeyValuePair<string, object?>("city", this._city),
                    1 => new global::System.Collections.Generic.KeyValuePair<string, object?>("province", this._province),
                    2 => new global::System.Collections.Generic.KeyValuePair<string, object?>("{OriginalFormat}", "Welcome to {city} {province}!"),

                    _ => throw new global::System.IndexOutOfRangeException(nameof(index)),  // return the same exception LoggerMessage.Define returns in this case
                };
            }

            public global::System.Collections.Generic.IEnumerator<global::System.Collections.Generic.KeyValuePair<string, object?>> GetEnumerator()
            {
                for (int i = 0; i < 3; i++)
                {
                    yield return this[i];
                }
            }

            global::System.Collections.IEnumerator global::System.Collections.IEnumerable.GetEnumerator() => GetEnumerator();
        }

        [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Extensions.Logging.Generators", "7.0.7.1805")]
        public partial void LogWithDynamicLogLevel(global::System.String city, global::Microsoft.Extensions.Logging.LogLevel level, global::System.String province)
        {
            if (_logger.IsEnabled(level))
            {
                _logger.Log(
                    level,
                    new global::Microsoft.Extensions.Logging.EventId(10, nameof(LogWithDynamicLogLevel)),
                    new __LogWithDynamicLogLevelStruct(city, province),
                    null,
                    __LogWithDynamicLogLevelStruct.Format);
            }
        }
    }

Code and pdf at

https://ignatandrei.github.io/RSCG_Examples/v2/docs/Microsoft.Extensions.Logging