Save Log4Net in a Database

Adding your Log4Net logging info into your DNN database will provide you with more flexibility, reporting and security options for accessing critical application data.

  • Posted on Jun 07, 2016

Log4Net is a great framework from Apache that is used for outputting logging information to a variety of targets in a .NET application.

In DNN, Log4Net is built-in to the platform and is an excellent troubleshooting resource. By default, DNN is configured to store the logs as a flat file in the /portals/_default/logs/ folder. This setup can be changed by modifying the DotNetNuke.log4net.config file located in the root folder of the application.

I've found that having the flat file is perfectly fine for some scenarios, however, when you want to grant multiple users access to the data but not necessarily grant them access to the application folders/files then saving the information into a database is much more versatile solution.

There are 2 steps that we must do in order to set this up:

  1. Create a table in a database to store the logging information (I usually create the table within the DNN site)
  2. Modify the DotNetNuke.log4net.config file and add an appender that will send the logging info to the database

Database Table Creation

CREATE TABLE [dbo].[Log4Net_Log]( [Id] [int] IDENTITY(1,1) NOT NULL, [Date] [datetime] NOT NULL, [HostName] [varchar](255) NOT NULL, [AppDomain] [varchar](255) NOT NULL, [Thread] [varchar](255) NOT NULL, [Level] [varchar](50) NOT NULL, [Logger] [varchar](255) NOT NULL, [Message] [varchar](max) NOT NULL ) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]

DotNetNuke.log4net.config Modifications

This example leaves the default flat file logging setup in-place and can be used as a backup incase database connectivity fails.

Add the following appender under the existing <appender name="RollingFile" type="log4net.Appender.RollingFileAppender"> *** </appender> section.  Notice that the connectionStringName property matches the default DNN connection string name. Having these match will ensure that the logging info always goes into the DNN database that is setup for the application. I've found this very useful in situations where you change your database name with some frequency.

<appender name="AdoNetAppender" type="log4net.Appender.AdoNetAppender">     <bufferSize value="1" />     <connectionType value="System.Data.SqlClient.SqlConnection, System.Data, Version=1.0.3300.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />     <connectionStringName value="SiteSqlServer" />     <commandText value="INSERT INTO Log4Net_Log([Date], [HostName], [AppDomain], [Thread],[Level],[Logger],[Message]) VALUES (@log_date, @hostname, @appdomain, @thread, @log_level, @logger, @message)" />     <parameter>       <parameterName value="@log_date" />       <dbType value="DateTime" />       <layout type="log4net.Layout.RawTimeStampLayout" />     </parameter>     <parameter>       <parameterName value="@hostname" />       <dbType value="String" />       <size value="255" />       <layout type="log4net.Layout.PatternLayout">         <conversionPattern value="%property{log4net:HostName}" />       </layout>     </parameter>     <parameter>       <parameterName value="@appdomain" />       <dbType value="String" />       <size value="255" />       <layout type="log4net.Layout.PatternLayout">         <conversionPattern value="%property{appdomain}" />       </layout>     </parameter>     <parameter>       <parameterName value="@thread" />       <dbType value="String" />       <size value="255" />       <layout type="log4net.Layout.PatternLayout">         <conversionPattern value="%thread" />       </layout>     </parameter>     <parameter>       <parameterName value="@log_level" />       <dbType value="String" />       <size value="50" />       <layout type="log4net.Layout.PatternLayout">         <conversionPattern value="%level" />       </layout>     </parameter>     <parameter>       <parameterName value="@logger" />       <dbType value="String" />       <size value="255" />       <layout type="log4net.Layout.PatternLayout">         <conversionPattern value="%logger" />       </layout>     </parameter>     <parameter>       <parameterName value="@message" />       <dbType value="String" />       <size value="4000" />       <layout type="log4net.Layout.PatternLayout">         <conversionPattern value="%message" />       </layout>     </parameter>   </appender>

The next step is to add the following reference to the appender in the <root>**</root> section.

<appender-ref ref="AdoNetAppender" />

That's it! You may need to restart your DNN site for the changes to be picked up but now you will have all of your Log4Net info saving to the database.

Requirements & Disclaimer

I've tested these modification on DNN Platform 7.3.4 and DNN Platform 8.0.0. If you run into any issues or have additional improvements that you would like to share please leave a comment below.