azure.net-corelog4netazure-application-insightsloggerfactory

Customize log messages using Loggerfactory in .net core application


I have two console applications, one created in .Net framework 4.6. And other one in .net core 2.0. For logging, in .Net framework I'm using log4Net, in .net core I'm using Logger. This logger directly writes into Application Insights directly in Azure.

Now my question is, how to customize the logging messages using Logger. In log4Net, I have used aiappender and defined a conversion pattern based on my requirement. For example:

<appender name="aiAppender" type="Microsoft.ApplicationInsights.Log4NetAppender.ApplicationInsightsAppender, Microsoft.ApplicationInsights.Log4NetAppender">
    <layout type="log4net.Layout.PatternLayout">
      <parameterName value="@Extra"/>      
        <conversionPattern value="%date{dd/MM/yy HH:mm:ss} [%thread] %level  :: Extra = %property{Extra} %message%newline"   />
    </layout>
</appender> 

I have written this in the log4net.config and assigned values to Extra variable as below.

log4net.GlobalContext.Properties["Extra"] = "SomeValue";

I want to do the similar customization for Logger in .Net core. This the sample code I have:

public class Startup
{
    public Startup()
    {
    } 
     public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
    {

        loggerFactory.AddConsole();
        var logger = loggerFactory.CreateLogger<ConsoleLogger>();
        logger.LogInformation("Executing Configure()");
    }
}

public class HomeController : Controller
{
    ILogger _logger;

    public HomeController(ILogger<HomeController> logger)
    {
        _logger = logger;
    }
    public IActionResult Index()
    {
        _logger.LogInformation("Executing Home/Index");

        return View();
    } 
}

In this code, if I want extra information similar to Log4Net pattern, how do I do it?

PS: I cannot change from logger to log4Net, as in reality the code is pretty big. Also I do not want to append the required information every time I'm logging some data.


Solution

  • You can use a telemetry initializer to add extra properties to all telemetry items, or to modify existing properties:

    public class CustomInitializer : ITelemetryInitializer
    {
        public void Initialize(ITelemetry telemetry)
        {
            // modify trace message
            if (telemetry is TraceTelemetry trace)
                trace.Message = $"Modified Message: {trace.Message}"; 
    
            if (!(telemetry is ISupportProperties supportedTelemetry))
                return;
    
            // add custom property
            supportedTelemetry.Properties["MyProp"] = "MyValue";
        }
    }
    

    Add it to your services:

        // This method gets called by the runtime. Use this method to add services to the container.
        public void ConfigureServices(IServiceCollection services)
        {
            services.AddSingleton<ITelemetryInitializer, CustomInitializer>();
            services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
        }
    

    and make sure the Ilogger output is directed to App Insights:

        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
        public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }
    
            loggerFactory.AddApplicationInsights(app.ApplicationServices, LogLevel.Trace);
    
            app.UseMvc();
        }