A plugin patches a Node.js library so calls made by that library create SkyWalking spans. Read an existing plugin close to your target library before adding a new one.
Each automatic plugin in src/plugins/ implements SwPlugin and exports one default instance:
class ExamplePlugin implements SwPlugin { readonly module = 'example-library'; readonly versions = '^1.0.0'; install(installer: PluginInstaller): void { const target = installer.require?.(this.module) ?? require(this.module); // Patch the target API. } } export default new ExamplePlugin();
Use a file name ending in Plugin.ts. The normal loader scans compiled files in lib/plugins/.
module is the npm module that must be installed in the application.versions is a semantic version range checked by the loader.isBuiltIn = true only for a Node.js built-in module such as http.installer.require when possible so the plugin loads the application's copy of the module.Choose a version range from real API support. Do not use * only to avoid checking versions.
Keep library behavior unchanged apart from trace collection:
this, arguments, return values, thrown errors, callbacks, events, and Promise results.ContextManager.current.span.async() and span.resync() when work leaves and later returns to the active async path.src/core/SwPlugin.ts provides helpers for common callback, Promise, and event-emitter completion forms. Some libraries need a local helper because their API has different completion rules.
Use an existing component in src/trace/Component.ts when it matches. A new component ID must be agreed with the SkyWalking project so it does not conflict with another agent or integration.
Create tests/plugins/<module>/ by following a similar plugin suite. A normal suite contains:
test.ts to start Docker Compose and send expected data to the mock collector;docker-compose.yml for the collector, application, and target service;expected.data.yaml with the expected SkyWalking segment data.Add the target package to devDependencies and update package-lock.json when the test needs it. The CI plugin matrix finds each directory under tests/plugins/ except common, so a new directory becomes a CI job without a manual matrix entry.
Run the suite:
npm run test tests/plugins/example-library/
Also run lint and build as described in Build and test.
The normal loader finds a compiled plugin automatically. The Webpack loader does not. If the target package allows its package.json to be imported, add the plugin to PluginInstaller.installBundled() and test a production bundle.
If this is not possible, state the limit in Webpack. Do not claim Webpack support based only on the normal plugin test.
For a new plugin: