diff --git a/packages/opentelemetry-core/src/trace/instrumentation/BasePlugin.ts b/packages/opentelemetry-core/src/trace/instrumentation/BasePlugin.ts index 90631c7830b..b50f739481e 100644 --- a/packages/opentelemetry-core/src/trace/instrumentation/BasePlugin.ts +++ b/packages/opentelemetry-core/src/trace/instrumentation/BasePlugin.ts @@ -21,6 +21,7 @@ export abstract class BasePlugin implements Plugin { protected _moduleExports!: T; protected _tracer!: Tracer; protected _logger!: Logger; + supportedVersions?: string[]; enable( moduleExports: T, diff --git a/packages/opentelemetry-node-tracer/src/instrumentation/PluginLoader.ts b/packages/opentelemetry-node-tracer/src/instrumentation/PluginLoader.ts index 7137983bfae..20a680a097e 100644 --- a/packages/opentelemetry-node-tracer/src/instrumentation/PluginLoader.ts +++ b/packages/opentelemetry-node-tracer/src/instrumentation/PluginLoader.ts @@ -90,8 +90,6 @@ export class PluginLoader { `PluginLoader#load: trying loading ${name}.${version}` ); - // @todo (issues/132): Check if version and supportedVersions are - // satisfied if (!version) return exports; this.logger.debug( @@ -101,6 +99,11 @@ export class PluginLoader { // Expecting a plugin from module; try { const plugin: Plugin = require(moduleName).plugin; + + if (!utils.isSupportedVersion(version, plugin.supportedVersions)) { + return exports; + } + this._plugins.push(plugin); // Enable each supported plugin. return plugin.enable(exports, this.tracer, this.logger); diff --git a/packages/opentelemetry-node-tracer/src/instrumentation/utils.ts b/packages/opentelemetry-node-tracer/src/instrumentation/utils.ts index de9648e3024..1ea90230142 100644 --- a/packages/opentelemetry-node-tracer/src/instrumentation/utils.ts +++ b/packages/opentelemetry-node-tracer/src/instrumentation/utils.ts @@ -60,6 +60,19 @@ export function getPackageVersion( } } +export function isSupportedVersion( + moduleVersion: string, + supportedVersions?: string[] +) { + if (!Array.isArray(supportedVersions)) { + return true; + } + + return supportedVersions.some(supportedVersion => + semver.satisfies(moduleVersion, supportedVersion) + ); +} + /** * Adds a search path for plugin modules. Intended for testing purposes only. * @param searchPath The path to add. diff --git a/packages/opentelemetry-node-tracer/test/instrumentation/utils.test.ts b/packages/opentelemetry-node-tracer/test/instrumentation/utils.test.ts index 66d25390c59..c90bb469c90 100644 --- a/packages/opentelemetry-node-tracer/test/instrumentation/utils.test.ts +++ b/packages/opentelemetry-node-tracer/test/instrumentation/utils.test.ts @@ -69,4 +69,45 @@ describe('Instrumentation#utils', () => { }); }); }); + describe('isSupportedVersion', () => { + const version = '1.0.1'; + + it('should return true when supportedVersions is not defined', () => { + assert.strictEqual(utils.isSupportedVersion('1.0.0', undefined), true); + }); + + [ + ['1.X'], + [version], + ['1.X.X', '3.X.X'], + ['^1.0.0'], + ['~1.0.0', '^0.1.0'], + ['*'], + ['>1.0.0'], + ].forEach(supportedVersion => { + it(`should return true when version is equal to ${version} and supportedVersions is equal to ${supportedVersion}`, () => { + assert.strictEqual( + utils.isSupportedVersion(version, supportedVersion), + true + ); + }); + }); + + [['0.X'], ['0.0.1'], ['0.X.X'], ['^0.1.0'], ['1.0.0'], ['<1.0.0']].forEach( + supportedVersion => { + it(`should return false when version is equal to ${version} and supportedVersions is equal to ${supportedVersion}`, () => { + assert.strictEqual( + utils.isSupportedVersion(version, supportedVersion), + false + ); + }); + } + ); + + it(`should return false when version is equal to null and supportedVersions is equal to '*'`, () => { + /* tslint:disable:no-any */ + assert.strictEqual(utils.isSupportedVersion(null as any, ['*']), false); + /* tslint:enable:no-any */ + }); + }); }); diff --git a/packages/opentelemetry-types/src/trace/instrumentation/Plugin.ts b/packages/opentelemetry-types/src/trace/instrumentation/Plugin.ts index 643a4d45291..0c1174d963e 100644 --- a/packages/opentelemetry-types/src/trace/instrumentation/Plugin.ts +++ b/packages/opentelemetry-types/src/trace/instrumentation/Plugin.ts @@ -20,6 +20,14 @@ import { Logger } from '../../common/Logger'; /** Interface Plugin to apply patch. */ // tslint:disable-next-line:no-any export interface Plugin { + /** + * Contains all supported versions. + * all versions must be compatible with [semver](https://semver.org/spec/v2.0.0.html) format. + * If the version is not supported, we won't apply instrumentation patch (see `enable` method). + * If not defined, we will apply instrumentation for every version. + */ + supportedVersions?: string[]; + /** * Method that enables the instrumentation patch. * @param moduleExports The value of the `module.exports` property that would