{"id":20317564,"url":"https://github.com/dynatrace/oneagent-sdk-for-nodejs","last_synced_at":"2025-08-18T04:32:42.720Z","repository":{"id":41280916,"uuid":"117104869","full_name":"Dynatrace/OneAgent-SDK-for-NodeJs","owner":"Dynatrace","description":"Enables custom tracing of Node.js applications in Dynatrace","archived":false,"fork":false,"pushed_at":"2024-06-17T07:12:35.000Z","size":197,"stargazers_count":17,"open_issues_count":0,"forks_count":5,"subscribers_count":20,"default_branch":"main","last_synced_at":"2024-10-16T01:31:38.796Z","etag":null,"topics":["agent","apm","data-ingestion","dev-program","dynatrace","oneagent","sdk","sdk-nodejs"],"latest_commit_sha":null,"homepage":"https://www.dynatrace.com/support/help/extend-dynatrace/oneagent-sdk/what-is-oneagent-sdk/","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Dynatrace.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2018-01-11T13:35:53.000Z","updated_at":"2024-09-22T22:44:16.000Z","dependencies_parsed_at":"2024-06-18T21:21:24.224Z","dependency_job_id":"8181f07b-94a2-4e63-b4f6-a15d51c4d3e2","html_url":"https://github.com/Dynatrace/OneAgent-SDK-for-NodeJs","commit_stats":{"total_commits":32,"total_committers":10,"mean_commits":3.2,"dds":0.65625,"last_synced_commit":"4152e094d3e1f0faabafb1dc476a2b6e92cd573a"},"previous_names":[],"tags_count":10,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Dynatrace%2FOneAgent-SDK-for-NodeJs","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Dynatrace%2FOneAgent-SDK-for-NodeJs/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Dynatrace%2FOneAgent-SDK-for-NodeJs/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Dynatrace%2FOneAgent-SDK-for-NodeJs/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Dynatrace","download_url":"https://codeload.github.com/Dynatrace/OneAgent-SDK-for-NodeJs/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":230202357,"owners_count":18189437,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["agent","apm","data-ingestion","dev-program","dynatrace","oneagent","sdk","sdk-nodejs"],"created_at":"2024-11-14T18:33:19.739Z","updated_at":"2024-12-18T01:09:53.166Z","avatar_url":"https://github.com/Dynatrace.png","language":"TypeScript","readme":"# Dynatrace OneAgent SDK for Node.js\n\nThis SDK allows Dynatrace customers to instrument Node.js applications. This is useful to add service level insight for modules currently not directly supported by [Dynatrace OneAgent](https://www.dynatrace.com/technologies/nodejs-monitoring/) out-of-the-box.\n\nThis is the official Node.js implementation of the [Dynatrace OneAgent SDK](https://github.com/Dynatrace/OneAgent-SDK).\n\n## Table of Contents\n\n* [Package contents](#package-contents)\n* [Requirements](#requirements)\n* [Integration](#integration)\n  * [Installation](#installation)\n  * [Troubleshooting](#troubleshooting)\n* [API Concepts](#api-concepts)\n  * [OneAgentSDK object](#oneagentsdk-object)\n  * [Tracers](#tracers)\n* [Features](#features)\n  * [Trace incoming and outgoing remote calls](#trace-incoming-and-outgoing-remote-calls)\n  * [Trace messaging](#trace-messaging)\n  * [Trace SQL database requests](#trace-sql-database-requests)\n  * [Set custom request attributes](#set-custom-request-attributes)\n  * [Metrics (deprecated)](#metrics)\n  * [Trace context](#trace-context)\n* [Administrative Apis](#administrative-apis)\n  * [Current SDK state](#current-sdk-state)\n  * [Set callbacks for logging](#set-callbacks-for-logging)\n* [Constants](#constants)\n  * [Channel type](#channel-type)\n  * [Database vendors](#database-vendors)  \n  * [Message destination type](#message-destination-type)\n  * [Message system vendors](#message-system-vendors)\n* [Pass Context](#pass-context)\n* [Further reading](#further-readings)\n* [Help \u0026 Support](#help--support)\n* [Release notes](#release-notes)\n\n## Package contents\n\n* `samples`: sample applications, which demonstrates the usage of the SDK. See [readme](samples/README.md) inside the samples directory for more details\n* `src`: source code of the SDK\n* `test`: unit tests\n* `LICENSE`: license under which the whole SDK and sample applications are published\n\n## Requirements\n\n* 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\n* Dynatrace OneAgent (required versions see below)\n* The OneAgent SDK is not supported on serverless code modules, including those for AWS Lambda.\n  In these scenarios consider using [OpenTelemetry](https://www.dynatrace.com/support/help/shortlink/opentel-lambda) instead.\n\n|OneAgent SDK for Node.js|Required OneAgent version|Support status                           |\n|:-----------------------|:------------------------|:----------------------------------------|\n|1.5.x                   |\u003e=1.259                  |Supported                                |\n|1.4.x                   |\u003e=1.179                  |Supported                                |\n|1.3.x                   |\u003e=1.165                  |Deprecated with support ending 2023-08-01|\n|1.2.x                   |\u003e=1.145                  |Deprecated with support ending 2023-08-01|\n|1.1.x                   |\u003e=1.143                  |Deprecated with support ending 2023-08-01|\n|1.0.x                   |\u003e=1.137                  |Deprecated with support ending 2023-08-01|\n\n## Integration\n\nUsing this module should not cause any errors if no OneAgent is present (e.g. in testing).\n\nMake sure that this module is loaded after Dynatrace OneAgent.\n\n### Installation\n\n`npm install --save @dynatrace/oneagent-sdk`\n\n### Troubleshooting\n\nIf 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.\n\nVerify that OneAgent is working as intended (see [Dynatrace OneAgent](https://www.dynatrace.com/technologies/nodejs-monitoring/)).\n\nYou should ensure that you have set [LoggingCallbacks](#set-callbacks-for-logging).\n\nOneAgent 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.\n\n## API Concepts\n\nCommon concepts of the Dynatrace OneAgent SDK are explained in the [Dynatrace OneAgent SDK repository](https://github.com/Dynatrace/OneAgent-SDK).\n\n### OneAgentSDK object\n\nThe 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.\n\n```js\nconst Sdk = require('@dynatrace/oneagent-sdk');\nconst Api = Sdk.createInstance();\n```\n\n### Tracers\n\nThe life-cycle of a tracer is as follows:\n\n1. 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.\n1. Start the trace which in turn invokes and times the given handler function.\n1. For outgoing taggable traces fetch a Dynatrace tag and include it to the message being sent.\n1. Optionally mark the traced operation as failed via a call to `error()`\n1. End the trace once the operation is done. For outgoing traces you may pass a callback to be included in this trace.\n\nEach tracer offers following methods:\n\n* `start(handler, ...args)` Start a trace and calls the given handler function with the provides arguments. Returns the return value of handler.\n* `startWithContext(handler, thisObj, ...args)` Like `start()` but allows to specify the `this` context for the call to handler.\n* `error(err)` Mark trace as failed and attach an error object. Shall be call at max once per trace. Does not end the trace! Returns the tracer itself.\n* `end()` End the trace.\n\nTracers for outgoing requests additionally offer enhanced methods to end a trace which allow to include the follow-up callback to the PurePath of this trace.\n\n* `end(callback, ...args)` End the trace like `end()` but additionally calls the passed callback with given arguments. The return value from callback is forwarded to caller of `end`.\n* `endWithContext(callback, thisObj, ...args)` like `end()` above but with the possibility to specify the `this` context for the callback.\n\nTracers for outgoing taggable requests additionally offer following methods to get a _dynatrace tag_ to be sent to remote service after the trace was started:\n\n* `getDynatraceStringTag()` returns a Dynatrace tag encoded as `string`\n* `getDynatraceByteTag()` returns a Dynatrace tag binary encoded as `Buffer`\n\nThis 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.\nOn 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.\n\nThe 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.\n\nPlease note that OneAgent uses the name of the given functions in `start()` and `end()` to name PurePath nodes. Therefore we recommend to choose named functions over anonymous functions to give you higher quality traces.\n\n## Features\n\nThe feature sets differ slightly with each language implementation. More functionality will be added over time, see [Planned features for OneAgent SDK](https://community.dynatrace.com/t5/Feedback-channel/Planned-features-for-OneAgent-SDK/m-p/147331) for details on upcoming features.\n\nA more detailed specification of the features can be found in [Dynatrace OneAgent SDK](https://github.com/Dynatrace/OneAgent-SDK).\n\n|Feature                                  |Required OneAgent SDK for Node.js version|\n|:------                                  |:----------------------------------------|\n|Trace incoming and outgoing remote calls |\u003e=1.0.1                                  |\n|Trace SQL database requests              |\u003e=1.0.1                                  |\n|Set result data on SQL database requests |\u003e=1.1.0                                  |\n|Set custom request attributes            |\u003e=1.2.0                                  |\n|Trace Messaging                          |\u003e=1.3.0                                  |\n|Metrics (deprecated)                     |\u003e=1.4.0                                  |\n|Trace context                            |\u003e=1.5.0                                  |\n\n### Trace incoming and outgoing remote calls\n\n#### Trace outgoing remote calls\n\nAn outgoing remote call is traced by calling `traceOutgoingRemoteCall()` passing an object with following properties:\n\n* `serviceMethod` Mandatory - a string holding the name of the called remote method\n* `serviceName` Mandatory - a string holding the name of the remote service\n* `serviceEndpoint` Mandatory - a string describing the logical endpoint of the remote service. In case of a clustered/load balanced service, the `serviceEndpoint` represents the common logical endpoint (e.g. registry://staging-environment/myservices/serviceA) whereas the ConnectionInfo describes the actual communication endpoint. As such a single serviceEndpoint can have many connections.\n* `protocolName` Optional - a string describing the protocol used (e.g. Protobuf, GIOP,...), only for display purposes\n\nAdditionally it holds following properties describing the connection to the remote service. Depending on the connection type the corresponding property/properties shall be set.\nIf the specific information like host/socketPath/... is not available, the property `channelType` shall be set.\n\n* `host` A string specifying the hostname/IP of the server side in case of a TCP/IP connection is used (note that OneAgent may try to resolve the hostname)\n* `port` The TCP/IP port (optional)\n* `socketPath` A string specifying the UNIX domain socket file\n* `pipeName` A string specifying the name of the Pipe\n* `channelType` Specifies the protocol used as communication channel (e.g. TCP/IP, IN_PROCESS,... ). Valid values are available via [ChannelType](#channel-type))\n\nThe result of `traceOutgoingRemoteCall()` is a tracer object to be used for further operations related to this trace (see [Tracers](#tracers) for details).\nAs an outgoing remote call is _taggable_ a Dynatrace tag shall be created from tracer after it has been started and embedded to the remote call message content.\n\n**Example (see [OutgoingRemoteCallSample.js](samples/RemoteCall/OutgoingRemoteCallSample.js) for more details):**\n\n```js\n// Issue a traced outgoing remote call\nasync function tracedOutgoingRemoteCall(method, data) {\n  const tracer = Api.traceOutgoingRemoteCall({\n    serviceEndpoint: \"ChildProcess\",\n    serviceMethod: method,  // the name of the remote method called\n    serviceName: \"StringManipulator\",\n    channelType: Sdk.ChannelType.NAMED_PIPE\n  });\n\n  try {\n    // start tracer, get dynatrace tag and trigger sending via doOutgoingRemoteCall()\n    return await tracer.start(function triggerTaggedRemoteCall() {\n      // getting a tag from tracer needs to be done after start()\n      const dtTag = tracer.getDynatraceStringTag();\n      // now trigger the actual remote call\n      return doOutgoingRemoteCall(method, data, dtTag);\n    });\n  } catch (e) {\n    tracer.error(e);\n    throw e;\n  } finally {\n    tracer.end();\n  }\n}\n```\n\n#### Trace incoming remote calls\n\nAn incoming remote call is traced by calling `traceIncomingRemoteCall()` passing an object with following properties:\n\n* `serviceMethod` Mandatory - a string holding the name of the called remote method\n* `serviceName` Mandatory - a string holding the name of the remote service\n* `serviceEndpoint` Mandatory - a string describing the logical deployment endpoint of the remote service on server side\n* `protocolName` Optional - a string describing the protocol used (e.g. Protobuf, GIOP,...), only for display purposes\n* `dynatraceTag` - a `string` or `Buffer` holding the received Dynatrace tag received\n\nThe result of this call is a tracer object to be used for further operations related to this trace (see [Tracers](#tracers)).\n\n**Example (see [IncomingRemoteCallSample.js](samples/RemoteCall/IncomingRemoteCallSample.js) for more details):**\n\n```js\n// trace and handle incoming messages\nasync function tracedMessageHandler(message) {\n  const tracer = Api.traceIncomingRemoteCall({\n    serviceEndpoint: \"ChildProcess\",\n    serviceMethod: message.method,\n    serviceName: \"StringManipulator\",\n    dynatraceTag: message.traceTag,   // extract and set the dynatrace tag\n    protocolName: \"Json\"              // optional\n  });\n\n  try {\n    // start tracer and trigger actual message processing via processMessage(message)\n    const result = await tracer.start(processMessage, message);\n\n    // send result calculated by processMessage() back to caller\n    process.send({ result: result, id: message.id });\n\n    // end tracer\n    tracer.end();\n  } catch (e) {\n    // send error back\n    process.send({ error: e.message, id: message.id });\n\n    // set error and end tracer\n    tracer.error(e).end();\n  }\n}\n```\n\n### Trace Messaging\n\n#### Trace outgoing messages\n\nAn outgoing message is traced by calling `traceOutgoingMessage()` passing an object with following properties:\n\n* `vendorName` Mandatory - a string holding the messaging system vendor name (e.g. RabbitMq, Apache Kafka, ...), can be a user defined name. If possible use a constant defined in [MessageSystemVendor](#message-system-vendors).\n* `destinationName` Mandatory - a string holding the destination name (e.g. queue name, topic name).\n* `destinationType` Mandatory - specifies the type of the destination. Valid values are available via [MessageDestinationType](#message-destination-type)\n\nAdditionally it holds following properties describing the connection to the messaging service. Depending on the connection type the corresponding property/properties shall be set.\nIf the specific information like host/socketPath/... is not available, the property `channelType` shall be set.\n\n* `host` A string specifying the hostname/IP of the server side in case of a TCP/IP connection is used (note that OneAgent may try to resolve the hostname)\n* `port` The TCP/IP port (optional)\n* `socketPath` A string specifying the UNIX domain socket file\n* `pipeName` A string specifying the name of the Pipe\n* `channelType` Specifies the protocol used as communication channel (e.g. TCP/IP, IN_PROCESS,... ). Valid values are available via [ChannelType](#channel-type))\n\nThe result of `traceOutgoingMessage()` is a tracer object to be used for further operations related to this trace (see [Tracers](#tracers) for details).\nAs an outgoing message is _taggable_ a Dynatrace tag shall be created from tracer after it has been started and embedded to the message content.\n\nBesides the common APIs for outgoing tracers this tracer offers the additional methods `setVendorMessageId()` and `setCorrelationId()` which may be used to set more details about the message sent. Both APIs receive a `string` as parameter to pass the `correlationId` or `vendorMessageId` provided by messaging system.\n\n**Example (see [MessagingSample.js](samples/Messaging/MessagingSample.js) for more details):**\n\n```js\nfunction traceOutgoingMessage(name, data, corrId) {\n  // create a tracer instance and start the trace\n  const tracer = Api.traceOutgoingMessage(systemInfo);\n  tracer.start(function sendTaggedMessage() {\n    // getting a tag from tracer needs to be done after start()\n    const dtTag = tracer.getDynatraceStringTag();\n    try {\n      // now trigger the actual sending of the message\n      const messageId = sendMessage(name, data, corrId, dtTag);\n\n      // optional: set correlationId/vendorMessageId if present/relevant\n      tracer.setCorrelationId(corrId).setVendorMessageId(`${messageId}`);\n    } catch (e) {\n      tracer.error(e);\n      throw e;\n    } finally {\n      tracer.end();\n    }\n  });\n}\n```\n\n#### Trace incoming messages\n\nAn incoming message is traced by calling `traceIncomingMessage()` passing an object with following properties:\n\n* `vendorName` Mandatory - a string holding the messaging system vendor name (e.g. RabbitMq, Apache Kafka, ...), can be a user defined name. If possible use a constant defined in [MessageSystemVendor](#message-system-vendors).\n* `destinationName` Mandatory - a string holding the destination name (e.g. queue name, topic name).\n* `destinationType` Mandatory - specifies the type of the destination. Valid values are available via [MessageDestinationType](#message-destination-type)\n* `dynatraceTag` - a string or Buffer holding the received Dynatrace tag received\n\nAdditionally it holds following properties describing the connection to the messaging service. Depending on the connection type the corresponding property/properties shall be set.\nIf the specific information like host/socketPath/... is not available, the property `channelType` shall be set.\n\n* `host` A string specifying the hostname/IP of the server side in case of a TCP/IP connection is used (note that OneAgent may try to resolve the hostname)\n* `port` The TCP/IP port (optional)\n* `socketPath` A string specifying the UNIX domain socket file\n* `pipeName` A string specifying the name of the Pipe\n* `channelType` Specifies the protocol used as communication channel (e.g. TCP/IP, IN_PROCESS,... ). Valid values are available via [ChannelType](#channel-type))\n\nThe result of `traceIncomingMessage()` is a tracer object to be used for further operations related to this trace (see [Tracers](#tracers) for details).\n\nBesides the common APIs for incoming tracers this tracer offers the additional methods `setVendorMessageId()` and `setCorrelationId()` which may be used to set more details about the message sent. Both APIs receive a `string` as parameter to pass the `correlationId` or `vendorMessageId` provided by messaging system.\n\n**Example (see [MessagingSample.js](samples/Messaging/MessagingSample.js) for more details):**\n\n```js\nfunction traceIncomingMessage(msg) {\n  // create a tracer instance and start the trace, ensure dynatraceTag is set\n  const startData = Object.assign({ dynatraceTag: msg.meta.dtTag }, systemInfo);\n  const tracer = Api.traceIncomingMessage(startData);\n  tracer.start(function processMessage(done) {\n    // optional: set correlationId/vendorMessageId if present/relevant\n    tracer.setCorrelationId(msg.meta.corrId).setVendorMessageId(`${msg.meta.msgId}`);\n\n    // do whatever needed with the message, simulated via nextTick() here\n    process.nextTick(done);\n  }, function onDone(err) {\n    if (err) {\n      tracer.error();\n    }\n    tracer.end();\n  });\n}\n```\n\n### Trace SQL database requests\n\nA SQL database request is traced by calling `traceSQLDatabaseRequest()` which requires a database info object as first argument and an object with request specific data as second parameter.\n\nThe database info is an object which usually doesn't change during runtime. It holds following properties:\n\n* `name` Mandatory - a string defining the name of the database\n* `vendor` Mandatory - a string holding the database vendor name (e.g. Oracle, MySQL, ...), can be a user defined name. If possible use a constant defined in [DatabaseVendor](#database-vendors)\n\nAdditionally, it holds following properties describing the connection to the database. Depending on the actual connection used the corresponding property/properties shall be set.\nIf the specific information like host/socketPath/... is not available, the property channelType shall be set.\n\n* `host` A string specifying the hostname/IP of the server side in case of a TCP/IP connection is used (note that OneAgent may try to resolve the hostname)\n* `port` The TCP/IP port (optional)\n* `socketPath` A string specifying the UNIX domain socket file\n* `pipeName` A string specifying the name of the pipe\n* `channelType` Specifies the protocol used as communication channel (e.g. TCP/IP, IN_PROCESS,... ). Valid values are available via [ChannelType](#channel-type).\n\nThe second argument holds data describing the concrete operation and holds following properties:\n\n* `statement` Mandatory - a string holding the SQL statement to be sent to database.\n\nThe result of `traceSQLDatabaseRequest()` is a tracer object to be used for further operations related to this trace (see [Tracers](#tracers) for details).\n\nBesides the common APIs for outgoing tracers this tracer offers the additional method `setResultData()` which may be used to set details about the result of the database request.\nIt receives an object with following properties:\n\n* `rowsReturned` Optional - Number of rows returned by this traced database request. Only positive values are allowed\n* `roundTripCount` Optional - Count of round-trips that took place. Only positive values are allowed\n\nPlease 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).\n\n**Example (see [DatabaseRequestSample.js](samples/Database/DatabaseRequestSample.js) for more details):**\n\n```js\n// Static info describing the database\nconst dbInfo = {\n  name: dbConfig.database,\n  vendor: Sdk.DatabaseVendor.MARIADB,\n  host: dbConfig.host,\n  port: dbConfig.port\n};\n\n// Issue a traced SQL database request\nfunction tracedSqlDatabaseRequest(sql, clientCb) {\n  // create a SQL database tracer\n  const tracer = Api.traceSQLDatabaseRequest(dbInfo, {\n    statement: sql\n  });\n\n  // start tracer, calls connection.query(sql, cb) with connection set as this in query()\n  tracer.startWithContext(connection.query, connection, sql, (err, results, fields) =\u003e {\n    if (err) {\n      // set the error on the tracer\n      tracer.error(err);\n    } else {\n      // optionally set result data\n      tracer.setResultData({\n        rowsReturned: 15,\n        roundTripCount: 32\n      });\n    }\n    // end the tracer and call client callback forwarding results\n    tracer.end(clientCb, err, results, fields);\n  });\n}\n```\n\n### Set custom request attributes\n\nThe API `addCustomRequestAttribute()` adds a custom request attribute to the currently traced service call. There is no reference to a tracer needed as OneAgent SDK will select the current open trace. This may be a trace created by SDK or\na trace created by built in sensors of OneAgent. The API may be called several times to add more attributes. If the same attribute key is set several times all values will be recorded.\n\n`addCustomRequestAttribute()` takes two arguments:\n\n* `key` Mandatory - a string specifying the name of the attribute\n* `value` Mandatory - a string or number specifying the attribute value\n\n**Example (see [CustomRequestAttributesSample.js](samples/CustomRequestAttributes/CustomRequestAttributesSample.js) for more details):**\n\n```js\nApi.addCustomRequestAttribute(\"fooAttribute\", \"bar\");\nApi.addCustomRequestAttribute(\"barAttribute\", 15.34);\n```\n\n\u003ca name=\"metrics\"\u003e\u003c/a\u003e\n\n### Metrics (deprecated)\n\n\u003e **Note**: The metrics API was part of a\n\u003e [Dynatrace preview program](https://www.dynatrace.com/support/help/whats-new/preview-and-early-adopter-releases/)\n\u003e that has been **discontinued**. All metrics-related APIs and types described below\n\u003e have been **deprecated** and will be removed in a future release.\n\u003e The [Metric ingestion](https://www.dynatrace.com/support/help/how-to-use-dynatrace/metrics/metric-ingestion/)\n\u003e page provides further information on how to replace these APIs and how to report\n\u003e metrics data from now on.\n\nThe SDK supports two **metric value types**: `Integer` and `Float` (double precision floating point).\nYou should prefer integer metrics as they are more efficient, unless the loss of precision is unacceptable (but\nconsider using a different unit, e.g. integer microseconds instead of floating point seconds).\n\nThere are these different **kinds of metrics**:\n\n* **Counter**: For all metrics that are counting something like sent/received bytes to/from network.\nCounters should only be used when tracking things in flow, as opposed to state. It reports the `sum`\nonly and is the most lightweight metric kind.\n* **Gauge**: For metrics that periodically sample a current state, e.g. temperatures, total number\nof bytes stored on a disk. Gauges report a `min`, `max` and `average` value (but no `sum`).\n* **Statistics**: For event-driven metrics like the packet size of a network interface. The most\nheavyweight metric. Reports `min`, `max`, `average` and `count`.\n\nEach combination of metric value type and kind has its own create-function, named `create\u003cValueType\u003e\u003cMetricKind\u003eMetric`.\n\nWhen creating a metric following information needs to be provided:\n\n* `metricName` Mandatory - a string identifying the metric. Maximum size is 100 bytes.\nAlthough it is not recommended, you may create multiple metric instances with the same name, as long as you use the same creation function (metric value type and kind are the same) and the same options.\nOtherwise, using the same metric name multiple times is an error. All metrics with the same name will be aggregated together as if you used only one metric instance.\n\n* `MetricOptions` Optional - an `object` with following properties:\n  * `unit` Optional - a string that will be displayed when browsing for metrics in the Dynatrace UI.\n  * `dimensionName` Optional - a `string` specifying the name of the dimension added to the metric.\n  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\".\n\n### Trace context\nThe implementation follows the specification from [Dynatrace OneAgent SDK - Trace Context](https://github.com/Dynatrace/OneAgent-SDK#tracecontext).\nFor an usage example refer to [W3CTraceContextApiSample.js](samples/TraceContext/W3CTraceContextApiSample.js).\n\n### Administrative APIs\n\n#### Current SDK state\n\nThe method `getCurrentState()` returns the current status of SDK. Valid values are available via constant object `SDK.SDKState`:\n\n* `ACTIVE` SDK is connected to OneAgent and capturing data.\n* `TEMPORARILY_INACTIVE` SDK is connected to OneAgent, but capturing is disabled. It is good practice to skip creating SDK transactions to save resources. The SDK state should be checked regularly as it may change at every point in time.\n* `PERMANENTLY_INACTIVE` SDK isn't connected to OneAgent, so it will never capture data. This SDK state will never change during the lifetime of the process. It is good practice to never call any SDK API to save resources.\n\n#### Set callbacks for logging\n\nThe method `setLoggingCallback(callbacks)` can be used to set callbacks for warning and error logs. A logging callback receives a string as argument. As parameter pass an object with following properties:\n\n* `warning` Optional - a function accepting a string as parameter called to pass warning messages\n* `error` Optional - a function accepting a string as parameter called to pass error messages\n\nOmitting a callback property will uninstall a previous installed callback.\n\n```js\nApi.setLoggingCallbacks({\n  warning: (msg) =\u003e console.error(\"DatabaseRequestSample SDK warning: \" + msg),\n  error: (msg) =\u003e console.error(\"DatabaseRequestSample SDK error: \" + msg),\n});\n```\n\n### Constants\n\n#### Channel type\n\nThe values of constant `ChannelType` specify the type of the transport channel used. Following values are provided:\n\n* `TCP_IP` Communication via TCP/IP\n* `UNIX_DOMAIN_SOCKET` Communication via UNIX domain socket\n* `NAMED_PIPE` Communication via named pipe\n* `IN_PROCESS` Communication is some mechanism within current process (e.g. via files,...)\n* `OTHER` To be used for any other channel type\n\n#### Database vendors\n\nThe values of constant `DatabaseVendor` may be used as input for `traceSQLDatabaseRequest()`. Following values are provided:\n\n* `APACHE_HIVE`\n* `CLOUDSCAPE`\n* `HSQLDB`\n* `PROGRESS`\n* `MAXDB`\n* `HANADB`\n* `INGRES`\n* `FIRST_SQL`\n* `ENTERPRISE_DB`\n* `CACHE`\n* `ADABAS`\n* `FIREBIRD`\n* `DB2`\n* `DERBY_CLIENT`\n* `DERBY_EMBEDDED`\n* `FILEMAKER`\n* `INFORMIX`\n* `INSTANT_DB`\n* `INTERBASE`\n* `MYSQL`\n* `MARIADB`\n* `NETEZZA`\n* `ORACLE`\n* `PERVASIVE`\n* `POINTBASE`\n* `POSTGRESQL`\n* `SQLSERVER`\n* `SQLITE`\n* `SYBASE`\n* `TERADATA`\n* `VERTICA`\n* `CASSANDRA`\n* `H2`\n* `COLDFUSION_IMQ`\n* `REDSHIFT`\n* `COUCHBASE`\n\n#### Message destination type\n\nThe values of constant `MessageDestinationType` specify the type of the message destination used. Following values are provided:\n\n* `QUEUE`\n* `TOPIC`\n\n#### Message system vendors\n\nThe values of constant `MessageSystemVendor` may be used as input for `traceIncomingMessage()` and `traceOutgoingMessage()`. Using these constants ensures that services captured by OneAgentSDK are handled the same way as traced via built-in sensors. Following values are provided:\n\n* `HORNETQ`\n* `ACTIVE_MQ`\n* `RABBIT_MQ`\n* `ARTEMIS`\n* `WEBSPHERE`\n* `MQSERIES_JMS`\n* `MQSERIES`\n* `TIBCO`\n* `KAFKA`\n\n### Pass Context\n\nDynatrace transparently wraps *supported* libraries to add context information. For every yet *unsupported* module `passContext()` can be used to provide transactional context to callbacks.\n\n**What is transactional context?**\n\n[Dynatrace patented PurePath Technology®](https://www.dynatrace.com/en_us/application-performance-management/products/purepath-technology.html) captures timing and code level context for *all* transactions, end-to-end, from user click, across all tiers, to the database of record and back. Technically this means that Dynatrace adds transactional context to any inbound and outbound function calls of an application.\n\n**What does this mean for Node.js applications?**\n\nNode.js is single threaded - its control flow is based on events and asynchronous callbacks.\n\nLet's look at an example for finding a document with mongoDB:\n\n```js\nfunction callback(err, document) {\n  console.log(document.name);\n\n  http.get('https://some-api.xyz/service', (res) =\u003e {});\n    // ^^^                                 °°°°°°°°°°°\n    // Asynchronous call                   Asynchronous callback\n}\n\ncollection.findOne({_id: doc_id}, callback);\n        // ^^^^^^^                °°°°°°°°\n        // Asynchronous call      Asynchronous callback\n\n```\n\nAfter `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'.\n\n**Example: Regular callbacks**\nAssume `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()`.\n\n```js\nconst Api = require('@dynatrace/oneagent-sdk').createInstance();\n\nsome.asyncFunction(someParam, Api.passContext(function(err, result) {\n  // Context is preserved\n  http.get('https://some-api.xyz/service', Api.passContext((res) =\u003e {\n    // other activity, e.g. outgoing web requests,...\n  }));\n}));\n```\n\n**Important: The wrapping via `passContext()` needs to happen call time of the corresponding sync call**\n\n```js\n// This will *NOT* work as transactional context at call time of some.asyncFunction() is not preserved\n// instead the transactional context at definition of doSomething() is preserved which is not\n// related to the relevant transaction triggered by calling some.asyncFunction().\nconst wrappedFunction = dta.passContext(someFunction);\nfunction doSomething() {\n  some.asyncFunction('someParam', wrappedFunction);\n}\n\n// This works, passContext() is called at invocation time of some.asyncFunction()\nfunction doSomething() {\n  some.asyncFunction('someParam', dta.passContext(someFunction));\n}\n```\n\n## Further readings\n\n* [What is the OneAgent SDK?](https://www.dynatrace.com/support/help/extend-dynatrace/oneagent-sdk/what-is-oneagent-sdk/) in the Dynatrace documentation\n* [Feedback \u0026 Roadmap thread in dynatrace community](https://community.dynatrace.com/t5/Feedback-channel/Planned-features-for-OneAgent-SDK/m-p/147331)\n* [Dynatrace OneAgent SDK for Node.js: Extend end-to-end visibility](https://www.dynatrace.com/news/blog/dynatrace-oneagent-sdk-for-node-js-extend-end-to-end-visibility/)\n\n## Help \u0026 Support\n\n**Support policy**\n\nThe Dynatrace OneAgent SDK for Node.js has GA status. The features are fully supported by Dynatrace.\n\nFor detailed support policy see [Dynatrace OneAgent SDK help](https://github.com/Dynatrace/OneAgent-SDK#help).\n\n### Get Help\n\n* Ask a question in the [product forums](https://community.dynatrace.com/)\n* Read the [product documentation](https://www.dynatrace.com/support/help)\n\n### Open a [GitHub issue](https://github.com/Dynatrace/OneAgent-SDK-for-NodeJs/issues) to\n\n* Report minor defects, minor items or typos\n* Ask for improvements or changes in the SDK API\n* Ask any questions related to the community effort\n\nSLAs don't apply for GitHub tickets\n\n### Customers can open a ticket on the [Dynatrace support portal](https://dt-url.net/lb626l9) to\n\n* Get support from the Dynatrace technical support engineering team\n* Manage and resolve product related technical issues\n\nSLAs apply according to the customer's support level.\n\n## Release Notes\n\nsee also [Releases](https://github.com/Dynatrace/OneAgent-SDK-for-NodeJs/releases)\n\n|Version|Description                                              |\n|:------|:--------------------------------------------------------|\n|1.5.0  |deprecate old SDK Versions, add TraceContextInfo support |\n|1.4.1  |deprecate metrics-related types and APIs                 |\n|1.4.0  |add support for metrics (preview only)                   |\n|1.3.0  |add support to trace messaging                           |\n|1.2.2  |don't swallow exceptions                                 |\n|1.2.1  |improve type definitions                                 |\n|1.2.0  |add support for custom request attributes                |\n|1.1.0  |add setResultData() for SQL Database tracer              |\n|1.0.3  |early access to beta                                     |\n|1.0.1  |Initial release                                          |\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdynatrace%2Foneagent-sdk-for-nodejs","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdynatrace%2Foneagent-sdk-for-nodejs","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdynatrace%2Foneagent-sdk-for-nodejs/lists"}