具有通用主机和 Serilog .NET 7 的 Sentry

Sentry with generic host and Serilog .NET 7

提问人:Yesname 提问时间:11/9/2023 最后编辑:Yesname 更新时间:11/19/2023 访问量:68

问:

这是一个普遍的问题。

我真的花了一整天的时间弄清楚,但没有任何成功。在任何地方都有示例,或者可以使用 Sentry 完成,或者我们必须将日志订阅更改为 antoher 订阅?我根据我在 WEB 上找到的样本尝试了所有方法。不幸的是,当 Sentry 从appsettings.json读取其配置时,没有示例代码如何将 Sentry 与 Serilog 一起使用以及通用主机(托管服务)。

编辑: 我找到了一个解决方案,尽管它不是我想要的。 我想使用appsettings.json配置:

{
  "Sentry": {
    "Dsn": "<dsn>",
    "MinimumBreadcrumbLevel": "Debug",
    "MinimumEventLevel": "Debug"
  },
  "Serilog": {
    "Using": [ "Serilog.Sinks.Console", "Serilog.Sinks.File" ],
    "MinimumLevel": {
      "Default": "Verbose",
      "Override": {
        "Microsoft": "Information",
        "System": "Warning",
        "Sentry": "Information"
      }
    },
    "WriteTo": [
      {
        "Name": "Console",
        "Args": {
          "formatter": {
            "type": "Serilog.Templates.ExpressionTemplate, Serilog.Expressions",
            "template": "[{@t:HH:mm:ss} {@l:u3}{#if SN is not null} {SN}{#end}] {@m}\n{@x}",
            "theme": "Serilog.Templates.Themes.TemplateTheme::Code, Serilog.Expressions"
          }
        }
      },
      {
        "Name": "File",
        "Args": {
          "path": "Logs\\Service.log",
          "rollOnFileSizeLimit": true,
          "formatter": {
            "type": "Serilog.Templates.ExpressionTemplate, Serilog.Expressions",
            "template": "[{@t:HH:mm:ss} {@l:u3}{#if SN is not null} {SN}{#end}] {@m}\n{@x}"
          }
        }
      },
      {
        "Name": "Sentry",
        "Args": {
          "MinimumBreadcrumbLevel": "Debug",
          "MinimumEventLevel": "Warning"
        }
      }
    ],
    "Enrich": [ "FromLogContext" ]
  }
}

日志记录配置:

var builder = Host.CreateDefaultBuilder(args);
builder.UseSerilog((context, services, loggerConfiguration) => loggerConfiguration.ReadFrom.Configuration(context.Configuration));
builder.UseSentry();

上面使用的 UseSentry() 扩展方法:

public static IHostBuilder UseSentry(this IHostBuilder builder) =>
      builder.ConfigureLogging((context, logging) =>
      {
          var section = context.Configuration.GetRequiredSection("Sentry");
          logging.Services.Configure<SentryLoggingOptions>(section);
          logging.AddSentry();
      });

问题在于 Sentry.Serilog 不使用在扩展方法中读取的 Sentry 配置部分。

目前的解决方案:

  1. 将所有 Sentry 设置添加到 Serilog 部分的 Sentry 部分,并删除根 Sentry 配置。
  2. 删除生成器。UseSentry(),所以我不能使用扩展方法,如果我想向 Sentry 添加特定设置,这是一个缺点。

最好使用一个独立的 Sentry 部分,其中可以为不同的环境应用程序设置配置通用设置,但我不知道该怎么做。 此外,我必须找到一种方法来设置 Sentry 选项,例如 ServerName 和 Environment 在启动时动态。

C# .NET Serilog 哨兵

评论


答:

2赞 Bruno Garcia 11/11/2023 #1

存储库上有一个示例:https://github.com/getsentry/sentry-dotnet/blob/main/samples/Sentry.Samples.Serilog/Program.cs

但您也可以查看 NuGet 趋势:

https://github.com/dotnet/nuget-trends/blob/main/src/NuGetTrends.Scheduler/Program.cs

在这里,我在任何框架代码之前设置了 serilog,因此如果启动时发生崩溃,它也会捕获它

编辑:根据您的评论,不需要WebHost:

如果您没有 WebHost,则无需,因为这会添加两个中间件,用于捕获根目录的错误,以及如果请求标头中有 trace-id,则继续跟踪。它也会自动添加,但您可以将其直接添加到您的应用程序中。Sentry.AspNetCoreSentry.Extensions.Logging

以下是一些直接添加到 : https://github.com/getsentry/sentry-dotnet/blob/main/samples/Sentry.Samples.ME.Logging/Program.csLoggerFactory

如果要将 Serilog 添加到应用程序,则还需要(例如如何添加原始消息)。这是因为 Serilog 接管了日志记录后端。它可能仅适用于 Serilog 包,我还没有尝试过。Sentry.Serilog

您可能需要读取 .NET 内容并将其传递给代码IConfiguration

编辑 2:在最后一个问题之后更新解决方案

问题在于 Sentry.Serilog 不使用在扩展方法中读取的 Sentry 配置部分。

哨兵不能,真的。除非您手动将配置的那部分与它绑定。但是您在这里使用两个单独的包,默认情况下它们有自己的配置部分。

Sentry 应尽早初始化一次。在您必须做出选择的情况下,这成为一个问题:通过 Serilog 配置(因此在 Serilog 配置部分下)或通过顶级 Sentry 配置进行初始化,它可以绑定一两行代码,甚至在任何代码之前调用,确保如果应用程序崩溃甚至读取配置或任何东西, 哨兵会让你知道的。当然,权衡是在从 etc 读取配置方面不太灵活,但 Sentry 确实对某些环境变量有内置支持,因此您可以设置例如 、 、 等。Sentry.Extensions.LoggingSentrySdk.InitjsonSENTRY_DSNSENTRY_ENVIRONMENTSENTRY_RELEASE

Sentry 的 Serilog 部分只能接受您设置的两个值,因为这是“特定于 Serilog”的唯一内容。可以将其设置为根元素,以便 Sentry.Extension.Logging,以便初始化 SDK。不过,这似乎就是你已经在做的事情了。DSN

此外,我必须找到一种方法来设置 Sentry 选项,例如 ServerName 和 Environment 在启动时动态。

如上所述,您可以通过 env var 设置一些选项。ServerName 自动从 中读取。您可以通过以下命令以编程方式更改所有这些内容:Environment.MachineName

AddSentry(o => o.ServerName)等在主机启动后立即进行。您选择分配的值可以来自 .NET的内置配置系统,如果你想通过env、var或json来定义。

Sentry 会将配置值与您显式传递的回调合并

评论

0赞 Yesname 11/15/2023
我知道这些样本。很遗憾,这些样品不符合我们的要求。我们有作为服务运行的 .NET 7 应用程序,没有 WebHost。它们是简单的 Sdk.Worker 项目,我们不需要那里的 WebHosts,但我们希望将 Sentry(或其他集中式日志服务)与 Serilog 和 appsettings.json 配置一起使用。根据我在 Git 上找到的讨论,Sentry 无法支持这一点。由于:(,他们今年关闭了 3 年前的功能请求。
0赞 Bruno Garcia 11/17/2023
我会编辑答案
0赞 Yesname 11/18/2023
谢谢!我编辑了我的问题。我认为我现在面临的问题更加清晰。如果可以做得更好,请告诉我。
0赞 Bruno Garcia 11/19/2023
很高兴你至少找到了一个解决方案。由于这是两个与两个独立事物集成的包(Sentry 的 serilog 集成与 aspnet 分离),默认情况下有两个配置块,我同意这并不理想。希望进一步的解释有助于提供更多背景信息