diff --git a/api/README.md b/api/README.md
index 792daa6ec6..586054dbf4 100644
--- a/api/README.md
+++ b/api/README.md
@@ -1 +1,123 @@
-# opentelemetry-js-api
\ No newline at end of file
+# OpenTelemetry API for JavaScript
+[![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]
+
+This package provides everything needed to interact with the OpenTelemetry API, including all TypeScript interfaces, enums, and no-op implementations. It is intended for use both on the server and in the browser.
+
+## Basic Use
+
+### API Entry Point
+
+API entry points are defined as global singleton objects `trace` and `metrics` which contain methods used to initialize SDK implementations and acquire resources from the API.
+
+- [Trace API Documentation][trace-api-docs]
+- [Metrics API Documentation][metrics-api-docs]
+
+```javascript
+const api = require("@opentelemetry/api")
+
+/* Initialize TraceRegistry */
+api.trace.initGlobalTracerRegistry(traceRegistry);
+/* returns traceRegistry (no-op if a working registry has not been initialized) */
+api.trace.getTracerRegistry();
+/* returns a tracer from the registered global tracer registry (no-op if a working registry has not been initialized); */
+api.trace.getTracer(name, version);
+
+/* Initialize MeterRegistry */
+api.metrics.initGlobalMeterRegistry(meterRegistry);
+/* returns meterRegistry (no-op if a working registry has not been initialized) */
+api.metrics.getMeterRegistry();
+/* returns a meter from the registered global meter registry (no-op if a working registry has not been initialized); */
+api.metrics.getMeter(name, version);
+```
+
+### Application Owners
+
+Application owners will also need a working OpenTelemetry SDK implementation. OpenTelemetry provides working SDK implementations for [web] and [node] for both [tracing] and [metrics].
+
+#### Simple NodeJS Example
+
+Before any other module in your application is loaded, you must initialize the global tracer and meter registries. If you fail to initialize a registry, no-op implementations will be provided to any library which acquires them from the API.
+
+```javascript
+const api = require("@opentelemetry/api");
+const sdk = require("@opentelemetry/node");
+
+const { SimpleSpanProcessor } = require('@opentelemetry/tracing');
+const { JaegerExporter } = require('@opentelemetry/exporter-jaeger');
+
+// Initialize an exporter
+const exporter = new JaegerExporter({
+ serviceName: 'basic-service'
+});
+
+// Create a registry which we will configure as the global tracer registry
+const registry = new sdk.NodeTracerRegistry();
+
+// Configure span processor to send spans to the exporter
+registry.addSpanProcessor(new SimpleSpanProcessor(exporter));
+
+// Initialize the OpenTelemetry APIs to use the NodeTracerRegistry bindings
+api.trace.initGlobalTracerRegistry(registry);
+
+// your application code below this line
+```
+
+### Library Authors
+
+Library authors need only to depend on the `@opentelemetry/api` package and trust that the application owners which use their library will initialize an appropriate SDK.
+
+```javascript
+const api = require("@opentelemetry/api");
+
+const tracer = api.trace.getTracer("my-library-name", "0.2.3");
+
+async function doSomething() {
+ const span = tracer.startSpan("doSomething", { parent: tracer.getCurrentSpan() });
+ try {
+ const result = await doSomethingElse();
+ span.end();
+ return result;
+ } catch (err) {
+ span.setStatus({
+ // use an appropriate status code here
+ code: api.CanonicalCode.INTERNAL,
+ message: err.message,
+ });
+ span.end();
+ return null;
+ }
+}
+```
+
+
+## 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-api
+[dependencies-url]: https://david-dm.org/open-telemetry/opentelemetry-js?path=packages%2Fopentelemetry-api
+[devDependencies-image]: https://david-dm.org/open-telemetry/opentelemetry-js/dev-status.svg?path=packages/opentelemetry-api
+[devDependencies-url]: https://david-dm.org/open-telemetry/opentelemetry-js?path=packages%2Fopentelemetry-api&type=dev
+[npm-url]: https://www.npmjs.com/package/@opentelemetry/api
+[npm-img]: https://badge.fury.io/js/%40opentelemetry%2Ftypes.svg
+
+[trace-api-docs]: https://open-telemetry.github.io/opentelemetry-js/classes/traceapi.html
+[metrics-api-docs]: https://open-telemetry.github.io/opentelemetry-js/classes/metricsapi.html
+
+[web]: https://github.com/open-telemetry/opentelemetry-js/tree/master/packages/opentelemetry-web
+[tracing]: https://github.com/open-telemetry/opentelemetry-js/tree/master/packages/opentelemetry-tracing
+[node]: https://github.com/open-telemetry/opentelemetry-js/tree/master/packages/opentelemetry-node
+[metrics]: https://github.com/open-telemetry/opentelemetry-js/tree/master/packages/opentelemetry-metrics
diff --git a/api/package.json b/api/package.json
new file mode 100644
index 0000000000..e270187111
--- /dev/null
+++ b/api/package.json
@@ -0,0 +1,72 @@
+{
+ "name": "@opentelemetry/api",
+ "version": "0.3.3",
+ "description": "Public API for OpenTelemetry",
+ "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/**/*.ts",
+ "test:browser": "nyc karma start --single-run",
+ "codecov": "nyc report --reporter=json && codecov -f coverage/*.json -p ../../",
+ "codecov:browser": "nyc report --reporter=json && codecov -f coverage/*.json -p ../../",
+ "build": "npm run compile",
+ "check": "gts check",
+ "precompile": "tsc --version",
+ "version:update": "node ../../scripts/version-update.js",
+ "compile": "npm run version:update && tsc -p .",
+ "fix": "gts fix",
+ "docs-test": "linkinator docs/out --silent --skip david-dm.org --skip https://open-telemetry.github.io/opentelemetry-js/classes/.+api.html",
+ "docs": "typedoc --tsconfig tsconfig.json",
+ "prepare": "npm run compile"
+ },
+ "keywords": [
+ "opentelemetry",
+ "nodejs",
+ "browser",
+ "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",
+ "doc",
+ "LICENSE",
+ "README.md"
+ ],
+ "publishConfig": {
+ "access": "public"
+ },
+ "devDependencies": {
+ "@types/mocha": "^5.2.7",
+ "@types/node": "^12.6.8",
+ "@types/webpack-env": "1.13.9",
+ "codecov": "^3.6.1",
+ "gts": "^1.1.0",
+ "istanbul-instrumenter-loader": "^3.0.1",
+ "karma-chrome-launcher": "^3.1.0",
+ "karma-coverage-istanbul-reporter": "^2.1.0",
+ "karma-mocha": "^1.3.0",
+ "karma-spec-reporter": "^0.0.32",
+ "karma-webpack": "^4.0.2",
+ "karma": "^4.4.1",
+ "linkinator": "^1.5.0",
+ "mocha": "^6.1.0",
+ "nyc": "^14.1.1",
+ "ts-loader": "^6.0.4",
+ "ts-mocha": "^6.0.0",
+ "tslint-consistent-codestyle": "^1.15.1",
+ "tslint-microsoft-contrib": "^6.2.0",
+ "typedoc": "^0.15.0",
+ "typescript": "3.7.2",
+ "webpack": "^4.35.2"
+ }
+}
diff --git a/api/packages/opentelemetry-api/LICENSE b/api/packages/opentelemetry-api/LICENSE
new file mode 100644
index 0000000000..261eeb9e9f
--- /dev/null
+++ b/api/packages/opentelemetry-api/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/api/packages/opentelemetry-api/karma.conf.js b/api/packages/opentelemetry-api/karma.conf.js
new file mode 100644
index 0000000000..7183aab033
--- /dev/null
+++ b/api/packages/opentelemetry-api/karma.conf.js
@@ -0,0 +1,24 @@
+/*!
+ * Copyright 2019, 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
+ *
+ * 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.
+ */
+
+const karmaWebpackConfig = require('../../karma.webpack');
+const karmaBaseConfig = require('../../karma.base');
+
+module.exports = (config) => {
+ config.set(Object.assign({}, karmaBaseConfig, {
+ webpack: karmaWebpackConfig
+ }))
+};
diff --git a/api/packages/opentelemetry-api/tsconfig.json b/api/packages/opentelemetry-api/tsconfig.json
new file mode 100644
index 0000000000..2b05ed8413
--- /dev/null
+++ b/api/packages/opentelemetry-api/tsconfig.json
@@ -0,0 +1,16 @@
+{
+ "extends": "../tsconfig.base",
+ "compilerOptions": {
+ "rootDir": ".",
+ "outDir": "build"
+ },
+ "include": [
+ "src/**/*.ts"
+ ],
+ "typedocOptions": {
+ "name": "OpenTelemetry API for JavaScript",
+ "out": "docs/out",
+ "mode": "file",
+ "hideGenerator": true
+ }
+}
diff --git a/api/packages/opentelemetry-api/tslint.json b/api/packages/opentelemetry-api/tslint.json
new file mode 100644
index 0000000000..0710b135d0
--- /dev/null
+++ b/api/packages/opentelemetry-api/tslint.json
@@ -0,0 +1,4 @@
+{
+ "rulesDirectory": ["node_modules/tslint-microsoft-contrib"],
+ "extends": ["../../tslint.base.js", "./node_modules/tslint-consistent-codestyle"]
+}
diff --git a/api/src/api/metrics.ts b/api/src/api/metrics.ts
new file mode 100644
index 0000000000..80a1bf1c23
--- /dev/null
+++ b/api/src/api/metrics.ts
@@ -0,0 +1,61 @@
+/*!
+ * 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 { Meter } from '../metrics/Meter';
+import { MeterRegistry } from '../metrics/MeterRegistry';
+import { NOOP_METER_REGISTRY } from '../metrics/NoopMeterRegistry';
+
+/**
+ * Singleton object which represents the entry point to the OpenTelemetry Metrics API
+ */
+export class MetricsAPI {
+ private static _instance?: MetricsAPI;
+ private _meterRegistry: MeterRegistry = NOOP_METER_REGISTRY;
+
+ /** Empty private constructor prevents end users from constructing a new instance of the API */
+ private constructor() {}
+
+ /** Get the singleton instance of the Metrics API */
+ public static getInstance(): MetricsAPI {
+ if (!this._instance) {
+ this._instance = new MetricsAPI();
+ }
+
+ return this._instance;
+ }
+
+ /**
+ * Set the current global meter. Returns the initialized global meter registry.
+ */
+ public initGlobalMeterRegistry(registry: MeterRegistry): MeterRegistry {
+ this._meterRegistry = registry;
+ return registry;
+ }
+
+ /**
+ * Returns the global meter registry.
+ */
+ public getMeterRegistry(): MeterRegistry {
+ return this._meterRegistry;
+ }
+
+ /**
+ * Returns a meter from the global meter registry.
+ */
+ public getMeter(name: string, version?: string): Meter {
+ return this.getMeterRegistry().getMeter(name, version);
+ }
+}
diff --git a/api/src/api/trace.ts b/api/src/api/trace.ts
new file mode 100644
index 0000000000..60b1a30c97
--- /dev/null
+++ b/api/src/api/trace.ts
@@ -0,0 +1,61 @@
+/*!
+ * 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 { NOOP_TRACER_REGISTRY } from '../trace/NoopTracerRegistry';
+import { TracerRegistry } from '../trace/tracer_registry';
+import { Tracer } from '../trace/tracer';
+
+/**
+ * Singleton object which represents the entry point to the OpenTelemetry Tracing API
+ */
+export class TraceAPI {
+ private static _instance?: TraceAPI;
+ private _tracerRegistry: TracerRegistry = NOOP_TRACER_REGISTRY;
+
+ /** Empty private constructor prevents end users from constructing a new instance of the API */
+ private constructor() {}
+
+ /** Get the singleton instance of the Trace API */
+ public static getInstance(): TraceAPI {
+ if (!this._instance) {
+ this._instance = new TraceAPI();
+ }
+
+ return this._instance;
+ }
+
+ /**
+ * Set the current global tracer. Returns the initialized global tracer registry
+ */
+ public initGlobalTracerRegistry(registry: TracerRegistry): TracerRegistry {
+ this._tracerRegistry = registry;
+ return registry;
+ }
+
+ /**
+ * Returns the global tracer registry.
+ */
+ public getTracerRegistry(): TracerRegistry {
+ return this._tracerRegistry;
+ }
+
+ /**
+ * Returns a tracer from the global tracer registry.
+ */
+ public getTracer(name: string, version?: string): Tracer {
+ return this.getTracerRegistry().getTracer(name, version);
+ }
+}
diff --git a/api/src/common/Logger.ts b/api/src/common/Logger.ts
new file mode 100644
index 0000000000..abb8885a15
--- /dev/null
+++ b/api/src/common/Logger.ts
@@ -0,0 +1,25 @@
+/*!
+ * Copyright 2019, 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 type LogFunction = (message: string, ...args: unknown[]) => void;
+
+/** Defines a logger interface. */
+export interface Logger {
+ error: LogFunction;
+ warn: LogFunction;
+ info: LogFunction;
+ debug: LogFunction;
+}
diff --git a/api/src/common/Time.ts b/api/src/common/Time.ts
new file mode 100644
index 0000000000..0723d9cc43
--- /dev/null
+++ b/api/src/common/Time.ts
@@ -0,0 +1,25 @@
+/*!
+ * Copyright 2019, 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.
+ */
+
+/** High resolution HrTime: [seconds: number, nanoseconds: number] */
+export type HrTime = [number, number];
+
+/**
+ * Defines TimeInput.
+ *
+ * hrtime, epoch milliseconds, performance.now() or Date
+ */
+export type TimeInput = HrTime | number | Date;
diff --git a/api/src/context/propagation/BinaryFormat.ts b/api/src/context/propagation/BinaryFormat.ts
new file mode 100644
index 0000000000..3ca33f309d
--- /dev/null
+++ b/api/src/context/propagation/BinaryFormat.ts
@@ -0,0 +1,36 @@
+/*!
+ * Copyright 2019, 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 { SpanContext } from '../../trace/span_context';
+
+/**
+ * Formatter to serializing and deserializing a value with into a binary format.
+ */
+export interface BinaryFormat {
+ /**
+ * Serialize the given span context into a Buffer.
+ * @param spanContext The span context to serialize.
+ */
+ toBytes(spanContext: SpanContext): ArrayBuffer;
+
+ /**
+ * Deseralize the given span context from binary encoding. If the input is a
+ * Buffer of incorrect size or unexpected fields, then this function will
+ * return `null`.
+ * @param buffer The span context to deserialize.
+ */
+ fromBytes(buffer: ArrayBuffer): SpanContext | null;
+}
diff --git a/api/src/context/propagation/HttpTextFormat.ts b/api/src/context/propagation/HttpTextFormat.ts
new file mode 100644
index 0000000000..c3cf8c314e
--- /dev/null
+++ b/api/src/context/propagation/HttpTextFormat.ts
@@ -0,0 +1,52 @@
+/*!
+ * Copyright 2019, 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 { SpanContext } from '../../trace/span_context';
+
+/**
+ * Injects and extracts a value as text into carriers that travel in-band
+ * across process boundaries. Encoding is expected to conform to the HTTP
+ * Header Field semantics. Values are often encoded as RPC/HTTP request headers.
+ *
+ * The carrier of propagated data on both the client (injector) and server
+ * (extractor) side is usually an http request. Propagation is usually
+ * implemented via library- specific request interceptors, where the
+ * client-side injects values and the server-side extracts them.
+ */
+export interface HttpTextFormat {
+ /**
+ * Injects the given {@link SpanContext} instance to transmit over the wire.
+ *
+ * OpenTelemetry defines a common set of format values (BinaryFormat and
+ * HTTPTextFormat), and each has an expected `carrier` type.
+ *
+ * @param spanContext the SpanContext to transmit over the wire.
+ * @param format the format of the carrier.
+ * @param carrier the carrier of propagation fields, such as an http request.
+ */
+ inject(spanContext: SpanContext, format: string, carrier: unknown): void;
+
+ /**
+ * Returns a {@link SpanContext} instance extracted from `carrier` in the
+ * given format from upstream.
+ *
+ * @param format the format of the carrier.
+ * @param carrier the carrier of propagation fields, such as an http request.
+ * @returns SpanContext The extracted SpanContext, or null if no such
+ * SpanContext could be found in carrier.
+ */
+ extract(format: string, carrier: unknown): SpanContext | null;
+}
diff --git a/api/src/context/propagation/NoopBinaryFormat.ts b/api/src/context/propagation/NoopBinaryFormat.ts
new file mode 100644
index 0000000000..effec6183f
--- /dev/null
+++ b/api/src/context/propagation/NoopBinaryFormat.ts
@@ -0,0 +1,36 @@
+/*!
+ * Copyright 2019, 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 { SpanContext } from '../../trace/span_context';
+import { BinaryFormat } from './BinaryFormat';
+
+/**
+ * No-op implementations of {@link BinaryFormat}.
+ */
+export class NoopBinaryFormat implements BinaryFormat {
+ private readonly _buff = new ArrayBuffer(0);
+ // By default does nothing
+ toBytes(spanContext: SpanContext): ArrayBuffer {
+ return this._buff;
+ }
+
+ // By default does nothing
+ fromBytes(buf: ArrayBuffer): SpanContext | null {
+ return null;
+ }
+}
+
+export const NOOP_BINARY_FORMAT = new NoopBinaryFormat();
diff --git a/api/src/context/propagation/NoopHttpTextFormat.ts b/api/src/context/propagation/NoopHttpTextFormat.ts
new file mode 100644
index 0000000000..7596dd96b3
--- /dev/null
+++ b/api/src/context/propagation/NoopHttpTextFormat.ts
@@ -0,0 +1,32 @@
+/*!
+ * Copyright 2019, 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 { SpanContext } from '../../trace/span_context';
+import { HttpTextFormat } from './HttpTextFormat';
+
+/**
+ * No-op implementations of {@link HttpTextFormat}.
+ */
+export class NoopHttpTextFormat implements HttpTextFormat {
+ // By default does nothing
+ inject(spanContext: SpanContext, format: string, carrier: unknown): void {}
+ // By default does nothing
+ extract(format: string, carrier: unknown): SpanContext | null {
+ return null;
+ }
+}
+
+export const NOOP_HTTP_TEXT_FORMAT = new NoopHttpTextFormat();
diff --git a/api/src/distributed_context/DistributedContext.ts b/api/src/distributed_context/DistributedContext.ts
new file mode 100644
index 0000000000..b06dcb8059
--- /dev/null
+++ b/api/src/distributed_context/DistributedContext.ts
@@ -0,0 +1,29 @@
+/*!
+ * Copyright 2019, 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 { EntryValue } from './EntryValue';
+
+/**
+ * DistributedContext represents collection of entries. Each key of
+ * DistributedContext is associated with exactly one value. DistributedContext
+ * is serializable, to facilitate propagating it not only inside the process
+ * but also across process boundaries. DistributedContext is used to annotate
+ * telemetry with the name:value pair Entry. Those values can be used to add
+ * dimension to the metric or additional contest properties to logs and traces.
+ */
+export interface DistributedContext {
+ [entryKey: string]: EntryValue;
+}
diff --git a/api/src/distributed_context/EntryValue.ts b/api/src/distributed_context/EntryValue.ts
new file mode 100644
index 0000000000..cb0c58557e
--- /dev/null
+++ b/api/src/distributed_context/EntryValue.ts
@@ -0,0 +1,45 @@
+/*!
+ * Copyright 2019, 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.
+ */
+
+/**
+ * {@link EntryValue} contains properties associated with a {@link
+ * DistributedContext}.
+ */
+export interface EntryValue {
+ /** `String` value of the `EntryValue`. */
+ value: string;
+ /**
+ * ttl is an integer that represents number of hops an entry can
+ * propagate.
+ */
+ ttl?: EntryTtl;
+}
+
+/**
+ * EntryTtl is an integer that represents number of hops an entry can propagate.
+ *
+ * For now, ONLY special values (0 and -1) are supported.
+ */
+export enum EntryTtl {
+ /**
+ * NO_PROPAGATION is considered to have local scope and is used within the
+ * process it created.
+ */
+ NO_PROPAGATION = 0,
+
+ /** UNLIMITED_PROPAGATION can propagate unlimited hops. */
+ UNLIMITED_PROPAGATION = -1,
+}
diff --git a/api/src/index.ts b/api/src/index.ts
new file mode 100644
index 0000000000..d73844a715
--- /dev/null
+++ b/api/src/index.ts
@@ -0,0 +1,59 @@
+/*!
+ * Copyright 2019, 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 * from './common/Logger';
+export * from './common/Time';
+export * from './context/propagation/BinaryFormat';
+export * from './context/propagation/HttpTextFormat';
+export * from './distributed_context/DistributedContext';
+export * from './distributed_context/EntryValue';
+export * from './metrics/BoundInstrument';
+export * from './metrics/Meter';
+export * from './metrics/MeterRegistry';
+export * from './metrics/Metric';
+export * from './trace/attributes';
+export * from './trace/Event';
+export * from './trace/instrumentation/Plugin';
+export * from './trace/link';
+export * from './trace/Sampler';
+export * from './trace/span';
+export * from './trace/SpanOptions';
+export * from './trace/span_context';
+export * from './trace/span_kind';
+export * from './trace/status';
+export * from './trace/TimedEvent';
+export * from './trace/tracer';
+export * from './trace/tracer_registry';
+export * from './trace/trace_flags';
+export * from './trace/trace_state';
+export * from './trace/NoopSpan';
+export * from './trace/NoopTracer';
+export * from './trace/NoopTracerRegistry';
+export * from './metrics/NoopMeterRegistry';
+export * from './metrics/NoopMeter';
+
+import { TraceAPI } from './api/trace';
+/** Entrypoint for trace API */
+export const trace = TraceAPI.getInstance();
+
+import { MetricsAPI } from './api/metrics';
+/** Entrypoint for metrics API */
+export const metrics = MetricsAPI.getInstance();
+
+export default {
+ trace,
+ metrics,
+};
diff --git a/api/src/metrics/BoundInstrument.ts b/api/src/metrics/BoundInstrument.ts
new file mode 100644
index 0000000000..83612d6b4d
--- /dev/null
+++ b/api/src/metrics/BoundInstrument.ts
@@ -0,0 +1,54 @@
+/*!
+ * Copyright 2019, 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 { DistributedContext } from '../distributed_context/DistributedContext';
+import { SpanContext } from '../trace/span_context';
+
+/** An Instrument for Counter Metric. */
+export interface BoundCounter {
+ /**
+ * Adds the given value to the current value. Values cannot be negative.
+ * @param value the value to add.
+ */
+ add(value: number): void;
+}
+
+/** An Instrument for Gauge Metric. */
+export interface BoundGauge {
+ /**
+ * Sets the given value. Values can be negative.
+ * @param value the new value.
+ */
+ set(value: number): void;
+}
+
+/** Measure to report instantaneous measurement of a value. */
+export interface BoundMeasure {
+ /**
+ * Records the given value to this measure.
+ * @param value the measurement to record.
+ * @param distContext the distContext associated with the measurements.
+ * @param spanContext the {@link SpanContext} that identifies the {@link Span}
+ * for which the measurements are associated with.
+ */
+ record(value: number): void;
+ record(value: number, distContext: DistributedContext): void;
+ record(
+ value: number,
+ distContext: DistributedContext,
+ spanContext: SpanContext
+ ): void;
+}
diff --git a/api/src/metrics/Meter.ts b/api/src/metrics/Meter.ts
new file mode 100644
index 0000000000..dec54e8a9f
--- /dev/null
+++ b/api/src/metrics/Meter.ts
@@ -0,0 +1,69 @@
+/*!
+ * Copyright 2019, 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 { Metric, MetricOptions, Labels, LabelSet } from './Metric';
+import { BoundCounter, BoundGauge, BoundMeasure } from './BoundInstrument';
+
+/**
+ * An interface to allow the recording metrics.
+ *
+ * {@link Metric}s are used for recording pre-defined aggregation (Gauge and
+ * Counter), or raw values ({@link Measure}) in which the aggregation and labels
+ * for the exported metric are deferred.
+ */
+export interface Meter {
+ /**
+ * Creates and returns a new {@link Measure}.
+ * @param name the name of the metric.
+ * @param [options] the metric options.
+ */
+ createMeasure(name: string, options?: MetricOptions): Metric;
+
+ /**
+ * Creates a new counter metric. Generally, this kind of metric when the
+ * value is a quantity, the sum is of primary interest, and the event count
+ * and value distribution are not of primary interest.
+ * @param name the name of the metric.
+ * @param [options] the metric options.
+ */
+ createCounter(name: string, options?: MetricOptions): Metric;
+
+ // TODO: Measurements can have a long or double type. However, it looks like
+ // the metric timeseries API (according to spec) accepts values instead of
+ // Measurements, meaning that if you accept a `number`, the type gets lost.
+ // Both java and csharp have gone down the route of having two gauge interfaces,
+ // GaugeDoubleTimeseries and GaugeLongTimeseries, with param for that type. It'd
+ // be cool to only have a single interface, but maybe having two is necessary?
+ // Maybe include the type as a metrics option? Probs a good gh issue, the same goes for Measure types.
+
+ /**
+ * Creates a new gauge metric. Generally, this kind of metric should be used
+ * when the metric cannot be expressed as a sum or because the measurement
+ * interval is arbitrary. Use this kind of metric when the measurement is not
+ * a quantity, and the sum and event count are not of interest.
+ * @param name the name of the metric.
+ * @param [options] the metric options.
+ */
+ createGauge(name: string, options?: MetricOptions): Metric;
+
+ /**
+ * Provide a pre-computed re-useable LabelSet by
+ * converting the unordered labels into a canonicalized
+ * set of labels with an unique identifier, useful for pre-aggregation.
+ * @param labels user provided unordered Labels.
+ */
+ labels(labels: Labels): LabelSet;
+}
diff --git a/api/src/metrics/MeterRegistry.ts b/api/src/metrics/MeterRegistry.ts
new file mode 100644
index 0000000000..75a36272da
--- /dev/null
+++ b/api/src/metrics/MeterRegistry.ts
@@ -0,0 +1,29 @@
+/*!
+ * Copyright 2019, 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 { Meter } from './Meter';
+
+/**
+ * MeterRegistry provides an interface for creating {@link Meter}s
+ */
+export interface MeterRegistry {
+ /**
+ * Returns a Meter, creating one if one with the given name and version is not already created
+ *
+ * @returns Meter A Meter with the given name and version
+ */
+ getMeter(name: string, version?: string): Meter;
+}
diff --git a/api/src/metrics/Metric.ts b/api/src/metrics/Metric.ts
new file mode 100644
index 0000000000..dffdbe4241
--- /dev/null
+++ b/api/src/metrics/Metric.ts
@@ -0,0 +1,146 @@
+/*!
+ * Copyright 2019, 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 { DistributedContext } from '../distributed_context/DistributedContext';
+import { SpanContext } from '../trace/span_context';
+
+/**
+ * Options needed for metric creation
+ */
+export interface MetricOptions {
+ /** The name of the component that reports the Metric. */
+ component?: string;
+
+ /**
+ * The description of the Metric.
+ * @default ''
+ */
+ description?: string;
+
+ /**
+ * The unit of the Metric values.
+ * @default '1'
+ */
+ unit?: string;
+
+ /** The list of label keys for the Metric. */
+ labelKeys?: string[];
+
+ /** The map of constant labels for the Metric. */
+ constantLabels?: Map;
+
+ /**
+ * Indicates the metric is a verbose metric that is disabled by default
+ * @default false
+ */
+ disabled?: boolean;
+
+ /**
+ * Monotonic allows this metric to accept negative values. If `true` only
+ * non-negative values are expected.
+ */
+ monotonic?: boolean;
+
+ /**
+ * Indicates the type of the recorded value.
+ * @default {@link ValueType.DOUBLE}
+ */
+ valueType?: ValueType;
+}
+
+/** The Type of value. It describes how the data is reported. */
+export enum ValueType {
+ INT,
+ DOUBLE,
+}
+
+/**
+ * Metric represents a base class for different types of metric
+ * pre aggregations.
+ */
+export interface Metric {
+ /**
+ * Returns a Instrument associated with specified LabelSet.
+ * It is recommended to keep a reference to the Instrument instead of always
+ * calling this method for every operations.
+ * @param labels the canonicalized LabelSet used to associate with this metric instrument.
+ */
+ bind(labels: LabelSet): T;
+
+ /**
+ * Returns a Instrument for a metric with all labels not set.
+ */
+ getDefaultBound(): T;
+
+ /**
+ * Removes the Instrument from the metric, if it is present.
+ * @param labels the canonicalized LabelSet used to associate with this metric instrument.
+ */
+ unbind(labels: LabelSet): void;
+
+ /**
+ * Clears all timeseries from the Metric.
+ */
+ clear(): void;
+
+ /**
+ * what should the callback signature be?
+ */
+ setCallback(fn: () => void): void;
+}
+
+export interface MetricUtils {
+ /**
+ * Adds the given value to the current value. Values cannot be negative.
+ */
+ add(value: number, labelSet: LabelSet): void;
+
+ /**
+ * Sets the given value. Values can be negative.
+ */
+ set(value: number, labelSet: LabelSet): void;
+
+ /**
+ * Records the given value to this measure.
+ */
+ record(value: number, labelSet: LabelSet): void;
+
+ record(
+ value: number,
+ labelSet: LabelSet,
+ distContext: DistributedContext
+ ): void;
+
+ record(
+ value: number,
+ labelSet: LabelSet,
+ distContext: DistributedContext,
+ spanContext: SpanContext
+ ): void;
+}
+
+/**
+ * key-value pairs passed by the user.
+ */
+export type Labels = Record;
+
+/**
+ * Canonicalized labels with an unique string identifier.
+ */
+export interface LabelSet {
+ identifier: string;
+ labels: Labels;
+}
diff --git a/api/src/metrics/NoopMeter.ts b/api/src/metrics/NoopMeter.ts
new file mode 100644
index 0000000000..c39a664aa5
--- /dev/null
+++ b/api/src/metrics/NoopMeter.ts
@@ -0,0 +1,171 @@
+/*!
+ * Copyright 2019, 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 { Meter } from './Meter';
+import { MetricOptions, Metric, Labels, LabelSet, MetricUtils } from './Metric';
+import { BoundMeasure, BoundCounter, BoundGauge } from './BoundInstrument';
+import { DistributedContext } from '../distributed_context/DistributedContext';
+import { SpanContext } from '../trace/span_context';
+
+/**
+ * NoopMeter is a noop implementation of the {@link Meter} interface. It reuses constant
+ * NoopMetrics for all of its methods.
+ */
+export class NoopMeter implements Meter {
+ constructor() {}
+
+ /**
+ * Returns constant noop measure.
+ * @param name the name of the metric.
+ * @param [options] the metric options.
+ */
+ createMeasure(name: string, options?: MetricOptions): Metric {
+ return NOOP_MEASURE_METRIC;
+ }
+
+ /**
+ * Returns a constant noop counter.
+ * @param name the name of the metric.
+ * @param [options] the metric options.
+ */
+ createCounter(name: string, options?: MetricOptions): Metric {
+ return NOOP_COUNTER_METRIC;
+ }
+
+ /**
+ * Returns a constant gauge metric.
+ * @param name the name of the metric.
+ * @param [options] the metric options.
+ */
+ createGauge(name: string, options?: MetricOptions): Metric {
+ return NOOP_GAUGE_METRIC;
+ }
+
+ labels(labels: Labels): LabelSet {
+ return NOOP_LABEL_SET;
+ }
+}
+
+export class NoopMetric implements Metric {
+ private readonly _instrument: T;
+
+ constructor(instrument: T) {
+ this._instrument = instrument;
+ }
+ /**
+ * Returns a Bound Instrument associated with specified LabelSet.
+ * It is recommended to keep a reference to the Bound Instrument instead of always
+ * calling this method for every operations.
+ * @param labels the canonicalized LabelSet used to associate with this metric instrument.
+ */
+ bind(labels: LabelSet): T {
+ return this._instrument;
+ }
+
+ /**
+ * Returns a Bound Instrument for a metric with all labels not set.
+ */
+ getDefaultBound(): T {
+ return this._instrument;
+ }
+
+ /**
+ * Removes the Binding from the metric, if it is present.
+ * @param labels the canonicalized LabelSet used to associate with this metric instrument.
+ */
+ unbind(labels: LabelSet): void {
+ // @todo: implement this method
+ return;
+ }
+
+ /**
+ * Clears all timeseries from the Metric.
+ */
+ clear(): void {
+ return;
+ }
+
+ setCallback(fn: () => void): void {
+ return;
+ }
+}
+
+export class NoopCounterMetric extends NoopMetric
+ implements Pick {
+ add(value: number, labelSet: LabelSet) {
+ this.bind(labelSet).add(value);
+ }
+}
+
+export class NoopGaugeMetric extends NoopMetric
+ implements Pick {
+ set(value: number, labelSet: LabelSet) {
+ this.bind(labelSet).set(value);
+ }
+}
+
+export class NoopMeasureMetric extends NoopMetric
+ implements Pick {
+ record(
+ value: number,
+ labelSet: LabelSet,
+ distContext?: DistributedContext,
+ spanContext?: SpanContext
+ ) {
+ if (typeof distContext === 'undefined') {
+ this.bind(labelSet).record(value);
+ } else if (typeof spanContext === 'undefined') {
+ this.bind(labelSet).record(value, distContext);
+ } else {
+ this.bind(labelSet).record(value, distContext, spanContext);
+ }
+ }
+}
+
+export class NoopBoundCounter implements BoundCounter {
+ add(value: number): void {
+ return;
+ }
+}
+
+export class NoopBoundGauge implements BoundGauge {
+ set(value: number): void {
+ return;
+ }
+}
+
+export class NoopBoundMeasure implements BoundMeasure {
+ record(
+ value: number,
+ distContext?: DistributedContext,
+ spanContext?: SpanContext
+ ): void {
+ return;
+ }
+}
+
+export const NOOP_METER = new NoopMeter();
+
+export const NOOP_BOUND_GAUGE = new NoopBoundGauge();
+export const NOOP_GAUGE_METRIC = new NoopGaugeMetric(NOOP_BOUND_GAUGE);
+
+export const NOOP_BOUND_COUNTER = new NoopBoundCounter();
+export const NOOP_COUNTER_METRIC = new NoopCounterMetric(NOOP_BOUND_COUNTER);
+
+export const NOOP_BOUND_MEASURE = new NoopBoundMeasure();
+export const NOOP_MEASURE_METRIC = new NoopMeasureMetric(NOOP_BOUND_MEASURE);
+
+export const NOOP_LABEL_SET = {} as LabelSet;
diff --git a/api/src/metrics/NoopMeterRegistry.ts b/api/src/metrics/NoopMeterRegistry.ts
new file mode 100644
index 0000000000..81911dd733
--- /dev/null
+++ b/api/src/metrics/NoopMeterRegistry.ts
@@ -0,0 +1,31 @@
+/*!
+ * Copyright 2019, 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 { Meter } from './Meter';
+import { MeterRegistry } from './MeterRegistry';
+import { NOOP_METER } from './NoopMeter';
+
+/**
+ * An implementation of the {@link MeterRegistry} which returns an impotent Meter
+ * for all calls to `getMeter`
+ */
+export class NoopMeterRegistry implements MeterRegistry {
+ getMeter(_name?: string, _version?: string): Meter {
+ return NOOP_METER;
+ }
+}
+
+export const NOOP_METER_REGISTRY = new NoopMeterRegistry();
diff --git a/api/src/trace/Event.ts b/api/src/trace/Event.ts
new file mode 100644
index 0000000000..c3238c5393
--- /dev/null
+++ b/api/src/trace/Event.ts
@@ -0,0 +1,25 @@
+/*!
+ * Copyright 2019, 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 { Attributes } from './attributes';
+
+/** A text annotation with a set of attributes. */
+export interface Event {
+ /** The name of the event. */
+ name: string;
+ /** The attributes of the event. */
+ attributes?: Attributes;
+}
diff --git a/api/src/trace/NoopSpan.ts b/api/src/trace/NoopSpan.ts
new file mode 100644
index 0000000000..cfa3c9c4c0
--- /dev/null
+++ b/api/src/trace/NoopSpan.ts
@@ -0,0 +1,86 @@
+/*!
+ * Copyright 2019, 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 { TimeInput } from '../common/Time';
+import { Attributes } from './attributes';
+import { Span } from './span';
+import { SpanContext } from './span_context';
+import { Status } from './status';
+import { TraceFlags } from './trace_flags';
+
+export const INVALID_TRACE_ID = '0';
+export const INVALID_SPAN_ID = '0';
+const INVALID_SPAN_CONTEXT: SpanContext = {
+ traceId: INVALID_TRACE_ID,
+ spanId: INVALID_SPAN_ID,
+ traceFlags: TraceFlags.UNSAMPLED,
+};
+
+/**
+ * The NoopSpan is the default {@link Span} that is used when no Span
+ * implementation is available. All operations are no-op including context
+ * propagation.
+ */
+export class NoopSpan implements Span {
+ constructor(
+ private readonly _spanContext: SpanContext = INVALID_SPAN_CONTEXT
+ ) {}
+
+ // Returns a SpanContext.
+ context(): SpanContext {
+ return this._spanContext;
+ }
+
+ // By default does nothing
+ setAttribute(key: string, value: unknown): this {
+ return this;
+ }
+
+ // By default does nothing
+ setAttributes(attributes: Attributes): this {
+ return this;
+ }
+
+ // By default does nothing
+ addEvent(name: string, attributes?: Attributes): this {
+ return this;
+ }
+
+ // By default does nothing
+ addLink(spanContext: SpanContext, attributes?: Attributes): this {
+ return this;
+ }
+
+ // By default does nothing
+ setStatus(status: Status): this {
+ return this;
+ }
+
+ // By default does nothing
+ updateName(name: string): this {
+ return this;
+ }
+
+ // By default does nothing
+ end(endTime?: TimeInput): void {}
+
+ // isRecording always returns false for noopSpan.
+ isRecording(): boolean {
+ return false;
+ }
+}
+
+export const NOOP_SPAN = new NoopSpan();
diff --git a/api/src/trace/NoopTracer.ts b/api/src/trace/NoopTracer.ts
new file mode 100644
index 0000000000..27e47a9093
--- /dev/null
+++ b/api/src/trace/NoopTracer.ts
@@ -0,0 +1,57 @@
+/*!
+ * 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 { BinaryFormat, HttpTextFormat, Span, SpanOptions, Tracer } from '..';
+import { NOOP_BINARY_FORMAT } from '../context/propagation/NoopBinaryFormat';
+import { NOOP_HTTP_TEXT_FORMAT } from '../context/propagation/NoopHttpTextFormat';
+import { NOOP_SPAN } from './NoopSpan';
+
+/**
+ * No-op implementations of {@link Tracer}.
+ */
+export class NoopTracer implements Tracer {
+ getCurrentSpan(): Span {
+ return NOOP_SPAN;
+ }
+
+ // startSpan starts a noop span.
+ startSpan(name: string, options?: SpanOptions): Span {
+ return NOOP_SPAN;
+ }
+
+ withSpan ReturnType>(
+ span: Span,
+ fn: T
+ ): ReturnType {
+ return fn();
+ }
+
+ bind(target: T, span?: Span): T {
+ return target;
+ }
+
+ // By default does nothing
+ getBinaryFormat(): BinaryFormat {
+ return NOOP_BINARY_FORMAT;
+ }
+
+ // By default does nothing
+ getHttpTextFormat(): HttpTextFormat {
+ return NOOP_HTTP_TEXT_FORMAT;
+ }
+}
+
+export const NOOP_TRACER = new NoopTracer();
diff --git a/api/src/trace/NoopTracerRegistry.ts b/api/src/trace/NoopTracerRegistry.ts
new file mode 100644
index 0000000000..c28e99af89
--- /dev/null
+++ b/api/src/trace/NoopTracerRegistry.ts
@@ -0,0 +1,31 @@
+/*!
+ * Copyright 2019, 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 { NOOP_TRACER } from './NoopTracer';
+import { Tracer } from './tracer';
+import { TracerRegistry } from './tracer_registry';
+
+/**
+ * An implementation of the {@link TracerRegistry} which returns an impotent Tracer
+ * for all calls to `getTracer`
+ */
+export class NoopTracerRegistry implements TracerRegistry {
+ getTracer(_name?: string, _version?: string): Tracer {
+ return NOOP_TRACER;
+ }
+}
+
+export const NOOP_TRACER_REGISTRY = new NoopTracerRegistry();
diff --git a/api/src/trace/Sampler.ts b/api/src/trace/Sampler.ts
new file mode 100644
index 0000000000..798b5450f7
--- /dev/null
+++ b/api/src/trace/Sampler.ts
@@ -0,0 +1,37 @@
+/*!
+ * Copyright 2019, 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 { SpanContext } from './span_context';
+
+/**
+ * This interface represent a sampler. Sampling is a mechanism to control the
+ * noise and overhead introduced by OpenTelemetry by reducing the number of
+ * samples of traces collected and sent to the backend.
+ */
+export interface Sampler {
+ /**
+ * Checks whether span needs to be created and tracked.
+ *
+ * TODO: Consider to add required arguments https://github.com/open-telemetry/opentelemetry-specification/blob/master/specification/sampling-api.md#shouldsample
+ * @param [parentContext] Parent span context. Typically taken from the wire.
+ * Can be null.
+ * @returns whether span should be sampled or not.
+ */
+ shouldSample(parentContext?: SpanContext): boolean;
+
+ /** Returns the sampler name or short description with the configuration. */
+ toString(): string;
+}
diff --git a/api/src/trace/SpanOptions.ts b/api/src/trace/SpanOptions.ts
new file mode 100644
index 0000000000..a546876a5f
--- /dev/null
+++ b/api/src/trace/SpanOptions.ts
@@ -0,0 +1,53 @@
+/*!
+ * Copyright 2019, 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 { Span } from './span';
+import { Attributes } from './attributes';
+import { SpanKind } from './span_kind';
+import { SpanContext } from './span_context';
+import { Link } from './link';
+
+/**
+ * Options needed for span creation
+ */
+export interface SpanOptions {
+ /**
+ * The SpanKind of a span
+ * @default {@link SpanKind.INTERNAL}
+ */
+ kind?: SpanKind;
+
+ /** A spans attributes */
+ attributes?: Attributes;
+
+ /**
+ * Indicates that if this Span is active and recording information like
+ * events with the `AddEvent` operation and attributes using `setAttributes`.
+ */
+ isRecording?: boolean;
+
+ /** A spans links */
+ links?: Link[];
+
+ /**
+ * A parent `SpanContext` (or `Span`, for convenience) that the newly-started
+ * span will be the child of.
+ */
+ parent?: Span | SpanContext | null;
+
+ /** A manually specified start time for the created `Span` object. */
+ startTime?: number;
+}
diff --git a/api/src/trace/TimedEvent.ts b/api/src/trace/TimedEvent.ts
new file mode 100644
index 0000000000..3218bfa604
--- /dev/null
+++ b/api/src/trace/TimedEvent.ts
@@ -0,0 +1,26 @@
+/*!
+ * Copyright 2019, 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 { Event } from './Event';
+import { HrTime } from '../common/Time';
+
+/**
+ * Represents a timed event.
+ * A timed event is an event with a timestamp.
+ */
+export interface TimedEvent extends Event {
+ time: HrTime;
+}
diff --git a/api/src/trace/attributes.ts b/api/src/trace/attributes.ts
new file mode 100644
index 0000000000..188b1e574a
--- /dev/null
+++ b/api/src/trace/attributes.ts
@@ -0,0 +1,20 @@
+/*!
+ * Copyright 2019, 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.
+ */
+
+/** Defines a attributes interface. */
+export interface Attributes {
+ [attributeKey: string]: unknown;
+}
diff --git a/api/src/trace/instrumentation/Plugin.ts b/api/src/trace/instrumentation/Plugin.ts
new file mode 100644
index 0000000000..3462a5df09
--- /dev/null
+++ b/api/src/trace/instrumentation/Plugin.ts
@@ -0,0 +1,99 @@
+/*!
+ * Copyright 2019, 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 { Logger } from '../../common/Logger';
+import { TracerRegistry } from '../tracer_registry';
+
+/** Interface Plugin to apply patch. */
+// tslint:disable-next-line:no-any
+export interface Plugin {
+ /**
+ * Contains all supported versions.
+ * All versions must be compatible with [semver](https://semver.org/spec/v2.0.0.html) format.
+ * If the version is not supported, we won't apply instrumentation patch (see `enable` method).
+ * If omitted, all versions of the module will be patched.
+ */
+ supportedVersions?: string[];
+
+ /**
+ * Method that enables the instrumentation patch.
+ * @param moduleExports The value of the `module.exports` property that would
+ * normally be exposed by the required module. ex: `http`, `https` etc.
+ * @param TracerRegistry a tracer registry.
+ * @param logger a logger instance.
+ * @param [config] an object to configure the plugin.
+ */
+ enable(
+ moduleExports: T,
+ TracerRegistry: TracerRegistry,
+ logger: Logger,
+ config?: PluginConfig
+ ): T;
+
+ /** Method to disable the instrumentation */
+ disable(): void;
+}
+
+export interface PluginConfig {
+ /**
+ * Whether to enable the plugin.
+ * @default true
+ */
+ enabled?: boolean;
+
+ /**
+ * Path of the trace plugin to load.
+ * @default '@opentelemetry/plugin-http' in case of http.
+ */
+ path?: string;
+
+ /**
+ * Request methods that match any string in ignoreMethods will not be traced.
+ */
+ ignoreMethods?: string[];
+
+ /**
+ * URLs that partially match any regex in ignoreUrls will not be traced.
+ * In addition, URLs that are _exact matches_ of strings in ignoreUrls will
+ * also not be traced.
+ */
+ ignoreUrls?: Array;
+
+ /**
+ * List of internal files that need patch and are not exported by
+ * default.
+ */
+ internalFilesExports?: PluginInternalFiles;
+
+ /**
+ * If true, additional information about query parameters and
+ * results will be attached (as `attributes`) to spans representing
+ * database operations.
+ */
+ enhancedDatabaseReporting?: boolean;
+}
+
+export interface PluginInternalFilesVersion {
+ [pluginName: string]: string;
+}
+
+/**
+ * Each key should be the name of the module to trace, and its value
+ * a mapping of a property name to a internal plugin file name.
+ */
+export interface PluginInternalFiles {
+ [versions: string]: PluginInternalFilesVersion;
+}
diff --git a/api/src/trace/link.ts b/api/src/trace/link.ts
new file mode 100644
index 0000000000..5baf8c30f9
--- /dev/null
+++ b/api/src/trace/link.ts
@@ -0,0 +1,30 @@
+/*!
+ * Copyright 2019, 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 { Attributes } from './attributes';
+import { SpanContext } from './span_context';
+
+/**
+ * A pointer from the current {@link Span} to another span in the same trace or
+ * in a different trace. Used (for example) in batching operations, where a
+ * single batch handler processes multiple requests from different traces.
+ */
+export interface Link {
+ /** The {@link SpanContext} of a linked span. */
+ spanContext: SpanContext;
+ /** A set of {@link Attributes} on the link. */
+ attributes?: Attributes;
+}
diff --git a/api/src/trace/span.ts b/api/src/trace/span.ts
new file mode 100644
index 0000000000..2a725afdc2
--- /dev/null
+++ b/api/src/trace/span.ts
@@ -0,0 +1,103 @@
+/*!
+ * Copyright 2019, 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 { Attributes } from './attributes';
+import { SpanContext } from './span_context';
+import { Status } from './status';
+import { TimeInput } from '../common/Time';
+
+/**
+ * An interface that represents a span. A span represents a single operation
+ * within a trace. Examples of span might include remote procedure calls or a
+ * in-process function calls to sub-components. A Trace has a single, top-level
+ * "root" Span that in turn may have zero or more child Spans, which in turn
+ * may have children.
+ */
+export interface Span {
+ /**
+ * Returns the {@link SpanContext} object associated with this Span.
+ *
+ * @returns the SpanContext object associated with this Span.
+ */
+ context(): SpanContext;
+
+ /**
+ * Sets an attribute to the span.
+ *
+ * @param key the key for this attribute.
+ * @param value the value for this attribute.
+ */
+ setAttribute(key: string, value: unknown): this;
+
+ /**
+ * Sets attributes to the span.
+ *
+ * @param attributes the attributes that will be added.
+ */
+ setAttributes(attributes: Attributes): this;
+
+ /**
+ * Adds an event to the Span.
+ *
+ * @param name the name of the event.
+ * @param [attributesOrStartTime] the attributes that will be added; these are
+ * associated with this event. Can be also a start time
+ * if type is {@type TimeInput} and 3rd param is undefined
+ * @param [startTime] start time of the event.
+ */
+ addEvent(
+ name: string,
+ attributesOrStartTime?: Attributes | TimeInput,
+ startTime?: TimeInput
+ ): this;
+
+ /**
+ * Sets a status to the span. If used, this will override the default Span
+ * status. Default is {@link CanonicalCode.OK}.
+ *
+ * @param status the Status to set.
+ */
+ setStatus(status: Status): this;
+
+ /**
+ * Updates the Span name.
+ *
+ * @param name the Span name.
+ */
+ updateName(name: string): this;
+
+ /**
+ * Marks the end of Span execution.
+ *
+ * Call to End of a Span MUST not have any effects on child spans. Those may
+ * still be running and can be ended later.
+ *
+ * Do not return `this`. The Span generally should not be used after it
+ * is ended so chaining is not desired in this context.
+ *
+ * @param [endTime] the time to set as Span's end time. If not provided,
+ * use the current time as the span's end time.
+ */
+ end(endTime?: TimeInput): void;
+
+ /**
+ * Returns the flag whether this span will be recorded.
+ *
+ * @returns true if this Span is active and recording information like events
+ * with the AddEvent operation and attributes using setAttributes.
+ */
+ isRecording(): boolean;
+}
diff --git a/api/src/trace/span_context.ts b/api/src/trace/span_context.ts
new file mode 100644
index 0000000000..b901cf52eb
--- /dev/null
+++ b/api/src/trace/span_context.ts
@@ -0,0 +1,70 @@
+/*!
+ * Copyright 2019, 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 { TraceFlags } from './trace_flags';
+import { TraceState } from './trace_state';
+
+/**
+ * A SpanContext represents the portion of a {@link Span} which must be
+ * serialized and propagated along side of a {@link DistributedContext}.
+ */
+export interface SpanContext {
+ /**
+ * The ID of the trace that this span belongs to. It is worldwide unique
+ * with practically sufficient probability by being made as 16 randomly
+ * generated bytes, encoded as a 32 lowercase hex characters corresponding to
+ * 128 bits.
+ */
+ traceId: string;
+ /**
+ * The ID of the Span. It is globally unique with practically sufficient
+ * probability by being made as 8 randomly generated bytes, encoded as a 16
+ * lowercase hex characters corresponding to 64 bits.
+ */
+ spanId: string;
+ /**
+ * Only true if the SpanContext was propagated from a remote parent.
+ */
+ isRemote?: boolean;
+ /**
+ * Trace flags to propagate.
+ *
+ * It is represented as 1 byte (bitmap). Bit to represent whether trace is
+ * sampled or not. When set, the least significant bit documents that the
+ * caller may have recorded trace data. A caller who does not record trace
+ * data out-of-band leaves this flag unset.
+ *
+ * SAMPLED = 0x1 and UNSAMPLED = 0x0;
+ */
+ traceFlags?: TraceFlags;
+ /**
+ * Tracing-system-specific info to propagate.
+ *
+ * The tracestate field value is a `list` as defined below. The `list` is a
+ * series of `list-members` separated by commas `,`, and a list-member is a
+ * key/value pair separated by an equals sign `=`. Spaces and horizontal tabs
+ * surrounding `list-members` are ignored. There can be a maximum of 32
+ * `list-members` in a `list`.
+ * More Info: https://www.w3.org/TR/trace-context/#tracestate-field
+ *
+ * Examples:
+ * Single tracing system (generic format):
+ * tracestate: rojo=00f067aa0ba902b7
+ * Multiple tracing systems (with different formatting):
+ * tracestate: rojo=00f067aa0ba902b7,congo=t61rcWkgMzE
+ */
+ traceState?: TraceState;
+}
diff --git a/api/src/trace/span_kind.ts b/api/src/trace/span_kind.ts
new file mode 100644
index 0000000000..a6ca9b522c
--- /dev/null
+++ b/api/src/trace/span_kind.ts
@@ -0,0 +1,50 @@
+/*!
+ * Copyright 2019, 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.
+ */
+
+/**
+ * Type of span. Can be used to specify additional relationships between spans
+ * in addition to a parent/child relationship.
+ */
+export enum SpanKind {
+ /** Default value. Indicates that the span is used internally. */
+ INTERNAL = 0,
+
+ /**
+ * Indicates that the span covers server-side handling of an RPC or other
+ * remote request.
+ */
+ SERVER = 1,
+
+ /**
+ * Indicates that the span covers the client-side wrapper around an RPC or
+ * other remote request.
+ */
+ CLIENT = 2,
+
+ /**
+ * Indicates that the span describes producer sending a message to a
+ * broker. Unlike client and server, there is no direct critical path latency
+ * relationship between producer and consumer spans.
+ */
+ PRODUCER = 3,
+
+ /**
+ * Indicates that the span describes consumer receiving a message from a
+ * broker. Unlike client and server, there is no direct critical path latency
+ * relationship between producer and consumer spans.
+ */
+ CONSUMER = 4,
+}
diff --git a/api/src/trace/status.ts b/api/src/trace/status.ts
new file mode 100644
index 0000000000..e9fa7201d8
--- /dev/null
+++ b/api/src/trace/status.ts
@@ -0,0 +1,163 @@
+/*!
+ * Copyright 2019, 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 status of a Span by providing a standard CanonicalCode in conjunction
+ * with an optional descriptive message.
+ */
+export interface Status {
+ /** The canonical code of this message. */
+ code: CanonicalCode;
+ /** A developer-facing error message. */
+ message?: string;
+}
+
+/**
+ * An enumeration of canonical status codes.
+ */
+export enum CanonicalCode {
+ /**
+ * Not an error; returned on success
+ */
+ OK = 0,
+ /**
+ * The operation was cancelled (typically by the caller).
+ */
+ CANCELLED = 1,
+ /**
+ * Unknown error. An example of where this error may be returned is
+ * if a status value received from another address space belongs to
+ * an error-space that is not known in this address space. Also
+ * errors raised by APIs that do not return enough error information
+ * may be converted to this error.
+ */
+ UNKNOWN = 2,
+ /**
+ * Client specified an invalid argument. Note that this differs
+ * from FAILED_PRECONDITION. INVALID_ARGUMENT indicates arguments
+ * that are problematic regardless of the state of the system
+ * (e.g., a malformed file name).
+ */
+ INVALID_ARGUMENT = 3,
+ /**
+ * Deadline expired before operation could complete. For operations
+ * that change the state of the system, this error may be returned
+ * even if the operation has completed successfully. For example, a
+ * successful response from a server could have been delayed long
+ * enough for the deadline to expire.
+ */
+ DEADLINE_EXCEEDED = 4,
+ /**
+ * Some requested entity (e.g., file or directory) was not found.
+ */
+ NOT_FOUND = 5,
+ /**
+ * Some entity that we attempted to create (e.g., file or directory)
+ * already exists.
+ */
+ ALREADY_EXISTS = 6,
+ /**
+ * The caller does not have permission to execute the specified
+ * operation. PERMISSION_DENIED must not be used for rejections
+ * caused by exhausting some resource (use RESOURCE_EXHAUSTED
+ * instead for those errors). PERMISSION_DENIED must not be
+ * used if the caller can not be identified (use UNAUTHENTICATED
+ * instead for those errors).
+ */
+ PERMISSION_DENIED = 7,
+ /**
+ * Some resource has been exhausted, perhaps a per-user quota, or
+ * perhaps the entire file system is out of space.
+ */
+ RESOURCE_EXHAUSTED = 8,
+ /**
+ * Operation was rejected because the system is not in a state
+ * required for the operation's execution. For example, directory
+ * to be deleted may be non-empty, an rmdir operation is applied to
+ * a non-directory, etc.
+ *
+ * A litmus test that may help a service implementor in deciding
+ * between FAILED_PRECONDITION, ABORTED, and UNAVAILABLE:
+ *
+ * - Use UNAVAILABLE if the client can retry just the failing call.
+ * - Use ABORTED if the client should retry at a higher-level
+ * (e.g., restarting a read-modify-write sequence).
+ * - Use FAILED_PRECONDITION if the client should not retry until
+ * the system state has been explicitly fixed. E.g., if an "rmdir"
+ * fails because the directory is non-empty, FAILED_PRECONDITION
+ * should be returned since the client should not retry unless
+ * they have first fixed up the directory by deleting files from it.
+ * - Use FAILED_PRECONDITION if the client performs conditional
+ * REST Get/Update/Delete on a resource and the resource on the
+ * server does not match the condition. E.g., conflicting
+ * read-modify-write on the same resource.
+ */
+ FAILED_PRECONDITION = 9,
+ /**
+ * The operation was aborted, typically due to a concurrency issue
+ * like sequencer check failures, transaction aborts, etc.
+ *
+ * See litmus test above for deciding between FAILED_PRECONDITION,
+ * ABORTED, and UNAVAILABLE.
+ */
+ ABORTED = 10,
+ /**
+ * Operation was attempted past the valid range. E.g., seeking or
+ * reading past end of file.
+ *
+ * Unlike INVALID_ARGUMENT, this error indicates a problem that may
+ * be fixed if the system state changes. For example, a 32-bit file
+ * system will generate INVALID_ARGUMENT if asked to read at an
+ * offset that is not in the range [0,2^32-1], but it will generate
+ * OUT_OF_RANGE if asked to read from an offset past the current
+ * file size.
+ *
+ * There is a fair bit of overlap between FAILED_PRECONDITION and
+ * OUT_OF_RANGE. We recommend using OUT_OF_RANGE (the more specific
+ * error) when it applies so that callers who are iterating through
+ * a space can easily look for an OUT_OF_RANGE error to detect when
+ * they are done.
+ */
+ OUT_OF_RANGE = 11,
+ /**
+ * Operation is not implemented or not supported/enabled in this service.
+ */
+ UNIMPLEMENTED = 12,
+ /**
+ * Internal errors. Means some invariants expected by underlying
+ * system has been broken. If you see one of these errors,
+ * something is very broken.
+ */
+ INTERNAL = 13,
+ /**
+ * The service is currently unavailable. This is a most likely a
+ * transient condition and may be corrected by retrying with
+ * a backoff.
+ *
+ * See litmus test above for deciding between FAILED_PRECONDITION,
+ * ABORTED, and UNAVAILABLE.
+ */
+ UNAVAILABLE = 14,
+ /**
+ * Unrecoverable data loss or corruption.
+ */
+ DATA_LOSS = 15,
+ /**
+ * The request does not have valid authentication credentials for the
+ * operation.
+ */
+ UNAUTHENTICATED = 16,
+}
diff --git a/api/src/trace/trace_flags.ts b/api/src/trace/trace_flags.ts
new file mode 100644
index 0000000000..419af60579
--- /dev/null
+++ b/api/src/trace/trace_flags.ts
@@ -0,0 +1,27 @@
+/*!
+ * Copyright 2019, 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.
+ */
+
+/**
+ * An enumeration that represents global trace flags. These flags are
+ * propagated to all child {@link Span}. These determine features such as
+ * whether a Span should be traced. It is implemented as a bitmask.
+ */
+export enum TraceFlags {
+ /** Bit to represent whether trace is unsampled in trace flags. */
+ UNSAMPLED = 0x0,
+ /** Bit to represent whether trace is sampled in trace flags. */
+ SAMPLED = 0x1,
+}
diff --git a/api/src/trace/trace_state.ts b/api/src/trace/trace_state.ts
new file mode 100644
index 0000000000..b137eba60b
--- /dev/null
+++ b/api/src/trace/trace_state.ts
@@ -0,0 +1,63 @@
+/*!
+ * Copyright 2019, 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.
+ */
+
+/**
+ * Tracestate carries system-specific configuration data, represented as a list
+ * of key-value pairs. TraceState allows multiple tracing systems to
+ * participate in the same trace.
+ */
+export interface TraceState {
+ /**
+ * Adds or updates the TraceState that has the given `key` if it is
+ * present. The new State will always be added in the front of the
+ * list of states.
+ *
+ * @param key key of the TraceState entry.
+ * @param value value of the TraceState entry.
+ */
+ set(key: string, value: string): void;
+
+ /**
+ * Removes the TraceState Entry that has the given `key` if it is present.
+ *
+ * @param key the key for the TraceState Entry to be removed.
+ */
+ unset(key: string): void;
+
+ /**
+ * Returns the value to which the specified key is mapped, or `undefined` if
+ * this map contains no mapping for the key.
+ *
+ * @param key with which the specified value is to be associated.
+ * @returns the value to which the specified key is mapped, or `undefined` if
+ * this map contains no mapping for the key.
+ */
+ get(key: string): string | undefined;
+
+ // TODO: Consider to add support for merging an object as well by also
+ // accepting a single internalTraceState argument similar to the constructor.
+
+ /**
+ * Serializes the TraceState to a `list` as defined below. The `list` is a
+ * series of `list-members` separated by commas `,`, and a list-member is a
+ * key/value pair separated by an equals sign `=`. Spaces and horizontal tabs
+ * surrounding `list-members` are ignored. There can be a maximum of 32
+ * `list-members` in a `list`.
+ *
+ * @returns the serialized string.
+ */
+ serialize(): string;
+}
diff --git a/api/src/trace/tracer.ts b/api/src/trace/tracer.ts
new file mode 100644
index 0000000000..6d17cbc5a1
--- /dev/null
+++ b/api/src/trace/tracer.ts
@@ -0,0 +1,92 @@
+/*!
+ * Copyright 2019, 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 { HttpTextFormat } from '../context/propagation/HttpTextFormat';
+import { BinaryFormat } from '../context/propagation/BinaryFormat';
+import { Span } from './span';
+import { SpanOptions } from './SpanOptions';
+
+/**
+ * Tracer provides an interface for creating {@link Span}s and propagating
+ * context in-process.
+ *
+ * Users may choose to use manual or automatic Context propagation. Because of
+ * that this class offers APIs to facilitate both usages.
+ */
+export interface Tracer {
+ /**
+ * Returns the current Span from the current context if available.
+ *
+ * If there is no Span associated with the current context, null is returned.
+ *
+ * @returns Span The currently active Span
+ */
+ getCurrentSpan(): Span | undefined;
+
+ /**
+ * Starts a new {@link Span}.
+ * @param name The name of the span
+ * @param [options] SpanOptions used for span creation
+ * @returns Span The newly created span
+ */
+ startSpan(name: string, options?: SpanOptions): Span;
+
+ /**
+ * Executes the function given by fn within the context provided by Span
+ *
+ * @param span The span that provides the context
+ * @param fn The function to be executed inside the provided context
+ * @example
+ * tracer.withSpan(span, function() { ... });
+ */
+ withSpan ReturnType>(
+ span: Span,
+ fn: T
+ ): ReturnType;
+
+ /**
+ * Bind a span as the target's scope or propagate the current one.
+ *
+ * @param target Any object to which a scope need to be set
+ * @param [span] Optionally specify the span which you want to assign
+ */
+ bind(target: T, span?: Span): T;
+
+ /**
+ * Returns the {@link BinaryFormat} interface which can serialize/deserialize
+ * Spans.
+ *
+ * If no tracer implementation is provided, this defaults to the W3C Trace
+ * Context binary format {@link BinaryFormat}. For more details see
+ * W3C Trace Context
+ * binary protocol.
+ *
+ * @returns the {@link BinaryFormat} for this implementation.
+ */
+ getBinaryFormat(): BinaryFormat;
+
+ /**
+ * Returns the {@link HttpTextFormat} interface which can inject/extract
+ * Spans.
+ *
+ * If no tracer implementation is provided, this defaults to the W3C Trace
+ * Context HTTP text format {@link HttpTextFormat}. For more details see
+ * W3C Trace Context.
+ *
+ * @returns the {@link HttpTextFormat} for this implementation.
+ */
+ getHttpTextFormat(): HttpTextFormat;
+}
diff --git a/api/src/trace/tracer_registry.ts b/api/src/trace/tracer_registry.ts
new file mode 100644
index 0000000000..ce2c36cdb1
--- /dev/null
+++ b/api/src/trace/tracer_registry.ts
@@ -0,0 +1,31 @@
+/*!
+ * Copyright 2019, 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 { Tracer } from './tracer';
+
+/**
+ * TracerRegistry provides an interface for creating {@link Tracer}s
+ */
+export interface TracerRegistry {
+ /**
+ * Returns a Tracer, creating one if one with the given name and version is not already created
+ *
+ * If there is no Span associated with the current context, null is returned.
+ *
+ * @returns Tracer A Tracer with the given name and version
+ */
+ getTracer(name: string, version?: string): Tracer;
+}
diff --git a/api/src/version.ts b/api/src/version.ts
new file mode 100644
index 0000000000..d2d10b02a6
--- /dev/null
+++ b/api/src/version.ts
@@ -0,0 +1,18 @@
+/*!
+ * Copyright 2019, 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.3.3';
diff --git a/api/test/api/api.test.ts b/api/test/api/api.test.ts
new file mode 100644
index 0000000000..d77b252cf7
--- /dev/null
+++ b/api/test/api/api.test.ts
@@ -0,0 +1,83 @@
+/*!
+ * Copyright 2019, 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 assert from 'assert';
+import api, { TraceFlags, NoopSpan, NoopTracerRegistry, NoopTracer, SpanOptions, Span } from '../../src';
+
+describe('API', () => {
+ const functions = [
+ 'getCurrentSpan',
+ 'startSpan',
+ 'withSpan',
+ 'getBinaryFormat',
+ 'getHttpTextFormat',
+ ];
+
+ it('should expose a tracer registry via getTracerRegistry', () => {
+ const tracer = api.trace.getTracerRegistry();
+ assert.ok(tracer);
+ assert.strictEqual(typeof tracer, 'object');
+ });
+
+ describe('GlobalTracerRegistry', () => {
+ const spanContext = {
+ traceId: 'd4cda95b652f4a1592b449d5929fda1b',
+ spanId: '6e0c63257de34c92',
+ traceFlags: TraceFlags.UNSAMPLED,
+ };
+ const dummySpan = new NoopSpan(spanContext);
+
+ afterEach(() => {
+ api.trace.initGlobalTracerRegistry(new NoopTracerRegistry());
+ });
+
+ it('should not crash', () => {
+ functions.forEach(fn => {
+ const tracer = api.trace.getTracerRegistry();
+ try {
+ ((tracer as unknown) as { [fn: string]: Function })[fn](); // Try to run the function
+ assert.ok(true, fn);
+ } catch (err) {
+ if (err.message !== 'Method not implemented.') {
+ assert.ok(true, fn);
+ }
+ }
+ });
+ });
+
+ it('should use the global tracer registry', () => {
+ api.trace.initGlobalTracerRegistry(new TestTracerRegistry());
+ const tracer = api.trace.getTracerRegistry().getTracer('name');
+ const span = tracer.startSpan('test');
+ assert.deepStrictEqual(span, dummySpan);
+ });
+
+ class TestTracer extends NoopTracer {
+ startSpan(
+ name: string,
+ options?: SpanOptions | undefined
+ ): Span {
+ return dummySpan;
+ }
+ }
+
+ class TestTracerRegistry extends NoopTracerRegistry {
+ getTracer(_name: string, version?: string) {
+ return new TestTracer();
+ }
+ }
+ });
+});
diff --git a/api/test/index-webpack.ts b/api/test/index-webpack.ts
new file mode 100644
index 0000000000..7731f09091
--- /dev/null
+++ b/api/test/index-webpack.ts
@@ -0,0 +1,23 @@
+/*!
+ * Copyright 2019, 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 is the webpack entry point for the browser Karma tests. It requires
+// all modules ending in "test" from the current folder and all its subfolders.
+const testsContext = require.context('.', true, /test$/);
+testsContext.keys().forEach(testsContext);
+
+const srcContext = require.context('.', true, /src$/);
+srcContext.keys().forEach(srcContext);
diff --git a/api/test/noop-implementations/noop-meter.test.ts b/api/test/noop-implementations/noop-meter.test.ts
new file mode 100644
index 0000000000..a8a0a189c5
--- /dev/null
+++ b/api/test/noop-implementations/noop-meter.test.ts
@@ -0,0 +1,88 @@
+/*!
+ * Copyright 2019, 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 assert from 'assert';
+import {
+ Labels,
+ NoopMeterRegistry,
+ NOOP_BOUND_COUNTER,
+ NOOP_BOUND_GAUGE,
+ NOOP_BOUND_MEASURE,
+ NOOP_COUNTER_METRIC,
+ NOOP_GAUGE_METRIC,
+ NOOP_MEASURE_METRIC
+} from '../../src';
+
+
+describe('NoopMeter', () => {
+ it('should not crash', () => {
+ const meter = new NoopMeterRegistry().getMeter('test-noop');
+ const counter = meter.createCounter('some-name');
+ const labels = {} as Labels;
+ const labelSet = meter.labels(labels);
+
+ // ensure NoopMetric does not crash.
+ counter.setCallback(() => {
+ assert.fail('callback occurred');
+ });
+ counter.bind(labelSet).add(1);
+ counter.getDefaultBound().add(1);
+ counter.unbind(labelSet);
+
+ // ensure the correct noop const is returned
+ assert.strictEqual(counter, NOOP_COUNTER_METRIC);
+ assert.strictEqual(counter.bind(labelSet), NOOP_BOUND_COUNTER);
+ assert.strictEqual(counter.getDefaultBound(), NOOP_BOUND_COUNTER);
+ counter.clear();
+
+ const measure = meter.createMeasure('some-name');
+ measure.getDefaultBound().record(1);
+ measure.getDefaultBound().record(1, { key: { value: 'value' } });
+ measure.getDefaultBound().record(
+ 1,
+ { key: { value: 'value' } },
+ {
+ traceId: 'a3cda95b652f4a1592b449d5929fda1b',
+ spanId: '5e0c63257de34c92',
+ }
+ );
+
+ // ensure the correct noop const is returned
+ assert.strictEqual(measure, NOOP_MEASURE_METRIC);
+ assert.strictEqual(measure.getDefaultBound(), NOOP_BOUND_MEASURE);
+ assert.strictEqual(measure.bind(labelSet), NOOP_BOUND_MEASURE);
+
+ const gauge = meter.createGauge('some-name');
+ gauge.getDefaultBound().set(1);
+
+ // ensure the correct noop const is returned
+ assert.strictEqual(gauge, NOOP_GAUGE_METRIC);
+ assert.strictEqual(gauge.getDefaultBound(), NOOP_BOUND_GAUGE);
+ assert.strictEqual(gauge.bind(labelSet), NOOP_BOUND_GAUGE);
+
+ const options = {
+ component: 'tests',
+ description: 'the testing package',
+ };
+
+ const measureWithOptions = meter.createMeasure('some-name', options);
+ assert.strictEqual(measureWithOptions, NOOP_MEASURE_METRIC);
+ const counterWithOptions = meter.createCounter('some-name', options);
+ assert.strictEqual(counterWithOptions, NOOP_COUNTER_METRIC);
+ const gaugeWithOptions = meter.createGauge('some-name', options);
+ assert.strictEqual(gaugeWithOptions, NOOP_GAUGE_METRIC);
+ });
+});
diff --git a/api/test/noop-implementations/noop-span.test.ts b/api/test/noop-implementations/noop-span.test.ts
new file mode 100644
index 0000000000..0350a9ab53
--- /dev/null
+++ b/api/test/noop-implementations/noop-span.test.ts
@@ -0,0 +1,60 @@
+/*!
+ * Copyright 2019, 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 assert from 'assert';
+import { CanonicalCode, INVALID_SPAN_ID, INVALID_TRACE_ID, NoopSpan, TraceFlags } from '../../src';
+
+describe('NoopSpan', () => {
+ it('do not crash', () => {
+ const span = new NoopSpan();
+ span.setAttribute('my_string_attribute', 'foo');
+ span.setAttribute('my_number_attribute', 123);
+ span.setAttribute('my_boolean_attribute', false);
+ span.setAttribute('my_obj_attribute', { a: true });
+ span.setAttribute('my_sym_attribute', Symbol('a'));
+ span.setAttributes({
+ my_string_attribute: 'foo',
+ my_number_attribute: 123,
+ });
+
+ span.addEvent('sent');
+ span.addEvent('sent', { id: '42', key: 'value' });
+
+ span.addLink({
+ traceId: 'd4cda95b652f4a1592b449d5929fda1b',
+ spanId: '6e0c63257de34c92',
+ });
+ span.addLink(
+ {
+ traceId: 'd4cda95b652f4a1592b449d5929fda1b',
+ spanId: '6e0c63257de34c92',
+ },
+ { id: '42', key: 'value' }
+ );
+
+ span.setStatus({ code: CanonicalCode.CANCELLED });
+
+ span.updateName('my-span');
+
+ assert.ok(!span.isRecording());
+ assert.deepStrictEqual(span.context(), {
+ traceId: INVALID_TRACE_ID,
+ spanId: INVALID_SPAN_ID,
+ traceFlags: TraceFlags.UNSAMPLED,
+ });
+ span.end();
+ });
+});
diff --git a/api/test/noop-implementations/noop-tracer.test.ts b/api/test/noop-implementations/noop-tracer.test.ts
new file mode 100644
index 0000000000..32dd6813ed
--- /dev/null
+++ b/api/test/noop-implementations/noop-tracer.test.ts
@@ -0,0 +1,65 @@
+/*!
+ * Copyright 2019, 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 assert from 'assert';
+import { NoopTracer, NOOP_SPAN, SpanKind } from '../../src';
+
+describe('NoopTracer', () => {
+ it('should not crash', () => {
+ const spanContext = { traceId: '', spanId: '' };
+ const tracer = new NoopTracer();
+
+ assert.deepStrictEqual(tracer.startSpan('span-name'), NOOP_SPAN);
+ assert.deepStrictEqual(
+ tracer.startSpan('span-name1', { kind: SpanKind.CLIENT }),
+ NOOP_SPAN
+ );
+ assert.deepStrictEqual(
+ tracer.startSpan('span-name2', {
+ kind: SpanKind.CLIENT,
+ isRecording: true,
+ }),
+ NOOP_SPAN
+ );
+
+ assert.deepStrictEqual(tracer.getCurrentSpan(), NOOP_SPAN);
+ const httpTextFormat = tracer.getHttpTextFormat();
+ assert.ok(httpTextFormat);
+ httpTextFormat.inject(spanContext, 'HttpTextFormat', {});
+ assert.deepStrictEqual(httpTextFormat.extract('HttpTextFormat', {}), null);
+
+ const binaryFormat = tracer.getBinaryFormat();
+ assert.ok(binaryFormat);
+ assert.ok(binaryFormat.toBytes(spanContext), typeof ArrayBuffer);
+ assert.deepStrictEqual(binaryFormat.fromBytes(new ArrayBuffer(0)), null);
+ });
+
+ it('should not crash when .withSpan()', done => {
+ const tracer = new NoopTracer();
+ tracer.withSpan(NOOP_SPAN, () => {
+ return done();
+ });
+ });
+
+ it('should not crash when .bind()', done => {
+ const tracer = new NoopTracer();
+ const fn = () => {
+ return done();
+ };
+ const patchedFn = tracer.bind(fn, NOOP_SPAN);
+ return patchedFn();
+ });
+});