From bfbdc3fbf25c323b7b3a85bf88c63849e3bd0395 Mon Sep 17 00:00:00 2001 From: Daniel Dyla Date: Thu, 11 Jun 2020 16:05:23 -0400 Subject: [PATCH 01/26] feat: add nodejs sdk package --- packages/opentelemetry-metrics/src/index.ts | 1 + packages/opentelemetry-node/src/index.ts | 1 + packages/opentelemetry-sdk-node/.eslintignore | 1 + packages/opentelemetry-sdk-node/.eslintrc.js | 8 + packages/opentelemetry-sdk-node/LICENSE | 201 ++++++++++++++++++ packages/opentelemetry-sdk-node/README.md | 98 +++++++++ packages/opentelemetry-sdk-node/package.json | 66 ++++++ packages/opentelemetry-sdk-node/src/index.ts | 91 ++++++++ packages/opentelemetry-sdk-node/src/types.ts | 38 ++++ .../opentelemetry-sdk-node/src/version.ts | 18 ++ packages/opentelemetry-sdk-node/tsconfig.json | 11 + 11 files changed, 534 insertions(+) create mode 100644 packages/opentelemetry-sdk-node/.eslintignore create mode 100644 packages/opentelemetry-sdk-node/.eslintrc.js create mode 100644 packages/opentelemetry-sdk-node/LICENSE create mode 100644 packages/opentelemetry-sdk-node/README.md create mode 100644 packages/opentelemetry-sdk-node/package.json create mode 100644 packages/opentelemetry-sdk-node/src/index.ts create mode 100644 packages/opentelemetry-sdk-node/src/types.ts create mode 100644 packages/opentelemetry-sdk-node/src/version.ts create mode 100644 packages/opentelemetry-sdk-node/tsconfig.json diff --git a/packages/opentelemetry-metrics/src/index.ts b/packages/opentelemetry-metrics/src/index.ts index 6cb01ff9a8..f1e6cf9323 100644 --- a/packages/opentelemetry-metrics/src/index.ts +++ b/packages/opentelemetry-metrics/src/index.ts @@ -22,3 +22,4 @@ export * from './MetricObservable'; export * from './export/aggregators'; export * from './export/ConsoleMetricExporter'; export * from './export/types'; +export * from './export/Batcher'; diff --git a/packages/opentelemetry-node/src/index.ts b/packages/opentelemetry-node/src/index.ts index 665900aefb..e7a10c0635 100644 --- a/packages/opentelemetry-node/src/index.ts +++ b/packages/opentelemetry-node/src/index.ts @@ -15,3 +15,4 @@ */ export * from './NodeTracerProvider'; +export { Plugins } from "./instrumentation/PluginLoader"; diff --git a/packages/opentelemetry-sdk-node/.eslintignore b/packages/opentelemetry-sdk-node/.eslintignore new file mode 100644 index 0000000000..378eac25d3 --- /dev/null +++ b/packages/opentelemetry-sdk-node/.eslintignore @@ -0,0 +1 @@ +build diff --git a/packages/opentelemetry-sdk-node/.eslintrc.js b/packages/opentelemetry-sdk-node/.eslintrc.js new file mode 100644 index 0000000000..e20344660f --- /dev/null +++ b/packages/opentelemetry-sdk-node/.eslintrc.js @@ -0,0 +1,8 @@ +module.exports = { + "env": { + "mocha": true, + "commonjs": true, + "shared-node-browser": true + }, + ...require('../../eslint.config.js') +} diff --git a/packages/opentelemetry-sdk-node/LICENSE b/packages/opentelemetry-sdk-node/LICENSE new file mode 100644 index 0000000000..261eeb9e9f --- /dev/null +++ b/packages/opentelemetry-sdk-node/LICENSE @@ -0,0 +1,201 @@ + 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. diff --git a/packages/opentelemetry-sdk-node/README.md b/packages/opentelemetry-sdk-node/README.md new file mode 100644 index 0000000000..a7204352d1 --- /dev/null +++ b/packages/opentelemetry-sdk-node/README.md @@ -0,0 +1,98 @@ +# OpenTelemetry SDK for NodeJS + +[![Gitter chat][gitter-image]][gitter-url] +[![NPM Published Version][npm-img]][npm-url] +[![dependencies][dependencies-image]][dependencies-url] +[![devDependencies][devDependencies-image]][devDependencies-url] +[![Apache License][license-image]][license-image] + +@ToDo +This package provides... + +## Quick Start + +@ToDo +To get started you need to ... + +### Installation + +```sh +$ # Install the SDK +$ npm install @opentelemetry/sdk-node + +$ # Install exporters and plugins +$ npm install \ + @opentelemetry/exporter-jaeger \ # add tracing exporters as needed + @opentelemetry/exporter-prometheus # add metrics exporters as needed + @opentelemetry/plugin-http # add plugins as needed +``` + +> Note: this example is for node.js. See [examples/tracer-web](https://github.com/open-telemetry/opentelemetry-js/tree/master/examples/tracer-web) for a browser example. + +### Initialize the SDK + +Before any other module in your application is loaded, you must initialize the SDK. +If you fail to initialize the SDK or initialize it too late, no-op implementations will be provided to any library which acquires a tracer or meter from the API. +This example uses Jaeger and Prometheus, but exporters exist for [other tracing backends][other-tracing-backends]. +```javascript +const opentelemetry = require("@opentelemetry/sdk-node"); +const { JaegerExporter } = require("@opentelemetry/exporter-jaeger"); +const { PrometheusExporter } = require("@opentelemetry/exporter-prometheus"); + +const jaegerExporter = new JaegerExporter({ + serviceName: 'my-service', +}); +const prometheusExporter = new PrometheusExporter({ startServer: true }); + +opentelemetry.configure({ + // Optional - if omitted, the tracing SDK will not be initialized + traceExporter: jaegerExporter, + // Optional - If omitted, the metrics SDK will not be initialized + metricExporter: prometheusExporter, + + // See the Configuration section below for additional configuration options +}); +``` + +## Configuration + +@ToDo add descriptions for all configurations + +### autoDetectResources +### contextManager +### httpTextPropagator +### logger +### logLevel +### metricBatcher +### metricExporter +### metricInterval +### metricResource +### plugins +### resource +### sampler +### traceExporter +### traceParams +### traceResource + +## Useful links + +- For more information on OpenTelemetry, visit: +- For more about OpenTelemetry JavaScript: +- For help or feedback on this project, join us on [gitter][gitter-url] + +## License + +Apache 2.0 - See [LICENSE][license-url] for more information. + +[gitter-image]: https://badges.gitter.im/open-telemetry/opentelemetry-js.svg +[gitter-url]: https://gitter.im/open-telemetry/opentelemetry-node?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge +[license-url]: https://github.com/open-telemetry/opentelemetry-js/blob/master/LICENSE +[license-image]: https://img.shields.io/badge/license-Apache_2.0-green.svg?style=flat +[dependencies-image]: https://david-dm.org/open-telemetry/opentelemetry-js/status.svg?path=packages/opentelemetry-sdk-node +[dependencies-url]: https://david-dm.org/open-telemetry/opentelemetry-js?path=packages%2Fopentelemetry-sdk-node +[devDependencies-image]: https://david-dm.org/open-telemetry/opentelemetry-js/dev-status.svg?path=packages/opentelemetry-sdk-node +[devDependencies-url]: https://david-dm.org/open-telemetry/opentelemetry-js?path=packages%2Fopentelemetry-sdk-node&type=dev +[npm-url]: https://www.npmjs.com/package/@opentelemetry/sdk-node +[npm-img]: https://badge.fury.io/js/%40opentelemetry%2Fsdk-node.svg + +[other-tracing-backends]: https://github.com/open-telemetry/opentelemetry-js#trace-exporters diff --git a/packages/opentelemetry-sdk-node/package.json b/packages/opentelemetry-sdk-node/package.json new file mode 100644 index 0000000000..663eb2d853 --- /dev/null +++ b/packages/opentelemetry-sdk-node/package.json @@ -0,0 +1,66 @@ +{ + "name": "@opentelemetry/sdk-node", + "version": "0.8.3", + "description": "OpenTelemetry SDK for NodeJS", + "main": "build/src/index.js", + "types": "build/src/index.d.ts", + "repository": "open-telemetry/opentelemetry-js", + "scripts": { + "test": "nyc ts-mocha -p tsconfig.json test/**/*.test.ts", + "codecov": "nyc report --reporter=json && codecov -f coverage/*.json -p ../../", + "build": "npm run compile", + "lint": "eslint . --ext .ts", + "lint:fix": "eslint . --ext .ts --fix", + "precompile": "tsc --version", + "version:update": "node ../../scripts/version-update.js", + "compile": "npm run version:update && tsc -p .", + "prepare": "npm run compile", + "watch": "tsc -w" + }, + "keywords": [ + "opentelemetry", + "nodejs", + "tracing", + "profiling", + "metrics", + "stats", + "monitoring" + ], + "author": "OpenTelemetry Authors", + "license": "Apache-2.0", + "engines": { + "node": ">=8.0.0" + }, + "files": [ + "build/src/**/*.js", + "build/src/**/*.d.ts", + "LICENSE", + "README.md" + ], + "publishConfig": { + "access": "public" + }, + "dependencies": { + "@opentelemetry/api": "0.8.3", + "@opentelemetry/context-base": "0.8.3", + "@opentelemetry/context-async-hooks": "0.8.3", + "@opentelemetry/core": "0.8.3", + "@opentelemetry/metrics": "0.8.3", + "@opentelemetry/node": "0.8.3", + "@opentelemetry/resources": "0.8.3", + "@opentelemetry/tracing": "0.8.3" + }, + "devDependencies": { + "@types/mocha": "7.0.2", + "@types/node": "14.0.13", + "codecov": "3.7.0", + "gts": "2.0.2", + "istanbul-instrumenter-loader": "3.0.1", + "linkinator": "2.1.1", + "mocha": "7.2.0", + "nyc": "15.1.0", + "ts-loader": "7.0.5", + "ts-mocha": "7.0.0", + "typescript": "3.9.5" + } +} diff --git a/packages/opentelemetry-sdk-node/src/index.ts b/packages/opentelemetry-sdk-node/src/index.ts new file mode 100644 index 0000000000..fada7550f0 --- /dev/null +++ b/packages/opentelemetry-sdk-node/src/index.ts @@ -0,0 +1,91 @@ +/*! + * Copyright 2020, 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 { metrics } from '@opentelemetry/api'; +import { MeterProvider } from '@opentelemetry/metrics'; +import { NodeTracerProvider } from '@opentelemetry/node'; +import { detectResources, Resource } from '@opentelemetry/resources'; +import { BatchSpanProcessor } from '@opentelemetry/tracing'; +import { SDKConfiguration } from './types'; + +export * as api from '@opentelemetry/api'; +export * as contextBase from '@opentelemetry/context-base'; +export * as core from '@opentelemetry/core'; +export * as metrics from '@opentelemetry/metrics'; +export * as node from '@opentelemetry/node'; +export * as resources from '@opentelemetry/resources'; +export * as tracing from '@opentelemetry/tracing'; + +export async function configure( + configuration: Partial = {} +): Promise { + const resource = await getResources(configuration); + + if (configuration.spanProcessor || configuration.traceExporter) { + const traceResource = + configuration.traceResource?.merge(resource) ?? resource; + + const tracerProvider = new NodeTracerProvider({ + defaultAttributes: configuration.defaultAttributes, + logLevel: configuration.logLevel, + logger: configuration.logger, + plugins: configuration.plugins, + resource: traceResource, + sampler: configuration.sampler, + traceParams: configuration.traceParams, + }); + + const spanProcessor = + configuration.spanProcessor ?? + new BatchSpanProcessor(configuration.traceExporter!); + + tracerProvider.addSpanProcessor(spanProcessor); + tracerProvider.register({ + contextManager: configuration.contextManager, + propagator: configuration.httpTextPropagator, + }); + } + + if (configuration.metricExporter) { + const metricResource = + configuration.metricResource?.merge(resource) ?? resource; + + const meterProvider = new MeterProvider({ + batcher: configuration.metricBatcher, + exporter: configuration.metricExporter, + interval: configuration.metricInterval, + logLevel: configuration.logLevel, + logger: configuration.logger, + resource: metricResource, + }); + + metrics.setGlobalMeterProvider(meterProvider); + } +} + +async function getResources(configuration: Partial) { + const autoDetectResources = configuration.autoDetectResources ?? true; + + if (autoDetectResources) { + const autoDetectedResource = await detectResources(); + return ( + configuration.resource?.merge(autoDetectedResource) ?? + autoDetectedResource + ); + } + + return configuration.resource ?? new Resource({}); +} diff --git a/packages/opentelemetry-sdk-node/src/types.ts b/packages/opentelemetry-sdk-node/src/types.ts new file mode 100644 index 0000000000..dd96b20c40 --- /dev/null +++ b/packages/opentelemetry-sdk-node/src/types.ts @@ -0,0 +1,38 @@ +/*! + * Copyright 2020, 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 type { ContextManager } from '@opentelemetry/context-base'; +import type { api, core, metrics, node, resources, tracing } from '.'; + +export interface SDKConfiguration { + autoDetectResources: boolean; + defaultAttributes: api.Attributes; + logger: api.Logger; + logLevel: core.LogLevel; + contextManager: ContextManager; + metricBatcher: metrics.Batcher; + metricExporter: metrics.MetricExporter; + metricInterval: number; + metricResource: resources.Resource; + plugins: node.Plugins; + httpTextPropagator: api.HttpTextPropagator; + resource: resources.Resource; + sampler: api.Sampler; + spanProcessor: tracing.SpanProcessor; + traceExporter: tracing.SpanExporter; + traceParams: tracing.TraceParams; + traceResource: resources.Resource; +} diff --git a/packages/opentelemetry-sdk-node/src/version.ts b/packages/opentelemetry-sdk-node/src/version.ts new file mode 100644 index 0000000000..90d0ab01d0 --- /dev/null +++ b/packages/opentelemetry-sdk-node/src/version.ts @@ -0,0 +1,18 @@ +/* + * Copyright 2020, 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 is autogenerated file, see scripts/version-update.js +export const VERSION = '0.8.3'; diff --git a/packages/opentelemetry-sdk-node/tsconfig.json b/packages/opentelemetry-sdk-node/tsconfig.json new file mode 100644 index 0000000000..a2042cd68b --- /dev/null +++ b/packages/opentelemetry-sdk-node/tsconfig.json @@ -0,0 +1,11 @@ +{ + "extends": "../tsconfig.base", + "compilerOptions": { + "rootDir": ".", + "outDir": "build" + }, + "include": [ + "src/**/*.ts", + "test/**/*.ts" + ] +} From 5d05108620a52d472ecf314a0534ca07405b485b Mon Sep 17 00:00:00 2001 From: Daniel Dyla Date: Thu, 11 Jun 2020 16:07:59 -0400 Subject: [PATCH 02/26] chore: set eslint environment --- packages/opentelemetry-sdk-node/.eslintrc.js | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/packages/opentelemetry-sdk-node/.eslintrc.js b/packages/opentelemetry-sdk-node/.eslintrc.js index e20344660f..f726f3becb 100644 --- a/packages/opentelemetry-sdk-node/.eslintrc.js +++ b/packages/opentelemetry-sdk-node/.eslintrc.js @@ -1,8 +1,7 @@ module.exports = { "env": { "mocha": true, - "commonjs": true, - "shared-node-browser": true + "node": true }, ...require('../../eslint.config.js') } From 3d0ab78b3153b70815179ce0009116b635b1b921 Mon Sep 17 00:00:00 2001 From: Daniel Dyla Date: Fri, 12 Jun 2020 08:10:01 -0400 Subject: [PATCH 03/26] Update packages/opentelemetry-sdk-node/README.md Co-authored-by: Naseem --- packages/opentelemetry-sdk-node/README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/opentelemetry-sdk-node/README.md b/packages/opentelemetry-sdk-node/README.md index a7204352d1..99e07f88ba 100644 --- a/packages/opentelemetry-sdk-node/README.md +++ b/packages/opentelemetry-sdk-node/README.md @@ -34,6 +34,7 @@ $ npm install \ Before any other module in your application is loaded, you must initialize the SDK. If you fail to initialize the SDK or initialize it too late, no-op implementations will be provided to any library which acquires a tracer or meter from the API. This example uses Jaeger and Prometheus, but exporters exist for [other tracing backends][other-tracing-backends]. + ```javascript const opentelemetry = require("@opentelemetry/sdk-node"); const { JaegerExporter } = require("@opentelemetry/exporter-jaeger"); From acb3a509debb85262e6cf75237760e4cc87a2c21 Mon Sep 17 00:00:00 2001 From: Daniel Dyla Date: Fri, 19 Jun 2020 11:31:10 -0400 Subject: [PATCH 04/26] refactor: separate sdk configuration and start --- packages/opentelemetry-metrics/src/index.ts | 1 + packages/opentelemetry-node/src/index.ts | 3 +- packages/opentelemetry-sdk-node/package.json | 16 +- packages/opentelemetry-sdk-node/src/index.ts | 74 +--------- packages/opentelemetry-sdk-node/src/sdk.ts | 137 ++++++++++++++++++ packages/opentelemetry-sdk-node/src/types.ts | 7 +- .../opentelemetry-sdk-node/src/version.ts | 2 +- 7 files changed, 156 insertions(+), 84 deletions(-) create mode 100644 packages/opentelemetry-sdk-node/src/sdk.ts diff --git a/packages/opentelemetry-metrics/src/index.ts b/packages/opentelemetry-metrics/src/index.ts index 5058cfe621..9cff84c9f3 100644 --- a/packages/opentelemetry-metrics/src/index.ts +++ b/packages/opentelemetry-metrics/src/index.ts @@ -24,3 +24,4 @@ export * from './export/ConsoleMetricExporter'; export * from './export/types'; export * from './export/Batcher'; export * from './UpDownCounterMetric'; +export { MeterConfig } from './types'; diff --git a/packages/opentelemetry-node/src/index.ts b/packages/opentelemetry-node/src/index.ts index 1d9f9c25b1..092ae180c9 100644 --- a/packages/opentelemetry-node/src/index.ts +++ b/packages/opentelemetry-node/src/index.ts @@ -14,5 +14,6 @@ * limitations under the License. */ +export { NodeTracerConfig } from './config'; +export { Plugins } from './instrumentation/PluginLoader'; export * from './NodeTracerProvider'; -export { Plugins } from "./instrumentation/PluginLoader"; diff --git a/packages/opentelemetry-sdk-node/package.json b/packages/opentelemetry-sdk-node/package.json index 663eb2d853..b24727dc81 100644 --- a/packages/opentelemetry-sdk-node/package.json +++ b/packages/opentelemetry-sdk-node/package.json @@ -41,14 +41,14 @@ "access": "public" }, "dependencies": { - "@opentelemetry/api": "0.8.3", - "@opentelemetry/context-base": "0.8.3", - "@opentelemetry/context-async-hooks": "0.8.3", - "@opentelemetry/core": "0.8.3", - "@opentelemetry/metrics": "0.8.3", - "@opentelemetry/node": "0.8.3", - "@opentelemetry/resources": "0.8.3", - "@opentelemetry/tracing": "0.8.3" + "@opentelemetry/api": "0.9.0", + "@opentelemetry/context-base": "0.9.0", + "@opentelemetry/context-async-hooks": "0.9.0", + "@opentelemetry/core": "0.9.0", + "@opentelemetry/metrics": "0.9.0", + "@opentelemetry/node": "0.9.0", + "@opentelemetry/resources": "0.9.0", + "@opentelemetry/tracing": "0.9.0" }, "devDependencies": { "@types/mocha": "7.0.2", diff --git a/packages/opentelemetry-sdk-node/src/index.ts b/packages/opentelemetry-sdk-node/src/index.ts index fada7550f0..b511af8046 100644 --- a/packages/opentelemetry-sdk-node/src/index.ts +++ b/packages/opentelemetry-sdk-node/src/index.ts @@ -1,5 +1,5 @@ -/*! - * Copyright 2020, OpenTelemetry Authors +/* + * 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. @@ -14,13 +14,6 @@ * limitations under the License. */ -import { metrics } from '@opentelemetry/api'; -import { MeterProvider } from '@opentelemetry/metrics'; -import { NodeTracerProvider } from '@opentelemetry/node'; -import { detectResources, Resource } from '@opentelemetry/resources'; -import { BatchSpanProcessor } from '@opentelemetry/tracing'; -import { SDKConfiguration } from './types'; - export * as api from '@opentelemetry/api'; export * as contextBase from '@opentelemetry/context-base'; export * as core from '@opentelemetry/core'; @@ -28,64 +21,5 @@ export * as metrics from '@opentelemetry/metrics'; export * as node from '@opentelemetry/node'; export * as resources from '@opentelemetry/resources'; export * as tracing from '@opentelemetry/tracing'; - -export async function configure( - configuration: Partial = {} -): Promise { - const resource = await getResources(configuration); - - if (configuration.spanProcessor || configuration.traceExporter) { - const traceResource = - configuration.traceResource?.merge(resource) ?? resource; - - const tracerProvider = new NodeTracerProvider({ - defaultAttributes: configuration.defaultAttributes, - logLevel: configuration.logLevel, - logger: configuration.logger, - plugins: configuration.plugins, - resource: traceResource, - sampler: configuration.sampler, - traceParams: configuration.traceParams, - }); - - const spanProcessor = - configuration.spanProcessor ?? - new BatchSpanProcessor(configuration.traceExporter!); - - tracerProvider.addSpanProcessor(spanProcessor); - tracerProvider.register({ - contextManager: configuration.contextManager, - propagator: configuration.httpTextPropagator, - }); - } - - if (configuration.metricExporter) { - const metricResource = - configuration.metricResource?.merge(resource) ?? resource; - - const meterProvider = new MeterProvider({ - batcher: configuration.metricBatcher, - exporter: configuration.metricExporter, - interval: configuration.metricInterval, - logLevel: configuration.logLevel, - logger: configuration.logger, - resource: metricResource, - }); - - metrics.setGlobalMeterProvider(meterProvider); - } -} - -async function getResources(configuration: Partial) { - const autoDetectResources = configuration.autoDetectResources ?? true; - - if (autoDetectResources) { - const autoDetectedResource = await detectResources(); - return ( - configuration.resource?.merge(autoDetectedResource) ?? - autoDetectedResource - ); - } - - return configuration.resource ?? new Resource({}); -} +export * from './sdk'; +export * from './types'; diff --git a/packages/opentelemetry-sdk-node/src/sdk.ts b/packages/opentelemetry-sdk-node/src/sdk.ts new file mode 100644 index 0000000000..f3718aca5a --- /dev/null +++ b/packages/opentelemetry-sdk-node/src/sdk.ts @@ -0,0 +1,137 @@ +/* + * 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 { HttpTextPropagator, metrics } from '@opentelemetry/api'; +import { ContextManager } from '@opentelemetry/context-base'; +import { MeterConfig, MeterProvider } from '@opentelemetry/metrics'; +import { NodeTracerConfig, NodeTracerProvider } from '@opentelemetry/node'; +import { detectResources, Resource } from '@opentelemetry/resources'; +import { BatchSpanProcessor, SpanProcessor } from '@opentelemetry/tracing'; +import { NodeSDKConfiguration } from './types'; + +export class NodeSDK { + private _tracerProviderConfig?: { + tracerConfig: NodeTracerConfig; + spanProcessor: SpanProcessor; + contextManager?: ContextManager; + httpTextPropagator?: HttpTextPropagator; + }; + private _meterProviderConfig?: MeterConfig; + + private _traceResource: Resource; + private _metricsResource: Resource; + + public constructor(configuration: Partial = {}) { + const resource = configuration.resource ?? new Resource({}); + + this._traceResource = configuration.traceResource ?? new Resource({}); + this._metricsResource = configuration.metricResource ?? new Resource({}); + + this._traceResource = this._traceResource.merge(resource); + this._metricsResource = this._metricsResource.merge(resource); + + if (configuration.spanProcessor || configuration.traceExporter) { + const tracerProviderConfig = { + defaultAttributes: configuration.defaultAttributes, + logLevel: configuration.logLevel, + logger: configuration.logger, + plugins: configuration.plugins, + sampler: configuration.sampler, + traceParams: configuration.traceParams, + }; + + const spanProcessor = + configuration.spanProcessor ?? + new BatchSpanProcessor(configuration.traceExporter!); + + this.configureTracerProvider( + tracerProviderConfig, + spanProcessor, + configuration.contextManager, + configuration.httpTextPropagator + ); + } + + if (configuration.metricExporter) { + this.configureMeterProvider({ + batcher: configuration.metricBatcher, + exporter: configuration.metricExporter, + interval: configuration.metricInterval, + logLevel: configuration.logLevel, + logger: configuration.logger, + }); + } + } + + public configureTracerProvider( + tracerConfig: NodeTracerConfig, + spanProcessor: SpanProcessor, + contextManager?: ContextManager, + httpTextPropagator?: HttpTextPropagator + ) { + this._tracerProviderConfig = { + tracerConfig, + spanProcessor, + contextManager, + httpTextPropagator, + }; + } + + public configureMeterProvider(config: MeterConfig) { + this._meterProviderConfig = config; + } + + public async detectResources() { + this.addResource(await detectResources()); + } + + public async addResource(resource: Resource) { + this.addTraceResource(resource); + this.addMetricsResource(resource); + } + + public async addTraceResource(resource: Resource) { + this._traceResource.merge(resource); + } + + public async addMetricsResource(resource: Resource) { + this._metricsResource.merge(resource); + } + + public start() { + if (this._tracerProviderConfig) { + const tracerProvider = new NodeTracerProvider({ + ...this._tracerProviderConfig, + resource: this._traceResource, + }); + + tracerProvider.addSpanProcessor(this._tracerProviderConfig.spanProcessor); + tracerProvider.register({ + contextManager: this._tracerProviderConfig.contextManager, + propagator: this._tracerProviderConfig.httpTextPropagator, + }); + } + + if (this._meterProviderConfig) { + const meterProvider = new MeterProvider({ + ...this._meterProviderConfig, + resource: this._metricsResource, + }); + + metrics.setGlobalMeterProvider(meterProvider); + } + } +} diff --git a/packages/opentelemetry-sdk-node/src/types.ts b/packages/opentelemetry-sdk-node/src/types.ts index dd96b20c40..b936152cf9 100644 --- a/packages/opentelemetry-sdk-node/src/types.ts +++ b/packages/opentelemetry-sdk-node/src/types.ts @@ -1,5 +1,5 @@ -/*! - * Copyright 2020, OpenTelemetry Authors +/* + * 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. @@ -17,8 +17,7 @@ import type { ContextManager } from '@opentelemetry/context-base'; import type { api, core, metrics, node, resources, tracing } from '.'; -export interface SDKConfiguration { - autoDetectResources: boolean; +export interface NodeSDKConfiguration { defaultAttributes: api.Attributes; logger: api.Logger; logLevel: core.LogLevel; diff --git a/packages/opentelemetry-sdk-node/src/version.ts b/packages/opentelemetry-sdk-node/src/version.ts index 90d0ab01d0..9e616149a4 100644 --- a/packages/opentelemetry-sdk-node/src/version.ts +++ b/packages/opentelemetry-sdk-node/src/version.ts @@ -1,5 +1,5 @@ /* - * Copyright 2020, OpenTelemetry Authors + * 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. From 406988ed4441b80928c3681b506eebde172ec2fa Mon Sep 17 00:00:00 2001 From: Daniel Dyla Date: Fri, 19 Jun 2020 11:34:12 -0400 Subject: [PATCH 05/26] chore: update sdk readme --- packages/opentelemetry-sdk-node/README.md | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/packages/opentelemetry-sdk-node/README.md b/packages/opentelemetry-sdk-node/README.md index 99e07f88ba..28733d738e 100644 --- a/packages/opentelemetry-sdk-node/README.md +++ b/packages/opentelemetry-sdk-node/README.md @@ -45,7 +45,7 @@ const jaegerExporter = new JaegerExporter({ }); const prometheusExporter = new PrometheusExporter({ startServer: true }); -opentelemetry.configure({ +const sdk = new opentelemetry.NodeSDK({ // Optional - if omitted, the tracing SDK will not be initialized traceExporter: jaegerExporter, // Optional - If omitted, the metrics SDK will not be initialized @@ -53,13 +53,20 @@ opentelemetry.configure({ // See the Configuration section below for additional configuration options }); + +// You can optionally detect resources asynchronously from the environment. +// Detected resources are merged with the resources provided in the SDK configuration. +sdk + .autoDetectResources() + .then(() => { + sdk.start(); + }) ``` ## Configuration @ToDo add descriptions for all configurations -### autoDetectResources ### contextManager ### httpTextPropagator ### logger From 7f20ea258f1bdfba4ca7639cee96efa765b6070a Mon Sep 17 00:00:00 2001 From: Daniel Dyla Date: Fri, 19 Jun 2020 11:50:51 -0400 Subject: [PATCH 06/26] chore: markdown lint --- packages/opentelemetry-sdk-node/README.md | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/packages/opentelemetry-sdk-node/README.md b/packages/opentelemetry-sdk-node/README.md index 28733d738e..06112b4bab 100644 --- a/packages/opentelemetry-sdk-node/README.md +++ b/packages/opentelemetry-sdk-node/README.md @@ -68,18 +68,31 @@ sdk @ToDo add descriptions for all configurations ### contextManager + ### httpTextPropagator + ### logger + ### logLevel + ### metricBatcher + ### metricExporter + ### metricInterval + ### metricResource + ### plugins + ### resource + ### sampler + ### traceExporter + ### traceParams + ### traceResource ## Useful links From 5bbb7b85543f513a96c1c0fdf4ee58054884ee9e Mon Sep 17 00:00:00 2001 From: Daniel Dyla Date: Mon, 22 Jun 2020 09:18:23 -0400 Subject: [PATCH 07/26] chore: use tracerConfig --- packages/opentelemetry-sdk-node/src/sdk.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/opentelemetry-sdk-node/src/sdk.ts b/packages/opentelemetry-sdk-node/src/sdk.ts index f3718aca5a..fc077f533c 100644 --- a/packages/opentelemetry-sdk-node/src/sdk.ts +++ b/packages/opentelemetry-sdk-node/src/sdk.ts @@ -114,7 +114,7 @@ export class NodeSDK { public start() { if (this._tracerProviderConfig) { const tracerProvider = new NodeTracerProvider({ - ...this._tracerProviderConfig, + ...this._tracerProviderConfig.tracerConfig, resource: this._traceResource, }); From 54c2a77f12df209980ad6314ad3f8e23f46dfb49 Mon Sep 17 00:00:00 2001 From: Daniel Dyla Date: Mon, 22 Jun 2020 09:18:55 -0400 Subject: [PATCH 08/26] chore: start adding tests --- .../opentelemetry-sdk-node/test/sdk.test.ts | 161 ++++++++++++++++++ 1 file changed, 161 insertions(+) create mode 100644 packages/opentelemetry-sdk-node/test/sdk.test.ts diff --git a/packages/opentelemetry-sdk-node/test/sdk.test.ts b/packages/opentelemetry-sdk-node/test/sdk.test.ts new file mode 100644 index 0000000000..140a5f4912 --- /dev/null +++ b/packages/opentelemetry-sdk-node/test/sdk.test.ts @@ -0,0 +1,161 @@ +/* + * 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 { + context, + metrics, + NoopHttpTextPropagator, + NoopMeterProvider, NoopTracerProvider, propagation, + trace +} from '@opentelemetry/api'; +import { AsyncHooksContextManager } from '@opentelemetry/context-async-hooks'; +import { NoopContextManager } from '@opentelemetry/context-base'; +import { CompositePropagator } from '@opentelemetry/core'; +import { ConsoleMetricExporter, MeterProvider } from '@opentelemetry/metrics'; +import { NodeTracerProvider } from '@opentelemetry/node'; +import { ConsoleSpanExporter, InMemorySpanExporter, SimpleSpanProcessor } from '@opentelemetry/tracing'; +import * as assert from 'assert'; +import { api, NodeSDK, tracing } from '../src'; + +describe('Node SDK', () => { + beforeEach(() => { + context.disable(); + trace.disable(); + propagation.disable(); + metrics.disable(); + }); + + describe("Basic Registration", () => { + it('should not register any unconfigured SDK components', () => { + const sdk = new NodeSDK(); + + sdk.start(); + + assert.ok( + context['_getContextManager']() instanceof NoopContextManager + ); + assert.ok( + propagation['_getGlobalPropagator']() instanceof NoopHttpTextPropagator + ); + + assert.ok(trace.getTracerProvider() instanceof NoopTracerProvider); + assert.ok(metrics.getMeterProvider() instanceof NoopMeterProvider); + }); + + it('should register a tracer provider if an exporter is provided', () => { + const sdk = new NodeSDK({ + traceExporter: new ConsoleSpanExporter(), + }); + + sdk.start(); + + + assert.ok(metrics.getMeterProvider() instanceof NoopMeterProvider); + + + assert.ok( + context['_getContextManager']() instanceof AsyncHooksContextManager + ); + assert.ok( + propagation['_getGlobalPropagator']() instanceof CompositePropagator + ); + assert.ok(trace.getTracerProvider() instanceof NodeTracerProvider); + }); + + it('should register a tracer provider if a span processor is provided', () => { + const exporter = new ConsoleSpanExporter(); + const spanProcessor = new SimpleSpanProcessor(exporter); + + const sdk = new NodeSDK({ + spanProcessor, + }); + + sdk.start(); + + + assert.ok(metrics.getMeterProvider() instanceof NoopMeterProvider); + + + assert.ok( + context['_getContextManager']() instanceof AsyncHooksContextManager + ); + assert.ok( + propagation['_getGlobalPropagator']() instanceof CompositePropagator + ); + assert.ok(trace.getTracerProvider() instanceof NodeTracerProvider); + }); + + + it('should register a meter provider if an exporter is provided', () => { + const exporter = new ConsoleMetricExporter(); + + const sdk = new NodeSDK({ + metricExporter: exporter, + }); + + sdk.start(); + + assert.ok( + context['_getContextManager']() instanceof NoopContextManager + ); + assert.ok( + propagation['_getGlobalPropagator']() instanceof NoopHttpTextPropagator + ); + + assert.ok(trace.getTracerProvider() instanceof NoopTracerProvider); + + assert.ok(metrics.getMeterProvider() instanceof MeterProvider); + }); + + describe("Tracing Options", () => { + let traceExporter: InMemorySpanExporter; + let spanProcessor: SimpleSpanProcessor; + + beforeEach(() => { + traceExporter = new InMemorySpanExporter(); + spanProcessor = new SimpleSpanProcessor(traceExporter); + }); + + afterEach(() => { + traceExporter.reset(); + }); + + it("should apply global attributes to every span", () => { + const sdk = new NodeSDK({ + spanProcessor, + defaultAttributes: { + "default.attribute": "test" + } + }); + + sdk.start(); + const tracer = api.trace.getTracer("test"); + + assert(tracer instanceof tracing.Tracer); + + const provider = tracer["_tracerProvider"]; + + assert(provider instanceof NodeTracerProvider); + + + const span = api.trace.getTracer("test").startSpan("test"); + + assert(span instanceof tracing.Span); + assert.strictEqual(span.attributes["default.attribute"], "test") + }) + }) + }); +}); \ No newline at end of file From ca3b1210183d6f8a42516df48e6301a93e0bd2b8 Mon Sep 17 00:00:00 2001 From: Daniel Dyla Date: Wed, 1 Jul 2020 11:38:03 -0400 Subject: [PATCH 09/26] chore: remove unused dependencies --- packages/opentelemetry-sdk-node/package.json | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/packages/opentelemetry-sdk-node/package.json b/packages/opentelemetry-sdk-node/package.json index b24727dc81..a9019e6c39 100644 --- a/packages/opentelemetry-sdk-node/package.json +++ b/packages/opentelemetry-sdk-node/package.json @@ -43,7 +43,6 @@ "dependencies": { "@opentelemetry/api": "0.9.0", "@opentelemetry/context-base": "0.9.0", - "@opentelemetry/context-async-hooks": "0.9.0", "@opentelemetry/core": "0.9.0", "@opentelemetry/metrics": "0.9.0", "@opentelemetry/node": "0.9.0", @@ -51,12 +50,12 @@ "@opentelemetry/tracing": "0.9.0" }, "devDependencies": { + "@opentelemetry/context-async-hooks": "0.9.0", "@types/mocha": "7.0.2", "@types/node": "14.0.13", "codecov": "3.7.0", "gts": "2.0.2", "istanbul-instrumenter-loader": "3.0.1", - "linkinator": "2.1.1", "mocha": "7.2.0", "nyc": "15.1.0", "ts-loader": "7.0.5", From be003720e543519ca18ed6cb4f52d04080df6e4f Mon Sep 17 00:00:00 2001 From: Daniel Dyla Date: Wed, 1 Jul 2020 11:38:36 -0400 Subject: [PATCH 10/26] chore: lint, add tsdocs, and remove meter/tracer resource separation --- packages/opentelemetry-sdk-node/src/sdk.ts | 35 +++++++------ packages/opentelemetry-sdk-node/src/types.ts | 1 - .../opentelemetry-sdk-node/test/sdk.test.ts | 50 +++++++++---------- 3 files changed, 40 insertions(+), 46 deletions(-) diff --git a/packages/opentelemetry-sdk-node/src/sdk.ts b/packages/opentelemetry-sdk-node/src/sdk.ts index fc077f533c..dfe679dbe6 100644 --- a/packages/opentelemetry-sdk-node/src/sdk.ts +++ b/packages/opentelemetry-sdk-node/src/sdk.ts @@ -22,6 +22,7 @@ import { detectResources, Resource } from '@opentelemetry/resources'; import { BatchSpanProcessor, SpanProcessor } from '@opentelemetry/tracing'; import { NodeSDKConfiguration } from './types'; +/** This class represents everything needed to register a fully configured OpenTelemetry NodeJS SDK */ export class NodeSDK { private _tracerProviderConfig?: { tracerConfig: NodeTracerConfig; @@ -31,17 +32,17 @@ export class NodeSDK { }; private _meterProviderConfig?: MeterConfig; - private _traceResource: Resource; - private _metricsResource: Resource; + private _resource: Resource; + /** + * Create a new NodeJS SDK instance + */ public constructor(configuration: Partial = {}) { const resource = configuration.resource ?? new Resource({}); - this._traceResource = configuration.traceResource ?? new Resource({}); - this._metricsResource = configuration.metricResource ?? new Resource({}); + this._resource = configuration.traceResource ?? new Resource({}); - this._traceResource = this._traceResource.merge(resource); - this._metricsResource = this._metricsResource.merge(resource); + this._resource = this._resource.merge(resource); if (configuration.spanProcessor || configuration.traceExporter) { const tracerProviderConfig = { @@ -76,6 +77,7 @@ export class NodeSDK { } } + /** Set configurations required to register a NodeTracerProvider */ public configureTracerProvider( tracerConfig: NodeTracerConfig, spanProcessor: SpanProcessor, @@ -90,32 +92,29 @@ export class NodeSDK { }; } + /** Set configurations needed to register a MeterProvider */ public configureMeterProvider(config: MeterConfig) { this._meterProviderConfig = config; } + /** Detect resource attributes from the execution environment */ public async detectResources() { this.addResource(await detectResources()); } + /** Manually add a resource */ public async addResource(resource: Resource) { - this.addTraceResource(resource); - this.addMetricsResource(resource); - } - - public async addTraceResource(resource: Resource) { - this._traceResource.merge(resource); - } - - public async addMetricsResource(resource: Resource) { - this._metricsResource.merge(resource); + this._resource.merge(resource); } + /** + * Once the SDK has been configured, call this method to construct SDK components and register them with the OpenTelemetry API. + */ public start() { if (this._tracerProviderConfig) { const tracerProvider = new NodeTracerProvider({ ...this._tracerProviderConfig.tracerConfig, - resource: this._traceResource, + resource: this._resource, }); tracerProvider.addSpanProcessor(this._tracerProviderConfig.spanProcessor); @@ -128,7 +127,7 @@ export class NodeSDK { if (this._meterProviderConfig) { const meterProvider = new MeterProvider({ ...this._meterProviderConfig, - resource: this._metricsResource, + resource: this._resource, }); metrics.setGlobalMeterProvider(meterProvider); diff --git a/packages/opentelemetry-sdk-node/src/types.ts b/packages/opentelemetry-sdk-node/src/types.ts index b936152cf9..dcc37aa396 100644 --- a/packages/opentelemetry-sdk-node/src/types.ts +++ b/packages/opentelemetry-sdk-node/src/types.ts @@ -25,7 +25,6 @@ export interface NodeSDKConfiguration { metricBatcher: metrics.Batcher; metricExporter: metrics.MetricExporter; metricInterval: number; - metricResource: resources.Resource; plugins: node.Plugins; httpTextPropagator: api.HttpTextPropagator; resource: resources.Resource; diff --git a/packages/opentelemetry-sdk-node/test/sdk.test.ts b/packages/opentelemetry-sdk-node/test/sdk.test.ts index 140a5f4912..64189371a1 100644 --- a/packages/opentelemetry-sdk-node/test/sdk.test.ts +++ b/packages/opentelemetry-sdk-node/test/sdk.test.ts @@ -18,15 +18,21 @@ import { context, metrics, NoopHttpTextPropagator, - NoopMeterProvider, NoopTracerProvider, propagation, - trace + NoopMeterProvider, + NoopTracerProvider, + propagation, + trace, } from '@opentelemetry/api'; import { AsyncHooksContextManager } from '@opentelemetry/context-async-hooks'; import { NoopContextManager } from '@opentelemetry/context-base'; import { CompositePropagator } from '@opentelemetry/core'; import { ConsoleMetricExporter, MeterProvider } from '@opentelemetry/metrics'; import { NodeTracerProvider } from '@opentelemetry/node'; -import { ConsoleSpanExporter, InMemorySpanExporter, SimpleSpanProcessor } from '@opentelemetry/tracing'; +import { + ConsoleSpanExporter, + InMemorySpanExporter, + SimpleSpanProcessor, +} from '@opentelemetry/tracing'; import * as assert from 'assert'; import { api, NodeSDK, tracing } from '../src'; @@ -38,15 +44,13 @@ describe('Node SDK', () => { metrics.disable(); }); - describe("Basic Registration", () => { + describe('Basic Registration', () => { it('should not register any unconfigured SDK components', () => { const sdk = new NodeSDK(); sdk.start(); - assert.ok( - context['_getContextManager']() instanceof NoopContextManager - ); + assert.ok(context['_getContextManager']() instanceof NoopContextManager); assert.ok( propagation['_getGlobalPropagator']() instanceof NoopHttpTextPropagator ); @@ -62,10 +66,8 @@ describe('Node SDK', () => { sdk.start(); - assert.ok(metrics.getMeterProvider() instanceof NoopMeterProvider); - assert.ok( context['_getContextManager']() instanceof AsyncHooksContextManager ); @@ -85,10 +87,8 @@ describe('Node SDK', () => { sdk.start(); - assert.ok(metrics.getMeterProvider() instanceof NoopMeterProvider); - assert.ok( context['_getContextManager']() instanceof AsyncHooksContextManager ); @@ -98,7 +98,6 @@ describe('Node SDK', () => { assert.ok(trace.getTracerProvider() instanceof NodeTracerProvider); }); - it('should register a meter provider if an exporter is provided', () => { const exporter = new ConsoleMetricExporter(); @@ -108,9 +107,7 @@ describe('Node SDK', () => { sdk.start(); - assert.ok( - context['_getContextManager']() instanceof NoopContextManager - ); + assert.ok(context['_getContextManager']() instanceof NoopContextManager); assert.ok( propagation['_getGlobalPropagator']() instanceof NoopHttpTextPropagator ); @@ -120,7 +117,7 @@ describe('Node SDK', () => { assert.ok(metrics.getMeterProvider() instanceof MeterProvider); }); - describe("Tracing Options", () => { + describe('Tracing Options', () => { let traceExporter: InMemorySpanExporter; let spanProcessor: SimpleSpanProcessor; @@ -133,29 +130,28 @@ describe('Node SDK', () => { traceExporter.reset(); }); - it("should apply global attributes to every span", () => { + it('should apply global attributes to every span', () => { const sdk = new NodeSDK({ spanProcessor, defaultAttributes: { - "default.attribute": "test" - } + 'default.attribute': 'test', + }, }); sdk.start(); - const tracer = api.trace.getTracer("test"); + const tracer = api.trace.getTracer('test'); assert(tracer instanceof tracing.Tracer); - const provider = tracer["_tracerProvider"]; + const provider = tracer['_tracerProvider']; assert(provider instanceof NodeTracerProvider); - - const span = api.trace.getTracer("test").startSpan("test"); + const span = api.trace.getTracer('test').startSpan('test'); assert(span instanceof tracing.Span); - assert.strictEqual(span.attributes["default.attribute"], "test") - }) - }) + assert.strictEqual(span.attributes['default.attribute'], 'test'); + }); + }); }); -}); \ No newline at end of file +}); From 72d55a85953a076b47852a7e98b88fd27c9ee48c Mon Sep 17 00:00:00 2001 From: Daniel Dyla Date: Wed, 1 Jul 2020 11:54:37 -0400 Subject: [PATCH 11/26] chore: do not overwrite defaults with undefined --- packages/opentelemetry-sdk-node/src/sdk.ts | 60 +++++++++++++------- packages/opentelemetry-sdk-node/src/types.ts | 1 - 2 files changed, 40 insertions(+), 21 deletions(-) diff --git a/packages/opentelemetry-sdk-node/src/sdk.ts b/packages/opentelemetry-sdk-node/src/sdk.ts index dfe679dbe6..521a2318a0 100644 --- a/packages/opentelemetry-sdk-node/src/sdk.ts +++ b/packages/opentelemetry-sdk-node/src/sdk.ts @@ -38,21 +38,29 @@ export class NodeSDK { * Create a new NodeJS SDK instance */ public constructor(configuration: Partial = {}) { - const resource = configuration.resource ?? new Resource({}); - - this._resource = configuration.traceResource ?? new Resource({}); - - this._resource = this._resource.merge(resource); + this._resource = configuration.resource ?? new Resource({}); if (configuration.spanProcessor || configuration.traceExporter) { - const tracerProviderConfig = { - defaultAttributes: configuration.defaultAttributes, - logLevel: configuration.logLevel, - logger: configuration.logger, - plugins: configuration.plugins, - sampler: configuration.sampler, - traceParams: configuration.traceParams, - }; + const tracerProviderConfig = {} as NodeTracerConfig; + + if (configuration.defaultAttributes) { + tracerProviderConfig.defaultAttributes = configuration.defaultAttributes; + } + if (typeof configuration.logLevel === 'number') { + tracerProviderConfig.logLevel = configuration.logLevel; + } + if (configuration.logger) { + tracerProviderConfig.logger = configuration.logger; + } + if (configuration.plugins) { + tracerProviderConfig.plugins = configuration.plugins; + } + if (configuration.sampler) { + tracerProviderConfig.sampler = configuration.sampler; + } + if (configuration.traceParams) { + tracerProviderConfig.traceParams = configuration.traceParams; + } const spanProcessor = configuration.spanProcessor ?? @@ -67,13 +75,25 @@ export class NodeSDK { } if (configuration.metricExporter) { - this.configureMeterProvider({ - batcher: configuration.metricBatcher, - exporter: configuration.metricExporter, - interval: configuration.metricInterval, - logLevel: configuration.logLevel, - logger: configuration.logger, - }); + const meterConfig: MeterConfig = {}; + + if (configuration.metricBatcher) { + meterConfig.batcher = configuration.metricBatcher; + } + if (configuration.metricExporter) { + meterConfig.exporter = configuration.metricExporter; + } + if (typeof configuration.metricInterval === 'number') { + meterConfig.interval = configuration.metricInterval; + } + if (typeof configuration.logLevel === 'number') { + meterConfig.logLevel = configuration.logLevel; + } + if (configuration.logger) { + meterConfig.logger = configuration.logger; + } + + this.configureMeterProvider(meterConfig); } } diff --git a/packages/opentelemetry-sdk-node/src/types.ts b/packages/opentelemetry-sdk-node/src/types.ts index dcc37aa396..84cf7319c4 100644 --- a/packages/opentelemetry-sdk-node/src/types.ts +++ b/packages/opentelemetry-sdk-node/src/types.ts @@ -32,5 +32,4 @@ export interface NodeSDKConfiguration { spanProcessor: tracing.SpanProcessor; traceExporter: tracing.SpanExporter; traceParams: tracing.TraceParams; - traceResource: resources.Resource; } From af30c471a47456036f3dbb30acb461e8396f25e3 Mon Sep 17 00:00:00 2001 From: Daniel Dyla Date: Wed, 1 Jul 2020 11:55:19 -0400 Subject: [PATCH 12/26] chore: lint --- packages/opentelemetry-sdk-node/src/sdk.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/packages/opentelemetry-sdk-node/src/sdk.ts b/packages/opentelemetry-sdk-node/src/sdk.ts index 521a2318a0..1ae4c5828a 100644 --- a/packages/opentelemetry-sdk-node/src/sdk.ts +++ b/packages/opentelemetry-sdk-node/src/sdk.ts @@ -44,7 +44,8 @@ export class NodeSDK { const tracerProviderConfig = {} as NodeTracerConfig; if (configuration.defaultAttributes) { - tracerProviderConfig.defaultAttributes = configuration.defaultAttributes; + tracerProviderConfig.defaultAttributes = + configuration.defaultAttributes; } if (typeof configuration.logLevel === 'number') { tracerProviderConfig.logLevel = configuration.logLevel; From fd0b6da20d69e1607649819a88853d7ed5fd057e Mon Sep 17 00:00:00 2001 From: Daniel Dyla Date: Wed, 1 Jul 2020 13:31:24 -0400 Subject: [PATCH 13/26] Update packages/opentelemetry-sdk-node/README.md Co-authored-by: legendecas --- packages/opentelemetry-sdk-node/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/opentelemetry-sdk-node/README.md b/packages/opentelemetry-sdk-node/README.md index 06112b4bab..55a3bf5c1b 100644 --- a/packages/opentelemetry-sdk-node/README.md +++ b/packages/opentelemetry-sdk-node/README.md @@ -27,7 +27,7 @@ $ npm install \ @opentelemetry/plugin-http # add plugins as needed ``` -> Note: this example is for node.js. See [examples/tracer-web](https://github.com/open-telemetry/opentelemetry-js/tree/master/examples/tracer-web) for a browser example. +> Note: this example is for Node.js. See [examples/tracer-web](https://github.com/open-telemetry/opentelemetry-js/tree/master/examples/tracer-web) for a browser example. ### Initialize the SDK From 6abf36f87ba7b28bc1ee4a202282d1bf32dd469e Mon Sep 17 00:00:00 2001 From: Daniel Dyla Date: Wed, 1 Jul 2020 16:14:12 -0400 Subject: [PATCH 14/26] Update packages/opentelemetry-sdk-node/package.json Co-authored-by: Mark Wolff --- packages/opentelemetry-sdk-node/package.json | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/opentelemetry-sdk-node/package.json b/packages/opentelemetry-sdk-node/package.json index a9019e6c39..9f2be8372f 100644 --- a/packages/opentelemetry-sdk-node/package.json +++ b/packages/opentelemetry-sdk-node/package.json @@ -33,6 +33,7 @@ }, "files": [ "build/src/**/*.js", + "build/src/**/*.js.map", "build/src/**/*.d.ts", "LICENSE", "README.md" From 28a1cde51be9457d77507fcf609d07652a19bdd3 Mon Sep 17 00:00:00 2001 From: Daniel Dyla Date: Wed, 1 Jul 2020 16:20:48 -0400 Subject: [PATCH 15/26] chore: node.js casing --- packages/opentelemetry-sdk-node/README.md | 2 +- packages/opentelemetry-sdk-node/package.json | 2 +- packages/opentelemetry-sdk-node/src/sdk.ts | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/opentelemetry-sdk-node/README.md b/packages/opentelemetry-sdk-node/README.md index 55a3bf5c1b..a4358d7903 100644 --- a/packages/opentelemetry-sdk-node/README.md +++ b/packages/opentelemetry-sdk-node/README.md @@ -1,4 +1,4 @@ -# OpenTelemetry SDK for NodeJS +# OpenTelemetry SDK for Node.js [![Gitter chat][gitter-image]][gitter-url] [![NPM Published Version][npm-img]][npm-url] diff --git a/packages/opentelemetry-sdk-node/package.json b/packages/opentelemetry-sdk-node/package.json index 9f2be8372f..3d9d8cf42e 100644 --- a/packages/opentelemetry-sdk-node/package.json +++ b/packages/opentelemetry-sdk-node/package.json @@ -1,7 +1,7 @@ { "name": "@opentelemetry/sdk-node", "version": "0.8.3", - "description": "OpenTelemetry SDK for NodeJS", + "description": "OpenTelemetry SDK for Node.js", "main": "build/src/index.js", "types": "build/src/index.d.ts", "repository": "open-telemetry/opentelemetry-js", diff --git a/packages/opentelemetry-sdk-node/src/sdk.ts b/packages/opentelemetry-sdk-node/src/sdk.ts index 1ae4c5828a..2e8546daa8 100644 --- a/packages/opentelemetry-sdk-node/src/sdk.ts +++ b/packages/opentelemetry-sdk-node/src/sdk.ts @@ -22,7 +22,7 @@ import { detectResources, Resource } from '@opentelemetry/resources'; import { BatchSpanProcessor, SpanProcessor } from '@opentelemetry/tracing'; import { NodeSDKConfiguration } from './types'; -/** This class represents everything needed to register a fully configured OpenTelemetry NodeJS SDK */ +/** This class represents everything needed to register a fully configured OpenTelemetry Node.js SDK */ export class NodeSDK { private _tracerProviderConfig?: { tracerConfig: NodeTracerConfig; From 66bb9d772c29626616116ab97bc91571f47af54d Mon Sep 17 00:00:00 2001 From: Daniel Dyla Date: Thu, 2 Jul 2020 10:02:08 -0400 Subject: [PATCH 16/26] Update packages/opentelemetry-sdk-node/package.json Co-authored-by: Naseem --- packages/opentelemetry-sdk-node/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/opentelemetry-sdk-node/package.json b/packages/opentelemetry-sdk-node/package.json index 3d9d8cf42e..7815a67644 100644 --- a/packages/opentelemetry-sdk-node/package.json +++ b/packages/opentelemetry-sdk-node/package.json @@ -1,6 +1,6 @@ { "name": "@opentelemetry/sdk-node", - "version": "0.8.3", + "version": "0.9.0", "description": "OpenTelemetry SDK for Node.js", "main": "build/src/index.js", "types": "build/src/index.d.ts", From d8de20bcc115b0f0e61355fa6c614398c5c16ac9 Mon Sep 17 00:00:00 2001 From: Daniel Dyla Date: Thu, 2 Jul 2020 14:25:38 -0400 Subject: [PATCH 17/26] chore: document sdk options --- packages/opentelemetry-sdk-node/README.md | 37 ++++++++++++++++++----- 1 file changed, 30 insertions(+), 7 deletions(-) diff --git a/packages/opentelemetry-sdk-node/README.md b/packages/opentelemetry-sdk-node/README.md index a4358d7903..47745bbd6b 100644 --- a/packages/opentelemetry-sdk-node/README.md +++ b/packages/opentelemetry-sdk-node/README.md @@ -6,13 +6,11 @@ [![devDependencies][devDependencies-image]][devDependencies-url] [![Apache License][license-image]][license-image] -@ToDo -This package provides... +This package provides the full OpenTelemetry SDK for Node.js including tracing and metrics. ## Quick Start -@ToDo -To get started you need to ... +To get started you need to install `@opentelemetry/sdk-node`, a metrics and/or tracing exporter, and any appropriate plugins for the node modules used by your application. ### Installation @@ -25,6 +23,9 @@ $ npm install \ @opentelemetry/exporter-jaeger \ # add tracing exporters as needed @opentelemetry/exporter-prometheus # add metrics exporters as needed @opentelemetry/plugin-http # add plugins as needed + +$ # or install all officially supported core and contrib plugins +$ npm install @opentelemetry/plugins-node-all ``` > Note: this example is for Node.js. See [examples/tracer-web](https://github.com/open-telemetry/opentelemetry-js/tree/master/examples/tracer-web) for a browser example. @@ -65,35 +66,57 @@ sdk ## Configuration -@ToDo add descriptions for all configurations +Below is a full list of configuration options which may be passed into the `NodeSDK` constructor; ### contextManager +Use a custom context manager. Default: [AsyncHooksContextManager](../opentelemetry-context-async-hooks/README.md) + ### httpTextPropagator +Use a custom propagator. Default: [CompositePropagator]() using [W3C Trace Context](../opentelemetry-core/README.md#httptracecontext-propagator) and [Correlation Context](../opentelemetry-core/README.md#correlation-context-propagator) + ### logger +Use a custom logger. Default: Logging disabled + ### logLevel +Default: [INFO](../opentelemetry-core/src/common/types.ts#L19) + ### metricBatcher +Use a custom batcher for metrics. Default: [UngroupedBatcher](../opentelemetry-metrics/src/export/Batcher.ts#L50) + ### metricExporter +Configure a metric exporter. If an exporter is not configured, the metrics SDK will not be initialized and registered. + ### metricInterval -### metricResource +Configure an interval for metrics export in ms. Default: 60,000 (60 seconds) ### plugins +Configure plugins. By default, all plugins which are installed and in the [Default Plugins List](../opentelemetry-node/src/config.ts#L29) will be enabled. + ### resource +Configure a resource. Resources may also be detected by using the `autoDetectResources` method of the SDK. + ### sampler +Configure a custom sampler. By default all traces will be sampled. + +### spanProcessor + ### traceExporter +Configure a trace exporter. If an exporter OR span processor is not configured, the tracing SDK will not be initialized and registered. If an exporter is configured, it will be used with a [BatchSpanProcessor](../opentelemetry-tracing/src/export/BatchSpanProcessor.ts). + ### traceParams -### traceResource +Configure tracing parameters. These are the same trace parameters used to [configure a tracer](../opentelemetry-tracing/src/types.ts#L71). ## Useful links From 4941111cf06fed04b5842d824f02dc6ded3c8081 Mon Sep 17 00:00:00 2001 From: Daniel Dyla Date: Thu, 2 Jul 2020 14:31:11 -0400 Subject: [PATCH 18/26] chore: fix empty link --- packages/opentelemetry-sdk-node/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/opentelemetry-sdk-node/README.md b/packages/opentelemetry-sdk-node/README.md index 47745bbd6b..52189e74cb 100644 --- a/packages/opentelemetry-sdk-node/README.md +++ b/packages/opentelemetry-sdk-node/README.md @@ -74,7 +74,7 @@ Use a custom context manager. Default: [AsyncHooksContextManager](../opentelemet ### httpTextPropagator -Use a custom propagator. Default: [CompositePropagator]() using [W3C Trace Context](../opentelemetry-core/README.md#httptracecontext-propagator) and [Correlation Context](../opentelemetry-core/README.md#correlation-context-propagator) +Use a custom propagator. Default: [CompositePropagator](../opentelemetry-core/src/context/propagation/composite.ts) using [W3C Trace Context](../opentelemetry-core/README.md#httptracecontext-propagator) and [Correlation Context](../opentelemetry-core/README.md#correlation-context-propagator) ### logger From caa95470156b9b0a44c9389b3ca05f45db551c30 Mon Sep 17 00:00:00 2001 From: Daniel Dyla Date: Thu, 16 Jul 2020 15:12:17 -0400 Subject: [PATCH 19/26] chore: add auto detect resources --- packages/opentelemetry-sdk-node/README.md | 8 ++++++-- packages/opentelemetry-sdk-node/src/sdk.ts | 12 ++++++++++-- packages/opentelemetry-sdk-node/src/types.ts | 2 ++ packages/opentelemetry-sdk-node/src/version.ts | 2 +- 4 files changed, 19 insertions(+), 5 deletions(-) diff --git a/packages/opentelemetry-sdk-node/README.md b/packages/opentelemetry-sdk-node/README.md index 52189e74cb..2db342d0d7 100644 --- a/packages/opentelemetry-sdk-node/README.md +++ b/packages/opentelemetry-sdk-node/README.md @@ -58,9 +58,9 @@ const sdk = new opentelemetry.NodeSDK({ // You can optionally detect resources asynchronously from the environment. // Detected resources are merged with the resources provided in the SDK configuration. sdk - .autoDetectResources() + .start() .then(() => { - sdk.start(); + // Resources have been detected and SDK is started }) ``` @@ -68,6 +68,10 @@ sdk Below is a full list of configuration options which may be passed into the `NodeSDK` constructor; +### autoDetectResources + +Detect resources automatically from the environment using the default resource detectors. Default `true`. + ### contextManager Use a custom context manager. Default: [AsyncHooksContextManager](../opentelemetry-context-async-hooks/README.md) diff --git a/packages/opentelemetry-sdk-node/src/sdk.ts b/packages/opentelemetry-sdk-node/src/sdk.ts index 2e8546daa8..fd560c3f49 100644 --- a/packages/opentelemetry-sdk-node/src/sdk.ts +++ b/packages/opentelemetry-sdk-node/src/sdk.ts @@ -34,12 +34,16 @@ export class NodeSDK { private _resource: Resource; + private _autoDetectResources: boolean; + /** * Create a new NodeJS SDK instance */ public constructor(configuration: Partial = {}) { this._resource = configuration.resource ?? new Resource({}); + this._autoDetectResources = configuration.autoDetectResources ?? true; + if (configuration.spanProcessor || configuration.traceExporter) { const tracerProviderConfig = {} as NodeTracerConfig; @@ -124,14 +128,18 @@ export class NodeSDK { } /** Manually add a resource */ - public async addResource(resource: Resource) { + public addResource(resource: Resource) { this._resource.merge(resource); } /** * Once the SDK has been configured, call this method to construct SDK components and register them with the OpenTelemetry API. */ - public start() { + public async start() { + if (this._autoDetectResources) { + await this.detectResources(); + } + if (this._tracerProviderConfig) { const tracerProvider = new NodeTracerProvider({ ...this._tracerProviderConfig.tracerConfig, diff --git a/packages/opentelemetry-sdk-node/src/types.ts b/packages/opentelemetry-sdk-node/src/types.ts index 84cf7319c4..760d7b2ff4 100644 --- a/packages/opentelemetry-sdk-node/src/types.ts +++ b/packages/opentelemetry-sdk-node/src/types.ts @@ -18,6 +18,8 @@ import type { ContextManager } from '@opentelemetry/context-base'; import type { api, core, metrics, node, resources, tracing } from '.'; export interface NodeSDKConfiguration { + autoDetectResources: boolean; + defaultAttributes: api.Attributes; logger: api.Logger; logLevel: core.LogLevel; diff --git a/packages/opentelemetry-sdk-node/src/version.ts b/packages/opentelemetry-sdk-node/src/version.ts index 9e616149a4..2c92beb616 100644 --- a/packages/opentelemetry-sdk-node/src/version.ts +++ b/packages/opentelemetry-sdk-node/src/version.ts @@ -15,4 +15,4 @@ */ // this is autogenerated file, see scripts/version-update.js -export const VERSION = '0.8.3'; +export const VERSION = '0.9.0'; From ee625a6b16250dbe188062d9657855265a26718c Mon Sep 17 00:00:00 2001 From: Daniel Dyla Date: Tue, 21 Jul 2020 15:42:44 -0400 Subject: [PATCH 20/26] fix: replace resource with merged resource Co-authored-by: Matthew Wear --- packages/opentelemetry-sdk-node/src/sdk.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/opentelemetry-sdk-node/src/sdk.ts b/packages/opentelemetry-sdk-node/src/sdk.ts index fd560c3f49..03626314f4 100644 --- a/packages/opentelemetry-sdk-node/src/sdk.ts +++ b/packages/opentelemetry-sdk-node/src/sdk.ts @@ -129,7 +129,7 @@ export class NodeSDK { /** Manually add a resource */ public addResource(resource: Resource) { - this._resource.merge(resource); + this._resource = this._resource.merge(resource); } /** From 7578e7be7f1daa64a1467dfa1560ddf8f18b521a Mon Sep 17 00:00:00 2001 From: Daniel Dyla Date: Tue, 21 Jul 2020 15:42:59 -0400 Subject: [PATCH 21/26] chore: copyright header Co-authored-by: Matthew Wear --- packages/opentelemetry-sdk-node/LICENSE | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/opentelemetry-sdk-node/LICENSE b/packages/opentelemetry-sdk-node/LICENSE index 261eeb9e9f..5d6f747bfd 100644 --- a/packages/opentelemetry-sdk-node/LICENSE +++ b/packages/opentelemetry-sdk-node/LICENSE @@ -186,7 +186,7 @@ same "printed page" as the copyright notice for easier identification within third-party archives. - Copyright [yyyy] [name of copyright owner] + Copyright 2020 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. From c93a6cc8274c3f3eb510856cee710e8309d653f3 Mon Sep 17 00:00:00 2001 From: Daniel Dyla Date: Wed, 22 Jul 2020 15:40:29 -0400 Subject: [PATCH 22/26] chore: make tests pass --- packages/opentelemetry-sdk-node/src/sdk.ts | 4 +-- packages/opentelemetry-sdk-node/src/types.ts | 5 ++-- .../opentelemetry-sdk-node/test/sdk.test.ts | 28 +++++++++++-------- 3 files changed, 21 insertions(+), 16 deletions(-) diff --git a/packages/opentelemetry-sdk-node/src/sdk.ts b/packages/opentelemetry-sdk-node/src/sdk.ts index fd560c3f49..2a1c677d60 100644 --- a/packages/opentelemetry-sdk-node/src/sdk.ts +++ b/packages/opentelemetry-sdk-node/src/sdk.ts @@ -45,7 +45,7 @@ export class NodeSDK { this._autoDetectResources = configuration.autoDetectResources ?? true; if (configuration.spanProcessor || configuration.traceExporter) { - const tracerProviderConfig = {} as NodeTracerConfig; + const tracerProviderConfig: NodeTracerConfig = {}; if (configuration.defaultAttributes) { tracerProviderConfig.defaultAttributes = @@ -122,7 +122,7 @@ export class NodeSDK { this._meterProviderConfig = config; } - /** Detect resource attributes from the execution environment */ + /** Detect resource attributes */ public async detectResources() { this.addResource(await detectResources()); } diff --git a/packages/opentelemetry-sdk-node/src/types.ts b/packages/opentelemetry-sdk-node/src/types.ts index 760d7b2ff4..a093cbcfa4 100644 --- a/packages/opentelemetry-sdk-node/src/types.ts +++ b/packages/opentelemetry-sdk-node/src/types.ts @@ -19,16 +19,15 @@ import type { api, core, metrics, node, resources, tracing } from '.'; export interface NodeSDKConfiguration { autoDetectResources: boolean; - + contextManager: ContextManager; defaultAttributes: api.Attributes; + httpTextPropagator: api.HttpTextPropagator; logger: api.Logger; logLevel: core.LogLevel; - contextManager: ContextManager; metricBatcher: metrics.Batcher; metricExporter: metrics.MetricExporter; metricInterval: number; plugins: node.Plugins; - httpTextPropagator: api.HttpTextPropagator; resource: resources.Resource; sampler: api.Sampler; spanProcessor: tracing.SpanProcessor; diff --git a/packages/opentelemetry-sdk-node/test/sdk.test.ts b/packages/opentelemetry-sdk-node/test/sdk.test.ts index 64189371a1..d9a6c0c6cb 100644 --- a/packages/opentelemetry-sdk-node/test/sdk.test.ts +++ b/packages/opentelemetry-sdk-node/test/sdk.test.ts @@ -45,10 +45,12 @@ describe('Node SDK', () => { }); describe('Basic Registration', () => { - it('should not register any unconfigured SDK components', () => { - const sdk = new NodeSDK(); + it('should not register any unconfigured SDK components', async () => { + const sdk = new NodeSDK({ + autoDetectResources: false, + }); - sdk.start(); + await sdk.start(); assert.ok(context['_getContextManager']() instanceof NoopContextManager); assert.ok( @@ -59,12 +61,13 @@ describe('Node SDK', () => { assert.ok(metrics.getMeterProvider() instanceof NoopMeterProvider); }); - it('should register a tracer provider if an exporter is provided', () => { + it('should register a tracer provider if an exporter is provided', async () => { const sdk = new NodeSDK({ traceExporter: new ConsoleSpanExporter(), + autoDetectResources: false, }); - sdk.start(); + await sdk.start(); assert.ok(metrics.getMeterProvider() instanceof NoopMeterProvider); @@ -77,15 +80,16 @@ describe('Node SDK', () => { assert.ok(trace.getTracerProvider() instanceof NodeTracerProvider); }); - it('should register a tracer provider if a span processor is provided', () => { + it('should register a tracer provider if a span processor is provided', async () => { const exporter = new ConsoleSpanExporter(); const spanProcessor = new SimpleSpanProcessor(exporter); const sdk = new NodeSDK({ spanProcessor, + autoDetectResources: false, }); - sdk.start(); + await sdk.start(); assert.ok(metrics.getMeterProvider() instanceof NoopMeterProvider); @@ -98,14 +102,15 @@ describe('Node SDK', () => { assert.ok(trace.getTracerProvider() instanceof NodeTracerProvider); }); - it('should register a meter provider if an exporter is provided', () => { + it('should register a meter provider if an exporter is provided', async () => { const exporter = new ConsoleMetricExporter(); const sdk = new NodeSDK({ metricExporter: exporter, + autoDetectResources: false, }); - sdk.start(); + await sdk.start(); assert.ok(context['_getContextManager']() instanceof NoopContextManager); assert.ok( @@ -130,15 +135,16 @@ describe('Node SDK', () => { traceExporter.reset(); }); - it('should apply global attributes to every span', () => { + it('should apply global attributes to every span', async () => { const sdk = new NodeSDK({ spanProcessor, defaultAttributes: { 'default.attribute': 'test', }, + autoDetectResources: false, }); - sdk.start(); + await sdk.start(); const tracer = api.trace.getTracer('test'); assert(tracer instanceof tracing.Tracer); From 1c0b6e4cc0fea53e0fdd02dabfb2ef7e9e80ab4c Mon Sep 17 00:00:00 2001 From: Daniel Dyla Date: Thu, 23 Jul 2020 16:05:59 -0400 Subject: [PATCH 23/26] chore: remove double export --- packages/opentelemetry-metrics/src/index.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/opentelemetry-metrics/src/index.ts b/packages/opentelemetry-metrics/src/index.ts index 41c66d8b6b..2a0c408d71 100644 --- a/packages/opentelemetry-metrics/src/index.ts +++ b/packages/opentelemetry-metrics/src/index.ts @@ -25,6 +25,5 @@ export * from './export/aggregators'; export * from './export/Batcher'; export * from './export/ConsoleMetricExporter'; export * from './export/types'; -export * from './export/Batcher'; export * from './UpDownCounterMetric'; export { MeterConfig } from './types'; From 6b0e26e1065fb8e9c4256f059371e264ce67378d Mon Sep 17 00:00:00 2001 From: Daniel Dyla Date: Mon, 27 Jul 2020 12:37:31 -0400 Subject: [PATCH 24/26] chore: remove default attributes --- packages/opentelemetry-sdk-node/src/sdk.ts | 4 -- .../opentelemetry-sdk-node/test/sdk.test.ts | 38 ------------------- 2 files changed, 42 deletions(-) diff --git a/packages/opentelemetry-sdk-node/src/sdk.ts b/packages/opentelemetry-sdk-node/src/sdk.ts index f098fad052..3b27e1331e 100644 --- a/packages/opentelemetry-sdk-node/src/sdk.ts +++ b/packages/opentelemetry-sdk-node/src/sdk.ts @@ -47,10 +47,6 @@ export class NodeSDK { if (configuration.spanProcessor || configuration.traceExporter) { const tracerProviderConfig: NodeTracerConfig = {}; - if (configuration.defaultAttributes) { - tracerProviderConfig.defaultAttributes = - configuration.defaultAttributes; - } if (typeof configuration.logLevel === 'number') { tracerProviderConfig.logLevel = configuration.logLevel; } diff --git a/packages/opentelemetry-sdk-node/test/sdk.test.ts b/packages/opentelemetry-sdk-node/test/sdk.test.ts index d9a6c0c6cb..e20326ee47 100644 --- a/packages/opentelemetry-sdk-node/test/sdk.test.ts +++ b/packages/opentelemetry-sdk-node/test/sdk.test.ts @@ -121,43 +121,5 @@ describe('Node SDK', () => { assert.ok(metrics.getMeterProvider() instanceof MeterProvider); }); - - describe('Tracing Options', () => { - let traceExporter: InMemorySpanExporter; - let spanProcessor: SimpleSpanProcessor; - - beforeEach(() => { - traceExporter = new InMemorySpanExporter(); - spanProcessor = new SimpleSpanProcessor(traceExporter); - }); - - afterEach(() => { - traceExporter.reset(); - }); - - it('should apply global attributes to every span', async () => { - const sdk = new NodeSDK({ - spanProcessor, - defaultAttributes: { - 'default.attribute': 'test', - }, - autoDetectResources: false, - }); - - await sdk.start(); - const tracer = api.trace.getTracer('test'); - - assert(tracer instanceof tracing.Tracer); - - const provider = tracer['_tracerProvider']; - - assert(provider instanceof NodeTracerProvider); - - const span = api.trace.getTracer('test').startSpan('test'); - - assert(span instanceof tracing.Span); - assert.strictEqual(span.attributes['default.attribute'], 'test'); - }); - }); }); }); From a1f65e061b595214a0858e4d0f710efbfcb9db32 Mon Sep 17 00:00:00 2001 From: Daniel Dyla Date: Mon, 27 Jul 2020 13:32:08 -0400 Subject: [PATCH 25/26] chore: fix build --- packages/opentelemetry-sdk-node/test/sdk.test.ts | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/packages/opentelemetry-sdk-node/test/sdk.test.ts b/packages/opentelemetry-sdk-node/test/sdk.test.ts index e20326ee47..86d41ba28d 100644 --- a/packages/opentelemetry-sdk-node/test/sdk.test.ts +++ b/packages/opentelemetry-sdk-node/test/sdk.test.ts @@ -21,7 +21,7 @@ import { NoopMeterProvider, NoopTracerProvider, propagation, - trace, + trace } from '@opentelemetry/api'; import { AsyncHooksContextManager } from '@opentelemetry/context-async-hooks'; import { NoopContextManager } from '@opentelemetry/context-base'; @@ -30,11 +30,10 @@ import { ConsoleMetricExporter, MeterProvider } from '@opentelemetry/metrics'; import { NodeTracerProvider } from '@opentelemetry/node'; import { ConsoleSpanExporter, - InMemorySpanExporter, - SimpleSpanProcessor, + SimpleSpanProcessor } from '@opentelemetry/tracing'; import * as assert from 'assert'; -import { api, NodeSDK, tracing } from '../src'; +import { NodeSDK } from '../src'; describe('Node SDK', () => { beforeEach(() => { From 5e1a23338532abd2d443c5e0b518512c7153cd83 Mon Sep 17 00:00:00 2001 From: Daniel Dyla Date: Mon, 27 Jul 2020 13:40:49 -0400 Subject: [PATCH 26/26] chore: lint --- packages/opentelemetry-sdk-node/test/sdk.test.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/opentelemetry-sdk-node/test/sdk.test.ts b/packages/opentelemetry-sdk-node/test/sdk.test.ts index 86d41ba28d..b9d464025d 100644 --- a/packages/opentelemetry-sdk-node/test/sdk.test.ts +++ b/packages/opentelemetry-sdk-node/test/sdk.test.ts @@ -21,7 +21,7 @@ import { NoopMeterProvider, NoopTracerProvider, propagation, - trace + trace, } from '@opentelemetry/api'; import { AsyncHooksContextManager } from '@opentelemetry/context-async-hooks'; import { NoopContextManager } from '@opentelemetry/context-base'; @@ -30,7 +30,7 @@ import { ConsoleMetricExporter, MeterProvider } from '@opentelemetry/metrics'; import { NodeTracerProvider } from '@opentelemetry/node'; import { ConsoleSpanExporter, - SimpleSpanProcessor + SimpleSpanProcessor, } from '@opentelemetry/tracing'; import * as assert from 'assert'; import { NodeSDK } from '../src';