# @adobe/openwhisk-newrelic

> Library for gathering metrics for Apache OpenWhisk actions and sending them to NewRelic

Latest version **2.0.1** (published 2024-11-14) · Apache-2.0 license · 0 weekly downloads

## Install

```sh
npm install @adobe/openwhisk-newrelic
pnpm add @adobe/openwhisk-newrelic
yarn add @adobe/openwhisk-newrelic
bun add @adobe/openwhisk-newrelic
```

## Health

**Score 25/100 (F)** — status: maintenance-mode.

Positive: no vulnerabilities.

Warnings: low downloads; no types; no esm support.

Negative: stale; low maintenance score.

## Facts

| | |
|---|---|
| Version | 2.0.1 |
| Published | 2024-11-14 |
| First published | 2020-05-01 |
| Weekly downloads | 0 |
| License | Apache-2.0 |
| TypeScript types | none |
| Module format | CommonJS |
| Dependencies | 4 |
| Unpacked size | 78.8 KB |
| Known vulnerabilities | 0 |
| Install scripts | no |
| GitHub stars | 4 |
| Author | Adobe Systems Inc. |
| Maintainers | mhaack, amol-anand, doten, stopp-adobe, dylandepass, djaeggi, adobehalls, fullcolorcoder, marbec, tripod, garthdb, lazd, adobe-admin, patrickfulton, trieloff, shazron, krisnye, dcpfsdk, natebaldwin, devongovett, aspro83, symanovi, dpfister, stefan-guggisberg, korra, rofe, kptdobe |
| Keywords | scripts, openwhisk, new relic, library, metrics, adobe |

## Links

- npm: https://www.npmjs.com/package/@adobe/openwhisk-newrelic
- Repository: https://github.com/adobe/node-openwhisk-newrelic
- Homepage: https://github.com/adobe/node-openwhisk-newrelic#readme
- Issues: https://github.com/adobe/node-openwhisk-newrelic/issues
- npm.io page: https://npm.io/package/@adobe/openwhisk-newrelic

## Dependencies (4)

- [debug](https://npm.io/package/debug.md) ^4.3.4
- [dotenv](https://npm.io/package/dotenv.md) ^16.0.2
- [cls-hooked](https://npm.io/package/cls-hooked.md) ^4.2.2
- [node-fetch](https://npm.io/package/node-fetch.md) ^2.6.7

## Recent versions

- 2.0.1 (latest) — 2024-11-14
- 2.0.0 — 2022-09-21
- 1.0.8 — 2022-08-08
- 1.0.7 — 2022-06-30
- 1.0.6 — 2022-06-23
- 1.0.5 — 2022-06-22
- 1.0.4 — 2022-06-22
- 1.0.3 — 2022-02-16
- 1.0.2 — 2020-08-20
- 1.0.1 — 2020-05-05
- 1.0.0 — 2020-05-01

## README

<!--- when a new release happens, the VERSION and URL in the badge have to be manually updated because it's a private registry --->
[![Version](https://img.shields.io/npm/v/@adobe/openwhisk-newrelic.svg)](https://npmjs.org/package/@adobe/openwhisk-newrelic)

# node-openwhisk-newrelic

Library for gathering metrics from Apache OpenWhisk actions and sending them to New Relic Insights. 

## NewRelic Insert API JSON format guidelines

Reference: <https://docs.newrelic.com/docs/insights/insights-data-sources/custom-data/send-custom-events-event-api>

* `eventType` required
* `timestamp` Unix epoch timestamp either in seconds or milliseconds
* Key-value pairs with `float` and `string` values only
* Limits:
  * 255 attributes
  * 255 characters in the attribute name
  * 100 character length limit of individual string values (NR supports 4k but this library will truncate long strings automatically and add an ellipsis.)
  * 1500 character length for error metric strings by default, or configurable by setting the `NEW_RELIC_ERROR_METRIC_MAX_STRING_LENGTH` environment variable
  * 100,000 HTTP POST requests/min, 429 status after, counter reset of 1 minute window


## Usage

From New Relic you will need:
- your account id
- your New Relic Insights API key (note the "Insights" here, it's separate from a plain NR api key)

Initialize the New Relic Metrics agent with those values.
You typically want to do that right when your action starts in order to get action timeout metrics or support automatic instrumentation (see below).

```javascript
const { NewRelic } = require('@adobe/openwhisk-newrelic');
const metrics = new NewRelic({
    newRelicEventsURL: 'https://insights-collector.newrelic.com/v1/accounts/<YOUR_ACOUNT_ID>/events',
    newRelicApiKey: 'YOUR_INSIGHTS_API_KEY'
});
```

Then collect all your custom/background metrics in a separate object

```javascript
const customMetrics = {
    data: "value",
    userName: "sampleUser"
}
```

Send your metrics to New Relic:

```javascript
await metrics.send('EVENT_TYPE', customMetrics);
```

Note that metrics are not sent immediately but are collected in the background and sent in intervals every 10 seconds by default. This can be configured via `sendIntervalMs` in the options of the constructor (in milliseconds).

Also note that `new NewRelic()` will start a `setTimeout` that will send metrics if your action is close to timeout using `__OW_DEADLINE`.

You MUST call `activationFinished()` to stop the agent when you are done sending metrics, or when your action is finishing. This will clear the action timeout that began when the class instance was defined.

```javascript
metrics.activationFinished();
```

To disable all sending of metrics to New Relic (for example in unit tests), set this environment variable:

```
OPENWHISK_NEWRELIC_DISABLE_METRICS=true
```

### Instrumentation

Supported instrumentation:

* **http** requests (outgoing requests, via the node `http` and `https` modules):
  - [reference documentation](#http)
  - on by default
  - can be disabled with environment variable: `OPENWHISK_NEWRELIC_DISABLE_HTTP_INSTRUMENTATION=true`
  - can also be disabled by setting `disableHttpClient: true` in the options passed to `NewRelic.instrument()`

To enable instrumentation, wrap the action main function in `NewRelic.instrument()`. A complete example might look like this:

```javascript
async function main(params) {
    const metrics = new NewRelic({
        newRelicEventsURL: 'https://insights-collector.newrelic.com/v1/accounts/<YOUR_ACOUNT_ID>/events',
        newRelicApiKey: 'YOUR_INSIGHTS_API_KEY'
    });
    try {
        // do something
    } finally {
        metrics.activationFinished();
    }
}

exports.main = NewRelic.instrument(main);
```

To disable all instrumentation (for example in unit tests), set this environment variable:

```
OPENWHISK_NEWRELIC_DISABLE_ALL_INSTRUMENTATION=true
```

### Action Timeout

The default behavior of the agent is it will begin a `setTimeout` that will send metrics right before the  action times out, using the `OW_DEADLINE` environment variable.

In case you want to opt out of the action timeout, (example: unit tests) there are two ways to opt out:

1. Pass in `disableActionTimeout` to options:

   ```javascript
   const metrics = new NewRelic({
       newRelicEventsURL: 'https://insights-collector.newrelic.com/v1/accounts/<YOUR_ACOUNT_ID>/events',
       newRelicApiKey: 'YOUR_INSIGHTS_API_KEY',
       disableActionTimeout: true
   });
   ```

2. Set the environment variable: `DISABLE_ACTION_TIMEOUT_METRIC` to `true`:

   ```
   export DISABLE_ACTION_TIMEOUT_METRIC = true
   ```

If either of these are set to true, there will be no action timeout and calling `activationFinished` is no longer necessary.


In case you want to pass custom metrics to the action timeout, you can define a callback function in New Relic options. The result of the callback will be added to the default metrics and sent at action timeout. If you do not define an `eventType`, it will default to `timeout`.:

```javascript
const metrics = new NewRelic({
    newRelicEventsURL: 'https://insights-collector.newrelic.com/v1/accounts/<YOUR_ACOUNT_ID>/events',
    newRelicApiKey: 'YOUR_INSIGHTS_API_KEY',
    actionTimeoutMetricsCb: function () {
        return {
            eventType: 'error',
            ...customMetrics
        }
    }
});
```

### Standard

Sent for all metrics.

| Attribute         | Format           | Description                                                                                                                                                                                            |
|-------------------|------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `eventType`       | string           | Event type, required, [standard New Relic Insights type](https://docs.newrelic.com/docs/insights/insights-data-sources/custom-data/insights-custom-data-requirements-limits).                          |
| `timestamp`       | utc millis (?)   | The UTC timestamp to associate with the event. [Standard New Relic Insights type](https://docs.newrelic.com/docs/insights/insights-data-sources/custom-data/insights-custom-data-requirements-limits). |
| `namespace`       | string           | OpenWhisk namespace of the action that sent the event.                                                                                                                                                 |
| `package`         | string           | OpenWhisk package name of the action that sent the event.                                                                                                                                              |
| `actionName`      | string           | OpenWhisk action name (without package) of the action that sent the event.                                                                                                                             |
| `activationId`    | string           | OpenWhisk activation id of the action that sent the event.                                                                                                                                             |
| `cloud`           | string           | Cloud in which the activation ran, e.g. `aws` or `azure` (`__OW_CLOUD`).                                                                                                                               |
| `region`          | string           | Region in which the activation ran, e.g. `us-east-1` (`__OW_REGION`).                                                                                                                                  |
| `transactionId`   | string           | OpenWhisk transaction id (`__OW_TRANSACTION_ID`).                                                                                                                                                      |
| `activationHost`  | string           | Hostname where the activation ran (`HOSTNAME` env var).                                                                                                                                                |
| `activationContainerName`  | string  | Container name where the activation ran (`MESOS_CONTAINER_NAME` env var).                                                                                                                              |
| `nodeVersion`     | string           | Nodejs version on which the action ran, e.g. `13.12.0`.                                                                                                                                                |
| `containerMemorySize`  | number  | Container memory size found in `/sys/fs/cgroup/memory/memory.limit_in_bytes` in CGROUPV1 or `/sys/fs/cgroup/memory.max` in CGROUPV2                                                                    |

### Http

Tracks each outgoing http request. Automatically instrumented in node and done in all actions.

Naming is aligned with NewRelic's standard [SyntheticRequest](https://docs.newrelic.com/attribute-dictionary?attribute_name=&events_tids%5B%5D=8387) attributes.

Event type: `http`

| Attribute         | Format           | Description                     | Example      |
|-------------------|------------------|---------------------------------|--------------|
| [...](#standard) | | [All standard attributes](#standard) | |
| `method` | string | HTTP method | `"POST"` |
| `url` | string | complete URL of the request | `"https://eg-ingress.adobe.io/api/events"` |
| `protocol` | string | protocol of the URL, `http:` or `https:` | `"https:"` |
| `domain` | string | host without any subdomain for simpler aggregation: `<domain>.<tld>` | `"adobe.io"` |
| `host` | string | hostname of the server | `"eg-ingress.adobe.io"` |
| `port` | number | TCP port of the server | `443` |
| `path` | string | path of the URL, including query parameters | `"/api/events"` |
| `responseCode` | number | HTTP response status code | `200` |
| `responseStatus` | string | HTTP response status text | `"OK"` |
| `requestBodySize` | number | size of the HTTP request body | `1874` |
| `responseBodySize` | number | size of the HTTP response body | `2` |
| `contentType` | string | content-type of the response | `"application/json;charset=UTF-8"` |
| `serverRequestId` | string | `x-request-id` header of the response, if present | `"cLqJ2lcWXUmXpnRCDULturVM9lTovQxx"` |
| `localIPAddress` | string | IP address of the client | `"172.20.0.23"` |
| `serverIPAddress` | string | IP address of the server | `"34.196.31.105"` |
| `duration` | number | total duration of the request in milliseconds | `294.551398` |
| `durationBlocked` | number | time until a socket was available in milliseconds | `0.587596` |
| `durationDNS` | number | duration of DNS resolution in milliseconds | `0.441319` |
| `durationConnect` | number | TCP connection duration in milliseconds | `1.138568` |
| `durationSSL` | number | SSL handshake duration in milliseconds (https only) | `3.639361` |
| `durationSend` | number | time it took to send the HTTP request. Note this currently does not work for streaming requests as done for our rendition uploads until we upgrade to Node 12+ in Adobe I/O Runtime. Until then the send time is included in the `durationConnect`. | `0.065885` |
| `durationWait` | number | time between request was sent and first byte of response was received in milliseconds | `288.649511` |
| `durationReceive` | number | time it took to receive the entire response body in milliseconds | `0.029158` |
| `error` | string | Only set if there was a low-level connection error. Set as `true` in json, represented as `1` in NewRelic. | `1` |
| `errorCode` | string | OS or nodejs error code (name or number) in case there was a low-level connection error. `110` means `ETIMEDOUT`. | `"ECONNRESET"` or `"110"` |
| `errorMessage` | string | Error message in case there was a low-level connection error. | `"socket hang up"` |

### Contributing
Contributions are welcomed! Read the [Contributing Guide](./.github/CONTRIBUTING.md) for more information.

### Licensing
This project is licensed under the Apache V2 License. See [LICENSE](LICENSE) for more information.

---
_Source: https://npm.io/package/@adobe/openwhisk-newrelic · Machine-readable twin of the npm.io package page. Health data is recomputed on every publish._
