Skip to content
This repository was archived by the owner on Oct 3, 2023. It is now read-only.

Commit 423b608

Browse files
crdgonzalezcadraffensperger
authored andcommitted
Custom spans (#141)
1 parent 0fdebb3 commit 423b608

5 files changed

Lines changed: 81 additions & 9 deletions

File tree

examples/user_interaction/client/src/App.js

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
* you may not use this file except in compliance with the License.
66
* You may obtain a copy of the License at
77
*
8-
* gRPC://www.apache.org/licenses/LICENSE-2.0
8+
* https://www.apache.org/licenses/LICENSE-2.0
99
*
1010
* Unless required by applicable law or agreed to in writing, software
1111
* distributed under the License is distributed on an "AS IS" BASIS,
@@ -15,6 +15,7 @@
1515
*/
1616

1717
import React from 'react';
18+
import { tracing } from '@opencensus/web-core';
1819

1920
class App extends React.Component {
2021

@@ -29,21 +30,34 @@ class App extends React.Component {
2930
handleClick() {
3031
// Use promises to test behavior on MicroTasks.
3132
const promise = new Promise(resolve => {
33+
// Start a child span for the setTimeout as this is the operation we want
34+
// to measure.
35+
// This span will be child of the current root span related to the
36+
// current user interaction. Additionally, these spans should be created
37+
// in the code the click handler will run.
38+
const setTimeoutCustomSpan = tracing.tracer.startChildSpan({ name: 'setTimeout custom span' });
3239
setTimeout(function () {
3340
resolve();
41+
// End the span as the setTimeout has finished running the callback.
42+
setTimeoutCustomSpan.end();
3443
}, 1000);
3544
});
3645

3746
promise.then(() => {
38-
console.log("Resolving promise");
3947
this.callSleepApi();
4048
});
4149
}
4250

4351
callSleepApi() {
4452
const xhr = new XMLHttpRequest();
53+
// Create a child span for the XHR. It is possible to create your own spans
54+
// even if the involved task or operation already generates an automatic
55+
// span. In this case, automatic spans are generated for XHRs.
56+
const callSleepApiCustomSpan = tracing.tracer.startChildSpan({ name: 'Call Sleep API' });
4557
xhr.onreadystatechange = () => {
4658
if (xhr.readyState === XMLHttpRequest.DONE) {
59+
// End the XHR span once it is DONE.
60+
callSleepApiCustomSpan.end();
4761
this.callPrimeNumbersApi();
4862
}
4963
};
@@ -66,10 +80,11 @@ class App extends React.Component {
6680
}
6781

6882
callCalculatePi() {
83+
// Start span for synchronous code.
84+
const calculatePiCustomSpan = tracing.tracer.startChildSpan({ name: 'Calculate PI' });
6985
const time = Date.now();
70-
console.log("Calculating PI");
7186
const pi = this.calculatePi();
72-
console.log("Finished calculating PI");
87+
calculatePiCustomSpan.end();
7388
return { time: (Date.now() - time), value: pi };
7489
}
7590

examples/user_interaction/client/src/SecondPage.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
* you may not use this file except in compliance with the License.
66
* You may obtain a copy of the License at
77
*
8-
* gRPC://www.apache.org/licenses/LICENSE-2.0
8+
* https://www.apache.org/licenses/LICENSE-2.0
99
*
1010
* Unless required by applicable law or agreed to in writing, software
1111
* distributed under the License is distributed on an "AS IS" BASIS,

examples/user_interaction/client/src/index.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
* you may not use this file except in compliance with the License.
66
* You may obtain a copy of the License at
77
*
8-
* gRPC://www.apache.org/licenses/LICENSE-2.0
8+
* https://www.apache.org/licenses/LICENSE-2.0
99
*
1010
* Unless required by applicable law or agreed to in writing, software
1111
* distributed under the License is distributed on an "AS IS" BASIS,

packages/opencensus-web-instrumentation-zone/README.md

Lines changed: 26 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,31 @@ The library is in alpha stage and the API is subject to change.
1111

1212
## Usage
1313

14-
Currently the primary intended usage of OpenCensus Web is to collect
15-
spans from the resource timing waterfall of an initial page load. See the
16-
[OpenCensus Web readme][oc-web-readme-url] for details.
14+
#### Custom spans
15+
In addition to automatic user interaction tracing, it is possible to create
16+
your own spans for the tasks or code involved in a user interaction.
17+
Here is an example for JavaScript
18+
19+
```javascript
20+
import { tracing } from '@opencensus/web-core';
21+
22+
function handleClick() {
23+
// Start child span which will be child of the current root span on the current interaction.
24+
// To make sure the span is attached to the root span, add this in code that the button is running.
25+
const childSpan = tracing.tracer.startChildSpan({
26+
name: 'name of your child span'
27+
});
28+
// Do some operation...
29+
// Finish the child span at the end of it's operation
30+
childSpan.end();
31+
}
32+
33+
// Create a fake button to point out the custom span is created in the click handler.
34+
const button = document.createElement('button');
35+
button.onclick = handleClick;
36+
```
37+
Check the [user interaction client example][client-example-url] which instruments the package and
38+
create some custom spans.
1739

1840
## Useful links
1941
- For more information on OpenCensus, visit: <https://opencensus.io/>
@@ -31,3 +53,4 @@ Apache 2.0 - See [LICENSE][license-url] for more information.
3153
[nav-timing-url]: https://www.w3.org/TR/navigation-timing-2/
3254
[resource-timing-url]: https://www.w3.org/TR/resource-timing-2/
3355
[long-tasks-url]: https://w3c.github.io/longtasks/
56+
[client-example-url]: https://github.com/census-instrumentation/opencensus-web/tree/master/examples/user_interaction/client

packages/opencensus-web-instrumentation-zone/test/test-interaction-tracker.ts

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -283,6 +283,40 @@ describe('InteractionTracker', () => {
283283
});
284284
});
285285

286+
describe('Custom Spans', () => {
287+
it('Should handle the custom spans and add them to the current root span as child spans', done => {
288+
const onclick = () => {
289+
// Start a custom span for the setTimeout.
290+
const setTimeoutCustomSpan = tracing.tracer.startChildSpan({
291+
name: 'setTimeout custom span',
292+
});
293+
setTimeout(() => {
294+
setTimeoutCustomSpan.end();
295+
}, SET_TIMEOUT_TIME);
296+
};
297+
fakeInteraction(onclick);
298+
299+
onEndSpanSpy.and.callFake((rootSpan: Span) => {
300+
expect(rootSpan.name).toBe('test interaction');
301+
expect(rootSpan.attributes['EventType']).toBe('click');
302+
expect(rootSpan.attributes['TargetElement']).toBe(BUTTON_TAG_NAME);
303+
expect(rootSpan.ended).toBeTruthy();
304+
expect(rootSpan.spans.length).toBe(1);
305+
const childSpan = rootSpan.spans[0];
306+
expect(childSpan.name).toBe('setTimeout custom span');
307+
expect(childSpan.duration).toBeGreaterThanOrEqual(SET_TIMEOUT_TIME);
308+
expect(childSpan.duration).toBeLessThanOrEqual(
309+
SET_TIMEOUT_TIME + TIME_BUFFER
310+
);
311+
expect(rootSpan.duration).toBeGreaterThanOrEqual(SET_TIMEOUT_TIME);
312+
expect(rootSpan.duration).toBeLessThanOrEqual(
313+
SET_TIMEOUT_TIME + TIME_BUFFER
314+
);
315+
done();
316+
});
317+
});
318+
});
319+
286320
describe('HTTP requests', () => {
287321
// Value to be full when the XMLHttpRequest.send method is faked,
288322
// That way the perfornamce resource entries have a accurate timing.

0 commit comments

Comments
 (0)