2.0.0 • Published 2 years ago

@adobe/openwhisk-newrelic v2.0.0

Weekly downloads
549
License
Apache-2.0
Repository
github
Last release
2 years ago

Version

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).

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

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

Send your metrics to New Relic:

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.

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
    • 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:

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:

    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.:

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.

AttributeFormatDescription
eventTypestringEvent type, required, standard New Relic Insights type.
timestamputc millis (?)The UTC timestamp to associate with the event. Standard New Relic Insights type.
namespacestringOpenWhisk namespace of the action that sent the event.
packagestringOpenWhisk package name of the action that sent the event.
actionNamestringOpenWhisk action name (without package) of the action that sent the event.
activationIdstringOpenWhisk activation id of the action that sent the event.
cloudstringCloud in which the activation ran, e.g. aws or azure (__OW_CLOUD).
regionstringRegion in which the activation ran, e.g. us-east-1 (__OW_REGION).
transactionIdstringOpenWhisk transaction id (__OW_TRANSACTION_ID).
activationHoststringHostname where the activation ran (HOSTNAME env var).
activationContainerNamestringContainer name where the activation ran (MESOS_CONTAINER_NAME env var).
nodeVersionstringNodejs version on which the action ran, e.g. 13.12.0.
containerMemorySizenumberContainer memory size found in /sys/fs/cgroup/memory/memory.limit_in_bytes

Http

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

Naming is aligned with NewRelic's standard SyntheticRequest attributes.

Event type: http

AttributeFormatDescriptionExample
...All standard attributes
methodstringHTTP method"POST"
urlstringcomplete URL of the request"https://eg-ingress.adobe.io/api/events"
protocolstringprotocol of the URL, http: or https:"https:"
domainstringhost without any subdomain for simpler aggregation: <domain>.<tld>"adobe.io"
hoststringhostname of the server"eg-ingress.adobe.io"
portnumberTCP port of the server443
pathstringpath of the URL, including query parameters"/api/events"
responseCodenumberHTTP response status code200
responseStatusstringHTTP response status text"OK"
requestBodySizenumbersize of the HTTP request body1874
responseBodySizenumbersize of the HTTP response body2
contentTypestringcontent-type of the response"application/json;charset=UTF-8"
serverRequestIdstringx-request-id header of the response, if present"cLqJ2lcWXUmXpnRCDULturVM9lTovQxx"
localIPAddressstringIP address of the client"172.20.0.23"
serverIPAddressstringIP address of the server"34.196.31.105"
durationnumbertotal duration of the request in milliseconds294.551398
durationBlockednumbertime until a socket was available in milliseconds0.587596
durationDNSnumberduration of DNS resolution in milliseconds0.441319
durationConnectnumberTCP connection duration in milliseconds1.138568
durationSSLnumberSSL handshake duration in milliseconds (https only)3.639361
durationSendnumbertime 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
durationWaitnumbertime between request was sent and first byte of response was received in milliseconds288.649511
durationReceivenumbertime it took to receive the entire response body in milliseconds0.029158
errorstringOnly set if there was a low-level connection error. Set as true in json, represented as 1 in NewRelic.1
errorCodestringOS or nodejs error code (name or number) in case there was a low-level connection error. 110 means ETIMEDOUT."ECONNRESET" or "110"
errorMessagestringError message in case there was a low-level connection error."socket hang up"

Contributing

Contributions are welcomed! Read the Contributing Guide for more information.

Licensing

This project is licensed under the Apache V2 License. See LICENSE for more information.

2.0.0

2 years ago

1.0.8

2 years ago

1.0.7

2 years ago

1.0.6

2 years ago

1.0.5

2 years ago

1.0.4

2 years ago

1.0.3

2 years ago

1.0.2

4 years ago

1.0.1

4 years ago

1.0.0

4 years ago