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

fix: handling of multipleInstrumentationNodeModuleDefinition with the same name #3

Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
53 changes: 28 additions & 25 deletions packages/esbuild-plugin-node/src/common.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,39 +32,42 @@ export function wrapModule(
${originalSource}
})(...arguments);
{
let mod = module.exports;

const { satisfies } = require('semver');
const { ${oTelInstrumentationClass} } = require('${oTelInstrumentationPackage}');
const { diag } = require('@opentelemetry/api');
drewcorlin1 marked this conversation as resolved.
Show resolved Hide resolved
const instrumentations = new ${oTelInstrumentationClass}(${oTelInstrumentationConstructorArgs}).getModuleDefinitions();

if (instrumentations.length > 1 && !'${instrumentationName}') {
diag.error('instrumentationName must be specified because ${oTelInstrumentationClass} has multiple instrumentations');
return;
}
const instrumentation = ${
instrumentationName
? `instrumentations.find(i => i.name === '${instrumentationName}')`
: 'instrumentations[0]'
};
try {
let mod = module.exports;

if (instrumentation.patch) {
mod = instrumentation.patch(mod)
}
const { satisfies } = require('semver');
const { ${oTelInstrumentationClass} } = require('${oTelInstrumentationPackage}');
const instrumentations = new ${oTelInstrumentationClass}(${oTelInstrumentationConstructorArgs}).getModuleDefinitions();

if (instrumentation.files?.length) {
for (const file of instrumentation.files.filter(f => f.name === '${path}')) {
if (!file.supportedVersions.some(v => satisfies('${moduleVersion}', v))) {
diag.debug('Skipping instrumentation for ${path}@${moduleVersion} because it does not match supported versions ' + file.supportedVersions.join(','));
for (const instrumentation of instrumentations.filter(i => i.name === '${instrumentationName}')) {
if (!instrumentation.supportedVersions.some(v => satisfies('${moduleVersion}', v))) {
diag.debug('Skipping instrumentation ${instrumentationName}, because module version ${moduleVersion} does not match supported versions ' + instrumentation.supportedVersions.join(','));
continue;
}
mod = file.patch(mod, '${moduleVersion}');
}
}

if (instrumentation.patch) {
drewcorlin1 marked this conversation as resolved.
Show resolved Hide resolved
diag.debug('Applying instrumentation patch ${instrumentationName} via esbuild-plugin-node');
drewcorlin1 marked this conversation as resolved.
Show resolved Hide resolved
mod = instrumentation.patch(mod)
}

module.exports = mod;
if (instrumentation.files?.length) {
for (const file of instrumentation.files.filter(f => f.name === '${path}')) {
if (!file.supportedVersions.some(v => satisfies('${moduleVersion}', v))) {
diag.debug('Skipping instrumentation for ${path}@${moduleVersion} because it does not match supported versions' + file.supportedVersions.join(','));
continue;
}
diag.debug('Applying instrumentation patch to ${path}@${moduleVersion} via esbuild-plugin-node');
mod = file.patch(mod, '${moduleVersion}');
}
}
}

module.exports = mod;
} catch (e) {
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Shouldn't we throw the underlying error to make any issues with this visible to users without requiring them to set the OTel diag log level?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My opinion is that bugs in instrumentation (especially automatic) shouldn't break the service. I would like to surface the errors message of course.

I'm not sure what's idiomatic across otel, but I think this is a similar case to how auto-instrumentations-node handles startup errors here: https://github.com/open-telemetry/opentelemetry-js-contrib/blob/main/metapackages/auto-instrumentations-node/src/register.ts#L37

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good point + agree the consistency with auto instrumentations is good

diag.error('Error applying instrumentation ${instrumentationName}', e);
}
}
`;
}