Skip to content

Commit

Permalink
chore: fixing documentation for web tracer provider, fixing exam… (op…
Browse files Browse the repository at this point in the history
…en-telemetry#906)

* chore: fixing documentation for web tracer provider, fixing examples for web, enable manager when registering

* chore: fixing span extraction from zone after context updates

* chore: bump
  • Loading branch information
obecny committed Mar 27, 2020
1 parent 9e114d1 commit 6afa63c
Show file tree
Hide file tree
Showing 10 changed files with 128 additions and 55 deletions.
69 changes: 37 additions & 32 deletions examples/tracer-web/examples/document-load/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,19 +10,13 @@ const provider = new WebTracerProvider({
],
});
provider.addSpanProcessor(new SimpleSpanProcessor(new ConsoleSpanExporter()));
provider.addSpanProcessor(new SimpleSpanProcessor(new CollectorExporter()));

const providerWithZone = new WebTracerProvider({
provider.register({
contextManager: new ZoneContextManager(),
plugins: [
new DocumentLoad(),
],
});
providerWithZone.addSpanProcessor(new SimpleSpanProcessor(new ConsoleSpanExporter()));
providerWithZone.addSpanProcessor(new SimpleSpanProcessor(new CollectorExporter()));

const tracerWithZone = providerWithZone.getTracer('example-tracer-web');
let window;
console.log('Current span is window', tracerWithZone.getCurrentSpan() === window);
const tracer = provider.getTracer('example-tracer-web');

const getData = (url) => new Promise((resolve, reject) => {
// eslint-disable-next-line no-undef
Expand All @@ -45,37 +39,48 @@ const prepareClickEvent = () => {
const url1 = 'https://raw.githubusercontent.com/open-telemetry/opentelemetry-js/master/package.json';
const url2 = 'https://raw.githubusercontent.com/open-telemetry/opentelemetry-js/master/packages/opentelemetry-web/package.json';

let document;
const element = document.getElementById('button1');
const mainSpan = tracerWithZone.startSpan('main-span');
tracerWithZone.bind(element, mainSpan);

const onClick = () => {
const span1 = tracerWithZone.startSpan('files-series-info-1', {
parent: tracerWithZone.getCurrentSpan(),
});
let count = 0;

const span2 = tracerWithZone.startSpan('files-series-info-2', {
parent: tracerWithZone.getCurrentSpan(),
});
function finish() {
count++;
if (count === 2) {
mainSpan.end();
}
}

tracerWithZone.withSpan(span1, () => {
getData(url1).then((data) => {
console.log('current span is span1', tracerWithZone.getCurrentSpan() === span1);
console.log('info from package.json', data.description, data.version);
tracerWithZone.getCurrentSpan().addEvent('fetching-span1-completed');
span1.end();
const mainSpan = tracer.startSpan('click button');
tracer.withSpan(mainSpan, () => {
const span1 = tracer.startSpan('files-series-info-1', {
parent: tracer.getCurrentSpan(),
});

const span2 = tracer.startSpan('files-series-info-2', {
parent: tracer.getCurrentSpan(),
});
});

tracerWithZone.withSpan(span2, () => {
getData(url2).then((data) => {
setTimeout(() => {
console.log('current span is span2', tracerWithZone.getCurrentSpan() === span2);
tracer.withSpan(span1, () => {
getData(url1).then((data) => {
console.log('current span is span1', tracer.getCurrentSpan() === span1);
console.log('info from package.json', data.description, data.version);
tracerWithZone.getCurrentSpan().addEvent('fetching-span2-completed');
span2.end();
}, 100);
tracer.getCurrentSpan().addEvent('fetching-span1-completed');
span1.end();
finish();
});
});

tracer.withSpan(span2, () => {
getData(url2).then((data) => {
setTimeout(() => {
console.log('current span is span2', tracer.getCurrentSpan() === span2);
console.log('info from package.json', data.description, data.version);
tracer.getCurrentSpan().addEvent('fetching-span2-completed');
span2.end();
finish();
}, 100);
});
});
});
};
Expand Down
2 changes: 0 additions & 2 deletions examples/tracer-web/examples/xml-http-request/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,6 @@ const getData = (url) => new Promise((resolve, _reject) => {
const prepareClickEvent = () => {
const url1 = 'https://httpbin.org/get';

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

const onClick = () => {
Expand All @@ -61,5 +60,4 @@ const prepareClickEvent = () => {
element.addEventListener('click', onClick);
};

let window;
window.addEventListener('load', prepareClickEvent);
3 changes: 2 additions & 1 deletion packages/opentelemetry-context-base/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,8 @@
"precompile": "tsc --version",
"version:update": "node ../../scripts/version-update.js",
"compile": "npm run version:update && tsc -p .",
"prepare": "npm run compile"
"prepare": "npm run compile",
"watch": "tsc -w"
},
"keywords": [
"opentelemetry",
Expand Down
5 changes: 4 additions & 1 deletion packages/opentelemetry-core/src/context/context.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,10 @@
import { Span, SpanContext } from '@opentelemetry/api';
import { Context } from '@opentelemetry/context-base';

const ACTIVE_SPAN_KEY = Context.createKey(
/**
* Active span key
*/
export const ACTIVE_SPAN_KEY = Context.createKey(
'OpenTelemetry Context Key ACTIVE_SPAN'
);
const EXTRACTED_SPAN_CONTEXT_KEY = Context.createKey(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ export class DocumentLoad extends BasePlugin<unknown> {
) as PerformanceResourceTiming[];
if (resources) {
resources.forEach(resource => {
this._initResourceSpan(resource);
this._initResourceSpan(resource, { parent: rootSpan });
});
}
}
Expand Down
1 change: 1 addition & 0 deletions packages/opentelemetry-plugin-user-interaction/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -102,3 +102,4 @@ Apache 2.0 - See [LICENSE][license-url] for more information.
[npm-img]: https://badge.fury.io/js/%40opentelemetry%2Fplugin-user-interaction.svg
[zone-js]: https://www.npmjs.com/package/zone.js
[@opentelemetry/context-zone]: https://www.npmjs.com/package/@opentelemetry/context-zone

Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,13 @@
*/

import * as shimmer from 'shimmer';
import { BasePlugin, hrTime, isWrapped } from '@opentelemetry/core';
import * as types from '@opentelemetry/api';
import {
ACTIVE_SPAN_KEY,
BasePlugin,
hrTime,
isWrapped,
} from '@opentelemetry/core';
import * as api from '@opentelemetry/api';
import { getElementXPath } from '@opentelemetry/web';
import {
AsyncTask,
Expand All @@ -41,7 +46,7 @@ export class UserInteractionPlugin extends BasePlugin<unknown> {
readonly component: string = 'user-interaction';
readonly version = VERSION;
moduleName = this.component;
private _spansData = new WeakMap<types.Span, SpanData>();
private _spansData = new WeakMap<api.Span, SpanData>();
private _zonePatched = false;

constructor() {
Expand All @@ -56,7 +61,7 @@ export class UserInteractionPlugin extends BasePlugin<unknown> {
* @param task
* @param span
*/
private _checkForTimeout(task: AsyncTask, span: types.Span) {
private _checkForTimeout(task: AsyncTask, span: api.Span) {
const spanData = this._spansData.get(span);
if (spanData) {
if (task.source === 'setTimeout') {
Expand All @@ -78,7 +83,7 @@ export class UserInteractionPlugin extends BasePlugin<unknown> {
private _createSpan(
element: HTMLElement,
eventName: string
): types.Span | undefined {
): api.Span | undefined {
if (!element.getAttribute) {
return undefined;
}
Expand Down Expand Up @@ -114,7 +119,7 @@ export class UserInteractionPlugin extends BasePlugin<unknown> {
* This is needed to be able to end span when no more tasks left
* @param span
*/
private _decrementTask(span: types.Span) {
private _decrementTask(span: api.Span) {
const spanData = this._spansData.get(span);
if (spanData) {
spanData.taskCount--;
Expand All @@ -124,6 +129,19 @@ export class UserInteractionPlugin extends BasePlugin<unknown> {
}
}

/**
* Return the current span
* @param zone
* @private
*/
private _getCurrentSpan(zone: Zone): api.Span | undefined {
const context: api.Context | undefined = zone.get(ZONE_CONTEXT_KEY);
if (context) {
return context.getValue(ACTIVE_SPAN_KEY) as api.Span;
}
return context;
}

/**
* It gets the element that has been clicked when zone tries to run a new task
* @param task
Expand All @@ -140,7 +158,7 @@ export class UserInteractionPlugin extends BasePlugin<unknown> {
* This is needed to be able to end span when no more tasks left
* @param span
*/
private _incrementTask(span: types.Span) {
private _incrementTask(span: api.Span) {
const spanData = this._spansData.get(span);
if (spanData) {
spanData.taskCount++;
Expand Down Expand Up @@ -228,7 +246,7 @@ export class UserInteractionPlugin extends BasePlugin<unknown> {
* @param url
*/
_updateInteractionName(url: string) {
const span: types.Span | undefined = this._tracer.getCurrentSpan();
const span: api.Span | undefined = this._tracer.getCurrentSpan();
if (span && typeof span.updateName === 'function') {
span.updateName(`${EVENT_NAVIGATION_NAME} ${url}`);
}
Expand All @@ -246,7 +264,7 @@ export class UserInteractionPlugin extends BasePlugin<unknown> {
task: AsyncTask
) {
const currentZone = Zone.current;
const currentSpan = currentZone.get(ZONE_CONTEXT_KEY);
const currentSpan = plugin._getCurrentSpan(currentZone);
if (currentSpan && plugin._shouldCountTask(task, currentZone)) {
plugin._decrementTask(currentSpan);
}
Expand All @@ -269,7 +287,7 @@ export class UserInteractionPlugin extends BasePlugin<unknown> {
task: AsyncTask
) {
const currentZone = Zone.current;
const currentSpan: types.Span = currentZone.get(ZONE_CONTEXT_KEY);
const currentSpan = plugin._getCurrentSpan(currentZone);
if (currentSpan && plugin._shouldCountTask(task, currentZone)) {
plugin._incrementTask(currentSpan);
plugin._checkForTimeout(task, currentSpan);
Expand All @@ -294,7 +312,7 @@ export class UserInteractionPlugin extends BasePlugin<unknown> {
applyArgs?: any
): Zone {
const target: HTMLElement | undefined = plugin._getClickedElement(task);
let span: types.Span | undefined;
let span: api.Span | undefined;
if (target) {
span = plugin._createSpan(target, 'click');
if (span) {
Expand All @@ -310,7 +328,7 @@ export class UserInteractionPlugin extends BasePlugin<unknown> {
}
}
} else {
span = this.get(ZONE_CONTEXT_KEY);
span = plugin._getCurrentSpan(this);
}

try {
Expand All @@ -337,7 +355,7 @@ export class UserInteractionPlugin extends BasePlugin<unknown> {
if (!currentZone || !task.data || task.data.isPeriodic) {
return false;
}
const currentSpan = currentZone.get(ZONE_CONTEXT_KEY);
const currentSpan = this._getCurrentSpan(currentZone);
if (!currentSpan) {
return false;
}
Expand All @@ -353,7 +371,7 @@ export class UserInteractionPlugin extends BasePlugin<unknown> {
* @param endTime
* @private
*/
private _tryToEndSpan(span: types.Span, endTime?: types.HrTime) {
private _tryToEndSpan(span: api.Span, endTime?: api.HrTime) {
if (span) {
const spanData = this._spansData.get(span);
if (spanData) {
Expand Down
8 changes: 6 additions & 2 deletions packages/opentelemetry-web/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,16 +45,20 @@ const provider = new WebTracerProvider({
});

provider.addSpanProcessor(new SimpleSpanProcessor(new ConsoleSpanExporter()));
provider.register();

// Changing default contextManager to use ZoneContextManager - supports asynchronous operations
const providerWithZone = new WebTracerProvider({
contextManager: new ZoneContextManager(),
plugins: [
new DocumentLoad()
]
});
providerWithZone.addSpanProcessor(new SimpleSpanProcessor(new ConsoleSpanExporter()));

// Changing default contextManager to use ZoneContextManager - supports asynchronous operations
providerWithZone.register({
contextManager: new ZoneContextManager(),
});

```

## Useful links
Expand Down
10 changes: 10 additions & 0 deletions packages/opentelemetry-web/src/WebTracerProvider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,14 @@ export class WebTracerProvider extends BasicTracerProvider {
for (const plugin of config.plugins) {
plugin.enable([], this, this.logger);
}

if ((config as SDKRegistrationConfig).contextManager) {
throw 'contextManager should be defined in register method not in' +
' constructor';
}
if ((config as SDKRegistrationConfig).propagator) {
throw 'propagator should be defined in register method not in constructor';
}
}

/**
Expand All @@ -61,6 +69,8 @@ export class WebTracerProvider extends BasicTracerProvider {
register(config: SDKRegistrationConfig = {}) {
if (config.contextManager === undefined) {
config.contextManager = new StackContextManager();
}
if (config.contextManager) {
config.contextManager.enable();
}

Expand Down
37 changes: 35 additions & 2 deletions packages/opentelemetry-web/test/WebTracerProvider.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
*/

import { context } from '@opentelemetry/api';
import { BasePlugin, NoopLogger } from '@opentelemetry/core';
import { B3Propagator, BasePlugin, NoopLogger } from '@opentelemetry/core';
import { ContextManager } from '@opentelemetry/context-base';
import { ZoneContextManager } from '@opentelemetry/context-zone';
import { Tracer, Span } from '@opentelemetry/tracing';
Expand Down Expand Up @@ -79,8 +79,40 @@ describe('WebTracerProvider', () => {
});
});

it('should throw error when context manager is passed in constructor', () => {
let error = '';
try {
new WebTracerProvider({
contextManager: new ZoneContextManager(),
} as any);
} catch (e) {
error = e;
}
assert.strictEqual(
error,
'contextManager should be defined in' +
' register method not in constructor'
);
});

it('should throw error when propagator is passed in constructor', () => {
let error = '';
try {
new WebTracerProvider({
propagator: new B3Propagator(),
} as any);
} catch (e) {
error = e;
}
assert.strictEqual(
error,
'propagator should be defined in register' +
' method not in constructor'
);
});

describe('when contextManager is "ZoneContextManager"', () => {
it('should correctly return the contexts for 2 parallel actions', () => {
it('should correctly return the contexts for 2 parallel actions', done => {
const webTracerWithZone = new WebTracerProvider().getTracer('default');

const rootSpan = webTracerWithZone.startSpan('rootSpan');
Expand Down Expand Up @@ -112,6 +144,7 @@ describe('WebTracerProvider', () => {
webTracerWithZone.getCurrentSpan() === concurrentSpan2,
'Current span is concurrentSpan2'
);
done();
}, 20);
});
});
Expand Down

0 comments on commit 6afa63c

Please sign in to comment.