feat(js): add JavaScript instrumentation watcher and initial registry#577
Conversation
✅ Deploy Preview for otel-ecosystem-explorer canceled.
|
|
Hey @jaydeluca , Could you review it? |
|
Hi @MeloveGupta, thanks for your contribution! Just a tip: you don't need to tag the approvers / maintainers every time you open a PR - GitHub already does this automatically. It might take a bit since maintainers have a lot going on, but don't worry, your PR will get reviewed. If it's been over a week with no activity, feel free to tag someone then. Thanks! |
| "PyYAML>=6.0.1", | ||
| "GitPython>=3.1.40", |
There was a problem hiding this comment.
I just removed the need for these dependencies from the other modules in #600 could you take a look and do the same thing for this new watcher?
| """ | ||
| Manages storage of JS instrumentation metadata in the registry. | ||
|
|
||
| Registry layout (per maintainer direction): |
There was a problem hiding this comment.
| Registry layout (per maintainer direction): | |
| Registry layout: |
|
|
||
| Each package is versioned independently — there is no single | ||
| aggregated version file like the Java watcher uses. |
There was a problem hiding this comment.
| Each package is versioned independently — there is no single | |
| aggregated version file like the Java watcher uses. |
| # limitations under the License. | ||
| # | ||
|
|
||
| """Tests for InventoryManager.""" |
There was a problem hiding this comment.
you need to add a new job to the https://github.com/open-telemetry/opentelemetry-ecosystem-explorer/blob/main/.github/workflows/build-and-test.yml#L53 workflow to run the tests for this module in CI
| "source": "README.md", | ||
| }) | ||
|
|
||
| return results |
There was a problem hiding this comment.
whenever possible with watchers we want to sort things so that the data is always written in a deterministic way
| return results | |
| return sorted(results, key=lambda x: (x["package"], x["version_range"])) |
| if isinstance(versions, dict) and versions: | ||
| results.append(self._build_tav_entry(pkg_name, versions)) | ||
|
|
||
| return results No newline at end of file |
There was a problem hiding this comment.
| return results | |
| return sorted(results, key=lambda x: (x["package"], x["range"])) |
| entry: dict = { | ||
| "package": pkg_name, | ||
| "range": versions.get("include", ""), | ||
| "mode": versions.get("mode", ""), | ||
| "source": ".tav.yml", | ||
| } |
There was a problem hiding this comment.
Let's do the same pattern we're using for exclude and only add this when not empty
| entry: dict = { | |
| "package": pkg_name, | |
| "range": versions.get("include", ""), | |
| "mode": versions.get("mode", ""), | |
| "source": ".tav.yml", | |
| } | |
| entry: dict = { | |
| "package": pkg_name, | |
| "range": versions.get("include", ""), | |
| "source": ".tav.yml", | |
| } | |
| mode = versions.get("mode", "") | |
| if mode: | |
| entry["mode"] = mode |
| COMPONENT_OWNERS_FILE = ".github/component_owners.yml" | ||
|
|
||
|
|
||
| class PackageScanner: |
There was a problem hiding this comment.
this class has enough logic in it that i think it deserves some tests
There was a problem hiding this comment.
Pull request overview
Adds a new Python watcher to sync metadata for opentelemetry-js-contrib instrumentation packages into the repo’s versioned registry, plus an initial generated snapshot of the JS registry output.
Changes:
- Introduces
js-instrumentation-watcher(repo clone/pull, package discovery, metadata parsing, registry writes). - Wires the new watcher into the
uvworkspace and rootpyproject.toml. - Adds initial
ecosystem-registry/javascript/<package>/v<version>.yamlentries for current active packages.
Reviewed changes
Copilot reviewed 59 out of 60 changed files in this pull request and generated 10 comments.
Show a summary per file
| File | Description |
|---|---|
| uv.lock | Adds js-instrumentation-watcher as a workspace package and locks its deps. |
| pyproject.toml | Registers js-instrumentation-watcher in the root workspace/dependencies. |
| ecosystem-registry/javascript/instrumentation-winston/v0.62.0.yaml | Initial generated registry entry for instrumentation-winston. |
| ecosystem-registry/javascript/instrumentation-web-exception/v0.11.0.yaml | Initial generated registry entry for instrumentation-web-exception. |
| ecosystem-registry/javascript/instrumentation-user-interaction/v0.62.0.yaml | Initial generated registry entry for instrumentation-user-interaction. |
| ecosystem-registry/javascript/instrumentation-undici/v0.28.0.yaml | Initial generated registry entry for instrumentation-undici. |
| ecosystem-registry/javascript/instrumentation-typeorm/v0.18.0.yaml | Initial generated registry entry for instrumentation-typeorm. |
| ecosystem-registry/javascript/instrumentation-tedious/v0.37.0.yaml | Initial generated registry entry for instrumentation-tedious. |
| ecosystem-registry/javascript/instrumentation-socket.io/v0.65.0.yaml | Initial generated registry entry for instrumentation-socket.io. |
| ecosystem-registry/javascript/instrumentation-sequelize/v0.11.0.yaml | Initial generated registry entry for instrumentation-sequelize. |
| ecosystem-registry/javascript/instrumentation-runtime-node/v0.31.0.yaml | Initial generated registry entry for instrumentation-runtime-node. |
| ecosystem-registry/javascript/instrumentation-router/v0.62.0.yaml | Initial generated registry entry for instrumentation-router. |
| ecosystem-registry/javascript/instrumentation-restify/v0.63.0.yaml | Initial generated registry entry for instrumentation-restify. |
| ecosystem-registry/javascript/instrumentation-redis/v0.66.0.yaml | Initial generated registry entry for instrumentation-redis. |
| ecosystem-registry/javascript/instrumentation-pino/v0.64.0.yaml | Initial generated registry entry for instrumentation-pino. |
| ecosystem-registry/javascript/instrumentation-pg/v0.70.0.yaml | Initial generated registry entry for instrumentation-pg. |
| ecosystem-registry/javascript/instrumentation-oracledb/v0.43.0.yaml | Initial generated registry entry for instrumentation-oracledb. |
| ecosystem-registry/javascript/instrumentation-openai/v0.16.0.yaml | Initial generated registry entry for instrumentation-openai. |
| ecosystem-registry/javascript/instrumentation-net/v0.62.0.yaml | Initial generated registry entry for instrumentation-net. |
| ecosystem-registry/javascript/instrumentation-nestjs-core/v0.64.0.yaml | Initial generated registry entry for instrumentation-nestjs-core. |
| ecosystem-registry/javascript/instrumentation-mysql2/v0.64.0.yaml | Initial generated registry entry for instrumentation-mysql2. |
| ecosystem-registry/javascript/instrumentation-mysql/v0.64.0.yaml | Initial generated registry entry for instrumentation-mysql. |
| ecosystem-registry/javascript/instrumentation-mongoose/v0.64.0.yaml | Initial generated registry entry for instrumentation-mongoose. |
| ecosystem-registry/javascript/instrumentation-mongodb/v0.71.0.yaml | Initial generated registry entry for instrumentation-mongodb. |
| ecosystem-registry/javascript/instrumentation-memcached/v0.61.0.yaml | Initial generated registry entry for instrumentation-memcached. |
| ecosystem-registry/javascript/instrumentation-lru-memoizer/v0.62.0.yaml | Initial generated registry entry for instrumentation-lru-memoizer. |
| ecosystem-registry/javascript/instrumentation-long-task/v0.62.0.yaml | Initial generated registry entry for instrumentation-long-task. |
| ecosystem-registry/javascript/instrumentation-langchain/v0.6.0.yaml | Initial generated registry entry for instrumentation-langchain. |
| ecosystem-registry/javascript/instrumentation-koa/v0.66.0.yaml | Initial generated registry entry for instrumentation-koa. |
| ecosystem-registry/javascript/instrumentation-knex/v0.62.0.yaml | Initial generated registry entry for instrumentation-knex. |
| ecosystem-registry/javascript/instrumentation-kafkajs/v0.27.0.yaml | Initial generated registry entry for instrumentation-kafkajs. |
| ecosystem-registry/javascript/instrumentation-ioredis/v0.66.0.yaml | Initial generated registry entry for instrumentation-ioredis. |
| ecosystem-registry/javascript/instrumentation-hapi/v0.64.0.yaml | Initial generated registry entry for instrumentation-hapi. |
| ecosystem-registry/javascript/instrumentation-graphql/v0.66.0.yaml | Initial generated registry entry for instrumentation-graphql. |
| ecosystem-registry/javascript/instrumentation-generic-pool/v0.61.0.yaml | Initial generated registry entry for instrumentation-generic-pool. |
| ecosystem-registry/javascript/instrumentation-fs/v0.37.0.yaml | Initial generated registry entry for instrumentation-fs. |
| ecosystem-registry/javascript/instrumentation-express/v0.66.0.yaml | Initial generated registry entry for instrumentation-express. |
| ecosystem-registry/javascript/instrumentation-document-load/v0.63.0.yaml | Initial generated registry entry for instrumentation-document-load. |
| ecosystem-registry/javascript/instrumentation-dns/v0.61.0.yaml | Initial generated registry entry for instrumentation-dns. |
| ecosystem-registry/javascript/instrumentation-dataloader/v0.35.0.yaml | Initial generated registry entry for instrumentation-dataloader. |
| ecosystem-registry/javascript/instrumentation-cucumber/v0.34.0.yaml | Initial generated registry entry for instrumentation-cucumber. |
| ecosystem-registry/javascript/instrumentation-connect/v0.61.0.yaml | Initial generated registry entry for instrumentation-connect. |
| ecosystem-registry/javascript/instrumentation-cassandra-driver/v0.63.0.yaml | Initial generated registry entry for instrumentation-cassandra-driver. |
| ecosystem-registry/javascript/instrumentation-bunyan/v0.63.0.yaml | Initial generated registry entry for instrumentation-bunyan. |
| ecosystem-registry/javascript/instrumentation-browser-navigation/v0.11.0.yaml | Initial generated registry entry for instrumentation-browser-navigation. |
| ecosystem-registry/javascript/instrumentation-aws-sdk/v0.73.0.yaml | Initial generated registry entry for instrumentation-aws-sdk. |
| ecosystem-registry/javascript/instrumentation-aws-lambda/v0.70.0.yaml | Initial generated registry entry for instrumentation-aws-lambda. |
| ecosystem-registry/javascript/instrumentation-amqplib/v0.65.0.yaml | Initial generated registry entry for instrumentation-amqplib. |
| ecosystem-automation/js-instrumentation-watcher/tests/test_package_parser.py | Unit tests for parsing package.json, README supported versions, and .tav.yml. |
| ecosystem-automation/js-instrumentation-watcher/tests/test_inventory_manager.py | Unit tests for registry write/read path behavior. |
| ecosystem-automation/js-instrumentation-watcher/tests/init.py | Adds a tests package marker file. |
| ecosystem-automation/js-instrumentation-watcher/src/js_instrumentation_watcher/repository_manager.py | Repo setup logic (env override vs clone/pull). |
| ecosystem-automation/js-instrumentation-watcher/src/js_instrumentation_watcher/package_scanner.py | Discovers packages and loads bundle membership / component owners. |
| ecosystem-automation/js-instrumentation-watcher/src/js_instrumentation_watcher/package_parser.py | Extracts metadata from package.json/README/.tav.yml. |
| ecosystem-automation/js-instrumentation-watcher/src/js_instrumentation_watcher/main.py | Watcher entrypoint. |
| ecosystem-automation/js-instrumentation-watcher/src/js_instrumentation_watcher/inventory_manager.py | Writes per-package versioned YAML to registry. |
| ecosystem-automation/js-instrumentation-watcher/src/js_instrumentation_watcher/instrumentation_sync.py | Orchestrates scanning/parsing/writing and produces a summary. |
| ecosystem-automation/js-instrumentation-watcher/src/js_instrumentation_watcher/main.py | Enables python -m js_instrumentation_watcher. |
| ecosystem-automation/js-instrumentation-watcher/src/js_instrumentation_watcher/init.py | Package init file. |
| ecosystem-automation/js-instrumentation-watcher/pyproject.toml | Defines the new watcher package, deps, and console script entrypoint. |
| try: | ||
| data = json.loads(auto_node_path.read_text()) | ||
| deps = data.get("dependencies", {}) | ||
| return set(deps.keys()) |
| try: | ||
| data = yaml.safe_load(owners_path.read_text()) | ||
| components = data.get("components", {}) | ||
| result = {} | ||
| for path, owners in components.items(): | ||
| result[path] = owners if isinstance(owners, list) else [] | ||
| return result |
|
|
||
| return results |
| results.append(self._build_tav_entry(pkg_name, versions)) | ||
|
|
||
| return results No newline at end of file |
| Returns: | ||
| List of dicts with package, range, mode, source, and optionally | ||
| exclude fields. Empty fields are omitted. | ||
| """ |
| logging.basicConfig( | ||
| level=logging.INFO, | ||
| format="%(asctime)s - %(name)s - %(levelname)s - %(message)s", | ||
| ) | ||
| logger = logging.getLogger(__name__) | ||
|
|
||
| REGISTRY_DIR = "ecosystem-registry/javascript" | ||
|
|
||
|
|
||
| def main() -> None: | ||
| """Main entry point for the JS instrumentation watcher.""" | ||
| base_dir = os.environ.get("JS_CONTRIB_REPOS_DIR", "tmp_repos") | ||
|
|
||
| logger.info("Starting JS instrumentation watcher...") |
| import pytest | ||
| import yaml |
|
going to mark this is as draft to help with bookkeeping. Feel free to open back up when review comments are addressed |
…tion-watcher # Conflicts: # uv.lock
|
Hey @jaydeluca , I've pushed fixes for all the review feedback.
All 23 tests passing, watcher still produces 46 correct registry entries against current js-contrib HEAD. |
|
Thank you for your contribution @MeloveGupta! 🎉 We would like to hear from you about your experience contributing to OpenTelemetry by taking a few minutes to fill out this survey. |
What
Adds a Phase 1 watcher for the
opentelemetry-js-contribecosystem that walks the repository and generates per-package versioned YAML entries in the registry.How it works
The watcher clones (or reuses) the
opentelemetry-js-contribrepo, discovers all activepackages/instrumentation-*directories, and for each package reads:package.json- name, version, description, source path, node engine.github/component_owners.yml- component owners per packageauto-instrumentations-node/package.jsondeps - bundle membership### Supported Versionssection - supported library version ranges.tav.yml- tested version ranges (handles bothversions:andjobs:structures used across the ecosystem)Registry layout
JS packages version independently so the registry is per-package, not per-release:
Output
Running the watcher against the current js-contrib HEAD produces 46 registry entries, all active instrumentation packages.
Example entry
Known gaps (Phase 2)
supported_versionsfor packages that use non-standard README formats (e.g.instrumentation-aws-sdk)Tests
8 unit tests covering package parsing, inventory management, and version path formatting. All passing.
Related to #9