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

@jay-chauhan/logger

v1.0.0

Published

A standalone info/warn/error logger with caller-location banners, .env-driven configuration, and date-based log files.

Readme

@jay-chauhan/logger

A standalone info / warn / error logger with caller-location banners, .env-driven configuration, and date-based log files. No relation to any other logging package — a fresh design, not a wrapper or extension.

Install

npm install @jay-chauhan/logger

To use startAutoCleanup(), also install the optional peer dependency:

npm install node-cron

Usage

const Logger = require('@jay-chauhan/logger');

const logger = new Logger(); // reads config from .env + defaults

logger.info('Server started');
logger.warn('Cache miss for key X');
logger.error('Payment failed', err); // accepts a message and/or an Error object

// optional category override — controls the log file path
logger.info('User logged in', 'auth/info');
logger.error('DB connection lost', dbError, 'database/error');

// manual cleanup
logger.cleanupLogs();

// scheduled cleanup (requires node-cron)
logger.startAutoCleanup();
logger.stopAutoCleanup();

Each level writes to its own log file per category, under a human-readable dated folder structure:

log/2026/July/29/category/name.log

(Year → full month name → zero-padded day → category → file.)

Output format

==================================================
Error: /home/jay/projects/api/src/services/payment.js:42
==================================================
Payment failed for order #4821
TypeError: Cannot read properties of undefined (reading 'id')
    at processPayment (/home/jay/projects/api/src/services/payment.js:42:18)
    ...stack...
==================================================
  • The banner label (Error: / Warning: / Info:) is followed by the absolute file path and line number of the call site — not the logger's own internal code.
  • If an Error object is passed, its .stack is appended below the message.
  • A trailing blank line separates entries when tailing the file.

Configuration

Resolved in priority order (highest wins):

  1. Options object passed to new Logger({ ... })
  2. .env variables (loaded once, lazily, via dotenv)
  3. Hardcoded defaults

| Key | Option | Default | Purpose | |---|---|---|---| | LOG_DIR | logDir | log | Where logs are written, relative to the project root unless absolute | | LOG_RETENTION_DAYS | retentionDays | 7 | Cleanup age threshold, in days | | LOG_LEVEL | level | info | Minimum level written (error < warn < info in verbosity) | | LOG_TO_CONSOLE | toConsole | true | Mirror entries to stdout/stderr | | LOG_COLOR | color | true | Colorize console output | | LOG_AUTO_CLEANUP | autoCleanup | false | Self-schedule cleanup on instantiation | | LOG_CLEANUP_CRON | cleanupCron | 0 0 * * * | Cron expression if auto-cleanup is on | | LOG_MAX_FILE_SIZE_MB | maxFileSizeMb | 0 (disabled) | Size-based rotation (not yet implemented) |

new Logger({ projectRoot }) can override project-root discovery, which otherwise walks up from require.main.filename until it finds a package.json, falling back to process.cwd().

Level filtering

error (highest severity, always most important)
warn
info  (lowest severity)

LOG_LEVEL=warn writes error and warn, and skips info. Skipped levels short-circuit before any stack-trace capture or file I/O.

API

logger.info(message, category?)

Banner label Info:. Writes to log/YYYY/MonthName/DD/{category||'app/info'}.log and mirrors to console.log if LOG_TO_CONSOLE.

logger.warn(message, category?)

Banner label Warning:. Same mechanics, default category app/warn, mirrors to console.warn.

logger.error(message, errorOrCategory?, category?)

Banner label Error:. Overloads:

logger.error('msg');
logger.error('msg', err);
logger.error('msg', err, 'category');
logger.error('msg', 'category'); // no Error object

If an Error instance is present, its .stack is appended under the message. Default category app/error. Mirrors to console.error.

logger.cleanupLogs()

Recursively deletes files (and resulting empty folders) older than retentionDays, based on file mtime — this doesn't depend on parsing the date out of the folder name.

logger.startAutoCleanup() / logger.stopAutoCleanup()

Schedules cleanupLogs() on cleanupCron using node-cron. Throws a clear error if node-cron isn't installed, since it's an optional peer dependency.

Safety notes

  • Category sanitization — the category argument is stripped of .. and empty/. segments before being joined into a file path, since it may originate from user-influenced strings.
  • Write failures don't crash the host app — if a log write fails (permissions, disk full), the entry is dumped to console.error instead of throwing.
  • Circular-safe message formatting — object messages that fail JSON.stringify (circular references) fall back to util.inspect.
  • Config validated at construction — an unwritable LOG_DIR or an invalid LOG_LEVEL throws immediately rather than failing silently later. An invalid LOG_CLEANUP_CRON throws when startAutoCleanup() is called.

Testing

npm test

Runs unit tests for formatter/caller/cleanup as pure functions, plus an integration test that runs a Logger against a temp directory and asserts on actual file contents.