Skip to content

Commit fa95f06

Browse files
authored
Implement getTraceContextInfo, update to SDK v1.5.0 (#28)
1 parent 6de3758 commit fa95f06

File tree

9 files changed

+183
-54
lines changed

9 files changed

+183
-54
lines changed

README.md

Lines changed: 38 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ This is the official Node.js implementation of the [Dynatrace OneAgent SDK](http
2020
* [Trace SQL database requests](#trace-sql-database-requests)
2121
* [Set custom request attributes](#set-custom-request-attributes)
2222
* [Metrics (deprecated)](#metrics)
23+
* [Trace context](#trace-context)
2324
* [Administrative Apis](#administrative-apis)
2425
* [Current SDK state](#current-sdk-state)
2526
* [Set callbacks for logging](#set-callbacks-for-logging)
@@ -45,43 +46,44 @@ This is the official Node.js implementation of the [Dynatrace OneAgent SDK](http
4546
* When loading the OneAgent via [OneAgent NPM module](https://www.npmjs.com/package/@dynatrace/oneagent) or a similar tool, make sure to require the SDK after the OneAgent
4647
* Dynatrace OneAgent (required versions see below)
4748
* The OneAgent SDK is not supported on serverless code modules, including those for AWS Lambda.
48-
Consider using [OpenTelemetry](https://www.dynatrace.com/support/help/shortlink/opentel-lambda) instead in these scenarios.
49+
In these scenarios consider using [OpenTelemetry](https://www.dynatrace.com/support/help/shortlink/opentel-lambda) instead.
4950

50-
|OneAgent SDK for Node.js|Required OneAgent version|Support status|
51-
|:-----------------------|:------------------------|:-------------|
52-
|1.4.x |>=1.179 |Supported |
53-
|1.3.x |>=1.165 |Supported |
54-
|1.2.x |>=1.145 |Supported |
55-
|1.1.x |>=1.143 |Supported |
56-
|1.0.x |>=1.137 |Supported |
51+
|OneAgent SDK for Node.js|Required OneAgent version|Support status |
52+
|:-----------------------|:------------------------|:----------------------------------------|
53+
|1.5.x |>=1.259 |Supported |
54+
|1.4.x |>=1.179 |Supported |
55+
|1.3.x |>=1.165 |Deprecated with support ending 2023-08-01|
56+
|1.2.x |>=1.145 |Deprecated with support ending 2023-08-01|
57+
|1.1.x |>=1.143 |Deprecated with support ending 2023-08-01|
58+
|1.0.x |>=1.137 |Deprecated with support ending 2023-08-01|
5759

5860
## Integration
5961

6062
Using this module should not cause any errors if no OneAgent is present (e.g. in testing).
6163

62-
Make sure that this module is required after Dynatrace OneAgent.
64+
Make sure that this module is loaded after Dynatrace OneAgent.
6365

6466
### Installation
6567

6668
`npm install --save @dynatrace/oneagent-sdk`
6769

6870
### Troubleshooting
6971

70-
If the SDK can't connect to the OneAgent ([Current SDK state](#current-sdk-state) is not `ACTIVE`) verify that a matching version of OneAgent is used *and required before* the SDK module.
72+
If the SDK cannot connect to the OneAgent ([Current SDK state](#current-sdk-state) is not `ACTIVE`) verify that a matching version of OneAgent is used *and loaded before* the SDK module.
7173

7274
Verify that OneAgent is working as intended (see [Dynatrace OneAgent](https://www.dynatrace.com/technologies/nodejs-monitoring/)).
7375

7476
You should ensure that you have set [LoggingCallbacks](#set-callbacks-for-logging).
7577

76-
OneAgent transparently wrap *supported* libraries to add context information. For every yet *unsupported* module [Pass Context](#pass-context) can be used to provide transactional context to callbacks.
78+
OneAgent transparently wraps *supported* libraries to add context information. For every currently *unsupported* module [Pass Context](#pass-context) can be used to provide transactional context to callbacks.
7779

7880
## API Concepts
7981

80-
Common concepts of the Dynatrace OneAgent SDK are explained the [Dynatrace OneAgent SDK repository](https://github.com/Dynatrace/OneAgent-SDK).
82+
Common concepts of the Dynatrace OneAgent SDK are explained in the [Dynatrace OneAgent SDK repository](https://github.com/Dynatrace/OneAgent-SDK).
8183

8284
### OneAgentSDK object
8385

84-
The first step is to acquire an OneAgent SDK API object by calling `createInstance()`. The resulting object holds methods to create tracers, administrative methods (e.g. check SDK state, install logging callbacks) and `passContext()`. Every call to `createInstance()` will return a new API object allowing the user to install separate logging callbacks for separate use cases.
86+
The first step is to acquire a OneAgent SDK API object by calling `createInstance()`. The resulting object holds methods to create tracers, administrative methods (e.g. check SDK state, install logging callbacks) and `passContext()`. Every call to `createInstance()` will return a new API object allowing the user to install separate logging callbacks for separate use cases.
8587

8688
```js
8789
const Sdk = require('@dynatrace/oneagent-sdk');
@@ -94,8 +96,8 @@ The life-cycle of a tracer is as follows:
9496

9597
1. Create a trace using the `traceXXX` method matching to your use case. For incoming taggable traces pass the received Dynatrace tag (if present) to the `traceXXX` method.
9698
1. Start the trace which in turn invokes and times the given handler function.
97-
1. For outgoing taggable traces fetch a Dynatrace tag and include it to the message sent out.
98-
1. Optional mark the traced operation as failed via a call to `error()`
99+
1. For outgoing taggable traces fetch a Dynatrace tag and include it to the message being sent.
100+
1. Optionally mark the traced operation as failed via a call to `error()`
99101
1. End the trace once the operation is done. For outgoing traces you may pass a callback to be included in this trace.
100102

101103
Each tracer offers following methods:
@@ -115,8 +117,8 @@ Tracers for outgoing taggable requests additionally offer following methods to g
115117
* `getDynatraceStringTag()` returns a Dynatrace tag encoded as `string`
116118
* `getDynatraceByteTag()` returns a Dynatrace tag binary encoded as `Buffer`
117119

118-
This Dynatrace tag needs to be embedded into the message sent to remote service. Depending on the concrete protocol used the `string` or binary representation may fit better and it's up to the user to decide which variant to use.
119-
On incoming service this tag needs to be extracted by the user and passed to the corresponding `traceXXX` method using the `dynatraceTag` property of the arguments to allow linking of outgoing and the corresponding incoming trace.
120+
This Dynatrace tag needs to be embedded into the message sent to remote service. The `string` or binary representation may fit better depending on the concrete protocol used. It is up to the user to decide which variant to use.
121+
On an incoming service this tag needs to be extracted by the user and passed to the corresponding `traceXXX` method using the `dynatraceTag` property of the arguments to allow linking of outgoing and the corresponding incoming trace.
120122

121123
The tracer objects returned by above methods are always valid even if there is no OneAgent present or no trace is created for whatever reason. In this case the methods are still present to avoid the need of extra checking in client code.
122124

@@ -136,6 +138,7 @@ A more detailed specification of the features can be found in [Dynatrace OneAgen
136138
|Set custom request attributes |>=1.2.0 |
137139
|Trace Messaging |>=1.3.0 |
138140
|Metrics (deprecated) |>=1.4.0 |
141+
|Trace context |>=1.5.0 |
139142

140143
### Trace incoming and outgoing remote calls
141144

@@ -356,7 +359,7 @@ It receives an object with following properties:
356359
* `rowsReturned` Optional - Number of rows returned by this traced database request. Only positive values are allowed
357360
* `roundTripCount` Optional - Count of round-trips that took place. Only positive values are allowed
358361

359-
Please note that SQL database traces are only created if they occur within some other SDK trace (e.g. incoming remote call) or an OneAgent built-in trace (e.g. incoming web request).
362+
Please note that SQL database traces are only created if they occur within some other SDK trace (e.g. incoming remote call) or a OneAgent built-in trace (e.g. incoming web request).
360363

361364
**Example (see [DatabaseRequestSample.js](samples/Database/DatabaseRequestSample.js) for more details):**
362365

@@ -450,6 +453,10 @@ Otherwise, using the same metric name multiple times is an error. All metrics wi
450453
* `dimensionName` Optional - a `string` specifying the name of the dimension added to the metric.
451454
If a name is given here it's required to set a dimension value during booking samples on the metric. A dimension is like an additional label attached to values, for example a "disk.written.bytes" metric could have a dimension name of "disk-id" and when adding values to it a dimension value would be "/dev/sda1".
452455

456+
### Trace context
457+
The implementation follows the specification from [Dynatrace OneAgent SDK - Trace Context](https://github.com/Dynatrace/OneAgent-SDK#tracecontext).
458+
For an usage example refer to [W3CTraceContextApiSample.js](samples/TraceContext/W3CTraceContextApiSample.js).
459+
453460
### Administrative APIs
454461

455462
#### Current SDK state
@@ -579,7 +586,7 @@ collection.findOne({_id: doc_id}, callback);
579586

580587
```
581588

582-
After `collection.findOne()` is executed asynchronously `callback()` will be called. `callback()` again contains an asynchronous call `http.get()` which performs an outbound HTTP request. If there is a current transactional context with an ongoing trace, Dynatrace OneAgent will transparently add a HTTP header containing a Dynatrace tag to this outbound request. The next tier - if instrumented with OneAgent - will continue this trace then. Without further intervention any transactional context would get lost between asynchronous invocation and a callback. Currently the only reliable way to pass over context information to a callback is called 'wrapping'.
589+
After `collection.findOne()` is executed asynchronously `callback()` will be called. `callback()` again contains an asynchronous call `http.get()` which performs an outbound HTTP request. If there is a current transactional context with an ongoing trace, Dynatrace OneAgent will transparently add a HTTP header containing a Dynatrace tag to this outbound request. The next tier - if instrumented with OneAgent - will continue this trace then. Without further intervention any transactional context would be lost between asynchronous invocation and a callback. Currently the only reliable way to pass over context information to a callback is called 'wrapping'.
583590

584591
**Example: Regular callbacks**
585592
Assume `some.asyncFunction()` in below sample causes loss of transactional context in OneAgent. To ensure that OneAgent correctly shows activities triggered inside the callback of this function `passContext()` can be used to create a closure preserving the transactional context active at call time of `some.asyncFunction()`.
@@ -650,14 +657,15 @@ SLAs apply according to the customer's support level.
650657

651658
see also [Releases](https://github.com/Dynatrace/OneAgent-SDK-for-NodeJs/releases)
652659

653-
|Version|Description |
654-
|:------|:-------------------------------------------|
655-
|1.4.1 |deprecate metrics-related types and APIs |
656-
|1.4.0 |add support for metrics (preview only) |
657-
|1.3.0 |add support to trace messaging |
658-
|1.2.2 |don't swallow exceptions |
659-
|1.2.1 |improve type definitions |
660-
|1.2.0 |add support for custom request attributes |
661-
|1.1.0 |add setResultData() for SQL Database tracer |
662-
|1.0.3 |early access to beta |
663-
|1.0.1 |Initial release |
660+
|Version|Description |
661+
|:------|:--------------------------------------------------------|
662+
|1.5.0 |deprecate old SDK Versions, add TraceContextInfo support |
663+
|1.4.1 |deprecate metrics-related types and APIs |
664+
|1.4.0 |add support for metrics (preview only) |
665+
|1.3.0 |add support to trace messaging |
666+
|1.2.2 |don't swallow exceptions |
667+
|1.2.1 |improve type definitions |
668+
|1.2.0 |add support for custom request attributes |
669+
|1.1.0 |add setResultData() for SQL Database tracer |
670+
|1.0.3 |early access to beta |
671+
|1.0.1 |Initial release |

package-lock.json

Lines changed: 35 additions & 14 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
{
22
"name": "@dynatrace/oneagent-sdk",
3-
"version": "1.4.1",
3+
"version": "1.5.0",
44
"description": "Node.js SDK for Dynatrace OneAgent",
55
"engines": {
6-
"node": ">= 6.0.0"
6+
"node": ">= 10.0.0"
77
},
88
"main": "./lib/Sdk.js",
99
"types": "./lib/Sdk.d.ts",
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
/*
2+
Copyright 2023 Dynatrace LLC
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
*/
16+
17+
"use strict";
18+
19+
// tslint:disable:no-console
20+
21+
// ----------------------------------------------------------------------------
22+
const Sdk = require("@dynatrace/oneagent-sdk");
23+
const Api = Sdk.createInstance();
24+
25+
// ----------------------------------------------------------------------------
26+
if (Api.getCurrentState() !== Sdk.SDKState.ACTIVE) {
27+
console.error("W3CTraceContextApiSample: SDK is not active!");
28+
}
29+
30+
// install logging callbacks
31+
Api.setLoggingCallbacks({
32+
warning: (msg) => console.error("W3CTraceContextApiSample SDK warning: " + msg),
33+
error: (msg) => console.error("W3CTraceContextApiSample SDK error: " + msg)
34+
});
35+
36+
// ----------------------------------------------------------------------------
37+
const http = require("http");
38+
39+
// ----------------------------------------------------------------------------
40+
const server = http.createServer(function onRequest(req, res) {
41+
// if a OneAgent is available this will return a TraceContextInfo where `isValid` is `true`.
42+
// traceId and spanId will have non-default valid values
43+
const localTC = Api.getTraceContextInfo();
44+
console.log(`valid: ${localTC.isValid}, traceid: ${localTC.traceid}, spanid: ${localTC.spanid}`);
45+
}).listen(8001).on("listening", () => setInterval(() => http.get("http://localhost:" + server.address().port), 500));
46+
47+
// this will return a TraceContextInfo where `isValid` is false and the traceId and spanId have their respective default values
48+
const currentTC = Api.getTraceContextInfo();
49+
console.log(`valid: ${currentTC.isValid}, traceid: ${currentTC.traceid}, spanid: ${currentTC.spanid}`);
50+
51+
setTimeout(() => process.exit(0), 120000);

samples/package.json

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
{
22
"name": "sdksamples",
3-
"version": "1.4.1",
3+
"version": "1.5.0",
44
"description": "Samples showing usage of OneAgent SDK",
55
"engines": {
6-
"node": ">= 8.0.0"
6+
"node": ">= 10.0.0"
77
},
88
"scripts": {
99
"remotecall": "node RemoteCall/OutgoingRemoteCallSample.js",
@@ -12,7 +12,7 @@
1212
"messaging": "node Messaging/MessagingSample.js"
1313
},
1414
"dependencies": {
15-
"@dynatrace/oneagent-sdk": "1.4.1"
15+
"@dynatrace/oneagent-sdk": "1.5.0"
1616
},
1717
"repository": {
1818
"type": "git",

0 commit comments

Comments
 (0)