As33
@periodic/
arsenic

Quick Start

Up and running in under 5 minutes. This guide uses Express + MongoDB. Swap adapters freely — the monitor code is identical for Fastify, Prisma, or PostgreSQL.

1. Install

bash
npm install @periodic/arsenic mongoose express

2. Create a monitor

Create once, export, and reuse everywhere.

src/monitor.ts
typescript
1import { createMonitor, SignalSeverity } from '@periodic/arsenic';
2 
3export const monitor = createMonitor({
4 slowQueryThresholdMs: 200,
5 includeDocs: true,
6 emitPositiveSignals: false,
7 
8 exporter: (event) => {
9 if (event.severity === SignalSeverity.CRITICAL) {
10 sendToPagerDuty(event);
11 } else if (event.severity === SignalSeverity.WARNING) {
12 sendToSlack(event);
13 } else {
14 logger.info(event);
15 }
16 },
17});

3. Attach Express middleware

Must be added before your routes.

src/app.ts
typescript
import express from 'express';
import { expressContext } from '@periodic/arsenic';
import { monitor } from './monitor';

const app = express();

// Add BEFORE routes
app.use(expressContext(monitor, {
  attachUser: (req) => req.user?.id, // optional
}));

4. Instrument Mongoose

typescript
import mongoose from 'mongoose';
import { mongooseAdapter } from '@periodic/arsenic';
import { monitor } from './monitor';

await mongoose.connect(process.env.MONGODB_URI);
mongooseAdapter(monitor, mongoose);

5. Write your routes normally

typescript
app.get('/api/users/:id', async (req, res) => {
  // Arsenic automatically monitors this query
  const user = await User.findOne({ _id: req.params.id });
  res.json(user);
});

app.listen(3000);

Example event output

json
{
  "type": "db.query",
  "db": "mongodb",
  "adapter": "mongoose",
  "model": "User",
  "operation": "findOne",
  "durationMs": 312,
  "slow": true,
  "signals": ["hot_path", "unbounded_query"],
  "severity": "critical",
  "request": {
    "id": "req_8f29",
    "method": "GET",
    "route": "/api/users/:id"
  },
  "callsite": {
    "file": "src/routes/users.ts",
    "line": 14
  },
  "timestamp": "2025-02-11T15: 30: 45.123Z"
}

Swap adapters freely

The monitor code is identical for Express or Fastify, Mongoose or Prisma. Only the context middleware and adapter call changes.