-
Notifications
You must be signed in to change notification settings - Fork 140
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
Node 8 / Async: Auto-Correlation support #381
Comments
I don't believe this is the same as #296 but something deeper. It's my current understanding that we don't have the proper integration points with our monkeypatching approach to apply context propagation across native async /await (vs say async/await transpiled into Promises). In newer versions of node the experimental async_hooks API may be providing the necessary information for us to propagate context, but we don't yet support this (and I believe it has performance implications). Some things that I think are related:
|
Thanks @OsvaldoRosado. Reading angular/zone.js#715 I agree that this does sound v.similar. If this limitation is something that you are choosing to adopt (rather than considering alternatives) then I really feel this needs to be quite explicitly documented - including alternatives / workarounds. Speaking of workarounds, are you able to offer any suggestions for how we might move forward in the interim?
Alternative Have you considered One obvious drawback is a lack of browser support. But would it be possible to plug-in/configure your context propogation technology of choice? |
Suggestions: The
Are we waiting for Clearly documenting some of the known limitations we have because we don't yet have an implementation that takes advantage of Why zone.js over cls?: Browser support isn't a main concern for us, since this SDK is intended for server-side node vs our separate client-side js package. If the compatibility landscape has changed between zone and cls we could consider changing our underlying context propagation. Having support for dropping in your own context propagation sounds like a great idea to me, since this is something that will definitely vary from app-to-app. Our library for managing context and collection patches for third-party modules like Redis and Mongo (https://github.com/Microsoft/node-diagnostic-channel/) already supports this, so it might not be much effort to expose it through this SDK as well. |
Yeah, I think the zone/cls debate is fairly moot if they would both depend upon I'm currently leaning towards a Node6/8 implementation with co/generators until native async is fully supported. But that's a conversation for my team. Linting checks for async/await should be an easy build time solution. |
Hi, as this is already an issue that is a bit older, I wanted to ask, if there were some steps forward with this or if you can propose a workaround. In our current code we use TypeScript and async/await, the compile target is ES6, but also with ES5 it isn't working. What we do is just a REST request to get some additional information. All other traces (logs from winston) are tracked within the right context of the incoming request, but our request to the other service is without operation id. I guess therefore this is the same issue. What I also tried is the usage of Is there any other way you can think of, that I could try beside avoiding async/await? btw. we are using the "request" library (like almost everyone I guess :-D ) |
@janis91 No steps forward for now other than to avoid async/await (assuming you are being impacted by this issue and not something else). When your compile target is set to ES5 is typescript converting your async/await to promises/generators in the resulting JS? |
@janis91 Actually from
I think you might be hitting a different issue. Does this seem to be #396 ? If this problem is with correlation between services (requests should be associated with dependencies that caused them) rather than correlation of telemetry within a service (dependencies should be associated with requests that caused them) this might be the case |
It is converting it to generators, if I'm right: "use strict";
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
function someAsyncFunction() {
return __awaiter(this, void 0, void 0, function* () {
someAwaitedFunction();
});
}
I think it's most likely this issuer here. I try to explain again:
This is a typical scenario in our service and unfortunately step 4 is causing that requests to other third-party services are not tracked within the same operation. I can find them tracked in AI at the same time, but without any correlation because the operation id is undefined. |
@janis91 Thanks for the extra detail! Just for clarity on step 4:
Is this item that's not correlated here the dependency recorded by the calling server, or the request recorded by the authorization server? |
The dependency. The authorization server is a third party, I don't have control over that one. |
Adding a note to this thread that #474 should address this and allow correlation to work across async/await. |
Hey @OsvaldoRosado that's great news. |
On the cls-hooked page, it mentions
From my understanding, for that range of versions, user should do some verification if everything works fine. |
Just adding to what @khairihafsham stated, the async API we use changes at Node 8.2.0. From looking at cls-hooked code, this seems to be the case as well (not at 8.2.1 as it is documented there). Before 8.2.0, we use async-listener (via plain cls library) instead of async_hooks (cls-hooked). |
@khairihafsham We only load @GavinOsborn You'll need to be on at least Node 8.2 to get correlation tracking working across native async/await. There may also be performance penalties to the Node APIs used to monitor async/await and Promises depending on your particular workload. I'd expect newer Node the better in terms of reducing these penalties. |
Thanks for the update @OsvaldoRosado @markwolff. Is it fair to say that async/await support is still |
@GavinOsborn It has been released to stable now ( |
@GavinOsborn as far as "use at your own risk" is concerned, I wouldn't expect anything like application crashes. (and as @markwolff says, it's certainly a lot more stable than our zone implementation was in this regard 😄) The underlying Node APIs are indeed non-final, but that's more of a problem of our SDK updating to support newer versions of Node when/if the APIs change. The main thing to watch is if your particular workload gets a noticably higher performance overhead from the underlying V8 async/await monitoring that upgrading Node versions doesn't mitigate. |
Closing this since it has been implemented and can be considered production ready at this point |
TL/DR
Auto dependency correlation appears to fail in all but the most trivial async/await scenarios.
I understand that you can't always rely on context propagation in nodejs but this seems too simple to be expected.
In more detail
Everything I'm about to say can be reproduced from this gist.
Recently I converted an existing application from a node 6 web API to node 8 and began updating the code-base to leverage async/await functionality. This application integrates with various Azure PaaS systems including Cosmos DB and Azure Storage. Everything was working great until we checked our application insights integration. I noticed that all of the data was there but all of a sudden our tracing and dependency correlation was broken.
Checking the issues page I thought it may be related to #296 (our application is quite complex) so I tried to boil it down to the simplest of repro steps - and it really was simple.
Looking at the gist you'll see that executing 1 async operation generates perfectly good dependency correlation
curl http://localhost:3000/endpoint/simple
But executing a series of identical async operations will drop the context half-way through the request
curl http://localhost:3000/endpoint/complex
But switching this to either a promise chain or a generator based solution produces perfect correlation
curl http://localhost:3000/endpoint/chained
Environment:
I understand that you can't always rely on context propagation in nodejs but this seems too simple to be expected.
Am I doing something wrong?
Is this the same issue as #296?
Please advise.
The text was updated successfully, but these errors were encountered: