Skip to content

Commit e2984f6

Browse files
Merge branch 'master' into change_default_propagator
2 parents 4fe8ea8 + 2486c3d commit e2984f6

File tree

388 files changed

+4266
-1090
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

388 files changed

+4266
-1090
lines changed

.github/CODEOWNERS

+1-1
Original file line numberDiff line numberDiff line change
@@ -12,4 +12,4 @@
1212
# https://help.github.com/en/articles/about-code-owners
1313
#
1414

15-
* @dyladan @mayurkale22 @rochdev @bg451 @OlivierAlbertini @vmarchaud @markwolff @obecny @mwear @naseemkullah
15+
* @dyladan @mayurkale22 @rochdev @bg451 @OlivierAlbertini @vmarchaud @markwolff @obecny @mwear @naseemkullah @legendecas

README.md

+3
Original file line numberDiff line numberDiff line change
@@ -135,6 +135,7 @@ Approvers ([@open-telemetry/js-approvers](https://github.com/orgs/open-telemetry
135135
- [Bartlomiej Obecny](https://github.com/obecny), LightStep
136136
- [Matthew Wear](https://github.com/mwear), LightStep
137137
- [Naseem K. Ullah](https://github.com/naseemkullah), Transit
138+
- [Chengzhong Wu](https://github.com/legendecas), Alibaba
138139

139140
*Find more about the approver role in [community repository](https://github.com/open-telemetry/community/blob/master/community-membership.md#approver).*
140141

@@ -205,6 +206,7 @@ These plugins are hosted at <https://github.com/open-telemetry/opentelemetry-js-
205206
##### Core
206207

207208
- [@opentelemetry/plugin-xml-http-request][otel-plugin-xml-http-request]
209+
- [@opentelemetry/plugin-fetch][otel-plugin-fetch]
208210

209211
##### Contrib
210212

@@ -240,6 +242,7 @@ Apache 2.0 - See [LICENSE][license-url] for more information.
240242
[otel-metrics]: https://github.com/open-telemetry/opentelemetry-js/tree/master/packages/opentelemetry-metrics
241243
[otel-node]: https://github.com/open-telemetry/opentelemetry-js/tree/master/packages/opentelemetry-node
242244

245+
[otel-plugin-fetch]: https://github.com/open-telemetry/opentelemetry-js/tree/master/packages/opentelemetry-plugin-fetch
243246
[otel-plugin-grpc]: https://github.com/open-telemetry/opentelemetry-js/tree/master/packages/opentelemetry-plugin-grpc
244247
[otel-plugin-http]: https://github.com/open-telemetry/opentelemetry-js/tree/master/packages/opentelemetry-plugin-http
245248
[otel-plugin-https]: https://github.com/open-telemetry/opentelemetry-js/tree/master/packages/opentelemetry-plugin-https

eslint.config.js

+5-5
Original file line numberDiff line numberDiff line change
@@ -27,10 +27,10 @@ module.exports = {
2727
"arrow-parens": ["error", "as-needed"],
2828
"prettier/prettier": ["error", { "singleQuote": true, "arrowParens": "avoid" }],
2929
"node/no-deprecated-api": ["warn"],
30-
"header/header": [2, "block", [{
31-
pattern: / \* Copyright \d{4}, OpenTelemetry Authors[\r\n]+ \*[\r\n]+ \* Licensed under the Apache License, Version 2\.0 \(the \"License\"\);[\r\n]+ \* you may not use this file except in compliance with the License\.[\r\n]+ \* You may obtain a copy of the License at[\r\n]+ \*[\r\n]+ \* https:\/\/www\.apache\.org\/licenses\/LICENSE-2\.0[\r\n]+ \*[\r\n]+ \* Unless required by applicable law or agreed to in writing, software[\r\n]+ \* distributed under the License is distributed on an \"AS IS\" BASIS,[\r\n]+ \* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied\.[\r\n]+ \* See the License for the specific language governing permissions and[\r\n]+ \* limitations under the License\./gm,
32-
template:
33-
`\n * Copyright ${new Date().getFullYear()}, OpenTelemetry Authors\n *\n * Licensed under the Apache License, Version 2.0 (the "License");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * https://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an "AS IS" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n `
30+
"header/header": [2, "block", [{
31+
pattern: / \* Copyright The OpenTelemetry Authors[\r\n]+ \*[\r\n]+ \* Licensed under the Apache License, Version 2\.0 \(the \"License\"\);[\r\n]+ \* you may not use this file except in compliance with the License\.[\r\n]+ \* You may obtain a copy of the License at[\r\n]+ \*[\r\n]+ \* https:\/\/www\.apache\.org\/licenses\/LICENSE-2\.0[\r\n]+ \*[\r\n]+ \* Unless required by applicable law or agreed to in writing, software[\r\n]+ \* distributed under the License is distributed on an \"AS IS\" BASIS,[\r\n]+ \* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied\.[\r\n]+ \* See the License for the specific language governing permissions and[\r\n]+ \* limitations under the License\./gm,
32+
template:
33+
`\n * Copyright The OpenTelemetry Authors\n *\n * Licensed under the Apache License, Version 2.0 (the "License");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * https://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an "AS IS" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n `
3434
}]]
3535
},
3636
overrides: [
@@ -39,7 +39,7 @@ module.exports = {
3939
"rules": {
4040
"no-empty": "off",
4141
"@typescript-eslint/ban-ts-ignore": "off",
42-
"@typescript-eslint/no-empty-function": "off",
42+
"@typescript-eslint/no-empty-function": "off",
4343
"@typescript-eslint/no-explicit-any": "off",
4444
"@typescript-eslint/no-unused-vars": "off",
4545
"@typescript-eslint/no-var-requires": "off"

examples/tracer-web/README.md

+5
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,11 @@ The screen will look as follows:
3535

3636
![Screenshot of the running example](images/xml-http-request.png)
3737

38+
39+
### Fetch
40+
41+
To see the results, open the browser at <http://localhost:8090/fetch/> and make sure you have the browser console open. The application is using the `ConsoleSpanExporter` and will post the created spans to the browser console.
42+
3843
## Useful links
3944

4045
- For more information on OpenTelemetry, visit: <https://opentelemetry.io/>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
<!DOCTYPE html>
2+
<html lang="en">
3+
4+
<head>
5+
<meta charset="utf-8">
6+
<title>Fetch Plugin Example</title>
7+
<base href="/">
8+
9+
<meta name="viewport" content="width=device-width, initial-scale=1">
10+
</head>
11+
12+
<body>
13+
Example of using Web Tracer with Fetch plugin with console exporter and collector exporter
14+
<script type="text/javascript" src="fetch.js"></script>
15+
<br/>
16+
<button id="button1">Test</button>
17+
18+
</body>
19+
20+
</html>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
'use strict';
2+
3+
import { ConsoleSpanExporter, SimpleSpanProcessor } from '@opentelemetry/tracing';
4+
import { CollectorExporter } from '@opentelemetry/exporter-collector';
5+
import { WebTracerProvider } from '@opentelemetry/web';
6+
import { FetchPlugin } from '@opentelemetry/plugin-fetch';
7+
import { ZoneContextManager } from '@opentelemetry/context-zone';
8+
import { B3Propagator } from '@opentelemetry/core';
9+
10+
const provider = new WebTracerProvider({
11+
plugins: [
12+
new FetchPlugin({
13+
ignoreUrls: [/localhost:8090\/sockjs-node/],
14+
propagateTraceHeaderCorsUrls: [
15+
'https://cors-test.appspot.com/test',
16+
'https://httpbin.org/get',
17+
],
18+
clearTimingResources: true
19+
}),
20+
],
21+
});
22+
23+
provider.addSpanProcessor(new SimpleSpanProcessor(new ConsoleSpanExporter()));
24+
provider.addSpanProcessor(new SimpleSpanProcessor(new CollectorExporter()));
25+
provider.register({
26+
contextManager: new ZoneContextManager(),
27+
propagator: new B3Propagator(),
28+
});
29+
30+
const webTracerWithZone = provider.getTracer('example-tracer-web');
31+
32+
const getData = (url) => fetch(url, {
33+
method: 'GET',
34+
headers: {
35+
'Accept': 'application/json',
36+
'Content-Type': 'application/json',
37+
},
38+
});
39+
40+
// example of keeping track of context between async operations
41+
const prepareClickEvent = () => {
42+
const url1 = 'https://httpbin.org/get';
43+
44+
const element = document.getElementById('button1');
45+
46+
const onClick = () => {
47+
const span1 = webTracerWithZone.startSpan(`files-series-info`, {
48+
parent: webTracerWithZone.getCurrentSpan(),
49+
});
50+
webTracerWithZone.withSpan(span1, () => {
51+
getData(url1).then((_data) => {
52+
webTracerWithZone.getCurrentSpan().addEvent('fetching-span1-completed');
53+
span1.end();
54+
});
55+
});
56+
for (let i = 0, j = 5; i < j; i += 1) {
57+
const span1 = webTracerWithZone.startSpan(`files-series-info-${i}`, {
58+
parent: webTracerWithZone.getCurrentSpan(),
59+
});
60+
webTracerWithZone.withSpan(span1, () => {
61+
getData(url1).then((_data) => {
62+
webTracerWithZone.getCurrentSpan().addEvent('fetching-span1-completed');
63+
span1.end();
64+
});
65+
});
66+
}
67+
};
68+
element.addEventListener('click', onClick);
69+
};
70+
71+
window.addEventListener('load', prepareClickEvent);

examples/tracer-web/package.json

+1
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@
3838
"@opentelemetry/core": "^0.8.3",
3939
"@opentelemetry/exporter-collector": "^0.8.3",
4040
"@opentelemetry/plugin-document-load": "^0.6.1",
41+
"@opentelemetry/plugin-fetch": "^0.8.3",
4142
"@opentelemetry/plugin-user-interaction": "^0.6.1",
4243
"@opentelemetry/plugin-xml-http-request": "^0.8.3",
4344
"@opentelemetry/tracing": "^0.8.3",

examples/tracer-web/webpack.config.js

+1
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ const common = {
88
mode: 'development',
99
entry: {
1010
'document-load': 'examples/document-load/index.js',
11+
fetch: 'examples/fetch/index.js',
1112
'xml-http-request': 'examples/xml-http-request/index.js',
1213
'user-interaction': 'examples/user-interaction/index.js',
1314
},

karma.base.js

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*!
2-
* Copyright 2019, OpenTelemetry Authors
2+
* Copyright The OpenTelemetry Authors
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -20,7 +20,7 @@ module.exports = {
2020
browsers: ['ChromeHeadless'],
2121
frameworks: ['mocha'],
2222
coverageIstanbulReporter: {
23-
reports: ['json'],
23+
reports: ['html', 'json'],
2424
dir: '.nyc_output',
2525
fixWebpackSourcePaths: true
2626
},

karma.webpack.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*!
2-
* Copyright 2019, OpenTelemetry Authors
2+
* Copyright The OpenTelemetry Authors
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
+51
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
# OpenTelemetry Plugins Node Core
2+
[![Gitter chat][gitter-image]][gitter-url]
3+
[![NPM Published Version][npm-img]][npm-url]
4+
[![dependencies][dependencies-image]][dependencies-url]
5+
[![Apache License][license-image]][license-image]
6+
7+
This package depends on all node plugins maintained by OpenTelemetry authors.
8+
Installing it will also install all plugins.
9+
10+
## Plugins
11+
12+
In addition to all [node core plugins][otel-plugins-node-core], the following plugins will be installed by this package:
13+
14+
- [@opentelemetry/plugin-express][otel-plugin-express]
15+
- [@opentelemetry/plugin-ioredis][otel-plugin-ioredis]
16+
- [@opentelemetry/plugin-mongodb][otel-plugin-mongodb]
17+
- [@opentelemetry/plugin-mysql][otel-plugin-mysql]
18+
- [@opentelemetry/plugin-pg-pool][otel-plugin-pg-pool]
19+
- [@opentelemetry/plugin-pg][otel-plugin-pg]
20+
- [@opentelemetry/plugin-redis][otel-plugin-redis]
21+
22+
Note: [@opentelemetry/plugin-dns][otel-plugin-dns] is excluded by default because it requires some manual configuration to prevent infinite loops with exporters.
23+
24+
## Useful links
25+
- For more information on OpenTelemetry, visit: <https://opentelemetry.io/>
26+
- For more about OpenTelemetry JavaScript: <https://github.com/open-telemetry/opentelemetry-js>
27+
- For help or feedback on this project, join us on [gitter][gitter-url]
28+
29+
## License
30+
31+
Apache 2.0 - See [LICENSE][license-url] for more information.
32+
33+
[gitter-image]: https://badges.gitter.im/open-telemetry/opentelemetry-js.svg
34+
[gitter-url]: https://gitter.im/open-telemetry/opentelemetry-node?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge
35+
[license-url]: https://github.com/open-telemetry/opentelemetry-js/blob/master/LICENSE
36+
[license-image]: https://img.shields.io/badge/license-Apache_2.0-green.svg?style=flat
37+
[dependencies-image]: https://david-dm.org/open-telemetry/opentelemetry-js/status.svg?path=metapackages/plugins-node-core
38+
[dependencies-url]: https://david-dm.org/open-telemetry/opentelemetry-js?path=packages%2Fopentelemetryplugins-node-core
39+
[npm-url]: https://www.npmjs.com/package/@opentelemetry/plugins-node-core
40+
[npm-img]: https://badge.fury.io/js/%40opentelemetry%2Fplugins-node-core.svg
41+
42+
[otel-plugins-node-core]: https://www.npmjs.com/package/@opentelemetry/plugins-node-core
43+
44+
[otel-plugin-dns]: https://github.com/open-telemetry/opentelemetry-js-contrib/tree/master/plugins/node/opentelemetry-plugin-dns
45+
[otel-plugin-express]: https://github.com/open-telemetry/opentelemetry-js-contrib/tree/master/plugins/node/opentelemetry-plugin-express
46+
[otel-plugin-ioredis]: https://github.com/open-telemetry/opentelemetry-js-contrib/tree/master/plugins/node/opentelemetry-plugin-ioredis
47+
[otel-plugin-mongodb]: https://github.com/open-telemetry/opentelemetry-js-contrib/tree/master/plugins/node/opentelemetry-plugin-mongodb
48+
[otel-plugin-mysql]: https://github.com/open-telemetry/opentelemetry-js-contrib/tree/master/plugins/node/opentelemetry-plugin-mysql
49+
[otel-plugin-pg-pool]: https://github.com/open-telemetry/opentelemetry-js-contrib/tree/master/plugins/node/opentelemetry-plugin-pg-pool
50+
[otel-plugin-pg]: https://github.com/open-telemetry/opentelemetry-js-contrib/tree/master/plugins/node/opentelemetry-plugin-pg
51+
[otel-plugin-redis]: https://github.com/open-telemetry/opentelemetry-js-contrib/tree/master/plugins/node/opentelemetry-plugin-redis
+28
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
{
2+
"name": "@opentelemetry/plugins-node-all",
3+
"version": "0.8.3",
4+
"description": "Metapackage which bundles opentelemetry node core and contrib plugins",
5+
"author": "OpenTelemetry Authors",
6+
"homepage": "https://github.com/open-telemetry/opentelemetry-js#readme",
7+
"license": "Apache-2.0",
8+
"publishConfig": {
9+
"access": "public"
10+
},
11+
"repository": {
12+
"type": "git",
13+
"url": "git+https://github.com/open-telemetry/opentelemetry-js.git"
14+
},
15+
"bugs": {
16+
"url": "https://github.com/open-telemetry/opentelemetry-js/issues"
17+
},
18+
"dependencies": {
19+
"@opentelemetry/plugins-node-core": "^0.8.3",
20+
"@opentelemetry/plugin-express": "0.8.0",
21+
"@opentelemetry/plugin-ioredis": "0.8.0",
22+
"@opentelemetry/plugin-mongodb": "0.8.0",
23+
"@opentelemetry/plugin-mysql": "0.8.0",
24+
"@opentelemetry/plugin-pg-pool": "0.8.0",
25+
"@opentelemetry/plugin-pg": "0.8.0",
26+
"@opentelemetry/plugin-redis": "0.8.0"
27+
}
28+
}

package.json

+4-4
Original file line numberDiff line numberDiff line change
@@ -42,12 +42,12 @@
4242
"@commitlint/config-conventional": "8.3.4",
4343
"beautify-benchmark": "0.2.4",
4444
"benchmark": "2.1.4",
45-
"eslint": "6.8.0",
46-
"eslint-config-airbnb-base": "14.1.0",
45+
"eslint": "7.2.0",
46+
"eslint-config-airbnb-base": "14.2.0",
4747
"eslint-plugin-import": "2.21.2",
4848
"eslint-plugin-header": "3.0.0",
49-
"@typescript-eslint/eslint-plugin": "3.2.0",
50-
"@typescript-eslint/parser": "3.2.0",
49+
"@typescript-eslint/eslint-plugin": "3.3.0",
50+
"@typescript-eslint/parser": "3.3.0",
5151
"gh-pages": "3.0.0",
5252
"gts": "2.0.2",
5353
"husky": "4.2.5",

packages/opentelemetry-api/karma.conf.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*!
2-
* Copyright 2019, OpenTelemetry Authors
2+
* Copyright The OpenTelemetry Authors
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.

packages/opentelemetry-api/package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@
6060
"codecov": "3.7.0",
6161
"gts": "2.0.2",
6262
"istanbul-instrumenter-loader": "3.0.1",
63-
"karma": "5.0.9",
63+
"karma": "5.1.0",
6464
"karma-chrome-launcher": "3.1.0",
6565
"karma-coverage-istanbul-reporter": "3.0.3",
6666
"karma-mocha": "2.0.1",

packages/opentelemetry-api/src/api/context.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
/*!
2-
* Copyright 2020, OpenTelemetry Authors
1+
/*
2+
* Copyright The OpenTelemetry Authors
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.

packages/opentelemetry-api/src/api/global-utils.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
/*!
2-
* Copyright 2020, OpenTelemetry Authors
1+
/*
2+
* Copyright The OpenTelemetry Authors
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.

packages/opentelemetry-api/src/api/metrics.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
/*!
2-
* Copyright 2020, OpenTelemetry Authors
1+
/*
2+
* Copyright The OpenTelemetry Authors
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.

packages/opentelemetry-api/src/api/propagation.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
/*!
2-
* Copyright 2020, OpenTelemetry Authors
1+
/*
2+
* Copyright The OpenTelemetry Authors
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.

packages/opentelemetry-api/src/api/trace.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
/*!
2-
* Copyright 2020, OpenTelemetry Authors
1+
/*
2+
* Copyright The OpenTelemetry Authors
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.

packages/opentelemetry-api/src/common/Logger.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
/*!
2-
* Copyright 2019, OpenTelemetry Authors
1+
/*
2+
* Copyright The OpenTelemetry Authors
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.

packages/opentelemetry-api/src/common/Time.ts

+2-4
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
/*!
2-
* Copyright 2019, OpenTelemetry Authors
1+
/*
2+
* Copyright The OpenTelemetry Authors
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -13,8 +13,6 @@
1313
* See the License for the specific language governing permissions and
1414
* limitations under the License.
1515
*/
16-
17-
/** High resolution HrTime: [seconds: number, nanoseconds: number] */
1816
export type HrTime = [number, number];
1917

2018
/**

packages/opentelemetry-api/src/context/propagation/HttpTextPropagator.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
/*!
2-
* Copyright 2019, OpenTelemetry Authors
1+
/*
2+
* Copyright The OpenTelemetry Authors
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.

packages/opentelemetry-api/src/context/propagation/NoopHttpTextPropagator.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
/*!
2-
* Copyright 2019, OpenTelemetry Authors
1+
/*
2+
* Copyright The OpenTelemetry Authors
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.

0 commit comments

Comments
 (0)