Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

XMLHttpRequest #595

Merged
merged 31 commits into from
Dec 19, 2019
Merged
Show file tree
Hide file tree
Changes from 24 commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
8fce91a
feat(xml-http-request): new plugin for auto instrumentation for xml-h…
obecny Dec 5, 2019
0875f3f
chore: new example for xml-http-request and updated examples structur…
obecny Dec 5, 2019
f1c6013
chore: updating readme
obecny Dec 5, 2019
6038bcc
chore: linting
obecny Dec 5, 2019
ac68ab9
chore: fixing origin for tests
obecny Dec 5, 2019
87dcdc6
chore: linting
obecny Dec 5, 2019
6e10df7
chore: updating to use b3 format from core
obecny Dec 5, 2019
e91d8f9
chore: updates after reviews
obecny Dec 6, 2019
8e01e96
chore: wrong function call
obecny Dec 6, 2019
898c190
chore: updating attribute names
obecny Dec 6, 2019
54d0ba0
chore: linting
obecny Dec 6, 2019
9f2c563
chore: adding preflight requests, fixing few other issues
obecny Dec 9, 2019
8a17c2a
chore: adding image to examples, updating readme
obecny Dec 9, 2019
db00221
chore: forcing async to be true, but propagate rest params
obecny Dec 9, 2019
ef66398
chore: fixing type for open and send function
obecny Dec 9, 2019
7d884db
chore: fixing format for headers
obecny Dec 9, 2019
3e39b1a
chore: reviews
obecny Dec 10, 2019
bcc1204
chore: decrement task count when span exists
obecny Dec 10, 2019
c9163e5
chore: changes after review
obecny Dec 10, 2019
f73aacb
chore: adding weakmap for keeping information connected with xhr
obecny Dec 10, 2019
88e122a
chore: renaming config param
obecny Dec 10, 2019
c3dac11
chore: not needed cast
obecny Dec 10, 2019
524da7a
chore: updating title
obecny Dec 11, 2019
50e151e
chore: refactored xhr, removed tracing dependency, few other issues f…
obecny Dec 11, 2019
6c143e7
chore: reviews
obecny Dec 13, 2019
3d7b32e
chore: refactored for collecting timing resources
obecny Dec 16, 2019
91bad5d
chore: merge branch 'master' into xml-http-request
obecny Dec 16, 2019
5aa23ca
chore: fixes after merging
obecny Dec 16, 2019
ab9795a
chore: reviews
obecny Dec 18, 2019
4d4e65f
chore: reviews
obecny Dec 19, 2019
ca96cb1
Merge branch 'master' into xml-http-request
mayurkale22 Dec 19, 2019
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
19 changes: 15 additions & 4 deletions examples/tracer-web/README.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
# Overview
obecny marked this conversation as resolved.
Show resolved Hide resolved

This example shows how to use [@opentelemetry/web](https://github.com/open-telemetry/opentelemetry-js/tree/master/packages/opentelemetry-web) to instrument your JavaScript code running in the browser.
This example uses the `ConsoleSpanExporter()` to export spans to the browser console output.
This example shows how to use [@opentelemetry/web](https://github.com/open-telemetry/opentelemetry-js/tree/master/packages/opentelemetry-web) with different plugins and setup to instrument your JavaScript code running in the browser.

## Installation

Expand All @@ -19,11 +18,23 @@ $ npm start

By default, the application will run on port `8090`.

To see the results, open the browser at <http://localhost:8090/> 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.
## Examples

### Document Load

To see the results, open the browser at <http://localhost:8090/document-load/> 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.

The screen will look as follows:

![Screenshot of the running example](images/traces.png)
![Screenshot of the running example](images/document-load.png)

### XMLHttpRequest

To see the results, open the browser at <http://localhost:8090/xml-http-request/> 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.
The screen will look as follows:

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


## Useful links

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

<head>
<meta charset="utf-8">
<title>Web Tracer Example</title>
<title>Document Load Plugin Example</title>
<base href="/">

<!--
Expand All @@ -22,7 +22,7 @@

<body>
Example of using Web Tracer with document load plugin with console exporter and collector exporter
<script type="text/javascript" src="/bundle.js"></script>
<script type="text/javascript" src="document-load.js"></script>
<br/>
<button id="button1">Test WebTracer with ZoneScopeManager - async</button>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,4 @@ const getData = (url) => {
});
};

window.addEventListener('load', () => {
prepareClickEvent();
});
window.addEventListener('load', prepareClickEvent);
20 changes: 20 additions & 0 deletions examples/tracer-web/examples/xml-http-request/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
<!DOCTYPE html>
<html lang="en">

<head>
<meta charset="utf-8">
<title>XMLHttpRequest Plugin Example</title>
<base href="/">

<meta name="viewport" content="width=device-width, initial-scale=1">
</head>

<body>
Example of using Web Tracer with XMLHttpRequest plugin with console exporter and collector exporter
<script type="text/javascript" src="xml-http-request.js"></script>
<br/>
<button id="button1">Test</button>

</body>

</html>
59 changes: 59 additions & 0 deletions examples/tracer-web/examples/xml-http-request/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
import { ConsoleSpanExporter, SimpleSpanProcessor } from '@opentelemetry/tracing';
mayurkale22 marked this conversation as resolved.
Show resolved Hide resolved
import { WebTracer } from '@opentelemetry/web';
import { XMLHttpRequestPlugin } from '@opentelemetry/plugin-xml-http-request';
import { ZoneScopeManager } from '@opentelemetry/scope-zone';
import { CollectorExporter } from '@opentelemetry/exporter-collector';
import { B3Format } from '@opentelemetry/core';

const webTracerWithZone = new WebTracer({
httpTextFormat: new B3Format(),
scopeManager: new ZoneScopeManager(),
plugins: [
new XMLHttpRequestPlugin({
ignoreUrls: [/localhost:8090\/sockjs-node/],
propagateTraceHeaderCorsUrls: [
'https://httpbin.org/get'
]
})
]
});

webTracerWithZone.addSpanProcessor(new SimpleSpanProcessor(new ConsoleSpanExporter()));
webTracerWithZone.addSpanProcessor(new SimpleSpanProcessor(new CollectorExporter()));

// example of keeping track of scope between async operations
const prepareClickEvent = () => {
const url1 = 'https://httpbin.org/get';

const element = document.getElementById('button1');

const onClick = () => {
for (let i = 0, j = 5; i < j; i++) {
const span1 = webTracerWithZone.startSpan(`files-series-info-${i}`, {
parent: webTracerWithZone.getCurrentSpan()
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe if there is no current span, this span will just be a root span, which is the correct behavior. I think my comment about having a nice root span for XHRs is more like a future feature and not so much an issue with this code.

});
webTracerWithZone.withSpan(span1, () => {
getData(url1).then((data) => {
webTracerWithZone.getCurrentSpan().addEvent('fetching-span1-completed');
span1.end();
});
});
}
};
element.addEventListener('click', onClick);
};

const getData = (url) => {
return new Promise(async (resolve, reject) => {
const req = new XMLHttpRequest();
req.open('GET', url, true);
req.setRequestHeader('Content-Type', 'application/json');
req.setRequestHeader('Accept', 'application/json');
req.send();
req.onload = function () {
resolve();
};
});
};

window.addEventListener('load', prepareClickEvent);
Binary file added examples/tracer-web/images/xml-http-request.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4 changes: 3 additions & 1 deletion examples/tracer-web/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
"description": "Example of using @opentelemetry/web in browser",
"main": "index.js",
"scripts": {
"start": "webpack-dev-server -d --progress --colors --port 8090 --config webpack.config.js --hot --inline --host 0.0.0.0"
"start": "webpack-dev-server -d --progress --colors --port 8090 --config webpack.config.js --hot --inline --host 0.0.0.0 --content-base examples"
},
"repository": {
"type": "git",
Expand Down Expand Up @@ -34,8 +34,10 @@
"webpack-merge": "^4.2.2"
},
"dependencies": {
"@opentelemetry/core": "^0.2.0",
"@opentelemetry/exporter-collector": "^0.2.0",
"@opentelemetry/plugin-document-load": "^0.2.0",
"@opentelemetry/plugin-xml-http-request": "^0.3.0",
"@opentelemetry/scope-zone": "^0.2.0",
"@opentelemetry/tracing": "^0.2.0",
"@opentelemetry/web": "^0.2.0"
Expand Down
18 changes: 10 additions & 8 deletions examples/tracer-web/webpack.config.js
Original file line number Diff line number Diff line change
@@ -1,12 +1,19 @@
const webpack = require('webpack');
const webpackMerge = require('webpack-merge');
const path = require('path');
const mainPath = path.resolve('');
const directory = path.resolve(__dirname);

const common = {
mode: 'development',
entry: 'index.js',
entry: {
'document-load': 'examples/document-load/index.js',
'xml-http-request': 'examples/xml-http-request/index.js'
},
output: {
path: path.resolve(__dirname, 'dist'),
filename: '[name].js',
sourceMapFilename: '[file].map'
},
target: 'web',
module: {
rules: [
Expand All @@ -28,7 +35,6 @@ const common = {
},
resolve: {
modules: [
path.resolve(mainPath, 'src'),
path.resolve(directory),
'node_modules'
],
Expand All @@ -38,12 +44,8 @@ const common = {

module.exports = webpackMerge(common, {
devtool: 'eval-source-map',
output: {
filename: 'bundle.js',
sourceMapFilename: '[file].map'
},
devServer: {
contentBase: path.resolve(__dirname),
contentBase: path.resolve(__dirname)
},
plugins: [
new webpack.DefinePlugin({
Expand Down
10 changes: 10 additions & 0 deletions packages/opentelemetry-core/src/common/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,3 +32,13 @@ export interface TimeOriginLegacy {
fetchStart: number;
};
}

/**
* This interface defines the params that are be added to the wrapped function
* using the "shimmer.wrap"
*/
export interface ShimWrapped {
__wrapped: boolean;
__unwrap: Function;
__original: Function;
}
2 changes: 2 additions & 0 deletions packages/opentelemetry-core/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,3 +33,5 @@ export * from './trace/spancontext-utils';
export * from './trace/TracerDelegate';
export * from './trace/TraceState';
export * from './metrics/NoopMeter';
export * from './utils/url';
export * from './utils/wrap';
48 changes: 48 additions & 0 deletions packages/opentelemetry-core/src/utils/url.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
/*!
* 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.
*/

/**
* Check if {@param url} matches {@param urlToMatch}
* @param url
* @param urlToMatch
*/
export function urlMatches(url: string, urlToMatch: string | RegExp): boolean {
if (typeof urlToMatch === 'string') {
return url === urlToMatch;
} else {
return !!url.match(urlToMatch);
}
}
/**
* Check if {@param url} should be ignored when comparing against {@param ignoredUrls}
* @param url
* @param ignoredUrls
*/
export function isUrlIgnored(
url: string,
ignoredUrls?: Array<string | RegExp>
): boolean {
if (!ignoredUrls) {
return false;
}

for (const ignoreUrl of ignoredUrls) {
if (urlMatches(url, ignoreUrl)) {
return true;
}
}
return false;
}
30 changes: 30 additions & 0 deletions packages/opentelemetry-core/src/utils/wrap.ts
Original file line number Diff line number Diff line change
@@ -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 { ShimWrapped } from '../common/types';

/**
* Checks if certain function has been already wrapped
* @param func
*/
export function isWrapped(func: any) {
return (
typeof func === 'function' &&
typeof (func as ShimWrapped).__original === 'function' &&
typeof (func as ShimWrapped).__unwrap === 'function' &&
(func as ShimWrapped).__wrapped === true
);
}
75 changes: 75 additions & 0 deletions packages/opentelemetry-core/test/utils/url.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
/**
* 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 { isUrlIgnored } from '../../src';

const urlIgnored = 'url should be ignored';
const urlNotIgnored = 'url should NOT be ignored';

const urlToTest = 'http://myaddress.com/somepath';

describe('BasePlugin - Utils', () => {
describe('isUrlIgnored', () => {
describe('when ignored urls are undefined', () => {
it('should return false', () => {
assert.strictEqual(isUrlIgnored(urlToTest), false, urlNotIgnored);
});
});
describe('when ignored urls are empty', () => {
it('should return false', () => {
assert.strictEqual(isUrlIgnored(urlToTest, []), false, urlNotIgnored);
});
});
describe('when ignored urls is the same as url', () => {
it('should return true', () => {
assert.strictEqual(
isUrlIgnored(urlToTest, ['http://myaddress.com/somepath']),
true,
urlIgnored
);
});
});
describe('when url is part of ignored urls', () => {
it('should return false', () => {
assert.strictEqual(
isUrlIgnored(urlToTest, ['http://myaddress.com/some']),
false,
urlNotIgnored
);
});
});
describe('when ignored urls is part of url - REGEXP', () => {
it('should return true', () => {
assert.strictEqual(
isUrlIgnored(urlToTest, [/.+?myaddress\.com/]),
true,
urlIgnored
);
});
});
describe('when url is part of ignored urls - REGEXP', () => {
it('should return false', () => {
assert.strictEqual(
isUrlIgnored(urlToTest, [/http:\/\/myaddress\.com\/somepath2/]),
false,
urlNotIgnored
);
});
});
});
});