.NET Core event logging in Kentico Xperience 13

08/02/2021

When Kentico Xperience 13 was launched, we gained the ability to build websites using ASP.NET Core 😁.  Behind the scenes, a lot of Xperience's core libraries had to be rewritten and migrated, so that they were compatible with .NET Core.

When creating a new Xperience site using .NET Core, you'll need to ensure you are registering the services correctly in the application's Startup class.

Event logging in .NET Core

One of the features introduced by the AddKentico() service is the KenticoEventLog logger.  This logger introduces the ability to log events from the .NET Core website, and displays them in the Event Log module within the admin site.  You can log error messages, exceptions, warnings or even just debug information to assist with troubleshooting problems.  The logger itself is built using the .NET Core logging API, so it should be easy to use and recognisable by ASP.NET Core developers.

However, this is where we hit a problem - the current implementation of the KenticoEventLog logger doesn't appear to fully recognise values set in the website appsettings.json like it should.  Lets explore this in more detail!

Scenario 1 - default setup

Lets take a look at the default appsettings.json for the base .NET Core site provided by the installer (or the Dancing Goat sample site), it should look something like this:

{
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft": "Warning",
      "Microsoft.Hosting.Lifetime": "Information"
    },
    "KenticoEventLog": {
      "LogLevel": {
        "Default": "Error",
        "Microsoft.AspNetCore.Server.Kestrel": "None"
      }
    }
  },
  "AllowedHosts": "*",
  "CMSHashStringSalt": "5a9755b0-10a7-442a-99aa-2d754b1e71ee",
  "ConnectionStrings": {
    "CMSConnectionString": "Data Source=localhost;Initial Catalog=Kentico13Blank;Integrated Security=True;Persist Security Info=False;Connect Timeout=60;Encrypt=False;Current Language=English;"
  },
  "CMSCIRepositoryPath": "D:\\Projects\\liamgold\\K13\\Kentico13\\CMS\\App_Data\\CIRepository"
}

The above code block suggests that the logger should only be logging Error level events or above, which is great - it's probably the right setting for most setups and you might not even want to change this.  But interestingly with this configuration, the logger still logs Information level events even though they are lower in severity.  Shouldn't the logger ignore Information level events here? 🤔

Scenario 2 - disable all logging

We could even try taking this one step further, if we set the log level to None then the logger should effectively be disabled.  All of the log levels below would be ignored and we shouldn't be getting any debug, information, events or exceptions logged.  Lets try this with the following appsettings.json configuration:

{
  "Logging": {
    "LogLevel": {
      "Default": "None",
      "Microsoft": "None",
      "Microsoft.Hosting.Lifetime": "None"
    },
    "KenticoEventLog": {
      "LogLevel": {
        "Default": "None",
        "Microsoft.AspNetCore.Server.Kestrel": "None"
      }
    }
  },
  "AllowedHosts": "*",
  "CMSHashStringSalt": "5a9755b0-10a7-442a-99aa-2d754b1e71ee",
  "ConnectionStrings": {
    "CMSConnectionString": "Data Source=localhost;Initial Catalog=Kentico13Blank;Integrated Security=True;Persist Security Info=False;Connect Timeout=60;Encrypt=False;Current Language=English;"
  },
  "CMSCIRepositoryPath": "D:\\Projects\\liamgold\\K13\\Kentico13\\CMS\\App_Data\\CIRepository"
}

After calling the different event logger API methods, the end result is: 

Event log showing the exception captured

So even if we disable all logging, the logger still logs everything done through the API.  Interesting! 🤔

Scenario 3 - try different levels?

At this point I am starting to assume this is expected functionality by Xperience.  Have I misunderstood the .NET Core logging API and the respective log levels?  Has the Xperience team made a decision to ignore the level set and to log everything?  Is it a bug in their implementation?

Out of curiosity, I decided to try out all of the .NET Core logging levels - here are my findings:

  • Trace (Level 0) - breaks Page Builder, and logs all levels to error log.
  • Debug (Level 1) - breaks Page Builder, and logs all levels to error log.
  • Information (Level 2) - breaks Page Builder, and logs all levels to error log.
  • Warning (Level 3) - logs all levels to error log.
  • Error (Level 4) - logs all levels to error log.
  • Critical (Level 5) - logs all levels to error log.
  • None (Level 6) - logs all levels to error log.

Something I didn't expect when lowering the log level (e.g. Trace, Debug, and Information), was that the Page Builder would break entirely when visiting the page tab.  Instead you are greeted with an error message InvalidOperationException: User is not authorized to modify current page.

Error displayed for an unauthorised user

This is something I saw last week on Ryan Overton's Twitch stream.  If you haven't already - then do check out his streams, they're a great way of getting involved and learning more about Kentico Xperience! 👍

With all this in mind, my current recommendation would be to leave the log level as the default value of Error.  This will ensure your event logging is working correctly, and won't affect the page builder.  I guess it's time to discuss this with Kentico Support 👀


UPDATE!

After lengthy discussions with Kentico Support, Kentico have now suggested that although the API is built using conventional .NET Core logging API, it does not support the use of IEventLogService.

However, they have confirmed that the page builder breaking in Scenario 3 is a bug and will be hotfixed in 13.0.17 - great result! 😎🎉