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.
Install
npm install @naijacloud/argusNode.js 18.18 or newer. The package has no dependencies.
Start
Start your app with the Argus flag, so it loads before your code:
ARGUS_DSN=https://<public key>@argus-in.naijacloud.com/<project id> node --import @naijacloud/argus/register app.jsThe 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:
{
"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.
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
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:httpornode:httpsserver: Express, Fastify, NestJS, Koa and plainhttp. Atraceparentheader from the caller continues its trace. - Outgoing
fetch()calls, as child spans with atraceparentheader, and as breadcrumbs. consolecalls, as breadcrumbs on the next error.
Database clients and node:http outgoing requests are not traced yet; only
fetch is.
Report errors yourself
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
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
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
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:
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 codewithMonitor reports the start, then success or failure, and rethrows your
job's error. A short script should await flush() before it exits.
Feature flags
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:
ARGUS_RELEASE=$(git rev-parse HEAD) ARGUS_ENVIRONMENT=staging \
node --import @naijacloud/argus/register app.jsWith init(), pass release and environment as options instead.
Privacy
On by default:
- Values of keys such as
password,token,secret,authorization,cookie,bvnandcardbecome[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:
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:
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.