datalust / seq-extensions-logging

Add centralized log collection to ASP.NET Core apps with one line of code.
https://datalust.co/seq
Apache License 2.0
84 stars 12 forks source link

Cannot expand objects #54

Open bitbonk opened 8 months ago

bitbonk commented 8 months ago

Since .NET 6, the preferred way to log (according to Microsoft), is using the the LoggerMessageAttribute, which causes the source generation of a strongly typed log message. Quite often, the LogPropertiesAttribute is used with it, which will cause all properties of the object to be added as properties to the log.

A typical way to use this would look like this:

internal static partial class LogPropertiesExampleExtensions
{
    [LoggerMessage(LogLevel.Information, Message = "Example log of MyProps {MyProps}")]
    public static partial void LogMyProp(this ILogger logger, [LogProperties] MyProps myProps);
}

where MyProps is a complex object that looks like this (stolen from a Microsoft.Extensions unit test):

internal class MyProps
{
    public DateTime P0 { get; set; }
    public DateTimeOffset P1 { get; set; }
    public TimeSpan P2 { get; set; }
    public Guid P3 { get; set; }
    public Version? P4 { get; set; }
    public Uri? P5 { get; set; }
    public IPAddress? P6 { get; set; }
    public EndPoint? P7 { get; set; }
    public IPEndPoint? P8 { get; set; }
    public DnsEndPoint? P9 { get; set; }
    public BigInteger P10 { get; set; }
    public Complex P11 { get; set; }
    public Matrix3x2 P12 { get; set; }
    public Matrix4x4 P13 { get; set; }
    public Plane P14 { get; set; }
    public Quaternion P15 { get; set; }
    public Vector2 P16 { get; set; }
    public Vector3 P17 { get; set; }
    public Vector4 P18 { get; set; }
    public TimeOnly P19 { get; set; }
    public DateOnly P20 { get; set; }
    public Dictionary<string, object>? P21 { get; set; }
}

The problem now is, that there doesn't seem to be a way to expand all properties of the object (MyProps) in Seq (so that it appears as proper highlighted json).

When I log something like this

_logger.LogMyProp(new MyProps()
{
    P0 = DateTime.Now,
    P1 = DateTimeOffset.Now,
    P2 = new TimeSpan(1234),
    P3 = Guid.NewGuid(),
    P4 = new Version(1, 2, 3, 4),
    P5 = new Uri("https://www.microsoft.com"),
    P6 = IPAddress.Parse("192.168.10.1"),
    P7 = new IPEndPoint(IPAddress.Parse("192.168.10.1"), 42),
    P8 = new IPEndPoint(IPAddress.Parse("192.168.10.1"), 42),
    P9 = new DnsEndPoint("microsoft.com", 42),
    P10 = new BigInteger(3.1415),
    P11 = new Complex(1.2, 3.4),
    P12 = new Matrix3x2(1, 2, 3, 4, 5, 6),
    P13 = new Matrix4x4(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16),
    P14 = new Plane(1, 2, 3, 4),
    P15 = new Quaternion(1, 2, 3, 4),
    P16 = new Vector2(1),
    P17 = new Vector3(1, 2, 3),
    P18 = new Vector4(1, 2, 3, 4),
    P19 = new TimeOnly(123),
    P20 = new DateOnly(2022, 6, 21),
    P21 = new Dictionary<string, object>()
    {
       ["DictP0"] = DateTime.Now,
       ["DictP1"] = DateTimeOffset.Now,
       ["DictP2"] = new TimeSpan(1234)
    }
});

Seq has all the expanded properties at the top level but the JSON of its values are just dumb strings (no highlighting no expand and collapse) and I don't see a way to make them expand:

image

If I remove the [LogProperties] attributes so that the top level properties are not added to the log entry, I also do not get any expansion at all:

image

Trying to add an @ to the property in the template like this

internal static partial class LogPropertiesExampleExtensions
{
    [LoggerMessage(LogLevel.Information, Message = "Example log of MyProps {@MyProps}")]
    public static partial void LogMyProp(this ILogger logger, MyProps myProps);
}

will give me the following compiler error:

[LOGGEN031] Logging method "LogMyProp" has template(s) that start with "@": @MyProps (https://aka.ms/dotnet-extensions-warnings/LOGGEN031)

So as far as I can tell there doesn't seem to be any way to get the fully expanded object into Seq. It would be very nice, if Seq could fully support the new way of logging with Microsoft.Extensions, if possible. Note that I am currently not using Serilog as a logging provider for Microsoft.Extensions.Logging. Maybe there is a way to solve this problem if I would?

nblumhardt commented 8 months ago

Thanks for raising this @bitbonk, needs some investigation, we'll dig into it :+1: