Base solution for your next web application
Open Closed

Use Application Insights with ANZ #11312


0
cangunaydin created

Hello, I am trying to use application insights inside ANZ project. But i couldn't make it work with ILogger. Whatever i log with ILogger injection, is not logged to application insights. Here is what i have done so far. 1- Added nuget packages from ApplicationInsights to web.host project

    <PackageReference Include="Microsoft.ApplicationInsights.AspNetCore" Version="2.21.0" />
    <PackageReference Include="Microsoft.ApplicationInsights.Log4NetAppender" Version="2.21.0" />

2- I have added extra appender to my log4net file.

<?xml version="1.0" encoding="utf-8" ?>
<log4net>
  <appender name="RollingFileAppender" type="log4net.Appender.RollingFileAppender" >
    <file type="log4net.Util.PatternString" value="%property{LoggerFilePath}/App_Data/Logs/Logs.txt" />
    <!--<file value="../../../App_Data/Logs/Logs.txt" />-->
    <appendToFile value="true" />
    <rollingStyle value="Size" />
    <maxSizeRollBackups value="10" />
    <maximumFileSize value="10000KB" />
    <staticLogFileName value="true" />
    <layout type="log4net.Layout.PatternLayout">
      <conversionPattern value="%-5level %date [%-5.5thread] %-40.40logger - %message%newline" />
    </layout>
  </appender>
  <appender name="ApplicationInsightsAppender" type="Microsoft.ApplicationInsights.Log4NetAppender.ApplicationInsightsAppender, Microsoft.ApplicationInsights.Log4NetAppender">
    <layout type="log4net.Layout.PatternLayout">
      <conversionPattern value="%message %newline" />
    </layout>
  </appender>
  <root>
    <appender-ref ref="RollingFileAppender" />
    <appender-ref ref="ApplicationInsightsAppender"/>
    <level value="DEBUG" />
  </root>
</log4net>

3- Change the Program.cs (this step is not really relevant, i am trying to support both application insights and file log on azure. Since azure portal does not allow writing to file inside root folder, i give the path to write from appsettings.json)

 .ConfigureLogging((context, logging) =>
                {
                    logging.AddFilter("Microsoft.EntityFrameworkCore.Database.Command", LogLevel.Error);
                    var hostingEnvironment = context.HostingEnvironment;
                    var configurationRoot = hostingEnvironment.GetAppConfiguration();
                    var defaultRootPath = hostingEnvironment.IsDevelopment() ?
                        "../../../" : "";
                    log4net.GlobalContext.Properties["LoggerFilePath"] = defaultRootPath;

                    var log4NetFilePath = configurationRoot["Log4Net:Path"];
                    if (!string.IsNullOrEmpty(log4NetFilePath))
                        log4net.GlobalContext.Properties["LoggerFilePath"] = log4NetFilePath;
                })

4- Configure application insights on web host module.

public IServiceProvider ConfigureServices(IServiceCollection services)
        {
            //some code above
            if (bool.Parse(_appConfiguration["ApplicationInsights:ApplicationInsightsEnabled"]))
            {
                services.AddApplicationInsightsTelemetry(new ApplicationInsightsServiceOptions
                {
                    ConnectionString = _appConfiguration["ApplicationInsights:ConnectionString"],
                    EnableActiveTelemetryConfigurationSetup = true
                });
            }
            //some code below
            }

5- here is my appsettings.json

  "ApplicationInsights": {
    "ApplicationInsightsEnabled": true,
    "ConnectionString": "InstrumentationKey=..."
  },
  "Log4Net": {
    "Path": ""
  },

When i try to inject ILogger and use that instance, i can see it on file but not on application insights only thing i have seen on app insights are Ef Core warnings and some parts i would never use.

so my question is, if there is any way logging into app insights with Logger.Warn() or Logger.Error(), and how can i remove ef core warnings?

 public async Task TestApplicationInsights()
        {
            Logger.Error("Application Insights test from Logger....",new Exception("this is custom exception"));
            _logger.Error("Application Insights by injection ILogger....", new InvalidOperationException("this is invalid operation exception"));
        }

Thank you for the assistance.


4 Answer(s)
  • 0
    ismcagdas created
    Support Team

    Hi,

    Your config totally seems fine. Could you check if this helps https://stackoverflow.com/a/65401502 ?

  • 0
    cangunaydin created

    Hello @ismcagdas Not really helped. Actually i realize that if i log it by using ilogger in application layer or in controller, i can see it in application insights, but background job and background worker errors are not logged at all (I am using Hangfire for it.) What i couldn't understand is, i can see the hangfire errors on text file that i append to azure appservice root folder. They both use log4net, why fileappender can do it but not application insights appender? I really couldn't grasp it. Do you have any idea?

  • 0
    ismcagdas created
    Support Team

    Hi,

    Do you run the background jobs on your web app ?

  • 0
    cangunaydin created

    Hello again, I was trying couple of things to be sure about the problem. I make it work by doing couple of things. First of all i need to state that i am using hangfire on my app. Since hangfire is polling the database i see lots of dependency logs, so to fix that issue i have implemented custom telemetry processor. This stackoverflow link was helpful for that https://stackoverflow.com/questions/38320886/app-insights-disable-sql-dependency-telemetry

    using Microsoft.ApplicationInsights.Channel;
    using Microsoft.ApplicationInsights.Extensibility;
    using Microsoft.ApplicationInsights.DataContracts;
    
    public class NoSQLDependencies : ITelemetryProcessor
    {
        private ITelemetryProcessor Next { get; set; }
    
        // Link processors to each other in a chain.
        public NoSQLDependencies(ITelemetryProcessor next)
        {
            this.Next = next;
        }
        public void Process(ITelemetry item)
        {
            if (IsSQLDependency(item)) { return; }
            this.Next.Process(item);
        }
    
        private bool IsSQLDependency(ITelemetry item)
        {
            var dependency = item as DependencyTelemetry;
            if (dependency?.DependencyTypeName == "SQL")
            {
                return true;
            }
            return false;
        }
    }
    

    Afterwards I explicitly configured Hangfire to use Log4net by this code inside WebHostModule PreInitialize()

    GlobalConfiguration.Configuration.UseLog4NetLogProvider();
    

    now everythings work fine on my local machine. There is only one thing left i couldn't understand. if you look at the code below.

        public class TestAppService : BookAndAdAppServiceBase
        {
            private readonly IBackgroundJobManager _backgroundJobManager;
    
            private readonly ILogger _logger;
            public TestAppService(IBackgroundJobManager backgroundJobManager, ILogger logger)
            {
                _backgroundJobManager = backgroundJobManager;
                _logger = logger;
            }
    
            public async Task TestLogger()
            {
                Logger.Error($"Application Insights test from {nameof(TestAppService)}....", new Exception("this is custom exception"));
                _logger.Error($"Application Insights test with reference (can2) {nameof(TestAppService)}");
                await _backgroundJobManager.EnqueueAsync<TestJob, TestJobArgs>(new TestJobArgs() { TenantId = AbpSession.TenantId,UserId=AbpSession.UserId },delay:TimeSpan.FromSeconds(10));
            }
        }
    

    as you can see first logger is logging with exception, and this is coming to application insights as exception which is expected. On the other hand second logger since it doesn't pass any exception it is logged as Trace. Which at first sight seems weird since i call Error() method. But anyway it works fine, i think we can close this.