NOTE: Apart from
(and even then it's questionable, I'm Scottish). These are machine translated in languages I don't read. If they're terrible please contact me.
You can see how this translation was done in this article.
Sunday, 27 October 2024
//Less than a minute
当然,登录是应用程序的一个重要部分,但我经常看到它在ASP.NET应用程序中被误解/滥用。 这是关于如何有效登录 ASP.NET 应用程序的部分文章和部分宣言。
这不是完整的伐木指南; 外面的人有LOTS; 更多的是选择一个有效的 ASP. NET 应用程序的伐木策略。
在主要伐木作业中,应该使用;无论是在开发过程中还是生产过程中的伐木作业,应该对你/你的团队/你的用户有用。
伐木常常被视为“只有在有例外时才这样做”的事情。 我认为这误解了伐木应该是什么。
买东西不只是为了例外
一般而言,您应该能够在当地办理相当大一部分申请。 log.LogInformation
这是你的朋友。
我写了30多年的代码 我看过几个好伐木的例子 还有更多贫穷伐木的例子
良好伐木原则:
记住; 记录 ALWAYS 拖曳您的应用程序性能; 您应该记录您需要什么来诊断一个问题, 但是在生产/ 性能至关重要的地方( 例如, 使用全部调试记录时不要运行性能测试 ) 。
在 ASP.NET 中,您已经在伐木系统上建了一座建筑; Microsoft.Extensions.Logging
.. 这是一个不错的伐木系统, 但它没有Serilog那么灵活。 Serilog是一个更灵活的伐木系统,使您能够登录多个汇(产出),并用补充信息丰富您的日志。
这是您应用程序启动时的日志 。 这是第一件事 发生, 这是第一件事 你应该看到 当你运行你的应用程序。 在 ASP. NET 中, 特别是当您使用配置时, 关键在于您了解应用程序启动时发生的情况。 这是ASP.NET应用软件中 最常见的问题源
例如,在Serilog,你可以做到这一点:
Log.Logger = new LoggerConfiguration()
.WriteTo.Console()
.WriteTo.File("logs/boot-*.txt", rollingInterval: RollingInterval.Day, retainedFileCountLimit: 7)
.CreateBootstrapLogger();
注意: 这是有限的, 因为您目前无法访问配置, 例如使用 AppInsights 您可能需要 #if RELEASE
复选框,以设置相应的密钥。
这将给您提供您应用程序中任何启动问题的数据; 它既写到控制台, 也写到文件 。 也必须确保你不会保存所有的日志文件; 你可以看到这里我们只保存了7天的日志。
您也会想要总结您的启动方法( 在此应用程序中, 我使用新程序) Program.cs
使用试捕/渔获物和记录那里发生的任何例外情况。
try
{
..all your startup code
}
catch (Exception ex)
{
if(args.Contains("migrate"))
{
Log.Information("Migration complete");
return;
}
Log.Fatal(ex, "Application terminated unexpectedly");
}
finally
{
Log.CloseAndFlush();
}
日志. CloseAflush () 很重要, 因为它能确保将所有日志写入磁盘( 您的应用程序正在崩溃, 否则它会在完成此操作之前退出) 。
在此我还检测应用程序是否在迁移模式下运行, 如果是的话, 我记录并退出 。
Log.Fatal
是最严厉的日志级别; 它用于您应用程序即将崩溃时 。
并非所有例外都是致命的 - 您应该使用 Log.Error
对于那些(除非他们指的是助理人员(而不是请求)),不能继续超过这一点。
在 APP.NET (和.NET ) 中,您有一些日志水平 :
Log.Fatal
- 这是最严重的日志级别; 当您的应用程序即将崩溃时使用 。Log.Error
- 当出现例外情况,意味着助理顾问(而不是请求)不能继续超过这一点时,即使用这一办法。Log.Warning
- 当某事发生时,这不是一个错误,而是你应该知道的(例如,服务退化/某事) 不太对 但不是错误)。Log.Information
- 这是用来为您应用程序中发生的一切提供一般信息。Log.Debug
- 这是用于信息, 只有在您调试应用程序时才有用( 这是正在开发的“ 每一个地方”, 但生产中应该关闭 ) 。为了生产,我一般会把伐木设为 Log.Fatal
, Log.Error
和 Log.Warning
仅此而已。
相对于启动日志, 这是您应用程序运行时发生的日志 。 这是您在任何特定时间在申请中 发生的事情的日志 。
比方说,在Serilog使用这些,你会这样做:
"Serilog": {
"Enrich": ["FromLogContext", "WithThreadId", "WithThreadName", "WithProcessId", "WithProcessName", "FromLogContext"],
"MinimumLevel": "Warning",
"WriteTo": [
{
"Name": "Seq",
"Args":
{
"serverUrl": "http://seq:5341",
"apiKey": ""
}
},
{
"Name": "Console"
},
{
"Name": "File",
"Args": {
"path": "logs/applog-.txt",
"rollingInterval": "Day"
}
}
],
"Properties": {
"ApplicationName": "mostlylucid"
}
},
正如你将看到的那样,我非常喜欢Serilog; 这是一个伟大的伐木图书馆,非常灵活。 我喜欢的事物之一是 能够用更多的信息 来丰富你的日志 这对于诊断您申请中的问题非常有用。 在上述例子中,你可以看到我正在用线索 ID、线索 名称、进程 ID 和进程 名称来丰富我的日志。 这对于诊断您申请中的问题非常有用。
我将记录设置为多个“sinks”(产出), 在此情况下, 我将发送到控制台、 文件、 以及Seq( 伐木服务) 。
有多个汇是有用的 万一一个失败, 在这种情况下,我更喜欢的伐木服务 是Seq, 所以我先寄到那里。 如果失败了 我就把它送到控制台和档案室
我还在日志中设置了应用程序Name 属性; 如果您有多个应用程序登录到相同的服务( 对于分布式应用程序, 您经常会使用这些应用程序; 并配有相关的标识, 将日志连接在一起, 用于一次请求), 这可能有用 。
例如,如果 JS 前端有一个 JS 前端和一个.NET 后端, 您可以在前端设置相关的 ID, 并将其传给后端 。 这样您就可以在一个地方看到所有单项请求的日志 。 OR 如果在后端使用 HttpClient, 您可以将信头中的对应代号传递到另一个服务 。
网站:https://josef.codes/ append-correlation-id-all-al-log-entries-in-asp-net-core/,
结构化伐木是一种伐木方式,便于搜索和过滤日志。 在Serilog, 您可以使用 Log.Information("This is a log message with {Property1} and {Property2}", property1, property2);
语法。 这样更容易查找带有特定属性的日志。
使用 Serilog, 您也可以使用 LogContext.PushProperty
将仅与特定范围相关的属性添加到您的日志中。 这对于诊断您申请中的问题非常有用。
Serilog 具有超级灵活性, 它允许您以代码配置它, 也可以通过配置配置配置 。 例如,使用上面的配置,你会这样做:
builder.Host.UseSerilog((context, services, configuration) =>
{
configuration
.MinimumLevel.Warning()
.Enrich.FromLogContext()
.Enrich.WithThreadId()
.Enrich.WithThreadName()
.Enrich.WithProcessId()
.Enrich.WithProcessName()
.WriteTo.Seq("http://seq:5341", apiKey: "")
.WriteTo.Console()
.WriteTo.File("logs/applog-.txt", rollingInterval: RollingInterval.Day)
.Enrich.WithProperty("ApplicationName", "mostlylucid");
});
这与上面的配置相同,但在代码中也是如此。 这是有用的, 如果您想要设置您的日志代码; 这真的取决于您是如何做的 。
在 APP.NET 中, 您可以使用例外过滤器来捕捉例外并登录 。 这是确保您在应用程序中记录所有例外的绝佳方式 。 但它不是方法水平记录的一种替代; 您应该仍然在方法水平上登录, 以便您可以详细查看您的应用程序中正在发生的情况; 例外过滤器只是显示当整个请求堆叠不响后会发生什么, 并且往往会非常混乱地找出发生了什么事情 。
这在ASP.NET核心8中已经改变 而且有一个通通可以做这些 新特性.
错误原则同样适用; 您应该登录在方法级别上, 以便您可以详细查看您的应用程序中发生的情况; 例外过滤器/ 状态处理器只显示整个请求堆放不响后会发生的情况, 并且往往会非常混乱地计算出发生的情况 。
日志应该适合环境; 在开发中, 记录所有内容, 以便您在应用中看到每点发生的一切, 但在测试中您需要更少的日志记录( 可能在这里是日志信息), 在生产中您需要更少的日志记录( 警告及以上) 。
将所有产品都记录下来很诱人 但这是个坏主意 你应该记录你需要的一切 来诊断一个问题,但没有更多。 在云源提供者中,您可以很容易地获得发送到日志服务的数据量的收费,这样您就应该小心记录什么以及保留这些日志的时间( 应用观察默认情况下保存日志90天; 这通常是TOO LONG, 只要日志数据被存储, 就会花费您很多时间 ) 。
对于一个非常“ 激活” 的应用程序, 你只要不需要长期记录数据, 就可以很好地了解过去几天的日志在应用程序中发生了什么。
在我所看到的生产中常见的问题是伐木失败的要求;虽然这些要求很有意思(没有人想要404 / 401),但可能是大量的数据,储存费用非常昂贵。 你只应该记录一些东西 您打算修补,对于 404, 这可能很重要,因为它可以显示您应用程序中断开的链接;对于 401, 这可能很重要,因为它可以显示断开的认证系统。
如我上述,这些在(401)中实际发生的代码中处理更好;也许这些代码也应作为(a)或(b)或(b)或(c)或(c)或(c)或(c)或(f)或(c)或(f)或(f)或(f)或(f)或(f)或(f)或(f)或(f)或(f)或(f)或(f)或(f)或(f)或(f)或(f)或(f)或(f)或(f)或(f)或(f)或(f)或(f)或(f)或(f)或(f)或(f)或(f)或(f)或(f)或(f)或(f)或(f)或(f)或(f)或(f)或(f)或(f)或(f)或(f)或(c)或(c)或(c)或(c)或(c)或(c)或(c)或(c)或(c)或(c)或(c)或(c)或(c)或(c)或(c)或(c)或(f(c)或(c)或(c)或(c)或(c)或(c)或(c)或(c)或(c)或(c)或(c)或(c)或(c)或(c)或(f(c)或(c)或(c)或(c)或(f(c)或(c)或(c)或(c)或(c)或或或或或或或或或或(c)或(c)或(c)或(c)或 Warning
或 Error
在实际生成 401 的代码中。
要在 Serilog 设置请求登录, 您可以做到这一点 :
app.UseSerilogRequestLogging();
这将将所有请求登录到您的应用程序; 这是一个很好的方法来查看您的应用程序在高层次上发生的情况; 但是再次, 您应该小心您的日志记录和保留这些日志的时间 。
对于应用程序 Insights 来说,您可能仍想使用信息级别登录, 因为它会给您带来 nifty 用户 Journey 功能; 这是一个很好的方法, 来了解用户如何使用您的应用程序, 并且可以在诊断问题时非常有用; 然而, 这些快速计提成本, 您应该小心记录什么和保留这些日志的时间 。
因此,这就是它,快速运行 如何登录在 ASP.NET 应用程序。 大部分是对我在许多生产应用中看到过热、无用的原木的反应。 发展过程中,你希望看到 应用程序是如何运行的;在您想要看到的制作中 应用程序如何失败. 伐木往往是应用开发中一个毫无用处、费用昂贵的部分。 与软件开发记录中的所有内容一样,应当侧重于USER;无论是您/其他开发商在您本地的IDE / 本地的应用程序中工作时,还是快速高效地解决生产中的问题。