Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ZeroLog.Core ? #57

Closed
roubachof opened this issue Aug 4, 2022 · 6 comments
Closed

ZeroLog.Core ? #57

roubachof opened this issue Aug 4, 2022 · 6 comments
Labels

Comments

@roubachof
Copy link

roubachof commented Aug 4, 2022

Hi there!
I'm in love with your zero allocation implementation since I'm a big fan of Span and stackalloc :)
I was in the process of doing that myself and stumble upon your great framework.
And then I had a thought:
It would be super great to have a ZeroLog.Core nuget implementing the core of a logging framework, then all the existing logging framework could re-implement their string management with this package and boom, you made the world sustainable again!

@ltrzesniewski
Copy link
Member

Hello!

I'm not sure what you mean: ZeroLog has some very tightly coupled code in order to be as efficient as possible. We coupled it even more in v2 (v1 used interfaces that we replaced with implementing classes directly just to avoid interface calls that use virtual stub dispatch). Extracting a core package would go against that goal.

@roubachof
Copy link
Author

well it's simple, in fact logging frameworks are 2 things:

  1. handling string interpolation efficiently,
  2. tons of features (to console, to file, to json, json configuration, code configuration, log levels, loggly sink, compressions, etc....).

Features and string handling are perfectly decoupled. Once the string is built, you just have to send it to targets.
Same for the configuration.

@ltrzesniewski
Copy link
Member

Well, in that case, I think ZeroLog already does what you want. 🙂

You can consider its primary job is the first point you mention, but it is still designed to be extensible (your second point):

  • You can supply your own appender that derives from ZeroLog.Appenders.Appender (or StreamAppender) if you need to add a new sink.
  • You can supply your own formatter ZeroLog.Formatting.Formatter if you need another log format. We may implement logfmt or ndjson formats in the future.

As for your first point, there are a few ways to extend it as well:

  • You can write extension methods on LogMessage for your own types (we have a few of those in our codebase).
  • You can use an LogMessage.AppendOperation<T> in interpolated strings.

That's something I should document I suppose. 🙂

@roubachof
Copy link
Author

Yup, after thorough digging, it seems that all the concepts (LogMessage, LogManager, Formatter, etc...) are too tied together to be able to extract a core string interpolation management lib...
Unfortunately, we can't extend either ZeroLog in a mobile cross platform context since it emits IL (well only for enum cache but still :), doing so it is not compatible with iOS.

@roubachof
Copy link
Author

mmmh, would you be opened to a PR replacing the IL emit by some good old Convert.ToUInt64 in case of targeting net6-ios ?
We could use preprocessor directives something like

#if __IOS__
public static ulong ToUInt64(Enum value)
    {
        // Only used when registering enums.

        return Type.GetTypeCode(Enum.GetUnderlyingType(value.GetType())) switch
        {
            TypeCode.SByte  => Convert.ToUInt64((sbyte)(object)value),
            TypeCode.Byte   => Convert.ToUInt64((byte)(object)value),
            TypeCode.Int16  => Convert.ToUInt64((short)(object)value),
            TypeCode.UInt16 => Convert.ToUInt64((ushort)(object)value),
            TypeCode.Int32  => Convert.ToUInt64((int)(object)value),
            TypeCode.UInt32 => Convert.ToUInt64((uint)(object)value),
            TypeCode.Int64  => Convert.ToUInt64((long)(object)value),
            TypeCode.UInt64 => Convert.ToUInt64((ulong)(object)value),
            _               => throw new InvalidOperationException($"Invalid enum: {value.GetType()}")
        };
    }
#else
[MethodImpl(MethodImplOptions.AggressiveInlining)]
    [SuppressMessage("ReSharper", "UnusedParameter.Global")]
    [SuppressMessage("ReSharper", "EntityNameCapturedOnly.Global")]
    public static ulong ToUInt64<T>(T value)
    {
        Ldarg(nameof(value));
        Conv_I8();
        return IL.Return<ulong>();
    }
#endif

@ltrzesniewski
Copy link
Member

ltrzesniewski commented Aug 4, 2022

Actually, it doesn't emit IL at runtime. v1 did that, but we removed it in v2.

The IL you see is "emitted" at compile time (see https://github.com/ltrzesniewski/InlineIL.Fody).

@ltrzesniewski ltrzesniewski closed this as not planned Won't fix, can't repro, duplicate, stale Oct 3, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants