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

Wcf instrumentation + example apps #38

Merged
merged 38 commits into from
Mar 5, 2021

Conversation

CodeBlanch
Copy link
Member

@CodeBlanch CodeBlanch commented Sep 26, 2020

Uses IClientMessageInspector & IDispatchMessageInspector to add instrumentation for WCF clients and servers.

/cc @mbakalov

TODOs

  • Error logging.
  • Unit tests.
  • Documentation.

@codecov
Copy link

codecov bot commented Sep 26, 2020

Codecov Report

Merging #38 (828752d) into main (9c11735) will increase coverage by 0.44%.
The diff coverage is 76.61%.

Impacted file tree graph

@@            Coverage Diff             @@
##             main      #38      +/-   ##
==========================================
+ Coverage   72.71%   73.16%   +0.44%     
==========================================
  Files          34       41       +7     
  Lines         953     1077     +124     
==========================================
+ Hits          693      788      +95     
- Misses        260      289      +29     
Impacted Files Coverage Δ
...cf/Implementation/WcfInstrumentationEventSource.cs 21.42% <21.42%> (ø)
...rumentation.Wcf/TracerProviderBuilderExtensions.cs 75.00% <75.00%> (ø)
...rumentation.Wcf/TelemetryClientMessageInspector.cs 80.30% <80.30%> (ø)
...b.Instrumentation.Wcf/WcfInstrumentationOptions.cs 88.88% <88.88%> (ø)
...b.Instrumentation.Wcf/TelemetryEndpointBehavior.cs 91.66% <91.66%> (ø)
...Implementation/WcfInstrumentationActivitySource.cs 92.30% <92.30%> (ø)
...strumentation.Wcf/Implementation/ActionMetadata.cs 100.00% <100.00%> (ø)
... and 4 more

@alexvaluyskiy
Copy link
Contributor

Will this instrumentation library support WCF client for .NET Core?
https://github.com/dotnet/wcf

@CodeBlanch
Copy link
Member Author

@alexvaluyskiy Not sure. I just poked around the repo, I think it could also work for the .NET Core version. I'll see if I can get it working when I find some cycles.

@CodeBlanch
Copy link
Member Author

@alexvaluyskiy I just pushed support for .NET Core WCF clients. There's no way to build a service client from config yet (that I could tell) but you can add endpoint behavior manually like this:

client.Endpoint.EndpointBehaviors.Add(new TelemetryEndpointBehavior());

There's an example in there of how to do it.

/cc @mconnew

@mconnew
Copy link

mconnew commented Oct 26, 2020

I'm not sure if I'm about to make you really happy or a little bit sad. We shipped in .NET Framework 4.8 support in WCF for really strong integration for telemetry. Another team were meant to create the piece for emitting the telemetry data but they never followed through. I created DiagnosticSource events in all the key areas where you would want to create telemetry information, many of them in places which are inaccessible via extensibility points. Because this was dropped by the other team so there was nothing to consume the diagnostics data I never bothered to port it to the open source WCF Core client.
You can see this support if you check the source code here: https://github.com/microsoft/referencesource/blob/master/System.ServiceModel/System/ServiceModel/Dispatcher/ImmutableDispatchRuntime.cs#L248

I can't remember how much I put in to the client side. I think I added the code to pick up the standard HTTP diagnostics headers and made it flow correctly. If you want to hook into this to get really rich data let me know and I'll dig out the commit diff so you have an exhaustive list of all the places I added things. If you want to integrate with what I added to .NET Framework, I would happily port the changes to the WCF client. I also have an unreviewed internal PR with some initial integration done which I could make available.

@CodeBlanch
Copy link
Member Author

@mconnew Cool thanks for the info. Right now I'm registering an IClientMessageInspector for .NET Framework & .NET Core which starts & stops Activity objects using the new .NET 5 ActivitySource API. ActivitySource is what the OpenTelemetry .NET engine is wired up to receive (we have a way to translate DiagnosticSources). For .NET Framework server-side, I'm registering an IDispatchMessageInspector and doing the same. I went with that approach over DiagnosticSource because I didn't know the latter existed until I was done 😄 But it sounds like I got lucky and that is the only option available for pre-4.8 .NET Framework & .NET Core? The one benefit to using DiagnosticSource that I can see would be we could trap those automatically, user wouldn't need to mess with their service/client config. But pre-4.8 support is very nice to have, so I'm not sure which option is best. Might need both?

As far as the level of detail, for OpenTelemetry tracing, traping start/end is probably fine. But OpenTelemetry also has a metric side to it. To provide really good metrics having more raw data would probably be useful. It's an area we're just getting into with the library & specification though so might want to wait a bit before spending a bunch of time on it?

@mconnew
Copy link

mconnew commented Oct 27, 2020

@CodeBlanch, the places I added the ability to emit events were intended to answer the question "Why has my service got slower", so I've added hooks into anything where the request can get delayed along the line. So for example, the throttling code emits multiple events. If a request gets throttled, I actually add a message property with the data so a later extensibility point could pick it up and emit the values. A property is added at the point of throttling, and another when the throttle is released. That way you can see if your P99 request time has gone up because some of your requests are getting delayed due to throttling. Also every extensibility point such as message inspectors installed also emit an event with how long it took to execute it.

It's been 2 years since I wrote that code so just had a look at it and I didn't actually use DiagnosticSource as it wasn't available in the framework. What I actually did was create a custom EventSource and emitted events using that. I had some other code (which I've just started the process of getting approval to release as sample code to help flesh out this implementation) which created an EventSourceListener and emitted the data using DiagnosticSource. It could be easily changed to use ActivitySource. I also wrote some channel layer classes (a ChannelListener and ChannelFactory) which did all the work of making the relevant id's flow through a client to the server via either HTTP headers if using HTTP or a custom SOAP header. It was all done via a single service behavior which hooked in and injected itself in all the required places so all you needed to do was add a single service behavior and everything else gets wired up for you. What's missing is defining exactly what data you want to be emitting such as all the tag's.

I'm not suggesting this work should be replaced by the sample code I'm getting approval to release, it's way too out of date for the current design of telemetry as I know it is quite different now than it was 2 years ago. The intention is as a reference implementation on how to collect all this data using already written helper code that exists in the framework and an example how to do end 2 end telemetry between the client and the server with correlated data.

@CodeBlanch
Copy link
Member Author

Thanks @mconnew! When you get the sample up please ping back here and I'll check it out!

@meastp
Copy link

meastp commented Jan 26, 2021

Is there any progress on this? I'd love to be able to depend on a nuget package instead of copy+paste source code :)

@CodeBlanch CodeBlanch marked this pull request as ready for review February 11, 2021 22:49
@CodeBlanch CodeBlanch requested a review from a team February 21, 2021 06:15
@SergeyKanzhelev
Copy link
Member

@CodeBlanch is it ready to be merged? Is there any other outstanding comments?

@CodeBlanch
Copy link
Member Author

@SergeyKanzhelev There are a couple of open questions for @mconnew still on here, but nothing blocking that I'm aware of. I think it's a good starting point, we can always continue to improve it 😄

@SergeyKanzhelev
Copy link
Member

@SergeyKanzhelev There are a couple of open questions for @mconnew still on here, but nothing blocking that I'm aware of. I think it's a good starting point, we can always continue to improve it 😄

I suggest we merge it than and track open questions as issues. Merging, can you please create issues?

@SergeyKanzhelev SergeyKanzhelev merged commit fd31e5b into open-telemetry:main Mar 5, 2021
@CodeBlanch CodeBlanch deleted the wcf-instrumentation branch March 11, 2021 07:35
@CodeBlanch CodeBlanch mentioned this pull request Sep 28, 2021
1 task
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

9 participants