-
Notifications
You must be signed in to change notification settings - Fork 282
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
Use StartOperation on PageViewTelemetry #1062
Comments
@lmolkova , what would be a right way to track operation that is started manually with PageView telemetry in .Net Code? |
Today I tried to manually get this working using OperationId and ParentId but I can't get it right. Is it even supported without using StartOperation or is PageView just not designed for this scenario? |
This issue is a little bit old, but we also have need of this behavior. The SDK currently assumes that correlation with PageViewTelemetry will happen naturally because the JavaScript SDK will associate its DependencyTelemetry with the root page view and, as the headers arrive to the server when receiving a request, will be passed into the RequestTelemetry. We actually use the PageViewTelemetry class from the SDK directly in our application and are unable (out of box) to associate dependencies with these. It looks like it wouldn't be particularly complicated, though it may prefer a different naming convention (since PageViewTelemetry is not considered an OperationTelemetry). All the properties being store in context here in TelemetryClientExtensions already exist in PageViewTelemetry. As a workaround we may wind up creating something like |
Actually another note about the incompleteness of PageViewTelemetry in the .NET SDK is that it doesn't automatically generate IDs like other telemetry does; OperationContext has an internal GenerateId method that would need to be run in the PageViewTelemetry constructor; since the context operation will likely always be null, it might be more helpful for the equivalent of StartOperation to do something like the following: var operationContext = new OperationContextForCallContext
{
ParentOperationId = pageViewTelemetry.Id,
RootOperationId = pageViewTelemetry.Id,
RootOperationName = pageViewTelemetry.Name,
};
CallContextHelpers.SaveOperationContext(operationContext); |
For reference, this is not a newly discussed issue and works correctly as long as your In a followup issue opened there (#361), approximately 2 years later @jpiyali replied stating
which further supports my view that I may be willing to submit a Pull Request as I've taken a pretty solid look around the code at this point, but I'd like confirmation that my thoughts so far are accurate. It looks like there's a release coming and I'd really much rather have this functionality in the framework than have to maintain additional workaround code. Since I'm proposing a new extension method in using (client.CorrelateOperations(pageViewTelemetry))
{
// some operation that later tracks DependencyTelemetry; e.g:
return new SomeService(_telemetryClient).Send(greeting);
} and the implementation, unless someone can identify some flaw in my thinking, would be as simple as: public static IOperationHolder<OperationTelemetry> CorrelateOperations(this TelemetryClient telemetryClient, PageViewTelemetry pageViewTelemetry)
{
if (telemetryClient == null)
{
throw new ArgumentNullException(nameof(telemetryClient));
}
if (pageViewTelemetry== null)
{
throw new ArgumentNullException(nameof(pageViewTelemetry));
}
var operationContext = new OperationContextForCallContext
{
ParentOperationId = pageViewTelemetry.Id,
RootOperationId = pageViewTelemetry.Id,
RootOperationName = pageViewTelemetry.Name,
};
CallContextHelpers.SaveOperationContext(operationContext);
return new PageViewOperationHolder();
} The one smell I don't much like a bout this is that EDIT: Actually it looks like |
CC @TimothyMothra since it seems you're the main person maintaining the BASE SDK and @lmolkova since you have made changes related to the W3C IDs in recent history. This issue hasn't had much comment history besides myself in recent history, but it's somewhat important to us and I was hoping someone with current responsibility in this area could help me get the ball rolling? |
Hi @TheXenocide, yeah our team has been stretched thin recently. ApplicationInsights-dotnet/BASE/src/Microsoft.ApplicationInsights/DataContracts/PageViewTelemetry.cs Line 21 in 5e10925
ApplicationInsights-dotnet/BASE/src/Microsoft.ApplicationInsights/DataContracts/RequestTelemetry.cs Line 23 in 5e10925
|
Just a note that above I said to add an extension method to |
@TimothyMothra ,@TheXenocide , @Expecho , speaking of historical reason, I think I remembered the origins of AI stopping to consider PageView as operation. Several years ago, monitoring charters for services and desktop/mobile were split between Application Insights and App Center. AI stopped supporting WPF apps where page view was the top-most operation, so our modifications for operation API at any given point after that were not thinking of PageView as an operation that would happen within AI Services SDK. In the services world, JavaScript SDK defines the client piece and therefore starts the operation that services SDK later picks up from the headers and continues. If we are still in that mode of Services v. Client (we, mostly, are), adding desktop-related concept into AI Services SDK won't be aligned. However, I do not see how it would hurt either and we should be open to a PR like that, unless others have some concerns. I do not think this will get onto the actual team backlog due to being off-charter, though. |
Yeah, that's the impression I had, though it makes the I've started to hack away at the code trying to get something working, but it looks like the My original approach to having a separate path for I think the one oddity to consider in this scenario is that, unless I go out of my way to prevent it (which I can do, if you prefer), using I also have some questions about things that came up along the way: I'm wondering if you have any guidance for what seems like a bug I ran into with the
|
So as I look at it, apparently only the lambda expressions use |
Hey, the PublicApiAnalyzer is kind of a pain in the ass. For compile issues it's usually an access modifier is missing, or maybe a statement didn't get copied to another text file (There's a text file each framework.) |
@SergeyKanzhelev , what were our plans on PageViewTelemetry type and would they contradict or support @TheXenocide 's suggestion?
|
Any news? Maybe we can continue creating a (Draft) PR to not loose the momentum gained. |
I had started one, but my approach was too simple and the path I go down next is rather dependent on these correlation questions regarding whether it's okay for a PageView to be nested or not. Another related subject came up around here as we've just had a conversation with @danroth27 regarding Blazor + Application Insights and I've been digging in to see how best we would take advantage of our existing Application Insights investments alongside our Blazor efforts. I found dotnet/aspnetcore#5461 from the Blazor backlog which I'm linking here because I think a solution to the .NET SDK portion of PageViewTelemetry may also be helpful for a pure C# solution for Blazor as well, though perhaps not the only solution (there are some significant differences between Blazor server-side and Web Assembly implementations in regards to telemetry). I'll walk through some of the stories I've considered though, for reference: In either scenario JavaScript-interop with external libraries could result in Ajax requests, so there is some merit to the existing JavaScript SDK, but this is not the primary usage pattern expected of Blazor applications in general (and often those requests would be to 3rd party service providers which could frequently be configured to either not record telemetry or filter correlation headers). Blazor Web Assembly currently uses the browser's HTTP stack via JavaScript interop, which may make the JavaScript SDK a viable implementation with a little extra support for its routing system akin to those used with Angular and other JavaScript SPA frameworks. Assuming WASM forever needs to use importObject to access the browser's fetch/XHR stack, this may be a durable enough solution. Blazor server-side performs all C# operations in an ASP.NET Core 3.1 applications, including any Web API calls performed via HttpClient. The DOM is synchronized and any JS interop is performed across a SignalR-based WebSocket mechanism referred to as a Circuit. All navigation events are available (and primarily managed) server side and any call from C# to JavaScript is a message from the server to the client. In this scenario the ongoing context of a Page View is known to the server more than to the client; navigation events integrating with Application Insights will first be understood on the C# side and any JS-interop to track a page view will be sent from the server to the client and then from the client to AI (which makes the page view come from the actual browser's IP address, but otherwise requires an additional hop to record telemetry). Additionally, whatever HTTP or SQL dependencies are performed by the server should be correlated with the current page view; no HTTP headers will be received after the first request because all subsequent operations will be conducted through the Circuit, so existing middleware to correlate ASP.NET Core Requests with Dependencies will not work out-of-box and all dependencies (as-is) would be root telemetry operations. As per microsoft/ApplicationInsights-node.js#154 it doesn't seem like every event that crosses the Circuit would want to be identified as a request, but ideally any dependency performed on the backend would be associated with the page view. To this end I believe a successful Blazor server-side story requires a C# mechanism to correlate downstream operation telemetry with a page view that isn't received via an HTTP header. |
Also, @novotnyllc (or @onovotny - not sure if one is preferable over the other for issue discussion) - it seems like it might be worth looping you into this discussion? I've recently stumbled on your I know us Desktop Application people are not the most common use case, but here's a little bit about our environment, where it came from and where we're trying to go with Application Insights. Hopefully it helps put the wider picture into perspective. In the past we had to implement our own correlation and tracking in all ways since the non-ASP.NET libraries didn't perform any form of automatic dependency tracking (neither HTTP nor SQL) or correlation. Our services were implemented with WCF so we already had to pass correlation across the wire with custom service behaviors. We took advantage of our existing ambient correlation structures (previously based on Now that .NET Standard has improved library portability and the official libraries have mechanisms for ambient correlation and automatic tracking of dependencies built in for non-ASP.NET environments (like the WorkerService package) we've been trying to update to the latest and cut all of our outdated code out. We're super close to being able to remove almost everything redundant (we'll keep some nice convenience features, the WPF aspect, some telemetry initializers that incorporate our other diagnostic work, etc.) but page view correlation is an important piece of our story, and Blazor is our next wave client which it feels like will also need attention in this area. |
Today PageView also doesn't have a response code of any sort - it doesn't indicate aborted or pages failed to load. That's said it's not how UI visualizes PageView now. And I understand where the desire of having So we are in the situation when we want to make PageView about visits and promote PageViewPerformance or analogous to be about latency, duration, correlation and results. But with no specific plans. Would the solution of having an external API work for you? You can create a new class inherited from |
Thanks for the details. We discussed the possibility of this workaround, but we'd rather avoid the technical debt of maintaining it. We previously maintained our own correlation layer because we adopted before the SDK implementation was complete, which has caused a pretty major overhaul when updating to the latest packages migrating to the latest frameworks. We'd rather avoid doing things like that going forward if we can. Just to entertain a thought, though, if we took the approach of making our own telemetry type and wanted to correlate operations with it after the initial operation has completed (which is standard behavior in page views with the JS SDK today) would it seem functional/acceptable to have another custom telemetry type inherit from OperationTelemetry just to restablish the same context id/parent id? Maybe we could use a filter to prevent tracking this operation while still leveraging the existing logic for ambient correlation? Given that Would there be any consideration for Do you have any guidance on what we should do if we were to try to create a pull request that would satisfy our need to have the JS SDK capabilities available in the .NET SDK? Is a pull request for such a thing likely to be accepted? Also, I've poked around in SignalR and Blazor a bit trying to ponder what might be the right place to integrate with Blazor, both from a Blazor WebAssembly perspective as well as a Blazor server-side perspective (which is a bigger priority for us at the moment). It seems like the WebAssembly version may be able to use the JavaScript SDK well enough, but since server-side performs all navigations and service calls through a SignalR-based WebSocket, it's difficult to see how one might cause all Dependencies to be associated with a common operation id. Do you have any advice on what the best approach might be to establish ambient correlation there? Ideally we would start new operations with new page views by tying in to I know that's a ton of questions in different directions. I appreciate any insight. Thanks for your time. |
I haven't tried correlating the requests from a PageView, but I agree that it would be useful to have. I also thought about Blazor and that it would probably be useful to have AppInsights working for those apps as well. For the Desktop scenario, I'm open to any PR's to implement things before they're available in any base SDK. |
@ramthi what's your position on the future of I'd say neither will become an operation. Directionally we will move to OpenTelemetry data model where distributed tracing will be represented by Spans and As of data model for messaging patterns - we are thinking of a few possibilities:
Depending on specific technology and scenario one of the approaches must work. But again, this is la bit longer term thing. As of now - I'd advice to implement |
I've tried something (created a custom telemetry type which inherits from |
This issue is stale because it has been open 300 days with no activity. Remove stale label or comment or this will be closed in 7 days. |
@SergeyKanzhelev could you elaborate regarding
I've tried something (created a custom telemetry type which inherits from |
Maybe @cijothomas can help. I'm not part of this team any longer and the exact extensibility points that are available in SDK to implement this are fading away from my memory. |
This issue is stale because it has been open 300 days with no activity. Remove stale label or this will be closed in 7 days. Commenting will instruct the bot to automatically remove the label. |
I would love to be able to start an operation on a
PageViewTelemetry
but right now that is not possible. I am trying to instrument a desktop application using AI but while I can get the requests and dependency working I cannot track a PageView using StartOperation and have the requests and dependencies as a suboperation of PageView.For example, given the code below, any subsequent calls are childs of the request, but how can I track a PageViewTelemetry that has a request as a child?
I cannot do
using (_telemetryClient.StartOperation<PageViewTelemetry>(nameof(Form1)))
When I go to the AI resource in the Azure Portal I see this:
PageView
Request
= Dependency
== Exception
so it is not clear that the request is caused by the pageview. I would like to get this:
PageView
= Request
==== Dependency
======== Exception
The text was updated successfully, but these errors were encountered: