- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
我们有一个相当简单的 netstandard2.0
自定义中间件项目,它使用 Serilog 的静态 LogContext 将指定的 HttpContext header 复制到日志上下文。
我正在尝试编写一个单元测试,我在其中设置了一个使用 DelegatingSink
写入变量的记录器。然后它执行 Invoke()
中间件方法。然后我尝试使用该事件来断言属性已添加。到目前为止,中间件添加的属性没有显示,但我在测试中添加的属性显示了。我假设它正在处理不同的上下文,但我不确定如何解决这个问题。我尝试了几种不同的方法,但都没有奏效。
由于 LogContext
是静态的,我认为这会非常简单,但我低估了某些东西。这就是我现在所在的位置(为简洁起见省略了一些代码)。我确实确认了中间件的 LogContext.PushProperty
行 在其余部分运行时被命中。
测试:
...
[Fact]
public async Task Adds_WidgetId_To_LogContext()
{
LogEvent lastEvent = null;
var log = new LoggerConfiguration()
.Enrich.FromLogContext()
.WriteTo.Sink(new DelegatingSink(e => lastEvent = e))
.CreateLogger();
// tried with and without this, also tried the middleware class name
//.ForContext<HttpContextCorrelationHeadersLoggingMiddlewareTests>();
var context = await GetInvokedContext().ConfigureAwait(false);
LogContext.PushProperty("MyTestProperty", "my-value");
log.Information("test");
// At this point, 'lastEvent' only has the property "MyTestProperty" :(
}
private async Task<DefaultHttpContext> GetInvokedContext(bool withHeaders = true)
{
RequestDelegate next = async (innerContext) =>
await innerContext.Response
.WriteAsync("Test response.")
.ConfigureAwait(false);
var middleware = new MyCustomMiddleware(next, _options);
var context = new DefaultHttpContext();
if (withHeaders)
{
context.Request.Headers.Add(_options.WidgetIdKey, _widgetId);
}
await middleware.Invoke(context).ConfigureAwait(false);
return context;
}
中间件(测试项目引用本项目):
...
public async Task Invoke(HttpContext context)
{
if (context == null || context.Request.Headers.Count == 0) { await _next(context).ConfigureAwait(false); }
var headers = context.Request.Headers;
foreach (var keyName in KeyNames)
{
if (headers.ContainsKey(keyName))
{
LogContext.PushProperty(keyName, headers[keyName]);
}
}
await _next(context).ConfigureAwait(false);
}
...
这是我从 Serilog 测试源中窃取的委托(delegate)接收器:
public class DelegatingSink : ILogEventSink
{
readonly Action<LogEvent> _write;
public DelegatingSink(Action<LogEvent> write)
{
_write = write ?? throw new ArgumentNullException(nameof(write));
}
public void Emit(LogEvent logEvent)
{
_write(logEvent);
}
public static LogEvent GetLogEvent(Action<ILogger> writeAction)
{
LogEvent result = null;
var l = new LoggerConfiguration()
.WriteTo.Sink(new DelegatingSink(le => result = le))
.CreateLogger();
writeAction(l);
return result;
}
}
最佳答案
我还必须对已记录事件的推送属性进行单元测试。假设您正在插入您的属性(property)如下:
public async Task<T> FooAsync(/*...*/)
{
/*...*/
using (LogContext.PushProperty("foo", "bar"))
{
Log.Information("foobar");
}
/*...*/
}
您可以使用 Serilog.Sinks.TestCorrelator 像这个例子一样对其进行单元测试作为专用于测试的 Serilog 接收器(我在这里也使用 NUnit 和 FluentAssertion):
[Test]
public async Task Should_assert_something()
{
///Arrange
// I had issues with unit test seeing log events from other tests running at the same time so I recreate context in each test now
using (TestCorrelator.CreateContext())
using (var logger = new LoggerConfiguration().WriteTo.Sink(new TestCorrelatorSink()).Enrich.FromLogContext().CreateLogger())
{
Log.Logger = logger;
/*...*/
/// Act
var xyz = await FooAsync(/*...*/)
/*...*/
/// Assert
TestCorrelator.GetLogEventsFromCurrentContext().Should().ContainSingle().Which.MessageTemplate.Text.Should().Be("foobar");
}
}
关于c# - 如何对 Serilog 的 LogContext 属性进行单元测试,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57227172/
我正在寻找一种为 serilog 提供独立 XML/JSON 配置文件的方法,该文件是从应用程序本身运行的目录中动态加载的。 我正在寻找类似的东西 NLog provides .如 Nlog#Conf
我在我的 aspnet core 应用程序中使用 Serilog 进行日志记录。我需要频繁地将日志事件写入控制台(每秒 300-500 个事件)。我在 docker 容器内运行我的应用程序,并使用 O
是否可以创建一个自动为每条消息添加前缀的记录器? 我通常在每条消息前加上帐户前缀,因为这样更容易阅读,像这样: user1 - did something user2 - did another th
我具有动态更改日志文件路径的功能。但是,当我更改 Consul 中可配置的路径时,它会在两个地方(即旧路径和新路径)写入部分日志。更改日志文件路径应该可以在没有任何服务重启的情况下工作。我们如何存档?
我有很多这样的日志: Log.Information("Submitting order {@order}", order); 此日志通过 RabbitMq -> LogStash -> Elasti
我有很多这样的日志: Log.Information("Submitting order {@order}", order); 此日志通过 RabbitMq -> LogStash -> Elasti
我在服务器端使用 Serilog 为我所有的 .NETCore 服务使用控制台、文件和 Graylog 接收器。我也喜欢在我的 Windows 胖客户端(WPF 应用程序)中使用它。 与 后者我有问题
我正在使用 Serilog.Extensions.Logging 并使用此 outputTemplate 输出到控制台: "{Timestamp:HH:mm} [{Level:u3}] {Messag
Date时间的RollingFile Sink的当前输出如下 2015-04-06 18:40:54.400 +10:00 [Information] Hello World! 无论如何,有没有要消除
我使用 Serilog 作为 .NET 的库,它为文件、控制台和其他地方提供诊断日志记录。 我的问题是我在我的代码中声明了一些日志记录事件,但是在查看 Windows 事件查看器时,分配给我的日志的事
Serilog 的 Azure 表存储接收器是否可以像其他接收器(例如 Elasticsearch 和 Seq)一样通过 app/Web.config 配置,这些接收器可以从配置文件进行配置。 Azu
我正在使用 SeriLog 登录基于 IdentityServer3 的身份验证服务。我刚刚将 serilog.sinks.literate 插件替换为 serilog.sinks.file 插件,以
我使用 Serilog 作为 .NET 的库,它为文件、控制台和其他地方提供诊断日志记录。 我的问题是我在我的代码中声明了一些日志记录事件,但是在查看 Windows 事件查看器时,分配给我的日志的事
我正在尝试安装 serilog,但出现错误 PM> Install-Package Serilog Install-Package : 'Serilog' already has a dependen
从 nlog 转移到 serilog,我希望我的 .NET 框架桌面应用程序在每次运行时重用一个静态命名的日志文件,但在每个新进程中清除文件的内容。可以这样配置serilog吗? This is a
serilog 的可用接收器位于此处:https://github.com/serilog/serilog/wiki/Provided-Sinks 但不包括蔚蓝服务巴士。 目前是否正在努力创建一个?如
我要写 Serilog Warning .NET 集合中的事件,以便它们可以包含在给用户的报告中。我该怎么做 configure the static Log.Logger 写信给类似 static
我尝试在结构化模式下将 JSNLog 与 Serilog 一起使用,如文档中所述: http://jsnlog.com/Documentation/HowTo/StructuredLogging 我在
我正在从 log4net 切换到 Serilog,但错过了我在 log4net 中的一些格式化可能性。我没有找到关于我可以在 outputTemplate 中使用哪些格式化程序的任何文档。有什么方法可
我远不是具有任何 .net 经验的开发人员,但工作中的开发团队希望使用 Serilog 和 serilog-sinks-elasticsearch 将日志推送到我的 ELK 堆栈中。 查看 seril
我是一名优秀的程序员,十分优秀!