-
Notifications
You must be signed in to change notification settings - Fork 156
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
XRAY does not work when an app initialises AWS clients that are already initialised in imported libraries #315
Comments
Hi @theshumanator,
|
Hi @willarmiros - thanks for your reply.
I'm going to try your suggestions and let you know how it goes. |
Hi @willarmiros - unfortunately the suggested changes did not work. Thanks.
|
Hi @theshumanator, |
Hi @willarmiros - yep it is enabled for all lambdas. |
Interesting, normally as the last line of logging output for X-Ray enabled Lambdas (after the REPORT line) you'll see something like:
Can you confirm you're seeing this? I'm particularly interested by the |
This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs in next 7 days. Thank you for your contributions. |
Reopening as this issue is still being experienced. |
We're experiencing a similar issue, if not the same, in the version 2.5 of this SDK. According to both @theshumanator logs posted above and ours, the SDK is initialised multiple times (note that "Starting the AWS X-Ray SDK in automatic mode"), which causes previous internal states to be lost. In both cases, this seems to occur when multiple libraries that use this SDK are used simultaneously and the dependencies to this SDK can't be flattened (eg, because their versions don't match, or because they are symlinked via Lerna). I'm not familiar with the implementation details but the cause may be related to a couple of details:
Not sure how feasible it would be to support this use case. The alternative for us would be to expose this SDK as a peer dependency across all of its upstream dependents to ensure a single copy is ever loaded, but that's far from ideal. EDIT: Fixed possible causes |
@frosas I don't think that several different versions of the X-Ray SDK would cause this, primarily because there are only 4 versions where "Disabling Centralized Sampling in Lambda" is logged and it's printed out 5 times, so I don't think each unique version could cause it. Several libraries depending on the SDK and them not getting flattened sounds more likely. My follow-up questions are does this repeated initialization logging happen on every invocation, or just on cold starts? And what impact are you observing, are you also not seeing Lambda functions traced? The initialization should be idempotent, but of course there would be problems if it overwrote custom settings of yours. |
Yes. That's why I was referring to multiple "copies", not versions 🙂
As far I remember, the repeated initialization happened only on cold starts. The impact we observed was segments not being recorded under the correct trace, or not being recorded at all. Our logs also showed the X-Ray request headers not being correctly formed, eg If it helps, I can see at least a couple of places where the initialization code is not idempotent: // packages/core/lib/context_utils.js
cls.createNamespace(NAMESPACE);
logger.getLogger().debug('Starting the AWS X-Ray SDK in automatic mode (default).');
if (process.env.AWS_XRAY_CONTEXT_MISSING) {
contextUtils.setContextMissingStrategy(process.env.AWS_XRAY_CONTEXT_MISSING);
contextOverride = true;
} else {
contextUtils.contextMissingStrategy.contextMissing = contextUtils.CONTEXT_MISSING_STRATEGY.RUNTIME_ERROR.contextMissing;
logger.getLogger().debug('Using default context missing strategy: RUNTIME_ERROR');
} // packages/core/lib/aws-xray.js
(function() {
var data = {
runtime: (process.release && process.release.name) ? process.release.name : UNKNOWN,
runtime_version: process.version,
version: process.env.npm_package_version || UNKNOWN,
name: process.env.npm_package_name || UNKNOWN
};
var sdkData = {
sdk: 'X-Ray for Node.js',
sdk_version: (module.exports && module.exports.version) ? module.exports.version : UNKNOWN,
package: (module.exports && module.exports.name) ? module.exports.name : UNKNOWN,
};
segmentUtils.setSDKData(sdkData);
segmentUtils.setServiceData(data);
if (process.env.LAMBDA_TASK_ROOT)
LambdaEnv.init();
})(); Btw, we just rewrote the X-Ray integration so that the library is loaded just once (and then its single instance is injected where needed), and the issue went away. |
@frosas thank you for the info! I think we can do a couple changes to make the initialization idempotent, namely:
I have not yet been able to reliably reproduce this issue, but given that your issue was resolved when the library was loaded only once, I think the above two items should fix whatever the underlying bug re-initialization was causing. If you'd like to take a stab at a PR for I'd be happy to review, otherwise I'll add it to our backlog. |
We considered that exact same approach, where we would use the SDK via a wrapper including the logic you detailed. We ended up dismissing that idea, though. By permitting multiple copies of the SDK, there was the possibility of ending up with multiple versions, which would confuse us as it wouldn't be clear which actual version is running. Other SDK users would find that behavior acceptable though. Alternatively, you could warn when the SDK init logic detects the presence of the SDK already being initialized. That way, at least user would be able to troubleshoot the issue more easily. |
Hello,
I'm seeing a strange issue with XRAY. Apologies if the title isn't clear. I'll describe the issue below:
Setup
The libraries and framework are bundled using webpack
The first point of entry of the app is a lambda function called
firstFunction
. All of the processing for this function is in the framework. It sends an SNS which is then handled by another lambda function calledsecondFunction
.secondFunction
is partially handled in the framework; it performs some tasks then emits events (I use theNodeJS.EventEmitter
). The event handling happens in the app whereas all tasks until and including event emission happen int he framework.Problem
I see XRAY traces lambda
firstFunction
but not forsecondFunction
.Workaround that works
The current workaround is not ideal but here it is:
So in the app, I go from:
...to:
Basically, any fn in these libraries that uses AWS clients should be imported via the framework and not directly from the library.
my-aws-clients
which basically has this:Then I exposed these in the framework so my app can import these AWS clients from the framework.
my-aws-clients
.Why is the workaround not ideal
I have libraries that do tasks which shouldn't be imported/exposed via the framework; basically it's not their place. For one particular library, I had to copy the entire code into the app so that the AWS interactions of this library happen via the AWS clients that are coming from the framework. This particular library is meant to be used by others apps/teams that have no relation to the framework so I cannot have the dependency on the framework.
What I tried that did not work
my-aws-clients
. But it looks like if I do that, XRAY is re-initialised and the rootId becomes null.secondFunction
in the app to replace the existing one from the framework. In this function, I did a simple Dynamo query (so no event emitters, etc) to see if there is any problem with event emitters. But this also did not work.Pls let me know if you require more info.
Thank you!
The text was updated successfully, but these errors were encountered: