消息不会记录到Hangfire控制台,因为您使用
Debug
日志级别,而默认Serilog级别为
Information
。您可以通过调用更改日志记录级别
.MinimumLevel.Debug()
在…上
LoggerConfiguration
。还用于通过以下方式记录消息
Serilog.Log
静态类,您应该设置
Logger
所有物
以下是将登录到Hangfire控制台的固定代码:
using (LogContext.PushProperty("Hangfirejob", "TestJob"))
{
try
{
using (var hangfireLog = new LoggerConfiguration().MinimumLevel.Debug().WriteTo.HangfireContextSink(context).CreateLogger())
{
// This is a dirty code that will be removed in final solution
var prevLogger = Log.Logger;
Log.Logger = hangfireLog;
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");
Log.Logger = prevLogger;
}
return true;
}
catch (Exception ex)
{
Log.Error(ex, "Error!");
return false;
}
}
这将起作用,但为每个作业创建新日志的总体方法非常糟糕。您可以通过传递
PerformContext
通过中的属性
LogEvent
。您应该定义从抽象
LogEventPropertyValue
并公开
PerformContext
。
以下是最终代码:
PerformContextProperty。cs:
public class PerformContextProperty : LogEventPropertyValue
{
public PerformContext PerformContext { get; }
public PerformContextProperty(PerformContext performContext)
{
PerformContext = performContext;
}
public override void Render(TextWriter output, string format = null, IFormatProvider formatProvider = null)
{
}
}
PerformContextEnricher。cs:
public class PerformContextEnricher : ILogEventEnricher
{
private readonly PerformContext performContext;
public PerformContextEnricher(PerformContext performContext)
{
this.performContext = performContext;
}
public void Enrich(LogEvent logEvent, ILogEventPropertyFactory propertyFactory)
{
logEvent.AddPropertyIfAbsent(new LogEventProperty(HangfireContextSink.PerformContextProperty, new PerformContextProperty(performContext)));
}
}
测试作业。cs:
public class TestJob
{
public static bool Execute(PerformContext context)
{
using (LogContext.PushProperty("Hangfirejob", "TestJob"))
using (LogContext.Push(new PerformContextEnricher(context)))
{
try
{
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", context);
Log.Debug("Test from hangfirelog");
Thread.Sleep(5000);
}
Log.Debug("Done testjob");
return true;
}
catch (Exception ex)
{
Log.Error(ex, "Error!");
return false;
}
}
}
}
HangfireContextSink。cs:
class HangfireContextSink : ILogEventSink
{
public const string PerformContextProperty = "PerformContext";
private readonly IFormatProvider formatProvider;
public HangfireContextSink(IFormatProvider formatProvider)
{
this.formatProvider = formatProvider;
}
public void Emit(LogEvent logEvent)
{
var message = logEvent.RenderMessage(formatProvider);
LogEventPropertyValue propertyValue;
if (logEvent.Properties.TryGetValue(PerformContextProperty, out propertyValue))
{
var context = (propertyValue as PerformContextProperty)?.PerformContext;
context?.WriteLine(ConsoleTextColor.Green, DateTimeOffset.Now + " " + message);
}
}
}
下沉延伸。cs:
public static class SinkExtensions
{
public static LoggerConfiguration HangfireContextSink(this LoggerSinkConfiguration loggerSinkConfiguration, IFormatProvider formatProvider = null)
{
return loggerSinkConfiguration.Sink(new HangfireContextSink(formatProvider));
}
}
Serilog配置:
Log.Logger = new LoggerConfiguration()
.Enrich.FromLogContext()
.MinimumLevel.Debug()
.WriteTo.HangfireContextSink()
.CreateLogger();
在Serilog配置中,不要忘记调用
.Enrich.FromLogContext()
这样,日志事件就可以通过
LogContext
。
上面的代码非常简单,这就是为什么我不详细注释它的原因。如果您对代码有一些问题,请提问,我将尝试解释不清楚的时刻。