我希望能够使用我的日志通过Hangfires context.console发出事件,这样我就不需要使用context.writeline将日志事件输出到我的hangfire仪表板 .
我试图为此目的实施一个特定的serilog水槽 . 但是由于我需要来自hangfire的PerformContext(在运行时注入任务方法),我无法在应用程序启动时配置日志接收器 . 我试图在任务方法中创建一个新的 Logger ,只是为了查看接收器是否真的有效,但它没有 - 任何人都可以看到它为什么不起作用,或者可能建议采用不同的方法?
这是水槽:
class HangfireContextSink : ILogEventSink {
private readonly IFormatProvider formatProvider;
private readonly PerformContext context;
public HangfireContextSink(IFormatProvider formatProvider, PerformContext context) {
this.formatProvider = formatProvider;
this.context = context;
}
public void Emit(LogEvent logEvent) {
var message = logEvent.RenderMessage(formatProvider);
context.WriteLine(ConsoleTextColor.Blue, DateTimeOffset.Now.ToString() + " " + message);
}
接收器配置:
public static class SinkExtensions {
public static LoggerConfiguration HangfireContextSink(this LoggerSinkConfiguration loggerSinkConfiguration, PerformContext context, IFormatProvider formatProvider = null) {
return loggerSinkConfiguration.Sink(new HangfireContextSink(formatProvider, context));
}
}
任务方法:
public static bool TestJob(PerformContext context) {
using (LogContext.PushProperty("Hangfirejob", "TestJob")) {
try {
using (var hangfireLog = new LoggerConfiguration().WriteTo.HangfireContextSink(context).CreateLogger()) {
var progress = context.WriteProgressBar("Progress");
for (int i = 0; i < 10; i++) {
context.WriteLine("Working with {0}", i);
progress.SetValue((i + 1) * 10);
Log.Debug("Test serilog");
hangfireLog.Debug("Test from hangfirelog");
Thread.Sleep(5000);
}
}
Log.Debug("Done testjob");
return true;
} catch (Exception ex) {
Log.Error(ex, "Error!");
return false;
}
}
}
1 回答
消息不会记录到Hangfire控制台,因为您使用
Debug
日志级别记录它们,而默认的Serilog级别是Information
. 您可以在LoggerConfiguration
上调用.MinimumLevel.Debug()
来更改日志记录级别 . 另外,对于通过Serilog.Log
static class记录消息,您应该设置其Logger
属性 .这是一个将登录到Hangfire控制台的固定代码:
这将起作用,但是为每个作业创建新日志的总体方法非常糟糕 . 您可以通过
LogEvent
中的PerformContext
实例传递实例来避免这种情况 . 您应该定义一个派生自抽象LogEventPropertyValue
的自定义属性类,并公开PerformContext
的实例 .这是最终的代码:
PerformContextProperty.cs:
PerformContextEnricher.cs:
TestJob.cs:
HangfireContextSink.cs:
SinkExtensions.cs:
Serilog configuration:
在Serilog配置中,不要忘记调用
.Enrich.FromLogContext()
,以便使用LogContext
中的属性丰富日志事件 .上面的代码非常简单,这就是为什么我不详细评论它 . 如果您对代码有疑问,请询问,我会尝试解释不清楚的时刻 .