I’m using Serilog for writing to disk and Seq.
I’d like to log to both disk, seq and console simultaneously using a single line of code. E.g.
Log.Information("This is some task related query");
As suppose to:
Log.Information("This is some task related message"); context.WriteLine("This is some task related message");
I followed a guide on how to extend Serilog sink to include Hangfire.Console
logs too (This article here https://www.dennis-s.dk/2019-07/hangfire-console-serilog-sink). However, when Seq tries to serialise the PerformContext property, it throws an error.
could not be formatted into JSON for Seq and will be dropped: System.NotSupportedException: The value x is not of a type supported by this visitor.
Anyone had any experience in getting this behaviour? Or would you just separate the two? Thanks.
Hi @Spinks90
You can solve this issue by using scalar, structured, dictionary property value
internal class PerformContextValue : LogEventPropertyValue
Replace LogEventProperyValue
with ScalarValue
The full class would be:
```
internal class PerformContextValue : ScalarValue
{
public PerformContextValue(object value) : base(value)
{
}
// The context attached to this property value
public PerformContext PerformContext { get; set; }
/// <inheritdoc />
public override void Render(TextWriter output, string format = null, IFormatProvider formatProvider = null)
{
// How the value will be rendered in Json output, etc.
// Not important for the function of this code..
output.Write(PerformContext.BackgroundJob.Id);
}
}
```
Why?
Serilog is using structured data toolkit to serialize objects.
PerformContextValue is unknown for serilog, so you need to let serilog know it is a scalar value
Reference: https://gist.github.com/nblumhardt/bd74fafc61d0c50ec07e0f3715df0d00#file-serilogstructureddatatoolkit-cs
1 Like
Then you can send null in the constructor
public class HangfireConsoleSerilogEnricher : ILogEventEnricher
{
// The context used to enrich log events
public PerformContext PerformContext { get; set; }
/// <inheritdoc />
public void Enrich(LogEvent logEvent, ILogEventPropertyFactory propertyFactory)
{
var prop = new LogEventProperty("PerformContext", new PerformContextValue(null) { PrformContext = PerformContext} );
logEvent.AddOrUpdateProperty(prop);
}
}
1 Like
Awesome, that works a treat. Thanks! 