Naijacloud
Docs

Node.js

Start your app with the Argus flag and it loads before your own code. Uncaught errors, incoming requests and outgoing fetch calls are then reported without any other change.

5 min read

Install

Install
bash
npm install @naijacloud/argus

Node.js 18.18 or newer. The package has no dependencies.

Start

Start your app with the Argus flag, so it loads before your code:

Start
bash
ARGUS_DSN=https://<public key>@argus-in.naijacloud.com/<project id> node --import @naijacloud/argus/register app.js

The flag works for ESM and CommonJS. Copy the DSN from your source under Argus → Sources.

On Naijacloud, the service's Send errors to Argus switch sets the DSN, release and environment for you, so put the flag in your start command and leave out ARGUS_DSN:

package.json
json
{ "scripts": { "start": "node --import @naijacloud/argus/register app.js" } }

Prefer code to a flag? Call init() first thing in your entry file, instead of the flag. You need this to pass options the environment can't carry, such as beforeSend. For ESM the flag is more reliable, because imports load before any code runs.

index.cjs
js
const { init } = require('@naijacloud/argus'); init({ dsn: process.env.ARGUS_DSN, release: '1.4.2' });

Use one or the other: with the flag, a later init() call returns the client the flag started and its options are ignored.

Send a test event

Send a test event
bash
npx @naijacloud/argus test --dsn https://<public key>@argus-in.naijacloud.com/<project id>

It sends one test event and says whether Argus accepted it. Without --dsn it uses ARGUS_DSN. The event shows under Argus → Errors.

What it captures

With only the flag:

  • Uncaught exceptions and unhandled rejections. The process still exits with code 1, as Node does without a handler.
  • Incoming requests, traced on any node:http or node:https server: Express, Fastify, NestJS, Koa and plain http. A traceparent header from the caller continues its trace.
  • Outgoing fetch() calls, as child spans with a traceparent header, and as breadcrumbs.
  • console calls, as breadcrumbs on the next error.

Database clients and node:http outgoing requests are not traced yet; only fetch is.

Report errors yourself

Errors
js
import { captureException, captureMessage, setTag, setUser } from '@naijacloud/argus'; try { await chargeCard(order); } catch (err) { captureException(err, { tags: { provider: 'paystack' }, extra: { orderId: order.id } }); } captureMessage('Webhook signature mismatch', 'warning'); setUser({ id: user.id }); setTag('region', 'af-west');

An error's cause chain is sent too, and the same error object is sent once, however many handlers see it.

Logs

Logs
js
import { log } from '@naijacloud/argus'; log.info('order placed', { orderId: 'ord_81', total: 18500 }); log.error('paystack timed out', { attempt: 3 });

Logs go to Argus → Logs in batches every 5 seconds. A log written inside a request carries its trace id. Pass captureConsole: true to init() to also send console.info, console.warn and console.error as logs.

Metrics

Metrics
js
import { metrics } from '@naijacloud/argus'; metrics.count('orders.placed', 1, { method: 'card' }); metrics.gauge('queue.depth', jobs.length); metrics.distribution('checkout.ms', elapsed, undefined, 'ms');

Metrics are added up in your process and sent every 10 seconds.

Traces

Traces
js
import { trace } from '@naijacloud/argus'; await trace('charge card', async (span) => { span?.setAttribute('provider', 'paystack'); await paystack.charge(order); });

A span joins the request it runs in. startSpan(name) gives you one to end yourself. Sample traces with the tracesSampleRate option, from 0 to 1 (default 1).

Cron check-ins

Create a cron monitor in Argus first, then report runs by its slug:

Cron check-ins
js
import { cron } from '@naijacloud/argus'; await cron.withMonitor('nightly-invoices', () => sendInvoices()); // or by hand: cron.checkIn('nightly-invoices', 'start'); cron.checkIn('nightly-invoices', 'ok'); // or 'error', or an exit code

withMonitor reports the start, then success or failure, and rethrows your job's error. A short script should await flush() before it exits.

Feature flags

Feature flags
js
import { flags } from '@naijacloud/argus'; if (await flags.isOn('new-checkout', user.id)) { // … } const theme = await flags.variant('theme', user.id, 'light');

Answers are cached for 30 seconds per user. If Argus can't be reached, or the flag doesn't exist, you get the fallback you passed.

Release and environment

The SDK reads ARGUS_RELEASE and ARGUS_ENVIRONMENT, then SENTRY_RELEASE and SENTRY_ENVIRONMENT. The environment is production when none is set. Set the release to your commit so Argus can say which deploy started an error:

Release and environment
bash
ARGUS_RELEASE=$(git rev-parse HEAD) ARGUS_ENVIRONMENT=staging \ node --import @naijacloud/argus/register app.js

With init(), pass release and environment as options instead.

Privacy

On by default:

  • Values of keys such as password, token, secret, authorization, cookie, bvn and card become [Filtered], at any depth.
  • Card numbers, bearer tokens and JWTs are filtered inside strings.
  • Query strings are removed from URLs in breadcrumbs and spans.
  • The user's IP address is not sent unless you set sendDefaultPii: true.

beforeSend, an init() option, changes an event before it is sent, or drops it when it returns null:

beforeSend
js
init({ beforeSend: (event) => { const error = event.exception?.values.at(-1); return error?.type === 'AbortError' ? null : event; }, });

Already on Sentry

Keep @sentry/node and its setup. In your Sentry.init call, change the dsn line:

Sentry.init
js
dsn: 'https://<public key>@argus-in.naijacloud.com/<project id>',

Source maps

Stack traces point at the files Node runs. If you bundle or minify your code, upload its maps as described in Source maps.