在ASP.NET Core Web API中使用Serilog进行日志记录

目录

创建ASP.NET Core Web API项目

Serilog配置

日志记录异常

Serilog接收器

自定义Serilog接收器

总结


在本教程中,我们将学习如何在ASP.NET Core Web API中使用Serilog实现日志记录,我们将使用Serilog库将日志写入滚动文件,并了解如何将日志记录实例注入到API项目的不同类中,以帮助我们开始写入日志。我们还将学习如何编写自己的自定义接收器。

日志记录是开发中最重要和最关键的功能之一,它允许开发人员和产品所有者对应用程序错误进行故障排除和分析。使用Serilog或任何其他日志记录提供程序,每当应用程序写入全面而广泛的日志时,您将能够跟踪发生的任何错误或问题,这将极大地帮助找到问题的解决方案。

在本教程中,我们将学习如何在ASP.NET Core Web API中使用Serilog实现日志记录。

ASP.NET Core Web API中使用Serilog引入日志记录非常简单直接。事实上,Serilog有一个特定的NuGet包,它是为ASP.NET Core项目量身定制的。

因此,让我们从教程开始。

创建ASP.NET Core Web API项目

打开Visual Studio 2022,并在ASP.NET Core Web API中创建新项目。给它起一个名字,比如:LoggingWithSerilog

选择.NET 6,然后按创建

加载模板项目后,右键单击解决方案资源管理器中的项目名称,然后选择管理NuGet,搜索Serilog,然后选择安装 Serilog.AspNetCore

NuGet包将Serilog接收器(包括调试、控制台和文件)的依赖项捆绑在一起。在本教程中,我们主要对文件接收器感兴趣,因为我们将在滚动文件中转储日志。

Serilog配置

现在打开您的appsettings.json文件并添加以下部分:

"Serilog": {
    "Using": [ "Serilog.Sinks.File" ],
    "MinimumLevel": {
      "Default": "Debug",
      "Override": {
        "Microsoft": "Error",
        "System": "Debug"
      }
    },
    "Enrich": [ "FromLogContext", "WithMachineName", "WithProcessId", "WithThreadId" ],
    "WriteTo": [
      {
        "Name": "File",
        "Args": {
          "path": "C:\\Web Apis\\Logs\\LoggingWithSerilog\\RestApiLog.log",
          "outputTemplate": "{Timestamp:yyyy-MM-dd HH:mm:ss.fff zzz} 
           [{Level}] [{SourceContext}] [{EventId}] {Message}{NewLine}{Exception}",
          "rollOnFileSizeLimit": true,
          "fileSizeLimitBytes": 4194304,
          "retainedFileCountLimit": 15,
          "rollingInterval": "Minute"
        }
      }
    ]
  }
 

Program.cs文件中,添加以下代码:

var logger = new LoggerConfiguration()
        .ReadFrom.Configuration(builder.Configuration)
        .Enrich.FromLogContext()
        .CreateLogger();
builder.Logging.ClearProviders();
builder.Logging.AddSerilog(logger);
 

现在,为了能够从控制器内部写入日志,我们需要使用注入到控制器构造函数的记录器实例。

打开WeatherController,在构造函数中,您会注意到已经有一个注入的记录器参数。

private readonly ILogger<weatherforecastcontroller> logger;
public WeatherForecastController(ILogger<weatherforecastcontroller> logger)
{
    this.logger = logger;
}
 

现在在此GetWeatherForecast端点中,将模板代码替换为以下行:

logger.LogDebug("Inside GetWeatherForecast endpoint");
var response = Enumerable.Range(1, 5).Select(index => new WeatherForecast
{
    Date = DateTime.Now.AddDays(index),
    TemperatureC = Random.Shared.Next(-20, 55),
    Summary = Summaries[Random.Shared.Next(Summaries.Length)]
})
.ToArray();
logger.LogDebug($"The response for the get weather forecast is 
{JsonConvert.SerializeObject(response)}");
return response;
 

请注意,这是 Newtonsoft.json 包中使用的JsonConvert类,因此如果您执行快速操作或Ctrl+.,您将获得建议安装所需NuGet包的菜单,您可以选择安装它:

现在我们已经设置好了Serilog并准备开始编写日志,让我们运行一个快速测试以查看它是否有效。

 F5,将显示默认浏览器并呈现APISwagger UI页面。

日志记录异常

日志记录最重要的用例是跟踪和排除错误和异常,一旦记录了异常详细信息,您将更容易知道错误发生的时间、地点和原因,这将导致更快地解决问题,尤其是当此类问题在您的生产应用程序上时。

要在整个API项目中进行适当的异常处理,建议您添加一个处理异常的中间件,并在内部注入记录器实例并实现日志记录代码。

此中间件将拦截在端点执行期间发生的任何异常,将返回带有响应的正确http状态代码,然后它将记录异常详细信息。

所以在你的项目中,让我们添加一个名为 Middleware 的文件夹,在其中,让我们创建一个名为的ExceptionHandlingMiddleware新类。

using Newtonsoft.Json;
using System.Net;
namespace LoggingWithSerilog.Middleware
{
    public class ExceptionHandlingMiddleware
    {
        public RequestDelegate requestDelegate;
        private readonly ILogger<ExceptionHandlingMiddleware> logger;
        public ExceptionHandlingMiddleware
        (RequestDelegate requestDelegate, ILogger<ExceptionHandlingMiddleware> logger)
        {
            this.requestDelegate = requestDelegate;
            this.logger = logger;
        }
        
        public async Task Invoke(HttpContext context)
        {
            try
            {
                await requestDelegate(context);
            }
            catch (Exception ex)
            {
                await HandleException(context, ex);
            }
        }
        private Task HandleException(HttpContext context, Exception ex)
        {
            logger.LogError(ex.ToString());
            var errorMessageObject = 
                new { Message = ex.Message, Code = "system_error" };
           
            var errorMessage = JsonConvert.SerializeObject(errorMessageObject);
            context.Response.ContentType = "application/json";
            context.Response.StatusCode = (int)HttpStatusCode.InternalServerError;
            return context.Response.WriteAsync(errorMessage);
        }
    }
}
 

此中间件将执行两个任务:处理在任何端点执行期间可能发生的任何异常,并返回包含错误代码和消息的通用响应,第二个任务将记录使用配置的日志记录提供程序(Serilog)发生的异常。

现在这里唯一剩下的就是将新的中间件注入到应用程序的管道中,所以打开你的Program.cs文件,让我们在builder.Build()方法调用后添加以下行:

app.UseMiddleware(typeof(ExceptionHandlingMiddleware));
 

接下来,让我们通过在端点内部抛出任意异常来使GetWeatherForecast端点失败:

throw new Exception("Failed to retrieve data");
 

运行应用程序并测试调用Get WeatherForecast终结点:

现在让我们看看Serilog是否有效并将日志记录详细信息添加到文件接收器中:

打开文件以查看转储的日志:

Serilog接收器

Serilog将接收器作为插件的概念,捆绑了许多预定义的接收器,您可以配置并直接使用这些接收器开始写入日志。

此类接收器的范围从简单的接收器(如控制台或文件)到更高级的接收器(如ElasticSearch)或可以直接连接日志并将其转储到SQL ServerMongoDB等数据库或Azure AnalyticsAmazon CloudWatch等云日志记录服务或Azure Cosmos DBAws Dynamo DB等云数据库的接收器,甚至您可以找到将日志转储到Windows的事件日志中的接收器等等其他选项。

在本教程中,我们学习了如何将ASP.NET Core Web APISerilog连接,你可以尝试不同类型的Serilog接收器。

查看以下链接以查看提供的Serilog接收器的完整列表

自定义Serilog接收器

在某些情况下,您可能需要编写自己的接收器,Serilog使您能够通过在自己的类中实现ILogEventSink并在Emit方法中编写所需的自定义日志记录代码来实现此目的。

让我们创建一个自定义接收器,添加一个名为 Sinks 的文件夹,并创建一个名称为CustomSink的新类。

using Serilog.Core;
using Serilog.Events;

namespace LoggingWithSerilog.Sinks
{
    public class CustomSink : ILogEventSink
    {
        public void Emit(LogEvent logEvent)
        {
            var result = logEvent.RenderMessage();

            Console.ForegroundColor = logEvent.Level switch
            {
                LogEventLevel.Debug => ConsoleColor.Green,
                LogEventLevel.Information => ConsoleColor.Blue,
                LogEventLevel.Error => ConsoleColor.Red,
                LogEventLevel.Warning => ConsoleColor.Yellow,
                _ => ConsoleColor.White,
            };
            Console.WriteLine($"{logEvent.Timestamp} - {logEvent.Level}: {result}");
        }
    }
}
 

在上面的示例中,我们根据日志的级别更改控制台文本颜色。

为了能够将应用程序配置为使用新的自定义接收器,我们必须为新的自定义接收器定义扩展方法。

using Serilog;
using Serilog.Configuration;

namespace LoggingWithSerilog.Sinks
{
    public static class CustomSinkExtensions
    {
        public static LoggerConfiguration CustomSink(
                  this LoggerSinkConfiguration loggerConfiguration)
        {
            return loggerConfiguration.Sink(new CustomSink());
        }
    }
}
 

现在,最后一部分是通过在Serilog日志记录配置中引入新的自定义接收器,将Program.cs中的组件粘合在一起。

var logger = new LoggerConfiguration()
        .ReadFrom.Configuration(builder.Configuration)
        .WriteTo.CustomSink()
        .Enrich.FromLogContext()
        .CreateLogger();
 

如上所示,我们使用了两个接收器,一个来自配置(文件接收器),另一个使用使用WriteTo自定义接收器扩展方法定义的自定义接收器。

现在让我们运行并在正在运行的控制台上查看结果:

如果打开日志文件夹,仍可以看到文件接收器将日志写入滚动文件:

总结

在本教程中,我们学习了如何在Core Web API中使用Serilog ASP.NET日志记录。此外,我们还学习了如何编写中间件来处理所有异常以及如何使用Serilog记录它们。

此外,我们还介绍了提供的不同Serilog接收器,我们设法创建了一个新的自定义接收器,该接收器将写入控制台并根据日志级别更改颜色。

我希望本教程向您正确介绍Serilog。请随时给我留下评论,并与您的网络和同事分享教程。

您可以在我的 GitHub帐户中找到源代码。

本文最初发表于 Logging with Serilog in ASP.NET Core Web API - Coding Sonata

https://www.codeproject.com/Articles/5344667/Logging-with-Serilog-in-ASP-NET-Core-Web-API

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值