net-commons / common-logging

A portable logging abstraction for .NET
http://net-commons.github.io/common-logging
Apache License 2.0
649 stars 203 forks source link

Shim for Microsoft.Framework.Logging #87

Open cherrydev opened 9 years ago

cherrydev commented 9 years ago

I wonder if this might be a controversial topic, but now that Microsoft has released its own open-source logging abstraction (for some definitions of "released") for the new aspnet5/vNext/DNX system, I think it would make sense for common.logging to have an adaptor that delegates to Microsoft.Framework.Logging (which in turn will delegate to another logging framework). This would allow libraries that are compiled against Common.Logging to work with the new system.

sbohlen commented 9 years ago

Hmmmm....I'm not certain that its as much controversial as (possibly) impossible (?)

As a MSFT FTE, I suppose I should be embarrassed to say it, but I'm honestly unfamiliar with Microsoft.Framework.Logging :) Can you provide more information about it? Specifically, can you advise whether it is only intended to be available on .NET Core 5.0 or is it also available on the main .NET Framework (e.g., 4.6) when released later this year?

TBH, my research here seems (initially) confusing at best or contradictory at worst. The NuGet package for Microsoft.Framework.Logging (https://www.nuget.org/packages/Microsoft.Framework.Logging/) states a dependency on both ASP.NETCore 5.0 (implying .NET Core) and .NET Framework 4.5 (implying support for the 'full' framework is intended).

But if you then explore the Microsoft.Framework.Logging.Interfaces dependency listed under .NET Framework 4.5 (https://www.nuget.org/packages/Microsoft.Framework.Logging.Interfaces/), that lists only ASP.NETCore 5.0 as dependency, suggesting that it only supports .NET Core (?) All of this probably means that we can't reverse-engineer the intent re: supported runtimes for Microsoft.Framework.Logging by inspecting its stated NuGet dependencies :-/

The reason I think this intent matters, is that as I understand your proposed use-case for this shim/adapter, it would be to provide the ability for projects with a dependency on Common.Logging to run their binaries unmodified on .NET Core(?) The problem is that as far as I know, the BCL-like functionality provided in .NET Core (at least thus far) is so small a subset of the larger .NET Framework as to make that premise unlikely.

To my knowledge, most people that are attempting to write e.g., OSS packages for .NET Core are either using rather substantial #IFDEF sections in their code or re-writing their entire code from scratch (or copy-paste) to address the differences in BCL-functionality that exist between the two runtime environments.

Getting Common.Logging to work in the .NET Core environment would almost certainly take a lot more work than merely creating a shim/adapter that targeted Microsoft.Framework.Logging -- the rest of Common.Logging would have to be retooled to be able to run on .NET Core as well.

While I admit I've not (yet) taken a hard look at what would be required to accomplish this, early reports about inclusion/exclusion of various BCL elements in .NET Core suggest either that there is no support at all for e.g., System.Xml or that XML-parsing capabilities are so different/limited as to require an entirely additional/different config-file-parsing subsystem be built for Common.Logging. This may of course have change since last I looked (~5 mos ago?) but this is my most-recent read of the situation.

To be fair, while XML was in favor when the .NET Framework was originally developed its JSON that has come into favor as the config-storage-file-format-of-choice these days and so having full support for XML parsing in .NET Core is perhaps a legit lower-priority than strong JSON support. That said a lot of loggers (all of them???) expect XML as the source of their config settings, so a lot of them are (probably?) in this same boat with Common.Logging in re: considering challenges facing them in .NET Core.

Some other thoughts that are probably worth considering in the whole ".NET Core vs. .NET Framework" scenario for Common.Logging include:

  1. Are other OSS logging frameworks planning (or perhaps work is already underway?) to support .NET Core? (e.g., even if we supported .NET Core, what actual loggers would be available for that platform?)
  2. In a sense, .NET Core support could be considered to be just another, different variant of the "PCL-support" scenario; would there be value/merit in attempting to mirror the current PCL strategy into the .NET Core context?

In short (too late!), I think there is merit in exploring both the technical challenges and the value-prop for finding some role for Common.Logging to play in .NET Core runtime scenarios, but its not clear to me (yet) that this would be a trivial undertaking as I understand the limited capabilities being provided to framework authors in the near-term for .NET Core....

We'd be very interested to understand what yourself (and others in the community!) think about this...?

cherrydev commented 9 years ago

Nono, I can assure you that Microsoft.Framework.Logging.Interfaces works on the full .NET Framework because I'm in the early stages of writing a full-stack (not Core) web application that's targeting DNX. It would be unnecessary to make any considerations for having to make any parts of Common.Logging work on the limited .NET Core runtime. All I'm talking about would be to write a Common.Logging provider that would pass logging messages to Microsoft.Framework.Logging. If you 're looking at the Dependencies on the NuGet page for Microsoft.Framework.Logging.Interfaces, what it's actually saying is that: IF your Runtime is ASP.NetCore 5.0, your ADDITIONAL dependencies are those three packages that are implicit in the full .NET runtime (but are extra APIs if you're on Core). That means if you're using other runtimes, you have no extra dependencies. I'm looking at the .nuspec document right now, and .NET 4.5 is one of the target frameworks, so you wouldn't even need to create a new DNX style project in order to consume the interface, you can do it right from within a standard .csproj. The same goes for the Microsoft.Framework.Logging package proper. It just has one more dependency on the dependency injection interfaces, but those are also 4.5 compatible. I've used the Logging package in a 'legacy' .csproj .NET 4.5 project before. Microsoft.Framework.Logging is not going to be a core framework assembly, but will just remain as a published package from Microsoft that people can choose to use. If they're using the new ASP.NET5 stack, though, they're almost certainly going to be using them. The only reason why I thought this might be controversial is that Microsoft.Framework.Logging actually duplicates the purpose Common.Logging. It's not a full logging provider itself, it just provides an interface that other logging providers can implement. If the ASP.Net5 stack catches on, it's likely that less people will choose to target the Common.Logging interface because Microsoft.Framework.Logging is already available and required.

sbohlen commented 9 years ago

OK, understood; thanks for the clarification. In that case, I don't see anything particularly controversial about this per se -- if you're interested in submitting a PR for this feature, we'd be happy to merge it into Common.Logging.

Even though there is (conceptually) overlap between this project and the Microsoft.Framework.Logging abstraction, I don't see any reason not to provide a bridge/pass-through that would permit a Common.Logging-dependent assembly to pass its log info on to Microsoft.Framework.Logging.

Ultimately, this project exists to fill an unmet need in the .NET Framework (simple logging abstraction to which you can code and then config-driven ability to swap out logging targets without modifying your own code). If that need is (ultimately) better met by something within the framework itself (that begins to see broad adoption), then I don't think that there's any reason we'd not all be happy to see Common.Logging die a very natural death (or at least transition into 'maintenance mode').

If, however, the solution in the .NET Framework isn't eventually broadly adopted and/or doesn't fill the exact same gap/offer the same features as Common.Logging, I see no reason the two cannot co-exist in peace and harmony moving forward.

I'm curious: in the Microsoft.Framework.Logging universe, who/what assumes the responsibility for coding the 'adapter' that connects the logging framework to the actual logger (e.g., Log4NET, NLog, EntLib Logging)? Is that something the individual developer would still be expected to do or is that something that the logger authors (e.g., Log4NET) would be expected to take on in this ecosystem?

Can you help me understand the 'division of responsibility' in this case (or perhaps point me to an online reference that clears some of this up for me) --?

The reason I ask this is that it almost seems to me that the greater value for Common.Logging might be to act as a consumer of data written to Microsoft.Framework.Logging instead of a producer to it. As a consumer of Microsoft.Framework.Logging, Common.Logging could then potentially still offer value in the form of adapters that front the various logging frameworks (e.g., Log4NET, NLog) just as it does now.

Data would then flow like this:

[User Code] --> [Microsoft.Framework.Logging] --> [Common.Logging] --> [log-specific adapter] --> [actual logging framework]

Would that make any sense, or am I now completely off-base in re: my understanding of the role of Microsoft.Framework.Logging --?

cherrydev commented 9 years ago

For now, there is, for example, an NLog provider for M.F.L. that's written by MS. That might imply that MS is responsible for it, but it may not always be that way. While I understand your point about possibly having the logs flow from M.F.L. into Common.Logging rather than the other way around, I might suggest that it would be preferable to have the largest number of components possible take the shortest possible route to the actual logging framework. Because almost every single component of the new ASP.Net5 stack uses M.F.L. it would seem that preference would be satisfied by avoiding having all of those ASP.Net5 involve themselves in Common.Logging at any route. I concede that this is subjective and the above is not a bulletproof argument. My suggestion for you, as the main developer of the Common.Logging framework would be to post an issue here: https://github.com/aspnet/Logging and introduce yourself as the developer of Common.Logging and ask if they have any preference. I've found the team to be extremely responsive and willing to listen to ideas. I would say, though, that because they have already made providers for NLog, SeriLog and TraceSource and NOT one for Common.Logging that they probably have considered and decided against it.

sbohlen commented 9 years ago

Then in that case I still think your original idea for a shim still makes some sense; we'd be happy to accept a PR if you'd want to take a shot at an implementation.

karldodd commented 9 years ago

Great topic. I think both directions (consumer/producer) are valuable and useful.

Recently I am also building an ASP.NET 5 application, which references quite a lot of existing libraries that uses Common.Logging. So in my case, I need Common.Logging to be a consumer of MFL logs.

Btw, I am with @cherrydev 's advice that @sbohlen, on behalf of we common.logging users, post an issue on https://github.com/aspnet/Logging to talk with asp.net guys about the right design of .net log abstraction. Anybody else could do that, but probably you are the best candidate :) :+1: