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

@sidhant_001/traceer

v0.1.0

Published

Centralized Winston-based logging SDK for Node.js with AWS CloudWatch, GCP Cloud Logging and per-request context.

Readme

traceer

Centralized, cloud-aware logging for Node.js, built on winston.

One logger API that writes the right format for wherever your service runs:

| Provider | Default output | Optional direct upload | | --- | --- | --- | | local | Coloured, pretty console (+ rotating files) | – | | aws (Lambda, ECS, EKS, EC2) | JSON on stdout, which CloudWatch Logs collects | CloudWatch Logs API (aws.logGroupName) | | gcp (Cloud Run, GKE, Functions, App Engine) | Structured JSON on stdout with severity + trace, which Cloud Logging collects | Cloud Logging API (gcp.useCloudLoggingApi) |

It also includes:

  • Per-request context: every log inside a request gets the same requestId and traceId (from traceparent, x-cloud-trace-context or x-amzn-trace-id).
  • Request summary logs: one log per request with method, url, status and duration.
  • Redaction of secrets (password, token, authorization, …) at any depth.
  • Error serialization: logger.error("msg", err) keeps message, stack, cause and code.
  • Graceful shutdown: await logger.close() flushes pending cloud uploads.

Install

npm install @sidhant_001/traceer

To upload directly through a cloud API (optional; stdout is enough on managed platforms):

npm install winston-cloudwatch @aws-sdk/client-cloudwatch-logs   # AWS
npm install @google-cloud/logging-winston                         # GCP

Quick start

import express from "express";
import { createLogger, requestLogger } from "@sidhant_001/traceer";

const logger = createLogger({ service: "orders-api" });

const app = express();
app.use(requestLogger(logger, { ignorePaths: ["/health"] }));

app.get("/orders/:id", (req, res) => {
  logger.info("Fetching order", { orderId: req.params.id }); // gets requestId automatically
  res.json({ id: req.params.id });
});

app.listen(3000, () => logger.info("Server started"));

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

requestLogger works with Express, Connect and plain http servers.

Options

createLogger({
  service: "orders-api",          // env SERVICE_NAME, default "app"
  provider: "auto",               // "auto" | "local" | "aws" | "gcp", env LOG_PROVIDER
  level: "info",                  // env LOG_LEVEL, default "debug" locally / "info" on cloud
  defaultMeta: { version: "1.4.0" },
  console: true,                  // write to stdout
  redactKeys: [...DEFAULT_REDACT_KEYS, "otp"],
  file: { enabled: true, directory: "./logs", maxSize: "20m", maxFiles: "7d" },
  aws: {
    logGroupName: "/services/orders-api", // set to upload through the CloudWatch API
    logStreamName: "instance-1",          // default <service>-<hostname>-<pid>
    region: "ap-south-1",                 // default AWS_REGION
    retentionInDays: 30,
  },
  gcp: {
    projectId: "my-project",              // default GOOGLE_CLOUD_PROJECT, enables trace linking
    useCloudLoggingApi: false,            // true = upload through the Cloud Logging API
    keyFilename: "/secrets/sa.json",
    logName: "orders-api",
  },
});

provider: "auto" detects AWS from AWS_LAMBDA_FUNCTION_NAME / AWS_EXECUTION_ENV / ECS_CONTAINER_METADATA_URI*, and GCP from K_SERVICE / CLOUD_RUN_JOB / FUNCTION_TARGET / GAE_SERVICE. On EKS, GKE or a plain VM, set provider (or LOG_PROVIDER) explicitly.

On Lambda / ECS / Cloud Run you usually don't need the API upload. stdout is already shipped. If you enable it anyway, set console: false to avoid duplicate logs.

gcp.useCloudLoggingApi needs valid Google credentials. If they are missing, @google-cloud/logging-winston throws an unhandled rejection inside its gRPC client, which crashes the process. traceer cannot catch that error.

Request context

HTTP

app.use(requestLogger(logger, {
  buffer: true,                 // default: collect a request's logs and write them together when it ends
  requestIdHeader: "x-request-id", // reused if sent by the caller, echoed on the response
  logRequests: true,            // one summary log per request
  ignorePaths: ["/health"],
}));

With buffer: true, a request's logs are written together (in order, with their original timestamps) when the response finishes. Logs written after the response are sent immediately. A request that buffers more than 1000 entries is flushed early. Use buffer: false to write every log as soon as it happens.

Jobs, queues, Lambda handlers

import { withRequestContext } from "@sidhant_001/traceer";

export const handler = async (event, context) =>
  withRequestContext(logger, async () => {
    logger.info("Processing event", { records: event.Records.length });
    // ...
  }, { requestId: context.awsRequestId });

Child loggers

const paymentsLog = logger.child({ module: "payments" });
paymentsLog.warn("Card declined", { orderId });

Errors

try { ... } catch (err) {
  logger.error("Payment failed", err);                 // -> { error: { name, message, stack, cause, code } }
  logger.error("Payment failed", { orderId, error: err });
}

Development

npm run build          # compiles src -> dist with .d.ts files
npm test               # builds, then runs the test suite (node:test, no extra dependencies)
npm run test:coverage  # same, with a coverage report
npm run example        # runs examples/express-app.js
npm publish            # runs the tests first (prepublishOnly)

Tests live in test/ and run against the compiled dist/, the same code users install. They cover:

  • log levels and output formats
  • redaction and error serialization
  • request context buffering
  • the HTTP middleware against a real server
  • config and env resolution
  • file logging
  • close() flushing

CI (.github/workflows/ci.yml) runs on every push and pull request. It:

  • type-checks and runs the tests on Node 20, 22 and 24
  • reports coverage
  • fails if anything other than dist/, README.md and package.json would be published
  • installs the packed tarball into an empty project as a final smoke test