Cysharp / ZLogger

Zero Allocation Text/Structured Logger for .NET with StringInterpolation and Source Generator, built on top of a Microsoft.Extensions.Logging.
MIT License
1.25k stars 88 forks source link

Prefix for printing DateTime with miliseconds ? #54

Closed genaray closed 2 years ago

genaray commented 2 years ago

Can anyone please explain how the heck we are supposed to print "dd-MM-YYYY HH:mm:ss.fff" format ? Yes i read the git section "DateTime" but it doesnt really help me at all...

This is my current code :

                builder.AddZLoggerConsole(options => {

                    // Tips: use PrepareUtf8 to achive better performance.
                    var prefixFormat = ZString.PrepareUtf8<LogLevel, DateTime>("[{0}][{1}]");
                    options.PrefixFormatter = (writer, info) => prefixFormat.FormatTo(ref writer, info.LogLevel, info.Timestamp.DateTime.ToLocalTime());
                });

Which only prints "dd-MM-YYYY HH:mm:ss"... how do we add milliseconds to it ?

github-actions[bot] commented 2 years ago

This issue is stale because it has been open 90 days with no activity. Remove stale label or comment or this will be closed in 7 days.

robertmircea commented 1 year ago

If the issue is still valid for you, the only solution I found it working is to use the following prefix formatting:

    logging.AddZLoggerConsole(options =>
    {
        var prefixFormat = ZString.PrepareUtf8<int, int, int, int, int, int, int, LogLevel>("{0:D4}-{1:D2}-{2:D2} {3:D2}:{4:D2}:{5:D2}.{6:D3} [{7}] ");
        options.PrefixFormatter = (writer, info) =>
        {
            var nowLocalTime = info.Timestamp.DateTime.ToLocalTime();
            prefixFormat.FormatTo(ref writer,
                nowLocalTime.Year,
                nowLocalTime.Month,
                nowLocalTime.Day,
                nowLocalTime.Hour,
                nowLocalTime.Minute,
                nowLocalTime.Second,
                nowLocalTime.Millisecond,
                info.LogLevel);
        };
    });

This is because Zlogger uses Utf8Formatter.TryFormat from Microsoft, and this function does not support formatting dates with other formats apart from what is documented at Utf8Formatter.TryFormat-system-int32@-system-buffers-standardformat)). So instead of using DateTime, I deconstruct the current date time in its constituents (year, month, day, hours, etc.) and then use one of the PrepareUtf8 generic overloads to format those integers in date format. D4, D2, D3 formats for integers are passed by the library directly to Utf8Formatter.TryFormat to format with 4, 2 or 3 leading digits in total including the leading zero if necessary.

The above code produces the following log messages:

2022-12-30 01:09:07.298 [Information] Now listening on: http://localhost:5178
2022-12-30 01:09:07.299 [Information] Application started. Press Ctrl+C to shut down.
2022-12-30 01:09:07.299 [Information] Hosting environment: Development