diff --git a/.release-please-manifest.json b/.release-please-manifest.json index 8402c34a6b..7a2ebcd7e6 100644 --- a/.release-please-manifest.json +++ b/.release-please-manifest.json @@ -1,13 +1,13 @@ { - "detectors/node/opentelemetry-resource-detector-alibaba-cloud": "0.29.7", - "detectors/node/opentelemetry-resource-detector-aws": "1.10.0", - "detectors/node/opentelemetry-resource-detector-azure": "0.5.0", - "detectors/node/opentelemetry-resource-detector-container": "0.5.3", - "detectors/node/opentelemetry-resource-detector-gcp": "0.32.0", - "detectors/node/opentelemetry-resource-detector-github": "0.29.0", - "detectors/node/opentelemetry-resource-detector-instana": "0.17.0", + "detectors/node/opentelemetry-resource-detector-alibaba-cloud": "0.30.0", + "detectors/node/opentelemetry-resource-detector-aws": "1.11.0", + "detectors/node/opentelemetry-resource-detector-azure": "0.6.0", + "detectors/node/opentelemetry-resource-detector-container": "0.6.0", + "detectors/node/opentelemetry-resource-detector-gcp": "0.33.0", + "detectors/node/opentelemetry-resource-detector-github": "0.30.0", + "detectors/node/opentelemetry-resource-detector-instana": "0.18.0", "metapackages/auto-configuration-propagators": "0.3.2", - "metapackages/auto-instrumentations-node": "0.55.2", + "metapackages/auto-instrumentations-node": "0.55.3", "metapackages/auto-instrumentations-web": "0.45.0", "packages/baggage-span-processor": "0.3.1", "packages/opentelemetry-host-metrics": "0.35.5", @@ -28,14 +28,14 @@ "plugins/node/instrumentation-socket.io": "0.46.0", "plugins/node/instrumentation-tedious": "0.18.0", "plugins/node/instrumentation-undici": "0.10.0", - "plugins/node/opentelemetry-instrumentation-aws-lambda": "0.50.1", + "plugins/node/opentelemetry-instrumentation-aws-lambda": "0.50.2", "plugins/node/opentelemetry-instrumentation-aws-sdk": "0.49.0", "plugins/node/opentelemetry-instrumentation-bunyan": "0.45.0", "plugins/node/opentelemetry-instrumentation-cassandra": "0.45.0", "plugins/node/opentelemetry-instrumentation-connect": "0.43.0", "plugins/node/opentelemetry-instrumentation-dns": "0.43.0", "plugins/node/opentelemetry-instrumentation-express": "0.47.0", - "plugins/node/opentelemetry-instrumentation-fastify": "0.44.0", + "plugins/node/opentelemetry-instrumentation-fastify": "0.44.1", "plugins/node/opentelemetry-instrumentation-generic-pool": "0.43.0", "plugins/node/opentelemetry-instrumentation-graphql": "0.47.0", "plugins/node/opentelemetry-instrumentation-hapi": "0.45.1", diff --git a/archive/opentelemetry-browser-extension-autoinjection/.eslintrc.js b/archive/opentelemetry-browser-extension-autoinjection/.eslintrc.js deleted file mode 100644 index 0d90aec2bb..0000000000 --- a/archive/opentelemetry-browser-extension-autoinjection/.eslintrc.js +++ /dev/null @@ -1,19 +0,0 @@ -module.exports = { - "env": { - "mocha": true, - "commonjs": true, - "browser": true, - "jquery": true - }, - "ignorePatterns": [ - ".eslintrc.js", - "build/*", - "ts-build/*" - ], - plugins: [ - "@typescript-eslint", - "json5", - "header" - ], - ...require('../../eslint.config.js') -}; diff --git a/archive/opentelemetry-browser-extension-autoinjection/.gitignore b/archive/opentelemetry-browser-extension-autoinjection/.gitignore deleted file mode 100644 index 41f3dc1005..0000000000 --- a/archive/opentelemetry-browser-extension-autoinjection/.gitignore +++ /dev/null @@ -1 +0,0 @@ -ts-build diff --git a/archive/opentelemetry-browser-extension-autoinjection/CHANGELOG.md b/archive/opentelemetry-browser-extension-autoinjection/CHANGELOG.md deleted file mode 100644 index 7d9ef92e37..0000000000 --- a/archive/opentelemetry-browser-extension-autoinjection/CHANGELOG.md +++ /dev/null @@ -1,101 +0,0 @@ -# Changelog - -## [0.29.0](https://github.com/open-telemetry/opentelemetry-js-contrib/compare/browser-extension-autoinjection-v0.28.0...browser-extension-autoinjection-v0.29.0) (2022-06-08) - - -### Features - -* update core dependencies stable ^1.3.1 experimental ^0.29.2 ([141b155](https://github.com/open-telemetry/opentelemetry-js-contrib/commit/141b155e344980b51264e26b26c117b2113bcef6)) - - -### Dependencies - -* The following workspace dependencies were updated - * dependencies - * @opentelemetry/instrumentation-document-load bumped from ^0.28.0 to ^0.29.0 - -## [0.28.0](https://github.com/open-telemetry/opentelemetry-js-contrib/compare/browser-extension-autoinjection-v0.27.4...browser-extension-autoinjection-v0.28.0) (2022-05-14) - - -### Features - -* add supported node versions for all packages ([#973](https://github.com/open-telemetry/opentelemetry-js-contrib/issues/973)) ([baaacbd](https://github.com/open-telemetry/opentelemetry-js-contrib/commit/baaacbdd35ca4baab0afae64647aa8c0380ee4b7)) -* remove colors dependency ([#943](https://github.com/open-telemetry/opentelemetry-js-contrib/issues/943)) ([b21b96c](https://github.com/open-telemetry/opentelemetry-js-contrib/commit/b21b96c1a3a4f871370f970d6b2825f00e1fe595)), closes [#826](https://github.com/open-telemetry/opentelemetry-js-contrib/issues/826) -* use Otel SDK 1.2/0.28 ([#984](https://github.com/open-telemetry/opentelemetry-js-contrib/issues/984)) ([098c2ed](https://github.com/open-telemetry/opentelemetry-js-contrib/commit/098c2ed6f9c5ab7bd865685018c0777245aab3b7)) - - -### Bug Fixes - -* remove link to browser extension to external repo. ([#979](https://github.com/open-telemetry/opentelemetry-js-contrib/issues/979)) ([c5b9356](https://github.com/open-telemetry/opentelemetry-js-contrib/commit/c5b9356d4eb925df64b66c859d1d8367ae57d437)) - - -### Dependencies - -* The following workspace dependencies were updated - * dependencies - * @opentelemetry/instrumentation-document-load bumped from 0.27.1 to ^0.28.0 - -### [0.27.4](https://github.com/open-telemetry/opentelemetry-js-contrib/compare/browser-extension-autoinjection-v0.27.3...browser-extension-autoinjection-v0.27.4) (2022-03-02) - - -### Bug Fixes - -* **browser-extension-autoinjection:** update eslint-plugin-json5 version to 0.1.4 ([#896](https://github.com/open-telemetry/opentelemetry-js-contrib/issues/896)) ([e47fcaa](https://github.com/open-telemetry/opentelemetry-js-contrib/commit/e47fcaa1a04de35b096f373f44abbf87ff4125f2)) - -### [0.27.3](https://www.github.com/open-telemetry/opentelemetry-js-contrib/compare/browser-extension-autoinjection-v0.27.2...browser-extension-autoinjection-v0.27.3) (2022-02-06) - - -### Bug Fixes - -* update eslint-plugin-import to resolve conflicts ([#864](https://www.github.com/open-telemetry/opentelemetry-js-contrib/issues/864)) ([45efaee](https://www.github.com/open-telemetry/opentelemetry-js-contrib/commit/45efaeec1da51398e44857dc9fe7ab3ef9456983)) - -### [0.27.2](https://www.github.com/open-telemetry/opentelemetry-js-contrib/compare/browser-extension-autoinjection-v0.27.1...browser-extension-autoinjection-v0.27.2) (2022-01-24) - - -### Bug Fixes - -* fix CI by forcing colors@1.4.0 ([#825](https://www.github.com/open-telemetry/opentelemetry-js-contrib/issues/825)) ([0ec9f08](https://www.github.com/open-telemetry/opentelemetry-js-contrib/commit/0ec9f080520fe0f146a915a656300ef53a151ace)) -* rename lerna's --include-filtered-dependencies option ([#817](https://www.github.com/open-telemetry/opentelemetry-js-contrib/issues/817)) ([cf268e7](https://www.github.com/open-telemetry/opentelemetry-js-contrib/commit/cf268e7a92b7800ad6dbec9ca77466f9ee03ee1a)) - - -### Dependencies - -* The following workspace dependencies were updated - * dependencies - * @opentelemetry/instrumentation-document-load bumped from 0.27.0 to ^0.27.1 - -### [0.27.1](https://www.github.com/open-telemetry/opentelemetry-js-contrib/compare/browser-extension-autoinjection-v0.27.0...browser-extension-autoinjection-v0.27.1) (2021-12-22) - - -### Bug Fixes - -* fastify and browser autoinjection failed to compile ([#793](https://www.github.com/open-telemetry/opentelemetry-js-contrib/issues/793)) ([c08efa8](https://www.github.com/open-telemetry/opentelemetry-js-contrib/commit/c08efa82a38d3d5b4d0c51d712a39052317b9f74)) - -## [0.27.0](https://www.github.com/open-telemetry/opentelemetry-js-contrib/compare/browser-extension-autoinjection-v0.26.0...browser-extension-autoinjection-v0.27.0) (2021-11-30) - - -### Features - -* use latest instrumentation base ([#769](https://www.github.com/open-telemetry/opentelemetry-js-contrib/issues/769)) ([7aff23e](https://www.github.com/open-telemetry/opentelemetry-js-contrib/commit/7aff23ebebbe209fa3b78c2e7f513c9cd2231be4)) - - -### Dependencies - -* The following workspace dependencies were updated - * dependencies - * @opentelemetry/instrumentation-document-load bumped from ^0.26.0 to ^0.27.0 - -## [0.26.0](https://www.github.com/open-telemetry/opentelemetry-js-contrib/compare/browser-extension-autoinjection-v0.25.0...browser-extension-autoinjection-v0.26.0) (2021-10-22) - - -### Features - -* support API and SDK 1.0 ([#706](https://www.github.com/open-telemetry/opentelemetry-js-contrib/issues/706)) ([096b694](https://www.github.com/open-telemetry/opentelemetry-js-contrib/commit/096b694bbc3079f0ab4ee0462869b10eb8185202)) - - - -### Dependencies - -* The following workspace dependencies were updated - * dependencies - * @opentelemetry/instrumentation-document-load bumped from ^0.25.0 to ^0.26.0 diff --git a/archive/opentelemetry-browser-extension-autoinjection/LICENSE b/archive/opentelemetry-browser-extension-autoinjection/LICENSE deleted file mode 100644 index f49a4e16e6..0000000000 --- a/archive/opentelemetry-browser-extension-autoinjection/LICENSE +++ /dev/null @@ -1,201 +0,0 @@ - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright [yyyy] [name of copyright owner] - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. \ No newline at end of file diff --git a/archive/opentelemetry-browser-extension-autoinjection/README.md b/archive/opentelemetry-browser-extension-autoinjection/README.md index 9e3747a868..be37d351b9 100644 --- a/archive/opentelemetry-browser-extension-autoinjection/README.md +++ b/archive/opentelemetry-browser-extension-autoinjection/README.md @@ -1,8 +1,11 @@ # OpenTelemetry Browser Extension -## :warning: ARCHIVED PROJECT - -> This project has been archived by the maintainers permanently on June 19 2024. +> [!CAUTION] +> +> This project is unmaintained and has been archived by the maintainers +> permanently on June 19 2024. It has not been updated for some time and no +> longer works properly with the latest SDK. +> > We encourage extensions to be developed and maintained outside this repository. > Alternatives can be found in the OpenTelemetry Registry: > @@ -11,58 +14,7 @@ > If you are a developer of such an extension you can > [add it to the registry](https://opentelemetry.io/ecosystem/registry/adding/) > as well. +> +> For reference, the archived code [can be found here][archived-code]. -This browser extension allows you to inject [OpenTelemetry](https://opentelemetry.io/) instrumentation in any web page. It uses the [Web SDK](https://github.com/open-telemetry/opentelemetry-js/tree/main/packages/opentelemetry-sdk-trace-web) and can export data to Zipkin or an OpenTelemetry Collector. - -Compatible with OpenTelemetry JS API and SDK `1.0+`. - -![This animated image shows the process of activating the extension and seeing console output in the developer toolbar](./images/inject-opentelemetry.gif) - -## Supported Environments - -- Google Chrome (with [Manifest Version 3](https://developer.chrome.com/docs/extensions/mv3/intro/) support) -- Chromium (with Manifest Version 2) -- Firefox (*unstable*, with Manifest Version 2) - -## Installation - -### from Source - -Run the following in your shell to download and build the extension from source: - -```shell -git clone https://github.com/open-telemetry/opentelemetry-js-contrib.git -cd opentelemetry-js-contrib/packages/opentelemetry-browser-extension-autoinjection -npm install -npm run build -``` - -This will create a so-called unpacked extension into the `build/` folder you now can load into your browser: - -- Open a new browser window and go to chrome://extensions -- Turn on "Developer Mode" -- Click on "Load unpacked" and select the `build/mv3` (or `build/mv2`) folder, which contains the extension - -If all goes well you should see the extension listed: - -![This image shows the extension being installed in chrome://extensions](./images/extensionCard.png) - -## Usage - -When visiting a website, click on the extension icon, add an url filter that partially matches the current domain, e.g for [https://opentelemetry.io/](https://opentelemetry.io/) you can set "opentel" as value: - -![This image shows an open extension popup with url filter set to "opentel"](./images/popup.png) - -Click on `Save & Reload`, check the developer toolbar to see how spans being are printed to the console and being sent to your collector: - -![This image shows spans being printed into the console of the developer toolbar for opentelemetry.io](./images/console.png) - -## Known Limitations - -1. The extension works with [active tab](https://developer.chrome.com/docs/extensions/mv3/manifest/activeTab/) permission, this means that every time you want to use it, you have to click the extension icon at least once for your tab. - -2. The use of the zone context manager and the used instrumentation libraries are fixed. - -3. Firefox support is unstable, sometimes it works, sometimes not. If you have experience building extensions for firefox, please reach out. - -4. The website you are targeting with this extension might have a [Content Security Policy](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy) (CSP) in place and block the extension from injecting javascript or block the exporters from sending spans to a collector. To work around this limitation, you need another browser extension, that allows you to disable CSP for a website. +[archived-code]: https://github.com/open-telemetry/opentelemetry-js-contrib/tree/688a92d14aa1bdb67de273205d76c2c6e21f6276/archive/opentelemetry-browser-extension-autoinjection diff --git a/archive/opentelemetry-browser-extension-autoinjection/images/console.png b/archive/opentelemetry-browser-extension-autoinjection/images/console.png deleted file mode 100644 index e19c8cbf4e..0000000000 Binary files a/archive/opentelemetry-browser-extension-autoinjection/images/console.png and /dev/null differ diff --git a/archive/opentelemetry-browser-extension-autoinjection/images/extensionCard.png b/archive/opentelemetry-browser-extension-autoinjection/images/extensionCard.png deleted file mode 100644 index c732afd8e2..0000000000 Binary files a/archive/opentelemetry-browser-extension-autoinjection/images/extensionCard.png and /dev/null differ diff --git a/archive/opentelemetry-browser-extension-autoinjection/images/inject-opentelemetry.gif b/archive/opentelemetry-browser-extension-autoinjection/images/inject-opentelemetry.gif deleted file mode 100644 index 7ecc11152b..0000000000 Binary files a/archive/opentelemetry-browser-extension-autoinjection/images/inject-opentelemetry.gif and /dev/null differ diff --git a/archive/opentelemetry-browser-extension-autoinjection/images/options.png b/archive/opentelemetry-browser-extension-autoinjection/images/options.png deleted file mode 100644 index e9e364c4d4..0000000000 Binary files a/archive/opentelemetry-browser-extension-autoinjection/images/options.png and /dev/null differ diff --git a/archive/opentelemetry-browser-extension-autoinjection/images/popup.png b/archive/opentelemetry-browser-extension-autoinjection/images/popup.png deleted file mode 100644 index 52b7323fcf..0000000000 Binary files a/archive/opentelemetry-browser-extension-autoinjection/images/popup.png and /dev/null differ diff --git a/archive/opentelemetry-browser-extension-autoinjection/package.json b/archive/opentelemetry-browser-extension-autoinjection/package.json deleted file mode 100644 index f0b7187c34..0000000000 --- a/archive/opentelemetry-browser-extension-autoinjection/package.json +++ /dev/null @@ -1,84 +0,0 @@ -{ - "name": "@opentelemetry/browser-extension-autoinjection", - "version": "0.29.0", - "description": "A browser extension that injects opentelemetry tracers into any website", - "scripts": { - "clean": "rimraf build/*", - "compile": "tsc --build tsconfig.json", - "build": "npx webpack --mode=production", - "build:mv2": "npx webpack --mode=production --env MV=2", - "build:mv3": "npx webpack --mode=production --env MV=3", - "lint": "eslint .", - "lint:fix": "eslint . --fix", - "precompile": "tsc --version && lerna run version:update --scope @opentelemetry/browser-extension-autoinjection --include-dependencies", - "prewatch": "npm run precompile", - "test": "nyc mocha 'test/**/*.test.ts'", - "tdd": "npm run test -- --watch-extensions ts --watch", - "watch": "npx webpack --mode=development --watch", - "watch:mv2": "npx webpack --mode=development --watch --env MV=2", - "watch:mv3": "npx webpack --mode=development --watch --env MV=3" - }, - "private": true, - "keywords": [], - "author": "OpenTelemetry Authors", - "license": "Apache-2.0", - "engines": { - "node": ">=14" - }, - "peerDependencies": { - "@opentelemetry/api": "^1.3.0" - }, - "devDependencies": { - "@opentelemetry/api": "^1.3.0", - "@types/chrome": "0.0.154", - "@types/jsdom": "16.2.13", - "@types/mocha": "8.2.3", - "@types/react": "17.0.16", - "@types/react-dom": "18.0.2", - "@types/sinon": "10.0.2", - "@types/sinon-chrome": "2.2.11", - "@typescript-eslint/eslint-plugin": "5.8.1", - "@typescript-eslint/parser": "5.8.1", - "eslint": "8.7.0", - "eslint-config-airbnb-base": "15.0.0", - "eslint-plugin-header": "3.1.1", - "eslint-plugin-import": "2.25.4", - "eslint-plugin-json5": "0.1.4", - "html-webpack-plugin": "5.3.2", - "jimp": "0.16.1", - "jsdom": "15.2.1", - "null-loader": "4.0.1", - "nyc": "15.1.0", - "responsive-loader": "2.3.0", - "rimraf": "4.2.0", - "sinon": "15.0.1", - "sinon-chrome": "3.0.1", - "ts-loader": "9.2.5", - "typescript": "4.4.4", - "webpack": "4.46.0", - "webpack-cli": "4.7.2", - "webpack-merge": "5.8.0" - }, - "dependencies": { - "@material-ui/core": "4.12.3", - "@material-ui/icons": "4.11.2", - "@material-ui/lab": "4.0.0-alpha.60", - "@opentelemetry/context-zone": "^1.0.0", - "@opentelemetry/core": "^1.8.0", - "@opentelemetry/exporter-trace-otlp-http": "^0.34.0", - "@opentelemetry/exporter-zipkin": "^1.0.0", - "@opentelemetry/instrumentation": "^0.35.1", - "@opentelemetry/instrumentation-document-load": "^0.29.0", - "@opentelemetry/instrumentation-fetch": "^0.35.1", - "@opentelemetry/instrumentation-xml-http-request": "^0.35.1", - "@opentelemetry/resources": "^1.8.0", - "@opentelemetry/sdk-trace-base": "^1.8.0", - "@opentelemetry/sdk-trace-web": "^1.8.0", - "@opentelemetry/semantic-conventions": "^1.27.0", - "change-case": "4.1.2", - "json5": "2.2.0", - "react": "17.0.2", - "react-dom": "17.0.2" - }, - "homepage": "https://github.com/open-telemetry/opentelemetry-js-contrib/tree/main/packages/opentelemetry-browser-extension-autoinjection#readme" -} diff --git a/archive/opentelemetry-browser-extension-autoinjection/src/background/ProgrammaticContentScriptInjector.ts b/archive/opentelemetry-browser-extension-autoinjection/src/background/ProgrammaticContentScriptInjector.ts deleted file mode 100644 index b85790bedf..0000000000 --- a/archive/opentelemetry-browser-extension-autoinjection/src/background/ProgrammaticContentScriptInjector.ts +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import { TabStatus, CONTENT_SCRIPT_NAME } from '../types'; - -export class ProgrammaticContentScriptInjector { - scope: typeof chrome; - - constructor(scope: typeof chrome) { - this.scope = scope; - } - - injectContentScript(tabId: number) { - this.scope.tabs.get(tabId, (tab: chrome.tabs.Tab) => { - if (tab.url) { - if (this.scope.scripting) { - this.scope.scripting.executeScript({ - target: { - allFrames: true, - tabId, - }, - files: [CONTENT_SCRIPT_NAME], - }); - } else { - this.scope.tabs.executeScript(tabId, { - file: CONTENT_SCRIPT_NAME, - allFrames: true, - }); - } - } - }); - } - - register() { - this.scope.tabs.onUpdated.addListener( - (tabId: number, changeInfo: chrome.tabs.TabChangeInfo) => { - if (changeInfo.status === TabStatus.LOADING) { - this.injectContentScript(tabId); - } - } - ); - } -} diff --git a/archive/opentelemetry-browser-extension-autoinjection/src/background/index.ts b/archive/opentelemetry-browser-extension-autoinjection/src/background/index.ts deleted file mode 100644 index 903e14e134..0000000000 --- a/archive/opentelemetry-browser-extension-autoinjection/src/background/index.ts +++ /dev/null @@ -1,28 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -// the following two 'require' are here for webpack. -require('../manifest.json5'); -require('../icons/otel-logo.png'); - -import { ProgrammaticContentScriptInjector } from './ProgrammaticContentScriptInjector'; - -// An error thrown in the background service worker will not be reported in the logs, it's caught here and printed. (MV3 only) -try { - new ProgrammaticContentScriptInjector(chrome).register(); -} catch (e) { - console.error(e); -} diff --git a/archive/opentelemetry-browser-extension-autoinjection/src/contentScript/InstrumentationInjector.ts b/archive/opentelemetry-browser-extension-autoinjection/src/contentScript/InstrumentationInjector.ts deleted file mode 100644 index 5c4369f21a..0000000000 --- a/archive/opentelemetry-browser-extension-autoinjection/src/contentScript/InstrumentationInjector.ts +++ /dev/null @@ -1,74 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import { - DomAttributes, - DomElements, - INSTRUMENTATION_SCRIPT_NAME, - Settings, -} from '../types'; - -export class InstrumentationInjector { - scope: typeof chrome; - doc: Document; - logger: Console; - - constructor(scope: typeof chrome, doc: Document, logger: Console) { - this.scope = scope; - this.doc = doc; - this.logger = logger; - } - - inject(settings: Settings) { - const script = this.scope.runtime.getURL(INSTRUMENTATION_SCRIPT_NAME); - this.logger.log( - `[otel-extension] injecting ${INSTRUMENTATION_SCRIPT_NAME}` - ); - const tag = this.doc.createElement('script'); - tag.setAttribute('src', script); - tag.setAttribute('id', DomElements.CONFIG_TAG); - // Config is based via this data attribute, since CSP might not allow inline script tags, so this is more robust. - tag.setAttribute(`data-${DomAttributes.CONFIG}`, JSON.stringify(settings)); - this.doc.head.appendChild(tag); - this.logger.log(`[otel-extension] ${INSTRUMENTATION_SCRIPT_NAME} injected`); - } - - static checkUrlFilter(urlFilter: string, href: string) { - return urlFilter !== '' && (urlFilter === '*' || href.includes(urlFilter)); - } - - execute() { - this.scope.storage.local.get('settings', ({ settings }) => { - // Define label of badge. - const urlFilter = settings.urlFilter; - if ( - InstrumentationInjector.checkUrlFilter( - urlFilter, - this.doc.location.href - ) - ) { - this.logger.log( - `[otel-extension] ${this.doc.location.href} includes ${urlFilter}` - ); - this.inject(settings); - } else { - this.logger.log( - `[otel-extension] ${this.doc.location.href} does not include ${urlFilter}` - ); - } - }); - } -} diff --git a/archive/opentelemetry-browser-extension-autoinjection/src/contentScript/index.ts b/archive/opentelemetry-browser-extension-autoinjection/src/contentScript/index.ts deleted file mode 100644 index 90da8a7760..0000000000 --- a/archive/opentelemetry-browser-extension-autoinjection/src/contentScript/index.ts +++ /dev/null @@ -1,19 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import { InstrumentationInjector } from './InstrumentationInjector'; - -new InstrumentationInjector(chrome, document, console).execute(); diff --git a/archive/opentelemetry-browser-extension-autoinjection/src/icons/otel-logo.png b/archive/opentelemetry-browser-extension-autoinjection/src/icons/otel-logo.png deleted file mode 100644 index 1e9deec244..0000000000 Binary files a/archive/opentelemetry-browser-extension-autoinjection/src/icons/otel-logo.png and /dev/null differ diff --git a/archive/opentelemetry-browser-extension-autoinjection/src/instrumentation/WebInstrumentation.ts b/archive/opentelemetry-browser-extension-autoinjection/src/instrumentation/WebInstrumentation.ts deleted file mode 100644 index d467460e7d..0000000000 --- a/archive/opentelemetry-browser-extension-autoinjection/src/instrumentation/WebInstrumentation.ts +++ /dev/null @@ -1,115 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -import { registerInstrumentations } from '@opentelemetry/instrumentation'; -import { DocumentLoadInstrumentation } from '@opentelemetry/instrumentation-document-load'; -import { FetchInstrumentation } from '@opentelemetry/instrumentation-fetch'; -import { XMLHttpRequestInstrumentation } from '@opentelemetry/instrumentation-xml-http-request'; -import { WebTracerProvider } from '@opentelemetry/sdk-trace-web'; -import { ZoneContextManager } from '@opentelemetry/context-zone'; -import { ZipkinExporter } from '@opentelemetry/exporter-zipkin'; -import { OTLPTraceExporter } from '@opentelemetry/exporter-trace-otlp-http'; -import { - BatchSpanProcessor, - ConsoleSpanExporter, - SimpleSpanProcessor, -} from '@opentelemetry/sdk-trace-base'; -import { - Exporters, - ExporterType, - InstrumentationConfiguration, - InstrumentationType, -} from '../types'; - -export class WebInstrumentation { - withZoneContextManager: boolean; - provider: WebTracerProvider; - exporters: Exporters; - instrumentations: { - [InstrumentationType.DOCUMENT_LOAD]: { enabled: boolean }; - [InstrumentationType.FETCH]: { enabled: boolean }; - [InstrumentationType.XML_HTTP_REQUEST]: { enabled: boolean }; - }; - constructor( - config: InstrumentationConfiguration, - provider: WebTracerProvider - ) { - this.exporters = config.exporters; - this.instrumentations = config.instrumentations; - this.provider = provider; - this.withZoneContextManager = config.withZoneContextManager; - } - - addExporters() { - if (this.exporters[ExporterType.CONSOLE].enabled) { - this.provider.addSpanProcessor( - new SimpleSpanProcessor(new ConsoleSpanExporter()) - ); - } - - if (this.exporters[ExporterType.ZIPKIN].enabled) { - this.provider.addSpanProcessor( - new BatchSpanProcessor( - new ZipkinExporter({ - url: this.exporters[ExporterType.ZIPKIN].url, - }) - ) - ); - } - - if (this.exporters[ExporterType.COLLECTOR_TRACE].enabled) { - this.provider.addSpanProcessor( - new BatchSpanProcessor( - new OTLPTraceExporter({ - url: this.exporters[ExporterType.COLLECTOR_TRACE].url, - }) - ) - ); - } - } - - registerInstrumentations() { - const instrumentations = []; - - if (this.instrumentations[InstrumentationType.DOCUMENT_LOAD].enabled) { - instrumentations.push(new DocumentLoadInstrumentation()); - } - - if (this.instrumentations[InstrumentationType.FETCH].enabled) { - instrumentations.push(new FetchInstrumentation()); - } - - if (this.instrumentations[InstrumentationType.XML_HTTP_REQUEST].enabled) { - instrumentations.push(new XMLHttpRequestInstrumentation()); - } - - registerInstrumentations({ - instrumentations, - tracerProvider: this.provider, - }); - } - - register() { - this.addExporters(); - - if (this.withZoneContextManager) { - this.provider.register({ - contextManager: new ZoneContextManager(), - }); - } - - this.registerInstrumentations(); - } -} diff --git a/archive/opentelemetry-browser-extension-autoinjection/src/instrumentation/index.ts b/archive/opentelemetry-browser-extension-autoinjection/src/instrumentation/index.ts deleted file mode 100644 index 2ae22adf05..0000000000 --- a/archive/opentelemetry-browser-extension-autoinjection/src/instrumentation/index.ts +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import { WebTracerProvider } from '@opentelemetry/sdk-trace-web'; -import { - DomAttributes, - DomElements, - InstrumentationType, - Settings, -} from '../types'; -import { WebInstrumentation } from './WebInstrumentation'; -import { Resource } from '@opentelemetry/resources'; -import { SemanticResourceAttributes } from '@opentelemetry/semantic-conventions'; - -const configTag = document.getElementById(DomElements['CONFIG_TAG']); -const { exporters }: Settings = configTag - ? JSON.parse(String(configTag.dataset[DomAttributes['CONFIG']])) - : {}; - -new WebInstrumentation( - { - exporters, - instrumentations: { - [InstrumentationType.DOCUMENT_LOAD]: { - enabled: true, - }, - [InstrumentationType.FETCH]: { - enabled: true, - }, - [InstrumentationType.XML_HTTP_REQUEST]: { - enabled: true, - }, - }, - withZoneContextManager: true, - }, - new WebTracerProvider({ - resource: new Resource({ - [SemanticResourceAttributes.SERVICE_NAME]: window.location.hostname, - }), - }) -).register(); diff --git a/archive/opentelemetry-browser-extension-autoinjection/src/manifest.json5 b/archive/opentelemetry-browser-extension-autoinjection/src/manifest.json5 deleted file mode 100644 index 48b89d5249..0000000000 --- a/archive/opentelemetry-browser-extension-autoinjection/src/manifest.json5 +++ /dev/null @@ -1,23 +0,0 @@ -{ - "permissions": [ - "activeTab", - "scripting", - "webNavigation", - "storage" - ], - "action": { - "default_popup": "popup.html" - }, - "icons": "icons/otel-logo_{size}.png", - "background": "background.js", - "options_ui": { - "page": "options.html", - "open_in_tab": true, - }, - "web_accessible_resources": [ - "instrumentation.js" - ], - "host_permissions": [ - '' - ] -} \ No newline at end of file diff --git a/archive/opentelemetry-browser-extension-autoinjection/src/template.html b/archive/opentelemetry-browser-extension-autoinjection/src/template.html deleted file mode 100644 index 37e14402dd..0000000000 --- a/archive/opentelemetry-browser-extension-autoinjection/src/template.html +++ /dev/null @@ -1,12 +0,0 @@ - - - - - OpenTelemetry Browser Extension - - -
-
- - - diff --git a/archive/opentelemetry-browser-extension-autoinjection/src/types.ts b/archive/opentelemetry-browser-extension-autoinjection/src/types.ts deleted file mode 100644 index dcd8f1cb01..0000000000 --- a/archive/opentelemetry-browser-extension-autoinjection/src/types.ts +++ /dev/null @@ -1,154 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import { styles } from './ui/styles'; -import { WithStyles } from '@material-ui/core'; - -export interface Exporters { - [ExporterType.CONSOLE]: { - enabled: boolean; - }; - [ExporterType.ZIPKIN]: { - enabled: boolean; - url: string; - }; - [ExporterType.COLLECTOR_TRACE]: { - enabled: boolean; - url: string; - }; -} - -export interface InstrumentationConfiguration { - exporters: Exporters; - instrumentations: { - [InstrumentationType.DOCUMENT_LOAD]: { - enabled: boolean; - }; - [InstrumentationType.FETCH]: { - enabled: boolean; - }; - [InstrumentationType.XML_HTTP_REQUEST]: { - enabled: boolean; - }; - }; - withZoneContextManager: boolean; -} - -export interface Settings { - urlFilter: string; - exporters: Exporters; -} - -export class Storage { - settings: Settings; - isPermissionAlertDismissed: boolean; - - // eslint-disable-next-line @typescript-eslint/no-explicit-any - constructor(storage: { [key: string]: any }) { - this.settings = storage.settings; - this.isPermissionAlertDismissed = storage.isPermissionAlertDismissed; - } -} - -export interface PermissionManagerProps { - permissions: chrome.permissions.Permissions; - onTogglePermissions: (currentValue: boolean) => void; - removingPermissionsFailed: boolean; -} - -export interface PermissionAlertProps { - permissions: chrome.permissions.Permissions; - dismissed: boolean; - onDismiss: () => void; - onGrantPermission: () => void; -} - -export interface ExporterOptionProps { - for: ExporterType; - isEnabled: boolean; - onToggle: (exporter: ExporterType) => void; - onValueChange?: ( - name: ExporterType.ZIPKIN | ExporterType.COLLECTOR_TRACE, - newValue: string - ) => void; - exporterPackageUrl: string; - placeholderValue?: PlaceholderValues; - value?: string; -} - -export interface SaveButtonProps { - label: Labels; - onClick: () => void; -} - -export interface AppProps extends WithStyles { - permissions: chrome.permissions.Permissions; - settings: Settings; - isPermissionAlertDismissed: boolean; - app: AppType; - activeTab: chrome.tabs.Tab | undefined; -} - -export interface AppState { - settings: Settings; - permissions: chrome.permissions.Permissions; - isPermissionAlertDismissed: boolean; - removingPermissionsFailed: boolean; -} - -export enum AppType { - OPTIONS = 'options', - POPUP = 'popup', -} - -export enum ExporterType { - CONSOLE = 'Console', - ZIPKIN = 'Zipkin', - COLLECTOR_TRACE = 'CollectorTrace', -} - -export enum InstrumentationType { - DOCUMENT_LOAD = 'DocumentLoad', - FETCH = 'Fetch', - XML_HTTP_REQUEST = 'XMLHttpRequest', -} - -export enum DomElements { - CONFIG_TAG = 'open-telemetry-instrumentation', -} - -export enum DomAttributes { - CONFIG = 'config', -} - -export enum PlaceholderValues { - ZIPKIN_URL = 'http://localhost:9411/api/v2/spans', - COLLECTOR_TRACE_URL = 'http://localhost:4318/v1/trace', -} - -export enum Labels { - SAVE = 'Save', - SAVE_AND_RELOAD = 'Save & Reload', -} - -export enum TabStatus { - UNLOADED = 'unloaded', - LOADING = 'loading', - COMPLETE = 'complete', -} - -export const CONTENT_SCRIPT_NAME = 'contentScript.js'; -export const INSTRUMENTATION_SCRIPT_NAME = 'instrumentation.js'; diff --git a/archive/opentelemetry-browser-extension-autoinjection/src/ui/App.tsx b/archive/opentelemetry-browser-extension-autoinjection/src/ui/App.tsx deleted file mode 100644 index 7d214fe73f..0000000000 --- a/archive/opentelemetry-browser-extension-autoinjection/src/ui/App.tsx +++ /dev/null @@ -1,286 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -import * as React from 'react'; -import { - AppType, - ExporterType, - Labels, - AppProps as AppProps, - AppState as AppState, - PlaceholderValues, -} from '../types'; -import { - AppBar, - CssBaseline, - Paper, - Toolbar, - Typography, - Grid, - TextField, -} from '@material-ui/core'; -import { ExporterOption } from './ExporterOption'; -import { capitalCase } from 'change-case'; -import { SaveButton } from './SaveButton'; -import { OpenOptionsPage } from './OpenOptionsPage'; -import { PermissionManager } from './PermissionManager'; -import { PermissionAlert } from './PermissionAlert'; -const packageJson = require('../../package.json'); - -export class App extends React.Component { - permissionsUpdated: () => void; - constructor(props: AppProps) { - super(props); - - this.state = { - settings: props.settings, - permissions: props.permissions, - isPermissionAlertDismissed: props.isPermissionAlertDismissed, - removingPermissionsFailed: false, - }; - - this.handleFilterChange = this.handleFilterChange.bind(this); - this.handleSaveSettings = this.handleSaveSettings.bind(this); - this.handleUrlChange = this.handleUrlChange.bind(this); - this.toggleExporter = this.toggleExporter.bind(this); - this.onTogglePermissions = this.onTogglePermissions.bind(this); - this.dismissPermissionAlert = this.dismissPermissionAlert.bind(this); - - this.permissionsUpdated = () => { - chrome.permissions.getAll(permissions => { - this.setState({ permissions }); - }); - }; - } - - override componentDidMount() { - if (chrome.permissions.onAdded) { - chrome.permissions.onAdded.addListener(this.permissionsUpdated); - chrome.permissions.onRemoved.addListener(this.permissionsUpdated); - } - } - - handleFilterChange(event: React.ChangeEvent) { - this.setState(state => { - state.settings.urlFilter = event.target.value; - return state; - }); - } - - handleUrlChange( - name: ExporterType.ZIPKIN | ExporterType.COLLECTOR_TRACE, - value: string - ) { - this.setState(state => { - state.settings.exporters[name].url = value; - return state; - }); - } - - toggleExporter(name: ExporterType) { - this.setState(state => { - state.settings.exporters[name].enabled = - !state.settings.exporters[name].enabled; - return state; - }); - } - - async handleSaveSettings() { - chrome.storage.local.set( - { - settings: this.state.settings, - }, - async () => { - if (this.props.activeTab) { - const tabId = Number(this.props.activeTab.id); - if (chrome.scripting) { - chrome.scripting.executeScript({ - target: { - tabId, - }, - func: () => { - window.location.reload(); - }, - }); - } else { - chrome.tabs.executeScript(tabId, { - code: 'window.location.reload();', - }); - } - } - } - ); - } - - onTogglePermissions(currentValue: boolean) { - if (currentValue) { - chrome.permissions.remove( - { - origins: ['http://*/*', 'https://*/*'], - }, - () => { - if (chrome.runtime.lastError) { - this.setState({ - removingPermissionsFailed: true, - }); - } - } - ); - } else { - chrome.permissions.request({ - origins: ['http://*/*', 'https://*/*'], - }); - } - } - - dismissPermissionAlert() { - this.setState( - { - isPermissionAlertDismissed: true, - }, - () => { - chrome.storage.local.set({ - isPermissionAlertDismissed: this.state.isPermissionAlertDismissed, - }); - } - ); - } - - override render() { - const { urlFilter, exporters } = this.state.settings; - - const classes = this.props.classes; - - const saveLabel = - this.props.app === AppType.POPUP ? Labels.SAVE_AND_RELOAD : Labels.SAVE; - - return ( - - - - - {this.props.app === AppType.OPTIONS ? ( - - {capitalCase(packageJson.name)} ({packageJson.version}) - - ) : ( - - - - - - )} - - -
- this.onTogglePermissions(false)} - /> - - - Injection Settings - - - - - - - - - - Exporter Settings - - - - - - - - - - Manage Permissions - - - - - - - - - - -
-
- ); - } -} diff --git a/archive/opentelemetry-browser-extension-autoinjection/src/ui/ExporterOption.tsx b/archive/opentelemetry-browser-extension-autoinjection/src/ui/ExporterOption.tsx deleted file mode 100644 index 9b8543c9fb..0000000000 --- a/archive/opentelemetry-browser-extension-autoinjection/src/ui/ExporterOption.tsx +++ /dev/null @@ -1,83 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -import { - FormControlLabel, - FormGroup, - FormHelperText, - Grid, - Link, - Switch, - TextField, -} from '@material-ui/core'; -import * as React from 'react'; -import { ExporterOptionProps, ExporterType } from '../types'; - -export class ExporterOption extends React.Component { - override render() { - return ( - - - - this.props.onToggle(this.props.for)} - > - } - label={this.props.for} - /> - - Toggle to enable{' '} - - {this.props.for}Exporter - - - - - {this.props.value !== undefined ? ( - - - this.props.onValueChange - ? this.props.onValueChange( - this.props.for as - | ExporterType.ZIPKIN - | ExporterType.COLLECTOR_TRACE, - event.target.value - ) - : () => {} - } - /> - - ) : ( - '' - )} - - ); - } -} diff --git a/archive/opentelemetry-browser-extension-autoinjection/src/ui/OpenOptionsPage.tsx b/archive/opentelemetry-browser-extension-autoinjection/src/ui/OpenOptionsPage.tsx deleted file mode 100644 index 8ba31e7a0e..0000000000 --- a/archive/opentelemetry-browser-extension-autoinjection/src/ui/OpenOptionsPage.tsx +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import { Link } from '@material-ui/core'; -import { Launch } from '@material-ui/icons'; -import * as React from 'react'; - -export class OpenOptionsPage extends React.Component { - constructor(props: {}) { - super(props); - this.openOptionsPage = this.openOptionsPage.bind(this); - } - - openOptionsPage(event: React.MouseEvent) { - event.preventDefault(); - if (chrome.runtime.openOptionsPage) { - chrome.runtime.openOptionsPage(); - } else { - window.open(chrome.runtime.getURL('options.html')); - } - } - - override render() { - return ( - - - - ); - } -} diff --git a/archive/opentelemetry-browser-extension-autoinjection/src/ui/PermissionAlert.tsx b/archive/opentelemetry-browser-extension-autoinjection/src/ui/PermissionAlert.tsx deleted file mode 100644 index 5a9d46b1c4..0000000000 --- a/archive/opentelemetry-browser-extension-autoinjection/src/ui/PermissionAlert.tsx +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import * as React from 'react'; -import { PermissionAlertProps } from '../types'; -import { Alert } from '@material-ui/lab'; -import { Link } from '@material-ui/core'; - -export class PermissionAlert extends React.Component { - override render() { - const origins = this.props.permissions.origins ?? []; - - const accessToAllUrlsGranted = - origins.includes('') || - (origins.includes('http://*/*') && origins.includes('https://*/*')); - - if (this.props.dismissed || accessToAllUrlsGranted) { - return ''; - } - return ( - - Without the permission to access all websites, you need to click on the - extension icon once every time you open a new tab.{' '} - Click here to grant - access or dismiss this - warning. - - ); - } -} diff --git a/archive/opentelemetry-browser-extension-autoinjection/src/ui/PermissionManager.tsx b/archive/opentelemetry-browser-extension-autoinjection/src/ui/PermissionManager.tsx deleted file mode 100644 index 295c98f7fd..0000000000 --- a/archive/opentelemetry-browser-extension-autoinjection/src/ui/PermissionManager.tsx +++ /dev/null @@ -1,78 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import { - Grid, - FormGroup, - FormControlLabel, - Switch, - FormHelperText, - Link, -} from '@material-ui/core'; -import * as React from 'react'; -import { PermissionManagerProps } from '../types'; -import { Alert } from '@material-ui/lab'; - -export class PermissionManager extends React.Component { - override render() { - const origins = this.props.permissions.origins ?? []; - - const accessToAllUrlsGranted = - origins.includes('') || - (origins.includes('http://*/*') && origins.includes('https://*/*')); - - return ( - - - {this.props.removingPermissionsFailed ? ( - - Permissions can not be revoked. Go to chrome://extensions, open - the details of this extension and revoke them manually. - - ) : ( - '' - )} - - - this.props.onTogglePermissions(accessToAllUrlsGranted) - } - > - } - label="Access all websites" - /> - - Toggle to have injection work immediately on opening a new tab. - Otherwise, you need to click the extension icon once to active it.{' '} - ( - - Learn More - - ) - - - - - ); - } -} diff --git a/archive/opentelemetry-browser-extension-autoinjection/src/ui/index.tsx b/archive/opentelemetry-browser-extension-autoinjection/src/ui/index.tsx deleted file mode 100644 index 2d6ed46554..0000000000 --- a/archive/opentelemetry-browser-extension-autoinjection/src/ui/index.tsx +++ /dev/null @@ -1,69 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -import * as React from 'react'; -import * as ReactDOM from 'react-dom'; -import { AppType } from '../types'; -import { styles } from './styles'; -import { withStyles } from '@material-ui/core'; -import { loadFromStorage } from '../utils/storage'; -import { App } from './App'; - -loadFromStorage() - .then(async storage => { - const app = window.location.pathname.startsWith('/options.html') - ? AppType.OPTIONS - : AppType.POPUP; - - let activeTab: chrome.tabs.Tab | undefined; - - if (app === AppType.POPUP) { - const tabs = await new Promise(resolve => { - chrome.tabs.query( - { - active: true, - lastFocusedWindow: true, - }, - result => { - resolve(result); - } - ); - }); - activeTab = tabs[0]; - } - - const permissions = await new Promise( - resolve => { - chrome.permissions.getAll(permissions => resolve(permissions)); - } - ); - - const StyledApp = withStyles(styles)(App); - - ReactDOM.render( - , - document.getElementById('root') - ); - }) - .catch(error => { - // eslint-disable-next-line no-console - console.error(error); - }); diff --git a/archive/opentelemetry-browser-extension-autoinjection/src/ui/styles.ts b/archive/opentelemetry-browser-extension-autoinjection/src/ui/styles.ts deleted file mode 100644 index 9851a9a9e3..0000000000 --- a/archive/opentelemetry-browser-extension-autoinjection/src/ui/styles.ts +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -import { Theme, createStyles } from '@material-ui/core'; - -export const styles = (theme: Theme) => - createStyles({ - appBar: { - position: 'relative', - }, - layout: { - width: 'auto', - marginLeft: theme.spacing(2), - marginRight: theme.spacing(2), - }, - paper: { - marginTop: theme.spacing(3), - marginBottom: theme.spacing(3), - padding: theme.spacing(2), - }, - title: { - flexGrow: 1, - }, - }); diff --git a/archive/opentelemetry-browser-extension-autoinjection/src/utils/manifest-loader.ts b/archive/opentelemetry-browser-extension-autoinjection/src/utils/manifest-loader.ts deleted file mode 100644 index eee7bfb055..0000000000 --- a/archive/opentelemetry-browser-extension-autoinjection/src/utils/manifest-loader.ts +++ /dev/null @@ -1,93 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/* eslint-disable node/no-extraneous-import */ - -import { capitalCase } from 'change-case'; -import * as json5 from 'json5'; - -// From https://github.com/TypeStrong/ts-loader/blob/main/src/interfaces.ts -interface WebpackLoaderContext { - emitFile(name: string, content: string): void; - getOptions(): { - manifestVersion: number; - }; -} - -interface IconSet { - [key: string]: string; -} - -export default function (this: WebpackLoaderContext, source: string): string { - const p = require('../../package.json'); - const options = this.getOptions(); - - const manifest5 = json5.parse(source); - - const sizes = ['16', '32', '48', '128']; - manifest5.icons = sizes.reduce((result: IconSet, size: string) => { - result[size] = manifest5.icons.replace('{size}', size); - return result; - }, {}); - - manifest5.action['default_icon'] = manifest5.icons; - - const background = - Number(options.manifestVersion) === 3 - ? { - service_worker: manifest5.background, - } - : { - scripts: [manifest5.background], - }; - - const web_accessible_resources = - Number(options.manifestVersion) === 3 - ? [ - { - resources: manifest5.web_accessible_resources, - matches: [''], - }, - ] - : manifest5.web_accessible_resources; - - if (Number(options.manifestVersion) === 2) { - manifest5.permissions = manifest5.permissions.filter( - (permission: string) => permission !== 'scripting' - ); - manifest5.browser_action = Object.assign({}, manifest5.action); - delete manifest5.action; - - manifest5.optional_permissions = Object.values(manifest5.host_permissions); - delete manifest5.host_permissions; - } - - const result = JSON.stringify( - Object.assign(manifest5, { - manifest_version: options.manifestVersion, - version: p.version, - background, - web_accessible_resources, - description: p.description, - name: capitalCase(p.name), - }), - null, - 2 - ); - - this.emitFile('manifest.json', result); - return source; -} diff --git a/archive/opentelemetry-browser-extension-autoinjection/src/utils/storage.ts b/archive/opentelemetry-browser-extension-autoinjection/src/utils/storage.ts deleted file mode 100644 index 20be513eb5..0000000000 --- a/archive/opentelemetry-browser-extension-autoinjection/src/utils/storage.ts +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import { ExporterType, Storage } from '../types'; - -export function loadFromStorage(): Promise { - return new Promise(resolve => { - chrome.storage.local.get( - { - isPermissionAlertDismissed: false, - settings: { - urlFilter: '', - exporters: { - [ExporterType.CONSOLE]: { - enabled: true, - }, - [ExporterType.ZIPKIN]: { - enabled: false, - url: '', - }, - [ExporterType.COLLECTOR_TRACE]: { - enabled: false, - url: '', - }, - }, - }, - }, - storage => resolve(new Storage(storage)) - ); - }); -} diff --git a/archive/opentelemetry-browser-extension-autoinjection/test/background.test.ts b/archive/opentelemetry-browser-extension-autoinjection/test/background.test.ts deleted file mode 100644 index 4e5c711ea0..0000000000 --- a/archive/opentelemetry-browser-extension-autoinjection/test/background.test.ts +++ /dev/null @@ -1,116 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/* eslint-disable node/no-unpublished-import */ - -import { ProgrammaticContentScriptInjector } from '../src/background/ProgrammaticContentScriptInjector'; -import * as chromeMock from 'sinon-chrome'; -import * as assert from 'assert'; -import sinon = require('sinon'); - -import { TAB_ID } from './utils'; -import { CONTENT_SCRIPT_NAME, TabStatus } from '../src/types'; - -describe('ProgrammaticContentScriptInjector', () => { - let listener: ProgrammaticContentScriptInjector; - let sandbox: sinon.SinonSandbox; - - before(() => { - sandbox = sinon.createSandbox(); - listener = new ProgrammaticContentScriptInjector( - chromeMock as unknown as typeof chrome - ); - listener.register(); - }); - - afterEach(async () => { - sandbox.restore(); - }); - - it('should subscribe on chrome.tabs.onUpdated', () => { - assert.ok(chromeMock.tabs.onUpdated.addListener.calledOnce); - }); - - it('should only be triggered on tab status "loading"', () => { - const spy = sandbox.spy(listener, 'injectContentScript'); - chromeMock.tabs.onUpdated.dispatch(TAB_ID, { - status: TabStatus.COMPLETE, - }); - chromeMock.tabs.onUpdated.dispatch(TAB_ID, { - status: TabStatus.UNLOADED, - }); - assert.ok(spy.notCalled); - assert.ok(chromeMock.tabs.get.notCalled); - - chromeMock.tabs.onUpdated.dispatch(TAB_ID, { - status: TabStatus.LOADING, - }); - assert.ok(spy.calledOnce, 'injectContentScript not triggered on "loading"'); - assert.ok(chromeMock.tabs.get.calledOnce); - }); - - it('should inject the content script if the url property of a tab is accessible', () => { - chromeMock.tabs.get.reset(); - chromeMock.tabs.get - .onFirstCall() - .callsArgWith(1, { url: undefined } as chrome.tabs.Tab); - chromeMock.tabs.get - .onSecondCall() - .callsArgWith(1, { url: 'http://www.example.com' } as chrome.tabs.Tab); - chromeMock.tabs.get - .onThirdCall() - .callsArgWith(1, { url: 'http://www.example.com' } as chrome.tabs.Tab); - - chromeMock.tabs.onUpdated.dispatch(TAB_ID, { - status: TabStatus.LOADING, - }); - - assert.ok(chromeMock.tabs.executeScript.notCalled); - - chromeMock.tabs.onUpdated.dispatch(TAB_ID, { - status: TabStatus.LOADING, - }); - - assert.ok( - chromeMock.tabs.executeScript.calledOnceWith(TAB_ID, { - file: CONTENT_SCRIPT_NAME, - allFrames: true, - }) - ); - - const chromeMockV3 = chromeMock as typeof chromeMock & { - scripting: { - executeScript: (args: any) => void; - }; - }; - - chromeMockV3.scripting = { - executeScript: args => { - assert.deepStrictEqual(args, { - target: { - allFrames: true, - tabId: TAB_ID, - }, - files: [CONTENT_SCRIPT_NAME], - }); - }, - }; - - chromeMock.tabs.onUpdated.dispatch(TAB_ID, { - status: TabStatus.LOADING, - }); - }); -}); diff --git a/archive/opentelemetry-browser-extension-autoinjection/test/contentScript.test.ts b/archive/opentelemetry-browser-extension-autoinjection/test/contentScript.test.ts deleted file mode 100644 index fd8e842a71..0000000000 --- a/archive/opentelemetry-browser-extension-autoinjection/test/contentScript.test.ts +++ /dev/null @@ -1,140 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/* eslint-disable node/no-unpublished-import */ - -import * as chromeMock from 'sinon-chrome'; -import * as assert from 'assert'; -import * as sinon from 'sinon'; - -import { InstrumentationInjector } from '../src/contentScript/InstrumentationInjector'; -import { JSDOM } from 'jsdom'; -import { - DomAttributes, - DomElements, - INSTRUMENTATION_SCRIPT_NAME, - Settings, -} from '../src/types'; -import { TEST_URL } from './utils'; - -describe('InstrumentationInjector', () => { - let sandbox: sinon.SinonSandbox; - let injector: InstrumentationInjector; - let jsdom: JSDOM; - - beforeEach(() => { - sandbox = sinon.createSandbox(); - jsdom = new JSDOM('', { - url: TEST_URL, - }); - injector = new InstrumentationInjector( - chromeMock as unknown as typeof chrome, - jsdom.window.document, - { - log: () => {}, - } as Console - ); - }); - - afterEach(async () => { - sandbox.restore(); - chromeMock.reset(); - }); - - describe('checkUrlFilter', () => { - it('matches on parts of the URL', () => { - assert.ok( - InstrumentationInjector.checkUrlFilter( - 'example', - 'http://www.example.com' - ) - ); - - assert.ok( - InstrumentationInjector.checkUrlFilter( - 'www.exa', - 'http://www.example.com' - ) - ); - - assert.ok( - !InstrumentationInjector.checkUrlFilter('123', 'http://www.example.com') - ); - }); - - it('accepts "*" as a catch all', () => { - assert.ok( - InstrumentationInjector.checkUrlFilter('*', 'http://www.example.com') - ); - - assert.ok( - InstrumentationInjector.checkUrlFilter( - '*', - 'http://www.opentelemetry.io' - ) - ); - }); - }); - - describe('execute', () => { - it('should load settings from storage', () => { - injector.execute(); - assert.ok(chromeMock.storage.local.get.calledOnceWith('settings')); - }); - - it('should only inject instrumentation if urlFilter matches', () => { - const spy = sandbox.spy(injector, 'inject'); - chromeMock.storage.local.get.onFirstCall().callsArgWith(1, { - settings: { - urlFilter: '123', - }, - }); - chromeMock.storage.local.get.onSecondCall().callsArgWith(1, { - settings: { - urlFilter: 'example', - }, - }); - - injector.execute(); - assert.ok(spy.notCalled); - - injector.execute(); - assert.ok(spy.calledOnce); - }); - }); - - describe('inject', () => { - it('adds a script element to the DOM that loads the instrumentation code', () => { - const scriptName = `chrome-extension://id/${INSTRUMENTATION_SCRIPT_NAME}`; - - chromeMock.runtime.getURL.onFirstCall().returns(scriptName); - - const settings = { exporters: {} }; - injector.inject(settings as Settings); - const configTag = jsdom.window.document.getElementById( - DomElements.CONFIG_TAG - ); - assert.ok(configTag instanceof jsdom.window.HTMLScriptElement); - assert.deepStrictEqual( - settings, - JSON.parse( - String(configTag.getAttribute(`data-${DomAttributes.CONFIG}`)) - ) - ); - assert.ok(configTag.getAttribute('src'), scriptName); - }); - }); -}); diff --git a/archive/opentelemetry-browser-extension-autoinjection/test/instrumentation.test.ts b/archive/opentelemetry-browser-extension-autoinjection/test/instrumentation.test.ts deleted file mode 100644 index 759d3c2589..0000000000 --- a/archive/opentelemetry-browser-extension-autoinjection/test/instrumentation.test.ts +++ /dev/null @@ -1,88 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/* eslint-disable node/no-unpublished-import */ - -import * as chromeMock from 'sinon-chrome'; -import * as assert from 'assert'; -import * as sinon from 'sinon'; -import { WebInstrumentation } from '../src/instrumentation/WebInstrumentation'; -import { - ExporterType, - InstrumentationType, - PlaceholderValues, -} from '../src/types'; -import { WebTracerProvider } from '@opentelemetry/sdk-trace-web'; -import { JSDOM } from 'jsdom'; -import { TEST_URL } from './utils'; - -describe('WebInstrumentation', () => { - let sandbox: sinon.SinonSandbox; - let provider: WebTracerProvider; - - beforeEach(() => { - sandbox = sinon.createSandbox(); - provider = new WebTracerProvider(); - const { window } = new JSDOM('', { - url: TEST_URL, - }); - - global.window = window as any; - global.XMLHttpRequest = window.XMLHttpRequest; - global.document = window.document; - }); - - afterEach(async () => { - sandbox.restore(); - chromeMock.reset(); - }); - - it('adds exporters to the trace provider', () => { - const addSpanProcessorSpy = sinon.spy(provider, 'addSpanProcessor'); - const instrumentation = new WebInstrumentation( - { - exporters: { - [ExporterType.CONSOLE]: { - enabled: true, - }, - [ExporterType.ZIPKIN]: { - enabled: true, - url: PlaceholderValues.ZIPKIN_URL, - }, - [ExporterType.COLLECTOR_TRACE]: { - enabled: true, - url: PlaceholderValues.COLLECTOR_TRACE_URL, - }, - }, - instrumentations: { - [InstrumentationType.DOCUMENT_LOAD]: { - enabled: true, - }, - [InstrumentationType.FETCH]: { - enabled: false, - }, - [InstrumentationType.XML_HTTP_REQUEST]: { - enabled: true, - }, - }, - withZoneContextManager: true, - }, - provider - ); - instrumentation.register(); - assert.ok(addSpanProcessorSpy.callCount === 3); - }); -}); diff --git a/archive/opentelemetry-browser-extension-autoinjection/test/utils.ts b/archive/opentelemetry-browser-extension-autoinjection/test/utils.ts deleted file mode 100644 index f273cc1b7f..0000000000 --- a/archive/opentelemetry-browser-extension-autoinjection/test/utils.ts +++ /dev/null @@ -1,18 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -export const TAB_ID = 13; -export const TEST_URL = 'http://www.example.com'; diff --git a/archive/opentelemetry-browser-extension-autoinjection/tsconfig.json b/archive/opentelemetry-browser-extension-autoinjection/tsconfig.json deleted file mode 100644 index c1e3fae6fe..0000000000 --- a/archive/opentelemetry-browser-extension-autoinjection/tsconfig.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "extends": "../../tsconfig.base", - "compilerOptions": { - "rootDir": ".", - "outDir": "build", - "jsx": "react" - }, - "include": [ - "src/**/*.ts", - "src/**/*.tsx", - "test/**/*.ts", - "webpack.config.ts" - ] -} diff --git a/archive/opentelemetry-browser-extension-autoinjection/webpack.config.ts b/archive/opentelemetry-browser-extension-autoinjection/webpack.config.ts deleted file mode 100644 index 53fdc8fa85..0000000000 --- a/archive/opentelemetry-browser-extension-autoinjection/webpack.config.ts +++ /dev/null @@ -1,157 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/* eslint-disable node/no-unpublished-import */ - -import * as path from 'path'; -import { mergeWithRules } from 'webpack-merge'; -import * as HtmlWebpackPlugin from 'html-webpack-plugin'; - -// Read the environment variables, and check for the existence of the "MV" variable -// This can be used to only build the one or the other target. -module.exports = (env: { MV?: string; WEBPACK_BUILD: boolean }) => { - // Build the extension for "Manifest Version 2" (Chromium, Firefox & others.) - const baseConfig = { - entry: { - background: './src/background/index.ts', - contentScript: './src/contentScript/index.ts', - instrumentation: './src/instrumentation/index.ts', - ui: './src/ui/index.tsx', - }, - module: { - rules: [ - { - include: [path.resolve(__dirname, 'src/manifest.json5')], - test: /manifest.json5$/, - use: [ - { - loader: 'null-loader', - options: {}, - }, - { - loader: path.resolve('src/utils/manifest-loader.ts'), - options: { - manifestVersion: 2, - }, - }, - ], - }, - { - include: [path.resolve(__dirname, 'src')], - test: /\.tsx?$/, - use: [ - { - loader: 'ts-loader', - options: { - transpileOnly: true, - experimentalWatchApi: true, - }, - }, - ], - }, - { - include: [path.resolve(__dirname, 'src/icons')], - test: /\.(jpe?g|png|webp)$/i, - use: [ - // We are not going to use any of the images for real, throw away all output - { - loader: 'null-loader', - options: {}, - }, - { - loader: 'responsive-loader', - options: { - name: '[name]_[width].[ext]', - outputPath: 'icons/', - sizes: [16, 32, 48, 128], - }, - }, - ], - }, - ], - }, - plugins: [ - new HtmlWebpackPlugin({ - chunks: ['ui'], - inject: 'head', - filename: 'options.html', - template: 'src/template.html', - }), - new HtmlWebpackPlugin({ - chunks: ['ui'], - filename: 'popup.html', - inject: 'head', - template: 'src/template.html', - }), - ], - resolve: { - extensions: ['.tsx', '.ts', '.js'], - }, - }; - - const merge = mergeWithRules({ - module: { - rules: { - test: 'match', - include: 'match', - use: { - loader: 'match', - options: 'replace', - }, - }, - }, - }); - - const targetMV2 = merge(baseConfig, { - output: { - filename: '[name].js', - path: path.resolve(__dirname, 'build/mv2'), - }, - }); - const targetMV3 = merge(baseConfig, { - module: { - rules: [ - { - include: [path.resolve(__dirname, 'src/manifest.json5')], - test: /manifest.json5$/, - use: [ - { - loader: path.resolve('src/utils/manifest-loader.ts'), - options: { - manifestVersion: 3, - }, - }, - ], - }, - ], - }, - output: { - filename: '[name].js', - path: path.resolve(__dirname, 'build/mv3'), - }, - }); - - const exports = []; - - if (env.MV) { - exports.push(Number(env.MV) === 3 ? targetMV3 : targetMV2); - } else { - exports.push(targetMV3); - exports.push(targetMV2); - } - - return exports; -}; diff --git a/detectors/node/opentelemetry-resource-detector-alibaba-cloud/CHANGELOG.md b/detectors/node/opentelemetry-resource-detector-alibaba-cloud/CHANGELOG.md index ccc06ed649..daa4e8bcb0 100644 --- a/detectors/node/opentelemetry-resource-detector-alibaba-cloud/CHANGELOG.md +++ b/detectors/node/opentelemetry-resource-detector-alibaba-cloud/CHANGELOG.md @@ -1,5 +1,13 @@ # Changelog +## [0.30.0](https://github.com/open-telemetry/opentelemetry-js-contrib/compare/resource-detector-alibaba-cloud-v0.29.7...resource-detector-alibaba-cloud-v0.30.0) (2025-01-20) + + +### Features + +* **detectors:** generate esm build files too ([#2636](https://github.com/open-telemetry/opentelemetry-js-contrib/issues/2636)) ([c2ad0af](https://github.com/open-telemetry/opentelemetry-js-contrib/commit/c2ad0af34e1570f3609beefc4a8d41ddfb7f8f77)) +* **detectors:** mark as side effect free ([#2663](https://github.com/open-telemetry/opentelemetry-js-contrib/issues/2663)) ([e9263a3](https://github.com/open-telemetry/opentelemetry-js-contrib/commit/e9263a36255c0016cca78bf16c4598f23519d5f1)) + ## [0.29.7](https://github.com/open-telemetry/opentelemetry-js-contrib/compare/resource-detector-alibaba-cloud-v0.29.6...resource-detector-alibaba-cloud-v0.29.7) (2024-12-18) diff --git a/detectors/node/opentelemetry-resource-detector-alibaba-cloud/package.json b/detectors/node/opentelemetry-resource-detector-alibaba-cloud/package.json index 137bcec331..609db889a1 100644 --- a/detectors/node/opentelemetry-resource-detector-alibaba-cloud/package.json +++ b/detectors/node/opentelemetry-resource-detector-alibaba-cloud/package.json @@ -1,6 +1,6 @@ { "name": "@opentelemetry/resource-detector-alibaba-cloud", - "version": "0.29.7", + "version": "0.30.0", "description": "OpenTelemetry resource detector for Alibaba Cloud", "main": "build/src/index.js", "module": "build/esm/index.js", @@ -61,5 +61,6 @@ "@opentelemetry/resources": "^1.10.0", "@opentelemetry/semantic-conventions": "^1.27.0" }, - "homepage": "https://github.com/open-telemetry/opentelemetry-js-contrib/tree/main/detectors/node/opentelemetry-resource-detector-alibaba-cloud#readme" + "homepage": "https://github.com/open-telemetry/opentelemetry-js-contrib/tree/main/detectors/node/opentelemetry-resource-detector-alibaba-cloud#readme", + "sideEffects": false } diff --git a/detectors/node/opentelemetry-resource-detector-aws/CHANGELOG.md b/detectors/node/opentelemetry-resource-detector-aws/CHANGELOG.md index 4ecb55261d..b84551d208 100644 --- a/detectors/node/opentelemetry-resource-detector-aws/CHANGELOG.md +++ b/detectors/node/opentelemetry-resource-detector-aws/CHANGELOG.md @@ -1,5 +1,19 @@ # Changelog +## [1.11.0](https://github.com/open-telemetry/opentelemetry-js-contrib/compare/resource-detector-aws-v1.10.0...resource-detector-aws-v1.11.0) (2025-01-20) + + +### Features + +* **detectors:** generate esm build files too ([#2636](https://github.com/open-telemetry/opentelemetry-js-contrib/issues/2636)) ([c2ad0af](https://github.com/open-telemetry/opentelemetry-js-contrib/commit/c2ad0af34e1570f3609beefc4a8d41ddfb7f8f77)) +* **detectors:** mark as side effect free ([#2663](https://github.com/open-telemetry/opentelemetry-js-contrib/issues/2663)) ([e9263a3](https://github.com/open-telemetry/opentelemetry-js-contrib/commit/e9263a36255c0016cca78bf16c4598f23519d5f1)) + + +### Bug Fixes + +* **detector-aws:** remove all deprecation warnings ([#2642](https://github.com/open-telemetry/opentelemetry-js-contrib/issues/2642)) ([f97bd70](https://github.com/open-telemetry/opentelemetry-js-contrib/commit/f97bd7099ed6ec4e99af98157608040708de15c6)) +* **detector-aws:** remove semconv incubating import ([#2668](https://github.com/open-telemetry/opentelemetry-js-contrib/issues/2668)) ([3e95995](https://github.com/open-telemetry/opentelemetry-js-contrib/commit/3e95995fcdaa7aecdc47bf52f01fa2e48e4f98ce)) + ## [1.10.0](https://github.com/open-telemetry/opentelemetry-js-contrib/compare/resource-detector-aws-v1.9.0...resource-detector-aws-v1.10.0) (2024-12-18) diff --git a/detectors/node/opentelemetry-resource-detector-aws/package.json b/detectors/node/opentelemetry-resource-detector-aws/package.json index a0c8c7496a..f34c951628 100644 --- a/detectors/node/opentelemetry-resource-detector-aws/package.json +++ b/detectors/node/opentelemetry-resource-detector-aws/package.json @@ -1,6 +1,6 @@ { "name": "@opentelemetry/resource-detector-aws", - "version": "1.10.0", + "version": "1.11.0", "description": "OpenTelemetry SDK resource detector for AWS", "main": "build/src/index.js", "module": "build/esm/index.js", @@ -62,5 +62,6 @@ "@opentelemetry/resources": "^1.10.0", "@opentelemetry/semantic-conventions": "^1.27.0" }, - "homepage": "https://github.com/open-telemetry/opentelemetry-js-contrib/tree/main/detectors/node/opentelemetry-resource-detector-aws#readme" + "homepage": "https://github.com/open-telemetry/opentelemetry-js-contrib/tree/main/detectors/node/opentelemetry-resource-detector-aws#readme", + "sideEffects": false } diff --git a/detectors/node/opentelemetry-resource-detector-aws/src/detectors/AwsBeanstalkDetectorSync.ts b/detectors/node/opentelemetry-resource-detector-aws/src/detectors/AwsBeanstalkDetectorSync.ts index 9f938f91a8..47b279738a 100644 --- a/detectors/node/opentelemetry-resource-detector-aws/src/detectors/AwsBeanstalkDetectorSync.ts +++ b/detectors/node/opentelemetry-resource-detector-aws/src/detectors/AwsBeanstalkDetectorSync.ts @@ -25,15 +25,17 @@ import { ResourceDetectionConfig, } from '@opentelemetry/resources'; import { - SEMRESATTRS_CLOUD_PROVIDER, - SEMRESATTRS_CLOUD_PLATFORM, - SEMRESATTRS_SERVICE_NAME, - SEMRESATTRS_SERVICE_NAMESPACE, - SEMRESATTRS_SERVICE_VERSION, - SEMRESATTRS_SERVICE_INSTANCE_ID, - CLOUDPROVIDERVALUES_AWS, - CLOUDPLATFORMVALUES_AWS_ELASTIC_BEANSTALK, + ATTR_SERVICE_NAME, + ATTR_SERVICE_VERSION, } from '@opentelemetry/semantic-conventions'; +import { + ATTR_CLOUD_PROVIDER, + ATTR_CLOUD_PLATFORM, + ATTR_SERVICE_NAMESPACE, + ATTR_SERVICE_INSTANCE_ID, + CLOUD_PROVIDER_VALUE_AWS, + CLOUD_PLATFORM_VALUE_AWS_ELASTIC_BEANSTALK, +} from '../semconv'; import * as fs from 'fs'; import * as util from 'util'; @@ -95,12 +97,12 @@ export class AwsBeanstalkDetectorSync implements DetectorSync { const parsedData = JSON.parse(rawData); return { - [SEMRESATTRS_CLOUD_PROVIDER]: CLOUDPROVIDERVALUES_AWS, - [SEMRESATTRS_CLOUD_PLATFORM]: CLOUDPLATFORMVALUES_AWS_ELASTIC_BEANSTALK, - [SEMRESATTRS_SERVICE_NAME]: CLOUDPLATFORMVALUES_AWS_ELASTIC_BEANSTALK, - [SEMRESATTRS_SERVICE_NAMESPACE]: parsedData.environment_name, - [SEMRESATTRS_SERVICE_VERSION]: parsedData.version_label, - [SEMRESATTRS_SERVICE_INSTANCE_ID]: parsedData.deployment_id, + [ATTR_CLOUD_PROVIDER]: CLOUD_PROVIDER_VALUE_AWS, + [ATTR_CLOUD_PLATFORM]: CLOUD_PLATFORM_VALUE_AWS_ELASTIC_BEANSTALK, + [ATTR_SERVICE_NAME]: CLOUD_PLATFORM_VALUE_AWS_ELASTIC_BEANSTALK, + [ATTR_SERVICE_NAMESPACE]: parsedData.environment_name, + [ATTR_SERVICE_VERSION]: parsedData.version_label, + [ATTR_SERVICE_INSTANCE_ID]: parsedData.deployment_id, }; } catch (e: any) { diag.debug(`AwsBeanstalkDetectorSync failed: ${e.message}`); diff --git a/detectors/node/opentelemetry-resource-detector-aws/src/detectors/AwsEc2DetectorSync.ts b/detectors/node/opentelemetry-resource-detector-aws/src/detectors/AwsEc2DetectorSync.ts index a0ef6b47b1..5b91d51b10 100644 --- a/detectors/node/opentelemetry-resource-detector-aws/src/detectors/AwsEc2DetectorSync.ts +++ b/detectors/node/opentelemetry-resource-detector-aws/src/detectors/AwsEc2DetectorSync.ts @@ -24,17 +24,17 @@ import { ResourceDetectionConfig, } from '@opentelemetry/resources'; import { - SEMRESATTRS_CLOUD_PROVIDER, - SEMRESATTRS_CLOUD_PLATFORM, - SEMRESATTRS_CLOUD_REGION, - SEMRESATTRS_CLOUD_ACCOUNT_ID, - SEMRESATTRS_CLOUD_AVAILABILITY_ZONE, - SEMRESATTRS_HOST_ID, - SEMRESATTRS_HOST_TYPE, - SEMRESATTRS_HOST_NAME, - CLOUDPROVIDERVALUES_AWS, - CLOUDPLATFORMVALUES_AWS_EC2, -} from '@opentelemetry/semantic-conventions'; + ATTR_CLOUD_PROVIDER, + ATTR_CLOUD_PLATFORM, + ATTR_CLOUD_REGION, + ATTR_CLOUD_ACCOUNT_ID, + ATTR_CLOUD_AVAILABILITY_ZONE, + ATTR_HOST_ID, + ATTR_HOST_TYPE, + ATTR_HOST_NAME, + CLOUD_PROVIDER_VALUE_AWS, + CLOUD_PLATFORM_VALUE_AWS_EC2, +} from '../semconv'; import * as http from 'http'; /** @@ -79,14 +79,14 @@ class AwsEc2DetectorSync implements DetectorSync { const hostname = await this._fetchHost(token); return { - [SEMRESATTRS_CLOUD_PROVIDER]: CLOUDPROVIDERVALUES_AWS, - [SEMRESATTRS_CLOUD_PLATFORM]: CLOUDPLATFORMVALUES_AWS_EC2, - [SEMRESATTRS_CLOUD_ACCOUNT_ID]: accountId, - [SEMRESATTRS_CLOUD_REGION]: region, - [SEMRESATTRS_CLOUD_AVAILABILITY_ZONE]: availabilityZone, - [SEMRESATTRS_HOST_ID]: instanceId, - [SEMRESATTRS_HOST_TYPE]: instanceType, - [SEMRESATTRS_HOST_NAME]: hostname, + [ATTR_CLOUD_PROVIDER]: CLOUD_PROVIDER_VALUE_AWS, + [ATTR_CLOUD_PLATFORM]: CLOUD_PLATFORM_VALUE_AWS_EC2, + [ATTR_CLOUD_ACCOUNT_ID]: accountId, + [ATTR_CLOUD_REGION]: region, + [ATTR_CLOUD_AVAILABILITY_ZONE]: availabilityZone, + [ATTR_HOST_ID]: instanceId, + [ATTR_HOST_TYPE]: instanceType, + [ATTR_HOST_NAME]: hostname, }; } catch { return {}; diff --git a/detectors/node/opentelemetry-resource-detector-aws/src/detectors/AwsEcsDetectorSync.ts b/detectors/node/opentelemetry-resource-detector-aws/src/detectors/AwsEcsDetectorSync.ts index 56977c2c01..d7ccaf8465 100644 --- a/detectors/node/opentelemetry-resource-detector-aws/src/detectors/AwsEcsDetectorSync.ts +++ b/detectors/node/opentelemetry-resource-detector-aws/src/detectors/AwsEcsDetectorSync.ts @@ -23,26 +23,26 @@ import { ResourceAttributes, } from '@opentelemetry/resources'; import { - SEMRESATTRS_CLOUD_PROVIDER, - SEMRESATTRS_CLOUD_PLATFORM, - SEMRESATTRS_CONTAINER_ID, - SEMRESATTRS_CONTAINER_NAME, - SEMRESATTRS_AWS_ECS_CONTAINER_ARN, - SEMRESATTRS_AWS_ECS_CLUSTER_ARN, - SEMRESATTRS_AWS_ECS_LAUNCHTYPE, - SEMRESATTRS_AWS_ECS_TASK_ARN, - SEMRESATTRS_AWS_ECS_TASK_FAMILY, - SEMRESATTRS_AWS_ECS_TASK_REVISION, - SEMRESATTRS_CLOUD_ACCOUNT_ID, - SEMRESATTRS_CLOUD_REGION, - SEMRESATTRS_CLOUD_AVAILABILITY_ZONE, - SEMRESATTRS_AWS_LOG_GROUP_NAMES, - SEMRESATTRS_AWS_LOG_GROUP_ARNS, - SEMRESATTRS_AWS_LOG_STREAM_NAMES, - SEMRESATTRS_AWS_LOG_STREAM_ARNS, - CLOUDPROVIDERVALUES_AWS, - CLOUDPLATFORMVALUES_AWS_ECS, -} from '@opentelemetry/semantic-conventions'; + ATTR_CLOUD_PROVIDER, + ATTR_CLOUD_PLATFORM, + ATTR_CONTAINER_ID, + ATTR_CONTAINER_NAME, + ATTR_AWS_ECS_CONTAINER_ARN, + ATTR_AWS_ECS_CLUSTER_ARN, + ATTR_AWS_ECS_LAUNCHTYPE, + ATTR_AWS_ECS_TASK_ARN, + ATTR_AWS_ECS_TASK_FAMILY, + ATTR_AWS_ECS_TASK_REVISION, + ATTR_CLOUD_ACCOUNT_ID, + ATTR_CLOUD_REGION, + ATTR_CLOUD_AVAILABILITY_ZONE, + ATTR_AWS_LOG_GROUP_NAMES, + ATTR_AWS_LOG_GROUP_ARNS, + ATTR_AWS_LOG_STREAM_NAMES, + ATTR_AWS_LOG_STREAM_ARNS, + CLOUD_PROVIDER_VALUE_AWS, + CLOUD_PLATFORM_VALUE_AWS_ECS, +} from '../semconv'; // Patch until the OpenTelemetry SDK is updated to ship this attribute import { SemanticResourceAttributes as AdditionalSemanticResourceAttributes } from './SemanticResourceAttributes'; import * as http from 'http'; @@ -86,8 +86,8 @@ export class AwsEcsDetectorSync implements DetectorSync { try { let resource = new Resource({ - [SEMRESATTRS_CLOUD_PROVIDER]: CLOUDPROVIDERVALUES_AWS, - [SEMRESATTRS_CLOUD_PLATFORM]: CLOUDPLATFORMVALUES_AWS_ECS, + [ATTR_CLOUD_PROVIDER]: CLOUD_PROVIDER_VALUE_AWS, + [ATTR_CLOUD_PLATFORM]: CLOUD_PLATFORM_VALUE_AWS_ECS, }).merge(await AwsEcsDetectorSync._getContainerIdAndHostnameResource()); const metadataUrl = getEnv().ECS_CONTAINER_METADATA_URI_V4; @@ -146,8 +146,8 @@ export class AwsEcsDetectorSync implements DetectorSync { if (hostName || containerId) { return new Resource({ - [SEMRESATTRS_CONTAINER_NAME]: hostName || '', - [SEMRESATTRS_CONTAINER_ID]: containerId || '', + [ATTR_CONTAINER_NAME]: hostName || '', + [ATTR_CONTAINER_ID]: containerId || '', }); } @@ -166,8 +166,7 @@ export class AwsEcsDetectorSync implements DetectorSync { const accountId: string = AwsEcsDetectorSync._getAccountFromArn(taskArn); const region: string = AwsEcsDetectorSync._getRegionFromArn(taskArn); - const availabilityZone: string | undefined = - taskMetadata?.['AvailabilityZone']; + const availabilityZone: string | undefined = taskMetadata?.AvailabilityZone; const clusterArn = cluster.startsWith('arn:') ? cluster @@ -177,21 +176,21 @@ export class AwsEcsDetectorSync implements DetectorSync { // https://github.com/open-telemetry/semantic-conventions/blob/main/semantic_conventions/resource/cloud_provider/aws/ecs.yaml const attributes: ResourceAttributes = { - [SEMRESATTRS_AWS_ECS_CONTAINER_ARN]: containerArn, - [SEMRESATTRS_AWS_ECS_CLUSTER_ARN]: clusterArn, - [SEMRESATTRS_AWS_ECS_LAUNCHTYPE]: launchType?.toLowerCase(), - [SEMRESATTRS_AWS_ECS_TASK_ARN]: taskArn, - [SEMRESATTRS_AWS_ECS_TASK_FAMILY]: taskMetadata['Family'], - [SEMRESATTRS_AWS_ECS_TASK_REVISION]: taskMetadata['Revision'], - - [SEMRESATTRS_CLOUD_ACCOUNT_ID]: accountId, - [SEMRESATTRS_CLOUD_REGION]: region, + [ATTR_AWS_ECS_CONTAINER_ARN]: containerArn, + [ATTR_AWS_ECS_CLUSTER_ARN]: clusterArn, + [ATTR_AWS_ECS_LAUNCHTYPE]: launchType?.toLowerCase(), + [ATTR_AWS_ECS_TASK_ARN]: taskArn, + [ATTR_AWS_ECS_TASK_FAMILY]: taskMetadata['Family'], + [ATTR_AWS_ECS_TASK_REVISION]: taskMetadata['Revision'], + + [ATTR_CLOUD_ACCOUNT_ID]: accountId, + [ATTR_CLOUD_REGION]: region, [AdditionalSemanticResourceAttributes.CLOUD_RESOURCE_ID]: containerArn, }; // The availability zone is not available in all Fargate runtimes if (availabilityZone) { - attributes[SEMRESATTRS_CLOUD_AVAILABILITY_ZONE] = availabilityZone; + attributes[ATTR_CLOUD_AVAILABILITY_ZONE] = availabilityZone; } return new Resource(attributes); @@ -222,10 +221,10 @@ export class AwsEcsDetectorSync implements DetectorSync { const logsStreamArn = `arn:aws:logs:${logsRegion}:${awsAccount}:log-group:${logsGroupName}:log-stream:${logsStreamName}`; return new Resource({ - [SEMRESATTRS_AWS_LOG_GROUP_NAMES]: [logsGroupName], - [SEMRESATTRS_AWS_LOG_GROUP_ARNS]: [logsGroupArn], - [SEMRESATTRS_AWS_LOG_STREAM_NAMES]: [logsStreamName], - [SEMRESATTRS_AWS_LOG_STREAM_ARNS]: [logsStreamArn], + [ATTR_AWS_LOG_GROUP_NAMES]: [logsGroupName], + [ATTR_AWS_LOG_GROUP_ARNS]: [logsGroupArn], + [ATTR_AWS_LOG_STREAM_NAMES]: [logsStreamName], + [ATTR_AWS_LOG_STREAM_ARNS]: [logsStreamArn], }); } diff --git a/detectors/node/opentelemetry-resource-detector-aws/src/detectors/AwsEksDetectorSync.ts b/detectors/node/opentelemetry-resource-detector-aws/src/detectors/AwsEksDetectorSync.ts index 051d3af5e8..244bf50247 100644 --- a/detectors/node/opentelemetry-resource-detector-aws/src/detectors/AwsEksDetectorSync.ts +++ b/detectors/node/opentelemetry-resource-detector-aws/src/detectors/AwsEksDetectorSync.ts @@ -24,13 +24,13 @@ import { ResourceDetectionConfig, } from '@opentelemetry/resources'; import { - SEMRESATTRS_CLOUD_PROVIDER, - SEMRESATTRS_CLOUD_PLATFORM, - SEMRESATTRS_K8S_CLUSTER_NAME, - SEMRESATTRS_CONTAINER_ID, - CLOUDPROVIDERVALUES_AWS, - CLOUDPLATFORMVALUES_AWS_EKS, -} from '@opentelemetry/semantic-conventions'; + ATTR_CLOUD_PROVIDER, + ATTR_CLOUD_PLATFORM, + ATTR_K8S_CLUSTER_NAME, + ATTR_CONTAINER_ID, + CLOUD_PROVIDER_VALUE_AWS, + CLOUD_PLATFORM_VALUE_AWS_EKS, +} from '../semconv'; import * as https from 'https'; import * as fs from 'fs'; import * as util from 'util'; @@ -94,10 +94,10 @@ export class AwsEksDetectorSync implements DetectorSync { return !containerId && !clusterName ? {} : { - [SEMRESATTRS_CLOUD_PROVIDER]: CLOUDPROVIDERVALUES_AWS, - [SEMRESATTRS_CLOUD_PLATFORM]: CLOUDPLATFORMVALUES_AWS_EKS, - [SEMRESATTRS_K8S_CLUSTER_NAME]: clusterName || '', - [SEMRESATTRS_CONTAINER_ID]: containerId || '', + [ATTR_CLOUD_PROVIDER]: CLOUD_PROVIDER_VALUE_AWS, + [ATTR_CLOUD_PLATFORM]: CLOUD_PLATFORM_VALUE_AWS_EKS, + [ATTR_K8S_CLUSTER_NAME]: clusterName || '', + [ATTR_CONTAINER_ID]: containerId || '', }; } catch (e) { diag.debug('Process is not running on K8S', e); diff --git a/detectors/node/opentelemetry-resource-detector-aws/src/detectors/AwsLambdaDetectorSync.ts b/detectors/node/opentelemetry-resource-detector-aws/src/detectors/AwsLambdaDetectorSync.ts index 4b85f44bdc..66fe94ee2a 100644 --- a/detectors/node/opentelemetry-resource-detector-aws/src/detectors/AwsLambdaDetectorSync.ts +++ b/detectors/node/opentelemetry-resource-detector-aws/src/detectors/AwsLambdaDetectorSync.ts @@ -22,14 +22,14 @@ import { ResourceDetectionConfig, } from '@opentelemetry/resources'; import { - SEMRESATTRS_CLOUD_PROVIDER, - SEMRESATTRS_CLOUD_PLATFORM, - SEMRESATTRS_CLOUD_REGION, - SEMRESATTRS_FAAS_VERSION, - SEMRESATTRS_FAAS_NAME, - CLOUDPROVIDERVALUES_AWS, - CLOUDPLATFORMVALUES_AWS_LAMBDA, -} from '@opentelemetry/semantic-conventions'; + ATTR_CLOUD_PROVIDER, + ATTR_CLOUD_PLATFORM, + ATTR_CLOUD_REGION, + ATTR_FAAS_VERSION, + ATTR_FAAS_NAME, + CLOUD_PROVIDER_VALUE_AWS, + CLOUD_PLATFORM_VALUE_AWS_LAMBDA, +} from '../semconv'; /** * The AwsLambdaDetector can be used to detect if a process is running in AWS Lambda @@ -47,18 +47,18 @@ export class AwsLambdaDetectorSync implements DetectorSync { const region = process.env.AWS_REGION; const attributes: ResourceAttributes = { - [SEMRESATTRS_CLOUD_PROVIDER]: String(CLOUDPROVIDERVALUES_AWS), - [SEMRESATTRS_CLOUD_PLATFORM]: String(CLOUDPLATFORMVALUES_AWS_LAMBDA), + [ATTR_CLOUD_PROVIDER]: String(CLOUD_PROVIDER_VALUE_AWS), + [ATTR_CLOUD_PLATFORM]: String(CLOUD_PLATFORM_VALUE_AWS_LAMBDA), }; if (region) { - attributes[SEMRESATTRS_CLOUD_REGION] = region; + attributes[ATTR_CLOUD_REGION] = region; } if (functionName) { - attributes[SEMRESATTRS_FAAS_NAME] = functionName; + attributes[ATTR_FAAS_NAME] = functionName; } if (functionVersion) { - attributes[SEMRESATTRS_FAAS_VERSION] = functionVersion; + attributes[ATTR_FAAS_VERSION] = functionVersion; } return new Resource(attributes); diff --git a/detectors/node/opentelemetry-resource-detector-aws/src/semconv.ts b/detectors/node/opentelemetry-resource-detector-aws/src/semconv.ts new file mode 100644 index 0000000000..3d34526643 --- /dev/null +++ b/detectors/node/opentelemetry-resource-detector-aws/src/semconv.ts @@ -0,0 +1,345 @@ +/* + * Copyright The OpenTelemetry Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* + * This file contains a copy of unstable semantic convention definitions + * used by this package. + * @see https://github.com/open-telemetry/opentelemetry-js/tree/main/semantic-conventions#unstable-semconv + */ + +/** + * The ARN of an [ECS cluster](https://docs.aws.amazon.com/AmazonECS/latest/developerguide/clusters.html). + * + * @example arn:aws:ecs:us-west-2:123456789123:cluster/my-cluster + * + * @experimental This attribute is experimental and is subject to breaking changes in minor releases of `@opentelemetry/semantic-conventions`. + */ +export const ATTR_AWS_ECS_CLUSTER_ARN = 'aws.ecs.cluster.arn'; + +/** + * The Amazon Resource Name (ARN) of an [ECS container instance](https://docs.aws.amazon.com/AmazonECS/latest/developerguide/ECS_instances.html). + * + * @example arn:aws:ecs:us-west-1:123456789123:container/32624152-9086-4f0e-acae-1a75b14fe4d9 + * + * @experimental This attribute is experimental and is subject to breaking changes in minor releases of `@opentelemetry/semantic-conventions`. + */ +export const ATTR_AWS_ECS_CONTAINER_ARN = 'aws.ecs.container.arn'; + +/** + * The [launch type](https://docs.aws.amazon.com/AmazonECS/latest/developerguide/launch_types.html) for an ECS task. + * + * @experimental This attribute is experimental and is subject to breaking changes in minor releases of `@opentelemetry/semantic-conventions`. + */ +export const ATTR_AWS_ECS_LAUNCHTYPE = 'aws.ecs.launchtype'; + +/** + * The ARN of a running [ECS task](https://docs.aws.amazon.com/AmazonECS/latest/developerguide/ecs-account-settings.html#ecs-resource-ids). + * + * @example arn:aws:ecs:us-west-1:123456789123:task/10838bed-421f-43ef-870a-f43feacbbb5b + * @example arn:aws:ecs:us-west-1:123456789123:task/my-cluster/task-id/23ebb8ac-c18f-46c6-8bbe-d55d0e37cfbd + * + * @experimental This attribute is experimental and is subject to breaking changes in minor releases of `@opentelemetry/semantic-conventions`. + */ +export const ATTR_AWS_ECS_TASK_ARN = 'aws.ecs.task.arn'; + +/** + * The family name of the [ECS task definition](https://docs.aws.amazon.com/AmazonECS/latest/developerguide/task_definitions.html) used to create the ECS task. + * + * @example opentelemetry-family + * + * @experimental This attribute is experimental and is subject to breaking changes in minor releases of `@opentelemetry/semantic-conventions`. + */ +export const ATTR_AWS_ECS_TASK_FAMILY = 'aws.ecs.task.family'; + +/** + * The revision for the task definition used to create the ECS task. + * + * @example 8 + * @example 26 + * + * @experimental This attribute is experimental and is subject to breaking changes in minor releases of `@opentelemetry/semantic-conventions`. + */ +export const ATTR_AWS_ECS_TASK_REVISION = 'aws.ecs.task.revision'; + +/** + * The Amazon Resource Name(s) (ARN) of the AWS log group(s). + * + * @example ["arn:aws:logs:us-west-1:123456789012:log-group:/aws/my/group:*"] + * + * @note See the [log group ARN format documentation](https://docs.aws.amazon.com/AmazonCloudWatch/latest/logs/iam-access-control-overview-cwl.html#CWL_ARN_Format). + * + * @experimental This attribute is experimental and is subject to breaking changes in minor releases of `@opentelemetry/semantic-conventions`. + */ +export const ATTR_AWS_LOG_GROUP_ARNS = 'aws.log.group.arns'; + +/** + * The name(s) of the AWS log group(s) an application is writing to. + * + * @example ["/aws/lambda/my-function", "opentelemetry-service"] + * + * @note Multiple log groups must be supported for cases like multi-container applications, where a single application has sidecar containers, and each write to their own log group. + * + * @experimental This attribute is experimental and is subject to breaking changes in minor releases of `@opentelemetry/semantic-conventions`. + */ +export const ATTR_AWS_LOG_GROUP_NAMES = 'aws.log.group.names'; + +/** + * The ARN(s) of the AWS log stream(s). + * + * @example ["arn:aws:logs:us-west-1:123456789012:log-group:/aws/my/group:log-stream:logs/main/10838bed-421f-43ef-870a-f43feacbbb5b"] + * + * @note See the [log stream ARN format documentation](https://docs.aws.amazon.com/AmazonCloudWatch/latest/logs/iam-access-control-overview-cwl.html#CWL_ARN_Format). One log group can contain several log streams, so these ARNs necessarily identify both a log group and a log stream. + * + * @experimental This attribute is experimental and is subject to breaking changes in minor releases of `@opentelemetry/semantic-conventions`. + */ +export const ATTR_AWS_LOG_STREAM_ARNS = 'aws.log.stream.arns'; + +/** + * The name(s) of the AWS log stream(s) an application is writing to. + * + * @example ["logs/main/10838bed-421f-43ef-870a-f43feacbbb5b"] + * + * @experimental This attribute is experimental and is subject to breaking changes in minor releases of `@opentelemetry/semantic-conventions`. + */ +export const ATTR_AWS_LOG_STREAM_NAMES = 'aws.log.stream.names'; + +/** + * The cloud account ID the resource is assigned to. + * + * @example 111111111111 + * @example opentelemetry + * + * @experimental This attribute is experimental and is subject to breaking changes in minor releases of `@opentelemetry/semantic-conventions`. + */ +export const ATTR_CLOUD_ACCOUNT_ID = 'cloud.account.id'; + +/** + * Cloud regions often have multiple, isolated locations known as zones to increase availability. Availability zone represents the zone where the resource is running. + * + * @example us-east-1c + * + * @note Availability zones are called "zones" on Alibaba Cloud and Google Cloud. + * + * @experimental This attribute is experimental and is subject to breaking changes in minor releases of `@opentelemetry/semantic-conventions`. + */ +export const ATTR_CLOUD_AVAILABILITY_ZONE = 'cloud.availability_zone'; + +/** + * The cloud platform in use. + * + * @note The prefix of the service **SHOULD** match the one specified in `cloud.provider`. + * + * @experimental This attribute is experimental and is subject to breaking changes in minor releases of `@opentelemetry/semantic-conventions`. + */ +export const ATTR_CLOUD_PLATFORM = 'cloud.platform'; + +/** + * Name of the cloud provider. + * + * @experimental This attribute is experimental and is subject to breaking changes in minor releases of `@opentelemetry/semantic-conventions`. + */ +export const ATTR_CLOUD_PROVIDER = 'cloud.provider'; + +/** + * The geographical region the resource is running. + * + * @example us-central1 + * @example us-east-1 + * + * @note Refer to your provider's docs to see the available regions, for example [Alibaba Cloud regions](https://www.alibabacloud.com/help/doc-detail/40654.htm), [AWS regions](https://aws.amazon.com/about-aws/global-infrastructure/regions_az/), [Azure regions](https://azure.microsoft.com/global-infrastructure/geographies/), [Google Cloud regions](https://cloud.google.com/about/locations), or [Tencent Cloud regions](https://www.tencentcloud.com/document/product/213/6091). + * + * @experimental This attribute is experimental and is subject to breaking changes in minor releases of `@opentelemetry/semantic-conventions`. + */ +export const ATTR_CLOUD_REGION = 'cloud.region'; + +/** + * Container ID. Usually a UUID, as for example used to [identify Docker containers](https://docs.docker.com/engine/containers/run/#container-identification). The UUID might be abbreviated. + * + * @example a3bf90e006b2 + * + * @experimental This attribute is experimental and is subject to breaking changes in minor releases of `@opentelemetry/semantic-conventions`. + */ +export const ATTR_CONTAINER_ID = 'container.id'; + +/** + * Container name used by container runtime. + * + * @example opentelemetry-autoconf + * + * @experimental This attribute is experimental and is subject to breaking changes in minor releases of `@opentelemetry/semantic-conventions`. + */ +export const ATTR_CONTAINER_NAME = 'container.name'; + +/** + * The name of the single function that this runtime instance executes. + * + * @example my-function + * @example myazurefunctionapp/some-function-name + * + * @note This is the name of the function as configured/deployed on the FaaS + * platform and is usually different from the name of the callback + * function (which may be stored in the + * [`code.namespace`/`code.function`](/docs/general/attributes.md#source-code-attributes) + * span attributes). + * + * For some cloud providers, the above definition is ambiguous. The following + * definition of function name **MUST** be used for this attribute + * (and consequently the span name) for the listed cloud providers/products: + * + * - **Azure:** The full name `/`, i.e., function app name + * followed by a forward slash followed by the function name (this form + * can also be seen in the resource JSON for the function). + * This means that a span attribute **MUST** be used, as an Azure function + * app can host multiple functions that would usually share + * a TracerProvider (see also the `cloud.resource_id` attribute). + * + * @experimental This attribute is experimental and is subject to breaking changes in minor releases of `@opentelemetry/semantic-conventions`. + */ +export const ATTR_FAAS_NAME = 'faas.name'; + +/** + * The immutable version of the function being executed. + * + * @example 26 + * @example pinkfroid-00002 + * + * @note Depending on the cloud provider and platform, use: + * + * - **AWS Lambda:** The [function version](https://docs.aws.amazon.com/lambda/latest/dg/configuration-versions.html) + * (an integer represented as a decimal string). + * - **Google Cloud Run (Services):** The [revision](https://cloud.google.com/run/docs/managing/revisions) + * (i.e., the function name plus the revision suffix). + * - **Google Cloud Functions:** The value of the + * [`K_REVISION` environment variable](https://cloud.google.com/functions/docs/env-var#runtime_environment_variables_set_automatically). + * - **Azure Functions:** Not applicable. Do not set this attribute. + * + * @experimental This attribute is experimental and is subject to breaking changes in minor releases of `@opentelemetry/semantic-conventions`. + */ +export const ATTR_FAAS_VERSION = 'faas.version'; + +/** + * Unique host ID. For Cloud, this must be the instance_id assigned by the cloud provider. For non-containerized systems, this should be the `machine-id`. See the table below for the sources to use to determine the `machine-id` based on operating system. + * + * @example fdbf79e8af94cb7f9e8df36789187052 + * + * @experimental This attribute is experimental and is subject to breaking changes in minor releases of `@opentelemetry/semantic-conventions`. + */ +export const ATTR_HOST_ID = 'host.id'; + +/** + * Name of the host. On Unix systems, it may contain what the hostname command returns, or the fully qualified hostname, or another name specified by the user. + * + * @example opentelemetry-test + * + * @experimental This attribute is experimental and is subject to breaking changes in minor releases of `@opentelemetry/semantic-conventions`. + */ +export const ATTR_HOST_NAME = 'host.name'; + +/** + * Type of host. For Cloud, this must be the machine type. + * + * @example n1-standard-1 + * + * @experimental This attribute is experimental and is subject to breaking changes in minor releases of `@opentelemetry/semantic-conventions`. + */ +export const ATTR_HOST_TYPE = 'host.type'; + +/** + * The name of the cluster. + * + * @example opentelemetry-cluster + * + * @experimental This attribute is experimental and is subject to breaking changes in minor releases of `@opentelemetry/semantic-conventions`. + */ +export const ATTR_K8S_CLUSTER_NAME = 'k8s.cluster.name'; + +/** + * The string ID of the service instance. + * + * @example 627cc493-f310-47de-96bd-71410b7dec09 + * + * @note **MUST** be unique for each instance of the same `service.namespace,service.name` pair (in other words + * `service.namespace,service.name,service.instance.id` triplet **MUST** be globally unique). The ID helps to + * distinguish instances of the same service that exist at the same time (e.g. instances of a horizontally scaled + * service). + * + * Implementations, such as SDKs, are recommended to generate a random Version 1 or Version 4 [RFC + * 4122](https://www.ietf.org/rfc/rfc4122.txt) UUID, but are free to use an inherent unique ID as the source of + * this value if stability is desirable. In that case, the ID **SHOULD** be used as source of a UUID Version 5 and + * **SHOULD** use the following UUID as the namespace: `4d63009a-8d0f-11ee-aad7-4c796ed8e320`. + * + * UUIDs are typically recommended, as only an opaque value for the purposes of identifying a service instance is + * needed. Similar to what can be seen in the man page for the + * [`/etc/machine-id`](https://www.freedesktop.org/software/systemd/man/machine-id.html) file, the underlying + * data, such as pod name and namespace should be treated as confidential, being the user's choice to expose it + * or not via another resource attribute. + * + * For applications running behind an application server (like unicorn), we do not recommend using one identifier + * for all processes participating in the application. Instead, it's recommended each division (e.g. a worker + * thread in unicorn) to have its own instance.id. + * + * It's not recommended for a Collector to set `service.instance.id` if it can't unambiguously determine the + * service instance that is generating that telemetry. For instance, creating an UUID based on `pod.name` will + * likely be wrong, as the Collector might not know from which container within that pod the telemetry originated. + * However, Collectors can set the `service.instance.id` if they can unambiguously determine the service instance + * for that telemetry. This is typically the case for scraping receivers, as they know the target address and + * port. + * + * @experimental This attribute is experimental and is subject to breaking changes in minor releases of `@opentelemetry/semantic-conventions`. + */ +export const ATTR_SERVICE_INSTANCE_ID = 'service.instance.id'; + +/** + * A namespace for `service.name`. + * + * @example Shop + * + * @note A string value having a meaning that helps to distinguish a group of services, for example the team name that owns a group of services. `service.name` is expected to be unique within the same namespace. If `service.namespace` is not specified in the Resource then `service.name` is expected to be unique for all services that have no explicit namespace defined (so the empty/unspecified namespace is simply one more valid namespace). Zero-length namespace string is assumed equal to unspecified namespace. + * + * @experimental This attribute is experimental and is subject to breaking changes in minor releases of `@opentelemetry/semantic-conventions`. + */ +export const ATTR_SERVICE_NAMESPACE = 'service.namespace'; + +/** + * Enum value "aws_ec2" for attribute {@link ATTR_CLOUD_PLATFORM}. + */ +export const CLOUD_PLATFORM_VALUE_AWS_EC2 = 'aws_ec2'; + +/** + * Enum value "aws_ecs" for attribute {@link ATTR_CLOUD_PLATFORM}. + */ +export const CLOUD_PLATFORM_VALUE_AWS_ECS = 'aws_ecs'; + +/** + * Enum value "aws_eks" for attribute {@link ATTR_CLOUD_PLATFORM}. + */ +export const CLOUD_PLATFORM_VALUE_AWS_EKS = 'aws_eks'; + +/** + * Enum value "aws_elastic_beanstalk" for attribute {@link ATTR_CLOUD_PLATFORM}. + */ +export const CLOUD_PLATFORM_VALUE_AWS_ELASTIC_BEANSTALK = + 'aws_elastic_beanstalk'; + +/** + * Enum value "aws_lambda" for attribute {@link ATTR_CLOUD_PLATFORM}. + */ +export const CLOUD_PLATFORM_VALUE_AWS_LAMBDA = 'aws_lambda'; + +/** + * Enum value "aws" for attribute {@link ATTR_CLOUD_PROVIDER}. + */ +export const CLOUD_PROVIDER_VALUE_AWS = 'aws'; diff --git a/detectors/node/opentelemetry-resource-detector-azure/CHANGELOG.md b/detectors/node/opentelemetry-resource-detector-azure/CHANGELOG.md index 6ed23ed8de..d38ffa1c70 100644 --- a/detectors/node/opentelemetry-resource-detector-azure/CHANGELOG.md +++ b/detectors/node/opentelemetry-resource-detector-azure/CHANGELOG.md @@ -1,5 +1,13 @@ # Changelog +## [0.6.0](https://github.com/open-telemetry/opentelemetry-js-contrib/compare/resource-detector-azure-v0.5.0...resource-detector-azure-v0.6.0) (2025-01-20) + + +### Features + +* **detectors:** generate esm build files too ([#2636](https://github.com/open-telemetry/opentelemetry-js-contrib/issues/2636)) ([c2ad0af](https://github.com/open-telemetry/opentelemetry-js-contrib/commit/c2ad0af34e1570f3609beefc4a8d41ddfb7f8f77)) +* **detectors:** mark as side effect free ([#2663](https://github.com/open-telemetry/opentelemetry-js-contrib/issues/2663)) ([e9263a3](https://github.com/open-telemetry/opentelemetry-js-contrib/commit/e9263a36255c0016cca78bf16c4598f23519d5f1)) + ## [0.5.0](https://github.com/open-telemetry/opentelemetry-js-contrib/compare/resource-detector-azure-v0.4.0...resource-detector-azure-v0.5.0) (2024-12-18) diff --git a/detectors/node/opentelemetry-resource-detector-azure/package.json b/detectors/node/opentelemetry-resource-detector-azure/package.json index 8901bc884e..176affec50 100644 --- a/detectors/node/opentelemetry-resource-detector-azure/package.json +++ b/detectors/node/opentelemetry-resource-detector-azure/package.json @@ -1,6 +1,6 @@ { "name": "@opentelemetry/resource-detector-azure", - "version": "0.5.0", + "version": "0.6.0", "description": "OpenTelemetry SDK resource detector for Azure", "main": "build/src/index.js", "module": "build/esm/index.js", @@ -53,5 +53,6 @@ "@opentelemetry/resources": "^1.10.1", "@opentelemetry/semantic-conventions": "^1.27.0" }, - "homepage": "https://github.com/open-telemetry/opentelemetry-js-contrib/tree/main/detectors/node/opentelemetry-resource-detector-azure#readme" + "homepage": "https://github.com/open-telemetry/opentelemetry-js-contrib/tree/main/detectors/node/opentelemetry-resource-detector-azure#readme", + "sideEffects": false } diff --git a/detectors/node/opentelemetry-resource-detector-container/CHANGELOG.md b/detectors/node/opentelemetry-resource-detector-container/CHANGELOG.md index 18de726c8b..f979533c6a 100644 --- a/detectors/node/opentelemetry-resource-detector-container/CHANGELOG.md +++ b/detectors/node/opentelemetry-resource-detector-container/CHANGELOG.md @@ -1,5 +1,13 @@ # Changelog +## [0.6.0](https://github.com/open-telemetry/opentelemetry-js-contrib/compare/resource-detector-container-v0.5.3...resource-detector-container-v0.6.0) (2025-01-20) + + +### Features + +* **detectors:** generate esm build files too ([#2636](https://github.com/open-telemetry/opentelemetry-js-contrib/issues/2636)) ([c2ad0af](https://github.com/open-telemetry/opentelemetry-js-contrib/commit/c2ad0af34e1570f3609beefc4a8d41ddfb7f8f77)) +* **detectors:** mark as side effect free ([#2663](https://github.com/open-telemetry/opentelemetry-js-contrib/issues/2663)) ([e9263a3](https://github.com/open-telemetry/opentelemetry-js-contrib/commit/e9263a36255c0016cca78bf16c4598f23519d5f1)) + ## [0.5.3](https://github.com/open-telemetry/opentelemetry-js-contrib/compare/resource-detector-container-v0.5.2...resource-detector-container-v0.5.3) (2024-12-18) diff --git a/detectors/node/opentelemetry-resource-detector-container/package.json b/detectors/node/opentelemetry-resource-detector-container/package.json index 68328e7e7d..37d1514d03 100644 --- a/detectors/node/opentelemetry-resource-detector-container/package.json +++ b/detectors/node/opentelemetry-resource-detector-container/package.json @@ -1,6 +1,6 @@ { "name": "@opentelemetry/resource-detector-container", - "version": "0.5.3", + "version": "0.6.0", "description": "Opentelemetry resource detector to get container resource attributes", "main": "build/src/index.js", "module": "build/esm/index.js", @@ -56,5 +56,6 @@ "@opentelemetry/resources": "^1.10.0", "@opentelemetry/semantic-conventions": "^1.27.0" }, - "homepage": "https://github.com/open-telemetry/opentelemetry-js-contrib/tree/main/detectors/node/opentelemetry-resource-detector-container#readme" + "homepage": "https://github.com/open-telemetry/opentelemetry-js-contrib/tree/main/detectors/node/opentelemetry-resource-detector-container#readme", + "sideEffects": false } diff --git a/detectors/node/opentelemetry-resource-detector-gcp/CHANGELOG.md b/detectors/node/opentelemetry-resource-detector-gcp/CHANGELOG.md index 74ab3b4a4c..be92a6ddd9 100644 --- a/detectors/node/opentelemetry-resource-detector-gcp/CHANGELOG.md +++ b/detectors/node/opentelemetry-resource-detector-gcp/CHANGELOG.md @@ -1,5 +1,13 @@ # Changelog +## [0.33.0](https://github.com/open-telemetry/opentelemetry-js-contrib/compare/resource-detector-gcp-v0.32.0...resource-detector-gcp-v0.33.0) (2025-01-20) + + +### Features + +* **detectors:** generate esm build files too ([#2636](https://github.com/open-telemetry/opentelemetry-js-contrib/issues/2636)) ([c2ad0af](https://github.com/open-telemetry/opentelemetry-js-contrib/commit/c2ad0af34e1570f3609beefc4a8d41ddfb7f8f77)) +* **detectors:** mark as side effect free ([#2663](https://github.com/open-telemetry/opentelemetry-js-contrib/issues/2663)) ([e9263a3](https://github.com/open-telemetry/opentelemetry-js-contrib/commit/e9263a36255c0016cca78bf16c4598f23519d5f1)) + ## [0.32.0](https://github.com/open-telemetry/opentelemetry-js-contrib/compare/resource-detector-gcp-v0.31.0...resource-detector-gcp-v0.32.0) (2024-12-18) diff --git a/detectors/node/opentelemetry-resource-detector-gcp/package.json b/detectors/node/opentelemetry-resource-detector-gcp/package.json index 64f08e1251..0bc946d66d 100644 --- a/detectors/node/opentelemetry-resource-detector-gcp/package.json +++ b/detectors/node/opentelemetry-resource-detector-gcp/package.json @@ -1,6 +1,6 @@ { "name": "@opentelemetry/resource-detector-gcp", - "version": "0.32.0", + "version": "0.33.0", "description": "OpenTelemetry SDK resource detector for GCP", "main": "build/src/index.js", "module": "build/esm/index.js", @@ -61,5 +61,6 @@ "@opentelemetry/semantic-conventions": "^1.27.0", "gcp-metadata": "^6.0.0" }, - "homepage": "https://github.com/open-telemetry/opentelemetry-js-contrib/tree/main/detectors/node/opentelemetry-resource-detector-gcp#readme" + "homepage": "https://github.com/open-telemetry/opentelemetry-js-contrib/tree/main/detectors/node/opentelemetry-resource-detector-gcp#readme", + "sideEffects": false } diff --git a/detectors/node/opentelemetry-resource-detector-github/CHANGELOG.md b/detectors/node/opentelemetry-resource-detector-github/CHANGELOG.md index 0e0a9866d2..95d3defee3 100644 --- a/detectors/node/opentelemetry-resource-detector-github/CHANGELOG.md +++ b/detectors/node/opentelemetry-resource-detector-github/CHANGELOG.md @@ -1,5 +1,13 @@ # Changelog +## [0.30.0](https://github.com/open-telemetry/opentelemetry-js-contrib/compare/resource-detector-github-v0.29.0...resource-detector-github-v0.30.0) (2025-01-20) + + +### Features + +* **detectors:** generate esm build files too ([#2636](https://github.com/open-telemetry/opentelemetry-js-contrib/issues/2636)) ([c2ad0af](https://github.com/open-telemetry/opentelemetry-js-contrib/commit/c2ad0af34e1570f3609beefc4a8d41ddfb7f8f77)) +* **detectors:** mark as side effect free ([#2663](https://github.com/open-telemetry/opentelemetry-js-contrib/issues/2663)) ([e9263a3](https://github.com/open-telemetry/opentelemetry-js-contrib/commit/e9263a36255c0016cca78bf16c4598f23519d5f1)) + ## [0.29.0](https://github.com/open-telemetry/opentelemetry-js-contrib/compare/resource-detector-github-v0.28.2...resource-detector-github-v0.29.0) (2024-08-05) diff --git a/detectors/node/opentelemetry-resource-detector-github/package.json b/detectors/node/opentelemetry-resource-detector-github/package.json index 9e9e6f3c47..34a5540c7e 100644 --- a/detectors/node/opentelemetry-resource-detector-github/package.json +++ b/detectors/node/opentelemetry-resource-detector-github/package.json @@ -1,6 +1,6 @@ { "name": "@opentelemetry/resource-detector-github", - "version": "0.29.0", + "version": "0.30.0", "description": "OpenTelemetry SDK resource detector for GitHub", "main": "build/src/index.js", "module": "build/esm/index.js", @@ -57,5 +57,6 @@ "dependencies": { "@opentelemetry/resources": "^1.10.0" }, - "homepage": "https://github.com/open-telemetry/opentelemetry-js-contrib/tree/main/detectors/node/opentelemetry-resource-detector-github#readme" + "homepage": "https://github.com/open-telemetry/opentelemetry-js-contrib/tree/main/detectors/node/opentelemetry-resource-detector-github#readme", + "sideEffects": false } diff --git a/detectors/node/opentelemetry-resource-detector-instana/CHANGELOG.md b/detectors/node/opentelemetry-resource-detector-instana/CHANGELOG.md index 329a0e5cf6..7b54a399e7 100644 --- a/detectors/node/opentelemetry-resource-detector-instana/CHANGELOG.md +++ b/detectors/node/opentelemetry-resource-detector-instana/CHANGELOG.md @@ -1,5 +1,13 @@ # Changelog +## [0.18.0](https://github.com/open-telemetry/opentelemetry-js-contrib/compare/resource-detector-instana-v0.17.0...resource-detector-instana-v0.18.0) (2025-01-20) + + +### Features + +* **detectors:** generate esm build files too ([#2636](https://github.com/open-telemetry/opentelemetry-js-contrib/issues/2636)) ([c2ad0af](https://github.com/open-telemetry/opentelemetry-js-contrib/commit/c2ad0af34e1570f3609beefc4a8d41ddfb7f8f77)) +* **detectors:** mark as side effect free ([#2663](https://github.com/open-telemetry/opentelemetry-js-contrib/issues/2663)) ([e9263a3](https://github.com/open-telemetry/opentelemetry-js-contrib/commit/e9263a36255c0016cca78bf16c4598f23519d5f1)) + ## [0.17.0](https://github.com/open-telemetry/opentelemetry-js-contrib/compare/resource-detector-instana-v0.16.0...resource-detector-instana-v0.17.0) (2024-12-18) diff --git a/detectors/node/opentelemetry-resource-detector-instana/package.json b/detectors/node/opentelemetry-resource-detector-instana/package.json index 3aef268d2f..eabbe7e2ab 100644 --- a/detectors/node/opentelemetry-resource-detector-instana/package.json +++ b/detectors/node/opentelemetry-resource-detector-instana/package.json @@ -1,6 +1,6 @@ { "name": "@opentelemetry/resource-detector-instana", - "version": "0.17.0", + "version": "0.18.0", "description": "OpenTelemetry SDK resource detector for Instana", "main": "build/src/index.js", "module": "build/esm/index.js", @@ -58,5 +58,6 @@ "peerDependencies": { "@opentelemetry/api": "^1.3.0" }, - "homepage": "https://github.com/open-telemetry/opentelemetry-js-contrib/tree/main/detectors/node/opentelemetry-resource-detector-instana#readme" + "homepage": "https://github.com/open-telemetry/opentelemetry-js-contrib/tree/main/detectors/node/opentelemetry-resource-detector-instana#readme", + "sideEffects": false } diff --git a/examples/connect/tracing.js b/examples/connect/tracing.js index 7639af2925..bbc8994126 100644 --- a/examples/connect/tracing.js +++ b/examples/connect/tracing.js @@ -22,10 +22,14 @@ function log() { } module.exports = (serviceName) => { + const exporter = new CollectorTraceExporter(); const provider = new NodeTracerProvider({ resource: new Resource({ [SEMRESATTRS_SERVICE_NAME]: serviceName, }), + spanProcessors: [ + new SimpleSpanProcessor(exporter), + ], }); const connectInstrumentation = new ConnectInstrumentation(); registerInstrumentations({ @@ -37,10 +41,6 @@ module.exports = (serviceName) => { ], }); - const exporter = new CollectorTraceExporter(); - - provider.addSpanProcessor(new SimpleSpanProcessor(exporter)); - // Initialize the OpenTelemetry APIs to use the NodeTracerProvider bindings provider.register({}); return { diff --git a/examples/dns/tracer.js b/examples/dns/tracer.js index a2cee3295c..1dbc49fc73 100644 --- a/examples/dns/tracer.js +++ b/examples/dns/tracer.js @@ -11,8 +11,6 @@ const { registerInstrumentations } = require('@opentelemetry/instrumentation'); const EXPORTER = process.env.EXPORTER || ''; module.exports = (serviceName) => { - const provider = new NodeTracerProvider(); - let exporter; if (EXPORTER.toLowerCase().startsWith('z')) { exporter = new ZipkinExporter({ @@ -24,7 +22,11 @@ module.exports = (serviceName) => { }); } - provider.addSpanProcessor(new SimpleSpanProcessor(exporter)); + const provider = new NodeTracerProvider({ + spanProcessors: [ + new SimpleSpanProcessor(exporter), + ], + }); // Initialize the OpenTelemetry APIs to use the NodeTracerProvider bindings provider.register(); diff --git a/examples/express/src/tracer.ts b/examples/express/src/tracer.ts index b86e92b712..d7122604cc 100644 --- a/examples/express/src/tracer.ts +++ b/examples/express/src/tracer.ts @@ -11,10 +11,14 @@ import { ExpressInstrumentation } from '@opentelemetry/instrumentation-express'; import { HttpInstrumentation } from '@opentelemetry/instrumentation-http'; export const setupTracing = (serviceName: string) => { + const exporter = new OTLPTraceExporter({}); const provider = new NodeTracerProvider({ resource: new Resource({ [ATTR_SERVICE_NAME]: serviceName, }), + spanProcessors: [ + new SimpleSpanProcessor(exporter), + ], sampler: filterSampler(ignoreHealthCheck, new AlwaysOnSampler()), }); registerInstrumentations({ @@ -26,10 +30,6 @@ export const setupTracing = (serviceName: string) => { ], }); - const exporter = new OTLPTraceExporter({}); - - provider.addSpanProcessor(new SimpleSpanProcessor(exporter)); - // Initialize the OpenTelemetry APIs to use the NodeTracerProvider bindings provider.register(); diff --git a/examples/graphql/tracer.js b/examples/graphql/tracer.js index 82a24edde8..c718f57532 100644 --- a/examples/graphql/tracer.js +++ b/examples/graphql/tracer.js @@ -14,10 +14,12 @@ const provider = new NodeTracerProvider({ resource: new Resource({ [SEMRESATTRS_SERVICE_NAME]: 'graphql-service', }), + spanProcessors: [ + new SimpleSpanProcessor(new OTLPTraceExporter()), + new SimpleSpanProcessor(new ConsoleSpanExporter()), + ], }); -provider.addSpanProcessor(new SimpleSpanProcessor(new OTLPTraceExporter())); -provider.addSpanProcessor(new SimpleSpanProcessor(new ConsoleSpanExporter())); provider.register(); registerInstrumentations({ diff --git a/examples/grpc-census-prop/tracer.js b/examples/grpc-census-prop/tracer.js index b8241dc2b1..7fcb590fdc 100644 --- a/examples/grpc-census-prop/tracer.js +++ b/examples/grpc-census-prop/tracer.js @@ -13,11 +13,13 @@ const { GrpcInstrumentation } = require('@opentelemetry/instrumentation-grpc'); * requested propagator */ module.exports = (serviceName, binaryPropagator) => { - const provider = new NodeTracerProvider(); - - // It is recommended to use this `BatchSpanProcessor` for better performance - // and optimization, especially in production. - provider.addSpanProcessor(new SimpleSpanProcessor(new ConsoleSpanExporter())); + const provider = new NodeTracerProvider({ + spanProcessors: [ + // It is recommended to use `BatchSpanProcessor` for better performance + // and optimization, especially in production. + new SimpleSpanProcessor(new ConsoleSpanExporter()), + ], + }); if (binaryPropagator) { // Initialize the OpenTelemetry APIs to use the NodeTracerProvider bindings diff --git a/examples/hapi/tracer.js b/examples/hapi/tracer.js index 9c335d108b..cf0993eda7 100644 --- a/examples/hapi/tracer.js +++ b/examples/hapi/tracer.js @@ -12,15 +12,18 @@ const { registerInstrumentations } = require('@opentelemetry/instrumentation'); const EXPORTER = process.env.EXPORTER || ''; module.exports = (serviceName) => { - const provider = new NodeTracerProvider(); - let exporter; if (EXPORTER === 'jaeger') { exporter = new JaegerExporter({ serviceName }); } else { exporter = new ZipkinExporter({ serviceName }); } - provider.addSpanProcessor(new SimpleSpanProcessor(exporter)); + + const provider = new NodeTracerProvider({ + spanProcessors: [ + new SimpleSpanProcessor(exporter), + ], + }); // Initialize the OpenTelemetry APIs to use the NodeTracerProvider bindings provider.register(); diff --git a/examples/ioredis/tracer.js b/examples/ioredis/tracer.js index 6d18533d9a..1b0701cd76 100644 --- a/examples/ioredis/tracer.js +++ b/examples/ioredis/tracer.js @@ -7,11 +7,13 @@ const { JaegerExporter } = require('@opentelemetry/exporter-jaeger'); const { IORedisInstrumentation } = require('@opentelemetry/instrumentation-ioredis'); const { registerInstrumentations } = require('@opentelemetry/instrumentation'); -const provider = new NodeTracerProvider(); - const exporter = new JaegerExporter({ serviceName: 'ioredis-example' }); -provider.addSpanProcessor(new SimpleSpanProcessor(exporter)); +const provider = new NodeTracerProvider({ + spanProcessors: [ + new SimpleSpanProcessor(exporter), + ], +}); // Initialize the OpenTelemetry APIs to use the BasicTracer bindings provider.register(); diff --git a/examples/koa/src/tracer.ts b/examples/koa/src/tracer.ts index d0a3321a68..1a06e748c4 100644 --- a/examples/koa/src/tracer.ts +++ b/examples/koa/src/tracer.ts @@ -15,19 +15,21 @@ import { SEMRESATTRS_SERVICE_NAME } from '@opentelemetry/semantic-conventions' const EXPORTER = process.env.EXPORTER || ''; export const setupTracing = (serviceName: string) => { - const provider = new NodeTracerProvider({ - resource: new Resource({ - [SEMRESATTRS_SERVICE_NAME]: serviceName - }) - }); - let exporter; if (EXPORTER === 'jaeger') { exporter = new JaegerExporter(); } else { exporter = new ZipkinExporter(); } - provider.addSpanProcessor(new SimpleSpanProcessor(exporter)); + + const provider = new NodeTracerProvider({ + resource: new Resource({ + [SEMRESATTRS_SERVICE_NAME]: serviceName + }), + spanProcessors: [ + new SimpleSpanProcessor(exporter), + ], + }); registerInstrumentations({ instrumentations: [ diff --git a/examples/memcached/tracer.js b/examples/memcached/tracer.js index 285233199a..aecd74956b 100644 --- a/examples/memcached/tracer.js +++ b/examples/memcached/tracer.js @@ -14,10 +14,14 @@ const { SEMRESATTRS_SERVICE_NAME } = require('@opentelemetry/semantic-convention const { MemcachedInstrumentation } = require('@opentelemetry/instrumentation-memcached'); module.exports = (serviceName) => { + const exporter = new ConsoleSpanExporter(); const provider = new NodeTracerProvider({ resource: new Resource({ [SEMRESATTRS_SERVICE_NAME]: serviceName, }), + spanProcessors: [ + new SimpleSpanProcessor(exporter), + ], }); registerInstrumentations({ tracerProvider: provider, @@ -26,10 +30,6 @@ module.exports = (serviceName) => { ], }); - const exporter = new ConsoleSpanExporter(); - - provider.addSpanProcessor(new SimpleSpanProcessor(exporter)); - // Initialize the OpenTelemetry APIs to use the NodeTracerProvider bindings provider.register(); diff --git a/examples/meta-node/tracer.js b/examples/meta-node/tracer.js index 4636e30392..50cbb957c6 100644 --- a/examples/meta-node/tracer.js +++ b/examples/meta-node/tracer.js @@ -17,8 +17,11 @@ module.exports = () => { serviceName: 'basic-service', }); - const provider = new NodeTracerProvider(); - provider.addSpanProcessor(new SimpleSpanProcessor(exporter)); + const provider = new NodeTracerProvider({ + spanProcessors: [ + new SimpleSpanProcessor(exporter), + ], + }); provider.register(); registerInstrumentations({ diff --git a/examples/mongodb/src/tracer.ts b/examples/mongodb/src/tracer.ts index a9599dec35..f3d9acdc68 100644 --- a/examples/mongodb/src/tracer.ts +++ b/examples/mongodb/src/tracer.ts @@ -15,6 +15,10 @@ export const setupTracing = (serviceName: string): api.Tracer => { resource: new Resource({ [ATTR_SERVICE_NAME]: serviceName, }), + spanProcessors: [ + new SimpleSpanProcessor(new ZipkinExporter()), + new SimpleSpanProcessor(new OTLPTraceExporter()), + ], }); // Initialize the OpenTelemetry APIs to use the NodeTracerProvider bindings @@ -30,8 +34,5 @@ export const setupTracing = (serviceName: string): api.Tracer => { tracerProvider: provider, }); - provider.addSpanProcessor(new SimpleSpanProcessor(new ZipkinExporter())); - provider.addSpanProcessor(new SimpleSpanProcessor(new OTLPTraceExporter())); - return api.trace.getTracer('mongodb-example'); }; diff --git a/examples/mysql/src/tracer.ts b/examples/mysql/src/tracer.ts index 2ded0e2567..34a1746cb7 100644 --- a/examples/mysql/src/tracer.ts +++ b/examples/mysql/src/tracer.ts @@ -2,7 +2,7 @@ import opentelemetry from '@opentelemetry/api'; import { NodeTracerProvider } from '@opentelemetry/sdk-trace-node'; -import { SimpleSpanProcessor } from '@opentelemetry/sdk-trace-base'; +import { SimpleSpanProcessor, SpanProcessor } from '@opentelemetry/sdk-trace-base'; import { ZipkinExporter } from '@opentelemetry/exporter-zipkin'; import { registerInstrumentations } from '@opentelemetry/instrumentation'; import { HttpInstrumentation } from '@opentelemetry/instrumentation-http'; @@ -20,25 +20,30 @@ const EXPORTER = process.env.EXPORTER || ''; export const setupTracing = (serviceName: string) => { //metrics: - const meterProvider = new MeterProvider() const metricExporter = new OTLPMetricExporter(); const metricReader = new PeriodicExportingMetricReader({ exporter: metricExporter, exportIntervalMillis: 100, exportTimeoutMillis: 100, }); - meterProvider.addMetricReader(metricReader); + const meterProvider = new MeterProvider({ + readers: [metricReader], + }); //traces: - const tracerProvider = new NodeTracerProvider({ - resource: new Resource({ - [SEMRESATTRS_SERVICE_NAME]: serviceName, - }),}); + const spanProcessors: SpanProcessor[] = []; if (EXPORTER.toLowerCase().startsWith('z')) { - tracerProvider.addSpanProcessor(new SimpleSpanProcessor(new ZipkinExporter())); + spanProcessors.push(new SimpleSpanProcessor(new ZipkinExporter())); } + const tracerProvider = new NodeTracerProvider({ + resource: new Resource({ + [SEMRESATTRS_SERVICE_NAME]: serviceName, + }), + spanProcessors, + }); + // Initialize the OpenTelemetry APIs to use the NodeTracerProvider bindings tracerProvider.register(); diff --git a/examples/network/client.js b/examples/network/client.js index 5ce3523971..8aad8eb04e 100644 --- a/examples/network/client.js +++ b/examples/network/client.js @@ -9,13 +9,14 @@ const { registerInstrumentations } = require('@opentelemetry/instrumentation'); const { SimpleSpanProcessor, ConsoleSpanExporter } = require('@opentelemetry/sdk-trace-base'); const { JaegerExporter } = require('@opentelemetry/exporter-jaeger'); -const provider = new NodeTracerProvider(); - -provider.addSpanProcessor(new SimpleSpanProcessor(new JaegerExporter({ - serviceName: 'http-client', -}))); - -provider.addSpanProcessor(new SimpleSpanProcessor(new ConsoleSpanExporter())); +const provider = new NodeTracerProvider({ + spanProcessors: [ + new SimpleSpanProcessor(new JaegerExporter({ + serviceName: 'http-client', + })), + new SimpleSpanProcessor(new ConsoleSpanExporter()), + ], +}); provider.register(); diff --git a/examples/react-load/preact/src/web-tracer.js b/examples/react-load/preact/src/web-tracer.js index b52d436e0a..f974a91b96 100644 --- a/examples/react-load/preact/src/web-tracer.js +++ b/examples/react-load/preact/src/web-tracer.js @@ -7,13 +7,15 @@ import { OTLPTraceExporter } from '@opentelemetry/exporter-trace-otlp-http'; export default (serviceName) => { diag.setLogger(new DiagConsoleLogger(), DiagLogLevel.DEBUG); - const provider = new WebTracerProvider(); const exporter = new OTLPTraceExporter({ url: 'http://localhost:4318/v1/traces', }); - - provider.addSpanProcessor(new SimpleSpanProcessor(new ConsoleSpanExporter())); - provider.addSpanProcessor(new SimpleSpanProcessor(exporter)); + const provider = new WebTracerProvider({ + spanProcessors: [ + new SimpleSpanProcessor(new ConsoleSpanExporter()), + new SimpleSpanProcessor(exporter), + ], + }); provider.register({ contextManager: new ZoneContextManager(), diff --git a/examples/react-load/react/src/web-tracer.js b/examples/react-load/react/src/web-tracer.js index 80796da13e..d026455dff 100644 --- a/examples/react-load/react/src/web-tracer.js +++ b/examples/react-load/react/src/web-tracer.js @@ -8,19 +8,20 @@ import { Resource } from '@opentelemetry/resources'; import { SEMRESATTRS_SERVICE_NAME } from '@opentelemetry/semantic-conventions' export default (serviceName) => { + const exporter = new CollectorTraceExporter({ + url: 'http://localhost:55678/v1/trace', + }); + const provider = new WebTracerProvider({ resource: new Resource({ [SEMRESATTRS_SERVICE_NAME]: "react-load-example" }), + spanProcessors: [ + new SimpleSpanProcessor(new ConsoleSpanExporter()), + new SimpleSpanProcessor(exporter), + ], }); - const exporter = new CollectorTraceExporter({ - url: 'http://localhost:55678/v1/trace', - }); - - provider.addSpanProcessor(new SimpleSpanProcessor(new ConsoleSpanExporter())); - provider.addSpanProcessor(new SimpleSpanProcessor(exporter)); - provider.register({ contextManager: new ZoneContextManager(), }); diff --git a/examples/redis/src/tracer.ts b/examples/redis/src/tracer.ts index de70a60418..91eb03bec2 100644 --- a/examples/redis/src/tracer.ts +++ b/examples/redis/src/tracer.ts @@ -14,11 +14,6 @@ import { SEMRESATTRS_SERVICE_NAME } from '@opentelemetry/semantic-conventions'; const EXPORTER = process.env.EXPORTER || ''; export const setupTracing = (serviceName: string) => { - const provider = new NodeTracerProvider({ - resource: new Resource({ - [SEMRESATTRS_SERVICE_NAME]: serviceName, - }),}); - let exporter; if (EXPORTER.toLowerCase().startsWith('z')) { exporter = new ZipkinExporter(); @@ -26,7 +21,14 @@ export const setupTracing = (serviceName: string) => { exporter = new JaegerExporter(); } - provider.addSpanProcessor(new SimpleSpanProcessor(exporter)); + const provider = new NodeTracerProvider({ + resource: new Resource({ + [SEMRESATTRS_SERVICE_NAME]: serviceName, + }), + spanProcessors: [ + new SimpleSpanProcessor(exporter), + ] + }); // Initialize the OpenTelemetry APIs to use the NodeTracerProvider bindings provider.register(); diff --git a/examples/restify/tracer.js b/examples/restify/tracer.js index ddeecc3b8d..b2712adf03 100644 --- a/examples/restify/tracer.js +++ b/examples/restify/tracer.js @@ -28,7 +28,16 @@ const Exporter = ((exporterParam) => { })(process.env.EXPORTER); module.exports = (serviceName) => { - const provider = new NodeTracerProvider(); + const exporter = new Exporter({ + serviceName, + }); + + const provider = new NodeTracerProvider({ + spanProcessors: [ + new SimpleSpanProcessor(exporter), + ], + }); + registerInstrumentations({ tracerProvider: provider, instrumentations: [ @@ -37,12 +46,6 @@ module.exports = (serviceName) => { ], }); - const exporter = new Exporter({ - serviceName, - }); - - provider.addSpanProcessor(new SimpleSpanProcessor(exporter)); - // Initialize the OpenTelemetry APIs to use the NodeTracerProvider bindings provider.register(); diff --git a/examples/router/tracer.js b/examples/router/tracer.js index 63aaaaa0a5..73ee585060 100644 --- a/examples/router/tracer.js +++ b/examples/router/tracer.js @@ -28,7 +28,16 @@ const Exporter = ((exporterParam) => { })(process.env.EXPORTER); module.exports = (serviceName) => { - const provider = new NodeTracerProvider(); + const exporter = new Exporter({ + serviceName, + }); + + const provider = new NodeTracerProvider({ + spanProcessors: [ + new SimpleSpanProcessor(exporter), + ], + }); + registerInstrumentations({ tracerProvider: provider, instrumentations: [ @@ -37,12 +46,6 @@ module.exports = (serviceName) => { ], }); - const exporter = new Exporter({ - serviceName, - }); - - provider.addSpanProcessor(new SimpleSpanProcessor(exporter)); - // Initialize the OpenTelemetry APIs to use the NodeTracerProvider bindings provider.register(); diff --git a/examples/web/examples/document-load/index.js b/examples/web/examples/document-load/index.js index 65db02bba3..c09039b587 100644 --- a/examples/web/examples/document-load/index.js +++ b/examples/web/examples/document-load/index.js @@ -15,11 +15,12 @@ const provider = new WebTracerProvider({ resource: new Resource({ [SEMRESATTRS_SERVICE_NAME]: 'web-service-dl', }), + spanProcessors: [ + new SimpleSpanProcessor(new ConsoleSpanExporter()), + new SimpleSpanProcessor(new OTLPTraceExporter()), + ], }); -provider.addSpanProcessor(new SimpleSpanProcessor(new ConsoleSpanExporter())); -provider.addSpanProcessor(new SimpleSpanProcessor(new OTLPTraceExporter())); - provider.register({ contextManager: new ZoneContextManager(), propagator: new CompositePropagator({ diff --git a/examples/web/examples/meta/index.js b/examples/web/examples/meta/index.js index 8b9cb5ad41..90e6e4ae73 100644 --- a/examples/web/examples/meta/index.js +++ b/examples/web/examples/meta/index.js @@ -12,11 +12,12 @@ const providerWithZone = new WebTracerProvider({ resource: new Resource({ [SEMRESATTRS_SERVICE_NAME]: 'web-service-meta', }), + spanProcessors: [ + new SimpleSpanProcessor(new ConsoleSpanExporter()), + new SimpleSpanProcessor(new OTLPTraceExporter()), + ], }); -providerWithZone.addSpanProcessor(new SimpleSpanProcessor(new ConsoleSpanExporter())); -providerWithZone.addSpanProcessor(new SimpleSpanProcessor(new OTLPTraceExporter())); - providerWithZone.register({ contextManager: new ZoneContextManager(), propagator: new B3Propagator(), diff --git a/examples/web/examples/user-interaction/index.js b/examples/web/examples/user-interaction/index.js index b75cae65d5..0360f13577 100644 --- a/examples/web/examples/user-interaction/index.js +++ b/examples/web/examples/user-interaction/index.js @@ -13,11 +13,12 @@ const providerWithZone = new WebTracerProvider({ resource: new Resource({ [SEMRESATTRS_SERVICE_NAME]: 'web-service-ui', }), + spanProcessors: [ + new SimpleSpanProcessor(new ConsoleSpanExporter()), + new SimpleSpanProcessor(new OTLPTraceExporter()), + ], }); -providerWithZone.addSpanProcessor(new SimpleSpanProcessor(new ConsoleSpanExporter())); -providerWithZone.addSpanProcessor(new SimpleSpanProcessor(new OTLPTraceExporter())); - providerWithZone.register({ contextManager: new ZoneContextManager(), propagator: new B3Propagator(), diff --git a/metapackages/auto-instrumentations-node/CHANGELOG.md b/metapackages/auto-instrumentations-node/CHANGELOG.md index 52b287e091..b1e5df017f 100644 --- a/metapackages/auto-instrumentations-node/CHANGELOG.md +++ b/metapackages/auto-instrumentations-node/CHANGELOG.md @@ -1,5 +1,26 @@ # Changelog +## [0.55.3](https://github.com/open-telemetry/opentelemetry-js-contrib/compare/auto-instrumentations-node-v0.55.2...auto-instrumentations-node-v0.55.3) (2025-01-20) + + +### Bug Fixes + +* **auto-instrumentations-node:** correct typo ([#2666](https://github.com/open-telemetry/opentelemetry-js-contrib/issues/2666)) ([4cf7e6f](https://github.com/open-telemetry/opentelemetry-js-contrib/commit/4cf7e6f80640538c9b5fd36135329e050c8ab8ba)) +* **auto-instrumentations-node:** make SIGTERM shutdown test more reliable ([#2667](https://github.com/open-telemetry/opentelemetry-js-contrib/issues/2667)) ([94414a1](https://github.com/open-telemetry/opentelemetry-js-contrib/commit/94414a1515c5c3b35ada2ec5370c196d8cbc03bc)) + + +### Dependencies + +* The following workspace dependencies were updated + * dependencies + * @opentelemetry/instrumentation-aws-lambda bumped from ^0.50.1 to ^0.50.2 + * @opentelemetry/instrumentation-fastify bumped from ^0.44.0 to ^0.44.1 + * @opentelemetry/resource-detector-alibaba-cloud bumped from ^0.29.7 to ^0.30.0 + * @opentelemetry/resource-detector-aws bumped from ^1.10.0 to ^1.11.0 + * @opentelemetry/resource-detector-azure bumped from ^0.5.0 to ^0.6.0 + * @opentelemetry/resource-detector-container bumped from ^0.5.3 to ^0.6.0 + * @opentelemetry/resource-detector-gcp bumped from ^0.32.0 to ^0.33.0 + ## [0.55.2](https://github.com/open-telemetry/opentelemetry-js-contrib/compare/auto-instrumentations-node-v0.55.1...auto-instrumentations-node-v0.55.2) (2025-01-09) diff --git a/metapackages/auto-instrumentations-node/README.md b/metapackages/auto-instrumentations-node/README.md index fa0bfae5ec..00b52837cf 100644 --- a/metapackages/auto-instrumentations-node/README.md +++ b/metapackages/auto-instrumentations-node/README.md @@ -138,8 +138,10 @@ const provider = new NodeTracerProvider({ resource: new Resource({ [SEMRESATTRS_SERVICE_NAME]: 'basic-service', }), + spanProcessors: [ + new SimpleSpanProcessor(exporter), + ], }); -provider.addSpanProcessor(new SimpleSpanProcessor(exporter)); provider.register(); registerInstrumentations({ diff --git a/metapackages/auto-instrumentations-node/package.json b/metapackages/auto-instrumentations-node/package.json index c5a6b1571c..f6ab8cfdf8 100644 --- a/metapackages/auto-instrumentations-node/package.json +++ b/metapackages/auto-instrumentations-node/package.json @@ -1,6 +1,6 @@ { "name": "@opentelemetry/auto-instrumentations-node", - "version": "0.55.2", + "version": "0.55.3", "description": "Metapackage which bundles opentelemetry node core and contrib instrumentations", "author": "OpenTelemetry Authors", "homepage": "https://github.com/open-telemetry/opentelemetry-js-contrib/tree/main/metapackages/auto-instrumentations-node#readme", @@ -48,7 +48,7 @@ "dependencies": { "@opentelemetry/instrumentation": "^0.57.0", "@opentelemetry/instrumentation-amqplib": "^0.46.0", - "@opentelemetry/instrumentation-aws-lambda": "^0.50.1", + "@opentelemetry/instrumentation-aws-lambda": "^0.50.2", "@opentelemetry/instrumentation-aws-sdk": "^0.49.0", "@opentelemetry/instrumentation-bunyan": "^0.45.0", "@opentelemetry/instrumentation-cassandra-driver": "^0.45.0", @@ -57,7 +57,7 @@ "@opentelemetry/instrumentation-dataloader": "^0.16.0", "@opentelemetry/instrumentation-dns": "^0.43.0", "@opentelemetry/instrumentation-express": "^0.47.0", - "@opentelemetry/instrumentation-fastify": "^0.44.0", + "@opentelemetry/instrumentation-fastify": "^0.44.1", "@opentelemetry/instrumentation-fs": "^0.19.0", "@opentelemetry/instrumentation-generic-pool": "^0.43.0", "@opentelemetry/instrumentation-graphql": "^0.47.0", @@ -86,11 +86,11 @@ "@opentelemetry/instrumentation-tedious": "^0.18.0", "@opentelemetry/instrumentation-undici": "^0.10.0", "@opentelemetry/instrumentation-winston": "^0.44.0", - "@opentelemetry/resource-detector-alibaba-cloud": "^0.29.7", - "@opentelemetry/resource-detector-aws": "^1.10.0", - "@opentelemetry/resource-detector-azure": "^0.5.0", - "@opentelemetry/resource-detector-container": "^0.5.3", - "@opentelemetry/resource-detector-gcp": "^0.32.0", + "@opentelemetry/resource-detector-alibaba-cloud": "^0.30.0", + "@opentelemetry/resource-detector-aws": "^1.11.0", + "@opentelemetry/resource-detector-azure": "^0.6.0", + "@opentelemetry/resource-detector-container": "^0.6.0", + "@opentelemetry/resource-detector-gcp": "^0.33.0", "@opentelemetry/resources": "^1.24.0", "@opentelemetry/sdk-node": "^0.57.0" }, diff --git a/metapackages/auto-instrumentations-node/test/register.test.ts b/metapackages/auto-instrumentations-node/test/register.test.ts index 2f952541db..47917c854b 100644 --- a/metapackages/auto-instrumentations-node/test/register.test.ts +++ b/metapackages/auto-instrumentations-node/test/register.test.ts @@ -90,7 +90,7 @@ describe('Register', function () { it('shuts down the NodeSDK when SIGTERM is received', async () => { const runPromise = runWithRegister('./test-app/app-server.js'); const { child } = runPromise; - await waitForString(child.stdout!, 'Finshed request'); + await waitForString(child.stdout!, 'Finished request'); child.kill('SIGTERM'); const { stdout } = await runPromise; diff --git a/metapackages/auto-instrumentations-node/test/test-app/app-server.js b/metapackages/auto-instrumentations-node/test/test-app/app-server.js index 489b4dfb7a..61e12b089e 100644 --- a/metapackages/auto-instrumentations-node/test/test-app/app-server.js +++ b/metapackages/auto-instrumentations-node/test/test-app/app-server.js @@ -17,22 +17,34 @@ //Used in register.test.ts to mimic a JS app that stays alive like a server. const http = require('http'); -const options = { - hostname: 'example.com', - port: 80, - path: '/', - method: 'GET', -}; +// Create a local server that responds immediately +const server = http.createServer((req, res) => { + res.end('ok'); +}); + +server.listen(0, () => { + const port = server.address().port; + const req = http.request({ + hostname: 'localhost', + port: port, + path: '/', + method: 'GET', + }); -const req = http.request(options); -req.end(); -req.on('close', () => { - console.log('Finshed request'); + req.end(); + req.on('response', res => { + res.on('end', () => { + console.log('Finished request'); + }); + res.resume(); + }); }); // Make sure there is work on the event loop const handle = setInterval(() => {}, 1); + // Gracefully shut down process.on('SIGTERM', () => { clearInterval(handle); + server.close(); }); diff --git a/metapackages/auto-instrumentations-web/README.md b/metapackages/auto-instrumentations-web/README.md index 864e031709..e51b806e84 100644 --- a/metapackages/auto-instrumentations-web/README.md +++ b/metapackages/auto-instrumentations-web/README.md @@ -26,8 +26,11 @@ const exporter = new CollectorTraceExporter({ serviceName: 'auto-instrumentations-web', }); -const provider = new WebTracerProvider(); -provider.addSpanProcessor(new SimpleSpanProcessor(exporter)); +const provider = new WebTracerProvider({ + spanProcessors: [ + new SimpleSpanProcessor(exporter), + ], +}); provider.register({ contextManager: new ZoneContextManager(), propagator: new B3Propagator(), diff --git a/package-lock.json b/package-lock.json index 616578c16c..064e56329f 100644 --- a/package-lock.json +++ b/package-lock.json @@ -42,7 +42,7 @@ }, "detectors/node/opentelemetry-resource-detector-alibaba-cloud": { "name": "@opentelemetry/resource-detector-alibaba-cloud", - "version": "0.29.7", + "version": "0.30.0", "license": "Apache-2.0", "dependencies": { "@opentelemetry/core": "^1.26.0", @@ -92,7 +92,7 @@ }, "detectors/node/opentelemetry-resource-detector-aws": { "name": "@opentelemetry/resource-detector-aws", - "version": "1.10.0", + "version": "1.11.0", "license": "Apache-2.0", "dependencies": { "@opentelemetry/core": "^1.0.0", @@ -144,7 +144,7 @@ }, "detectors/node/opentelemetry-resource-detector-azure": { "name": "@opentelemetry/resource-detector-azure", - "version": "0.5.0", + "version": "0.6.0", "license": "Apache-2.0", "dependencies": { "@opentelemetry/core": "^1.25.1", @@ -194,7 +194,7 @@ }, "detectors/node/opentelemetry-resource-detector-container": { "name": "@opentelemetry/resource-detector-container", - "version": "0.5.3", + "version": "0.6.0", "license": "Apache-2.0", "dependencies": { "@opentelemetry/core": "^1.26.0", @@ -246,7 +246,7 @@ }, "detectors/node/opentelemetry-resource-detector-gcp": { "name": "@opentelemetry/resource-detector-gcp", - "version": "0.32.0", + "version": "0.33.0", "license": "Apache-2.0", "dependencies": { "@opentelemetry/core": "^1.0.0", @@ -297,7 +297,7 @@ }, "detectors/node/opentelemetry-resource-detector-github": { "name": "@opentelemetry/resource-detector-github", - "version": "0.29.0", + "version": "0.30.0", "license": "Apache-2.0", "dependencies": { "@opentelemetry/resources": "^1.10.0" @@ -343,7 +343,7 @@ }, "detectors/node/opentelemetry-resource-detector-instana": { "name": "@opentelemetry/resource-detector-instana", - "version": "0.17.0", + "version": "0.18.0", "license": "Apache-2.0", "dependencies": { "@opentelemetry/resources": "^1.10.0", @@ -449,12 +449,12 @@ }, "metapackages/auto-instrumentations-node": { "name": "@opentelemetry/auto-instrumentations-node", - "version": "0.55.2", + "version": "0.55.3", "license": "Apache-2.0", "dependencies": { "@opentelemetry/instrumentation": "^0.57.0", "@opentelemetry/instrumentation-amqplib": "^0.46.0", - "@opentelemetry/instrumentation-aws-lambda": "^0.50.1", + "@opentelemetry/instrumentation-aws-lambda": "^0.50.2", "@opentelemetry/instrumentation-aws-sdk": "^0.49.0", "@opentelemetry/instrumentation-bunyan": "^0.45.0", "@opentelemetry/instrumentation-cassandra-driver": "^0.45.0", @@ -463,7 +463,7 @@ "@opentelemetry/instrumentation-dataloader": "^0.16.0", "@opentelemetry/instrumentation-dns": "^0.43.0", "@opentelemetry/instrumentation-express": "^0.47.0", - "@opentelemetry/instrumentation-fastify": "^0.44.0", + "@opentelemetry/instrumentation-fastify": "^0.44.1", "@opentelemetry/instrumentation-fs": "^0.19.0", "@opentelemetry/instrumentation-generic-pool": "^0.43.0", "@opentelemetry/instrumentation-graphql": "^0.47.0", @@ -492,11 +492,11 @@ "@opentelemetry/instrumentation-tedious": "^0.18.0", "@opentelemetry/instrumentation-undici": "^0.10.0", "@opentelemetry/instrumentation-winston": "^0.44.0", - "@opentelemetry/resource-detector-alibaba-cloud": "^0.29.7", - "@opentelemetry/resource-detector-aws": "^1.10.0", - "@opentelemetry/resource-detector-azure": "^0.5.0", - "@opentelemetry/resource-detector-container": "^0.5.3", - "@opentelemetry/resource-detector-gcp": "^0.32.0", + "@opentelemetry/resource-detector-alibaba-cloud": "^0.30.0", + "@opentelemetry/resource-detector-aws": "^1.11.0", + "@opentelemetry/resource-detector-azure": "^0.6.0", + "@opentelemetry/resource-detector-container": "^0.6.0", + "@opentelemetry/resource-detector-gcp": "^0.33.0", "@opentelemetry/resources": "^1.24.0", "@opentelemetry/sdk-node": "^0.57.0" }, @@ -34221,12 +34221,12 @@ } }, "node_modules/undici": { - "version": "6.11.1", - "resolved": "https://registry.npmjs.org/undici/-/undici-6.11.1.tgz", - "integrity": "sha512-KyhzaLJnV1qa3BSHdj4AZ2ndqI0QWPxYzaIOio0WzcEJB9gvuysprJSLtpvc2D9mhR9jPDUk7xlJlZbH2KR5iw==", + "version": "6.21.1", + "resolved": "https://registry.npmjs.org/undici/-/undici-6.21.1.tgz", + "integrity": "sha512-q/1rj5D0/zayJB2FraXdaWxbhWiNKDvu8naDT2dl1yTlvJp4BLtOcp2a5BvgGNQpYYJzau7tf1WgKv3b+7mqpQ==", "dev": true, "engines": { - "node": ">=18.0" + "node": ">=18.17" } }, "node_modules/undici-types": { @@ -37374,7 +37374,7 @@ "semver": "^7.6.0", "test-all-versions": "6.1.0", "typescript": "4.4.4", - "undici": "6.11.1" + "undici": "6.21.1" }, "engines": { "node": ">=14" @@ -37413,7 +37413,7 @@ }, "plugins/node/opentelemetry-instrumentation-aws-lambda": { "name": "@opentelemetry/instrumentation-aws-lambda", - "version": "0.50.1", + "version": "0.50.2", "license": "Apache-2.0", "dependencies": { "@opentelemetry/instrumentation": "^0.57.0", @@ -37830,7 +37830,7 @@ }, "plugins/node/opentelemetry-instrumentation-fastify": { "name": "@opentelemetry/instrumentation-fastify", - "version": "0.44.0", + "version": "0.44.1", "license": "Apache-2.0", "dependencies": { "@opentelemetry/core": "^1.8.0", @@ -38732,7 +38732,7 @@ "dependencies": { "@opentelemetry/core": "^1.26.0", "@opentelemetry/instrumentation": "^0.57.0", - "@opentelemetry/semantic-conventions": "1.27.0", + "@opentelemetry/semantic-conventions": "^1.27.0", "@opentelemetry/sql-common": "^0.40.1", "@types/pg": "8.6.1", "@types/pg-pool": "2.0.6" @@ -38763,14 +38763,6 @@ "@opentelemetry/api": "^1.3.0" } }, - "plugins/node/opentelemetry-instrumentation-pg/node_modules/@opentelemetry/semantic-conventions": { - "version": "1.27.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/semantic-conventions/-/semantic-conventions-1.27.0.tgz", - "integrity": "sha512-sAay1RrB+ONOem0OZanAR1ZI/k7yDpnOQSQmTMuGImUQb2y8EbSaCJ94FQluM74xoU03vlb2d2U90hZluL6nQg==", - "engines": { - "node": ">=14" - } - }, "plugins/node/opentelemetry-instrumentation-pg/node_modules/@types/mocha": { "version": "7.0.2", "resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-7.0.2.tgz", @@ -46874,7 +46866,7 @@ "@opentelemetry/api": "^1.4.1", "@opentelemetry/instrumentation": "^0.57.0", "@opentelemetry/instrumentation-amqplib": "^0.46.0", - "@opentelemetry/instrumentation-aws-lambda": "^0.50.1", + "@opentelemetry/instrumentation-aws-lambda": "^0.50.2", "@opentelemetry/instrumentation-aws-sdk": "^0.49.0", "@opentelemetry/instrumentation-bunyan": "^0.45.0", "@opentelemetry/instrumentation-cassandra-driver": "^0.45.0", @@ -46883,7 +46875,7 @@ "@opentelemetry/instrumentation-dataloader": "^0.16.0", "@opentelemetry/instrumentation-dns": "^0.43.0", "@opentelemetry/instrumentation-express": "^0.47.0", - "@opentelemetry/instrumentation-fastify": "^0.44.0", + "@opentelemetry/instrumentation-fastify": "^0.44.1", "@opentelemetry/instrumentation-fs": "^0.19.0", "@opentelemetry/instrumentation-generic-pool": "^0.43.0", "@opentelemetry/instrumentation-graphql": "^0.47.0", @@ -46912,11 +46904,11 @@ "@opentelemetry/instrumentation-tedious": "^0.18.0", "@opentelemetry/instrumentation-undici": "^0.10.0", "@opentelemetry/instrumentation-winston": "^0.44.0", - "@opentelemetry/resource-detector-alibaba-cloud": "^0.29.7", - "@opentelemetry/resource-detector-aws": "^1.10.0", - "@opentelemetry/resource-detector-azure": "^0.5.0", - "@opentelemetry/resource-detector-container": "^0.5.3", - "@opentelemetry/resource-detector-gcp": "^0.32.0", + "@opentelemetry/resource-detector-alibaba-cloud": "^0.30.0", + "@opentelemetry/resource-detector-aws": "^1.11.0", + "@opentelemetry/resource-detector-azure": "^0.6.0", + "@opentelemetry/resource-detector-container": "^0.6.0", + "@opentelemetry/resource-detector-gcp": "^0.33.0", "@opentelemetry/resources": "^1.24.0", "@opentelemetry/sdk-node": "^0.57.0", "@types/mocha": "7.0.2", @@ -48807,7 +48799,7 @@ "@opentelemetry/instrumentation": "^0.57.0", "@opentelemetry/sdk-trace-base": "^1.8.0", "@opentelemetry/sdk-trace-node": "^1.8.0", - "@opentelemetry/semantic-conventions": "1.27.0", + "@opentelemetry/semantic-conventions": "^1.27.0", "@opentelemetry/sql-common": "^0.40.1", "@types/mocha": "7.0.2", "@types/node": "18.18.14", @@ -48825,11 +48817,6 @@ "typescript": "4.4.4" }, "dependencies": { - "@opentelemetry/semantic-conventions": { - "version": "1.27.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/semantic-conventions/-/semantic-conventions-1.27.0.tgz", - "integrity": "sha512-sAay1RrB+ONOem0OZanAR1ZI/k7yDpnOQSQmTMuGImUQb2y8EbSaCJ94FQluM74xoU03vlb2d2U90hZluL6nQg==" - }, "@types/mocha": { "version": "7.0.2", "resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-7.0.2.tgz", @@ -49846,7 +49833,7 @@ "semver": "^7.6.0", "test-all-versions": "6.1.0", "typescript": "4.4.4", - "undici": "6.11.1" + "undici": "6.21.1" }, "dependencies": { "@types/mocha": { @@ -69473,9 +69460,9 @@ } }, "undici": { - "version": "6.11.1", - "resolved": "https://registry.npmjs.org/undici/-/undici-6.11.1.tgz", - "integrity": "sha512-KyhzaLJnV1qa3BSHdj4AZ2ndqI0QWPxYzaIOio0WzcEJB9gvuysprJSLtpvc2D9mhR9jPDUk7xlJlZbH2KR5iw==", + "version": "6.21.1", + "resolved": "https://registry.npmjs.org/undici/-/undici-6.21.1.tgz", + "integrity": "sha512-q/1rj5D0/zayJB2FraXdaWxbhWiNKDvu8naDT2dl1yTlvJp4BLtOcp2a5BvgGNQpYYJzau7tf1WgKv3b+7mqpQ==", "dev": true }, "undici-types": { diff --git a/packages/opentelemetry-test-utils/src/instrumentations/otel-default-provider.ts b/packages/opentelemetry-test-utils/src/instrumentations/otel-default-provider.ts index 7882b72c9a..a6c4d1ddd9 100644 --- a/packages/opentelemetry-test-utils/src/instrumentations/otel-default-provider.ts +++ b/packages/opentelemetry-test-utils/src/instrumentations/otel-default-provider.ts @@ -30,19 +30,23 @@ import { export const registerInstrumentationTestingProvider = ( config?: NodeTracerConfig ): NodeTracerProvider => { - const otelTestingProvider = new NodeTracerProvider(config); + const spanProcessors = config?.spanProcessors + ? [...config.spanProcessors] + : []; setTestMemoryExporter(new InMemorySpanExporter()); - otelTestingProvider.addSpanProcessor( - new SimpleSpanProcessor(getTestMemoryExporter()!) - ); + + spanProcessors.push(new SimpleSpanProcessor(getTestMemoryExporter()!)); if (process.env.OTEL_EXPORTER_JAEGER_AGENT_HOST) { - otelTestingProvider.addSpanProcessor( - new SimpleSpanProcessor(new JaegerExporter()) - ); + spanProcessors.push(new SimpleSpanProcessor(new JaegerExporter())); } + const otelTestingProvider = new NodeTracerProvider({ + ...config, + spanProcessors, + }); + otelTestingProvider.register(); return otelTestingProvider; }; diff --git a/plugins/node/instrumentation-cucumber/.tav.yml b/plugins/node/instrumentation-cucumber/.tav.yml index 0a9cf7031d..e00a9aeeb5 100644 --- a/plugins/node/instrumentation-cucumber/.tav.yml +++ b/plugins/node/instrumentation-cucumber/.tav.yml @@ -9,3 +9,8 @@ mode: latest-minors node: '>=18' commands: npm test + - versions: + include: '^11.0.0' + mode: latest-minors + node: '>=18' + commands: npm test diff --git a/plugins/node/instrumentation-cucumber/src/instrumentation.ts b/plugins/node/instrumentation-cucumber/src/instrumentation.ts index 62341ad990..1c8e73de19 100644 --- a/plugins/node/instrumentation-cucumber/src/instrumentation.ts +++ b/plugins/node/instrumentation-cucumber/src/instrumentation.ts @@ -47,7 +47,7 @@ type Cucumber = typeof cucumber; type Hook = (typeof hooks)[number]; type Step = (typeof steps)[number]; -const supportedVersions = ['>=8.0.0 <11']; +const supportedVersions = ['>=8.0.0 <12']; export class CucumberInstrumentation extends InstrumentationBase { private module: Cucumber | undefined; diff --git a/plugins/node/instrumentation-cucumber/test/cucumber.test.ts b/plugins/node/instrumentation-cucumber/test/cucumber.test.ts index deffbef31d..2ffdcae627 100644 --- a/plugins/node/instrumentation-cucumber/test/cucumber.test.ts +++ b/plugins/node/instrumentation-cucumber/test/cucumber.test.ts @@ -53,14 +53,14 @@ import { import { PassThrough } from 'stream'; describe('CucumberInstrumentation', () => { + const memoryExporter = new InMemorySpanExporter(); + const spanProcessor = new SimpleSpanProcessor(memoryExporter); const provider = new NodeTracerProvider({ resource: new Resource({ [SEMRESATTRS_SERVICE_NAME]: 'CucumberInstrumentation', }), + spanProcessors: [spanProcessor], }); - const memoryExporter = new InMemorySpanExporter(); - const spanProcessor = new SimpleSpanProcessor(memoryExporter); - provider.addSpanProcessor(spanProcessor); const contextManager = new AsyncHooksContextManager().enable(); before(() => { diff --git a/plugins/node/instrumentation-dataloader/test/dataloader.test.ts b/plugins/node/instrumentation-dataloader/test/dataloader.test.ts index 9686c21d2e..319bde4d03 100644 --- a/plugins/node/instrumentation-dataloader/test/dataloader.test.ts +++ b/plugins/node/instrumentation-dataloader/test/dataloader.test.ts @@ -37,12 +37,13 @@ describe('DataloaderInstrumentation', () => { let contextManager: AsyncHooksContextManager; const memoryExporter = new InMemorySpanExporter(); - const provider = new NodeTracerProvider(); + const provider = new NodeTracerProvider({ + spanProcessors: [new SimpleSpanProcessor(memoryExporter)], + }); const tracer = provider.getTracer('default'); instrumentation.setTracerProvider(provider); extraInstrumentation.setTracerProvider(provider); - provider.addSpanProcessor(new SimpleSpanProcessor(memoryExporter)); beforeEach(async () => { instrumentation.enable(); diff --git a/plugins/node/instrumentation-fs/test/fs.test.ts b/plugins/node/instrumentation-fs/test/fs.test.ts index 4e639ceb82..5383c9f1ef 100644 --- a/plugins/node/instrumentation-fs/test/fs.test.ts +++ b/plugins/node/instrumentation-fs/test/fs.test.ts @@ -58,10 +58,11 @@ const pluginConfig = { createHook, endHook, }; -const provider = new BasicTracerProvider(); -const tracer = provider.getTracer('default'); const memoryExporter = new InMemorySpanExporter(); -provider.addSpanProcessor(new SimpleSpanProcessor(memoryExporter)); +const provider = new BasicTracerProvider({ + spanProcessors: [new SimpleSpanProcessor(memoryExporter)], +}); +const tracer = provider.getTracer('default'); describe('fs instrumentation', () => { let contextManager: AsyncHooksContextManager; diff --git a/plugins/node/instrumentation-fs/test/fsHooks.test.ts b/plugins/node/instrumentation-fs/test/fsHooks.test.ts index bdffab00e8..7fa61ac0af 100644 --- a/plugins/node/instrumentation-fs/test/fsHooks.test.ts +++ b/plugins/node/instrumentation-fs/test/fsHooks.test.ts @@ -37,9 +37,10 @@ const pluginConfig = { endHook, }; -const provider = new BasicTracerProvider(); const memoryExporter = new InMemorySpanExporter(); -provider.addSpanProcessor(new SimpleSpanProcessor(memoryExporter)); +const provider = new BasicTracerProvider({ + spanProcessors: [new SimpleSpanProcessor(memoryExporter)], +}); const assertNotHookError = (err?: Error | null) => { assert.ok( diff --git a/plugins/node/instrumentation-fs/test/fsPromises.test.ts b/plugins/node/instrumentation-fs/test/fsPromises.test.ts index 0400f57ee7..73db46937a 100644 --- a/plugins/node/instrumentation-fs/test/fsPromises.test.ts +++ b/plugins/node/instrumentation-fs/test/fsPromises.test.ts @@ -37,10 +37,11 @@ const endHook = sinon.spy((fnName, { args, span }) => { const pluginConfig = { endHook, }; -const provider = new BasicTracerProvider(); -const tracer = provider.getTracer('default'); const memoryExporter = new InMemorySpanExporter(); -provider.addSpanProcessor(new SimpleSpanProcessor(memoryExporter)); +const provider = new BasicTracerProvider({ + spanProcessors: [new SimpleSpanProcessor(memoryExporter)], +}); +const tracer = provider.getTracer('default'); describe('fs/promises instrumentation', () => { let contextManager: AsyncHooksContextManager; diff --git a/plugins/node/instrumentation-fs/test/fsPromisesHooks.test.ts b/plugins/node/instrumentation-fs/test/fsPromisesHooks.test.ts index be3db71202..2d90bf8cce 100644 --- a/plugins/node/instrumentation-fs/test/fsPromisesHooks.test.ts +++ b/plugins/node/instrumentation-fs/test/fsPromisesHooks.test.ts @@ -37,9 +37,10 @@ const pluginConfig = { endHook, }; -const provider = new BasicTracerProvider(); const memoryExporter = new InMemorySpanExporter(); -provider.addSpanProcessor(new SimpleSpanProcessor(memoryExporter)); +const provider = new BasicTracerProvider({ + spanProcessors: [new SimpleSpanProcessor(memoryExporter)], +}); const assertNotHookError = (err?: Error | null) => { assert.ok( diff --git a/plugins/node/instrumentation-fs/test/parent.test.ts b/plugins/node/instrumentation-fs/test/parent.test.ts index 903e7e48e8..0619b7ed19 100644 --- a/plugins/node/instrumentation-fs/test/parent.test.ts +++ b/plugins/node/instrumentation-fs/test/parent.test.ts @@ -25,9 +25,10 @@ import type { FsInstrumentationConfig } from '../src/types'; import * as api from '@opentelemetry/api'; import { AsyncHooksContextManager } from '@opentelemetry/context-async-hooks'; -const provider = new BasicTracerProvider(); const memoryExporter = new InMemorySpanExporter(); -provider.addSpanProcessor(new SimpleSpanProcessor(memoryExporter)); +const provider = new BasicTracerProvider({ + spanProcessors: [new SimpleSpanProcessor(memoryExporter)], +}); const tracer = provider.getTracer('default'); diff --git a/plugins/node/instrumentation-runtime-node/test/event_loop_delay.test.ts b/plugins/node/instrumentation-runtime-node/test/event_loop_delay.test.ts index 9571ff23c6..d77bfbdcfe 100644 --- a/plugins/node/instrumentation-runtime-node/test/event_loop_delay.test.ts +++ b/plugins/node/instrumentation-runtime-node/test/event_loop_delay.test.ts @@ -27,8 +27,9 @@ describe(`${ConventionalNamePrefix.NodeJs}.eventloop`, function () { beforeEach(() => { metricReader = new TestMetricReader(); - meterProvider = new MeterProvider(); - meterProvider.addMetricReader(metricReader); + meterProvider = new MeterProvider({ + readers: [metricReader], + }); }); for (const metricName in metricNames) { diff --git a/plugins/node/instrumentation-runtime-node/test/event_loop_time.test.ts b/plugins/node/instrumentation-runtime-node/test/event_loop_time.test.ts index ac9a672ab9..7ee96150f3 100644 --- a/plugins/node/instrumentation-runtime-node/test/event_loop_time.test.ts +++ b/plugins/node/instrumentation-runtime-node/test/event_loop_time.test.ts @@ -29,8 +29,9 @@ describe(`${ConventionalNamePrefix.NodeJs}.${ATTR_NODEJS_EVENT_LOOP_TIME}`, func beforeEach(() => { metricReader = new TestMetricReader(); - meterProvider = new MeterProvider(); - meterProvider.addMetricReader(metricReader); + meterProvider = new MeterProvider({ + readers: [metricReader], + }); }); it('should not export before being enabled', async function () { diff --git a/plugins/node/instrumentation-runtime-node/test/event_loop_utilization.test.ts b/plugins/node/instrumentation-runtime-node/test/event_loop_utilization.test.ts index e434557f20..3200dd0392 100644 --- a/plugins/node/instrumentation-runtime-node/test/event_loop_utilization.test.ts +++ b/plugins/node/instrumentation-runtime-node/test/event_loop_utilization.test.ts @@ -29,8 +29,9 @@ describe(`${ConventionalNamePrefix.NodeJs}.${ATTR_NODEJS_EVENT_LOOP_UTILIZATION} beforeEach(() => { metricReader = new TestMetricReader(); - meterProvider = new MeterProvider(); - meterProvider.addMetricReader(metricReader); + meterProvider = new MeterProvider({ + readers: [metricReader], + }); }); it('should not export before being enabled', async function () { diff --git a/plugins/node/instrumentation-runtime-node/test/heap_space_and_used.test.ts b/plugins/node/instrumentation-runtime-node/test/heap_space_and_used.test.ts index 177834332f..43aae14344 100644 --- a/plugins/node/instrumentation-runtime-node/test/heap_space_and_used.test.ts +++ b/plugins/node/instrumentation-runtime-node/test/heap_space_and_used.test.ts @@ -31,8 +31,9 @@ describe('nodejs.heap_space', function () { beforeEach(() => { metricReader = new TestMetricReader(); - meterProvider = new MeterProvider(); - meterProvider.addMetricReader(metricReader); + meterProvider = new MeterProvider({ + readers: [metricReader], + }); }); for (const metricName in metricNames) { diff --git a/plugins/node/instrumentation-runtime-node/test/instrumentation.test.ts b/plugins/node/instrumentation-runtime-node/test/instrumentation.test.ts index 34de947e15..f3ccf82a0e 100644 --- a/plugins/node/instrumentation-runtime-node/test/instrumentation.test.ts +++ b/plugins/node/instrumentation-runtime-node/test/instrumentation.test.ts @@ -27,8 +27,9 @@ describe('instrumentation', function () { beforeEach(() => { metricReader = new TestMetricReader(); - meterProvider = new MeterProvider(); - meterProvider.addMetricReader(metricReader); + meterProvider = new MeterProvider({ + readers: [metricReader], + }); }); it('should not export before being enabled', async function () { diff --git a/plugins/node/instrumentation-tedious/test/instrumentation.test.ts b/plugins/node/instrumentation-tedious/test/instrumentation.test.ts index f9419cc4c6..d20d16cad7 100644 --- a/plugins/node/instrumentation-tedious/test/instrumentation.test.ts +++ b/plugins/node/instrumentation-tedious/test/instrumentation.test.ts @@ -89,10 +89,12 @@ describe('tedious', () => { let tedious: any; let contextManager: AsyncHooksContextManager; let connection: Connection; - const provider = new BasicTracerProvider(); + const memoryExporter = new InMemorySpanExporter(); + const provider = new BasicTracerProvider({ + spanProcessors: [new SimpleSpanProcessor(memoryExporter)], + }); const shouldTest = process.env.RUN_MSSQL_TESTS; // For CI: assumes local db is already available const shouldTestLocally = process.env.RUN_MSSQL_TESTS_LOCAL; // For local: spins up local db via docker - const memoryExporter = new InMemorySpanExporter(); before(function (done) { if (!(shouldTest || shouldTestLocally) || incompatVersions) { @@ -101,7 +103,6 @@ describe('tedious', () => { this.test!.parent!.pending = true; this.skip(); } - provider.addSpanProcessor(new SimpleSpanProcessor(memoryExporter)); if (shouldTestLocally) { testUtils.startDocker('mssql'); // wait 15 seconds for docker container to start diff --git a/plugins/node/instrumentation-undici/README.md b/plugins/node/instrumentation-undici/README.md index e0d9f8d158..154a915b63 100644 --- a/plugins/node/instrumentation-undici/README.md +++ b/plugins/node/instrumentation-undici/README.md @@ -35,9 +35,12 @@ const { } = require('@opentelemetry/sdk-trace-node'); const { registerInstrumentations } = require('@opentelemetry/instrumentation'); -const provider = new NodeTracerProvider(); +const provider = new NodeTracerProvider({ + spanProcessors: [ + new SimpleSpanProcessor(new ConsoleSpanExporter()), + ], +}); -provider.addSpanProcessor(new SimpleSpanProcessor(new ConsoleSpanExporter())); provider.register(); registerInstrumentations({ diff --git a/plugins/node/instrumentation-undici/package.json b/plugins/node/instrumentation-undici/package.json index 42b20045ed..9974b898ef 100644 --- a/plugins/node/instrumentation-undici/package.json +++ b/plugins/node/instrumentation-undici/package.json @@ -51,7 +51,7 @@ "semver": "^7.6.0", "test-all-versions": "6.1.0", "typescript": "4.4.4", - "undici": "6.11.1" + "undici": "6.21.1" }, "peerDependencies": { "@opentelemetry/api": "^1.7.0" diff --git a/plugins/node/instrumentation-undici/test/fetch.test.ts b/plugins/node/instrumentation-undici/test/fetch.test.ts index 9ef4e90767..863f74b6c8 100644 --- a/plugins/node/instrumentation-undici/test/fetch.test.ts +++ b/plugins/node/instrumentation-undici/test/fetch.test.ts @@ -42,8 +42,9 @@ describe('UndiciInstrumentation `fetch` tests', function () { const hostname = 'localhost'; const mockServer = new MockServer(); const memoryExporter = new InMemorySpanExporter(); - const provider = new NodeTracerProvider(); - provider.addSpanProcessor(new SimpleSpanProcessor(memoryExporter)); + const provider = new NodeTracerProvider({ + spanProcessors: [new SimpleSpanProcessor(memoryExporter)], + }); before(function (done) { // Do not test if the `fetch` global API is not available diff --git a/plugins/node/instrumentation-undici/test/metrics.test.ts b/plugins/node/instrumentation-undici/test/metrics.test.ts index a903698385..de7a9ad5c7 100644 --- a/plugins/node/instrumentation-undici/test/metrics.test.ts +++ b/plugins/node/instrumentation-undici/test/metrics.test.ts @@ -37,12 +37,13 @@ describe('UndiciInstrumentation metrics tests', function () { const hostname = 'localhost'; const mockServer = new MockServer(); const provider = new NodeTracerProvider(); - const meterProvider = new MeterProvider(); const metricsMemoryExporter = new InMemoryMetricExporter( AggregationTemporality.DELTA ); const metricReader = new MockMetricsReader(metricsMemoryExporter); - meterProvider.addMetricReader(metricReader); + const meterProvider = new MeterProvider({ + readers: [metricReader], + }); before(function (done) { // Do not test if the `fetch` global API is not available diff --git a/plugins/node/instrumentation-undici/test/undici.test.ts b/plugins/node/instrumentation-undici/test/undici.test.ts index effa2b3a3f..5a0757460c 100644 --- a/plugins/node/instrumentation-undici/test/undici.test.ts +++ b/plugins/node/instrumentation-undici/test/undici.test.ts @@ -68,8 +68,9 @@ describe('UndiciInstrumentation `undici` tests', function () { const hostname = 'localhost'; const mockServer = new MockServer(); const memoryExporter = new InMemorySpanExporter(); - const provider = new NodeTracerProvider(); - provider.addSpanProcessor(new SimpleSpanProcessor(memoryExporter)); + const provider = new NodeTracerProvider({ + spanProcessors: [new SimpleSpanProcessor(memoryExporter)], + }); before(function (done) { // Load `undici`. It may fail if nodejs version is <18 because the module uses diff --git a/plugins/node/opentelemetry-instrumentation-aws-lambda/CHANGELOG.md b/plugins/node/opentelemetry-instrumentation-aws-lambda/CHANGELOG.md index e7a85d8e91..1be266e30d 100644 --- a/plugins/node/opentelemetry-instrumentation-aws-lambda/CHANGELOG.md +++ b/plugins/node/opentelemetry-instrumentation-aws-lambda/CHANGELOG.md @@ -1,5 +1,12 @@ # Changelog +## [0.50.2](https://github.com/open-telemetry/opentelemetry-js-contrib/compare/instrumentation-aws-lambda-v0.50.1...instrumentation-aws-lambda-v0.50.2) (2025-01-20) + + +### Bug Fixes + +* **instrumentation-aws-lambda:** do not import from semantic-conventions incubating entry-point ([#2670](https://github.com/open-telemetry/opentelemetry-js-contrib/issues/2670)) ([0db649f](https://github.com/open-telemetry/opentelemetry-js-contrib/commit/0db649f8c59b6b4df455dd0012d735ce9b0118af)) + ## [0.50.1](https://github.com/open-telemetry/opentelemetry-js-contrib/compare/instrumentation-aws-lambda-v0.50.0...instrumentation-aws-lambda-v0.50.1) (2025-01-09) diff --git a/plugins/node/opentelemetry-instrumentation-aws-lambda/package.json b/plugins/node/opentelemetry-instrumentation-aws-lambda/package.json index 90a9617f6d..554575601b 100644 --- a/plugins/node/opentelemetry-instrumentation-aws-lambda/package.json +++ b/plugins/node/opentelemetry-instrumentation-aws-lambda/package.json @@ -1,6 +1,6 @@ { "name": "@opentelemetry/instrumentation-aws-lambda", - "version": "0.50.1", + "version": "0.50.2", "description": "OpenTelemetry instrumentation for AWS Lambda function invocations", "main": "build/src/index.js", "types": "build/src/index.d.ts", diff --git a/plugins/node/opentelemetry-instrumentation-aws-lambda/src/instrumentation.ts b/plugins/node/opentelemetry-instrumentation-aws-lambda/src/instrumentation.ts index efc336d0f1..352cb64ae5 100644 --- a/plugins/node/opentelemetry-instrumentation-aws-lambda/src/instrumentation.ts +++ b/plugins/node/opentelemetry-instrumentation-aws-lambda/src/instrumentation.ts @@ -45,7 +45,7 @@ import { SEMRESATTRS_CLOUD_ACCOUNT_ID, SEMRESATTRS_FAAS_ID, } from '@opentelemetry/semantic-conventions'; -import { ATTR_FAAS_COLDSTART } from '@opentelemetry/semantic-conventions/incubating'; +import { ATTR_FAAS_COLDSTART } from './semconv'; import { APIGatewayProxyEventHeaders, diff --git a/archive/opentelemetry-browser-extension-autoinjection/src/ui/SaveButton.tsx b/plugins/node/opentelemetry-instrumentation-aws-lambda/src/semconv.ts similarity index 53% rename from archive/opentelemetry-browser-extension-autoinjection/src/ui/SaveButton.tsx rename to plugins/node/opentelemetry-instrumentation-aws-lambda/src/semconv.ts index 2a3836b9a8..0bff224acd 100644 --- a/archive/opentelemetry-browser-extension-autoinjection/src/ui/SaveButton.tsx +++ b/plugins/node/opentelemetry-instrumentation-aws-lambda/src/semconv.ts @@ -14,21 +14,15 @@ * limitations under the License. */ -import { Button } from '@material-ui/core'; -import * as React from 'react'; -import { SaveButtonProps } from '../types'; +/* + * This file contains a copy of unstable semantic convention definitions + * used by this package. + * @see https://github.com/open-telemetry/opentelemetry-js/tree/main/semantic-conventions#unstable-semconv + */ -export class SaveButton extends React.Component { - override render() { - return ( - - ); - } -} +/** + * A boolean that is true if the serverless function is executed for the first time (aka cold-start). + * + * @experimental This attribute is experimental and is subject to breaking changes in minor releases of `@opentelemetry/semantic-conventions`. + */ +export const ATTR_FAAS_COLDSTART = 'faas.coldstart'; diff --git a/plugins/node/opentelemetry-instrumentation-aws-lambda/test/integrations/lambda-handler.force-flush.test.ts b/plugins/node/opentelemetry-instrumentation-aws-lambda/test/integrations/lambda-handler.force-flush.test.ts index 0a067dc758..8b68e71fe2 100644 --- a/plugins/node/opentelemetry-instrumentation-aws-lambda/test/integrations/lambda-handler.force-flush.test.ts +++ b/plugins/node/opentelemetry-instrumentation-aws-lambda/test/integrations/lambda-handler.force-flush.test.ts @@ -88,8 +88,9 @@ describe('force flush', () => { }); it('should force flush NodeTracerProvider', async () => { - const provider = new NodeTracerProvider(); - provider.addSpanProcessor(new BatchSpanProcessor(traceMemoryExporter)); + const provider = new NodeTracerProvider({ + spanProcessors: [new BatchSpanProcessor(traceMemoryExporter)], + }); provider.register(); let forceFlushed = false; const forceFlush = () => @@ -118,10 +119,9 @@ describe('force flush', () => { }); it('should force flush ProxyTracerProvider with NodeTracerProvider', async () => { - const nodeTracerProvider = new NodeTracerProvider(); - nodeTracerProvider.addSpanProcessor( - new BatchSpanProcessor(traceMemoryExporter) - ); + const nodeTracerProvider = new NodeTracerProvider({ + spanProcessors: [new BatchSpanProcessor(traceMemoryExporter)], + }); nodeTracerProvider.register(); const provider = new ProxyTracerProvider(); provider.setDelegate(nodeTracerProvider); @@ -152,10 +152,11 @@ describe('force flush', () => { }); it('should force flush MeterProvider', async () => { - const provider = new MeterProvider(); - provider.addMetricReader( - new PeriodicExportingMetricReader({ exporter: metricMemoryExporter }) - ); + const provider = new MeterProvider({ + readers: [ + new PeriodicExportingMetricReader({ exporter: metricMemoryExporter }), + ], + }); let forceFlushed = false; const forceFlush = () => new Promise(resolve => { @@ -183,10 +184,9 @@ describe('force flush', () => { }); it('should callback once after force flush providers', async () => { - const nodeTracerProvider = new NodeTracerProvider(); - nodeTracerProvider.addSpanProcessor( - new BatchSpanProcessor(traceMemoryExporter) - ); + const nodeTracerProvider = new NodeTracerProvider({ + spanProcessors: [new BatchSpanProcessor(traceMemoryExporter)], + }); nodeTracerProvider.register(); const tracerProvider = new ProxyTracerProvider(); tracerProvider.setDelegate(nodeTracerProvider); @@ -198,10 +198,11 @@ describe('force flush', () => { }); nodeTracerProvider.forceFlush = tracerForceFlush; - const meterProvider = new MeterProvider(); - meterProvider.addMetricReader( - new PeriodicExportingMetricReader({ exporter: metricMemoryExporter }) - ); + const meterProvider = new MeterProvider({ + readers: [ + new PeriodicExportingMetricReader({ exporter: metricMemoryExporter }), + ], + }); let meterForceFlushed = false; const meterForceFlush = () => new Promise(resolve => { diff --git a/plugins/node/opentelemetry-instrumentation-aws-lambda/test/integrations/lambda-handler.test.ts b/plugins/node/opentelemetry-instrumentation-aws-lambda/test/integrations/lambda-handler.test.ts index 65c4a76df8..a7aeadfae8 100644 --- a/plugins/node/opentelemetry-instrumentation-aws-lambda/test/integrations/lambda-handler.test.ts +++ b/plugins/node/opentelemetry-instrumentation-aws-lambda/test/integrations/lambda-handler.test.ts @@ -120,8 +120,9 @@ describe('lambda handler', () => { ) => { process.env._HANDLER = handler; - const provider = new NodeTracerProvider(); - provider.addSpanProcessor(new BatchSpanProcessor(memoryExporter)); + const provider = new NodeTracerProvider({ + spanProcessors: [new BatchSpanProcessor(memoryExporter)], + }); provider.register(); instrumentation = new AwsLambdaInstrumentation(config); diff --git a/plugins/node/opentelemetry-instrumentation-bunyan/test/bunyan.test.ts b/plugins/node/opentelemetry-instrumentation-bunyan/test/bunyan.test.ts index b26c290b97..aa4196f5d2 100644 --- a/plugins/node/opentelemetry-instrumentation-bunyan/test/bunyan.test.ts +++ b/plugins/node/opentelemetry-instrumentation-bunyan/test/bunyan.test.ts @@ -40,11 +40,10 @@ import type * as BunyanLogger from 'bunyan'; // import { diag, DiagConsoleLogger, DiagLogLevel } from '@opentelemetry/api'; // diag.setLogger(new DiagConsoleLogger(), DiagLogLevel.DEBUG); -const tracerProvider = new NodeTracerProvider(); +const tracerProvider = new NodeTracerProvider({ + spanProcessors: [new SimpleSpanProcessor(new InMemorySpanExporter())], +}); tracerProvider.register(); -tracerProvider.addSpanProcessor( - new SimpleSpanProcessor(new InMemorySpanExporter()) -); const tracer = tracerProvider.getTracer('default'); const resource = new Resource({ diff --git a/plugins/node/opentelemetry-instrumentation-cassandra/test/cassandra-driver.test.ts b/plugins/node/opentelemetry-instrumentation-cassandra/test/cassandra-driver.test.ts index 00171c8426..a51dc74a45 100644 --- a/plugins/node/opentelemetry-instrumentation-cassandra/test/cassandra-driver.test.ts +++ b/plugins/node/opentelemetry-instrumentation-cassandra/test/cassandra-driver.test.ts @@ -48,8 +48,9 @@ import { import { ResponseHookInfo } from '../src/types'; const memoryExporter = new InMemorySpanExporter(); -const provider = new NodeTracerProvider(); -provider.addSpanProcessor(new SimpleSpanProcessor(memoryExporter)); +const provider = new NodeTracerProvider({ + spanProcessors: [new SimpleSpanProcessor(memoryExporter)], +}); context.setGlobalContextManager(new AsyncHooksContextManager()); const testCassandra = process.env.RUN_CASSANDRA_TESTS; diff --git a/plugins/node/opentelemetry-instrumentation-connect/test/instrumentation.test.ts b/plugins/node/opentelemetry-instrumentation-connect/test/instrumentation.test.ts index cc2ef79fb5..8d228adc23 100644 --- a/plugins/node/opentelemetry-instrumentation-connect/test/instrumentation.test.ts +++ b/plugins/node/opentelemetry-instrumentation-connect/test/instrumentation.test.ts @@ -50,14 +50,15 @@ const httpRequest = { const instrumentation = new ConnectInstrumentation(); const contextManager = new AsyncHooksContextManager().enable(); const memoryExporter = new InMemorySpanExporter(); -const provider = new NodeTracerProvider(); const spanProcessor = new SimpleSpanProcessor(memoryExporter); +const provider = new NodeTracerProvider({ + spanProcessors: [spanProcessor], +}); instrumentation.setTracerProvider(provider); context.setGlobalContextManager(contextManager); const tracer = provider.getTracer('default'); -provider.addSpanProcessor(spanProcessor); instrumentation.enable(); import * as connect from 'connect'; diff --git a/plugins/node/opentelemetry-instrumentation-dns/test/functionals/dns-disable.test.ts b/plugins/node/opentelemetry-instrumentation-dns/test/functionals/dns-disable.test.ts index ddcf174127..79701f213f 100644 --- a/plugins/node/opentelemetry-instrumentation-dns/test/functionals/dns-disable.test.ts +++ b/plugins/node/opentelemetry-instrumentation-dns/test/functionals/dns-disable.test.ts @@ -26,9 +26,10 @@ import * as Sinon from 'sinon'; import * as dns from 'dns'; const memoryExporter = new InMemorySpanExporter(); -const provider = new NodeTracerProvider(); +const provider = new NodeTracerProvider({ + spanProcessors: [new SimpleSpanProcessor(memoryExporter)], +}); const tracer = provider.getTracer('default'); -provider.addSpanProcessor(new SimpleSpanProcessor(memoryExporter)); describe('DnsInstrumentation', () => { let instrumentation: DnsInstrumentation; diff --git a/plugins/node/opentelemetry-instrumentation-dns/test/integrations/dns-lookup.test.ts b/plugins/node/opentelemetry-instrumentation-dns/test/integrations/dns-lookup.test.ts index e17d8b06a2..b54e564b50 100644 --- a/plugins/node/opentelemetry-instrumentation-dns/test/integrations/dns-lookup.test.ts +++ b/plugins/node/opentelemetry-instrumentation-dns/test/integrations/dns-lookup.test.ts @@ -27,8 +27,9 @@ import { assertSpan } from '../utils/assertSpan'; import { SpanStatusCode } from '@opentelemetry/api'; const memoryExporter = new InMemorySpanExporter(); -const provider = new NodeTracerProvider(); -provider.addSpanProcessor(new SimpleSpanProcessor(memoryExporter)); +const provider = new NodeTracerProvider({ + spanProcessors: [new SimpleSpanProcessor(memoryExporter)], +}); describe('dns.lookup()', () => { let instrumentation: DnsInstrumentation; diff --git a/plugins/node/opentelemetry-instrumentation-dns/test/integrations/dns-slash-promises-lookup.test.ts b/plugins/node/opentelemetry-instrumentation-dns/test/integrations/dns-slash-promises-lookup.test.ts index 7489e25153..b96c74de8d 100644 --- a/plugins/node/opentelemetry-instrumentation-dns/test/integrations/dns-slash-promises-lookup.test.ts +++ b/plugins/node/opentelemetry-instrumentation-dns/test/integrations/dns-slash-promises-lookup.test.ts @@ -27,8 +27,9 @@ import { assertSpan } from '../utils/assertSpan'; import { SpanStatusCode } from '@opentelemetry/api'; const memoryExporter = new InMemorySpanExporter(); -const provider = new NodeTracerProvider(); -provider.addSpanProcessor(new SimpleSpanProcessor(memoryExporter)); +const provider = new NodeTracerProvider({ + spanProcessors: [new SimpleSpanProcessor(memoryExporter)], +}); const supportsPromises = parseInt(process.versions.node.split('.')[0], 10) >= 15; diff --git a/plugins/node/opentelemetry-instrumentation-dns/test/integrations/dnspromise-lookup.test.ts b/plugins/node/opentelemetry-instrumentation-dns/test/integrations/dnspromise-lookup.test.ts index 1338f43bac..7443d4d81e 100644 --- a/plugins/node/opentelemetry-instrumentation-dns/test/integrations/dnspromise-lookup.test.ts +++ b/plugins/node/opentelemetry-instrumentation-dns/test/integrations/dnspromise-lookup.test.ts @@ -27,8 +27,9 @@ import { assertSpan } from '../utils/assertSpan'; import { SpanStatusCode } from '@opentelemetry/api'; const memoryExporter = new InMemorySpanExporter(); -const provider = new NodeTracerProvider(); -provider.addSpanProcessor(new SimpleSpanProcessor(memoryExporter)); +const provider = new NodeTracerProvider({ + spanProcessors: [new SimpleSpanProcessor(memoryExporter)], +}); describe('dns.promises.lookup()', () => { let instrumentation: DnsInstrumentation; diff --git a/plugins/node/opentelemetry-instrumentation-express/test/custom-config.test.ts b/plugins/node/opentelemetry-instrumentation-express/test/custom-config.test.ts index 50d644086a..abdb7bc26f 100644 --- a/plugins/node/opentelemetry-instrumentation-express/test/custom-config.test.ts +++ b/plugins/node/opentelemetry-instrumentation-express/test/custom-config.test.ts @@ -39,10 +39,10 @@ import * as express from 'express'; import * as http from 'http'; describe('ExpressInstrumentation', () => { - const provider = new NodeTracerProvider(); const memoryExporter = new InMemorySpanExporter(); - const spanProcessor = new SimpleSpanProcessor(memoryExporter); - provider.addSpanProcessor(spanProcessor); + const provider = new NodeTracerProvider({ + spanProcessors: [new SimpleSpanProcessor(memoryExporter)], + }); const tracer = provider.getTracer('default'); const contextManager = new AsyncHooksContextManager().enable(); diff --git a/plugins/node/opentelemetry-instrumentation-express/test/express.test.ts b/plugins/node/opentelemetry-instrumentation-express/test/express.test.ts index 5991688ffd..13806b2698 100644 --- a/plugins/node/opentelemetry-instrumentation-express/test/express.test.ts +++ b/plugins/node/opentelemetry-instrumentation-express/test/express.test.ts @@ -37,10 +37,11 @@ import { RPCMetadata, getRPCMetadata } from '@opentelemetry/core'; import { Server } from 'http'; describe('ExpressInstrumentation', () => { - const provider = new NodeTracerProvider(); const memoryExporter = new InMemorySpanExporter(); const spanProcessor = new SimpleSpanProcessor(memoryExporter); - provider.addSpanProcessor(spanProcessor); + const provider = new NodeTracerProvider({ + spanProcessors: [spanProcessor], + }); const tracer = provider.getTracer('default'); const contextManager = new AsyncHooksContextManager().enable(); diff --git a/plugins/node/opentelemetry-instrumentation-express/test/hooks.test.ts b/plugins/node/opentelemetry-instrumentation-express/test/hooks.test.ts index 78cfdd3d4a..04af79540c 100644 --- a/plugins/node/opentelemetry-instrumentation-express/test/hooks.test.ts +++ b/plugins/node/opentelemetry-instrumentation-express/test/hooks.test.ts @@ -37,10 +37,11 @@ import { httpRequest, serverWithMiddleware } from './utils'; import { RPCMetadata, getRPCMetadata } from '@opentelemetry/core'; describe('ExpressInstrumentation hooks', () => { - const provider = new NodeTracerProvider(); const memoryExporter = new InMemorySpanExporter(); const spanProcessor = new SimpleSpanProcessor(memoryExporter); - provider.addSpanProcessor(spanProcessor); + const provider = new NodeTracerProvider({ + spanProcessors: [spanProcessor], + }); const tracer = provider.getTracer('default'); const contextManager = new AsyncHooksContextManager().enable(); diff --git a/plugins/node/opentelemetry-instrumentation-express/test/ignore-all.test.ts b/plugins/node/opentelemetry-instrumentation-express/test/ignore-all.test.ts index 0fdebeabfb..7d462baa13 100644 --- a/plugins/node/opentelemetry-instrumentation-express/test/ignore-all.test.ts +++ b/plugins/node/opentelemetry-instrumentation-express/test/ignore-all.test.ts @@ -41,10 +41,11 @@ import * as express from 'express'; import * as http from 'http'; describe('ExpressInstrumentation', () => { - const provider = new NodeTracerProvider(); const memoryExporter = new InMemorySpanExporter(); const spanProcessor = new SimpleSpanProcessor(memoryExporter); - provider.addSpanProcessor(spanProcessor); + const provider = new NodeTracerProvider({ + spanProcessors: [spanProcessor], + }); const tracer = provider.getTracer('default'); const contextManager = new AsyncHooksContextManager().enable(); diff --git a/plugins/node/opentelemetry-instrumentation-fastify/CHANGELOG.md b/plugins/node/opentelemetry-instrumentation-fastify/CHANGELOG.md index 522434efbc..8c6caadf64 100644 --- a/plugins/node/opentelemetry-instrumentation-fastify/CHANGELOG.md +++ b/plugins/node/opentelemetry-instrumentation-fastify/CHANGELOG.md @@ -1,5 +1,12 @@ # Changelog +## [0.44.1](https://github.com/open-telemetry/opentelemetry-js-contrib/compare/instrumentation-fastify-v0.44.0...instrumentation-fastify-v0.44.1) (2025-01-20) + + +### Bug Fixes + +* **instrumentation-fastify:** add missing module export ([#2633](https://github.com/open-telemetry/opentelemetry-js-contrib/issues/2633)) ([1a6839b](https://github.com/open-telemetry/opentelemetry-js-contrib/commit/1a6839b00bfb116528e620c19f118d0a920c987f)) + ## [0.44.0](https://github.com/open-telemetry/opentelemetry-js-contrib/compare/instrumentation-fastify-v0.43.0...instrumentation-fastify-v0.44.0) (2024-12-18) diff --git a/plugins/node/opentelemetry-instrumentation-fastify/package.json b/plugins/node/opentelemetry-instrumentation-fastify/package.json index dade9ea581..2cdf4f2069 100644 --- a/plugins/node/opentelemetry-instrumentation-fastify/package.json +++ b/plugins/node/opentelemetry-instrumentation-fastify/package.json @@ -1,6 +1,6 @@ { "name": "@opentelemetry/instrumentation-fastify", - "version": "0.44.0", + "version": "0.44.1", "description": "OpenTelemetry instrumentation for `fastify` http web application framework", "main": "build/src/index.js", "types": "build/src/index.d.ts", diff --git a/plugins/node/opentelemetry-instrumentation-fastify/test/instrumentation.test.ts b/plugins/node/opentelemetry-instrumentation-fastify/test/instrumentation.test.ts index 80c4195742..1ac82b125f 100644 --- a/plugins/node/opentelemetry-instrumentation-fastify/test/instrumentation.test.ts +++ b/plugins/node/opentelemetry-instrumentation-fastify/test/instrumentation.test.ts @@ -66,13 +66,14 @@ const httpInstrumentation = new HttpInstrumentation(); const instrumentation = new FastifyInstrumentation(); const contextManager = new AsyncHooksContextManager().enable(); const memoryExporter = new InMemorySpanExporter(); -const provider = new NodeTracerProvider(); const spanProcessor = new SimpleSpanProcessor(memoryExporter); +const provider = new NodeTracerProvider({ + spanProcessors: [spanProcessor], +}); instrumentation.setTracerProvider(provider); httpInstrumentation.setTracerProvider(provider); context.setGlobalContextManager(contextManager); -provider.addSpanProcessor(spanProcessor); instrumentation.enable(); httpInstrumentation.enable(); diff --git a/plugins/node/opentelemetry-instrumentation-generic-pool/README.md b/plugins/node/opentelemetry-instrumentation-generic-pool/README.md index 90404555dc..32b791d12c 100644 --- a/plugins/node/opentelemetry-instrumentation-generic-pool/README.md +++ b/plugins/node/opentelemetry-instrumentation-generic-pool/README.md @@ -27,9 +27,12 @@ const { NodeTracerProvider } = require('@opentelemetry/sdk-trace-node'); const { registerInstrumentations } = require('@opentelemetry/instrumentation'); const { GenericPoolInstrumentation } = require('@opentelemetry/instrumentation-generic-pool'); -const provider = new NodeTracerProvider(); +const provider = new NodeTracerProvider({ + spanProcessors: [ + new SimpleSpanProcessor(new ConsoleSpanExporter()), + ], +}); -provider.addSpanProcessor(new SimpleSpanProcessor(new ConsoleSpanExporter())); provider.register(); registerInstrumentations({ diff --git a/plugins/node/opentelemetry-instrumentation-generic-pool/test/index.test.ts b/plugins/node/opentelemetry-instrumentation-generic-pool/test/index.test.ts index e2e634d4be..3d99207ae5 100644 --- a/plugins/node/opentelemetry-instrumentation-generic-pool/test/index.test.ts +++ b/plugins/node/opentelemetry-instrumentation-generic-pool/test/index.test.ts @@ -67,10 +67,11 @@ const createPool = { }[isOldVersion ? 'v2' : 'v3']; describe('GenericPool instrumentation', () => { - const provider = new NodeTracerProvider(); const memoryExporter = new InMemorySpanExporter(); const spanProcessor = new SimpleSpanProcessor(memoryExporter); - provider.addSpanProcessor(spanProcessor); + const provider = new NodeTracerProvider({ + spanProcessors: [spanProcessor], + }); plugin.setTracerProvider(provider); const tracer = provider.getTracer('default'); let contextManager: AsyncHooksContextManager; diff --git a/plugins/node/opentelemetry-instrumentation-graphql/test/graphql.test.ts b/plugins/node/opentelemetry-instrumentation-graphql/test/graphql.test.ts index 661304a212..c538a4d1d2 100644 --- a/plugins/node/opentelemetry-instrumentation-graphql/test/graphql.test.ts +++ b/plugins/node/opentelemetry-instrumentation-graphql/test/graphql.test.ts @@ -99,8 +99,9 @@ const queryInvalid = ` `; const exporter = new InMemorySpanExporter(); -const provider = new BasicTracerProvider(); -provider.addSpanProcessor(new SimpleSpanProcessor(exporter)); +const provider = new BasicTracerProvider({ + spanProcessors: [new SimpleSpanProcessor(exporter)], +}); graphQLInstrumentation.setTracerProvider(provider); describe('graphql', () => { diff --git a/plugins/node/opentelemetry-instrumentation-hapi/test/hapi-plugin.test.ts b/plugins/node/opentelemetry-instrumentation-hapi/test/hapi-plugin.test.ts index a9cbe7dd26..684ab99406 100644 --- a/plugins/node/opentelemetry-instrumentation-hapi/test/hapi-plugin.test.ts +++ b/plugins/node/opentelemetry-instrumentation-hapi/test/hapi-plugin.test.ts @@ -29,10 +29,11 @@ import { HapiLayerType } from '../src/internal-types'; import { AttributeNames } from '../src/enums/AttributeNames'; describe('Hapi Instrumentation - Hapi.Plugin Tests', () => { - const provider = new NodeTracerProvider(); const memoryExporter = new InMemorySpanExporter(); const spanProcessor = new SimpleSpanProcessor(memoryExporter); - provider.addSpanProcessor(spanProcessor); + const provider = new NodeTracerProvider({ + spanProcessors: [spanProcessor], + }); const tracer = provider.getTracer('default'); let contextManager: AsyncHooksContextManager; let server: hapi.Server; diff --git a/plugins/node/opentelemetry-instrumentation-hapi/test/hapi-server-ext.test.ts b/plugins/node/opentelemetry-instrumentation-hapi/test/hapi-server-ext.test.ts index 529df11299..4508bca44a 100644 --- a/plugins/node/opentelemetry-instrumentation-hapi/test/hapi-server-ext.test.ts +++ b/plugins/node/opentelemetry-instrumentation-hapi/test/hapi-server-ext.test.ts @@ -30,10 +30,11 @@ import { HapiLayerType } from '../src/internal-types'; import { AttributeNames } from '../src/enums/AttributeNames'; describe('Hapi Instrumentation - Server.Ext Tests', () => { - const provider = new NodeTracerProvider(); const memoryExporter = new InMemorySpanExporter(); const spanProcessor = new SimpleSpanProcessor(memoryExporter); - provider.addSpanProcessor(spanProcessor); + const provider = new NodeTracerProvider({ + spanProcessors: [spanProcessor], + }); const tracer = provider.getTracer('default'); let contextManager: AsyncHooksContextManager; let server: hapi.Server; diff --git a/plugins/node/opentelemetry-instrumentation-hapi/test/hapi.test.ts b/plugins/node/opentelemetry-instrumentation-hapi/test/hapi.test.ts index 48e2c51912..e6be869a26 100644 --- a/plugins/node/opentelemetry-instrumentation-hapi/test/hapi.test.ts +++ b/plugins/node/opentelemetry-instrumentation-hapi/test/hapi.test.ts @@ -35,10 +35,11 @@ import { HapiLayerType } from '../src/internal-types'; import { AttributeNames } from '../src/enums/AttributeNames'; describe('Hapi Instrumentation - Core Tests', () => { - const provider = new NodeTracerProvider(); const memoryExporter = new InMemorySpanExporter(); const spanProcessor = new SimpleSpanProcessor(memoryExporter); - provider.addSpanProcessor(spanProcessor); + const provider = new NodeTracerProvider({ + spanProcessors: [spanProcessor], + }); const tracer = provider.getTracer('default'); let contextManager: AsyncHooksContextManager; let server: hapi.Server; diff --git a/plugins/node/opentelemetry-instrumentation-ioredis/test/ioredis.test.ts b/plugins/node/opentelemetry-instrumentation-ioredis/test/ioredis.test.ts index 6dad19a9e4..b1a1505e7b 100644 --- a/plugins/node/opentelemetry-instrumentation-ioredis/test/ioredis.test.ts +++ b/plugins/node/opentelemetry-instrumentation-ioredis/test/ioredis.test.ts @@ -86,7 +86,9 @@ const sanitizeEventForAssertion = (span: ReadableSpan) => { }; describe('ioredis', () => { - const provider = new NodeTracerProvider(); + const provider = new NodeTracerProvider({ + spanProcessors: [new SimpleSpanProcessor(memoryExporter)], + }); let ioredis: typeof ioredisTypes.default; let instrumentation: IORedisInstrumentation; const shouldTestLocal = process.env.RUN_REDIS_TESTS_LOCAL; @@ -115,7 +117,6 @@ describe('ioredis', () => { testUtils.startDocker('redis'); } - provider.addSpanProcessor(new SimpleSpanProcessor(memoryExporter)); instrumentation = new IORedisInstrumentation(); instrumentation.setTracerProvider(provider); ioredis = require('ioredis'); diff --git a/plugins/node/opentelemetry-instrumentation-knex/README.md b/plugins/node/opentelemetry-instrumentation-knex/README.md index e467172648..596fdcc619 100644 --- a/plugins/node/opentelemetry-instrumentation-knex/README.md +++ b/plugins/node/opentelemetry-instrumentation-knex/README.md @@ -27,9 +27,12 @@ const { ConsoleSpanExporter, SimpleSpanProcessor } = require('@opentelemetry/sdk const { NodeTracerProvider } = require('@opentelemetry/sdk-trace-node'); const { registerInstrumentations } = require('@opentelemetry/instrumentation'); -const provider = new NodeTracerProvider(); +const provider = new NodeTracerProvider({ + spanProcessors: [ + new SimpleSpanProcessor(new ConsoleSpanExporter()), + ], +}); -provider.addSpanProcessor(new SimpleSpanProcessor(new ConsoleSpanExporter())); provider.register(); registerInstrumentations({ diff --git a/plugins/node/opentelemetry-instrumentation-knex/test/index.test.ts b/plugins/node/opentelemetry-instrumentation-knex/test/index.test.ts index aa00a3a9f2..61f7be90b2 100644 --- a/plugins/node/opentelemetry-instrumentation-knex/test/index.test.ts +++ b/plugins/node/opentelemetry-instrumentation-knex/test/index.test.ts @@ -36,10 +36,11 @@ const plugin = new KnexInstrumentation({ import knex from 'knex'; describe('Knex instrumentation', () => { - const provider = new NodeTracerProvider(); const memoryExporter = new InMemorySpanExporter(); const spanProcessor = new SimpleSpanProcessor(memoryExporter); - provider.addSpanProcessor(spanProcessor); + const provider = new NodeTracerProvider({ + spanProcessors: [spanProcessor], + }); plugin.setTracerProvider(provider); const tracer = provider.getTracer('default'); let contextManager: AsyncHooksContextManager; diff --git a/plugins/node/opentelemetry-instrumentation-koa/test/koa.test.ts b/plugins/node/opentelemetry-instrumentation-koa/test/koa.test.ts index c1b894a026..06b914e968 100644 --- a/plugins/node/opentelemetry-instrumentation-koa/test/koa.test.ts +++ b/plugins/node/opentelemetry-instrumentation-koa/test/koa.test.ts @@ -73,10 +73,11 @@ const isrouterCompat = (semver.gte(LIB_VERSION, '13.0.0') && semver.gte(NODE_VERSION, '18.0.0')); describe('Koa Instrumentation', function () { - const provider = new NodeTracerProvider(); const memoryExporter = new InMemorySpanExporter(); const spanProcessor = new SimpleSpanProcessor(memoryExporter); - provider.addSpanProcessor(spanProcessor); + const provider = new NodeTracerProvider({ + spanProcessors: [spanProcessor], + }); plugin.setTracerProvider(provider); const tracer = provider.getTracer('default'); let contextManager: AsyncHooksContextManager; diff --git a/plugins/node/opentelemetry-instrumentation-memcached/test/index.test.ts b/plugins/node/opentelemetry-instrumentation-memcached/test/index.test.ts index ca6e883cac..25be005aeb 100644 --- a/plugins/node/opentelemetry-instrumentation-memcached/test/index.test.ts +++ b/plugins/node/opentelemetry-instrumentation-memcached/test/index.test.ts @@ -75,9 +75,10 @@ const shouldTestLocal = process.env.RUN_MEMCACHED_TESTS_LOCAL; const shouldTest = process.env.RUN_MEMCACHED_TESTS || shouldTestLocal; describe('memcached@2.x', () => { - const provider = new NodeTracerProvider(); + const provider = new NodeTracerProvider({ + spanProcessors: [new SimpleSpanProcessor(memoryExporter)], + }); const tracer = provider.getTracer('default'); - provider.addSpanProcessor(new SimpleSpanProcessor(memoryExporter)); instrumentation.setTracerProvider(provider); let contextManager: AsyncHooksContextManager; diff --git a/plugins/node/opentelemetry-instrumentation-mongodb/test/mongodb-v4-v5-v6.metrics.test.ts b/plugins/node/opentelemetry-instrumentation-mongodb/test/mongodb-v4-v5-v6.metrics.test.ts index 9bb49cb45b..47e925ac14 100644 --- a/plugins/node/opentelemetry-instrumentation-mongodb/test/mongodb-v4-v5-v6.metrics.test.ts +++ b/plugins/node/opentelemetry-instrumentation-mongodb/test/mongodb-v4-v5-v6.metrics.test.ts @@ -28,7 +28,6 @@ import { ResourceMetrics, } from '@opentelemetry/sdk-metrics'; -const otelTestingMeterProvider = new MeterProvider(); const inMemoryMetricsExporter = new InMemoryMetricExporter( AggregationTemporality.CUMULATIVE ); @@ -37,6 +36,9 @@ const metricReader = new PeriodicExportingMetricReader({ exportIntervalMillis: 100, exportTimeoutMillis: 100, }); +const otelTestingMeterProvider = new MeterProvider({ + readers: [metricReader], +}); import { registerInstrumentationTesting } from '@opentelemetry/contrib-test-utils'; const instrumentation = registerInstrumentationTesting( @@ -85,7 +87,6 @@ describe('MongoDBInstrumentation-Metrics', () => { let collection: Collection; before(done => { - otelTestingMeterProvider.addMetricReader(metricReader); instrumentation?.setMeterProvider(otelTestingMeterProvider); shouldTest = true; diff --git a/plugins/node/opentelemetry-instrumentation-mysql/test/index.metrics.test.ts b/plugins/node/opentelemetry-instrumentation-mysql/test/index.metrics.test.ts index b6015d65a8..3661904b5b 100644 --- a/plugins/node/opentelemetry-instrumentation-mysql/test/index.metrics.test.ts +++ b/plugins/node/opentelemetry-instrumentation-mysql/test/index.metrics.test.ts @@ -67,7 +67,6 @@ describe('mysql@2.x-Metrics', () => { const shouldTest = testMysql || testMysqlLocally; // Skips these tests if false (default) function initMeterProvider() { - otelTestingMeterProvider = new MeterProvider(); inMemoryMetricsExporter = new InMemoryMetricExporter( AggregationTemporality.CUMULATIVE ); @@ -76,8 +75,10 @@ describe('mysql@2.x-Metrics', () => { exportIntervalMillis: 100, exportTimeoutMillis: 100, }); + otelTestingMeterProvider = new MeterProvider({ + readers: [metricReader], + }); - otelTestingMeterProvider.addMetricReader(metricReader); instrumentation.setMeterProvider(otelTestingMeterProvider); } diff --git a/plugins/node/opentelemetry-instrumentation-mysql/test/index.test.ts b/plugins/node/opentelemetry-instrumentation-mysql/test/index.test.ts index 36b7cd1d5f..7679cb0182 100644 --- a/plugins/node/opentelemetry-instrumentation-mysql/test/index.test.ts +++ b/plugins/node/opentelemetry-instrumentation-mysql/test/index.test.ts @@ -54,11 +54,13 @@ describe('mysql@2.x-Tracing', () => { let connection: mysqlTypes.Connection; let pool: mysqlTypes.Pool; let poolCluster: mysqlTypes.PoolCluster; - const provider = new BasicTracerProvider(); const testMysql = process.env.RUN_MYSQL_TESTS; // For CI: assumes local mysql db is already available const testMysqlLocally = process.env.RUN_MYSQL_TESTS_LOCAL; // For local: spins up local mysql db via docker const shouldTest = testMysql || testMysqlLocally; // Skips these tests if false (default) const memoryExporter = new InMemorySpanExporter(); + const provider = new BasicTracerProvider({ + spanProcessors: [new SimpleSpanProcessor(memoryExporter)], + }); before(function (done) { if (!shouldTest) { @@ -67,7 +69,7 @@ describe('mysql@2.x-Tracing', () => { this.test!.parent!.pending = true; this.skip(); } - provider.addSpanProcessor(new SimpleSpanProcessor(memoryExporter)); + if (testMysqlLocally) { testUtils.startDocker('mysql'); // wait 15 seconds for docker container to start diff --git a/plugins/node/opentelemetry-instrumentation-mysql2/src/instrumentation.ts b/plugins/node/opentelemetry-instrumentation-mysql2/src/instrumentation.ts index 8c90080980..d22db9a020 100644 --- a/plugins/node/opentelemetry-instrumentation-mysql2/src/instrumentation.ts +++ b/plugins/node/opentelemetry-instrumentation-mysql2/src/instrumentation.ts @@ -18,6 +18,7 @@ import * as api from '@opentelemetry/api'; import { InstrumentationBase, InstrumentationNodeModuleDefinition, + InstrumentationNodeModuleFile, isWrapped, safeExecuteInTheMiddle, } from '@opentelemetry/instrumentation'; @@ -41,6 +42,8 @@ import { PACKAGE_NAME, PACKAGE_VERSION } from './version'; type formatType = typeof mysqlTypes.format; +const supportedVersions = ['>=1.4.2 <4']; + export class MySQL2Instrumentation extends InstrumentationBase { static readonly COMMON_ATTRIBUTES = { [SEMATTRS_DB_SYSTEM]: DBSYSTEMVALUES_MYSQL, @@ -51,45 +54,75 @@ export class MySQL2Instrumentation extends InstrumentationBase { + if (isWrapped(ConnectionPrototype.query)) { + this._unwrap(ConnectionPrototype, 'query'); + } + this._wrap( + ConnectionPrototype, + 'query', + this._patchQuery(format, false) as any + ); + if (isWrapped(ConnectionPrototype.execute)) { + this._unwrap(ConnectionPrototype, 'execute'); + } + this._wrap( + ConnectionPrototype, + 'execute', + this._patchQuery(format, true) as any + ); + }; + const unpatch = (ConnectionPrototype: mysqlTypes.Connection) => { + this._unwrap(ConnectionPrototype, 'query'); + this._unwrap(ConnectionPrototype, 'execute'); + }; return [ new InstrumentationNodeModuleDefinition( 'mysql2', - ['>=1.4.2 <4'], + supportedVersions, (moduleExports: any) => { - const ConnectionPrototype: mysqlTypes.Connection = - getConnectionPrototypeToInstrument(moduleExports.Connection); - if (isWrapped(ConnectionPrototype.query)) { - this._unwrap(ConnectionPrototype, 'query'); - } - this._wrap( - ConnectionPrototype, - 'query', - this._patchQuery(moduleExports.format, false) as any - ); - - if (isWrapped(ConnectionPrototype.execute)) { - this._unwrap(ConnectionPrototype, 'execute'); - } - this._wrap( - ConnectionPrototype, - 'execute', - this._patchQuery(moduleExports.format, true) as any - ); - + setFormatFunction(moduleExports); return moduleExports; }, - (moduleExports: any) => { - if (moduleExports === undefined) return; - const ConnectionPrototype: mysqlTypes.Connection = - moduleExports.Connection.prototype; - this._unwrap(ConnectionPrototype, 'query'); - this._unwrap(ConnectionPrototype, 'execute'); - } + () => {}, + [ + new InstrumentationNodeModuleFile( + 'mysql2/promise.js', + supportedVersions, + (moduleExports: any) => { + setFormatFunction(moduleExports); + return moduleExports; + }, + () => {} + ), + new InstrumentationNodeModuleFile( + 'mysql2/lib/connection.js', + supportedVersions, + (moduleExports: any) => { + const ConnectionPrototype: mysqlTypes.Connection = + getConnectionPrototypeToInstrument(moduleExports); + patch(ConnectionPrototype); + return moduleExports; + }, + (moduleExports: any) => { + if (moduleExports === undefined) return; + const ConnectionPrototype: mysqlTypes.Connection = + getConnectionPrototypeToInstrument(moduleExports); + unpatch(ConnectionPrototype); + } + ), + ] ), ]; } - private _patchQuery(format: formatType, isPrepared: boolean) { + private _patchQuery(format: formatType | undefined, isPrepared: boolean) { return (originalQuery: Function): Function => { const thisPlugin = this; return function query( diff --git a/plugins/node/opentelemetry-instrumentation-mysql2/src/utils.ts b/plugins/node/opentelemetry-instrumentation-mysql2/src/utils.ts index bb0fb763d3..9e495a7d2c 100644 --- a/plugins/node/opentelemetry-instrumentation-mysql2/src/utils.ts +++ b/plugins/node/opentelemetry-instrumentation-mysql2/src/utils.ts @@ -22,6 +22,9 @@ import { SEMATTRS_NET_PEER_NAME, SEMATTRS_NET_PEER_PORT, } from '@opentelemetry/semantic-conventions'; +import type * as mysqlTypes from 'mysql2'; + +type formatType = typeof mysqlTypes.format; /* Following types declare an expectation on mysql2 types and define a subset we @@ -103,14 +106,12 @@ function getJDBCString( */ export function getDbStatement( query: string | Query | QueryOptions, - format: ( - sql: string, - values: any[], - stringifyObjects?: boolean, - timeZone?: string - ) => string, + format?: formatType, values?: any[] ): string { + if (!format) { + return typeof query === 'string' ? query : query.sql; + } if (typeof query === 'string') { return values ? format(query, values) : query; } else { diff --git a/plugins/node/opentelemetry-instrumentation-mysql2/test/mysql.test.ts b/plugins/node/opentelemetry-instrumentation-mysql2/test/mysql.test.ts index ef14d7d982..b966900521 100644 --- a/plugins/node/opentelemetry-instrumentation-mysql2/test/mysql.test.ts +++ b/plugins/node/opentelemetry-instrumentation-mysql2/test/mysql.test.ts @@ -48,57 +48,28 @@ const instrumentation = new MySQL2Instrumentation(); instrumentation.enable(); instrumentation.disable(); -import * as mysqlTypes from 'mysql2'; - -interface Result extends mysqlTypes.RowDataPacket { +import type { Connection, Pool, PoolCluster, RowDataPacket } from 'mysql2'; +import { + createConnection, + createPool, + createPoolCluster, + format, +} from 'mysql2'; +import type { + Connection as ConnectionAsync, + createConnection as createConnectionAsync, +} from 'mysql2/promise'; + +interface Result extends RowDataPacket { solution: number; } describe('mysql2', () => { - let contextManager: AsyncHooksContextManager; - let connection: mysqlTypes.Connection; - let rootConnection: mysqlTypes.Connection; - let pool: mysqlTypes.Pool; - let poolCluster: mysqlTypes.PoolCluster; - const provider = new BasicTracerProvider(); const testMysql = process.env.RUN_MYSQL_TESTS; // For CI: assumes local mysql db is already available const testMysqlLocally = process.env.RUN_MYSQL_TESTS_LOCAL; // For local: spins up local mysql db via docker const shouldTest = testMysql || testMysqlLocally; // Skips these tests if false (default) - const memoryExporter = new InMemorySpanExporter(); - - const getLastQueries = (count: number) => - new Promise(res => { - const queries: string[] = []; - const query = rootConnection.query({ - sql: "SELECT * FROM mysql.general_log WHERE command_type = 'Query' ORDER BY event_time DESC LIMIT ? OFFSET 1", - values: [count], - }); - - query.on('result', (row: { argument: string | Buffer }) => { - if (typeof row.argument === 'string') { - queries.push(row.argument); - } else { - queries.push(row.argument.toString('utf-8')); - } - }); - query.on('end', () => res(queries)); - }); before(function (done) { - if (!shouldTest) { - // this.skip() workaround - // https://github.com/mochajs/mocha/issues/2683#issuecomment-375629901 - this.test!.parent!.pending = true; - this.skip(); - } - provider.addSpanProcessor(new SimpleSpanProcessor(memoryExporter)); - rootConnection = mysqlTypes.createConnection({ - port, - user: 'root', - host, - password: rootPassword, - database, - }); if (testMysqlLocally) { testUtils.startDocker('mysql'); // wait 15 seconds for docker container to start @@ -110,155 +81,223 @@ describe('mysql2', () => { }); after(function (done) { - rootConnection.end(() => { - if (testMysqlLocally) { - this.timeout(5000); - testUtils.cleanUpDocker('mysql'); + if (testMysqlLocally) { + this.timeout(5000); + testUtils.cleanUpDocker('mysql'); + } + done(); + }); + + describe('callback API', () => { + let contextManager: AsyncHooksContextManager; + const memoryExporter = new InMemorySpanExporter(); + const provider = new BasicTracerProvider({ + spanProcessors: [new SimpleSpanProcessor(memoryExporter)], + }); + + let connection: Connection; + let rootConnection: Connection; + let pool: Pool; + let poolCluster: PoolCluster; + + const getLastQueries = (count: number) => + new Promise(res => { + const queries: string[] = []; + const query = rootConnection.query({ + sql: "SELECT * FROM mysql.general_log WHERE command_type = 'Query' ORDER BY event_time DESC LIMIT ? OFFSET 1", + values: [count], + }); + + query.on('result', (row: { argument: string | Buffer }) => { + if (typeof row.argument === 'string') { + queries.push(row.argument); + } else { + queries.push(row.argument.toString('utf-8')); + } + }); + query.on('end', () => res(queries)); + }); + + before(function (done) { + if (!shouldTest) { + // this.skip() workaround + // https://github.com/mochajs/mocha/issues/2683#issuecomment-375629901 + this.test!.parent!.pending = true; + this.skip(); } + rootConnection = createConnection({ + port, + user: 'root', + host, + password: rootPassword, + database, + }); done(); }); - }); - beforeEach(() => { - instrumentation.disable(); - contextManager = new AsyncHooksContextManager().enable(); - context.setGlobalContextManager(contextManager); - instrumentation.setTracerProvider(provider); - instrumentation.enable(); - connection = mysqlTypes.createConnection({ - port, - user, - host, - password, - database, - }); - pool = mysqlTypes.createPool({ - port, - user, - host, - password, - database, + after(function (done) { + rootConnection.end(() => { + done(); + }); }); - poolCluster = mysqlTypes.createPoolCluster(); - // the implementation actually accepts ConnectionConfig as well, - // but the types do not reflect that - poolCluster.add('name', { - port, - user, - host, - password, - database, + + beforeEach(() => { + instrumentation.disable(); + contextManager = new AsyncHooksContextManager().enable(); + context.setGlobalContextManager(contextManager); + instrumentation.setTracerProvider(provider); + instrumentation.enable(); + connection = createConnection({ + port, + user, + host, + password, + database, + }); + pool = createPool({ + port, + user, + host, + password, + database, + }); + poolCluster = createPoolCluster(); + // the implementation actually accepts ConnectionConfig as well, + // but the types do not reflect that + poolCluster.add('name', { + port, + user, + host, + password, + database, + }); }); - }); - afterEach(done => { - context.disable(); - memoryExporter.reset(); - instrumentation.setConfig({}); - instrumentation.disable(); - connection.end(() => { - pool.end(() => { - if (isPoolClusterEndIgnoreCallback()) { - poolCluster.end(); - done(); - } else { - // PoolCluster.end types in the package are invalid - // https://github.com/sidorares/node-mysql2/pull/1332 - (poolCluster as any).end(() => { + afterEach(done => { + context.disable(); + memoryExporter.reset(); + instrumentation.setConfig({}); + instrumentation.disable(); + connection.end(() => { + pool.end(() => { + if (isPoolClusterEndIgnoreCallback()) { + poolCluster.end(); done(); - }); - } + } else { + // PoolCluster.end types in the package are invalid + // https://github.com/sidorares/node-mysql2/pull/1332 + (poolCluster as any).end(() => { + done(); + }); + } + }); }); }); - }); - describe('when the query is a string', () => { - it('should name the span accordingly ', done => { - const span = provider.getTracer('default').startSpan('test span'); - context.with(trace.setSpan(context.active(), span), () => { - const sql = 'SELECT 1+1 as solution'; - const query = connection.query(sql); + describe('when the query is a string', () => { + it('should name the span accordingly ', done => { + const span = provider.getTracer('default').startSpan('test span'); + context.with(trace.setSpan(context.active(), span), () => { + const sql = 'SELECT 1+1 as solution'; + const query = connection.query(sql); - query.on('end', () => { - const spans = memoryExporter.getFinishedSpans(); - assert.strictEqual(spans[0].name, 'SELECT'); - assert.strictEqual(spans[0].attributes[SEMATTRS_DB_STATEMENT], sql); - done(); + query.on('end', () => { + const spans = memoryExporter.getFinishedSpans(); + assert.strictEqual(spans[0].name, 'SELECT'); + assert.strictEqual(spans[0].attributes[SEMATTRS_DB_STATEMENT], sql); + done(); + }); }); }); }); - }); - describe('when the query is an object', () => { - it('should name the span accordingly ', done => { - const span = provider.getTracer('default').startSpan('test span'); - context.with(trace.setSpan(context.active(), span), () => { - const sql = 'SELECT 1+? as solution'; - const query = connection.query({ sql, values: [1] }); + describe('when the query is an object', () => { + it('should name the span accordingly ', done => { + const span = provider.getTracer('default').startSpan('test span'); + context.with(trace.setSpan(context.active(), span), () => { + const sql = 'SELECT 1+? as solution'; + const query = connection.query({ sql, values: [1] }); - query.on('end', () => { - const spans = memoryExporter.getFinishedSpans(); - assert.strictEqual(spans[0].name, 'SELECT'); - assert.strictEqual( - spans[0].attributes[SEMATTRS_DB_STATEMENT], - query.sql - ); - done(); + query.on('end', () => { + const spans = memoryExporter.getFinishedSpans(); + assert.strictEqual(spans[0].name, 'SELECT'); + assert.strictEqual( + spans[0].attributes[SEMATTRS_DB_STATEMENT], + query.sql + ); + done(); + }); }); }); }); - }); - describe('#Connection.query', () => { - it('should intercept connection.query(text: string)', done => { - const span = provider.getTracer('default').startSpan('test span'); - context.with(trace.setSpan(context.active(), span), () => { - const sql = 'SELECT 1+1 as solution'; - const query = connection.query(sql); - let rows = 0; - - query.on('result', (row: mysqlTypes.RowDataPacket) => { - assert.strictEqual(row.solution, 2); - rows += 1; + describe('#Connection.query', () => { + it('should intercept connection.query(text: string)', done => { + const span = provider.getTracer('default').startSpan('test span'); + context.with(trace.setSpan(context.active(), span), () => { + const sql = 'SELECT 1+1 as solution'; + const query = connection.query(sql); + let rows = 0; + + query.on('result', (row: RowDataPacket) => { + assert.strictEqual(row.solution, 2); + rows += 1; + }); + + query.on('end', () => { + try { + assert.strictEqual(rows, 1); + const spans = memoryExporter.getFinishedSpans(); + assert.strictEqual(spans.length, 1); + assertSpan(spans[0], sql); + } catch (e) { + done(e); + } + done(); + }); }); + }); - query.on('end', () => { - try { - assert.strictEqual(rows, 1); + it('should intercept connection.query(text: string, callback)', done => { + const span = provider.getTracer('default').startSpan('test span'); + context.with(trace.setSpan(context.active(), span), () => { + const sql = 'SELECT 1+1 as solution'; + connection.query(sql, (err, res: RowDataPacket[]) => { + assert.ifError(err); + assert.ok(res); + assert.strictEqual(res[0].solution, 2); const spans = memoryExporter.getFinishedSpans(); assert.strictEqual(spans.length, 1); assertSpan(spans[0], sql); - } catch (e) { - done(e); - } - done(); + done(); + }); }); }); - }); - it('should intercept connection.query(text: string, callback)', done => { - const span = provider.getTracer('default').startSpan('test span'); - context.with(trace.setSpan(context.active(), span), () => { - const sql = 'SELECT 1+1 as solution'; - connection.query(sql, (err, res: mysqlTypes.RowDataPacket[]) => { - assert.ifError(err); - assert.ok(res); - assert.strictEqual(res[0].solution, 2); - const spans = memoryExporter.getFinishedSpans(); - assert.strictEqual(spans.length, 1); - assertSpan(spans[0], sql); - done(); + it('should intercept connection.query(text: options, callback)', done => { + const span = provider.getTracer('default').startSpan('test span'); + context.with(trace.setSpan(context.active(), span), () => { + const sql = 'SELECT 1+? as solution'; + connection.query( + { sql, values: [1] }, + (err, res: RowDataPacket[]) => { + assert.ifError(err); + assert.ok(res); + assert.strictEqual(res[0].solution, 2); + const spans = memoryExporter.getFinishedSpans(); + assert.strictEqual(spans.length, 1); + assertSpan(spans[0], sql, [1]); + done(); + } + ); }); }); - }); - it('should intercept connection.query(text: options, callback)', done => { - const span = provider.getTracer('default').startSpan('test span'); - context.with(trace.setSpan(context.active(), span), () => { - const sql = 'SELECT 1+? as solution'; - connection.query( - { sql, values: [1] }, - (err, res: mysqlTypes.RowDataPacket[]) => { + it('should intercept connection.query(text: options, values: [], callback)', done => { + const span = provider.getTracer('default').startSpan('test span'); + context.with(trace.setSpan(context.active(), span), () => { + const sql = 'SELECT 1+? as solution'; + connection.query({ sql }, [1], (err, res: RowDataPacket[]) => { assert.ifError(err); assert.ok(res); assert.strictEqual(res[0].solution, 2); @@ -266,213 +305,189 @@ describe('mysql2', () => { assert.strictEqual(spans.length, 1); assertSpan(spans[0], sql, [1]); done(); - } - ); + }); + }); }); - }); - it('should intercept connection.query(text: options, values: [], callback)', done => { - const span = provider.getTracer('default').startSpan('test span'); - context.with(trace.setSpan(context.active(), span), () => { - const sql = 'SELECT 1+? as solution'; - connection.query( - { sql }, - [1], - (err, res: mysqlTypes.RowDataPacket[]) => { + it('should intercept connection.query(text: string, values: [], callback)', done => { + const span = provider.getTracer('default').startSpan('test span'); + context.with(trace.setSpan(context.active(), span), () => { + const sql = 'SELECT ? as solution'; + connection.query(sql, [1], (err, res: RowDataPacket[]) => { assert.ifError(err); assert.ok(res); - assert.strictEqual(res[0].solution, 2); + assert.strictEqual(res[0].solution, 1); const spans = memoryExporter.getFinishedSpans(); assert.strictEqual(spans.length, 1); assertSpan(spans[0], sql, [1]); done(); - } - ); - }); - }); - - it('should intercept connection.query(text: string, values: [], callback)', done => { - const span = provider.getTracer('default').startSpan('test span'); - context.with(trace.setSpan(context.active(), span), () => { - const sql = 'SELECT ? as solution'; - connection.query(sql, [1], (err, res: mysqlTypes.RowDataPacket[]) => { - assert.ifError(err); - assert.ok(res); - assert.strictEqual(res[0].solution, 1); - const spans = memoryExporter.getFinishedSpans(); - assert.strictEqual(spans.length, 1); - assertSpan(spans[0], sql, [1]); - done(); + }); }); }); - }); - it('should intercept connection.query(text: string, value: any, callback)', done => { - const span = provider.getTracer('default').startSpan('test span'); - context.with(trace.setSpan(context.active(), span), () => { - const sql = 'SELECT ? as solution'; - connection.query(sql, 1, (err, res: mysqlTypes.RowDataPacket[]) => { - assert.ifError(err); - assert.ok(res); - assert.strictEqual(res[0].solution, 1); - const spans = memoryExporter.getFinishedSpans(); - assert.strictEqual(spans.length, 1); - assertSpan(spans[0], sql, [1]); - done(); + it('should intercept connection.query(text: string, value: any, callback)', done => { + const span = provider.getTracer('default').startSpan('test span'); + context.with(trace.setSpan(context.active(), span), () => { + const sql = 'SELECT ? as solution'; + connection.query(sql, 1, (err, res: RowDataPacket[]) => { + assert.ifError(err); + assert.ok(res); + assert.strictEqual(res[0].solution, 1); + const spans = memoryExporter.getFinishedSpans(); + assert.strictEqual(spans.length, 1); + assertSpan(spans[0], sql, [1]); + done(); + }); }); }); - }); - it('should attach error messages to spans', done => { - const span = provider.getTracer('default').startSpan('test span'); - context.with(trace.setSpan(context.active(), span), () => { - const sql = 'SELECT ? as solution'; - connection.query(sql, (err, res) => { - assert.ok(err); - const spans = memoryExporter.getFinishedSpans(); - assert.strictEqual(spans.length, 1); - assertSpan(spans[0], sql, undefined, err!.message); - done(); + it('should attach error messages to spans', done => { + const span = provider.getTracer('default').startSpan('test span'); + context.with(trace.setSpan(context.active(), span), () => { + const sql = 'SELECT ? as solution'; + connection.query(sql, (err, res) => { + assert.ok(err); + const spans = memoryExporter.getFinishedSpans(); + assert.strictEqual(spans.length, 1); + assertSpan(spans[0], sql, undefined, err!.message); + done(); + }); }); }); - }); - it('should not add comment by default', done => { - const span = provider.getTracer('default').startSpan('test span'); - context.with(trace.setSpan(context.active(), span), () => { - connection.query('SELECT 1+1 as solution', () => { - const spans = memoryExporter.getFinishedSpans(); - assert.strictEqual(spans.length, 1); - getLastQueries(1).then(([query]) => { - try { - assert.doesNotMatch(query, /.*traceparent.*/); - done(); - } catch (e) { - done(e); - } + it('should not add comment by default', done => { + const span = provider.getTracer('default').startSpan('test span'); + context.with(trace.setSpan(context.active(), span), () => { + connection.query('SELECT 1+1 as solution', () => { + const spans = memoryExporter.getFinishedSpans(); + assert.strictEqual(spans.length, 1); + getLastQueries(1).then(([query]) => { + try { + assert.doesNotMatch(query, /.*traceparent.*/); + done(); + } catch (e) { + done(e); + } + }); }); }); }); - }); - it('should not add comment when specified if existing block comment', done => { - instrumentation.setConfig({ - addSqlCommenterCommentToQueries: true, - } as any); - const span = provider.getTracer('default').startSpan('test span'); - context.with(trace.setSpan(context.active(), span), () => { - connection.query('SELECT 1+1 as solution /*block comment*/', () => { - const spans = memoryExporter.getFinishedSpans(); - assert.strictEqual(spans.length, 1); - getLastQueries(1).then(([query]) => { - assert.doesNotMatch(query, /.*traceparent.*/); - done(); + it('should not add comment when specified if existing block comment', done => { + instrumentation.setConfig({ + addSqlCommenterCommentToQueries: true, + } as any); + const span = provider.getTracer('default').startSpan('test span'); + context.with(trace.setSpan(context.active(), span), () => { + connection.query('SELECT 1+1 as solution /*block comment*/', () => { + const spans = memoryExporter.getFinishedSpans(); + assert.strictEqual(spans.length, 1); + getLastQueries(1).then(([query]) => { + assert.doesNotMatch(query, /.*traceparent.*/); + done(); + }); }); }); }); - }); - it('should not add comment when specified if existing line comment', done => { - instrumentation.setConfig({ - addSqlCommenterCommentToQueries: true, - } as any); - const span = provider.getTracer('default').startSpan('test span'); - context.with(trace.setSpan(context.active(), span), () => { - connection.query('SELECT 1+1 as solution -- line comment', () => { - const spans = memoryExporter.getFinishedSpans(); - assert.strictEqual(spans.length, 1); - getLastQueries(1).then(([query]) => { - assert.doesNotMatch(query, /.*traceparent.*/); - done(); + it('should not add comment when specified if existing line comment', done => { + instrumentation.setConfig({ + addSqlCommenterCommentToQueries: true, + } as any); + const span = provider.getTracer('default').startSpan('test span'); + context.with(trace.setSpan(context.active(), span), () => { + connection.query('SELECT 1+1 as solution -- line comment', () => { + const spans = memoryExporter.getFinishedSpans(); + assert.strictEqual(spans.length, 1); + getLastQueries(1).then(([query]) => { + assert.doesNotMatch(query, /.*traceparent.*/); + done(); + }); }); }); }); - }); - it('should add comment when specified if no existing comment', done => { - instrumentation.setConfig({ - addSqlCommenterCommentToQueries: true, - } as any); - const span = provider.getTracer('default').startSpan('test span'); - context.with(trace.setSpan(context.active(), span), () => { - connection.query('SELECT 1+1 as solution', () => { - const spans = memoryExporter.getFinishedSpans(); - assert.strictEqual(spans.length, 1); - getLastQueries(1).then(([query]) => { - assert.match(query, /.*traceparent.*/); - done(); + it('should add comment when specified if no existing comment', done => { + instrumentation.setConfig({ + addSqlCommenterCommentToQueries: true, + } as any); + const span = provider.getTracer('default').startSpan('test span'); + context.with(trace.setSpan(context.active(), span), () => { + connection.query('SELECT 1+1 as solution', () => { + const spans = memoryExporter.getFinishedSpans(); + assert.strictEqual(spans.length, 1); + getLastQueries(1).then(([query]) => { + assert.match(query, /.*traceparent.*/); + done(); + }); }); }); }); }); - }); - describe('#Connection.execute', () => { - it('should intercept connection.execute(text: string)', done => { - const span = provider.getTracer('default').startSpan('test span'); - context.with(trace.setSpan(context.active(), span), () => { - const sql = 'SELECT 1+1 as solution'; - const query = connection.execute(sql); - let rows = 0; - - query.on('result', (row: mysqlTypes.RowDataPacket) => { - assert.strictEqual(row.solution, 2); - rows += 1; - }); + describe('#Connection.execute', () => { + it('should intercept connection.execute(text: string)', done => { + const span = provider.getTracer('default').startSpan('test span'); + context.with(trace.setSpan(context.active(), span), () => { + const sql = 'SELECT 1+1 as solution'; + const query = connection.execute(sql); + let rows = 0; - query.on('end', () => { - assert.strictEqual(rows, 1); - const spans = memoryExporter.getFinishedSpans(); - assert.strictEqual(spans.length, 1); - assertSpan(spans[0], sql); - done(); - }); - }); - }); + query.on('result', (row: RowDataPacket) => { + assert.strictEqual(row.solution, 2); + rows += 1; + }); - it('should intercept connection.execute(text: string, callback)', done => { - const span = provider.getTracer('default').startSpan('test span'); - context.with(trace.setSpan(context.active(), span), () => { - const sql = 'SELECT 1+1 as solution'; - connection.execute(sql, (err, res: mysqlTypes.RowDataPacket[]) => { - assert.ifError(err); - assert.ok(res); - assert.strictEqual(res[0].solution, 2); - const spans = memoryExporter.getFinishedSpans(); - assert.strictEqual(spans.length, 1); - assertSpan(spans[0], sql); - done(); + query.on('end', () => { + assert.strictEqual(rows, 1); + const spans = memoryExporter.getFinishedSpans(); + assert.strictEqual(spans.length, 1); + assertSpan(spans[0], sql); + done(); + }); }); }); - }); - it('should intercept connection.execute(text: options, callback)', done => { - const span = provider.getTracer('default').startSpan('test span'); - context.with(trace.setSpan(context.active(), span), () => { - const sql = 'SELECT 1+? as solution'; - connection.execute( - { sql, values: [1] }, - (err, res: mysqlTypes.RowDataPacket[]) => { + it('should intercept connection.execute(text: string, callback)', done => { + const span = provider.getTracer('default').startSpan('test span'); + context.with(trace.setSpan(context.active(), span), () => { + const sql = 'SELECT 1+1 as solution'; + connection.execute(sql, (err, res: RowDataPacket[]) => { assert.ifError(err); assert.ok(res); assert.strictEqual(res[0].solution, 2); const spans = memoryExporter.getFinishedSpans(); assert.strictEqual(spans.length, 1); - assertSpan(spans[0], sql, [1]); + assertSpan(spans[0], sql); done(); - } - ); + }); + }); }); - }); - it('should intercept connection.execute(text: options, values: [], callback)', done => { - const span = provider.getTracer('default').startSpan('test span'); - context.with(trace.setSpan(context.active(), span), () => { - const sql = 'SELECT 1+? as solution'; - connection.execute( - { sql }, - [1], - (err, res: mysqlTypes.RowDataPacket[]) => { + it('should intercept connection.execute(text: options, callback)', done => { + const span = provider.getTracer('default').startSpan('test span'); + context.with(trace.setSpan(context.active(), span), () => { + const sql = 'SELECT 1+? as solution'; + connection.execute( + { sql, values: [1] }, + (err, res: RowDataPacket[]) => { + assert.ifError(err); + assert.ok(res); + assert.strictEqual(res[0].solution, 2); + const spans = memoryExporter.getFinishedSpans(); + assert.strictEqual(spans.length, 1); + assertSpan(spans[0], sql, [1]); + done(); + } + ); + }); + }); + + it('should intercept connection.execute(text: options, values: [], callback)', done => { + const span = provider.getTracer('default').startSpan('test span'); + context.with(trace.setSpan(context.active(), span), () => { + const sql = 'SELECT 1+? as solution'; + connection.execute({ sql }, [1], (err, res: RowDataPacket[]) => { assert.ifError(err); assert.ok(res); assert.strictEqual(res[0].solution, 2); @@ -480,90 +495,66 @@ describe('mysql2', () => { assert.strictEqual(spans.length, 1); assertSpan(spans[0], sql, [1]); done(); - } - ); - }); - }); - - it('should intercept connection.execute(text: string, values: [], callback)', done => { - const span = provider.getTracer('default').startSpan('test span'); - context.with(trace.setSpan(context.active(), span), () => { - const sql = 'SELECT 1+? as solution'; - connection.execute(sql, [1], (err, res: mysqlTypes.RowDataPacket[]) => { - assert.ifError(err); - assert.ok(res); - assert.strictEqual(res[0].solution, 2); - const spans = memoryExporter.getFinishedSpans(); - assert.strictEqual(spans.length, 1); - assertSpan(spans[0], sql, [1]); - done(); + }); }); }); - }); - it('should intercept connection.execute(text: string, value: any, callback)', done => { - const span = provider.getTracer('default').startSpan('test span'); - context.with(trace.setSpan(context.active(), span), () => { - const sql = 'SELECT 1+? as solution'; - connection.execute(sql, [1], (err, res: mysqlTypes.RowDataPacket[]) => { - assert.ifError(err); - assert.ok(res); - assert.strictEqual(res[0].solution, 2); - const spans = memoryExporter.getFinishedSpans(); - assert.strictEqual(spans.length, 1); - assertSpan(spans[0], sql, [1]); - done(); + it('should intercept connection.execute(text: string, values: [], callback)', done => { + const span = provider.getTracer('default').startSpan('test span'); + context.with(trace.setSpan(context.active(), span), () => { + const sql = 'SELECT 1+? as solution'; + connection.execute(sql, [1], (err, res: RowDataPacket[]) => { + assert.ifError(err); + assert.ok(res); + assert.strictEqual(res[0].solution, 2); + const spans = memoryExporter.getFinishedSpans(); + assert.strictEqual(spans.length, 1); + assertSpan(spans[0], sql, [1]); + done(); + }); }); }); - }); - it('should attach error messages to spans', done => { - const span = provider.getTracer('default').startSpan('test span'); - context.with(trace.setSpan(context.active(), span), () => { - const sql = 'SELECT ? as solution'; - connection.execute(sql, (err, res) => { - assert.ok(err); - const spans = memoryExporter.getFinishedSpans(); - assert.strictEqual(spans.length, 1); - assertSpan(spans[0], sql, undefined, err!.message); - done(); + it('should intercept connection.execute(text: string, value: any, callback)', done => { + const span = provider.getTracer('default').startSpan('test span'); + context.with(trace.setSpan(context.active(), span), () => { + const sql = 'SELECT 1+? as solution'; + connection.execute(sql, [1], (err, res: RowDataPacket[]) => { + assert.ifError(err); + assert.ok(res); + assert.strictEqual(res[0].solution, 2); + const spans = memoryExporter.getFinishedSpans(); + assert.strictEqual(spans.length, 1); + assertSpan(spans[0], sql, [1]); + done(); + }); }); }); - }); - }); - - describe('#Pool.query', () => { - it('should intercept pool.query(text: string)', done => { - const span = provider.getTracer('default').startSpan('test span'); - context.with(trace.setSpan(context.active(), span), () => { - const sql = 'SELECT 1+1 as solution'; - const query = pool.query(sql); - let rows = 0; - - query.on('result', (row: mysqlTypes.RowDataPacket) => { - assert.strictEqual(row.solution, 2); - rows += 1; - }); - query.on('end', () => { - assert.strictEqual(rows, 1); - const spans = memoryExporter.getFinishedSpans(); - assert.strictEqual(spans.length, 1); - assertSpan(spans[0], sql); - done(); + it('should attach error messages to spans', done => { + const span = provider.getTracer('default').startSpan('test span'); + context.with(trace.setSpan(context.active(), span), () => { + const sql = 'SELECT ? as solution'; + connection.execute(sql, (err, res) => { + assert.ok(err); + const spans = memoryExporter.getFinishedSpans(); + assert.strictEqual(spans.length, 1); + assertSpan(spans[0], sql, undefined, err!.message); + done(); + }); }); }); }); - it('should intercept pool.getConnection().query(text: string)', done => { - const span = provider.getTracer('default').startSpan('test span'); - context.with(trace.setSpan(context.active(), span), () => { - const sql = 'SELECT 1+1 as solution'; - pool.getConnection((err, conn) => { - const query = conn.query(sql); + describe('#Pool.query', () => { + it('should intercept pool.query(text: string)', done => { + const span = provider.getTracer('default').startSpan('test span'); + context.with(trace.setSpan(context.active(), span), () => { + const sql = 'SELECT 1+1 as solution'; + const query = pool.query(sql); let rows = 0; - query.on('result', (row: mysqlTypes.RowDataPacket) => { + query.on('result', (row: RowDataPacket) => { assert.strictEqual(row.solution, 2); rows += 1; }); @@ -577,30 +568,36 @@ describe('mysql2', () => { }); }); }); - }); - it('should intercept pool.query(text: string, callback)', done => { - const span = provider.getTracer('default').startSpan('test span'); - context.with(trace.setSpan(context.active(), span), () => { - const sql = 'SELECT 1+1 as solution'; - pool.query(sql, (err, res: mysqlTypes.RowDataPacket[]) => { - assert.ifError(err); - assert.ok(res); - assert.strictEqual(res[0].solution, 2); - const spans = memoryExporter.getFinishedSpans(); - assert.strictEqual(spans.length, 1); - assertSpan(spans[0], sql); - done(); + it('should intercept pool.getConnection().query(text: string)', done => { + const span = provider.getTracer('default').startSpan('test span'); + context.with(trace.setSpan(context.active(), span), () => { + const sql = 'SELECT 1+1 as solution'; + pool.getConnection((err, conn) => { + const query = conn.query(sql); + let rows = 0; + + query.on('result', (row: RowDataPacket) => { + assert.strictEqual(row.solution, 2); + rows += 1; + }); + + query.on('end', () => { + assert.strictEqual(rows, 1); + const spans = memoryExporter.getFinishedSpans(); + assert.strictEqual(spans.length, 1); + assertSpan(spans[0], sql); + done(); + }); + }); }); }); - }); - it('should intercept pool.getConnection().query(text: string, callback)', done => { - const span = provider.getTracer('default').startSpan('test span'); - context.with(trace.setSpan(context.active(), span), () => { - const sql = 'SELECT 1+1 as solution'; - pool.getConnection((err, conn) => { - conn.query(sql, (err, res: mysqlTypes.RowDataPacket[]) => { + it('should intercept pool.query(text: string, callback)', done => { + const span = provider.getTracer('default').startSpan('test span'); + context.with(trace.setSpan(context.active(), span), () => { + const sql = 'SELECT 1+1 as solution'; + pool.query(sql, (err, res: RowDataPacket[]) => { assert.ifError(err); assert.ok(res); assert.strictEqual(res[0].solution, 2); @@ -611,15 +608,30 @@ describe('mysql2', () => { }); }); }); - }); - it('should intercept pool.query(text: options, callback)', done => { - const span = provider.getTracer('default').startSpan('test span'); - context.with(trace.setSpan(context.active(), span), () => { - const sql = 'SELECT 1+? as solution'; - pool.query( - { sql, values: [1] }, - (err, res: mysqlTypes.RowDataPacket[]) => { + it('should intercept pool.getConnection().query(text: string, callback)', done => { + const span = provider.getTracer('default').startSpan('test span'); + context.with(trace.setSpan(context.active(), span), () => { + const sql = 'SELECT 1+1 as solution'; + pool.getConnection((err, conn) => { + conn.query(sql, (err, res: RowDataPacket[]) => { + assert.ifError(err); + assert.ok(res); + assert.strictEqual(res[0].solution, 2); + const spans = memoryExporter.getFinishedSpans(); + assert.strictEqual(spans.length, 1); + assertSpan(spans[0], sql); + done(); + }); + }); + }); + }); + + it('should intercept pool.query(text: options, callback)', done => { + const span = provider.getTracer('default').startSpan('test span'); + context.with(trace.setSpan(context.active(), span), () => { + const sql = 'SELECT 1+? as solution'; + pool.query({ sql, values: [1] }, (err, res: RowDataPacket[]) => { assert.ifError(err); assert.ok(res); assert.strictEqual(res[0].solution, 2); @@ -627,312 +639,186 @@ describe('mysql2', () => { assert.strictEqual(spans.length, 1); assertSpan(spans[0], sql, [1]); done(); - } - ); - }); - }); - - it('should intercept pool.query(text: options, values: [], callback)', done => { - const span = provider.getTracer('default').startSpan('test span'); - context.with(trace.setSpan(context.active(), span), () => { - const sql = 'SELECT 1+? as solution'; - pool.query({ sql }, [1], (err, res: mysqlTypes.RowDataPacket[]) => { - assert.ifError(err); - assert.ok(res); - assert.strictEqual(res[0].solution, 2); - const spans = memoryExporter.getFinishedSpans(); - assert.strictEqual(spans.length, 1); - assertSpan(spans[0], sql, [1]); - done(); - }); - }); - }); - - it('should intercept pool.query(text: string, values: [], callback)', done => { - const span = provider.getTracer('default').startSpan('test span'); - context.with(trace.setSpan(context.active(), span), () => { - const sql = 'SELECT ? as solution'; - pool.query(sql, [1], (err, res: mysqlTypes.RowDataPacket[]) => { - assert.ifError(err); - assert.ok(res); - assert.strictEqual(res[0].solution, 1); - const spans = memoryExporter.getFinishedSpans(); - assert.strictEqual(spans.length, 1); - assertSpan(spans[0], sql, [1]); - done(); - }); - }); - }); - - it('should intercept pool.query(text: string, value: any, callback)', done => { - const span = provider.getTracer('default').startSpan('test span'); - context.with(trace.setSpan(context.active(), span), () => { - const sql = 'SELECT ? as solution'; - pool.query(sql, 1, (err, res: mysqlTypes.RowDataPacket[]) => { - assert.ifError(err); - assert.ok(res); - assert.strictEqual(res[0].solution, 1); - const spans = memoryExporter.getFinishedSpans(); - assert.strictEqual(spans.length, 1); - assertSpan(spans[0], sql, [1]); - done(); - }); - }); - }); - - it('should attach error messages to spans', done => { - const span = provider.getTracer('default').startSpan('test span'); - context.with(trace.setSpan(context.active(), span), () => { - const sql = 'SELECT ? as solution'; - pool.query(sql, (err, res) => { - assert.ok(err); - const spans = memoryExporter.getFinishedSpans(); - assert.strictEqual(spans.length, 1); - assertSpan(spans[0], sql, undefined, err!.message); - done(); + }); }); }); - }); - it('should not add comment by default', done => { - const span = provider.getTracer('default').startSpan('test span'); - context.with(trace.setSpan(context.active(), span), () => { - pool.query('SELECT 1+1 as solution', () => { - const spans = memoryExporter.getFinishedSpans(); - assert.strictEqual(spans.length, 1); - getLastQueries(1).then(([query]) => { - assert.doesNotMatch(query, /.*traceparent.*/); + it('should intercept pool.query(text: options, values: [], callback)', done => { + const span = provider.getTracer('default').startSpan('test span'); + context.with(trace.setSpan(context.active(), span), () => { + const sql = 'SELECT 1+? as solution'; + pool.query({ sql }, [1], (err, res: RowDataPacket[]) => { + assert.ifError(err); + assert.ok(res); + assert.strictEqual(res[0].solution, 2); + const spans = memoryExporter.getFinishedSpans(); + assert.strictEqual(spans.length, 1); + assertSpan(spans[0], sql, [1]); done(); }); }); }); - }); - it('should not add comment when specified if existing block comment', done => { - instrumentation.setConfig({ - addSqlCommenterCommentToQueries: true, - } as any); - const span = provider.getTracer('default').startSpan('test span'); - context.with(trace.setSpan(context.active(), span), () => { - pool.query('SELECT 1+1 as solution /*block comment*/', () => { - const spans = memoryExporter.getFinishedSpans(); - assert.strictEqual(spans.length, 1); - getLastQueries(1).then(([query]) => { - assert.doesNotMatch(query, /.*traceparent.*/); + it('should intercept pool.query(text: string, values: [], callback)', done => { + const span = provider.getTracer('default').startSpan('test span'); + context.with(trace.setSpan(context.active(), span), () => { + const sql = 'SELECT ? as solution'; + pool.query(sql, [1], (err, res: RowDataPacket[]) => { + assert.ifError(err); + assert.ok(res); + assert.strictEqual(res[0].solution, 1); + const spans = memoryExporter.getFinishedSpans(); + assert.strictEqual(spans.length, 1); + assertSpan(spans[0], sql, [1]); done(); }); }); }); - }); - it('should not add comment when specified if existing line comment', done => { - instrumentation.setConfig({ - addSqlCommenterCommentToQueries: true, - } as any); - const span = provider.getTracer('default').startSpan('test span'); - context.with(trace.setSpan(context.active(), span), () => { - pool.query('SELECT 1+1 as solution -- line comment', () => { - const spans = memoryExporter.getFinishedSpans(); - assert.strictEqual(spans.length, 1); - getLastQueries(1).then(([query]) => { - assert.doesNotMatch(query, /.*traceparent.*/); + it('should intercept pool.query(text: string, value: any, callback)', done => { + const span = provider.getTracer('default').startSpan('test span'); + context.with(trace.setSpan(context.active(), span), () => { + const sql = 'SELECT ? as solution'; + pool.query(sql, 1, (err, res: RowDataPacket[]) => { + assert.ifError(err); + assert.ok(res); + assert.strictEqual(res[0].solution, 1); + const spans = memoryExporter.getFinishedSpans(); + assert.strictEqual(spans.length, 1); + assertSpan(spans[0], sql, [1]); done(); }); }); }); - }); - it('should add comment when specified if no existing comment', done => { - instrumentation.setConfig({ - addSqlCommenterCommentToQueries: true, - } as any); - const span = provider.getTracer('default').startSpan('test span'); - context.with(trace.setSpan(context.active(), span), () => { - pool.query('SELECT 1+1 as solution', () => { - const spans = memoryExporter.getFinishedSpans(); - assert.strictEqual(spans.length, 1); - getLastQueries(1).then(([query]) => { - assert.match(query, /.*traceparent.*/); + it('should attach error messages to spans', done => { + const span = provider.getTracer('default').startSpan('test span'); + context.with(trace.setSpan(context.active(), span), () => { + const sql = 'SELECT ? as solution'; + pool.query(sql, (err, res) => { + assert.ok(err); + const spans = memoryExporter.getFinishedSpans(); + assert.strictEqual(spans.length, 1); + assertSpan(spans[0], sql, undefined, err!.message); done(); }); }); }); - }); - }); - describe('#Pool.execute', () => { - it('should intercept pool.execute(text: string)', done => { - const span = provider.getTracer('default').startSpan('test span'); - context.with(trace.setSpan(context.active(), span), () => { - const sql = 'SELECT 1+1 as solution'; - pool.execute(sql, (err, row: mysqlTypes.RowDataPacket[]) => { - assert(!err); - assert.strictEqual(row[0].solution, 2); - const spans = memoryExporter.getFinishedSpans(); - assert.strictEqual(spans.length, 1); - assertSpan(spans[0], sql); - done(); + it('should not add comment by default', done => { + const span = provider.getTracer('default').startSpan('test span'); + context.with(trace.setSpan(context.active(), span), () => { + pool.query('SELECT 1+1 as solution', () => { + const spans = memoryExporter.getFinishedSpans(); + assert.strictEqual(spans.length, 1); + getLastQueries(1).then(([query]) => { + assert.doesNotMatch(query, /.*traceparent.*/); + done(); + }); + }); }); }); - }); - - it('should intercept pool.getConnection().execute(text: string)', done => { - const span = provider.getTracer('default').startSpan('test span'); - context.with(trace.setSpan(context.active(), span), () => { - const sql = 'SELECT 1+1 as solution'; - pool.getConnection((err, conn) => { - const query = conn.execute(sql); - let rows = 0; - - query.on('result', (row: mysqlTypes.RowDataPacket) => { - assert.strictEqual(row.solution, 2); - rows += 1; - }); - query.on('end', () => { - assert.strictEqual(rows, 1); + it('should not add comment when specified if existing block comment', done => { + instrumentation.setConfig({ + addSqlCommenterCommentToQueries: true, + } as any); + const span = provider.getTracer('default').startSpan('test span'); + context.with(trace.setSpan(context.active(), span), () => { + pool.query('SELECT 1+1 as solution /*block comment*/', () => { const spans = memoryExporter.getFinishedSpans(); assert.strictEqual(spans.length, 1); - assertSpan(spans[0], sql); - done(); + getLastQueries(1).then(([query]) => { + assert.doesNotMatch(query, /.*traceparent.*/); + done(); + }); }); }); }); - }); - it('should intercept pool.execute(text: string, callback)', done => { - const span = provider.getTracer('default').startSpan('test span'); - context.with(trace.setSpan(context.active(), span), () => { - const sql = 'SELECT 1+1 as solution'; - pool.execute(sql, (err, res: mysqlTypes.RowDataPacket[]) => { - assert.ifError(err); - assert.ok(res); - assert.strictEqual(res[0].solution, 2); - const spans = memoryExporter.getFinishedSpans(); - assert.strictEqual(spans.length, 1); - assertSpan(spans[0], sql); - done(); + it('should not add comment when specified if existing line comment', done => { + instrumentation.setConfig({ + addSqlCommenterCommentToQueries: true, + } as any); + const span = provider.getTracer('default').startSpan('test span'); + context.with(trace.setSpan(context.active(), span), () => { + pool.query('SELECT 1+1 as solution -- line comment', () => { + const spans = memoryExporter.getFinishedSpans(); + assert.strictEqual(spans.length, 1); + getLastQueries(1).then(([query]) => { + assert.doesNotMatch(query, /.*traceparent.*/); + done(); + }); + }); }); }); - }); - it('should intercept pool.getConnection().execute(text: string, callback)', done => { - const span = provider.getTracer('default').startSpan('test span'); - context.with(trace.setSpan(context.active(), span), () => { - const sql = 'SELECT 1+1 as solution'; - pool.getConnection((err, conn) => { - conn.execute(sql, (err, res: mysqlTypes.RowDataPacket[]) => { - assert.ifError(err); - assert.ok(res); - assert.strictEqual(res[0].solution, 2); + it('should add comment when specified if no existing comment', done => { + instrumentation.setConfig({ + addSqlCommenterCommentToQueries: true, + } as any); + const span = provider.getTracer('default').startSpan('test span'); + context.with(trace.setSpan(context.active(), span), () => { + pool.query('SELECT 1+1 as solution', () => { const spans = memoryExporter.getFinishedSpans(); assert.strictEqual(spans.length, 1); - assertSpan(spans[0], sql); - done(); + getLastQueries(1).then(([query]) => { + assert.match(query, /.*traceparent.*/); + done(); + }); }); }); }); }); - it('should intercept pool.execute(text: options, callback)', done => { - const span = provider.getTracer('default').startSpan('test span'); - context.with(trace.setSpan(context.active(), span), () => { - const sql = 'SELECT 1+? as solution'; - pool.execute( - { sql, values: [1] }, - (err, res: mysqlTypes.RowDataPacket[]) => { - assert.ifError(err); - assert.ok(res); - assert.strictEqual(res[0].solution, 2); + describe('#Pool.execute', () => { + it('should intercept pool.execute(text: string)', done => { + const span = provider.getTracer('default').startSpan('test span'); + context.with(trace.setSpan(context.active(), span), () => { + const sql = 'SELECT 1+1 as solution'; + pool.execute(sql, (err, row: RowDataPacket[]) => { + assert(!err); + assert.strictEqual(row[0].solution, 2); const spans = memoryExporter.getFinishedSpans(); assert.strictEqual(spans.length, 1); assertSpan(spans[0], sql); done(); - } - ); - }); - }); - - it('should intercept pool.execute(text: options, values: [], callback)', done => { - const span = provider.getTracer('default').startSpan('test span'); - context.with(trace.setSpan(context.active(), span), () => { - const sql = 'SELECT 1+? as solution'; - pool.execute({ sql }, [1], (err, res: mysqlTypes.RowDataPacket[]) => { - assert.ifError(err); - assert.ok(res); - assert.strictEqual(res[0].solution, 2); - const spans = memoryExporter.getFinishedSpans(); - assert.strictEqual(spans.length, 1); - assertSpan(spans[0], sql, [1]); - done(); + }); }); }); - }); - it('should intercept pool.execute(text: string, values: [], callback)', done => { - const span = provider.getTracer('default').startSpan('test span'); - context.with(trace.setSpan(context.active(), span), () => { - const sql = 'SELECT 1+? as solution'; - pool.execute(sql, [1], (err, res: mysqlTypes.RowDataPacket[]) => { - assert.ifError(err); - assert.ok(res); - assert.strictEqual(res[0].solution, 2); - const spans = memoryExporter.getFinishedSpans(); - assert.strictEqual(spans.length, 1); - assertSpan(spans[0], sql, [1]); - done(); - }); - }); - }); + it('should intercept pool.getConnection().execute(text: string)', done => { + const span = provider.getTracer('default').startSpan('test span'); + context.with(trace.setSpan(context.active(), span), () => { + const sql = 'SELECT 1+1 as solution'; + pool.getConnection((err, conn) => { + const query = conn.execute(sql); + let rows = 0; - it('should intercept pool.execute(text: string, value: any, callback)', done => { - const span = provider.getTracer('default').startSpan('test span'); - context.with(trace.setSpan(context.active(), span), () => { - const sql = 'SELECT 1+? as solution'; - pool.execute(sql, [1], (err, res: mysqlTypes.RowDataPacket[]) => { - assert.ifError(err); - assert.ok(res); - assert.strictEqual(res[0].solution, 2); - const spans = memoryExporter.getFinishedSpans(); - assert.strictEqual(spans.length, 1); - assertSpan(spans[0], sql, [1]); - done(); - }); - }); - }); + query.on('result', (row: RowDataPacket) => { + assert.strictEqual(row.solution, 2); + rows += 1; + }); - it('should attach error messages to spans', done => { - const span = provider.getTracer('default').startSpan('test span'); - context.with(trace.setSpan(context.active(), span), () => { - const sql = 'SELECT ? as solution'; - pool.execute(sql, (err, res) => { - assert.ok(err); - const spans = memoryExporter.getFinishedSpans(); - assert.strictEqual(spans.length, 1); - assertSpan(spans[0], sql, undefined, err!.message); - done(); + query.on('end', () => { + assert.strictEqual(rows, 1); + const spans = memoryExporter.getFinishedSpans(); + assert.strictEqual(spans.length, 1); + assertSpan(spans[0], sql); + done(); + }); + }); }); }); - }); - }); - describe('#PoolCluster', () => { - it('should intercept poolClusterConnection.query(text: string)', done => { - poolCluster.getConnection((err, poolClusterConnection) => { - assert.ifError(err); + it('should intercept pool.execute(text: string, callback)', done => { const span = provider.getTracer('default').startSpan('test span'); context.with(trace.setSpan(context.active(), span), () => { const sql = 'SELECT 1+1 as solution'; - const query = poolClusterConnection.query(sql); - let rows = 0; - - query.on('result', (row: mysqlTypes.RowDataPacket) => { - assert.strictEqual(row.solution, 2); - rows += 1; - }); - - query.on('end', () => { - assert.strictEqual(rows, 1); + pool.execute(sql, (err, res: RowDataPacket[]) => { + assert.ifError(err); + assert.ok(res); + assert.strictEqual(res[0].solution, 2); const spans = memoryExporter.getFinishedSpans(); assert.strictEqual(spans.length, 1); assertSpan(spans[0], sql); @@ -940,17 +826,13 @@ describe('mysql2', () => { }); }); }); - }); - it('should intercept poolClusterConnection.query(text: string, callback)', done => { - poolCluster.getConnection((err, poolClusterConnection) => { - assert.ifError(err); + it('should intercept pool.getConnection().execute(text: string, callback)', done => { const span = provider.getTracer('default').startSpan('test span'); context.with(trace.setSpan(context.active(), span), () => { const sql = 'SELECT 1+1 as solution'; - poolClusterConnection.query( - sql, - (err, res: mysqlTypes.RowDataPacket[]) => { + pool.getConnection((err, conn) => { + conn.execute(sql, (err, res: RowDataPacket[]) => { assert.ifError(err); assert.ok(res); assert.strictEqual(res[0].solution, 2); @@ -958,110 +840,80 @@ describe('mysql2', () => { assert.strictEqual(spans.length, 1); assertSpan(spans[0], sql); done(); - } - ); + }); + }); }); }); - }); - it('should intercept poolClusterConnection.query(text: options, callback)', done => { - poolCluster.getConnection((err, poolClusterConnection) => { - assert.ifError(err); + it('should intercept pool.execute(text: options, callback)', done => { const span = provider.getTracer('default').startSpan('test span'); context.with(trace.setSpan(context.active(), span), () => { const sql = 'SELECT 1+? as solution'; - poolClusterConnection.query( - { sql, values: [1] }, - (err, res: mysqlTypes.RowDataPacket[]) => { - assert.ifError(err); - assert.ok(res); - assert.strictEqual(res[0].solution, 2); - const spans = memoryExporter.getFinishedSpans(); - assert.strictEqual(spans.length, 1); - assertSpan(spans[0], sql, [1]); - done(); - } - ); + pool.execute({ sql, values: [1] }, (err, res: RowDataPacket[]) => { + assert.ifError(err); + assert.ok(res); + assert.strictEqual(res[0].solution, 2); + const spans = memoryExporter.getFinishedSpans(); + assert.strictEqual(spans.length, 1); + assertSpan(spans[0], sql); + done(); + }); }); }); - }); - it('should intercept poolClusterConnection.query(text: options, values: [], callback)', done => { - poolCluster.getConnection((err, poolClusterConnection) => { - assert.ifError(err); + it('should intercept pool.execute(text: options, values: [], callback)', done => { const span = provider.getTracer('default').startSpan('test span'); context.with(trace.setSpan(context.active(), span), () => { const sql = 'SELECT 1+? as solution'; - poolClusterConnection.query( - { sql }, - [1], - (err, res: mysqlTypes.RowDataPacket[]) => { - assert.ifError(err); - assert.ok(res); - assert.strictEqual(res[0].solution, 2); - const spans = memoryExporter.getFinishedSpans(); - assert.strictEqual(spans.length, 1); - assertSpan(spans[0], sql, [1]); - done(); - } - ); + pool.execute({ sql }, [1], (err, res: RowDataPacket[]) => { + assert.ifError(err); + assert.ok(res); + assert.strictEqual(res[0].solution, 2); + const spans = memoryExporter.getFinishedSpans(); + assert.strictEqual(spans.length, 1); + assertSpan(spans[0], sql, [1]); + done(); + }); }); }); - }); - it('should intercept poolClusterConnection.query(text: string, values: [], callback)', done => { - poolCluster.getConnection((err, poolClusterConnection) => { - assert.ifError(err); + it('should intercept pool.execute(text: string, values: [], callback)', done => { const span = provider.getTracer('default').startSpan('test span'); context.with(trace.setSpan(context.active(), span), () => { - const sql = 'SELECT ? as solution'; - poolClusterConnection.query( - sql, - [1], - (err, res: mysqlTypes.RowDataPacket[]) => { - assert.ifError(err); - assert.ok(res); - assert.strictEqual(res[0].solution, 1); - const spans = memoryExporter.getFinishedSpans(); - assert.strictEqual(spans.length, 1); - assertSpan(spans[0], sql, [1]); - done(); - } - ); + const sql = 'SELECT 1+? as solution'; + pool.execute(sql, [1], (err, res: RowDataPacket[]) => { + assert.ifError(err); + assert.ok(res); + assert.strictEqual(res[0].solution, 2); + const spans = memoryExporter.getFinishedSpans(); + assert.strictEqual(spans.length, 1); + assertSpan(spans[0], sql, [1]); + done(); + }); }); }); - }); - it('should intercept poolClusterConnection.query(text: string, value: any, callback)', done => { - poolCluster.getConnection((err, poolClusterConnection) => { - assert.ifError(err); + it('should intercept pool.execute(text: string, value: any, callback)', done => { const span = provider.getTracer('default').startSpan('test span'); context.with(trace.setSpan(context.active(), span), () => { - const sql = 'SELECT ? as solution'; - poolClusterConnection.query( - sql, - 1, - (err, res: mysqlTypes.RowDataPacket[]) => { - assert.ifError(err); - assert.ok(res); - assert.strictEqual(res[0].solution, 1); - const spans = memoryExporter.getFinishedSpans(); - assert.strictEqual(spans.length, 1); - assertSpan(spans[0], sql, [1]); - done(); - } - ); + const sql = 'SELECT 1+? as solution'; + pool.execute(sql, [1], (err, res: RowDataPacket[]) => { + assert.ifError(err); + assert.ok(res); + assert.strictEqual(res[0].solution, 2); + const spans = memoryExporter.getFinishedSpans(); + assert.strictEqual(spans.length, 1); + assertSpan(spans[0], sql, [1]); + done(); + }); }); }); - }); - it('should attach error messages to spans', done => { - poolCluster.getConnection((err, poolClusterConnection) => { - assert.ifError(err); + it('should attach error messages to spans', done => { const span = provider.getTracer('default').startSpan('test span'); context.with(trace.setSpan(context.active(), span), () => { const sql = 'SELECT ? as solution'; - poolClusterConnection.query(sql, (err, res) => { + pool.execute(sql, (err, res) => { assert.ok(err); const spans = memoryExporter.getFinishedSpans(); assert.strictEqual(spans.length, 1); @@ -1072,108 +924,236 @@ describe('mysql2', () => { }); }); - it('should get connection by name', done => { - poolCluster.getConnection('name', (err, poolClusterConnection) => { - assert.ifError(err); - const span = provider.getTracer('default').startSpan('test span'); - context.with(trace.setSpan(context.active(), span), () => { - const sql = 'SELECT 1 as solution'; - poolClusterConnection.query(sql, (err, res) => { - assert.ifError(err); - const spans = memoryExporter.getFinishedSpans(); - assert.strictEqual(spans.length, 1); - assertSpan(spans[0], sql); - done(); + describe('#PoolCluster', () => { + it('should intercept poolClusterConnection.query(text: string)', done => { + poolCluster.getConnection((err, poolClusterConnection) => { + assert.ifError(err); + const span = provider.getTracer('default').startSpan('test span'); + context.with(trace.setSpan(context.active(), span), () => { + const sql = 'SELECT 1+1 as solution'; + const query = poolClusterConnection.query(sql); + let rows = 0; + + query.on('result', (row: RowDataPacket) => { + assert.strictEqual(row.solution, 2); + rows += 1; + }); + + query.on('end', () => { + assert.strictEqual(rows, 1); + const spans = memoryExporter.getFinishedSpans(); + assert.strictEqual(spans.length, 1); + assertSpan(spans[0], sql); + done(); + }); }); }); }); - }); - it('should get connection by name and selector', done => { - poolCluster.getConnection( - 'name', - 'ORDER', - (err, poolClusterConnection) => { + it('should intercept poolClusterConnection.query(text: string, callback)', done => { + poolCluster.getConnection((err, poolClusterConnection) => { assert.ifError(err); - const sql = 'SELECT 1 as solution'; - poolClusterConnection.query(sql, (err, res) => { - assert.ifError(err); - const spans = memoryExporter.getFinishedSpans(); - assert.strictEqual(spans.length, 1); - assertSpan(spans[0], sql); - done(); + const span = provider.getTracer('default').startSpan('test span'); + context.with(trace.setSpan(context.active(), span), () => { + const sql = 'SELECT 1+1 as solution'; + poolClusterConnection.query(sql, (err, res: RowDataPacket[]) => { + assert.ifError(err); + assert.ok(res); + assert.strictEqual(res[0].solution, 2); + const spans = memoryExporter.getFinishedSpans(); + assert.strictEqual(spans.length, 1); + assertSpan(spans[0], sql); + done(); + }); }); - } - ); - }); - }); - - describe('#responseHook', () => { - const queryResultAttribute = 'query_result'; + }); + }); - describe('invalid response hook', () => { - beforeEach(() => { - const config: MySQL2InstrumentationConfig = { - responseHook: (span, responseHookInfo) => { - throw new Error('random failure!'); - }, - }; - instrumentation.setConfig(config); + it('should intercept poolClusterConnection.query(text: options, callback)', done => { + poolCluster.getConnection((err, poolClusterConnection) => { + assert.ifError(err); + const span = provider.getTracer('default').startSpan('test span'); + context.with(trace.setSpan(context.active(), span), () => { + const sql = 'SELECT 1+? as solution'; + poolClusterConnection.query( + { sql, values: [1] }, + (err, res: RowDataPacket[]) => { + assert.ifError(err); + assert.ok(res); + assert.strictEqual(res[0].solution, 2); + const spans = memoryExporter.getFinishedSpans(); + assert.strictEqual(spans.length, 1); + assertSpan(spans[0], sql, [1]); + done(); + } + ); + }); + }); }); - it('should not affect the behavior of the query', done => { - const span = provider.getTracer('default').startSpan('test span'); - context.with(trace.setSpan(context.active(), span), () => { - const sql = 'SELECT 1+1 as solution'; - connection.query(sql, (err, res: mysqlTypes.RowDataPacket[]) => { - assert.ifError(err); - assert.ok(res); - assert.strictEqual(res[0].solution, 2); - done(); + it('should intercept poolClusterConnection.query(text: options, values: [], callback)', done => { + poolCluster.getConnection((err, poolClusterConnection) => { + assert.ifError(err); + const span = provider.getTracer('default').startSpan('test span'); + context.with(trace.setSpan(context.active(), span), () => { + const sql = 'SELECT 1+? as solution'; + poolClusterConnection.query( + { sql }, + [1], + (err, res: RowDataPacket[]) => { + assert.ifError(err); + assert.ok(res); + assert.strictEqual(res[0].solution, 2); + const spans = memoryExporter.getFinishedSpans(); + assert.strictEqual(spans.length, 1); + assertSpan(spans[0], sql, [1]); + done(); + } + ); }); }); }); - }); - describe('valid response hook', () => { - beforeEach(() => { - const config: MySQL2InstrumentationConfig = { - responseHook: (span, responseHookInfo) => { - span.setAttribute( - queryResultAttribute, - JSON.stringify(responseHookInfo.queryResults) + it('should intercept poolClusterConnection.query(text: string, values: [], callback)', done => { + poolCluster.getConnection((err, poolClusterConnection) => { + assert.ifError(err); + const span = provider.getTracer('default').startSpan('test span'); + context.with(trace.setSpan(context.active(), span), () => { + const sql = 'SELECT ? as solution'; + poolClusterConnection.query( + sql, + [1], + (err, res: RowDataPacket[]) => { + assert.ifError(err); + assert.ok(res); + assert.strictEqual(res[0].solution, 1); + const spans = memoryExporter.getFinishedSpans(); + assert.strictEqual(spans.length, 1); + assertSpan(spans[0], sql, [1]); + done(); + } ); - }, - }; - instrumentation.setConfig(config); + }); + }); }); - it('should extract data from responseHook - connection', done => { - const span = provider.getTracer('default').startSpan('test span'); - context.with(trace.setSpan(context.active(), span), () => { - const sql = 'SELECT 1+1 as solution'; - connection.query(sql, (err, res: mysqlTypes.RowDataPacket[]) => { + it('should intercept poolClusterConnection.query(text: string, value: any, callback)', done => { + poolCluster.getConnection((err, poolClusterConnection) => { + assert.ifError(err); + const span = provider.getTracer('default').startSpan('test span'); + context.with(trace.setSpan(context.active(), span), () => { + const sql = 'SELECT ? as solution'; + poolClusterConnection.query(sql, 1, (err, res: RowDataPacket[]) => { + assert.ifError(err); + assert.ok(res); + assert.strictEqual(res[0].solution, 1); + const spans = memoryExporter.getFinishedSpans(); + assert.strictEqual(spans.length, 1); + assertSpan(spans[0], sql, [1]); + done(); + }); + }); + }); + }); + + it('should attach error messages to spans', done => { + poolCluster.getConnection((err, poolClusterConnection) => { + assert.ifError(err); + const span = provider.getTracer('default').startSpan('test span'); + context.with(trace.setSpan(context.active(), span), () => { + const sql = 'SELECT ? as solution'; + poolClusterConnection.query(sql, (err, res) => { + assert.ok(err); + const spans = memoryExporter.getFinishedSpans(); + assert.strictEqual(spans.length, 1); + assertSpan(spans[0], sql, undefined, err!.message); + done(); + }); + }); + }); + }); + + it('should get connection by name', done => { + poolCluster.getConnection('name', (err, poolClusterConnection) => { + assert.ifError(err); + const span = provider.getTracer('default').startSpan('test span'); + context.with(trace.setSpan(context.active(), span), () => { + const sql = 'SELECT 1 as solution'; + poolClusterConnection.query(sql, (err, res) => { + assert.ifError(err); + const spans = memoryExporter.getFinishedSpans(); + assert.strictEqual(spans.length, 1); + assertSpan(spans[0], sql); + done(); + }); + }); + }); + }); + + it('should get connection by name and selector', done => { + poolCluster.getConnection( + 'name', + 'ORDER', + (err, poolClusterConnection) => { assert.ifError(err); - assert.ok(res); - assert.strictEqual(res[0].solution, 2); - const spans = memoryExporter.getFinishedSpans(); - assert.strictEqual(spans.length, 1); - assertSpan(spans[0], sql); - assert.strictEqual( - spans[0].attributes[queryResultAttribute], - JSON.stringify(res) - ); - done(); + const sql = 'SELECT 1 as solution'; + poolClusterConnection.query(sql, (err, res) => { + assert.ifError(err); + const spans = memoryExporter.getFinishedSpans(); + assert.strictEqual(spans.length, 1); + assertSpan(spans[0], sql); + done(); + }); + } + ); + }); + }); + + describe('#responseHook', () => { + const queryResultAttribute = 'query_result'; + + describe('invalid response hook', () => { + beforeEach(() => { + const config: MySQL2InstrumentationConfig = { + responseHook: (span, responseHookInfo) => { + throw new Error('random failure!'); + }, + }; + instrumentation.setConfig(config); + }); + + it('should not affect the behavior of the query', done => { + const span = provider.getTracer('default').startSpan('test span'); + context.with(trace.setSpan(context.active(), span), () => { + const sql = 'SELECT 1+1 as solution'; + connection.query(sql, (err, res: RowDataPacket[]) => { + assert.ifError(err); + assert.ok(res); + assert.strictEqual(res[0].solution, 2); + done(); + }); }); }); }); - it('should extract data from responseHook - pool', done => { - const span = provider.getTracer('default').startSpan('test span'); - context.with(trace.setSpan(context.active(), span), () => { - const sql = 'SELECT 1+1 as solution'; - pool.getConnection((err, conn) => { - conn.query(sql, (err, res: mysqlTypes.RowDataPacket[]) => { + describe('valid response hook', () => { + beforeEach(() => { + const config: MySQL2InstrumentationConfig = { + responseHook: (span, responseHookInfo) => { + span.setAttribute( + queryResultAttribute, + JSON.stringify(responseHookInfo.queryResults) + ); + }, + }; + instrumentation.setConfig(config); + }); + + it('should extract data from responseHook - connection', done => { + const span = provider.getTracer('default').startSpan('test span'); + context.with(trace.setSpan(context.active(), span), () => { + const sql = 'SELECT 1+1 as solution'; + connection.query(sql, (err, res: RowDataPacket[]) => { assert.ifError(err); assert.ok(res); assert.strictEqual(res[0].solution, 2); @@ -1188,17 +1168,13 @@ describe('mysql2', () => { }); }); }); - }); - it('should extract data from responseHook - poolCluster', done => { - poolCluster.getConnection((err, poolClusterConnection) => { - assert.ifError(err); + it('should extract data from responseHook - pool', done => { const span = provider.getTracer('default').startSpan('test span'); context.with(trace.setSpan(context.active(), span), () => { const sql = 'SELECT 1+1 as solution'; - poolClusterConnection.query( - sql, - (err, res: mysqlTypes.RowDataPacket[]) => { + pool.getConnection((err, conn) => { + conn.query(sql, (err, res: RowDataPacket[]) => { assert.ifError(err); assert.ok(res); assert.strictEqual(res[0].solution, 2); @@ -1210,13 +1186,160 @@ describe('mysql2', () => { JSON.stringify(res) ); done(); - } - ); + }); + }); + }); + }); + + it('should extract data from responseHook - poolCluster', done => { + poolCluster.getConnection((err, poolClusterConnection) => { + assert.ifError(err); + const span = provider.getTracer('default').startSpan('test span'); + context.with(trace.setSpan(context.active(), span), () => { + const sql = 'SELECT 1+1 as solution'; + poolClusterConnection.query(sql, (err, res: RowDataPacket[]) => { + assert.ifError(err); + assert.ok(res); + assert.strictEqual(res[0].solution, 2); + const spans = memoryExporter.getFinishedSpans(); + assert.strictEqual(spans.length, 1); + assertSpan(spans[0], sql); + assert.strictEqual( + spans[0].attributes[queryResultAttribute], + JSON.stringify(res) + ); + done(); + }); + }); }); }); }); }); }); + describe('promise API', () => { + let instrumentation: MySQL2Instrumentation; + + let contextManager: AsyncHooksContextManager; + const memoryExporter = new InMemorySpanExporter(); + const provider = new BasicTracerProvider({ + spanProcessors: [new SimpleSpanProcessor(memoryExporter)], + }); + let connection: ConnectionAsync; + let rootConnection: ConnectionAsync; + let createConnection: typeof createConnectionAsync; + + before(async function () { + // cleanup cache for 'mysql2' + // in previous iterations these tests would have passed since 'mysql2' was already loaded, + // but 'mysql2/promise' does not import 'mysql2'. Therefore, if used without ever loading 'mysql2', + // the relevant code would never get patched. + delete require.cache[require.resolve('../src')]; + Object.keys(require.cache).forEach(key => { + if (key.includes('mysql2/')) { + delete require.cache[key]; + } + }); + + const { MySQL2Instrumentation } = await import('../src'); + instrumentation = new MySQL2Instrumentation(); + instrumentation.enable(); + instrumentation.disable(); + + createConnection = (await import('mysql2/promise')).createConnection; + + if (!shouldTest) { + // this.skip() workaround + // https://github.com/mochajs/mocha/issues/2683#issuecomment-375629901 + this.test!.parent!.pending = true; + this.skip(); + } + rootConnection = await createConnection({ + port, + user: 'root', + host, + password: rootPassword, + database, + }); + }); + + after(async function () { + await rootConnection.end(); + }); + + beforeEach(async () => { + instrumentation.disable(); + contextManager = new AsyncHooksContextManager().enable(); + context.setGlobalContextManager(contextManager); + instrumentation.setTracerProvider(provider); + instrumentation.enable(); + connection = await createConnection({ + port, + user, + host, + password, + database, + }); + }); + + afterEach(async () => { + context.disable(); + memoryExporter.reset(); + instrumentation.setConfig({}); + instrumentation.disable(); + await connection.end(); + }); + + it('should attach error messages to spans', async () => { + const span = provider.getTracer('default').startSpan('test span'); + await context.with(trace.setSpan(context.active(), span), async () => { + const sql = 'SELECT ? as solution'; + let err: Error; + await assert.rejects(async () => { + try { + await connection.execute(sql); + } catch (e) { + err = e instanceof Error ? e : new Error(e as string); + throw e; + } + }); + const spans = memoryExporter.getFinishedSpans(); + assert.strictEqual(spans.length, 1); + assertSpan(spans[0], sql, undefined, err!.message); + }); + }); + + describe('#Connection.query', () => { + it('should intercept connection.query(text: string)', async () => { + const span = provider.getTracer('default').startSpan('test span'); + await context.with(trace.setSpan(context.active(), span), async () => { + const sql = 'SELECT 1+1 as solution'; + const result = await connection.query(sql); + const rows = result[0]; + assert.strictEqual(rows.length, 1); + assert.strictEqual(rows[0].solution, 2); + const spans = memoryExporter.getFinishedSpans(); + assert.strictEqual(spans.length, 1); + assertSpan(spans[0], sql); + }); + }); + }); + + describe('#Connection.execute', () => { + it('should intercept connection.execute(text: string, phs: [])', async () => { + const span = provider.getTracer('default').startSpan('test span'); + await context.with(trace.setSpan(context.active(), span), async () => { + const sql = 'SELECT 1+? as solution'; + const result = await connection.execute(sql, [1]); + const rows = result[0]; + assert.strictEqual(rows.length, 1); + assert.strictEqual(rows[0].solution, 2); + const spans = memoryExporter.getFinishedSpans(); + assert.strictEqual(spans.length, 1); + assertSpan(spans[0], sql, [1]); + }); + }); + }); + }); }); function assertSpan( @@ -1232,7 +1355,7 @@ function assertSpan( assert.strictEqual(span.attributes[SEMATTRS_DB_USER], user); assert.strictEqual( span.attributes[SEMATTRS_DB_STATEMENT], - mysqlTypes.format(sql, values) + format(sql, values) ); if (errorMessage) { assert.strictEqual(span.status.message, errorMessage); diff --git a/plugins/node/opentelemetry-instrumentation-nestjs-core/test/index.test.ts b/plugins/node/opentelemetry-instrumentation-nestjs-core/test/index.test.ts index 236ade682d..aca1d7b3db 100644 --- a/plugins/node/opentelemetry-instrumentation-nestjs-core/test/index.test.ts +++ b/plugins/node/opentelemetry-instrumentation-nestjs-core/test/index.test.ts @@ -38,8 +38,9 @@ util.inspect.defaultOptions.depth = 3; util.inspect.defaultOptions.breakLength = 200; describe('nestjs-core', () => { - const provider = new NodeTracerProvider(); - provider.addSpanProcessor(new SimpleSpanProcessor(memoryExporter)); + const provider = new NodeTracerProvider({ + spanProcessors: [new SimpleSpanProcessor(memoryExporter)], + }); instrumentation.setTracerProvider(provider); let contextManager: AsyncHooksContextManager; let app: App; diff --git a/plugins/node/opentelemetry-instrumentation-net/test/connect.test.ts b/plugins/node/opentelemetry-instrumentation-net/test/connect.test.ts index 55849289ee..7090311229 100644 --- a/plugins/node/opentelemetry-instrumentation-net/test/connect.test.ts +++ b/plugins/node/opentelemetry-instrumentation-net/test/connect.test.ts @@ -28,8 +28,9 @@ import { SocketEvent } from '../src/internal-types'; import { assertIpcSpan, assertTcpSpan, IPC_PATH, HOST, PORT } from './utils'; const memoryExporter = new InMemorySpanExporter(); -const provider = new NodeTracerProvider(); -provider.addSpanProcessor(new SimpleSpanProcessor(memoryExporter)); +const provider = new NodeTracerProvider({ + spanProcessors: [new SimpleSpanProcessor(memoryExporter)], +}); function getSpan() { const spans = memoryExporter.getFinishedSpans(); diff --git a/plugins/node/opentelemetry-instrumentation-net/test/instrument.test.ts b/plugins/node/opentelemetry-instrumentation-net/test/instrument.test.ts index 09319a5808..6c8e933a39 100644 --- a/plugins/node/opentelemetry-instrumentation-net/test/instrument.test.ts +++ b/plugins/node/opentelemetry-instrumentation-net/test/instrument.test.ts @@ -27,9 +27,10 @@ import * as net from 'net'; import { HOST, PORT } from './utils'; const memoryExporter = new InMemorySpanExporter(); -const provider = new NodeTracerProvider(); +const provider = new NodeTracerProvider({ + spanProcessors: [new SimpleSpanProcessor(memoryExporter)], +}); const tracer = provider.getTracer('default'); -provider.addSpanProcessor(new SimpleSpanProcessor(memoryExporter)); describe('NetInstrumentation', () => { let instrumentation: NetInstrumentation; diff --git a/plugins/node/opentelemetry-instrumentation-net/test/tls.test.ts b/plugins/node/opentelemetry-instrumentation-net/test/tls.test.ts index 0052a4787c..e3232d46fd 100644 --- a/plugins/node/opentelemetry-instrumentation-net/test/tls.test.ts +++ b/plugins/node/opentelemetry-instrumentation-net/test/tls.test.ts @@ -34,8 +34,9 @@ import { } from './utils'; const memoryExporter = new InMemorySpanExporter(); -const provider = new NodeTracerProvider(); -provider.addSpanProcessor(new SimpleSpanProcessor(memoryExporter)); +const provider = new NodeTracerProvider({ + spanProcessors: [new SimpleSpanProcessor(memoryExporter)], +}); function getTLSSpans() { const spans = memoryExporter.getFinishedSpans(); diff --git a/plugins/node/opentelemetry-instrumentation-pg/package.json b/plugins/node/opentelemetry-instrumentation-pg/package.json index 4698da4a5c..bc2ec76777 100644 --- a/plugins/node/opentelemetry-instrumentation-pg/package.json +++ b/plugins/node/opentelemetry-instrumentation-pg/package.json @@ -71,7 +71,7 @@ "dependencies": { "@opentelemetry/core": "^1.26.0", "@opentelemetry/instrumentation": "^0.57.0", - "@opentelemetry/semantic-conventions": "1.27.0", + "@opentelemetry/semantic-conventions": "^1.27.0", "@opentelemetry/sql-common": "^0.40.1", "@types/pg": "8.6.1", "@types/pg-pool": "2.0.6" diff --git a/plugins/node/opentelemetry-instrumentation-pg/src/instrumentation.ts b/plugins/node/opentelemetry-instrumentation-pg/src/instrumentation.ts index 933796be7c..56029e568e 100644 --- a/plugins/node/opentelemetry-instrumentation-pg/src/instrumentation.ts +++ b/plugins/node/opentelemetry-instrumentation-pg/src/instrumentation.ts @@ -18,6 +18,7 @@ import { InstrumentationBase, InstrumentationNodeModuleDefinition, safeExecuteInTheMiddle, + InstrumentationNodeModuleFile, } from '@opentelemetry/instrumentation'; import { context, @@ -65,7 +66,13 @@ import { METRIC_DB_CLIENT_OPERATION_DURATION, ATTR_DB_NAMESPACE, ATTR_DB_OPERATION_NAME, -} from '@opentelemetry/semantic-conventions/incubating'; +} from './semconv'; + +function extractModuleExports(module: any) { + return module[Symbol.toStringTag] === 'Module' + ? module.default // ESM + : module; // CommonJS +} export class PgInstrumentation extends InstrumentationBase { private _operationDuration!: Histogram; @@ -125,45 +132,38 @@ export class PgInstrumentation extends InstrumentationBase=8.0.3 <9'], - (module: any) => { - const moduleExports: typeof pgTypes = - module[Symbol.toStringTag] === 'Module' - ? module.default // ESM - : module; // CommonJS - if (isWrapped(moduleExports.Client.prototype.query)) { - this._unwrap(moduleExports.Client.prototype, 'query'); - } + const SUPPORTED_PG_VERSIONS = ['>=8.0.3 <9']; - if (isWrapped(moduleExports.Client.prototype.connect)) { - this._unwrap(moduleExports.Client.prototype, 'connect'); - } + const modulePgNativeClient = new InstrumentationNodeModuleFile( + 'pg/lib/native/client.js', + SUPPORTED_PG_VERSIONS, + this._patchPgClient.bind(this), + this._unpatchPgClient.bind(this) + ); - this._wrap( - moduleExports.Client.prototype, - 'query', - this._getClientQueryPatch() as any - ); + const modulePgClient = new InstrumentationNodeModuleFile( + 'pg/lib/client.js', + SUPPORTED_PG_VERSIONS, + this._patchPgClient.bind(this), + this._unpatchPgClient.bind(this) + ); - this._wrap( - moduleExports.Client.prototype, - 'connect', - this._getClientConnectPatch() as any - ); + const modulePG = new InstrumentationNodeModuleDefinition( + 'pg', + SUPPORTED_PG_VERSIONS, + (module: any) => { + const moduleExports = extractModuleExports(module); + this._patchPgClient(moduleExports.Client); return module; }, (module: any) => { - const moduleExports: typeof pgTypes = - module[Symbol.toStringTag] === 'Module' - ? module.default // ESM - : module; // CommonJS - if (isWrapped(moduleExports.Client.prototype.query)) { - this._unwrap(moduleExports.Client.prototype, 'query'); - } - } + const moduleExports = extractModuleExports(module); + + this._unpatchPgClient(moduleExports.Client); + return module; + }, + [modulePgClient, modulePgNativeClient] ); const modulePGPool = new InstrumentationNodeModuleDefinition( @@ -190,6 +190,50 @@ export class PgInstrumentation extends InstrumentationBase { diff --git a/plugins/node/opentelemetry-instrumentation-pg/src/semconv.ts b/plugins/node/opentelemetry-instrumentation-pg/src/semconv.ts new file mode 100644 index 0000000000..f7a2ba5624 --- /dev/null +++ b/plugins/node/opentelemetry-instrumentation-pg/src/semconv.ts @@ -0,0 +1,100 @@ +/* + * Copyright The OpenTelemetry Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * The name of the connection pool; unique within the instrumented application. In case the connection pool implementation doesn't provide a name, instrumentation **SHOULD** use a combination of parameters that would make the name unique, for example, combining attributes `server.address`, `server.port`, and `db.namespace`, formatted as `server.address:server.port/db.namespace`. Instrumentations that generate connection pool name following different patterns **SHOULD** document it. + * + * @example myDataSource + * + * @experimental This attribute is experimental and is subject to breaking changes in minor releases of `@opentelemetry/semantic-conventions`. + */ +export const ATTR_DB_CLIENT_CONNECTION_POOL_NAME = + 'db.client.connection.pool.name'; + +/** + * The state of a connection in the pool + * + * @example idle + * + * @experimental This attribute is experimental and is subject to breaking changes in minor releases of `@opentelemetry/semantic-conventions`. + */ +export const ATTR_DB_CLIENT_CONNECTION_STATE = 'db.client.connection.state'; + +/** + * The name of the database, fully qualified within the server address and port. + * + * @example customers + * @example test.users + * + * @note If a database system has multiple namespace components, they **SHOULD** be concatenated (potentially using database system specific conventions) from most general to most specific namespace component, and more specific namespaces **SHOULD NOT** be captured without the more general namespaces, to ensure that "startswith" queries for the more general namespaces will be valid. + * Semantic conventions for individual database systems **SHOULD** document what `db.namespace` means in the context of that system. + * It is **RECOMMENDED** to capture the value as provided by the application without attempting to do any case normalization. + * This attribute has stability level RELEASE CANDIDATE. + * + * @experimental This attribute is experimental and is subject to breaking changes in minor releases of `@opentelemetry/semantic-conventions`. + */ +export const ATTR_DB_NAMESPACE = 'db.namespace'; + +/** + * The name of the operation or command being executed. + * + * @example findAndModify + * @example HMSET + * @example SELECT + * + * @note It is **RECOMMENDED** to capture the value as provided by the application without attempting to do any case normalization. + * If the operation name is parsed from the query text, it **SHOULD** be the first operation name found in the query. + * For batch operations, if the individual operations are known to have the same operation name then that operation name **SHOULD** be used prepended by `BATCH `, otherwise `db.operation.name` **SHOULD** be `BATCH` or some other database system specific term if more applicable. + * This attribute has stability level RELEASE CANDIDATE. + * + * @experimental This attribute is experimental and is subject to breaking changes in minor releases of `@opentelemetry/semantic-conventions`. + */ +export const ATTR_DB_OPERATION_NAME = 'db.operation.name'; + +/** + * Enum value "used" for attribute {@link ATTR_DB_CLIENT_CONNECTION_STATE}. + */ +export const DB_CLIENT_CONNECTION_STATE_VALUE_USED = 'used'; + +/** + * Enum value "idle" for attribute {@link ATTR_DB_CLIENT_CONNECTION_STATE}. + */ +export const DB_CLIENT_CONNECTION_STATE_VALUE_IDLE = 'idle'; + +/** + * The number of connections that are currently in state described by the `state` attribute + * + * @experimental This metric is experimental and is subject to breaking changes in minor releases of `@opentelemetry/semantic-conventions`. + */ +export const METRIC_DB_CLIENT_CONNECTION_COUNT = 'db.client.connection.count'; + +/** + * The number of current pending requests for an open connection + * + * @experimental This metric is experimental and is subject to breaking changes in minor releases of `@opentelemetry/semantic-conventions`. + */ +export const METRIC_DB_CLIENT_CONNECTION_PENDING_REQUESTS = + 'db.client.connection.pending_requests'; + +/** + * Duration of database client operations. + * + * @note Batch operations **SHOULD** be recorded as a single operation. + * + * @experimental This metric is experimental and is subject to breaking changes in minor releases of `@opentelemetry/semantic-conventions`. + */ +export const METRIC_DB_CLIENT_OPERATION_DURATION = + 'db.client.operation.duration'; diff --git a/plugins/node/opentelemetry-instrumentation-pg/src/utils.ts b/plugins/node/opentelemetry-instrumentation-pg/src/utils.ts index de21084a95..c4ebd05640 100644 --- a/plugins/node/opentelemetry-instrumentation-pg/src/utils.ts +++ b/plugins/node/opentelemetry-instrumentation-pg/src/utils.ts @@ -42,7 +42,7 @@ import { ATTR_DB_CLIENT_CONNECTION_STATE, DB_CLIENT_CONNECTION_STATE_VALUE_USED, DB_CLIENT_CONNECTION_STATE_VALUE_IDLE, -} from '@opentelemetry/semantic-conventions/incubating'; +} from './semconv'; import { PgClientExtended, PostgresCallback, diff --git a/plugins/node/opentelemetry-instrumentation-pg/test/fixtures/use-pg.mjs b/plugins/node/opentelemetry-instrumentation-pg/test/fixtures/use-pg.mjs new file mode 100644 index 0000000000..a9c8c5a6a4 --- /dev/null +++ b/plugins/node/opentelemetry-instrumentation-pg/test/fixtures/use-pg.mjs @@ -0,0 +1,57 @@ +/* + * Copyright The OpenTelemetry Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +// Use postgres from an ES module: +// node --experimental-loader=@opentelemetry/instrumentation/hook.mjs use-pg.mjs + +import { trace } from '@opentelemetry/api'; +import { createTestNodeSdk } from '@opentelemetry/contrib-test-utils'; +import assert from 'assert'; + +import { PgInstrumentation } from '../../build/src/index.js'; + +const CONFIG = { + user: process.env.POSTGRES_USER || 'postgres', + password: process.env.POSTGRES_PASSWORD || 'postgres', + database: process.env.POSTGRES_DB || 'postgres', + host: process.env.POSTGRES_HOST || 'localhost', + port: process.env.POSTGRES_PORT + ? parseInt(process.env.POSTGRES_PORT, 10) + : 54320, +}; + +const sdk = createTestNodeSdk({ + serviceName: 'use-pg', + instrumentations: [new PgInstrumentation()], +}); +sdk.start(); + +import pg from 'pg'; +const client = new pg.Client(CONFIG); + +await client.connect(); + +const tracer = trace.getTracer(); + +await tracer.startActiveSpan('test-span', async span => { + const res = await client.query('SELECT NOW()'); + + assert.ok(res); + span.end(); + + await client.end(); + await sdk.shutdown(); +}); diff --git a/plugins/node/opentelemetry-instrumentation-pg/test/pg-pool.test.ts b/plugins/node/opentelemetry-instrumentation-pg/test/pg-pool.test.ts index f0ac1508d9..d75eea6cb6 100644 --- a/plugins/node/opentelemetry-instrumentation-pg/test/pg-pool.test.ts +++ b/plugins/node/opentelemetry-instrumentation-pg/test/pg-pool.test.ts @@ -55,7 +55,7 @@ import { METRIC_DB_CLIENT_CONNECTION_COUNT, METRIC_DB_CLIENT_CONNECTION_PENDING_REQUESTS, METRIC_DB_CLIENT_OPERATION_DURATION, -} from '@opentelemetry/semantic-conventions/incubating'; +} from '../src/semconv'; const memoryExporter = new InMemorySpanExporter(); @@ -114,12 +114,18 @@ describe('pg-pool', () => { function create(config: PgInstrumentationConfig = {}) { instrumentation.setConfig(config); instrumentation.enable(); + + // Disable and enable the instrumentation to visit unwrap calls + instrumentation.disable(); + instrumentation.enable(); } let pool: pgPool; let contextManager: AsyncHooksContextManager; let instrumentation: PgInstrumentation; - const provider = new BasicTracerProvider(); + const provider = new BasicTracerProvider({ + spanProcessors: [new SimpleSpanProcessor(memoryExporter)], + }); const testPostgres = process.env.RUN_POSTGRES_TESTS; // For CI: assumes local postgres db is already available const testPostgresLocally = process.env.RUN_POSTGRES_TESTS_LOCAL; // For local: spins up local postgres db via docker @@ -137,7 +143,6 @@ describe('pg-pool', () => { skip(); } - provider.addSpanProcessor(new SimpleSpanProcessor(memoryExporter)); if (testPostgresLocally) { testUtils.startDocker('postgres'); } diff --git a/plugins/node/opentelemetry-instrumentation-pg/test/pg.test.ts b/plugins/node/opentelemetry-instrumentation-pg/test/pg.test.ts index b7169ec785..f842b1316c 100644 --- a/plugins/node/opentelemetry-instrumentation-pg/test/pg.test.ts +++ b/plugins/node/opentelemetry-instrumentation-pg/test/pg.test.ts @@ -56,7 +56,7 @@ import { import { METRIC_DB_CLIENT_OPERATION_DURATION, ATTR_DB_OPERATION_NAME, -} from '@opentelemetry/semantic-conventions/incubating'; +} from '../src/semconv'; import { addSqlCommenterComment } from '@opentelemetry/sql-common'; const memoryExporter = new InMemorySpanExporter(); @@ -108,13 +108,19 @@ describe('pg', () => { function create(config: PgInstrumentationConfig = {}) { instrumentation.setConfig(config); instrumentation.enable(); + + // Disable and enable the instrumentation to visit unwrap calls + instrumentation.disable(); + instrumentation.enable(); } let postgres: typeof pg; let client: pg.Client; let instrumentation: PgInstrumentation; let contextManager: AsyncHooksContextManager; - const provider = new BasicTracerProvider(); + const provider = new BasicTracerProvider({ + spanProcessors: [new SimpleSpanProcessor(memoryExporter)], + }); const tracer = provider.getTracer('external'); const testPostgres = process.env.RUN_POSTGRES_TESTS; // For CI: assumes local postgres db is already available @@ -139,7 +145,6 @@ describe('pg', () => { skip(); } - provider.addSpanProcessor(new SimpleSpanProcessor(memoryExporter)); if (testPostgresLocally) { testUtils.startDocker('postgres'); } @@ -152,6 +157,7 @@ describe('pg', () => { postgres = require('pg'); client = new postgres.Client(CONFIG); + await client.connect(); }); @@ -159,6 +165,7 @@ describe('pg', () => { if (testPostgresLocally) { testUtils.cleanUpDocker('postgres'); } + await client.end(); }); @@ -1087,3 +1094,32 @@ describe('pg', () => { }); }); }); + +describe('pg (ESM)', () => { + it('should work with ESM usage', async () => { + await testUtils.runTestFixture({ + cwd: __dirname, + argv: ['fixtures/use-pg.mjs'], + env: { + NODE_OPTIONS: + '--experimental-loader=@opentelemetry/instrumentation/hook.mjs', + NODE_NO_WARNINGS: '1', + }, + checkResult: (err, stdout, stderr) => { + assert.ifError(err); + }, + checkCollector: (collector: testUtils.TestCollector) => { + const spans = collector.sortedSpans; + + assert.strictEqual(spans.length, 3); + + assert.strictEqual(spans[0].name, 'pg.connect'); + assert.strictEqual(spans[0].kind, 3); + assert.strictEqual(spans[1].name, 'test-span'); + assert.strictEqual(spans[1].kind, 1); + assert.strictEqual(spans[2].name, 'pg.query:SELECT otel_pg_database'); + assert.strictEqual(spans[2].kind, 3); + }, + }); + }); +}); diff --git a/plugins/node/opentelemetry-instrumentation-pg/test/utils.test.ts b/plugins/node/opentelemetry-instrumentation-pg/test/utils.test.ts index a76bb61988..68f16e1b27 100644 --- a/plugins/node/opentelemetry-instrumentation-pg/test/utils.test.ts +++ b/plugins/node/opentelemetry-instrumentation-pg/test/utils.test.ts @@ -49,16 +49,14 @@ const getLatestSpan = () => { describe('utils.ts', () => { const client = new pg.Client(CONFIG) as PgClientExtended; let contextManager: AsyncHooksContextManager; - const provider = new BasicTracerProvider(); + const provider = new BasicTracerProvider({ + spanProcessors: [new SimpleSpanProcessor(memoryExporter)], + }); const tracer = provider.getTracer('external'); const instrumentationConfig: PgInstrumentationConfig & InstrumentationConfig = {}; - before(() => { - provider.addSpanProcessor(new SimpleSpanProcessor(memoryExporter)); - }); - beforeEach(() => { contextManager = new AsyncHooksContextManager().enable(); context.setGlobalContextManager(contextManager); diff --git a/plugins/node/opentelemetry-instrumentation-pino/test/pino.test.ts b/plugins/node/opentelemetry-instrumentation-pino/test/pino.test.ts index 6f03e197cd..3c3f805ee6 100644 --- a/plugins/node/opentelemetry-instrumentation-pino/test/pino.test.ts +++ b/plugins/node/opentelemetry-instrumentation-pino/test/pino.test.ts @@ -45,11 +45,10 @@ import { PACKAGE_NAME, PACKAGE_VERSION } from '../src/version'; import type { pino as Pino } from 'pino'; -const tracerProvider = new NodeTracerProvider(); +const tracerProvider = new NodeTracerProvider({ + spanProcessors: [new SimpleSpanProcessor(new InMemorySpanExporter())], +}); tracerProvider.register(); -tracerProvider.addSpanProcessor( - new SimpleSpanProcessor(new InMemorySpanExporter()) -); const tracer = tracerProvider.getTracer('default'); // Setup LoggerProvider for "log sending" tests. diff --git a/plugins/node/opentelemetry-instrumentation-redis/test/redis.test.ts b/plugins/node/opentelemetry-instrumentation-redis/test/redis.test.ts index 13113a2f3d..23f9cd3512 100644 --- a/plugins/node/opentelemetry-instrumentation-redis/test/redis.test.ts +++ b/plugins/node/opentelemetry-instrumentation-redis/test/redis.test.ts @@ -68,7 +68,9 @@ const unsetStatus: SpanStatus = { }; describe('redis@2.x', () => { - const provider = new NodeTracerProvider(); + const provider = new NodeTracerProvider({ + spanProcessors: [new SimpleSpanProcessor(memoryExporter)], + }); const tracer = provider.getTracer('external'); let redis: typeof redisTypes; const shouldTestLocal = process.env.RUN_REDIS_TESTS_LOCAL; @@ -98,7 +100,6 @@ describe('redis@2.x', () => { } redis = require('redis'); - provider.addSpanProcessor(new SimpleSpanProcessor(memoryExporter)); instrumentation.setTracerProvider(provider); instrumentation.enable(); }); diff --git a/plugins/node/opentelemetry-instrumentation-restify/README.md b/plugins/node/opentelemetry-instrumentation-restify/README.md index 1894864da5..3115cba564 100644 --- a/plugins/node/opentelemetry-instrumentation-restify/README.md +++ b/plugins/node/opentelemetry-instrumentation-restify/README.md @@ -27,9 +27,12 @@ const { ConsoleSpanExporter, SimpleSpanProcessor } = require('@opentelemetry/sdk const { NodeTracerProvider } = require('@opentelemetry/sdk-trace-node'); const { registerInstrumentations } = require('@opentelemetry/instrumentation'); -const provider = new NodeTracerProvider(); +const provider = new NodeTracerProvider({ + spanProcessors: [ + new SimpleSpanProcessor(new ConsoleSpanExporter()), + ] +}); -provider.addSpanProcessor(new SimpleSpanProcessor(new ConsoleSpanExporter())); provider.register(); registerInstrumentations({ diff --git a/plugins/node/opentelemetry-instrumentation-restify/test/restify.test.ts b/plugins/node/opentelemetry-instrumentation-restify/test/restify.test.ts index ee7e6c524e..e5af1a6c6a 100644 --- a/plugins/node/opentelemetry-instrumentation-restify/test/restify.test.ts +++ b/plugins/node/opentelemetry-instrumentation-restify/test/restify.test.ts @@ -118,10 +118,11 @@ const createServer = async (setupRoutes?: Function) => { }; describe('Restify Instrumentation', () => { - const provider = new NodeTracerProvider(); const memoryExporter = new InMemorySpanExporter(); const spanProcessor = new SimpleSpanProcessor(memoryExporter); - provider.addSpanProcessor(spanProcessor); + const provider = new NodeTracerProvider({ + spanProcessors: [spanProcessor], + }); plugin.setTracerProvider(provider); const tracer = provider.getTracer('default'); let contextManager: AsyncHooksContextManager; diff --git a/plugins/node/opentelemetry-instrumentation-router/README.md b/plugins/node/opentelemetry-instrumentation-router/README.md index 7145d3b8a3..254541ae96 100644 --- a/plugins/node/opentelemetry-instrumentation-router/README.md +++ b/plugins/node/opentelemetry-instrumentation-router/README.md @@ -27,9 +27,12 @@ const { NodeTracerProvider } = require('@opentelemetry/sdk-trace-node'); const { registerInstrumentations } = require('@opentelemetry/instrumentation'); const { RouterInstrumentation } = require('@opentelemetry/instrumentation-router'); -const provider = new NodeTracerProvider(); +const provider = new NodeTracerProvider({ + spanProcessors: [ + new SimpleSpanProcessor(new ConsoleSpanExporter()), + ], +}); -provider.addSpanProcessor(new SimpleSpanProcessor(new ConsoleSpanExporter())); provider.register(); registerInstrumentations({ diff --git a/plugins/node/opentelemetry-instrumentation-router/test/index.test.ts b/plugins/node/opentelemetry-instrumentation-router/test/index.test.ts index 4958ca77f0..c7ca4d9eb9 100644 --- a/plugins/node/opentelemetry-instrumentation-router/test/index.test.ts +++ b/plugins/node/opentelemetry-instrumentation-router/test/index.test.ts @@ -152,10 +152,11 @@ const spans = { }; describe('Router instrumentation', () => { - const provider = new NodeTracerProvider(); const memoryExporter = new InMemorySpanExporter(); const spanProcessor = new SimpleSpanProcessor(memoryExporter); - provider.addSpanProcessor(spanProcessor); + const provider = new NodeTracerProvider({ + spanProcessors: [spanProcessor], + }); plugin.setTracerProvider(provider); const tracer = provider.getTracer('default'); let contextManager: AsyncHooksContextManager; diff --git a/plugins/node/opentelemetry-instrumentation-winston/test/winston.test.ts b/plugins/node/opentelemetry-instrumentation-winston/test/winston.test.ts index 2ecb4eab37..7da83449cd 100644 --- a/plugins/node/opentelemetry-instrumentation-winston/test/winston.test.ts +++ b/plugins/node/opentelemetry-instrumentation-winston/test/winston.test.ts @@ -35,9 +35,10 @@ import type { Winston2Logger, Winston3Logger } from '../src/internal-types'; import { WinstonInstrumentation } from '../src'; const memoryExporter = new InMemorySpanExporter(); -const provider = new NodeTracerProvider(); +const provider = new NodeTracerProvider({ + spanProcessors: [new SimpleSpanProcessor(memoryExporter)], +}); const tracer = provider.getTracer('default'); -provider.addSpanProcessor(new SimpleSpanProcessor(memoryExporter)); context.setGlobalContextManager(new AsyncHooksContextManager()); const loggerProvider = new LoggerProvider(); diff --git a/plugins/web/opentelemetry-instrumentation-document-load/README.md b/plugins/web/opentelemetry-instrumentation-document-load/README.md index c672add7a5..d127ac0d51 100644 --- a/plugins/web/opentelemetry-instrumentation-document-load/README.md +++ b/plugins/web/opentelemetry-instrumentation-document-load/README.md @@ -26,9 +26,11 @@ import { registerInstrumentations } from '@opentelemetry/instrumentation'; import { B3Propagator } from '@opentelemetry/propagator-b3'; import { CompositePropagator, W3CTraceContextPropagator } from '@opentelemetry/core'; -const provider = new WebTracerProvider(); - -provider.addSpanProcessor(new SimpleSpanProcessor(new ConsoleSpanExporter())); +const provider = new WebTracerProvider({ + spanProcessors: [ + new SimpleSpanProcessor(new ConsoleSpanExporter()), + ], +}); provider.register({ propagator: new CompositePropagator({ diff --git a/plugins/web/opentelemetry-instrumentation-document-load/test/documentLoad.test.ts b/plugins/web/opentelemetry-instrumentation-document-load/test/documentLoad.test.ts index cbe4b0c7b3..017bddc563 100644 --- a/plugins/web/opentelemetry-instrumentation-document-load/test/documentLoad.test.ts +++ b/plugins/web/opentelemetry-instrumentation-document-load/test/documentLoad.test.ts @@ -48,10 +48,11 @@ import { EventNames } from '../src/enums/EventNames'; const assert = chai.assert; const exporter = new InMemorySpanExporter(); -const provider = new BasicTracerProvider(); const spanProcessor = new SimpleSpanProcessor(exporter); +const provider = new BasicTracerProvider({ + spanProcessors: [spanProcessor], +}); -provider.addSpanProcessor(spanProcessor); provider.register(); const resources = [ diff --git a/plugins/web/opentelemetry-instrumentation-long-task/README.md b/plugins/web/opentelemetry-instrumentation-long-task/README.md index 5239e006b5..e14aff098b 100644 --- a/plugins/web/opentelemetry-instrumentation-long-task/README.md +++ b/plugins/web/opentelemetry-instrumentation-long-task/README.md @@ -23,9 +23,11 @@ import { WebTracerProvider } from '@opentelemetry/sdk-trace-web'; import { LongTaskInstrumentation } from '@opentelemetry/instrumentation-long-task'; import { registerInstrumentations } from '@opentelemetry/instrumentation'; -const provider = new WebTracerProvider(); - -provider.addSpanProcessor(new SimpleSpanProcessor(new ConsoleSpanExporter())); +const provider = new WebTracerProvider({ + spanProcessors: [ + new SimpleSpanProcessor(new ConsoleSpanExporter()), + ], +}); registerInstrumentations({ tracerProvider: provider, diff --git a/plugins/web/opentelemetry-instrumentation-long-task/test/compatibility.test.ts b/plugins/web/opentelemetry-instrumentation-long-task/test/compatibility.test.ts index d3404d19ae..bbc227d640 100644 --- a/plugins/web/opentelemetry-instrumentation-long-task/test/compatibility.test.ts +++ b/plugins/web/opentelemetry-instrumentation-long-task/test/compatibility.test.ts @@ -38,11 +38,10 @@ describe("LongTaskInstrumentation doesn't throw in unsupported environments", () let dummySpanExporter: DummySpanExporter; before(() => { - webTracerProvider = new WebTracerProvider(); dummySpanExporter = new DummySpanExporter(); - webTracerProvider.addSpanProcessor( - new tracing.SimpleSpanProcessor(dummySpanExporter) - ); + webTracerProvider = new WebTracerProvider({ + spanProcessors: [new tracing.SimpleSpanProcessor(dummySpanExporter)], + }); webTracerProvider.register(); }); diff --git a/plugins/web/opentelemetry-instrumentation-long-task/test/longTask.test.ts b/plugins/web/opentelemetry-instrumentation-long-task/test/longTask.test.ts index c65ed71e63..4feb913583 100644 --- a/plugins/web/opentelemetry-instrumentation-long-task/test/longTask.test.ts +++ b/plugins/web/opentelemetry-instrumentation-long-task/test/longTask.test.ts @@ -60,12 +60,11 @@ describe('LongTaskInstrumentation', () => { beforeEach(() => { sandbox = sinon.createSandbox(); - webTracerProvider = new WebTracerProvider(); dummySpanExporter = new DummySpanExporter(); exportSpy = sandbox.stub(dummySpanExporter, 'export'); - webTracerProvider.addSpanProcessor( - new tracing.SimpleSpanProcessor(dummySpanExporter) - ); + webTracerProvider = new WebTracerProvider({ + spanProcessors: [new tracing.SimpleSpanProcessor(dummySpanExporter)], + }); webTracerProvider.register(); longTaskInstrumentation = new LongTaskInstrumentation({ diff --git a/plugins/web/opentelemetry-instrumentation-user-interaction/README.md b/plugins/web/opentelemetry-instrumentation-user-interaction/README.md index 9d4f98bcb7..05f76a002b 100644 --- a/plugins/web/opentelemetry-instrumentation-user-interaction/README.md +++ b/plugins/web/opentelemetry-instrumentation-user-interaction/README.md @@ -32,10 +32,12 @@ import { registerInstrumentations } from '@opentelemetry/instrumentation'; // import { ZoneContextManager } from '@opentelemetry/context-zone-peer-dep'; const provider = new WebTracerProvider({ - contextManager: new ZoneContextManager() + contextManager: new ZoneContextManager(), + spanProcessors: [ + new SimpleSpanProcessor(new ConsoleSpanExporter()), + ], }); -provider.addSpanProcessor(new SimpleSpanProcessor(new ConsoleSpanExporter())); provider.register(); registerInstrumentations({ diff --git a/plugins/web/opentelemetry-instrumentation-user-interaction/test/userInteraction.nozone.test.ts b/plugins/web/opentelemetry-instrumentation-user-interaction/test/userInteraction.nozone.test.ts index 57fa3faba1..f1d4231329 100644 --- a/plugins/web/opentelemetry-instrumentation-user-interaction/test/userInteraction.nozone.test.ts +++ b/plugins/web/opentelemetry-instrumentation-user-interaction/test/userInteraction.nozone.test.ts @@ -90,13 +90,11 @@ describe('UserInteractionInstrumentation', () => { sandbox.useFakeTimers(); - webTracerProvider = new WebTracerProvider(); - dummySpanExporter = new DummySpanExporter(); exportSpy = sandbox.stub(dummySpanExporter, 'export'); - webTracerProvider.addSpanProcessor( - new tracing.SimpleSpanProcessor(dummySpanExporter) - ); + webTracerProvider = new WebTracerProvider({ + spanProcessors: [new tracing.SimpleSpanProcessor(dummySpanExporter)], + }); webTracerProvider.register(); registerTestInstrumentations(); diff --git a/plugins/web/opentelemetry-instrumentation-user-interaction/test/userInteraction.test.ts b/plugins/web/opentelemetry-instrumentation-user-interaction/test/userInteraction.test.ts index 792387e8c5..46b9f52daf 100644 --- a/plugins/web/opentelemetry-instrumentation-user-interaction/test/userInteraction.test.ts +++ b/plugins/web/opentelemetry-instrumentation-user-interaction/test/userInteraction.test.ts @@ -95,13 +95,11 @@ describe('UserInteractionInstrumentation', () => { sandbox.useFakeTimers(); - webTracerProvider = new WebTracerProvider(); dummySpanExporter = new DummySpanExporter(); exportSpy = sandbox.stub(dummySpanExporter, 'export'); - webTracerProvider.addSpanProcessor( - new tracing.SimpleSpanProcessor(dummySpanExporter) - ); - + webTracerProvider = new WebTracerProvider({ + spanProcessors: [new tracing.SimpleSpanProcessor(dummySpanExporter)], + }); webTracerProvider.register({ contextManager, }); diff --git a/plugins/web/opentelemetry-plugin-react-load/test/BaseOpenTelemetryComponent.test.ts b/plugins/web/opentelemetry-plugin-react-load/test/BaseOpenTelemetryComponent.test.ts index 2636e20338..323044bdc7 100644 --- a/plugins/web/opentelemetry-plugin-react-load/test/BaseOpenTelemetryComponent.test.ts +++ b/plugins/web/opentelemetry-plugin-react-load/test/BaseOpenTelemetryComponent.test.ts @@ -68,11 +68,11 @@ describe('ReactLoad Instrumentation', () => { contextManager = new StackContextManager().enable(); context.setGlobalContextManager(contextManager); - provider = new BasicTracerProvider(); - dummyExporter = new DummyExporter(); spanProcessor = new SimpleSpanProcessor(dummyExporter); - provider.addSpanProcessor(spanProcessor); + provider = new BasicTracerProvider({ + spanProcessors: [spanProcessor], + }); sandbox = sinon.createSandbox(); trace.setGlobalTracerProvider(provider);