npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

cronwatch

v1.0.0

Published

Lightweight cron job tracker, debugger, and monitor for Node.js applications

Downloads

19

Readme

CronWatch

Lightweight cron job tracker, debugger, and monitor for Node.js applications.

Zero dependencies. Full TypeScript support. Plugin-ready.

Install

npm install cronwatch

Quick Start

const { createCronWatch } = require('cronwatch');

const cron = createCronWatch();

await cron.trackJob('send-emails', async () => {
  // your job logic here
  await sendPendingEmails();
});

Every call to trackJob automatically captures start/end time, duration, success/failure status, error stacks, and retry counts.

Configuration

const cron = createCronWatch({
  retries: 3,                // max retry attempts (default: 0)
  retryDelay: 1000,          // base delay between retries in ms (default: 1000)
  retryBackoff: 'exponential', // 'fixed' | 'linear' | 'exponential'
  timeout: 30000,            // job timeout in ms, 0 = disabled (default: 0)
  logLevel: LOG_LEVELS.INFO, // DEBUG | INFO | WARN | ERROR | SILENT
  storeMaxEntries: 1000,     // max entries kept in memory (default: 1000)
  timestamps: true,          // ISO timestamps in log output (default: true)
  colorize: true,            // colorized console output (default: true)
});

Per-job overrides:

await cron.trackJob('heavy-job', jobFn, {
  retries: 5,
  retryDelay: 2000,
  retryBackoff: 'linear',
  timeout: 60000,
});

Structured Logs

Every tracked job produces a structured entry:

{
  "jobName": "send-emails",
  "status": "success",
  "startTime": "2026-03-20T10:00:00.000Z",
  "endTime": "2026-03-20T10:00:00.234Z",
  "duration": 234,
  "error": null,
  "retries": 0
}

On failure:

{
  "jobName": "sync-inventory",
  "status": "failure",
  "startTime": "2026-03-20T10:00:00.000Z",
  "endTime": "2026-03-20T10:00:03.512Z",
  "duration": 3512,
  "error": {
    "message": "Connection refused",
    "stack": "Error: Connection refused\n    at ...",
    "code": null
  },
  "retries": 3
}

Querying Logs

const emailLogs = await cron.getJobLogs('send-emails');
const allLogs   = await cron.getAllLogs();
await cron.clearLogs();

Plugin System

Extend CronWatch by hooking into job lifecycle events.

cron.use({
  name: 'slack-alerter',
  onFailure({ jobName, error }) {
    slack.send(`Job ${jobName} failed: ${error.message}`);
  },
  onTimeout({ jobName }) {
    slack.send(`Job ${jobName} timed out!`);
  },
});

Available Hooks

| Hook | Trigger | |------|---------| | onStart | Before job executes | | onSuccess | Job completed successfully | | onFailure | Job failed after all retries | | onRetry | Before each retry attempt | | onTimeout | Job exceeded timeout |

Custom Store Adapter

By default, logs are kept in memory. You can plug in any backend:

const { createCronWatch, StoreAdapter } = require('cronwatch');

class MongoAdapter extends StoreAdapter {
  async save(entry)          { /* insert into MongoDB */ }
  async getByJob(jobName)    { /* query by jobName */ }
  async getAll()             { /* return all entries */ }
  async clear()              { /* drop collection */ }
}

const cron = createCronWatch({
  storeAdapter: new MongoAdapter(),
});

See examples/custom-store-adapter.js for a working file-based adapter.

Use with node-cron

const nodeCron = require('node-cron');
const { createCronWatch } = require('cronwatch');

const cron = createCronWatch({ retries: 2, timeout: 10000 });

nodeCron.schedule('*/5 * * * *', () => {
  cron.trackJob('cleanup-temp-files', async () => {
    await cleanupTempFiles();
  });
});

TypeScript

Full type definitions are included. Import and use directly:

import { createCronWatch, CronWatchPlugin, JobEntry } from 'cronwatch';

const cron = createCronWatch({ retries: 2 });

const plugin: CronWatchPlugin = {
  name: 'my-plugin',
  onSuccess({ jobName }) {
    console.log(`${jobName} done`);
  },
};

cron.use(plugin);

API Reference

createCronWatch(options?)

Creates a new CronWatch instance.

instance.trackJob(jobName, jobFn, options?)

Executes and tracks a job. Returns a Promise<JobEntry>.

instance.use(plugin)

Registers a plugin. Returns this for chaining.

instance.getJobLogs(jobName)

Returns all log entries for a specific job.

instance.getAllLogs()

Returns all log entries.

instance.clearLogs()

Clears the log store.

Architecture

src/
  config.js    - Centralized config with defaults and merging
  logger.js    - Multi-level logger with pluggable outputs
  store.js     - In-memory store with adapter interface
  retry.js     - Retry engine with backoff strategies
  plugin.js    - Plugin lifecycle manager
  tracker.js   - Core trackJob orchestrator
  index.js     - Public API surface
types/
  index.d.ts   - Full TypeScript definitions

Roadmap

  • [ ] Database adapters (MongoDB, PostgreSQL, Redis)
  • [ ] Dashboard API (Express/Fastify)
  • [ ] Alert system (email, webhooks, Slack)
  • [ ] Job scheduling (built-in cron parser)
  • [ ] Metrics export (Prometheus, StatsD)

License

MIT