2013年12月24日 星期二

Common.Logging

在開始使用log4net或NLog這種Logging元件來處理log,是一個很美好的開發經驗,但在開發類別庫專案的時後,會碰到循環參考的問題,這時後改用Common.Logging會比較好

Common.Logging是一個Log介面,可以支援log4net、NLog、Enterprise Library Logging,透過設定檔把Log轉接到真正要使用的Log元件,在日後轉換Log元件的時後很方便,詳細的介紹可以參考官網,以下用一個類別庫專案搭配一個應用程式來介紹這個元件的使用方式

Common.Logging 2.2.0版之後,相依於Common.Logging.Core套件
應該是為了可儶性,把介面和抽象類別分離到Core套件
在套件的使用上要做點調整

Common Logging 2.3.1版之後,已不再使用Common.Logging.Core
為了比較好在Log套件的多個版本之間切換,對應的Log套件後面都會有指定的版本
例如Common.Logging.NLog31對應到NLog 3.1版本

首先開啟一個類別庫專案,並透過NuGet加入Common.Logging參考


簡單寫一個函式讓之後引用的程式來呼叫
using Common.Logging;

namespace ClassLibrary1
{
    public class Class1
    {
        private ILog log = LogManager.GetLogger<Class1>());

        public void SayHello()
        {
            this.log.Info("Hello");
        }
    }
}

再來新增一個Windows Form應用程式,並引用剛寫的庫別庫專案

簡單寫一個Button Click來呼叫類別庫中的函式
using System;
using System.Windows.Forms;

namespace WindowsFormsApplication1
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            ClassLibrary1.Class1 x = new ClassLibrary1.Class1();
            x.SayHello();
        }
    }
}

因為要轉接到NLog去,所以再新增套件Common.Logging.NLog31,對應的NLog版本就是3.1
如果要對應到其他的版本,可以選擇對應的套件

加入NLog,為了方便起見,順便加入NLog.Configuration和NLog Schema for Intellisense(TM)

接下來透過設定檔把Log轉接到NLog

<?xml version="1.0" encoding="utf-8"?>
<configuration>
    <configSections>
        <sectionGroup name="common">
            <section name="logging" type="Common.Logging.ConfigurationSectionHandler, Common.Logging"/>
        </sectionGroup>
    </configSections>
    <common>
        <logging>
            <factoryAdapter type="Common.Logging.NLog.NLogLoggerFactoryAdapter, Common.Logging.NLog31">
                <arg key="configType" value="FILE" />
                <arg key="configFile" value="~/NLog.config" />
            </factoryAdapter>
        </logging>
    </common>
    <startup>
        <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" />
    </startup>
    <runtime>
        <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
            <dependentAssembly>
                <assemblyIdentity name="NLog" publicKeyToken="5120e14c03d0593c" culture="neutral" />
                <bindingRedirect oldVersion="0.0.0.0-2.1.0.0" newVersion="2.1.0.0" />
            </dependentAssembly>
        </assemblyBinding>
    </runtime>
</configuration>
NLog使用預設的設定

<?xml version="1.0" encoding="utf-8" ?>
<nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd"
      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">

    <!-- 
  See http://nlog-project.org/wiki/Configuration_file 
  for information on customizing logging rules and outputs.
   -->
    <targets>
        <!-- add your targets here -->
        <target xsi:type="File" name="f" fileName="${basedir}/logs/${shortdate}.log"
                layout="${longdate} ${uppercase:${level}} ${message}" />

    </targets>

    <rules>
        <!-- add your logging rules here -->
        <logger name="*" minlevel="Trace" writeTo="f" />
    </rules>
</nlog>
輸出的結果