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

pinqloq

v1.2.1

Published

Structured logging and log shipping SDK for Express — captures HTTP request/response logs and manual application events, and ships them to the Pinqloq log management platform.

Readme

Pinqloq (Node.js / Express)

npm License: MIT

Pinqloq is a structured logging and log shipping SDK for centralized application logs. It captures HTTP request/response logs through Express middleware and sends manual application events to the Pinqloq log management platform using in-memory buffering, batching, and HTTPS delivery. This is the Node.js counterpart of the .NET pinqloq SDK — same platform, same wire protocol, idiomatic API on each side.

Features

  • Automatic Express request/response logging
  • Correlation id read from the caller's header, falling back to a generated request id
  • Name-based redaction of sensitive fields, headers, and whole endpoints
  • Manual structured application events
  • Buffered and batched HTTPS delivery
  • Graceful shutdown flush

Requirements

  • Node.js 18 or later
  • Express 4 or 5
  • A Pinqloq project and secret key

Installation

npm install pinqloq

Quick Start

Store your secret key in an environment variable or a secret manager. Do not hardcode production credentials.

import express from "express";
import { createPinqloq } from "pinqloq";

const pinqloqClient = createPinqloq({
  secretKey: process.env.PINQLOQ_SECRET_KEY!,
  apiLogsCollectionName: "myapp_api_logs"
});

const app = express();
app.use(express.json());

// Mount AFTER body-parsing middleware so req.body is populated when the log is captured.
app.use(
  pinqloqClient.requestLogging({
    excludePaths: ["/health"]
  })
);

app.listen(3000);

process.on("SIGTERM", async () => {
  await pinqloqClient.shutdown();
  process.exit(0);
});

The middleware captures the HTTP method, path, and status code as searchable metadata. The request body, response body, request headers, and response headers go to the log detail as InputJson, OutputJson, RequestHeaders, and ResponseHeaders. Bodies are truncated at 32 KB.

Manual Logging

Use pinqloqClient.enqueue to send structured application events:

pinqloqClient.enqueue({
  event: "order.created",
  deviceIdentifier: order.customerId,
  logLevel: PinqloqLogLevel.Information,
  logSourceType: PinqloqLogSourceType.Backend,
  metadata: { orderId: order.id }
});

event is required on every entry.

deviceIdentifier is optional and has no global fallback: set it per entry, and an entry that leaves it unset is stored without one.

pinqloqClient.logger still returns the same PinqloqLogger — useful when you want to pass just the logging capability into a function without handing it the whole client (request logging, shutdown, and all).

Add Request Metadata

By default the middleware reads the optional deviceIdentifier from the device-identifier request header. Override how it is resolved with resolveDeviceIdentifier. The override wins; if it returns undefined/blank, the middleware falls back to the device-identifier header. If neither resolves a value, the log is stored without a deviceIdentifier.

app.use(
  pinqloqClient.requestLogging({
    excludePaths: ["/health"],
    resolveDeviceIdentifier: (req) => req.user?.id,
    resolveAppVersionName: (req) => req.header("x-app-version"),
    metadata: {
      userId: (req) => req.user?.id
    }
  })
);

Use metadata for searchable values such as user and tenant IDs. Use detail for additional drill-down information. The event key (the panel title) defaults to "{method} {path}" and can be overridden via metadata.event.

Correlation ID

Every log carries a correlationId that ties together the records of a single request or flow. The request-logging middleware fills it with no configuration: the caller's correlation-id request header when present, otherwise a generated id.

pinqloqClient.enqueue({
  event: "order.created",
  deviceIdentifier: order.customerId,
  correlationId: currentCorrelationId
});

Redacting Sensitive Values

Request and response bodies and headers may contain credentials, tokens, or personal information. Unlike the .NET SDK's attribute-based redaction (which relies on C# reflection over typed DTOs — not available at runtime in TypeScript/Express), this SDK redacts by name:

  • redactFields — case-insensitive field/header names masked with *****REDACTED***** wherever they appear in a captured body or header, at any nesting depth.
  • redactPaths — path prefixes (matched the same way as excludePaths) where every value in InputJson, OutputJson, RequestHeaders, and ResponseHeaders is masked, keeping the JSON structure and header names intact — the equivalent of the .NET SDK's [PinqloqRedactEndpoint].
app.use(
  pinqloqClient.requestLogging({
    redactFields: ["ssnLastFour"],
    redactPaths: ["/payment"]
  })
);

A built-in, unconditional floor of common credential names (password, token, Authorization, card numbers, ...) is always masked, even with no configuration — see src/redaction/plan.ts for the full list.

Security and Reliability

Logs are buffered in memory and sent in batches. Buffered logs may be lost if the process is terminated without a graceful shutdown — call pinqloqClient.shutdown() on SIGTERM/SIGINT.

Delivery failures are reported through onFailed callbacks and, even without callbacks, as throttled console.error/console.warn output — never silently discarded, but also never blocking. If your secret key is authorized for more than one collection, set apiLogsCollectionName (or a per-entry collectionName); otherwise the batch is rejected.

Documentation

License

MIT