Skip to content

MVC use concrete types for DiagnosticListener#11730

Merged
rynowak merged 11 commits into
dotnet:masterfrom
benaadams:diag
Jul 15, 2019
Merged

MVC use concrete types for DiagnosticListener#11730
rynowak merged 11 commits into
dotnet:masterfrom
benaadams:diag

Conversation

@benaadams

@benaadams benaadams commented Jul 1, 2019

Copy link
Copy Markdown
Member

Pattern:

Under Diagnostics namespace

Event Type is same name as Event Name

Type has a EventName string const so what to listen to is exposed without having to check the source (and is a const so can be used in switch and Attributes).

Type has its data exposed as readonly properties.

Type implements IReadOnlyList<KeyValuePair<string, object>> so the data can be iterated over.

Type implements IEnumerable<KeyValuePair<string, object>> so the data can be enumerated over,

Interfaces are explicit so they don't interfere with reflection/serialization (i.e. Count being seen as a data item)

Each event has its own type so pattern matching can be used to differentiate events.

e.g.

namespace Microsoft.AspNetCore.Mvc.Diagnostics
{
    public sealed partial class AfterAction : IEnumerable<KeyValuePair<string, object>>, IReadOnlyList<KeyValuePair<string, object>>
    {
        public const string EventName = "Microsoft.AspNetCore.Mvc.AfterAction";
        
        public AfterAction(ActionDescriptor actionDescriptor, HttpContext httpContext, RouteData routeData);
        
        public ActionDescriptor ActionDescriptor { get; }
        public HttpContext HttpContext { get; }
        public RouteData RouteData { get ; }

        int IReadOnlyCollection<KeyValuePair<string, object>>.Count { get; }
        KeyValuePair<string, object> IReadOnlyList<KeyValuePair<string, object>>.this[int index];

        IEnumerator<KeyValuePair<string, object>> IEnumerable<KeyValuePair<string, object>>.GetEnumerator(););
    }
}

/cc @rynowak @davidfowl @NickCraver

@benaadams
benaadams force-pushed the diag branch 3 times, most recently from 57df950 to 29dde5b Compare July 1, 2019 04:28
@Eilon Eilon added the area-mvc Includes: MVC, Actions and Controllers, Localization, CORS, most templates label Jul 1, 2019
Comment thread src/Mvc/Mvc.Razor/src/RazorPagePropertyActivator.cs Outdated
@benaadams

Copy link
Copy Markdown
Member Author

Are still anonymous diagnostics in other places like Hosting, but will see how this goes down first before seeing about those.

@NickCraver

Copy link
Copy Markdown
Member

This would be a huge improvement - constants as event names make both the adapter case and general usage (e.g. a case in an IObserver) much better. The strong typing is very welcomed for anyone taking the reference and makes the whole thing sane (over loads of reflection today).

If anyone's curious about context: https://github.com/dotnet/corefx/issues/18114 is the original issue pushing for this, but closed since the teams weren't going to make any more breaking changes. With 3.0, it seems like hopefully that's back on the table.

NickCraver pushed a commit to MiniProfiler/dotnet that referenced this pull request Jul 6, 2019
Note that 3.x doesn't include view profiling for the moment. See dotnet/aspnetcore#11730 for progress on the 3.0 approach.
NickCraver added a commit to MiniProfiler/dotnet that referenced this pull request Jul 7, 2019
This set of changes drops view profiling for the moment in ASP.NET Core 3.x since the types we were wrapping as "pubternal" are no longer exposed in 3.0. On the framework side, dotnet/aspnetcore#11730 is in progress so we can use the diagnostics API to hopefully re-enable this for the 3.0 release.

Samples for ASP.NET Core 2.2 and 3.0 are broken into separate samples for clarity though they are mostly the same.

Overall changes:
- (For Linux): Fix Azure DevOps builds (note they're not successfully running all tests yet - some providers are skipped, but they're working!)
- (For Linux): Change SQL Formatters to always use `\n`
- (For Linux): Add `WindowsOnly` to `[Fact]` and `[Theory]` for skipping inapplicable tests on Linux
- (For Linux): Add `xunit.runner.json` to make things work on Linux/Mono (only copied to output and in effect there)
- (For Linux): Null ref fix for SQL CE errors (happens on Linux)
- (For .NET Core 3.0): Add a `netcoreapp3.0` build for `MiniProfiler.AspNet*` libs
- (For .NET Core 3.0): Exclude view profiling for now (this is what was breaking, ultimately)
- (For .NET Core 3.0): Split ASP.NET Core v2 and v3 samples into different projects, since some fundamentals have changed
- (For all): Bump version to `4.1.0-preview.*` to reflect the preview dependencies for `netcoreapp3.0` builds
- (For all): Dropped `netcoreapp1.1` from testing (note: `netstandard1.5` is still built, it's just not tested)
@rynowak

rynowak commented Jul 11, 2019

Copy link
Copy Markdown
Member

@benaadams - this is dope, I like the design of this.

@rynowak

rynowak commented Jul 11, 2019

Copy link
Copy Markdown
Member

@ajcvickers - is it work comparing the design of this with https://github.com/aspnet/EntityFrameworkCore/tree/9026770af72683ba3cf6c2a8125fa7a8d602703f/src/EFCore/Diagnostics ?

I notice that you're using the same payloads for logging and diagnostics source.

Comment thread src/Http/Http/src/DefaultHttpContext.cs
Comment thread src/Mvc/Mvc.Abstractions/src/Diagnostics/MvcDiagnostic.cs Outdated
Comment thread src/Mvc/Mvc.Core/ref/Microsoft.AspNetCore.Mvc.Core.netcoreapp3.0.cs Outdated
}
public sealed partial class AfterOnActionExecuted : Microsoft.AspNetCore.Mvc.Diagnostics.MvcDiagnostic
{
public const string EventName = "Microsoft.AspNetCore.Mvc.AfterOnActionExecuted";

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ooops. This is a really unfortunate event name. I think we should call this type something like ActionFilterOnActionExecuted on so on for the other filter-related events.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is that everything that has IFilterMetadata property?

e.g. AfterOnException => AfterFilterOnException

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would call it ExceptionFilterAfterOnException. So the scheme is <filter kind> [Before|After] Method

Comment thread src/Mvc/Mvc.Core/ref/Microsoft.AspNetCore.Mvc.Core.netcoreapp3.0.cs Outdated
@NickCraver

Copy link
Copy Markdown
Member

I'm just curious around what constitutes a breaking change on these APIs w.r.t. event names.

Since the property names on the object are going from camelCase to proper C# Pascal case for properties, isn't it already breaking? Or is the latest binder reflection case-insensitive and that keeps working? I'm just confused on the event names being breaking when the property casing isn't...if we're firing the old events but they just don't work, maybe it would be better to change and break the event names? Just tossing that thought out there.

@rynowak

rynowak commented Jul 14, 2019

Copy link
Copy Markdown
Member

Since the property names on the object are going from camelCase to proper C# Pascal case for properties, isn't it already breaking? Or is the latest binder reflection case-insensitive and that keeps working?

It depends on the consumer. The consumer that I'm aware of is app-insights which I think is still using the Microsoft.Extensions.DiagnosticSourceAdapter package - which is case-insensitive.

Technically speaking, top level entries are defined as case-insensitive, but what really matters to me is whether we break people that have real usage.

If this is a breaking change that impacts existing usage of diagnostic source, then I would lean towards using lowercase properties. This is too late in the development cycle to be cavalier about breaking changes.

@lmolkova - any insights here?

@NickCraver

Copy link
Copy Markdown
Member

Given the very few people using these (as far as I'm aware) outside diagnostic adapter, IMO we should change them now while making changes and have them reflect the casing that should be on a public type API. Even if it's breaking, as long as DiagnosticAdapter is case-insensitive.

@benaadams

Copy link
Copy Markdown
Member Author

Aside: Just to make note on my understanding of the status of this PR. I've made the requested changes and @rynowak is picking up class naming changes.

Also outstanding issue on Instrumentation apis #11730 (comment) to be picked up separately?

@rynowak

rynowak commented Jul 15, 2019

Copy link
Copy Markdown
Member

@benaadams

Copy link
Copy Markdown
Member Author

There's still a breaking change here:

Surely not with the magic of DI and all that 😉

Reverted

@lmolkova

lmolkova commented Jul 15, 2019

Copy link
Copy Markdown

I'll look more into this PR later today.

Regarding this:

Microsoft.Extensions.DiagnosticSourceAdapter package - which is case-insensitive.

AppInsights is NOT using DiagnosticAdapter anymore and event handling is case-sensitive. We still have several work items to support ASP.NET Core 3.0 and can fit case-insensitive work if needed.

Also

very few people using these (as far as I'm aware) outside diagnostic adapter

After we introduced Activities, it became hard and inefficient to use DiagnosticAdapter because of aspnet/EventNotification#67 (check out this dotnet/extensions#1895 as an example I just found)

We also removed adapter because of perf - DiagnosticsSource.IsEnabled became twice as fast. And the ability to filter out events in IsEnabled (which brought more improvements) is not supported by the adapter.

So, I'd argue DiagnosticAdapter is the default way is not a good assumption.

@rynowak

rynowak commented Jul 15, 2019

Copy link
Copy Markdown
Member

I'll look more into this PR later today.

Regarding this:

Microsoft.Extensions.DiagnosticSourceAdapter package - which is case-insensitive.

AppInsights is NOT using DiagnosticAdapter anymore and event handling is case-sensitive. We still have several work items to support ASP.NET Core 3.0 and can fit case-insensitive work if needed.

Ok great. Is there somewhere you want me to file this?

After we introduced Activities, it became hard and inefficient to use DiagnosticAdapter because of aspnet/EventNotification#67 (check out this aspnet/Extensions#1895 as an example I just found)

We also removed adapter because of perf - DiagnosticsSource.IsEnabled became twice as fast. And the ability to filter out events in IsEnabled (which brought more improvements) is not supported by the adapter.

So, I'd argue DiagnosticAdapter is the default way is not a good assumption.

Also great from my POV. I'd like to use deprecate the adapter and stop shipping it in a future release. It hasn't really proved to be essential for diagnostic source.

@rynowak
rynowak merged commit 09722d1 into dotnet:master Jul 15, 2019
@benaadams
benaadams deleted the diag branch July 15, 2019 20:24
NickCraver pushed a commit to MiniProfiler/dotnet that referenced this pull request Apr 19, 2020
This adds timings based on the DiagnosticListener bits overhauled in dotnet/aspnetcore#11730 with some further cleanup in dotnet/aspnetcore@b23ea5b

This would also resolve #162 and #322.
NickCraver added a commit to MiniProfiler/dotnet that referenced this pull request Apr 22, 2020
This adds timings based on the `DiagnosticListener` bits overhauled in dotnet/aspnetcore#11730 with some further cleanup in dotnet/aspnetcore@b23ea5b

This would also resolve #162 and #322.

Entirely possible there are more efficient ways to do the correlation tracking (I hope!) - putting this up for more eyes.

Example profiling:
![image](https://user-images.githubusercontent.com/454813/79678735-784f5d00-81cc-11ea-93fc-11516b77ea59.png)
ylinax pushed a commit to ylinax/dot-net that referenced this pull request Jun 30, 2022
This set of changes drops view profiling for the moment in ASP.NET Core 3.x since the types we were wrapping as "pubternal" are no longer exposed in 3.0. On the framework side, dotnet/aspnetcore#11730 is in progress so we can use the diagnostics API to hopefully re-enable this for the 3.0 release.

Samples for ASP.NET Core 2.2 and 3.0 are broken into separate samples for clarity though they are mostly the same.

Overall changes:
- (For Linux): Fix Azure DevOps builds (note they're not successfully running all tests yet - some providers are skipped, but they're working!)
- (For Linux): Change SQL Formatters to always use `\n`
- (For Linux): Add `WindowsOnly` to `[Fact]` and `[Theory]` for skipping inapplicable tests on Linux
- (For Linux): Add `xunit.runner.json` to make things work on Linux/Mono (only copied to output and in effect there)
- (For Linux): Null ref fix for SQL CE errors (happens on Linux)
- (For .NET Core 3.0): Add a `netcoreapp3.0` build for `MiniProfiler.AspNet*` libs
- (For .NET Core 3.0): Exclude view profiling for now (this is what was breaking, ultimately)
- (For .NET Core 3.0): Split ASP.NET Core v2 and v3 samples into different projects, since some fundamentals have changed
- (For all): Bump version to `4.1.0-preview.*` to reflect the preview dependencies for `netcoreapp3.0` builds
- (For all): Dropped `netcoreapp1.1` from testing (note: `netstandard1.5` is still built, it's just not tested)
ylinax added a commit to ylinax/dot-net that referenced this pull request Jun 30, 2022
This adds timings based on the `DiagnosticListener` bits overhauled in dotnet/aspnetcore#11730 with some further cleanup in dotnet/aspnetcore@b23ea5b

This would also resolve #162 and #322.

Entirely possible there are more efficient ways to do the correlation tracking (I hope!) - putting this up for more eyes.

Example profiling:
![image](https://user-images.githubusercontent.com/454813/79678735-784f5d00-81cc-11ea-93fc-11516b77ea59.png)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area-mvc Includes: MVC, Actions and Controllers, Localization, CORS, most templates

Projects

None yet

Development

Successfully merging this pull request may close these issues.

9 participants