Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/templates/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 带有Func()参数的ASP.NET核心日志记录_C#_Logging_Asp.net Core_Nlog - Fatal编程技术网

C# 带有Func()参数的ASP.NET核心日志记录

C# 带有Func()参数的ASP.NET核心日志记录,c#,logging,asp.net-core,nlog,C#,Logging,Asp.net Core,Nlog,我将ASP.NET core与NLog一起使用,将其作为原始ASP.NET core记录器与NLog.Web.AspNetCore nugget包的替代品 NLog包含一个有用的Func()委托签名,该签名仅允许在启用相应日志记录级别时执行参数求值: static readonly Logger log = LogManager.GetCurrentClassLogger(); log.Trace(() => request.JsonSerializer.Serialize(body));

我将ASP.NET core与NLog一起使用,将其作为原始ASP.NET core记录器与NLog.Web.AspNetCore nugget包的替代品

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));
专用ILogger日志;
log.Trace(()=>request.JsonSerializer.Serialize(body));

在开始为自己编写一个方法之前,我想知道,如果我遗漏了什么,我还没有找到关于使用ASP.NET Core和NLog的委托参数的此类日志记录方法的任何信息。

在Microsoft.Extensions.logging抽象中没有这样的东西,而且按照它的构建方式,做这样的事情并不容易。虽然您可以轻松地向其添加扩展方法,实际上所有日志调用都是扩展方法,但基本
log
方法决定是否记录某些内容,因为它是唯一真正可以访问配置的日志级别的方法

这就是说,日志抽象使用的东西可能使它有可能做类似的事情。为此,考虑<代码> ILogger的签名。log < /代码>方法:

void Log<TState>(LogLevel logLevel, EventId eventId, TState state, Exception exception, Func<TState, Exception, string> formatter)
void日志(日志级别LogLevel、EventId EventId、TState状态、异常、Func格式化程序)
正如您所看到的,实际上没有一个字符串被传递给它,只有一个
状态
和一个
格式化程序
。在默认扩展方法中,状态是
FormattedLogValues
对象,而格式化程序只是在状态上调用
ToString()
的方法,即
FormattedLogValues
对象

FormattedLogValues
实际上是构建格式化字符串的,这也是结构化日志记录发生的地方。因此,在日志消息中序列化某些对象实际上是个坏主意;您可以直接将其传递给记录器


但是您可以在这里为
Log
提供您自己的重载,该重载采用函数,然后将函数包装到某个状态对象中,该状态对象在调用
ToString()
时执行函数。

Asp.net core 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>
设置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;
}
非直瞄测井模型。

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

提供新的日志重载通常是NLog.Web.AspNetCore包可以实现的。我本可以尝试提取有关它的请求,但包装自己的扩展方法要快得多。非常感谢您的宝贵意见!尽管它实际上并没有像NLog.Web.AspNetCore那样真正替代ASP.Net内核日志引擎,但这是一个关于如何包装NLog的好例子。谢谢你。
public class NLogData {
 public string SessionId {
  get;
  set;
 }
 public string BrowserDetail {
  get;
  set;
 }
}