- VisualStudio2022插件的安装及使用-编程手把手系列文章
- pprof-在现网场景怎么用
- C#实现的下拉多选框,下拉多选树,多级节点
- 【学习笔记】基础数据结构:猫树
Serilog 大多数情况下“只需使用”,并且在创建和处理日志记录器时不需要过多考虑。然而,由于以下原因:
某些接收器(sink)涉及后台进程,特别是那些使用网络的接收器; 。
一些接收器(尤其是文件和滚动文件接收器)所持有的资源; 。
因此,某些使用模式在效果和可靠性上表现得更好.
使用 Serilog 最简单的方法是通过全局 Log 类:
Log.Logger = new LoggerConfiguration()
.WriteTo.File(@"myapp\log.txt")
.CreateLogger();
Log.Information("Hello!");
// Your application runs, then:
Log.CloseAndFlush();
如果这样做,只需配置一次日志记录器,然后在应用程序的整个生命周期中使用它.
要创建更专业的日志记录器:
调用 Log.ForContext(...) 来接收一个附加了额外属性的 ILogger;这不需要任何特殊的关闭/刷新逻辑,因为这将由父日志记录器处理.
在少数情况下,可以使用单独的 LoggerConfiguration 创建一个额外的 ILogger,并使用 WriteTo.Logger(Log.Logger) 将事件传递到根日志记录器;在这种情况下,必须遵循下面的处置逻辑.
如果您不希望使用静态 Log 类,可以使用 LoggerConfiguration 创建一个 ILogger.
using (var log = new LoggerConfiguration()
.WriteTo.File(@"myapp\log.txt")
.CreateLogger())
{
log.Information("Hello again!");
// Your app runs, then disposal of `log` flushes any buffers
}
在这种情况下,不使用 Log.CloseAndFlush()。相反,当应用程序不再需要日志记录器时,会进行处置.
只有通过 LoggerConfiguration 创建的根日志记录器需要以这种方式处理。从 ForContext() 和类似方法返回的 ILoggers 不需要任何特殊处理.
请参见 Autofac 集成示例,了解如何与 Autofac IoC 容器一起使用可注入的 ILoggers。如果您希望更新此页面以提供其他容器的说明,请提出问题.
Serilog 认为,综合考虑,日志记录的优先级低于其他应用程序代码,绝不应在可避免的情况下影响正在运行的应用程序的操作.
在实践中,这主要转化为一种处理 Serilog 中异常的策略。在这个过程中会对可用性做出一些妥协。本文档解释了作为 Serilog 库用户您可以期待的内容,以及如果您正在扩展 Serilog,如何编写与其余代码库良好配合的代码.
在配置时,即调用 LoggerConfiguration 方法时,错误分为两类.
运行时配置错误 。
如果由于主机机器的运行时状态无法配置接收器(sink),Serilog 将捕获任何导致的异常并将其写入 SelfLog(参见调试和诊断).
// X: does not exist, but this is a runtime condition
// so Serilog will not fail here.
Log.Logger = new LoggerConfiguration()
.WriteTo.File("X:\\log.txt")
.CreateLogger();
这种策略可以防止部署环境中的暂时性问题导致原本有效的应用程序失败.
开发时不变性违规 。
在配置时,对于永远无法有效执行的代码(例如,违反 API 不变性的情况)会做出一定的容忍:
// Null is never acceptable as a filename, so
// Seriog will throw ArgumentNullException here.
Log.Logger = new LoggerConfiguration()
.WriteTo.File(null)
.CreateLogger();
这一决定基于两个原因:
这些错误不太可能通过开发者的工作站或测试环境,因为日志记录配置发生在启动时,并且应该总是以相同的方式失败.
允许无效值或静默忽略它们会导致意外行为,这很难调试,并使库的正确配置更加困难.
如果您愿意,可以将日志记录配置代码包装在 try/catch 结构中,以避免异常传播,但不推荐这样做.
接收器作者: 实现这一点的责任在于接收器的实现本身,因此需要明确考虑/处理.
事件分阶段写入日志记录管道。首先调用记录器,然后构造事件,接下来对其进行丰富,应用过滤器,最后将其传递(“发出”)到配置的接收器.
调用记录器 。
ILogger 和静态 Log 类上的方法会静默忽略无效参数:
// Safely does nothing
Log.Warning(null);
这样做是因为在执行频率较低的代码路径中的日志记录语句可能不会被测试,因此不应在运行时失败.
构造日志事件 。
当构造日志事件时,Serilog 可能会反射任何解构对象的属性.
如果这些属性抛出异常,Serilog 会捕获错误,写入 SelfLog,并在解构对象中包含错误信息而不是属性值.
关于类型加载的说明 。
如果一个应用程序在没有所需依赖项的情况下部署,加载器可能会无法找到/构造有效类型。这是一个主要的应用程序配置错误,可能在解构过程中或稍后,例如在 JIT 阶段显现出来。这种情况非常罕见。在这种情况下,Serilog 不会做任何事情,允许错误传播.
装饰器 。
装饰器向日志事件添加属性。装饰器可能会抛出异常:Serilog 会捕获这些异常并写入 SelfLog.
装饰器作者: Serilog 自身实现了这一策略,装饰器在意外失败时应抛出异常(尽管出于性能考虑,避免这种情况是明智的).
过滤器 。
过滤器决定哪些事件会被传递到日志记录管道中。过滤器不会抛出异常,而是写入 SelfLog:
// No events will be carried through this pipeline, but no
// errors will be thrown.
Log.Logger = new LoggerConfiguration()
.Filter.ByExcluding(e => { throw new Exception(); })
.WriteTo.ColoredConsole()
.CreateLogger();
过滤器作者: 如果过滤器意外抛出异常,这被视为一个错误——这对性能和功能的影响是显著的.
发出到接收器 。
Serilog 捕获并将接收器引发的任何异常写入 SelfLog。通常情况下,这些异常是正常使用 Serilog 时发生的绝大多数异常.
接收器作者: 接收器在失败时应抛出异常。Serilog 将一致地捕获和处理这些异常.
关于不可捕获的异常的说明 。
需要注意的是,仍然存在一类不可捕获的异常,Serilog 被迫传播这些异常,例如 StackOverflowException 等.
许多 Serilog 接收器使用相同的基础 PeriodicBatchingSink 架构。这些接收器(例如批处理的 Azure 表存储接收器、CouchDB 接收器、RavenDB 接收器和 Seq 接收器(在非持久模式下))会缓存日志事件,从而减少将日志数据传输到远程主机所需的网络往返次数.
Log.Logger = new LoggerConfiguration()
.WriteTo.CouchDB("api/missing")
.CreateLogger()
这些接收器在写入事件时不会失败,但可能会在后台异步发送批次时失败。当批次发送失败时,详细信息将写入 SelfLog.
正在发送的批次将保留在内存中,并会以逐渐增加的时间间隔重试,时间间隔从 5 秒逐步增加到 10 分钟。增加的时间间隔可以保护接收器,在经历一段停机后重新上线时,避免连接洪水.
如果经过 4 次尝试仍无法发送批次,该批次将被丢弃并尝试新的批次。这可以防止接收器拒绝的“坏”事件堵塞日志记录器。后续的成功将允许其他批次正常传输.
如果再有两次尝试失败(总共 6 次失败,通常在 10 分钟左右),等待的日志事件的整个缓冲区将被丢弃。这可以防止在日志事件长时间无法送达时出现内存不足错误.
如果连接仍然中断,缓冲区将每 10 分钟刷新一次,直到重新建立连接.
接收器作者: 通过从 PeriodicBatchingSink 派生,可以默认提供此行为。如果需要不同的行为,则需要实现自定义的 ILogEventSink.
注:相关源码都已经上传至代码库,有兴趣的可以看看。https://gitee.com/hugogoos/Planner 。
最后此篇关于Serilog文档翻译系列(八)-记录器的生命周期、可靠性的文章就讲到这里了,如果你想了解更多关于Serilog文档翻译系列(八)-记录器的生命周期、可靠性的内容请搜索CFSDN的文章或继续浏览相关文章,希望大家以后支持我的博客! 。
已关闭。这个问题是 off-topic 。目前不接受答案。 想要改进这个问题吗? Update the question所以它是on-topic用于堆栈溢出。 已关闭10 年前。 Improve th
我正在尝试将 JSON 发送到我的服务器并作为结果检索 JSON。例如发送用户名和密码并取回 token 和其他内容。 这就是我正在为发送的 HTTP 请求所做的。我现在如何检索同一请求中的内容?
我有以下 xts 矩阵: > options(digits.secs = 6) > set.seed(1234) > xts(1:10, as.POSIXlt(1366039619, tz="EST"
我目前正在开发一个应用程序,当用户到达某个位置时,它会提醒用户。我希望这个应用程序也在后台运行并搜索解决方案。 在 AppStore 中,我发现了一款名为“Sleep Cycle”的应用程序,它可
我想创建一个基于 farbtastic color picker 的颜色选择器。我想要实现的是添加我想要链接到色轮的 RGB slider 。这是我到目前为止所拥有的。 app.controller(
RFC 5545 允许 RDATE 属性具有 PERIOD 数据类型。该数据类型的语义是什么?据我所知,这是未指定的。它会改变事件的持续时间吗?如果时区更改且没有持续时间怎么办? 最佳答案 尽管我
在 CodinGame学习平台,C# 教程中用作示例的问题之一是: The aim of this exercise is to check the presence of a number in a
我听说网上有一本英特尔书,它描述了特定汇编指令所需的 CPU 周期,但我找不到(经过努力)。谁能告诉我如何找到CPU周期? 这是一个例子,在下面的代码中,mov/lock 是 1 个 CPU 周期,x
据我所知,Java GC有次要GC(低成本)和主要GC周期(高成本)。如果对象在本地范围内,则会在 Minor GC 中清理它。如果对象的引用存储在代码中的其他位置,则它会在主 GC 中被清除。 例如
到目前为止,我有一个很好的自旋锁,可以用作 intendend: std::atomic_flag barrier = ATOMIC_FLAG_INIT; inline void lo
晚上好,我将 cycle2 与 prev 和 next 函数一起使用,但我无法将 prev 和 next 函数置于图像下方的中心。我环顾四周,我知道这会很愚蠢,但我就是看不到它。非常令人沮丧。谢谢加里
出于教育目的,我想知道在优化(在不同级别)和编译之后执行函数需要多少 CPU 周期。有没有办法分析代码或可执行文件以获得可重现的答案?我在 64 位 Windows 7 Pro 上使用 Eclipse
我想彻底测量和调整我的 C/C++ 代码,以便在 x86_64 系统上更好地使用缓存。我知道如何使用计数器(我的 Windows 机器上的 QueryPerformanceCounter)来测量时间,
我尝试将一些数据分组到每四周一次的存储桶中,并使用 pd.Grouper(key='created_at', freq='4W')。我希望这些组是这样的,如果我有从 2019-08-26 到 2019
我正在做一个关于随机数的大型学校项目,但我找不到 Math.random() 的句点。我安装了 7.0.800.15 版本,并且正在使用 Windows 10 计算机。我试过用一个简单的程序来确定周期
我正在努力解决我们生产环境中垃圾收集利用率高的问题,我想知道设置一个大的堆大小来保证老年代永远不会被填满是否会阻止触发主要的 GC 周期。 为了实现这一点,我想有一个特定的阈值标记会触发主要的 GC
我想测量在 Python 3 中执行加法运算所需的时钟周期数。 我写了一个程序来计算加法运算的平均值: from timeit import timeit def test(n): for i
我正在寻找一种方法来测量线程上的函数调用所花费的 cpu 周期。 示例伪代码: void HostFunction() { var startTick = CurrentThread.Cur
就 CPU 周期而言,malloc() 的成本是多少?(Vista/OS,最新版本的 gcc,最高优化级别,...) 基本上,我正在实现一个复杂的 DAG 结构(类似于链表)由一些 16B(不太常见)
C/C++ 中的类型转换会导致额外的 CPU 周期吗? 我的理解是,至少在某些情况下应该消耗额外的 CPU 周期。就像从浮点类型转换为整数一样,CPU 需要将浮点结构转换为整数。 float a=2.
我是一名优秀的程序员,十分优秀!