2017-08-08 23 views
1

我現在正在使用ASP.NET核心LoggerFactorySerilog擴展)使用記錄工作。我想把日誌放在控制器和業務服務方法中。我這樣做,是通過構造函數注入的​​這樣ASP.NET核心 - 記錄器的多個實例

在控制器:

ILogger<HomeController> _logger 

在服務:

ILogger<ServiceName> _logger 

我相信,這將在每個請求被實例化,所以對於每個HTTP請求它會創建Logger的多個實例。說每個控制器和每個服務類,但它與以前的記錄方法有點不同,我們只用於創建一個記錄器實例,並用它來記錄任何地方的東西。

這有什麼缺點?

回答

2

這完全沒問題。通常,實例化記錄器很便宜,因此完全可以像執行性能那樣進行。

仍然可以考慮(1)使用Serilog所具有的全局日誌實例,或者(2)使用在字段聲明中初始化的靜態字段。再一次,不是出於性能的原因,而是爲了避免污染你的構造函數而不是相關的東西。

UPD更新關於實施(1)

基本上,它只是一個決定會在哪裏你把記錄器初始化代碼到的問題。在ASP.NET核心將是Main方法的第一行(即LogSerilog命名空間的靜態類):

Log.Logger = new LoggerConfiguration().WriteTo.LiterateConsole(LogEventLevel.Debug, LogTemplate) 
               .WriteTo.File(@"C:\logs\elbakogdabot.log", LogEventLevel.Debug, LogTemplate) 
               .Enrich.FromLogContext() 
               .CreateLogger(); 

(僅僅是明確的:我把代碼從我的實際項目,但是記錄器的實際配置可能不同)。

然後我會在任何地方使用它像這樣:

Log.Warning($"got a message for an unknown user: userid=[{userId}]"); 

此行可能被扔進任何類,你不必做任何額外的初始化這個類。

UPD更新關於執行(2)

我想在一個典型的企業應用程序這將是有問題永遠記得你每次登錄的東西的時候把類名在郵件中。所以我大部分時間都會去static readonly。隨着Serilog你可以做這樣的:

public class XYZService 
{ 
    private static readonly Serilog.ILogger log = Log.ForContext<XYZService>(); 
... 

這樣你既不會污染構造,並會自動在您所有的日誌信息的獲取類名。我曾經在ReSharper片段中有這條線,所以我不得不在每個新班級中輸入lg<TAB>

+0

感謝您的快速回復。選項1的任何好的參考文章? – vibs

+0

聽起來不錯。我試圖在我的代碼中實現它。它的工作原理! – vibs

+0

只有兩件事:1)我必須在我的業務庫中安裝serilog nuget軟件包以獲取Log對象的訪問權限2)我的輸出模板格式沒有獲取sourcecontext,因爲它是全局的。所以我們必須在日誌消息中編寫n類方法的詳細信息。如果錯了,糾正我。 – vibs