การใช้ Apache log4net™

  1. ติดตั้ง log4net ผ่าน NuGet
  2. สร้างไฟล์ log4net.config
  3. บอก log4net ให้โหลดไฟล์คอนฟิก
  4. เพิ่มโค๊ดที่ Program.cs
  5. การกำหนดชื่อไฟล์ log เป็น ปี เดือน วัน
  6. การเก็บ log แบบ indent
  7. log4net levels
  8. log ชื่อเพจที่กำลังทำงาน (ASP.NET)

1.ติดตั้ง log4net ผ่าน NuGet

PM> Install-Package log4net
Installing 'log4net 2.0.8'.
Successfully installed 'log4net 2.0.8'.
Adding 'log4net 2.0.8' to ConsoleApplication2.
Successfully added 'log4net 2.0.8' to ConsoleApplication2.

2.สร้างไฟล์ log4net.config

สร้างไฟล์ log4net.config ไว้เก็บค่า config เกี่ยวกับ log4net
และที่ “Copy to Output Directory” ให้เลือกเป็น “Copy Always” (ถ้าลืมเลือกอันนี้จะไม่เห็นไฟล์ log)

จากนั้นใส่ค่าในไฟล์ log4net.config ตามนี้

<?xml version="1.0" encoding="utf-8" ?>
<log4net>
  <root>
    <level value="ALL" />
    <appender-ref ref="console" />
    <appender-ref ref="file" />
  </root>
  <appender name="console" type="log4net.Appender.ConsoleAppender">
    <layout type="log4net.Layout.PatternLayout">
      <conversionPattern value="%date %level %logger - %message%newline" />
    </layout>
  </appender>
  <appender name="file" type="log4net.Appender.RollingFileAppender">
    <file value="myapp.log" />
    <appendToFile value="true" />
    <rollingStyle value="Size" />
    <maxSizeRollBackups value="5" />
    <maximumFileSize value="10MB" />
    <staticLogFileName value="true" />
    <encoding value="UTF-8"/>
    <layout type="log4net.Layout.PatternLayout">
      <conversionPattern value="%date [%thread] %level %logger - %message%newline" />
    </layout>
  </appender>
</log4net>

บรรทัดที่ 14 กำหนดชื่อไฟล์ที่ใช้เก็บ log เป็น myapp.log

3.บอก log4net ให้โหลดไฟล์คอนฟิก

ที่ด้านล่างของไฟล์ Properties/AssemblyInfo.cs เพิ่ม

[assembly: log4net.Config.XmlConfigurator(ConfigFile = "log4net.config")]

4.เพิ่มโค๊ดที่ Program.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;

namespace ConsoleApp1
{
    class Program
    {
        private static readonly log4net.ILog log =
            log4net.LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);

        static void Main(string[] args)
        {
            log.Info("Hello logging world!");

            SomeMethod();
        }

        static void SomeMethod()
        {
            log.Info("Hello from SomeMethod!");
        }
    }
}

เมื่อรันจะได้ไฟล์ myapp.log

2019-02-20 21:07:29,116 [1] INFO ConsoleApp1.Program - Hello logging world!
2019-02-20 21:07:29,126 [1] INFO ConsoleApp1.Program - Hello from SomeMethod!

5.การกำหนดชื่อไฟล์ log เป็น ปี เดือน วัน

การกำหนดชื่อไฟล์เป็น ปี เดือน วัน และวางไว้ในโฟลเดอร์ เช่น logs/20190218Jack.log

กำหนดค่าในไฟล์ log4net.config ตามนี้

<?xml version="1.0" encoding="utf-8" ?>
<log4net>
  <root>
    <level value="ALL" />
    <appender-ref ref="console" />
    <appender-ref ref="file" />
  </root>
  <appender name="console" type="log4net.Appender.ConsoleAppender">
    <layout type="log4net.Layout.PatternLayout">
      <conversionPattern value="%date %level %logger - %message%newline" />
    </layout>
  </appender>

  <appender name="file" type="log4net.Appender.RollingFileAppender">
    <lockingModel type="log4net.Appender.FileAppender+MinimalLock"/>
    <file value="logs/" />
    <datePattern value="yyyyMMdd'Jack.log'" />
    <staticLogFileName value="false" />
    <appendToFile value="true" />
    <rollingStyle value="Composite" />
    <maxSizeRollBackups value="10" />
    <maximumFileSize value="10MB" />
    <encoding value="UTF-8"/>
    <layout type="log4net.Layout.PatternLayout">
      <param name="ConversionPattern" value="%-5p%d{ yyyy-MM-dd HH:mm:ss} line:%line - [%thread] %m method:%method [stacktrace:%stacktrace{5}] %n" />
    </layout>
  </appender>
</log4net>

เก็บชื่อเมธอดใน log ด้วย

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <log4net>
    <root>
      <level value="All" />
      <appender-ref ref="console" />
      <appender-ref ref="file" />
    </root>
    <appender name="console" type="log4net.Appender.ConsoleAppender">
      <layout type="log4net.Layout.PatternLayout">
        <conversionPattern value="%date %level %method - %message%newline" />
      </layout>
    </appender>
    <appender name="file" type="log4net.Appender.RollingFileAppender">
      <lockingModel type="log4net.Appender.FileAppender+MinimalLock"/>
      <file value="logs/" />
      <datePattern value="yyyyMMdd'_jack.log'" />
      <staticLogFileName value="false" />
      <appendToFile value="true" />
      <rollingStyle value="Composite" />
      <maxSizeRollBackups value="10" />
      <maximumFileSize value="10MB" />
      <encoding value="UTF-8"/>
      <layout type="log4net.Layout.PatternLayout">
        <param name="ConversionPattern" value="%-5p%d{ yyyy-MM-dd HH:mm:ss} line:%line - [%method] %m  %n" />
      </layout>
    </appender>
  </log4net>
</configuration>
INFO  2019-06-13 10:29:31 line:25 - [Main] Content 1 

6.การเก็บ log แบบ indent

เพิ่มตัวแปร someSensible ไว้ในไฟล์ App.config 
โดยค่าของ someSensible ของการรันแบบ debug และ without debug ค่าที่ได้จะไม่เท่ากัน และโปรเจ็กส์แบบ console และ WebApp ก็ได้ค่าไม่เท่ากัน ต้องลองรันดูแล้วมาปรับค่าเอา

เพิ่ม reference ชื่อ System.Configuration เพื่อให้สามารถอ่านค่าจากไฟล์ App.config ได้

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
    <startup> 
        <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.6.1" />
    </startup>

  <appSettings>
    <add key="someSensible" value="3" />
  </appSettings>
  
</configuration>

กำหนดค่าในไฟล์ log4net.config ตามนี้

<?xml version="1.0" encoding="utf-8" ?>
<log4net>
  <root>
    <level value="ALL" />
    <appender-ref ref="console" />
    <appender-ref ref="file" />
  </root>
  <appender name="console" type="log4net.Appender.ConsoleAppender">
    <layout type="log4net.Layout.PatternLayout">
      <conversionPattern value="%date %level %logger - %message%newline" />
    </layout>
  </appender>

  <appender name="file" type="log4net.Appender.RollingFileAppender">
    <lockingModel type="log4net.Appender.FileAppender+MinimalLock"/>
    <file value="logs\" />
    <datePattern value="yyyyMMdd'Jack.log'" />
    <staticLogFileName value="false" />
    <appendToFile value="true" />
    <rollingStyle value="Composite" />
    <maxSizeRollBackups value="10" />
    <maximumFileSize value="10MB" />
    <encoding value="UTF-8"/>
    <layout type="log4net.Layout.PatternLayout">
      <param name="ConversionPattern" value="%-5p%d{ yyyy-MM-dd HH:mm:ss} line:%line - [%thread] %method: %m %n" />
    </layout>
  </appender>
</log4net>

บรรทัดที่ 4 กำหนด log4net levels เป็น All คือแสดงออกมาทั้งหมด

แก้ไขโค๊ดที่ Program.cs

using System;
using System.Collections.Generic;
using System.Configuration;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;

namespace ConsoleApp1
{
    class Program
    {
        private static readonly log4net.ILog log = log4net.LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
        private static readonly int someSensible = Convert.ToInt32(ConfigurationManager.AppSettings.Get("someSensible").ToString());
        private static readonly int spaces = 4;

        static void Main(string[] args)
        {
            Console.WriteLine(Environment.StackTrace.Count(a => a == '\n'));
            log.Info("Hello logging world!");

            Method1();

            string indent = new string(' ', Math.Max(0, (Environment.StackTrace.Count(a => a == '\n') - someSensible)) * spaces);
            string aa = "a";
            log.Error(string.Format("{0} oh no! ", indent));
        }

        static void Method1()
        {
            string indent = new string(' ', Math.Max(0, (Environment.StackTrace.Count(a => a == '\n') - someSensible)) * spaces);
            log.Info(string.Format("{0} {1} ", indent, MethodBase.GetCurrentMethod().Name));
            log.Info(string.Format("{0} {1} ", indent, "this is content1"));

            Method2();
        }
        static void Method2()
        {
            string indent = new string(' ', Math.Max(0, (Environment.StackTrace.Count(a => a == '\n') - someSensible)) * spaces);
            log.Info(string.Format("{0} {1} ", indent, MethodBase.GetCurrentMethod().Name));
            log.Info(string.Format("{0} {1} ", indent, "this is content2"));
        }
    }
}

ตัวอย่าง log

INFO  2019-02-20 21:35:30 line:20 - [1] Main: Hello logging world! 
INFO  2019-02-20 21:35:30 line:32 - [1] Method1:  Method1  
INFO  2019-02-20 21:35:30 line:33 - [1] Method1:  this is content1  
INFO  2019-02-20 21:35:30 line:40 - [1] Method2:      Method2  
INFO  2019-02-20 21:35:30 line:41 - [1] Method2:      this is content2  
ERROR 2019-02-20 21:35:30 line:26 - [1] Main:  oh no!  

7.log4net levels

  • All – Log everything
  • Debug
  • Info
  • Warn
  • Error
  • Fatal
  • Off – Don’t log anything

ตัวอย่างการเรียกใช้

log.Debug("");
log.Info("");
log.Warn("");
log.Error("");
log.Fatal("");

8.log ชื่อเพจที่กำลังทำงาน (ASP.NET)

string currentPageFileName = new FileInfo(this.Request.Url.LocalPath).Name;
log.Info(currentPageFileName);
log.Info(Server.MapPath(Page.AppRelativeVirtualPath));

จะได้

INFO  2019-05-31 14:02:25 line:22 - [Page_Load] Default.aspx  
INFO  2019-05-31 14:02:25 line:23 - [Page_Load] D:\Project\WebApp\Default.aspx