簡體   English   中英

使用Func()參數進行ASP.NET Core Logging

[英]ASP.NET Core Logging with Func() argument

我使用ASP.NET核心與NLog,使用它作為原始ASP.NET核心記錄器與NLog.Web.AspNetCore塊硬件包的替代品。

NLog包含一個有用的Func()委托簽名,只有在啟用相應的日志記錄級別時才允許執行參數評估:

static readonly Logger log = LogManager.GetCurrentClassLogger();
log.Trace(() => request.JsonSerializer.Serialize(body));

我使用ASP.NET和NLog,但聽起來這個功能不可用:

private ILogger<MyController> log;
log.Trace(() => request.JsonSerializer.Serialize(body));

在開始給自己寫一個方法之前,我想知道如果我錯過了一些東西,我沒有找到任何關於使用帶有NLog的ASP.NET Core的委托參數的日志記錄方法。

在Microsoft.Extensions.Logging抽象中沒有這樣的東西,以及它的構建方式,做這樣的事情並不容易。 雖然您可以輕松地向其添加擴展方法,並且實際上所有日志調用都是擴展方法,但基本Log方法決定是否記錄某些事情,因為它是唯一可以實際訪問已配置日志級別的事物。

話雖這么說,日志抽象使用的東西可以做一些類似的事情。 為此,請考慮ILogger.Log方法的簽名:

void Log<TState>(LogLevel logLevel, EventId eventId, TState state, Exception exception, Func<TState, Exception, string> formatter)

正如您所看到的,實際上並沒有傳遞給它的字符串,只是一個state和一個formatter 在默認擴展方法中,狀態是FormattedLogValues對象,格式化程序只是在狀態上調用ToString()的方法,即FormattedLogValues對象。

FormattedLogValues實際上構建了格式化的字符串,這也是結構化日志記錄發生的地方。 因此,在日志消息中序列化某個對象實際上是一個壞主意; 你可以直接將它傳遞給記錄器。

但是你可以在這里做的是為Log提供你自己的重載,取而代之的是一個函數,然后將其包裝到一個狀態對象中,該對象在調用ToString()時執行該函數。

Asp.net核心2.0的Nlog實施沒有太大變化。

設置1:你需要安裝Nuget包點擊這里

設置2:您需要使用以下配置創建Nlog配置文件。

<nlog>

  <!-- the targets to write to -->

   <targets>
    <!-- write logs to file  -->
    <target filename="${basedir}/logs/${shortdate}.log" layout="            
             -----------Time Stamp: ${longdate}----------              
             Log Level: ${level}${newline}                        
             Logger Name : ${logger}${newline}            
             Log Message : ${message}${newline}            
             Exception Message: ${event-context:item=ErrorMessage}${newline}      
             Browser Detail:  ${event-context:item=BrowserDetail}${newline}              
             Session Id: ${event-context:item=SessionId}" name="file" xsi:type="File">

 <target br="" connectionstring="${gdc:item=defaultConnection}" dbprovider="Oracle.ManagedDataAccess.Client.OracleConnection, 
 Oracle.ManagedDataAccess, Version=2.0.12.0, Culture=neutral, PublicKeyToken=89b483f429c47342" keepconnection="false" name="database" xsi:type="Database"> 
 commandText="INSERT INTO TableName (LOG_LEVEL,LOGGER_NAME,SESSION_ID,BROWSER_DETAIL) values(:LOGLEVEL,:LOGGERNAME,:SESSIONID,:BROWSERDETAIL)">
      <parameter layout="${level:uppercase=true}" name="LOGLEVEL">
      <parameter layout="${logger}" name="LOGGERNAME">
      <parameter layout="${event-context:item=SessionId}" name="SESSIONID">
      <parameter layout="${event-context:item=BrowserDetail}" name="BROWSERDETAIL">
    </parameter></parameter></parameter></parameter></target>
  </target></targets>

   <rules>
    <!--All logs, including from Microsoft-->
    <logger minlevel="Error" name="*" writeto="file">
    <logger minlevel="Trace" name="*" writeto="database">
    <!--Skip non-critical Microsoft logs and so log only own logs-->
    <logger final="true" maxlevel="Info" name="Microsoft.*">
    <!-- BlackHole -->
  </logger></logger></logger></rules>
</nlog>

設置3:需要更新啟動文件。

NLog.GlobalDiagnosticsContext.Set("defaultConnection", Connection string);    NLog.LogManager.LoadConfiguration(env.ContentRootPath + "\\NLog.config");

設置4:我們已經創建了自定義Nlog管理器。

public static class NLogManager {

 public static ILogger _logger = NLog.LogManager.GetCurrentClassLogger();

 public static void InfoLog(NLogData nLogData) {
  LogEventInfo theEvent = new LogEventInfo(LogLevel.Info, NLogManager._logger.Name, nLogData.Message);
  SetLogEventInfo(theEvent, nLogData);
  _logger.Log(theEvent);
 }


 public static void DebugLog(NLogData nLogData) {
  LogEventInfo theEvent = new LogEventInfo(LogLevel.Debug, NLogManager._logger.Name, nLogData.Message);
  SetLogEventInfo(theEvent, nLogData);
  _logger.Log(theEvent);
 }


 public static void ErrorLog(NLogData nLogData) {
  LogEventInfo theEvent = new LogEventInfo(LogLevel.Error, NLogManager._logger.Name, nLogData.Message);
  SetLogEventInfo(theEvent, nLogData);
  _logger.Log(theEvent);
 }
}

用於記錄的自定義事件參數

private static void SetLogEventInfo(LogEventInfo theEvent, NLogData nLogData) {
 theEvent.Properties["SessionId"] = nLogData.SessionId;
 theEvent.Properties["BrowserDetail"] = nLogData.BrowserDetail;
}

NLog日志記錄的模型。

public class NLogData {
 public string SessionId {
  get;
  set;
 }
 public string BrowserDetail {
  get;
  set;
 }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM