asp.net core+log4net 写入日志到sqlserver

asp.net core版本:5.0

log4net:2.0

一般情况下,我比较习惯把日志记录到日志文件中。但这种方式有一个缺点:把项目发布到生产环境后,每次查看日志都需要远程登录到服务器去查看日志文件,有点不太方便,所以我想把日志写入到数据库中。

首先我们新建一个asp.net core webapi项目,nuget添加如下包:

asp.net core+log4net 写入日志到sqlserver_第1张图片

向日志系统中添加log4net:

Host.CreateDefaultBuilder(args)
                .ConfigureWebHostDefaults(webBuilder =>
                {
                    webBuilder.UseStartup();
                }).ConfigureLogging(logBuilder =>
                {
                    logBuilder.AddLog4Net();
                });

配置log4net.config:



  
    
    
  
  
    
    
    
    
    
    
    
    

    
    
      
      
      
    
    
      
      
      
        
      
    
    
      
      
      
        
      
    
    
      
      
      
        
      
    
    
      
      
      
        
      
    
    
    
 
  

下面我们讲解一下这个配置文件。

logger节点,name随意命名,需要与LogManager.GetLogger的name参数一样。level子节点我配置为ERROR,只记录level为ERROR的日志。appender-ref,ref属性的值指定要添加的appender,即下面的appender

我们看appender这个节点,name属性可以按照我们的喜好命名,type则必须是log4net.Appender.ADONetAppender,因为我们使用的是sqlserver数据库。如果你使用的是mysql数据库,那就不是这个了。

connectionType,因为我们已经引入了System.Data.SqlClient包,所以不用添加Version和PublicKeyToken。这里有2个地方需要注意一下:1、我看有的博客在这个地方写的是Microsoft.Data.SqlClient.SqlConnection,Microsoft.Data,但是他又没告诉我们要引入Microsoft.Data.SqlClient。这种方式能不能用我没有试过,有兴趣的可以试一下。2、这个地方你写的包名必须要引入到你的项目中

parameter,这个节点对应insert values里面的每一个插入字段,是对插入字段做一个配置。

重点看一下layout,type属性就是对字段做配置的类名,这个值是类所在命名控件.类名,所以这个值要根据你自己的项目来确定。conversionPattern的value属性中的pattern字符串与AddConverter的第一个参数name必须相同。我的这个类的代码如下:

using log4net.Layout;

namespace LogDemo.LogDbConfig
{
    public class ActionLayoutPattern : PatternLayout
    {
        public ActionLayoutPattern()
        {
            this.AddConverter("pattern", typeof(FieldsConverter));
        }
    }
}

FieldsConverter类就是给每个自定义字段赋值,代码如下:

using log4net.Layout.Pattern;

public class FieldsConverter : PatternLayoutConverter
    {
        protected override void Convert(TextWriter writer, LoggingEvent loggingEvent)
        {
            var dto = loggingEvent.MessageObject as LogItems;
            switch (this.Option)
            {
                case "Uri":
                    writer.Write(dto.Uri);
                    break;
                case "HttpMethod":
                    writer.Write(dto.HttpMethod);
                    break;
                case "ErrMessage":
                    writer.Write(dto.ErrMessage);
                    break;
                case "ErrStackTrace":
                    writer.Write(dto.ErrStackTrace);
                    break;
                default:
                    writer.Write("");
                    break;
            }
        }
    }

LogItems,这个类是自定义字段的类,代码如下:

public class LogItems
    {
        public string Uri { get; set; }
        public string HttpMethod { get; set; }
        public string ErrMessage { get; set; }
        public string ErrStackTrace { get; set; }
    }

接下来我们写入数据库:

var logData = new LogItems();
logData.Uri = Request.Path;
logData.HttpMethod = Request.Method;
logData.ErrMessage = ex.Message;
logData.ErrStackTrace = ex.StackTrace;

var iLog = LogManager.GetLogger("actionLog");
iLog.Error(logData);

这段代码是写在catch里面的,ex就是Exception的实例。Request是ControllerBase的一个属性,用来获取当前http请求的元数据。

GetLogger的参数actionLog对应log4net.config中的

LogDateTime这个字段的值layout的type=log4net.Layout.RawTimeStampLayout,由log4net赋值,所以这里不需要赋值

数据库表结构如下:

asp.net core+log4net 写入日志到sqlserver_第2张图片

运行程序,故意写几行索引超出范围的代码。结果如下:

 我这里是把错误日志写入到数据库,但是其他Level的日志我还是想写入到文件中,这该怎么做呢?其实这个也很简单,和之前只写入到文件中一样,加一个写入文件的appender即可,配置如下:



  
    
    
  
  
    
    
    
    
    
    
    
    

    
    
      
      
      
    
    
      
      
      
        
      
    
    
      
      
      
        
      
    
    
      
      
      
        
      
    
    
      
      
      
        
      
    
  

  
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
      
    
    
    
      
      
    
  

  
    
    
  

如果不需要把日志写入到数据库,那我们就可以不用log4net的ILog类来写入(LogManager.GetLogger返回的就是ILog),而是通过Microsoft.Extensions.Logging.ILogger接口来写入。这里顺便提一下这个接口,它是asp.net core自带的日志接口,内置了console logger和debug logger(还有其他的logger,我记不清了),每次调用这个接口写入方法时(LogInfo、LogError等),它就向所有实现这个接口的logger发送日志。因为我们调用了ConfigureLogging把log4net也加入了日志系统(logBuilder.AddLog4Net()),所以使用ILogger写入日志时也会把日志写入到log4net。

至此,无论是把日志写入到数据库还是文件都可以了。

最后提醒一下大家,一定要认真检查commandText的insert语句,因为这个语句是写在log4net.config配置文件中,没有语法错误提示。如果写错了,程序运行的时候也不会有任何的错误提示,让你搞不清楚到底是哪里的问题,我就在这个地方耗费了很多的时间。

你可能感兴趣的:(ASP.NET,CORE,ASP.NET,CORE,log4net,sqlserver)