Monday, August 31, 2015

Umbraco errorlogging with Loggly

Service

At a client I'm currently working at we use GrayLog as our default logging system. This is an open source log management tool that offers a lot of features but for me has one major bottleneck. It requires you to setup a (virtual) server to host this service. While that's perfectly fine for bigger project, it's rather unachievable for little project or proof of concepts that demand centralized logging.

For those small project I wanted to investigate an alternative. I've selected Loggly for my test. This is a commercial cloud log management service that offers a free account that is limited to 200mb a day and 7-day retention. That's fine for me, let's integrate!

NuGet package

 I started this test by downloading Umbraco 7.3.0RC since this version will be released very soon now. As a second package I installed the Loggly log4net package that offers a Log4Net appender that will send out the errormesages to Loggly.

Finished !

Except that Umbraco uses an unsigned version of log4net 1.2.11.0 and Loggly requires a signed 1.2.13.0 version. This would be solvable using assembly binding redirect in the web.config if the appender would be compatible with log4net, but that's not the case. Umbraco will solve this in version 8 due to breaking changes (U4-1324).

Second try

The easiest way of fixing this issue was to download the Loggly appender sources that are available at GitHub and build this solution with the log4net (and Newtonsoft.Json) assemblies referenced from the Umbraco solution. There is only one incompatibility to get rid of. In log4net version 1.2.11.0 the threadcontext property keys are not available yet, but since Umbraco also cannot access them I just disable this bit of logging all the way.






After this I referenced the newly build appender to my Umbraco solution and added the configuration to the default log4net.config

<?xml version="1.0"?>
<log4net>
  
  <root>
    <priority value="DEBUG"/>
    <appender-ref ref="AsynchronousLog4NetAppender" />
    <appender-ref ref="LogglyAppender" />
  </root>

  <appender name="rollingFile" type="log4net.Appender.RollingFileAppender">
    <file value="App_Data\Logs\UmbracoTraceLog.txt" />
    <lockingModel type="log4net.Appender.FileAppender+MinimalLock" />
    <appendToFile value="true" />
    <rollingStyle value="Date" />
    <maximumFileSize value="5MB" />
    <layout type="log4net.Layout.PatternLayout">
      <conversionPattern value=" %date [P%property{processId}/D%property{appDomainId}/T%thread] %-5level %logger - %message%newline" />
    </layout>
    <encoding value="utf-8" />
  </appender>

  <appender name="LogglyAppender" type="log4net.loggly.LogglyAppender, log4net-loggly">
    <rootUrl value="http://logs-01.loggly.com/" />
    <inputKey value="[your token]" />
    <tag value="log4net" />
  </appender>

  <appender name="AsynchronousLog4NetAppender" type="Umbraco.Core.Logging.ParallelForwardingAppender,Umbraco.Core">
    <appender-ref ref="rollingFile" />
  </appender>

  <!--Here you can change the way logging works for certain namespaces  -->

  <logger name="NHibernate">
    <level value="WARN" />
  </logger>
  
</log4net>

And voila, we're logging to Loggly !!

Loggly

Let's check it out and add a dummy exception to the master view. After logging into Loggly I can now see my error messages (beside all the other messages within my defined log level of course).




4 comments:

  1. Going to be implementing this tomorrow. Exactly what I needed - thanks!

    ReplyDelete
  2. Bart, thanks for the great tip and guide on centralizing Umbraco logging.

    Regarding the log4net version conflict, we had an Umbraco site that used a third party library with a dependency on its own version of log4net. We were able to resolve it without recompiling by creating a sub-directory for one of the log4net files and using assembly binding. The details are described in this forum post:

    https://our.umbraco.org/forum/developers/extending-umbraco/45996-log4net-public-token-issues-could-not-load-file-or-assembly

    Dallas

    ReplyDelete
  3. Implemented nicely and without too much difficulty. Awesome toolkit!

    ReplyDelete