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

@jnode/server-log

v1.0.3

Published

Official logger for JNS.

Readme

@jnode/server-log

Official logger for JNS.

Installation

npm i @jnode/server-log

Quick start

Import

const { createServer, routerConstructors: r, handlerConstructors: h } = require('@jnode/server');
const { routerConstructors: lr } = require('@jnode/server-log');

Start a server with logging

const server = createServer(
  // wrap your root router with lr.Log
  lr.Log(
    r.Path(h.Text('Hello, world!'), {
      '/api': h.JSON({ ok: true })
    }),
    {
      // Optional: Log to files in the './logs' directory
      folder: './logs'
    }
  )
);

server.listen(8080);

How it works?

LogRouter is a specialized router that sits in front of your application logic. When a request arrives, it records the start time and injects a finalizeLog function into the ctx. It then passes the request to the next router or handler.

Once the response is finished (or a timeout is reached), it gathers information about the request (such as status code, method, and response time) and outputs it to the console and/or a log file.


Reference

Routers

Router: Log(next[, options])

  • next router | handler-extended The next step in the routing chain.
  • options <Object>
    • folder <string> The directory to save log files. If set, files will be named by date (e.g., 2023-12-31.log).
    • consoleItems <string[]> Array of item keys to display in the console. Default: ['localTime', 'statusCode', 'method', 'url', 'ip', 'responseTime'].
    • fileItems <string[]> Array of item keys to write to the log file. Default: ['iso', 'statusCode', 'method', 'url', 'ip', 'ua', 'responseTime'].
    • itemRegistery <Object> Custom log item functions.
    • disableConsoleLog <boolean> Disable logging to the console. Default: false.
    • plainConsoleLog <boolean> Disable ANSI colors in console output. Default: false.
    • sep <string> The separator between log items. Default: ' ' (space).
    • forceLog <number> Timeout in milliseconds to force log if the response hasn't finished. Default: 10000.

Records request metadata and logs it upon completion. It also adds a ctx.finalizeLog function, allowing handlers (like WebSocket upgrades) to trigger logging manually before the connection context changes.

The LogRouter will add a function .finalizeLog into ctx, when any of later router/handlers wants to log write away (e.g. the WebSocket-related requests) they could call this.

Log Items

Built-in Log Items

These keys can be used in consoleItems or fileItems:

| Item Key | Description | Example Output | | :--- | :--- | :--- | | local | Local date and time | [12/31/2023, 14:30:05] | | localTime | Local time string | [14:30:05] | | localDate | Local date string | [12/31/2023] | | iso | UTC ISO 8601 string | [2023-12-31T14:30:05.000Z] | | isoTime | UTC ISO time part | [14:30:05.000Z] | | isoDate | UTC ISO date part | [2023-12-31] | | timestamp | Unix timestamp (ms) | [1704024000000] | | responseTime| Request duration | 5ms (Green/Yellow/Red) | | method | HTTP method | GET, POST (Blue) | | statusCode | HTTP status code | 200, 404, 500 (Colored) | | path | URL pathname | /api/data | | url | Host + URL | example.com/api/data | | host | Hostname | example.com | | ip | Client IP address | 127.0.0.1 | | ua | User-Agent header | "Mozilla/5.0..." | | referer | Referer header | https://google.com/ | | depth | Routing step count | @2 (Cyan) |

Custom Log Items

You can define custom log items via the itemRegistery option or by passing a function directly into the items array.

The function signature is: (time, env, ctx, plain, styled) => void

  • time <Date> The start time of the request.
  • env <Object> JNS environment object.
  • ctx <Object> JNS context object.
  • plain <string[]> Push text here for file logs and plain console logs.
  • styled <string[]> Push text with ANSI escape codes here for styled console logs.

Example:

lr.Log(next, {
  itemRegistery: {
    hello: (time, env, ctx, plain, styled) => {
      plain.push('HELLO');
      styled.push('\x1b[32mHELLO\x1b[0m'); // Green HELLO
    }
  },
  consoleItems: ['localTime', 'hello', 'path']
});