zoukankan      html  css  js  c++  java
  • .Net Core3.0 WebApi 十五:使用Serilog替换掉Log4j

    .Net Core3.0 WebApi 目录

    为什么使用Serilog

    Serilog 是一个用于.NET应用程序的日志记录开源库,配置简单,接口干净,并可运行在最新的.NET平台上,与其他日志库不同, Serilog 是以功能强大的结构化事件数据为基础构建的, 支持将日志输出到控制台、文件、数据库和其它更多的方式,支持参数化日志模板,非常灵活。

    之前我们项目使用的是Log4j来记录用户日志的,在开发的过程中,慢慢的发现Log4j好像并不能满足我们的需求,比如结构化,日志分析等,于是决定使用serilog来替换掉Log4j,在使用的过程中发现Serilog还是很强大的。

    删除原有的Log4j

    1.卸载log4j包

     点击卸载

    2.删除log4j文件夹

    3.删除startup中关于log4net的代码

    4.将log4j相关的代码删除

    安装Serilog包

    nuget安装以下几个包

    配置Serilog

    编辑Appsetting.json

    "Serilog": {
        "MinimumLevel": {
          "Default": "Debug", //最小日志记录级别
          "Override": { //系统日志最小记录级别
            "Default": "Warning",
            "System": "Warning",
            "Microsoft": "Warning"
          }
        },
        "WriteTo": [
          { "Name": "Console" }//输出到控制台
        ]
      },

    program.cs将系统的logger替换为serilog

    public static IHostBuilder CreateHostBuilder(string[] args) =>
                Host.CreateDefaultBuilder(args)
                  .UseServiceProviderFactory(new AutofacServiceProviderFactory()) //<--NOTE THIS
            .ConfigureWebHostDefaults(webBuilder =>
            {
                webBuilder.UseStartup<Startup>()
                          .UseSerilog((context, logger) =>//注册Serilog
                          {
                              logger.ReadFrom.Configuration(context.Configuration);
                              logger.Enrich.FromLogContext();
                          });
            });

    Test控制器注入logger,并修改LogTest方法。

    private readonly ILogger<TestController> _logger;//using Microsoft.Extensions.Logging;
    
    public TestController(ILogger<TestController> logger)
    {
        _logger = logger;
    }
    /// <summary>
            /// 测试日志
            /// </summary>
            /// <returns></returns>
            [HttpGet]
            public IActionResult LogTest()
            {
                //_logger.Error(typeof(TestController), "这是错误日志", new Exception("123"));
                //_logger.Debug(typeof(TestController), "这是bug日志");
                //throw new System.IO.IOException();
                _logger.LogInformation("info 日志");
                _logger.LogDebug("debug 日志");
                _logger.LogError(new System.IO.IOException(), "io 错误");
                return Ok();
            }

    运行调用接口,可以看到日志输出到控制台了:

    配置Serilog输出到文件

    appsetting.json增加配置

    "WriteTo": [
          { "Name": "Console" }, //输出到控制台
          {
            "Name": "Async", //Serilog.Sinks.Async
            "Args": {
              "configure": [
                {
                  "Name": "File", //输出文件
                  "Args": {
                    "path": "log/log.txt",
                    "outputTemplate": "{NewLine}Date:{Timestamp:yyyy-MM-dd HH:mm:ss.fff}{NewLine}LogLevel:{Level}{NewLine}Message:{Message}{NewLine}{Exception}",
                    "rollingInterval": "3" //按天记录
                  }
                }
              ]
            }
          }
          ]

    启动项目测试,就有了日志文件:

     这里边,乱码的地方,其实是  : ,至于为什么乱码,等到找到解决方案再更新。有知道的小伙伴也可以评论下。

    配置Serilog输出到数据库

    {"Name": "Async", //Serilog.Sinks.Async
            "Args": {
              "configure": [
                {
                  "Name": "File", //输出文件
                  "Args": {
                    "path": "log/log.txt",
                    "outputTemplate": "{NewLine}Date:{Timestamp:yyyy-MM-dd HH:mm:ss.fff}{NewLine}LogLevel:{Level}{NewLine}Message:{Message}{NewLine}{Exception}",
                    "rollingInterval": "3" //按天记录
                  }
                },
                {
                  "Name": "MSSqlServer", //输出到sqlserver
                  "Args": {
                    "connectionString": "数据库",
                    "schemaName": "dbo", //数据库所有者,默认dbo
                    "tableName": "Logs", // 记录日志的表名 
                    "autoCreateSqlTable": true, // 是否自动创建表
                    "restrictedToMinimumLevel": "Information", // 记录日志的最小level 
                    "batchPostingLimit": 100, //单次批量处理中提交的最大日志数量
                    "period": "0.00:00:30", //进行批量提交的间隔
                    "columnOptionsSection": {
                      "disableTriggers": true,
                      "clusteredColumnstoreIndex": false,
                      "primaryKeyColumnName": "Id",
                      "addStandardColumns": [ "LogEvent" ],
                      "removeStandardColumns": [ "MessageTemplate" ],
                      "additionalColumns": [ //自定义列
                        {
                          "ColumnName": "Ip",
                          "DataType": "varchar",
                          "DataLength": 20
                        },
                        {
                          "ColumnName": "UserName",
                          "DataType": "varchar",
                          "DataLength": 30
                        },
                        {
                          "ColumnName": "UserId",
                          "DataType": "varchar",
                          "DataLength": 50
                        },
                        {
                          "ColumnName": "LogType",
                          "DataType": "tinyint"
                        },
                        {
                          "ColumnName": "Parameter"
                        },
                        {
                          "ColumnName": "Result"
                        }
    
                      ],
                      "id": { "nonClusteredIndex": true },
                      "properties": {
                        "columnName": "Properties",
                        "excludeAdditionalProperties": true,
                        "dictionaryElementName": "dict",
                        "itemElementName": "item",
                        "omitDictionaryContainerElement": false,
                        "omitSequenceContainerElement": false,
                        "omitStructureContainerElement": false,
                        "omitElementIfEmpty": true,
                        "propertyElementName": "prop",
                        "rootElementName": "root",
                        "sequenceElementName": "seq",
                        "structureElementName": "struct",
                        "usePropertyKeyAsElementName": false
                      },
                      "timeStamp": {
                        "columnName": "Timestamp",
                        "convertToUtc": true
                      },
                      "logEvent": {
                        "excludeAdditionalProperties": true,
                        "excludeStandardColumns": true
                      },
                      "message": { "columnName": "message" },
                      "exception": { "columnName": "exception" }
                    }
                  }
                }
              ]
            }
          }

    Test控制器修改Aoptest方法,添加以下语句

    _logger.LogInformation("ip:{IP},username{UserName},userid:{UserId}","127.0.0.1","admin","1");

    启动项目,测试接口,数据库已经插入数据。

    配置Serilog输出到Seq

    Seq组件,通过网页UI的形式将日志展现出来,内容更加多样化,并赋予了更多功能日志搜索。

    首先,安装Seq组件,Seq下载地址:https://getseq.net/Download

    本地开发情形下是免费使用的,如果需要在生产环境中使用,需要商业许可(你懂的,money).在目前的版本中,4.2是只能够在windows下跑,也就是说我们如果是在windows下开发,在测试时可以借助这个方便的查看日志信息,按照给定的安装步骤完成安装。

    安装完成之后,浏览器输出localhost:5341,会看到以下页面

     appsetting.json配置输出到seq

    {
      "Name": "Seq", //输出到seq
      "Args": {
        "serverUrl": "http://127.0.0.1:5341"
      }
    },

    启动项目,测试接口,可以通过页面看到数据。

      

    全局使用Serilog记录日志

    在CustomExceptionMiddleware.cs直接这样

    namespace WebApi.Core.Api.Middleware
    {
        public class CustomExceptionMiddleware
        {
            private readonly RequestDelegate _next;
            private readonly ILogger<CustomExceptionMiddleware> _logger;
            public CustomExceptionMiddleware(RequestDelegate next, ILogger<CustomExceptionMiddleware> logger)
            {
                _next = next;
                _logger = logger;
            }
            public async Task Invoke(HttpContext httpContext)
            {
                try
                {
                    await _next(httpContext);
                }
                catch (Exception ex)
                {
                    _logger.LogError(ex.Message, ex); // 日志记录
                    await HandleExceptionAsync(httpContext, ex.Message);
                }
                finally

    GlobalExceptionsFilter中也一样

    namespace WebApi.Core.Api.Filters
    {
        public class GlobalExceptionsFilter : IExceptionFilter
        {
            private readonly IHostEnvironment _env;
            private readonly ILogger<GlobalExceptionsFilter> _logger;
    
            public GlobalExceptionsFilter(IHostEnvironment env, ILogger<GlobalExceptionsFilter> logger)
            {
                _env = env;
                _logger = logger;
            }
    
            public void OnException(ExceptionContext context)
            {
                var json = new JsonErrorResponse();
                json.Message = context.Exception.Message;//错误信息
                if (_env.IsDevelopment())
                {
                    json.DevelopmentMessage = context.Exception.StackTrace;//堆栈信息
                }
                context.Result = new InternalServerErrorObjectResult(json);
                _logger.LogError(context.Exception, context.Exception.Message);
    
                //采用log4net 进行错误日志记录
                //_loggerHelper.Error(json.Message, "出现未知异常", context.Exception);
    
            }

    如果想在服务层或仓储层用的话,安装这个包

     然后直接代码里用就行了

    [Caching(AbsoluteExpiration = 1)]
    public async Task<UserResponse> GetUserDetails(int id)
    {
        //var userinfo = await userDal.QueryByID(id);
    
        _logger.LogError("错误日志!");
    
        var userinfo = new UserNew
        {
            UserId = id,
            UserName = "bingle",
            Age = 18
        };
    
        if (userinfo != null)
        {
            //UserResponse model = new UserResponse()
            //{
            //    UserId = userinfo.UserId,
            //    UserName = userinfo.UserName,
            //    Address = "xx市xx区xx小区",
            //    Age = userinfo.Age,
            //    Birthday = "1996-06-26",
            //    Phone = "13888888888"
    
            //};
            UserResponse model = iMapper.Map<UserResponse>(userinfo);
            model.Address = "xx市xx区xx小区";
            model.Birthday = "1996-06-26";
            model.Phone = "13888888888";
            return model;
        }
        else
        {
            return null;
        }
    }

    然后调试接口,这样就有了日志:

  • 相关阅读:
    java。equal()和== 的区别
    java。封装
    java。OOA,OOD,OOR
    java。类和对象
    java、数组;堆区,栈区
    java。 break和continue区别
    NYOJ 228 士兵杀敌(五)【差分标记裸题】
    2017CCPC 杭州 J. Master of GCD【差分标记/线段树/GCD】
    CF1025B Weakened Common Divisor【数论/GCD/思维】
    网络流算法笔记
  • 原文地址:https://www.cnblogs.com/taotaozhuanyong/p/13816181.html
Copyright © 2011-2022 走看看