Populate DependencyTelemetry with Operation Data for Initializers#897
Populate DependencyTelemetry with Operation Data for Initializers#897TimothyMothra merged 16 commits intomicrosoft:developfrom
Conversation
|
I assume there is a change to the core SDK nuget package required, but as that hasn't been built yet, I just worked with the update locally. If there is a better processor for changes which modify both, please point me in the right direction -- appreciated. |
lmolkova
left a comment
There was a problem hiding this comment.
Thanks for the PR and all the tests, overall looks great!
I have a concern here regarding duplication in the OperationDetails dictionary.
-
http response and headers should be mutually exclusive: in most of the cases reponse is available. the case where only headers are available is corener case and an ugly workaround.
-
It seems Sql connection is avaialble through the command.
| { | ||
| this.ParseResponse(response, telemetry); | ||
| telemetry.OperationDetails[RemoteDependencyConstants.HttpResponseOperationDetailName] = response; | ||
| telemetry.OperationDetails[RemoteDependencyConstants.HttpResponseHeadersOperationDetailName] = response.Headers; |
There was a problem hiding this comment.
why do we need to populate response AND headers? I'd prefer them to be mutually exclusive.
In case of .NET Core there is no case when a response is missing, but headers are present
There was a problem hiding this comment.
That was actually how I originally had it (until I hit the corner case where the response was not present). My rationale for always including them was to make development of a initializer easier -- if the developer is only interested in headers, headers is always populated. This is not a stance of principal or conviction -- you are much more familiar with what the developer experience of the initializers should be, so I will defer to you. Please ack that you would prefer to only have the headers when the response is not available and I will make the change after I finish an update on the SDK pull request.
There was a problem hiding this comment.
I hear your concern. I consider the scenario as very advanced and rare. And within this scenario case when a response is not available is rare itself. Making it convenient for a very small subset of users should come with a lowest possible performance impact even if it makes usage a bit less convenient.
So yes, I would prefer to have headers only when a response is not available.
| telemetry.OperationDetails[RemoteDependencyConstants.SqlCommandOperationDetailName] = command; | ||
| if (connection != null) | ||
| { | ||
| telemetry.OperationDetails[RemoteDependencyConstants.SqlConnectionOperationDetailName] = connection; |
There was a problem hiding this comment.
The connection is available through the command, why do we need to explicitly add it to the dictionary?
There was a problem hiding this comment.
Similar rationale as the response\headers comment above. I was not sure that the command would always be populated based on the failure cases, and I wanted to make it easier to develop the initializer if someone was only interested in properties on the connection. I will wait for confirmation on the comment above, and align the two to be consistent.
|
@anpete Our goal is to enable scenario when users add arbitrary dynamic properties to their dependency telemetry. In HTTP case it could be adding request or response header value to the telemetry. Could you please help us understand whether it is relevant for SQL and what kind of information could be useful/not useful. Basically, we proxy DiagnostiSource payload to users through telemetry instance (but this info is not serialized and is never sent to the backend as it). It's up to users to access these objects and modify telemetry based on them. This is a very advanced scenario we don't expect the absolute majority of users to implement. |
There was a problem hiding this comment.
Would like to have a 'flag' to turn this feature on/off if customer desires so, since some people may find the additional memory consumption not worth..
something like https://github.com/Microsoft/ApplicationInsights-dotnet-server/blob/develop/Src/DependencyCollector/Shared/DependencyTrackingTelemetryModule.cs#L57.
I have added couple other comments as well.
| Target = string.Join(" | ", connection.DataSource, connection.Database), | ||
| Data = operation, | ||
| Success = true | ||
| Success = true, |
There was a problem hiding this comment.
Not intentional, but it is a coding style from my projects. I'll remove the trailing comma when we hear back regarding the feature flag.
|
|
||
|
|
||
| // Populate the operation details for intializers | ||
| telemetry.SetOperationDetail(RemoteDependencyConstants.SqlCommandOperationDetailName, command); |
There was a problem hiding this comment.
need similar change here as well:
https://github.com/Microsoft/ApplicationInsights-dotnet-server/blob/develop/Src/DependencyCollector/Shared/Implementation/ProfilerSqlProcessingBase.cs
This contains SQL dependency collection logic with Profiler installed.
CHANGELOG.md
Outdated
|
|
||
| ## Version 2.7.0-beta1 | ||
| - [Added support to collect Perf Counters for .NET Core Apps if running inside Azure WebApps] (https://github.com/Microsoft/ApplicationInsights-dotnet-server/issues/889) | ||
| - [Add operation details for HTTP and SQL operation to the dependency telemetry.](https://github.com/Microsoft/ApplicationInsights-dotnet-server/issues/587) |
There was a problem hiding this comment.
If possible create a new issue in gh, which contain detail about the specific fix. The original issue is quite long discussion, and it'll be hard to figure out which part from that is being implemented here.
There was a problem hiding this comment.
Also helpful if an example TelemetryInitializer can be provided which utilizes this new feature.
There was a problem hiding this comment.
@cijothomas - Did you want the sample to be checked in somewhere and included in this PR, or inline in the new issue you were requesting on GitHub?
There was a problem hiding this comment.
Either is fine. Inline in a GH issue is easier to find as it's linked from release notes.
There was a problem hiding this comment.
K. I'll code up a sample as I was intending to use this feature and include it in a new GH issue.
There was a problem hiding this comment.
Here is a consolidated issue with a code sample for intended use:
#900
|
@SergeyKanzhelev and @Dmitry-Matveev - Please share your thoughts on making this under a feature flag, and having them OFF by default. I'd assume that this is only useful if customer has their own telemetry initializer which makes use of this. Those customers can turn this feature ON, so regular users dont see increased memory usage from AI SDK. |
|
@cijothomas - While we are waiting for @SergeyKanzhelev and @Dmitry-Matveev to respond to whether this needs to be placed under a feature flag, can you point me to a current example? I presume it would be something similar to ExcludeComponentCorrelationHttpHeadersOnDomains or IncludeDiagnosticSourceActivities on the current dependency collection module, but am not completely sure. |
|
@michaelwstark Yes you are pretty close. More relevant example is |
|
Thanks for the pointer. I will create a branch off of my current working code with this change in anticipation of @SergeyKanzhelev or @Dmitry-Matveev indicating that we should include a flag for this behavior. |
|
@cijothomas However, this feature does not look risky: DependencyTelemetry has a new property that is just assigned to something we have validated. It will be safely ignored by existing users. I could not see what can go wrong here and why we'd wan't to disable this feature. |
There should be no increase in memory usage. The new properties DependencyTelemetry gets already present in the memory and are cleaned up after dependency call is finished. E.g. in case of HTTP we add Http request and Http response - there are no new allocations, except for dictionary with 2 items. |
|
we discussed it with @cijothomas offline. I wonder, can we clean up the OperationDetails in public void TrackDependency(DependencyTelemetry telemetry)
{
if (telemetry == null)
{
telemetry = new DependencyTelemetry();
}
this.Track(telemetry);
!!! telemetry.OperationDetails.Clear();
}It totally makes sense to me, as Track happens syncronously with dependency call and request/response should not be accessed after that. |
|
@michaelwstark, I'm with Cijo on this one - due to increased memory usage for default scenario, I'd suggest to make this feature opt-in rather than on by default. Performant apps (let's say 500+ RPS) may all of a sudden become less performant if we store all request/responses/headers for 30 seconds (15000 * 3 objects). Super-performant apps (1000+ RPS) may struggle even if we come up with some optimization to release object sooner - it will still exist more than ASP.NET intended it to. |
|
@Dmitry-Matveev - Just wanting to confirm -- so the ask is to clear the captured objects on Track() as well as add a feature opt-in? |
|
@Dmitry-Matveev @michaelwstark |
|
Chatted with @Dmitry-Matveev offline (he had to run for a meeting so cannot reply right now). |
|
Thanks, @lmolkova! @michaelwstark, in case we do not copy nor keep response/request objects after the request is over - we are good without the feature flag. |
|
@Dmitry-Matveev Thanks! @lmolkova - I think that all of the outstanding feedback has been resolved, please let me know what else needs to be done prior to merging these PRs into their respective repos. I noticed there are some VSTS checks which never provide any feedback -- anything I need to do there? |
|
@michaelwstark thanks for addressing the suggestions! |
|
@MS-TimothyMothra to ensure this is merged AFTER base 2.7.0-beta1 is published to myget. |
updated changelog to reflect that this is expected to go in 2.7 Beta2
|
Sorry, I misunderstood and prep-ed this for Beta2. |
|
@MS-TimothyMothra has the Beta1 of the core SDK been published to myget? When do we expect this PR to merge? Thanks in advance. |
|
Sorry @michaelwstark, the 2.7 Beta1 got delayed to June 1st because we're working on hotfixes for 2.6 Stable. |
|
@michaelwstark It looks like some of your new tests are failing.
Will you have time to look at these today? |
|
@MS-TimothyMothra. Yup. I'll be able to take a look today. |
|
I've added these two recently: TestZeroAndNonZeroContentResponseDiagnosticSource Probably failures are result of auto-merge and new tests are missing something. |
|
One test is a negative case for response, and the validate call requires hint not to validate response data. The other leveraged a new Boolean value in the validate pipeline which was not named which conflicted with the one I added. Re-running unit tests after the update and will push shortly if they pass. |
|
@MS-TimothyMothra you should be good to proceed now. Let me know if you hit any more issues. |
|
Thanks @michaelwstark ! Queuing your build now. |
Fix Issue # .
[Consolidated]
#900
[Original]
#820
#747
#587
Populate DependencyTelemetry with operation data for initializers.
For significant contributions please make sure you have completed the following items:
Changes in public surface reviewed
Design discussion issue # Support adding arbitrary HTTP response headers from dependencies #587
CHANGELOG.md updated with one line description of the fix, and a link to the original issue.
The PR will trigger build, unit tests, and functional tests automatically. If your PR was submitted from fork - mention one of committers to initiate the build for you.
If you want to to re-run the build/tests, the easiest way is to simply Close and Re-Open this same PR. (Just click 'close pull request' followed by 'open pull request' buttons at the bottom of the PR)
Please follow [these] (https://github.com/Microsoft/ApplicationInsights-dotnet-server/blob/develop/CONTRIBUTING.md) instructions to build and test locally.