-
Notifications
You must be signed in to change notification settings - Fork 247
ILogger implementation that sends data to EventSource/EventListener #424
Conversation
Hi @karolz-ms, I'm your friendly neighborhood .NET Foundation Pull Request Bot (You can call me DNFBOT). Thanks for your contribution! TTYL, DNFBOT; |
@karolz-ms, Thanks for signing the contribution license agreement so quickly! Actual humans will now validate the agreement and then evaluate the PR. |
}, | ||
"imports": [ "dotnet" ] | ||
}, | ||
"netcoreapp1.0": { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This should be a netstandard
TFM, which is for library. netcoreapp
is only for apps. E.g. see this other logger: https://github.com/aspnet/Logging/blob/dev/src/Microsoft.Extensions.Logging.Debug/project.json#L25-L36.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The reason why I went with netcoreapp is that when I am trying to consume Newtonsoft JSON from a project that targets netstandard, I am getting the following error:
Errors in C:\code\aspnet-logging-rc\src\Microsoft.Extensions.Logging.EventSource\project.json
Package Newtonsoft.Json 8.0.3 is not compatible with netstandard1.3 (.NETStandard,Version=v1.3). Package Newtonsoft.Json 8.0.3 supports:
- net20 (.NETFramework,Version=v2.0)
- net35 (.NETFramework,Version=v3.5)
- net40 (.NETFramework,Version=v4.0)
- net45 (.NETFramework,Version=v4.5)
- portable-dnxcore50+net45+win8+wp8+wpa81 (.NETPortable,Version=v0.0,Profile=net45+wp80+win8+wpa81+dnxcore50)
- portable-net40+sl5+win8+wp8+wpa81 (.NETPortable,Version=v0.0,Profile=Profile328)
One or more packages are incompatible with .NETStandard,Version=v1.3.
Now, I use Newtonsoft to serialize log data into JSON format. The serialization is quite simple, so I could do it manually and remove the dependency if overcoming the problem above is hard, but I would prefer to leverage Newtonsoft if possible
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You still can't use netcoreapp
, it's the wrong TFM. Use imports
instead: https://github.com/aspnet/Mvc/blob/3d494fd7326d3e137fdb22b53f01c5a34866fbaa/src/Microsoft.AspNetCore.Mvc.ViewFeatures/project.json#L59-L61
(Mind you, this is all temporary; once a new build of Json.NET is out that supports netstandard
, this will go away.)
Yes, that has helped, thanks--I can compile and run tests fine with the new logger targeting netstandard. net46 issue still remains... |
return; | ||
|
||
// See if they want the formatted message | ||
if (LoggingEventSource.Instance.IsEnabled(System.Diagnostics.Tracing.EventLevel.Critical, LoggingEventSource.Keywords.FormattedMessage)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: Why are we using the full namespace for the EventLevel?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not sure what was original reason, but we do not need it. Fixed.
So @davidfowl : any ideas/recommendations on how to treat the .NET46 target? |
using System.Diagnostics.Tracing; | ||
using System.Threading; | ||
using Newtonsoft.Json; | ||
using System.IO; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sort & Remove.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
(Apply to all files, as necessary. Also, ensure "System" namespaces are at the top - VS has a setting for this.)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed
Added some comments 🕐 |
/// } | ||
/// } | ||
/// </summary> | ||
[EventSource(Name = "Microsoft-Extensions-Logging")] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How does this name show up?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This name represents a well-known ID of the EventSource/ETW provider that exposes ILogger data to the ETW world. It will be used to subscribe to ILogger data by consumers who use EventSource/ETW to capture diagnostic traces.
public EventSourceLogger(string categoryName, int factoryID, LoggingEventSource eventSource, EventSourceLogger next) | ||
{ | ||
CategoryName = categoryName; | ||
Level = LoggingEventSource.LoggingDisabled; // Default is to turn off logging |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: Can you put the comment on top instead of on the side?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Will do
|
||
private string ToJson(IEnumerable<KeyValuePair<string, string>> keyValues) | ||
{ | ||
StringWriter sw = new StringWriter(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: use more var
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
OK
After my last checkin
After the build issues are resolved this request should be ready to merge. I believe I have addressed all issues raised during the review |
/// FormattedMessage() is called when ILogger.Log() is called. and the FormattedMessage keyword is active | ||
/// This only gives you the human reasable formatted message. | ||
/// </summary> | ||
[Event(1, Keywords = Keywords.FormattedMessage, Level = EventLevel.LogAlways)] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[Event(1, Keywords = Keywords.FormattedMessage, Level = EventLevel.LogAlways, Message = "{2} - {4}")]
How about adding a formatter like this?
Indeed, I tried it, but it does not work (Message = null). I'm using azure fabric and tried it in local.
Don't know why.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
FormattedMessage is precisely what the producer of the data intended to expose. It is readily available from the event payload. I do not see an added benefit of using the Message for this event, it would be less flexible and redundant.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm using EventSource in Azure fabric. Azure fabric provide a ETW viewer (as a VS extension) for local fabric services. It will show Timestamp, Event name and Message. You need to click one row to see the detail info. Anyway, I agree with you.
….EventSource.Test assembly
Avoids using static variable for TestListener initialization parameters (an idea from Vance Morrison)
Includes necessary test changes related to the fact that .NET 4.5 does not have ETW payload names in listener args.
Looks good. I'm closing this because we'll end up merging #448, which has some formatting/administrative fixes (e.g. version number updates). Thanks!!! |
This implementation follows the standard "use extension method to enable" pattern. Nothing is on by default.
A separate test assembly was created because there are two slightly different implementations, one for .NET Core and one for .NET 4.6