0

I am trying to use Serilog with Application Insights sink for logging purposes. I can see the logs in Search bar in Azure Portal (Application Insights) but same logs are not visible if we view the timeline of events in Failures or Performance Tab. Thanks

Below is the code am using for registering Logger in FunctionStartup, which then gets injected in Function for logging:

var logger = new LoggerConfiguration()
                               .Enrich.FromLogContext()
                               .Enrich.WithProperty("ApplicationName", "testApp")
                               .Enrich.WithProperty("Environment", "Dev")                               
                               .WriteTo.ApplicationInsights(GetTelemetryClient("Instrumentationkey"), TelemetryConverter.Traces)
                               .CreateLogger();
builder.Services.AddSingleton<ILogger>(logger);

Telementory Client is getting fetched from a helper method:

public static TelemetryClient GetTelemetryClient(string key)
        {
            var teleConfig = new TelemetryConfiguration { InstrumentationKey = key };

            var teleClient = new TelemetryClient(teleConfig);

            return teleClient;
        }

host.json

{
    "version": "2.0",
    "logging": {
        "applicationInsights": {
            "samplingExcludedTypes": "Request",
            "samplingSettings": {
                "isEnabled": true
            }
        }
    }
}
Ahmed
  • 1
  • 2
  • WriteTo.ApplicationInsights(..., **elemetryConverter.Traces**), this means the logs all be write to traces, so you can't see in failure certainly. – Tiny Wang Jun 02 '21 at 02:26
  • Yes, the logs are getting into traces but are not visible in failures timeline – Ahmed Jun 03 '21 at 07:14
  • What's the **failures timeline** ? Failure blade in application insights? – Tiny Wang Jun 03 '21 at 07:19
  • yes the Failure blade, which shows a timeline/telemetry of logs as well, that has these custom traces and other exceptions. – Ahmed Jun 03 '21 at 10:17
  • Per my testing, after I set WriteTo.ApplicationInsights`, and my app meet an exception, application insights can capture it in this format. Dose it the timeline you mean? https://i.stack.imgur.com/7EQ5n.png – Tiny Wang Jun 04 '21 at 01:53
  • Yes this timeline, but if you use serilog for logging and then add any custom information within the flow before exception, and see if that information is visible in timeline – Ahmed Jun 08 '21 at 08:25
  • Hmmm, how about switch to `Transaction search` to see the whole timeline? That blade contains all the log information. – Tiny Wang Jun 08 '21 at 08:39
  • I can see the information in Transcation Search, all of the logs either custom or system generated. But same logs with custom information are missing in Failure and Performance Blade. I need to see the logs in order to debug a certain exception or view the Performance sequences – Ahmed Jun 09 '21 at 07:10

3 Answers3

1

I got your mean, and pls allow me to sum up my testing result here.

First, the failure blade is not designed for providing a timeline which used to trace the details(what happened before the exception take place), but to show all the exceptions, how often the error happened, how many users be affected, etc, it's more likely stand in a high place to see the whole program.

And to achieve your goal, I think you can use this kql query in the Logs blade or watching it in transaction blade.

union traces, requests,exceptions
| where operation_Id == "178845c426975d4eb96ba5f7b5f376e1"

enter image description here Basically, we may add many logs in the executing chain, e.g. in the controller, log the input parameter, then log the result of data combining or formatting, log the exception information in catch, so here's my testing code. I can't see any other information in failure blade as you, but in the transaction blade, I can see the timeline.

public class HelloController : Controller
    {
        public string greet(string name)
        {
            Log.Verbose("come to greet function");
            Log.Debug("serilog_debug_info");
            Log.Information("greet name input " + name);
            int count = int.Parse(name);
            Log.Warning("enter greet name is : {0}", count);
            return "hello " + name;
        }
    }

enter image description here

And we can easily find that, the whole chain shares the same operationId, and via all these logs, we can pinpoint the wrong line code. By the way, if I surround the code with try/catch, exception won't be captured in the failure blade.

==================================

Using Serilog integrate app insights, we need to send serilog to application insights, and we will see lots of Traces in transaction search, so it's better to made the MinimumLevel to be information and higher. The sreenshot below is my log details, and we can also use kql query by operationId to see the whole chain.

enter image description here

Tiny Wang
  • 10,423
  • 1
  • 11
  • 29
  • Can you please try Integrating Serilog with Application Insights in the above code, and then try log information? Also in terms of information, i used to see all the logs either custom or not. But something is either updated in Azure or .NET may be that is not showing the information in Failures blade rather than just in Transaction Seach – Ahmed Jun 09 '21 at 10:33
  • I tested in my side, I can see more log information when using serilog, but they still contains the whole execute chain. – Tiny Wang Jun 10 '21 at 05:56
  • Can you please share snippet where you are integrating Serilog with application insights in code? Also is there anything in your host.json? – Ahmed Jun 10 '21 at 08:53
  • Per my testing, that's true app insights can't track trace in function. It seems a bug, see https://stackoverflow.com/a/52717627/14574199 – Tiny Wang Jun 11 '21 at 06:38
0

You can easily solve this by following the solution provided by Azure Application Insights on their GitHub repo, as per this Github Issue, you can either use the DI to configure TelemetryConfiguration, i.e

services.Configure<TelemetryConfiguration>(
 (o) => {
   o.InstrumentationKey = "123";
   o.TelemetryInitializers.Add(new OperationCorrelationTelemetryInitializer());
 });

or you can configure it manually like this:

var config = TelemetryConfiguration.CreateDefault();
var client = new TelemetryClient(config);

So in your code, you have to change your GetTelemetryClient from

public static TelemetryClient GetTelemetryClient(string key)
    {
        var teleConfig = new TelemetryConfiguration { InstrumentationKey = key };

        var teleClient = new TelemetryClient(teleConfig);

        return teleClient;
    }

to this

public static TelemetryClient GetTelemetryClient(string key)
    {
        var teleConfig = TelemetryConfiguration.CreateDefault();

        var teleClient = new TelemetryClient(teleConfig);

        return teleClient;
    }
Shabir jan
  • 2,295
  • 2
  • 23
  • 37
0

In order to use logging using Telemetry Configuration as mentioned in the answer above for Azure Functions, we just need to update the function as in below snippet and on deployment it should fetch Instrumentation key itself

public static TelemetryClient GetTelemetryClient()
 {
   var teleConfig = TelemetryConfiguration.CreateDefault();
    
   var teleClient = new TelemetryClient(teleConfig);
    
   return teleClient;
 }

But to run both locally and after deployment on Azure. We need to add something like this in function Startup and get rid of the Function above.

builder.Services.Configure<TelemetryConfiguration>((o) =>
                {
                   o.InstrumentationKey = "KEY";
                   o.TelemetryInitializers.Add(new OperationCorrelationTelemetryInitializer());
                });
        
builder.Services.AddSingleton<ILogger>(sp =>
                {
                var logger = new LoggerConfiguration()
                 .Enrich.FromLogContext()
                 .Enrich.WithProperty("ApplicationName", "TEST")
                 .Enrich.WithProperty("Environment", "DEV")
                 .WriteTo.ApplicationInsights( 
        
                 sp.GetRequiredService<TelemetryConfiguration>(), TelemetryConverter.Traces).CreateLogger(); 
        
                 return logger;
               });

After wards we just need to use typical DI in our classes/azure function to use ILogger

public class Test{
      public ILogger _log;
      public void Test(ILogger log){
        _log=log;
      }
   }
Ahmed
  • 1
  • 2