Logs will persist into database tables

  • File‑based logs: Requires logging into the server to download and open text files for review; searching content is cumbersome;
  • Database‑backed logs: You may build a dedicated log‑management backend page, supporting SQL‑based conditional search, filtering and paging;
  1. Simplifies unified maintenance, log auditing and exception troubleshooting.

Drawback: High‑frequency logging adds database load. In production environments, optimise with buffered writes, table partitioning and periodic old‑log purging.

1 Create Log Table (SQL Server)

-- Log table Log
create table Log (
    Id bigint identity,
    AddTime datetime not null,
    Thread nvarchar(100) not null,
    Level nvarchar(200) not null,
    Logger nvarchar(500) not null,
    Message nvarchar(3000) not null,
    Exception nvarchar(4000) null,
    constraint PK_LOG primary key (Id)
)
go

-- ========== Field comments (optional, for database browsing convenience) ==========
declare @CurrentUser sysname
select @CurrentUser = user_name()
execute sp_addextendedproperty 'MS_Description',
'Log4net log table',
'user', @CurrentUser, 'table', 'Log'
go

declare @CurrentUser sysname
select @CurrentUser = user_name()
execute sp_addextendedproperty 'MS_Description',
'Primary key for log entries',
'user', @CurrentUser, 'table', 'Log', 'column', 'Id'
go

declare @CurrentUser sysname
select @CurrentUser = user_name()
execute sp_addextendedproperty 'MS_Description',
'Entry timestamp',
'user', @CurrentUser, 'table', 'Log', 'column', 'AddTime'
go

declare @CurrentUser sysname
select @CurrentUser = user_name()
execute sp_addextendedproperty 'MS_Description',
'Originating thread',
'user', @CurrentUser, 'table', 'Log', 'column', 'Thread'
go

declare @CurrentUser sysname
select @CurrentUser = user_name()
execute sp_addextendedproperty 'MS_Description',
'Log severity level (Info/Debug/Error etc.)',
'user', @CurrentUser, 'table', 'Log', 'column', 'Level'
go

declare @CurrentUser sysname
select @CurrentUser = user_name()
execute sp_addextendedproperty 'MS_Description',
'Logger instance name',
'user', @CurrentUser, 'table', 'Log', 'column', 'Logger'
go

declare @CurrentUser sysname
select @CurrentUser = user_name()
execute sp_addextendedproperty 'MS_Description',
'Log message body',
'user', @CurrentUser, 'table', 'Log', 'column', 'Message'
go

declare @CurrentUser sysname
select @CurrentUser = user_name()
execute sp_addextendedproperty 'MS_Description',
'Exception stack trace',
'user', @CurrentUser, 'table', 'Log', 'column', 'Exception'
goCode language: PHP (php)

Field reference:

FieldDescription
IdAuto‑increment primary key
AddTimeTime when log was generated
ThreadThread that triggered the log
LevelLog level: DEBUG/INFO/WARN/ERROR/FATAL
LoggerLogger name (full class name)
MessageRegular log text payload
ExceptionException stack trace; empty if no error occurred

2 Install NuGet Package

Install-Package log4net

Works natively with .NET Framework; also fully compatible for .NET Core/.NET5+/ASP.NET Core.

3 Full log4net Configuration (App.config / Web.config)

<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <configSections>
    <!-- Register log4net configuration section -->
    <section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler, log4net" />
  </configSections>

  <log4net>
    <!-- ADONetAppender: database output appender -->
    <appender name="ADONetAppender" type="log4net.Appender.ADONetAppender">
      <!-- bufferSize=1: write synchronously without buffering; raise value for batch inserts to ease database load -->
      <bufferSize value="1" />

      <!-- SqlServer ADO driver type -->
      <connectionType value="System.Data.SqlClient.SqlConnection, System.Data, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />

      <!-- Database connection string; adjust database name, credentials accordingly -->
      <connectionString value="DATABASE=log4netdemo;SERVER=.;UID=sa;PWD=pwdpwd;Connect Timeout=15;" />

      <!-- Insert statement, columns must exactly match table schema and parameters -->
      <commandText value="INSERT INTO Log ([AddTime],[Thread],[Level],[Logger],[Message],[Exception])
VALUES (@log_date, @thread, @log_level, @logger, @message, @exception)" />

      <!-- Param 1: log timestamp -->
      <parameter>
        <parameterName value="@log_date" />
        <dbType value="DateTime" />
        <layout type="log4net.Layout.RawTimeStampLayout" />
      </parameter>

      <!-- Param 2: thread name -->
      <parameter>
        <parameterName value="@thread" />
        <dbType value="String" />
        <size value="100" />
        <layout type="log4net.Layout.PatternLayout">
          <conversionPattern value="%t" />
        </layout>
      </parameter>

      <!-- Param 3: log severity level -->
      <parameter>
        <parameterName value="@log_level" />
        <dbType value="String" />
        <size value="200" />
        <layout type="log4net.Layout.PatternLayout">
          <conversionPattern value="%p" />
        </layout>
      </parameter>

      <!-- Param 4: logger name -->
      <parameter>
        <parameterName value="@logger" />
        <dbType value="String" />
        <size value="500" />
        <layout type="log4net.Layout.PatternLayout">
          <conversionPattern value="%c" />
        </layout>
      </parameter>

      <!-- Param 5: log content message -->
      <parameter>
        <parameterName value="@message" />
        <dbType value="String" />
        <size value="3000" />
        <layout type="log4net.Layout.PatternLayout">
          <conversionPattern value="%m" />
        </layout>
      </parameter>

      <!-- Param 6: exception details -->
      <parameter>
        <parameterName value="@exception" />
        <dbType value="String" />
        <size value="4000" />
        <layout type="log4net.Layout.ExceptionLayout" />
      </parameter>
    </appender>

    <!-- Root logger enabling database persistence -->
    <root>
      <level value="Info" />
      <appender-ref ref="ADONetAppender" />
      <!-- You may enable file logging alongside database output: <appender-ref ref="YourFileAppenderName"/> -->
    </root>
  </log4net>
</configuration>Code language: HTML, XML (xml)

Important note: Screenshots may only display first two parameters. You have to declare all six parameters otherwise startup exceptions will occur!

4 Initialize log4net in Code

1. .NET Framework Web Project (Global.asax)
protected void Application_Start(object sender, EventArgs e)
{
    // Load log4net configuration
    log4net.Config.XmlConfigurator.Configure();
}Code language: JavaScript (javascript)
2. Console / WinForms App

Add this as the very first line inside the Main method of Program.cs:

log4net.Config.XmlConfigurator.Configure();Code language: CSS (css)
3 Typical logging usage
// Obtain logger instance
private static readonly log4net.ILog log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);

// Write ordinary information log
log.Info("System started successfully");

// Write exception‑related log
try
{
    int a = 1 / 0;
}
catch (Exception ex)
{
    log.Error("Calculation error encountered", ex);
}Code language: PHP (php)

Logs will persist into database tables

Leave a Reply

Your email address will not be published. Required fields are marked *