2.0.0-beta.2 • Published 2 days ago

@salesforcedevs/apmagent v2.0.0-beta.2

Weekly downloads
-
License
UNLICENSED
Repository
-
Last release
2 days ago

Salesforce APM Agent for NodeJS

Install Node

  1. Install nvm. Do not use brew to install nvm as it is unsupported by nvm.
  2. Run nvm install. The current minimum Node version is Node 18 as defined in the .nvmrc file.
  3. Ensure the current Node version is loaded by running node -v.

Setting up the Agent

Pre-requisites

  1. A NodeJS application. Use nodejs-js-getting-started if you wish to have a sample application for testing.
  2. mTLS certificates to authenticate with Monitoring Cloud Funnel API endpoints.

Source the Agent from Nexus

Get the Agent from Nexus. You'll need to be logged into Nexus to see the Agent package. Additionally, this Confluence doc may provide guidance on how to configure your machine to pull from the Nexus NPM registry.

Note: In the Confluence doc linked above, it says to use nexus.soma.salesforce.com/nexus/content/groups/npm-all/:_authToken=. Use nexus.soma.salesforce.com/nexus/content/groups/npm-all/:_auth= instead.

Steps

  1. Configuring access to internal Nexus NPM Registry.
    • Refer to the example .npmrc as a template.
  2. Navigate to your application's base directory.
  3. Run npm install @salesforce/apmagent@1.14.0.
  4. Add the following at the top of your index.js or app.js:
const { Apm } = require("@salesforce/apmagent");
const apm = new Apm();
apm.load();
  1. Run your app: node app.js
  2. Discover your telemetry in Monitoring Cloud UI(https://monitoring.internal.salesforce.com/argusmvp/#/querymanagement.

Source the Agent locally

  1. Generate the binary:
git clone https://git.soma.salesforce.com/monitoring/salesforce-apmagent-nodejs
cd salesforce-apmagent-nodejs
npm install
npm pack

Verify the salesforce-apmagent-{version}.tgz is created in the current directory.

  1. Navigate to your application's base directory.
  2. Install the salesforce-apmagent package by running npm install path/to/salesforce-apmagent-{version}.tgz.
  3. Copy monitoring.js to your application's base directory.
  4. Run your app: node --require ./monitoring.js app.js
  5. Discover your telemetry in Monitoring Cloud UI(https://monitoring.internal.salesforce.com/argusmvp/#/querymanagement.

Configuration

A list of all available configurations can be found here.

In order to run the agent without APM, you can set the SFDC_AGENT_ENABLED environment variable to false.

Currently, it is only possible to configure the Agent via environment variables.

Custom Instrumentation

Recording custom events

Full docs for JS instrumentation can be found in the Otel documentation here: https://opentelemetry.io/docs/instrumentation/js/instrumentation/#create-spans To use our events library, you can ignore the instructions under the headings Tracing and Browser, as our extension creates and registers processors for you. Instead, if you are running your app with node app.js, then you can use the following code:

const opentelemetry = require("@opentelemetry/api");
//...

const tracer = opentelemetry.trace.getTracer(
  'my-service-tracer'
);

tracer.startActiveSpan('main', span => {
  for (let i = 0; i < 10; i += 1) {
    console.log(i)
  }
  span.end();
});

// Example of a function with span generation:
app.get('/always-error/:id', (req, res) => {

  const id = req.params.id;
  (async function() {
    tracer.startActiveSpan('main', span => {
      res.sendStatus(400);
      span.recordException(new Error('exception'));
      span.end();
    });
  })();

});

// Example of publishing a custom event
app.get('/custom-event/:id', (req, res) => {

   const id = req.params.id;
   const custom_event_payload_attributes = {
      "city": "Pittsburgh",
      "groupedRequestUrl": "groupedRequestUrl",
      "browserInteractionName": "browserInteractionName",
      "httpMethod": "httpMethod",
      "timeToLoadEventStart": 0.1,
      "userAgentName": "userAgentName",
      "hostname": "hostname",
      "regionCode": "USA",
      "countryCode": "US",
      "countryCode": "US",
      "requestUrl": "requestUrl",
      "timeSinceBrowserInteractionStart": 0.1,
      "appId": "appId",
      "entityGuid": "entityGuid",
      "userAgentOS": "userAgentOS",
      "asnLatitude": "asnLatitude",
      "parentEventId": "parentEventId",
      "deviceType": "deviceType",
      "eventId": "eventId",
      "actionText": "actionText",
      "appName": "appName",
      "groupedPageUrl": "groupedPageUrl",
      "asnOrganization": "asnOrganization",
      "asnLongitude": "asnLongitude",
      "browserInteractionId": "browserInteractionId",
      "userAgentVersion": "userAgentVersion",
      "port": 443,
      "jsDuration": 0.1,
      "httpResponseCode": 200,
      "pageUrl": "pageUrl",
      "timeToSettle": 0.1,
      "asn": "asn",
      "responseBodySize": 1119,
      "requestBodySize": 1119,
      "timeToLastCallbackEnd": 0.1
   };
   (async function() {
      tracer.startActiveSpan('main', span => {
         res.sendStatus(400);
         span.addEvent('MS_AjaxRequest', custom_event_payload_attributes);
         span.end();
      });
   })();

});

Contributing

Bug reports and pull requests are welcome on GitHub. Please fork the repository if you do not have write access.

Style Guide

This project follows https://github.com/felixge/node-style-guide.

Release a new Package

  1. Create a new PR.
  2. Bump version in package.json using semantic versioning.
  3. Also bump version in the version.ts file
  4. Merge PR into master branch. Strata will automatically build & release the version to Nexus.
  5. Run npm install to update package-lock.json
  6. Draft and publish a new tag and release under Releases.

Note: Subsequent PR merges to master using the same version will not overwrite existing published packages.