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

Request for Logging Internals to be public again #35060

Closed
JakenVeina opened this issue Feb 24, 2020 · 15 comments · Fixed by #40568
Closed

Request for Logging Internals to be public again #35060

JakenVeina opened this issue Feb 24, 2020 · 15 comments · Fixed by #40568
Labels
api-approved API was approved in API review, it can be implemented area-Extensions-Logging help wanted [up-for-grabs] Good issue for external contributors
Milestone

Comments

@JakenVeina
Copy link
Contributor

Use case: I'd like to have a LoggerMessage.Define() method that accepts more than 5 type args. I'm perfectly happy to implement this myself, by just copying how the others are done, in my own project, and adding more type args. However, the existing implementations rely on the internal LogValuesFormatter class, which used to be public within a .Internals namespace.

For now, my solution is simply to copy/paste the entire LogValuesFormatter class into my own project, which just seems like a waste.

Alternatively, could we simply get LoggerMessage.Define() methods that take more type args? Perhaps up to 8, like Action<T>, Func<T>, ValueTuple<T> etc? Is there some particular performance reason that more than 5 type args would be disadvantageous?

I'm happy to PR this myself, so long as no one is opposed to the change.

@davidfowl
Copy link
Member

Alternatively, could we simply get LoggerMessage.Define() methods that take more type args? Perhaps up to 8, like Action, Func, ValueTuple etc? Is there some particular performance reason that more than 5 type args would be disadvantageous?

This sounds reasonable.Would you like to send a PR?

@JakenVeina
Copy link
Contributor Author

Certainly.

@maryamariyan
Copy link
Member

@JakenVeina please note you can now find the Logging source code in the dotnet/runtime repository.

You might want to check these instruction links below:

I'll transfer this issue to runtime repo now.

@maryamariyan
Copy link
Member

I just noticed your PR :)

@maryamariyan maryamariyan transferred this issue from dotnet/extensions Apr 16, 2020
@Dotnet-GitSync-Bot Dotnet-GitSync-Bot added area-Meta untriaged New issue has not been triaged by the area owner labels Apr 16, 2020
@maryamariyan maryamariyan added area-Extensions-Logging help wanted [up-for-grabs] Good issue for external contributors and removed area-Meta untriaged New issue has not been triaged by the area owner labels Apr 16, 2020
@maryamariyan maryamariyan added this to the 5.0 milestone Apr 16, 2020
@maryamariyan
Copy link
Member

maryamariyan commented Apr 16, 2020

@JakenVeina, the runtime repo guidelines require us to go through an API review process.
https://github.com/dotnet/runtime/blob/b2bfe9c6cdeb9d6d658ff7e12da85105687281b6/docs/project/api-review-process.md

Looking at the existing APIs on LoggerMessage we see Define has more overloads than DefineScope.

    public static partial class LoggerMessage
    {
        public static System.Func<Microsoft.Extensions.Logging.ILogger, System.IDisposable> DefineScope(string formatString) { throw null; }
        public static System.Func<Microsoft.Extensions.Logging.ILogger, T1, System.IDisposable> DefineScope<T1>(string formatString) { throw null; }
        public static System.Func<Microsoft.Extensions.Logging.ILogger, T1, T2, System.IDisposable> DefineScope<T1, T2>(string formatString) { throw null; }
        public static System.Func<Microsoft.Extensions.Logging.ILogger, T1, T2, T3, System.IDisposable> DefineScope<T1, T2, T3>(string formatString) { throw null; }
        public static System.Action<Microsoft.Extensions.Logging.ILogger, System.Exception> Define(Microsoft.Extensions.Logging.LogLevel logLevel, Microsoft.Extensions.Logging.EventId eventId, string formatString) { throw null; }
        public static System.Action<Microsoft.Extensions.Logging.ILogger, T1, System.Exception> Define<T1>(Microsoft.Extensions.Logging.LogLevel logLevel, Microsoft.Extensions.Logging.EventId eventId, string formatString) { throw null; }
        public static System.Action<Microsoft.Extensions.Logging.ILogger, T1, T2, System.Exception> Define<T1, T2>(Microsoft.Extensions.Logging.LogLevel logLevel, Microsoft.Extensions.Logging.EventId eventId, string formatString) { throw null; }
        public static System.Action<Microsoft.Extensions.Logging.ILogger, T1, T2, T3, System.Exception> Define<T1, T2, T3>(Microsoft.Extensions.Logging.LogLevel logLevel, Microsoft.Extensions.Logging.EventId eventId, string formatString) { throw null; }
        public static System.Action<Microsoft.Extensions.Logging.ILogger, T1, T2, T3, T4, System.Exception> Define<T1, T2, T3, T4>(Microsoft.Extensions.Logging.LogLevel logLevel, Microsoft.Extensions.Logging.EventId eventId, string formatString) { throw null; }
        public static System.Action<Microsoft.Extensions.Logging.ILogger, T1, T2, T3, T4, T5, System.Exception> Define<T1, T2, T3, T4, T5>(Microsoft.Extensions.Logging.LogLevel logLevel, Microsoft.Extensions.Logging.EventId eventId, string formatString) { throw null; }
        public static System.Action<Microsoft.Extensions.Logging.ILogger, T1, T2, T3, T4, T5, T6, System.Exception> Define<T1, T2, T3, T4, T5, T6>(Microsoft.Extensions.Logging.LogLevel logLevel, Microsoft.Extensions.Logging.EventId eventId, string formatString) { throw null; }
    }

The missing ones you are proposing are:

...
        public static System.Func<Microsoft.Extensions.Logging.ILogger, T1, T2, T3, T4, System.IDisposable> DefineScope<T1, T2, T3, T4>(string formatString) { throw null; }
        public static System.Func<Microsoft.Extensions.Logging.ILogger, T1, T2, T3, T4, T5, System.IDisposable> DefineScope<T1, T2, T3, T4, T5>(string formatString) { throw null; }
        public static System.Func<Microsoft.Extensions.Logging.ILogger, T1, T2, T3, T4, T5, T6, System.IDisposable> DefineScope<T1, T2, T3, T4, T5, T6>(string formatString) { throw null; }
...

The above look reasonable. But looking at your PR, I see you are also proposing to added more overloads, to take up to 8 arg types. Regarding these other APIs, why the magic number 8? Is there a strong reason to have 8 and not just stick to existing 6?

Referring to:

        public static System.Func<Microsoft.Extensions.Logging.ILogger, T1, T2, T3, T4, T5, T6, T7, System.IDisposable> DefineScope<T1, T2, T3, T4, T5, T6, T7>(string formatString) { throw null; }
        public static System.Func<Microsoft.Extensions.Logging.ILogger, T1, T2, T3, T4, T5, T6, T7, T8, System.IDisposable> DefineScope<T1, T2, T3, T4, T5, T6, T7, T8>(string formatString) { throw null; }
  
        public static System.Action<Microsoft.Extensions.Logging.ILogger, T1, T2, T3, T4, T5, T6, T7, System.Exception> Define<T1, T2, T3, T4, T5, T6, T7>(Microsoft.Extensions.Logging.LogLevel logLevel, Microsoft.Extensions.Logging.EventId eventId, string formatString) { throw null; }
        public static System.Action<Microsoft.Extensions.Logging.ILogger, T1, T2, T3, T4, T5, T6, T7, T8, System.Exception> Define<T1, T2, T3, T4, T5, T6, T7, T8>(Microsoft.Extensions.Logging.LogLevel logLevel, Microsoft.Extensions.Logging.EventId eventId, string formatString) { throw null; }
 

@JakenVeina
Copy link
Contributor Author

JakenVeina commented Apr 19, 2020

No particular reason for 8, other than that's the "magic number" used elsewhere in the framework. E.G. Action<T>, Func<T>, and ValueTuple<T>.

@carlossanlop carlossanlop added api-ready-for-review API is ready for review, it is NOT ready for implementation and removed api-ready-for-review labels Jul 6, 2020
@terrajobst terrajobst added the blocking Marks issues that we want to fast track in order to unblock other important work label Jul 8, 2020
@bartonjs bartonjs added api-approved API was approved in API review, it can be implemented and removed api-ready-for-review API is ready for review, it is NOT ready for implementation blocking Marks issues that we want to fast track in order to unblock other important work labels Jul 9, 2020
@bartonjs
Copy link
Member

bartonjs commented Jul 9, 2020

Video

Adding the DefineScope T4-T6 for parity is approved. If you want to add further ones, that's also approved, but in the review the comments were "why stop at 8?" and "do we need 7 and 8?". If there's need for this, then they're approved. If not, then maybe hold off.

    public static partial class LoggerMessage
    {
        public static System.Func<Microsoft.Extensions.Logging.ILogger, T1, T2, T3, T4, System.IDisposable> DefineScope<T1, T2, T3, T4>(string formatString) { throw null; }
        public static System.Func<Microsoft.Extensions.Logging.ILogger, T1, T2, T3, T4, T5, System.IDisposable> DefineScope<T1, T2, T3, T4, T5>(string formatString) { throw null; }
        public static System.Func<Microsoft.Extensions.Logging.ILogger, T1, T2, T3, T4, T5, T6, System.IDisposable> DefineScope<T1, T2, T3, T4, T5, T6>(string formatString) { throw null; }
    }

@JakenVeina
Copy link
Contributor Author

That's a fair analysis. I can trim the T7 and T8 overloads out of the PR.

After watching the video, I will go ahead and clarify the original request: LoggerMessage.Create() and LoggerMessage.BeginScope() are not the methods that used to be internal. There actually used to be a namespace Microsoft.Extensions.Logging.Abstractions.Internal that contained a few public types. Most significantly, they contained the LogMessageFormatter type, which is actually where a lot of the logic is that powers the LoggerMessage.Create() and LoggerMessage.BeginScope() methods. My original thought was to just make these types public again, so that someone who needs more type args than what's available has an easier time just implementing their own methods.

The current internal version of LogMessageFormatter can be seen here.

Here's the commit that changed these from public to internal.

@maryamariyan
Copy link
Member

@JakenVeina I see you originally had a PR prepared for this.
Were you thinking of reviving your PR with the final approved APIs?

@JakenVeina
Copy link
Contributor Author

Yes, definitely. I'll see if I can get it re-worked this weekend.

@maryamariyan
Copy link
Member

Thanks for contributing @JakenVeina. If we wanted to get this in for 5.0 the deadline would be August 18 I believe. It would be good if we could get this merged in before that time.

@danmoseley
Copy link
Member

We branch on Aug 17th - I'm guessing midday, maybe later though.

@JakenVeina
Copy link
Contributor Author

I've force-pushed an update to my fork. You should be able to re-open #34741.

@maryamariyan
Copy link
Member

@JakenVeina I doubt reopening would work and it wouldn't get the updated changes. Could you please open a new PR instead?

@JakenVeina
Copy link
Contributor Author

Normally, that would work for me. I guess since it's already closed, github stops listening for changes on the forked branch.

Regardless. New PR submitted.

@ghost ghost locked as resolved and limited conversation to collaborators Dec 10, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
api-approved API was approved in API review, it can be implemented area-Extensions-Logging help wanted [up-for-grabs] Good issue for external contributors
Projects
None yet
Development

Successfully merging a pull request may close this issue.

8 participants