Skip to content

Commit ca97010

Browse files
authored
[core] - Add tracing sample (Azure#19911)
**Checklists** - [x] Added impacted package name to the issue description **Packages impacted by this PR:** @azure/core-tracing **Issues associated with this PR:** Resolves Azure#19738 **Describe the problem that is addressed by this PR:** When upgrading to the new @azure/core-tracing APIs, developers will need a sample demonstrating how to add tracing to their client libraries. In this PR, we're adding a simple sample demonstrating the most common scenarios using a fake client.
1 parent ced6c1f commit ca97010

File tree

13 files changed

+557
-1
lines changed

13 files changed

+557
-1
lines changed

sdk/core/core-tracing/package.json

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,5 +91,12 @@
9191
"util": "^0.12.1",
9292
"sinon": "^9.0.2",
9393
"@types/sinon": "^9.0.4"
94+
},
95+
"//sampleConfiguration": {
96+
"disableDocsMs": true,
97+
"productName": "Azure SDK Core",
98+
"productSlugs": [
99+
"azure"
100+
]
94101
}
95102
}

sdk/core/core-tracing/sample.env

Whitespace-only changes.
Lines changed: 119 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,119 @@
1+
// Copyright (c) Microsoft Corporation.
2+
// Licensed under the MIT license.
3+
4+
/**
5+
* @summary Uses `@azure/core-tracing` APIs to instrument method calls for a fake Azure client library.
6+
*/
7+
8+
import { createTracingClient, OperationTracingOptions, TracingClient } from "@azure/core-tracing";
9+
10+
/**
11+
* Represents common operation options
12+
*/
13+
interface OperationOptions {
14+
tracingOptions?: OperationTracingOptions;
15+
}
16+
17+
/**
18+
* Represents an Azure Client that does work against an Azure service.
19+
*/
20+
class BasicClient {
21+
private tracingClient: TracingClient;
22+
23+
constructor() {
24+
// Create a tracing client in the constructor
25+
this.tracingClient = createTracingClient({
26+
// The package name and version of your package.
27+
packageName: "@azure/some-example-package",
28+
packageVersion: "1.0.0",
29+
// The Resource Provider, which should normally be one of the values defined here:
30+
// https://docs.microsoft.com/azure/azure-resource-manager/management/azure-services-resource-providers
31+
namespace: "Microsoft.Sample",
32+
});
33+
}
34+
35+
/**
36+
* Represents the most common scenario - calling an azure service, mapping the result,
37+
* and returning the result.
38+
*
39+
* Creating the span, setting its status, recording exceptions, and ensuring the span
40+
* is closed will be handled by the tracing client.
41+
*
42+
* @param options - The operation options.
43+
*/
44+
async basicOperation(options: OperationOptions = {}): Promise<number> {
45+
return this.tracingClient.withSpan(
46+
"BasicClient.basicOperation",
47+
options,
48+
async (_updatedOptions, _span) => {
49+
// The `updatedOptions` argument will be returned, containing a new tracing context.
50+
// Call the generated client, passing updatedOptions, and handle the response as you
51+
// normally would.
52+
//
53+
// You do not need to close the span.
54+
const result = await Promise.resolve({ value: 42 });
55+
return result.value;
56+
}
57+
);
58+
}
59+
60+
/**
61+
* Represents a consumer which receives a message, creates a new span for processing the message, and links
62+
* the new span to the message span (via traceheader propagation).
63+
* @param traceparentHeader The {@link https://www.w3.org/TR/trace-context/#traceparent-header} header of the remote operation.
64+
* @param options - The Operation Options.
65+
*/
66+
async withSpanLinks(traceparentHeader: string, options: OperationOptions = {}): Promise<void> {
67+
const spanLinks = [];
68+
const linkContext = this.tracingClient.parseTraceparentHeader(traceparentHeader);
69+
if (linkContext) {
70+
spanLinks.push({ tracingContext: linkContext });
71+
}
72+
// You can pass additional span options to configure the newly created span.
73+
// In this case, we'll create a "consumer" span with a link to the remote span.
74+
return this.tracingClient.withSpan("BasicClient.withSpanLinks", options, () => {}, {
75+
spanLinks,
76+
spanKind: "consumer",
77+
});
78+
}
79+
80+
/**
81+
* Represents a scenario where a user provided callback is invoked. In this case, when leaving
82+
* the boundaries of the Azure SDK, you **MUST** either use `withSpan` or `withContext` when
83+
* a new span does not need to be created to ensure the active context is set for the duration
84+
* of the callback.
85+
* @param callback - The customer registered callback.
86+
* @param options - The operation options.
87+
*/
88+
async withUserCallback<Callback extends (...args: unknown[]) => ReturnType<Callback>>(
89+
callback: Callback,
90+
options: OperationOptions = {}
91+
): Promise<ReturnType<Callback>> {
92+
const { span, updatedOptions } = this.tracingClient.startSpan(
93+
"BasicClient.withUserCallback",
94+
options
95+
);
96+
const result = this.tracingClient.withContext(
97+
updatedOptions.tracingOptions!.tracingContext!,
98+
callback
99+
);
100+
span.setStatus({ status: "success" });
101+
span.end();
102+
return result;
103+
}
104+
}
105+
106+
export async function main(): Promise<void> {
107+
const client = new BasicClient();
108+
await client.basicOperation();
109+
// Using the example https://www.w3.org/TR/trace-context/#examples-of-http-traceparent-headers
110+
await client.withSpanLinks("00-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-01");
111+
await client.withUserCallback(() => {
112+
// no-op
113+
});
114+
}
115+
116+
main().catch((error) => {
117+
console.error("An error occurred:", error);
118+
process.exit(1);
119+
});
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
# Azure SDK Core client library samples for JavaScript
2+
3+
These sample programs show how to use the JavaScript client libraries for Azure SDK Core in some common scenarios.
4+
5+
| **File Name** | **Description** |
6+
| ------------------------------- | ------------------------------------------------------------------------------------------- |
7+
| [basicTracing.js][basictracing] | Uses `@azure/core-tracing` APIs to instrument method calls for a fake Azure client library. |
8+
9+
## Prerequisites
10+
11+
The sample programs are compatible with [LTS versions of Node.js](https://nodejs.org/about/releases/).
12+
13+
You need [an Azure subscription][freesub] to run these sample programs.
14+
15+
Samples retrieve credentials to access the service endpoint from environment variables. Alternatively, edit the source code to include the appropriate credentials. See each individual sample for details on which environment variables/credentials it requires to function.
16+
17+
Adapting the samples to run in the browser may require some additional consideration. For details, please see the [package README][package].
18+
19+
## Setup
20+
21+
To run the samples using the published version of the package:
22+
23+
1. Install the dependencies using `npm`:
24+
25+
```bash
26+
npm install
27+
```
28+
29+
2. Edit the file `sample.env`, adding the correct credentials to access the Azure service and run the samples. Then rename the file from `sample.env` to just `.env`. The sample programs will read this file automatically.
30+
31+
3. Run whichever samples you like (note that some samples may require additional setup, see the table above):
32+
33+
```bash
34+
node basicTracing.js
35+
```
36+
37+
Alternatively, run a single sample with the correct environment variables set (setting up the `.env` file is not required if you do this), for example (cross-platform):
38+
39+
```bash
40+
npx cross-env node basicTracing.js
41+
```
42+
43+
## Next Steps
44+
45+
Take a look at our [API Documentation][apiref] for more information about the APIs that are available in the clients.
46+
47+
[basictracing]: https://github.com/Azure/azure-sdk-for-js/blob/main/sdk/core/core-tracing/samples/v1/javascript/basicTracing.js
48+
[apiref]: https://docs.microsoft.com/javascript/api/@azure/core-tracing
49+
[freesub]: https://azure.microsoft.com/free/
50+
[package]: https://github.com/Azure/azure-sdk-for-js/tree/main/sdk/core/core-tracing/README.md
Lines changed: 111 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,111 @@
1+
// Copyright (c) Microsoft Corporation.
2+
// Licensed under the MIT license.
3+
4+
/**
5+
* @summary Uses `@azure/core-tracing` APIs to instrument method calls for a fake Azure client library.
6+
*/
7+
8+
const { createTracingClient } = require("@azure/core-tracing");
9+
10+
/**
11+
* Represents an Azure Client that does work against an Azure service.
12+
*/
13+
class BasicClient {
14+
tracingClient;
15+
16+
constructor() {
17+
// Create a tracing client in the constructor
18+
this.tracingClient = createTracingClient({
19+
// The package name and version of your package.
20+
packageName: "@azure/some-example-package",
21+
packageVersion: "1.0.0",
22+
// The Resource Provider, which should normally be one of the values defined here:
23+
// https://docs.microsoft.com/azure/azure-resource-manager/management/azure-services-resource-providers
24+
namespace: "Microsoft.Sample",
25+
});
26+
}
27+
28+
/**
29+
* Represents the most common scenario - calling an azure service, mapping the result,
30+
* and returning the result.
31+
*
32+
* Creating the span, setting its status, recording exceptions, and ensuring the span
33+
* is closed will be handled by the tracing client.
34+
*
35+
* @param options - The operation options.
36+
*/
37+
async basicOperation(options = {}) {
38+
return this.tracingClient.withSpan(
39+
"BasicClient.basicOperation",
40+
options,
41+
async (_updatedOptions, _span) => {
42+
// The `updatedOptions` argument will be returned, containing a new tracing context.
43+
// Call the generated client, passing updatedOptions, and handle the response as you
44+
// normally would.
45+
//
46+
// You do not need to close the span.
47+
const result = await Promise.resolve({ value: 42 });
48+
return result.value;
49+
}
50+
);
51+
}
52+
53+
/**
54+
* Represents a consumer which receives a message, creates a new span for processing the message, and links
55+
* the new span to the message span (via traceheader propagation).
56+
* @param traceparentHeader The {@link https://www.w3.org/TR/trace-context/#traceparent-header} header of the remote operation.
57+
* @param options - The Operation Options.
58+
*/
59+
async withSpanLinks(traceparentHeader, options = {}) {
60+
const spanLinks = [];
61+
const linkContext = this.tracingClient.parseTraceparentHeader(traceparentHeader);
62+
if (linkContext) {
63+
spanLinks.push({ tracingContext: linkContext });
64+
}
65+
// You can pass additional span options to configure the newly created span.
66+
// In this case, we'll create a "consumer" span with a link to the remote span.
67+
return this.tracingClient.withSpan("BasicClient.withSpanLinks", options, () => {}, {
68+
spanLinks,
69+
spanKind: "consumer",
70+
});
71+
}
72+
73+
/**
74+
* Represents a scenario where a user provided callback is invoked. In this case, when leaving
75+
* the boundaries of the Azure SDK, you **MUST** either use `withSpan` or `withContext` when
76+
* a new span does not need to be created to ensure the active context is set for the duration
77+
* of the callback.
78+
* @param callback - The customer registered callback.
79+
* @param options - The operation options.
80+
*/
81+
async withUserCallback(callback, options = {}) {
82+
const { span, updatedOptions } = this.tracingClient.startSpan(
83+
"BasicClient.withUserCallback",
84+
options
85+
);
86+
const result = this.tracingClient.withContext(
87+
updatedOptions.tracingOptions.tracingContext,
88+
callback
89+
);
90+
span.setStatus({ status: "success" });
91+
span.end();
92+
return result;
93+
}
94+
}
95+
96+
async function main() {
97+
const client = new BasicClient();
98+
await client.basicOperation();
99+
// Using the example https://www.w3.org/TR/trace-context/#examples-of-http-traceparent-headers
100+
await client.withSpanLinks("00-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-01");
101+
await client.withUserCallback(() => {
102+
// no-op
103+
});
104+
}
105+
106+
main().catch((error) => {
107+
console.error("An error occurred:", error);
108+
process.exit(1);
109+
});
110+
111+
module.exports = { main };
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
{
2+
"name": "azure-core-tracing-samples-js",
3+
"private": true,
4+
"version": "1.0.0",
5+
"description": "Azure SDK Core client library samples for JavaScript",
6+
"engines": {
7+
"node": ">=12.0.0"
8+
},
9+
"repository": {
10+
"type": "git",
11+
"url": "git+https://github.com/Azure/azure-sdk-for-js.git",
12+
"directory": "sdk/core/core-tracing"
13+
},
14+
"keywords": [
15+
"azure",
16+
"tracing",
17+
"cloud"
18+
],
19+
"author": "Microsoft Corporation",
20+
"license": "MIT",
21+
"bugs": {
22+
"url": "https://github.com/Azure/azure-sdk-for-js/issues"
23+
},
24+
"homepage": "https://github.com/Azure/azure-sdk-for-js/tree/main/sdk/core/core-tracing",
25+
"dependencies": {
26+
"@azure/core-tracing": "latest",
27+
"dotenv": "latest"
28+
}
29+
}

sdk/core/core-tracing/samples/v1/javascript/sample.env

Whitespace-only changes.
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
# Azure SDK Core client library samples for TypeScript
2+
3+
These sample programs show how to use the TypeScript client libraries for Azure SDK Core in some common scenarios.
4+
5+
| **File Name** | **Description** |
6+
| ------------------------------- | ------------------------------------------------------------------------------------------- |
7+
| [basicTracing.ts][basictracing] | Uses `@azure/core-tracing` APIs to instrument method calls for a fake Azure client library. |
8+
9+
## Prerequisites
10+
11+
The sample programs are compatible with [LTS versions of Node.js](https://nodejs.org/about/releases/).
12+
13+
Before running the samples in Node, they must be compiled to JavaScript using the TypeScript compiler. For more information on TypeScript, see the [TypeScript documentation][typescript]. Install the TypeScript compiler using:
14+
15+
```bash
16+
npm install -g typescript
17+
```
18+
19+
You need [an Azure subscription][freesub] to run these sample programs.
20+
21+
Samples retrieve credentials to access the service endpoint from environment variables. Alternatively, edit the source code to include the appropriate credentials. See each individual sample for details on which environment variables/credentials it requires to function.
22+
23+
Adapting the samples to run in the browser may require some additional consideration. For details, please see the [package README][package].
24+
25+
## Setup
26+
27+
To run the samples using the published version of the package:
28+
29+
1. Install the dependencies using `npm`:
30+
31+
```bash
32+
npm install
33+
```
34+
35+
2. Compile the samples:
36+
37+
```bash
38+
npm run build
39+
```
40+
41+
3. Edit the file `sample.env`, adding the correct credentials to access the Azure service and run the samples. Then rename the file from `sample.env` to just `.env`. The sample programs will read this file automatically.
42+
43+
4. Run whichever samples you like (note that some samples may require additional setup, see the table above):
44+
45+
```bash
46+
node dist/basicTracing.js
47+
```
48+
49+
Alternatively, run a single sample with the correct environment variables set (setting up the `.env` file is not required if you do this), for example (cross-platform):
50+
51+
```bash
52+
npx cross-env node dist/basicTracing.js
53+
```
54+
55+
## Next Steps
56+
57+
Take a look at our [API Documentation][apiref] for more information about the APIs that are available in the clients.
58+
59+
[basictracing]: https://github.com/Azure/azure-sdk-for-js/blob/main/sdk/core/core-tracing/samples/v1/typescript/src/basicTracing.ts
60+
[apiref]: https://docs.microsoft.com/javascript/api/@azure/core-tracing
61+
[freesub]: https://azure.microsoft.com/free/
62+
[package]: https://github.com/Azure/azure-sdk-for-js/tree/main/sdk/core/core-tracing/README.md
63+
[typescript]: https://www.typescriptlang.org/docs/home.html

0 commit comments

Comments
 (0)