文檔目錄
本節內容:
服務端
ABP使用Castle Windsor的日志記錄工具,它可以和不同的logginh(日志)類庫協作:Log4Net、NLog、Serilog等。Castle為所有Logger庫提供一個公共接口,所以它獨立於logging庫,也可以在有需要的時候很容易地替換logging。
Log4Net是最流行的Logging庫,ABP模板與適當配置後的Log4Net一起工作,但是它只是一個單行模式的依賴(查看“配置”主題),所以你可以替換成你喜歡的日志庫。
獲取Logger(記錄器)
不管你用哪個logging庫,寫日志的代碼是一樣的(歸功於Castle的公共ILogger接口)。
首先,我們應獲取一個Logger,由於ABP大量使用依賴注入,所以我們可以用屬性注入(或構造器注入)模式來注入一個Logger對象。看一下寫一行日志的示例類:
using Castle.Core.Logging; //1: Import Logging namespace public class TaskAppService : ITaskAppService { //2: Getting a logger using property injection public ILogger Logger { get; set; } public TaskAppService() { //3: Do not write logs if no Logger supplied. Logger = NullLogger.Instance; } public void CreateTask(CreateTaskInput input) { //4: Write logs Logger.Info("Creating a new task with description: " + input.Description); //TODO: save task to database... } }
首先,我們引用Castle的ILogger接口的命名空間。
其實,我們定義一個公開的ILogger對象,名為Logger,這個對象將寫日志,依賴注入系統將在TaskAppService對象創建之後,設置(注入)這個屬性,這就是著名的屬性注入模式。
第三,我們把Logger設置為NullLogger.Instance。沒這行代碼,系統也能工作,但這是屬性注入模式的最佳實踐,如果都沒有這個Logger,在使用它時會收到一個“對象引用...“的異常。這個就是保證它為不空,所以如果沒有設置這個Logger,它就是NullLogger。這就是著名的Null對象模式。NullLogger實質上什麼都不做,不寫任何日志,所以我們的類不管是有無實質上的logger,都能工作。
最後,我們用info(信息)級別來寫一文本日志,有幾個不同的級別(查看“配置”主題)。
如果我們調用CreateTask方法,檢查日志文件,我們可以看到類似以下一行日志:
INFO 2014-07-13 13:40:23,360 [8 ] SimpleTaskSystem.Tasks.TaskAppService - Creating a new task with description: Remember to drink milk before sleeping!
Logger的基類
ABP為Mvc的控制器、Web Api的控制器、應用服務類等提供了基類。它們聲明一個Logger屬性,所以你可以直接使用這個Logger寫日志,不需要注入,例如:
public class HomeController : SimpleTaskSystemControllerBase { public ActionResult Index() { Logger.Debug("A sample log message..."); return View(); } }
注意:SimpleTaskSystemControllerBase是我們應用特定的繼承自AbpController的基類。因此,它可以直接使用Logger。同樣,你也可以為你的其它類寫公共基類,然後,你就不必每次注入Logger了。
配置
從ABP模板創建的應用已經為Log4Net完成了所有的配置。
默認配置日志格式如下所示(每個一行)
它們在應用的log4net.config文件裡定義,如下:
<?xml version="1.0" encoding="utf-8" ?> <log4net> <appender name="RollingFileAppender" type="log4net.Appender.RollingFileAppender" > <file value="Logs/Logs.txt" /> <appendToFile value="true" /> <rollingStyle value="Size" /> <maxSizeRollBackups value="10" /> <maximumFileSize value="10000KB" /> <staticLogFileName value="true" /> <layout type="log4net.Layout.PatternLayout"> <conversionPattern value="%-5level %date [%-5.5thread] %-40.40logger - %message%newline" /> </layout> </appender> <root> <appender-ref ref="RollingFileAppender" /> <level value="DEBUG" /> </root> <logger name="NHibernate"> <level value="WARN" /> </logger> </log4net>
Log4net是高度可配置,並強大的logging庫,你可以用不同的格式寫日志並存向不同的介質(文本文件,數據庫...),你可以設置日志的最低級別,你可以寫不同的日志到不同的日志文件,當日志文件達到指定大小時,它會自動備份並創建新的日志文件(這個配置中,回滾文件每文件配置10000KB)等等,閱讀它自己的配置文檔獲取更多信息。
最後,在Global.asax文件中,我們聲明要用log4net.config文件來使用Log4Net:
public class MvcApplication : AbpWebApplication { protected override void Application_Start(object sender, EventArgs e) { IocManager.Instance.IocContainer.AddFacility<LoggingFacility>(f => f.UseLog4Net().WithConfig("log4net.config")); base.Application_Start(sender, e); } }
這是唯一一行依賴於log4net的代碼,同時,Web項目僅依賴log4net類的nuget包。所以,你可以很容易的換成另一個庫,而不必改其它日志代碼。
Abp.Castle.Log4Net 包
ABP使用Castle日志記錄工具,它不直接依賴於log4net,如上面的說法。但有一個Castle的Log4Net集成的問題,它不支持最新版的log4new。我們創建一個nuget包,名為Abp.Castle.Log4Net,來解決這個問題。把這個包加入到我們解決方案後,我們所需要做的只是在應用啟動代碼裡這樣修改代碼:
public class MvcApplication : AbpWebApplication { protected override void Application_Start(object sender, EventArgs e) { IocManager.Instance.IocContainer.AddFacility<LoggingFacility>(f => f.UseAbpLog4Net().WithConfig("log4net.config")); base.Application_Start(sender, e); } }
唯的不同是我們使用“UseAbpLog4Net()“方法(定義在Abp.Castle.Logging.Log4Net命名空間裡)替換”UseLog4Net()“。當我們使用Abp.Castle.Log4Net包,就不再需要Castle.Windsor-log4net和Castle.Core-log4net包。
客戶端
ABP為客戶端定義了一個簡單的Javascript logging Api,它默認在在浏覽器的控制台上寫日志,示例代碼:
abp.log.warn('a sample log message...');
更多信息,查看logging API 文檔。