tnblog
首页
视频
资源
登录

.net 使用 Serilog 和 Seq 构建强大的日志系统

652人阅读 2025/2/14 21:02 总访问:3455003 评论:0 收藏:0 手机
分类: .net后台框架

.netcore

.net 使用 Serilog 和 Seq 构建强大的日志系统


在现代软件开发中,日志记录是确保应用程序稳定性和可维护性的关键环节。Serilog 是一个功能强大的 .NET 日志库,而 Seq 是一个集中式的日志服务器,两者结合可以为您的应用程序提供一个高效、灵活且易于管理的日志解决方案。本文将介绍如何在 .NET 应用程序中使用 Serilog 和 Seq 进行日志记录。

Serilog 简介


Serilog 是一个流行的 .NET 日志库,以其简洁的 API 和丰富的扩展功能而闻名。Serilog 支持多种日志输出方式(称为 Sinks),包括控制台、文件、Seq、Elasticsearch 等。通过 Serilog,您可以轻松地将日志信息输出到不同的目标,并根据需要进行配置。

Seq 简介


Seq 是一个集中式的日志服务器,专为 Serilog 设计。它提供了强大的日志存储、查询和可视化功能,非常适合用于生产环境中的日志管理。Seq 支持日志的全文搜索、实时监控和警报功能,能够帮助您快速定位和解决问题。

安装和配置

Seq日志服务器安装方式


Seq 提供了多种安装方式,包括 Docker、Windows 安装包和 Linux 安装包。
以下是通过 Docker Compose安装 Seq 的步骤(修改docker-compose.yml):

  1. version: '3.4'
  2. services:
  3. ...
  4. newitemfeature.seq:
  5. image: docker.1ms.run/datalust/seq
  6. container_name: newitemfeature-seq
  7. environment:
  8. - ACCEPT_EULA=Y
  9. ports:
  10. - 5341:5341
  11. - 8081:80


对Seq日志服务器的80端口映射外部8081端口,并开放日志接口5341
也可以使用docker一行命令进行安装:

  1. docker run --name newitemfeature-seq -d -p 5341:5341 -p 8081:80 docker.1ms.run/datalust/seq

由于不能直接访问docker.io,所以我这里改成了国内能访问的接口docker.1ms.run/datalust/seq,更多国内可以参考的镜像网站请参考:2025年最新可用!Docker/DockerHub 国内镜像源/加速列表

配置 Serilog


在您的 .NET 应用程序中,您需要安装 Serilog 和 Seq 的相关 NuGet 包:

  1. <PackageReference Include="Serilog.AspNetCore" Version="8.0.3" />
  2. <PackageReference Include="Serilog.Sinks.Seq" Version="8.0.0" />


接下来,在程序启动时配置 Serilog,使其将日志输出到 Seq 服务器:

  1. builder.Host.UseSerilog((context,loggerConfig) =>
  2. loggerConfig.ReadFrom.Configuration(context.Configuration));


具体我们在appsettings.json中来进行修改我们的配置。

  1. {
  2. "Serilog": {
  3. "Using": [ "Serilog.Sinks.Console", "Serilog.Sinks.Seq" ],
  4. // 上述代码指定了 Serilog 使用的日志输出插件(Sinks):
  5. // - Serilog.Sinks.Console:将日志输出到控制台。
  6. // - Serilog.Sinks.Seq:将日志输出到 Seq 服务器(一个集中式日志服务器)。
  7. "MinimumLevel": {
  8. "Default": "Information",
  9. // 默认的日志级别设置为 "Information",表示会记录 Information 及以上级别的日志(如 WarningErrorFatal)。
  10. "Override": {
  11. "Microsoft": "Information"
  12. // 对于 "Microsoft" 命名空间下的日志,将日志级别覆盖为 "Information"
  13. // 这通常用于调整框架日志的详细程度。
  14. }
  15. },
  16. "WriteTo": [
  17. { "Name": "Console" },
  18. // 将日志写入控制台。
  19. {
  20. "Name": "Seq",
  21. "Args": { "serverUrl": "http://newitemfeature-seq:5341" }
  22. // 将日志写入 Seq 服务器,指定 Seq 服务器的地址为 "http://newitemfeature-seq:5341"
  23. }
  24. ],
  25. "Enrich": [ "FromLogContext", "WithMachineName", "WithThreadId" ]
  26. // 日志的丰富化设置:
  27. // - FromLogContext:从日志上下文中获取额外信息(如请求 ID 等)。
  28. // - WithMachineName:在日志中添加机器名称。
  29. // - WithThreadId:在日志中添加线程 ID
  30. }
  31. }


添加拦截的请求的进行使用Serilog日志记录。

  1. app.UseSerilogRequestLogging();


然后我们这里就可以启动程序了,我这里是使用Docker Compose进行启动的,打开Seq会发现大量的日志信息(http://127.0.0.1:8081)。

异常中间件


这里我们自定义一个异常记录中间件,这样如果有什么报错可以根据我们想要的格式进行显示Seq日志服务器上。

  1. public class ExceptionHandlingMiddleware
  2. {
  3. private readonly RequestDelegate _next;
  4. private readonly ILogger<ExceptionHandlingMiddleware> _logger;
  5. public ExceptionHandlingMiddleware(RequestDelegate next, ILogger<ExceptionHandlingMiddleware> logger)
  6. {
  7. _next = next;
  8. _logger = logger;
  9. }
  10. public async Task InvokeAsync(Microsoft.AspNetCore.Http.HttpContext context)
  11. {
  12. try
  13. {
  14. await _next(context);
  15. }
  16. catch (Exception exception)
  17. {
  18. _logger.LogError(exception, "Exception occurred: {Message}", exception.Message);
  19. var exceptionDetails = GetExceptionDetails(exception);
  20. var problemDetails = new ProblemDetails {
  21. Status = exceptionDetails.Status,
  22. Type = exceptionDetails.Type,
  23. Title = exceptionDetails.Title,
  24. Detail = exceptionDetails.Detail
  25. };
  26. if (exceptionDetails.Errors is not null)
  27. {
  28. problemDetails.Extensions["errors"] = exceptionDetails.Errors;
  29. }
  30. context.Response.StatusCode = exceptionDetails.Status;
  31. await context.Response.WriteAsJsonAsync(problemDetails);
  32. }
  33. }
  34. private static ExceptionDetails GetExceptionDetails(Exception exception)
  35. {
  36. var details = new ExceptionDetails
  37. {
  38. Type = exception.GetType().FullName,
  39. Title = "An error occurred while processing your request.",
  40. Status = 500, // 默认状态码为 500 (Internal Server Error)
  41. Detail = exception.Message,
  42. Errors = new Dictionary<string, object?>()
  43. };
  44. // 根据异常类型设置不同的响应信息
  45. if (exception is ArgumentException argEx)
  46. {
  47. details.Title = "Invalid argument provided.";
  48. details.Status = 400;
  49. details.Errors.Add("Argument", argEx.ParamName);
  50. }
  51. else if (exception is UnauthorizedAccessException unauthorizedEx)
  52. {
  53. details.Title = "Access denied.";
  54. details.Status = 403; // Forbidden
  55. }
  56. else if (exception is KeyNotFoundException keyNotFoundEx)
  57. {
  58. details.Title = "Resource not found.";
  59. details.Status = 404; // Not Found
  60. details.Errors.Add("Resource", keyNotFoundEx.Message);
  61. }
  62. else if (exception is ValidationException validationEx)
  63. {
  64. details.Title = "Validation failed.";
  65. details.Status = 400; // Bad Request
  66. details.Errors.Add("Validation", validationEx.Message);
  67. }
  68. else if (exception is InvalidOperationException invalidOpEx)
  69. {
  70. details.Title = "Invalid operation.";
  71. details.Status = 400; // Bad Request
  72. details.Errors.Add("Operation", invalidOpEx.Message);
  73. }
  74. return details;
  75. }
  76. public class ExceptionDetails
  77. {
  78. public string? Type { get; set; }
  79. public string? Title { get; set; }
  80. public int Status { get; set; }
  81. public string? Detail { get; set; }
  82. public IDictionary<string, object?> Errors { get; set; }
  83. }
  84. }


添加上我们这个异常中间件。

  1. app.UseMiddleware<ExceptionHandlingMiddleware>();


这里我们调用一个异常的接口测试一下。


如果还希望写多个不同的属性进行展示,这里我添加一个MM举例,可以在下面的代码进行修改:

  1. _logger.LogError(exception, "Exception occurred: {Message}", exception.Message);
  2. 修改为:
  3. _logger.LogError(exception, "Exception occurred: {Message} {MM}", exception.Message, exception.Message);


欢迎加群讨论技术,1群:677373950(满了,可以加,但通过不了),2群:656732739

评价

net core 使用 EF Code First

下面这些内容很老了看这篇:https://www.tnblog.net/aojiancc2/article/details/5365 项目使用多层,把数据库访问...

cAPS.net 保存base64位格式的图片

publicvoidUpload() { //取出图片对应的base64位字符 stringimgBase=Request[&quot;imgBase&quot;]; //c#里边的base6...

Quartz.net实例动态改变周期调度。misfire、Cron

Quartz:Java编写的开源的任务调度作业框架 类似Timer之类定时执行的功能,但是更强大Quartz.NET:是把Quartz转成C# NuGet...

.net Windows服务发布、安装、卸载、监听脚本。服务调试

一、脚本 为方便不用每次都去写安装卸载的脚本1.安装脚本@echooff @echo开始安装【服务】 %SystemRoot%\Microsoft.NET\Fr...

c、VB.net中全角半角转换方法

///&lt;summary&gt; ///转全角的函数(SBCcase) ///&lt;/summary&gt; ///&lt;paramname=&quot;input&quot;&gt;任意字符串...

.net mvc分部页,.net core分部页

.net分部页的三种方式第一种:@Html.Partial(&quot;_分部页&quot;)第二种:@{ Html.RenderPartial(&quot;分部页&quot;);}...

C.net 配合小程序实现经过第三方服务器中转文件

某些时候,微信小程序前段上传文件的时候需要经过第三方服务器再将文件上传到客户的服务器;操作如下:1:(小程序内向中端服...

.net实现QQ邮箱发送邮件功能

1、微软已经帮我们封装好了发送邮件的类MailMessage,MailMessage类构造一些邮件信息,然后通过SmtpClient进行邮件发送。Mai...

StackExchange.Redis操作redis(net core支持)

官方git开源地址https://github.com/StackExchange/StackExchange.Redis官方文档在docs里边都是官方的文档通过nuget命令下...

windows 自带的netsh进行端口映射

使用netsh 把本地任意ip的25566端口 映射到192.168.81.234的25565端口netshinterfaceportproxyaddv4tov4listenaddress=0.0....

确保.net程序始终以管理员身份运行

usingSystem; usingSystem.Collections.Generic; usingSystem.Linq; usingSystem.Text; usingSystem.Threading.Tasks; ...

ASP.net Timer细节处理

Timer的用法:1:本人称之为计时器,是asp.net官方的一种。用法即是计时所用 2:关于计时有很多中方式,本人学识有限,暂...

.net core 使用session

tip:net core 2.2后可以直接启用session了,不用在自己添加一次session依赖,本身就添加了使用nuget添加引用Microsoft.AspN...

通俗易懂,什么是.net?什么是.net Framework?什么是.net core?

朋友圈@蓝羽 看到一篇文章写的太详细太通俗了,搬过来细细看完,保证你对.NET有个新的认识理解原文地址:https://www.cnblo...

asp.net core2.0 依赖注入 AddTransient与AddScoped的区别

asp.net core主要提供了三种依赖注入的方式其中AddTransient与AddSingleton比较好区别AddTransient瞬时模式:每次都获取一...

asp.net主动推送百度seo

虽然可以使用百度提供的js自动推送,但是估计度娘还是希望主动推送一点。哈哈^_^,女孩子嘛大多都喜欢被动一点。publicclass...
这一世以无限游戏为使命!
排名
2
文章
633
粉丝
44
评论
93
docker中Sware集群与service
尘叶心繁 : 想学呀!我教你呀
一个bug让程序员走上法庭 索赔金额达400亿日元
叼着奶瓶逛酒吧 : 所以说做程序员也要懂点法律知识
.net core 塑形资源
剑轩 : 收藏收藏
映射AutoMapper
剑轩 : 好是好,这个对效率影响大不大哇,效率高不高
ASP.NET Core 服务注册生命周期
剑轩 : http://www.tnblog.net/aojiancc2/article/details/167
ICP备案 :渝ICP备18016597号-1
网站信息:2018-2025TNBLOG.NET
技术交流:群号656732739
联系我们:contact@tnblog.net
公网安备:50010702506256
欢迎加群交流技术