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

@cedtech/logger

v0.1.0

Published

Official logger SDK for CedtechLog — structured logs and events with automatic batching

Readme

@cedtech/logger

Official logger SDK for CedtechLog — structured logs and analytics events with automatic batching, works in Node.js, Bun, and the browser.

Installation

npm install @cedtech/logger
# or
bun add @cedtech/logger

Quick start

Create a project in your CedtechLog dashboard, generate an API key (ctl_…), then initialise the logger:

import { CedtechLogger } from "@cedtech/logger";

const logger = new CedtechLogger({
  endpoint: "https://your-cedtechlog-server.com",
  apiKey: "ctl_…",
});

logger.info("Server started", { port: 3000 });
logger.warn("High memory usage", { mb: 512 });
logger.error("Unhandled exception", { stack: err.stack }, requestId);

// Track analytics events
logger.event("user_signup", { plan: "pro" }, { user_id: "u_123" });

// Flush before process exit
process.on("beforeExit", () => logger.destroy());

The project name is resolved automatically from the API key — no need to specify service.


Log levels

| Method | Level | | -------------- | ------- | | logger.trace | trace | | logger.debug | debug | | logger.info | info | | logger.warn | warn | | logger.error | error | | logger.fatal | fatal |

All log methods share the same signature:

logger.info(message: string, fields?: Record<string, unknown>, traceId?: string)

Event tracking

logger.event(
  name: string,
  properties?: Record<string, unknown>,
  opts?: { user_id?: string; session_id?: string; timestamp?: string },
)
logger.event("page_view", { path: "/dashboard" }, { session_id: "s_abc" });
logger.event("purchase", { amount: 49.99, currency: "USD" }, { user_id: "u_123" });

Configuration

const logger = new CedtechLogger({
  // Required (unless `transport` is provided)
  endpoint: "https://…",
  apiKey: "ctl_…",

  // Optional
  service: "my-service",       // Override project name (resolved from key by default)
  flushInterval: 5_000,        // Auto-flush interval in ms (default: 5 000)
  batchSize: 100,              // Flush when buffer reaches this count (default: 100)
  defaultFields: {             // Merged into every log and event entry
    env: "production",
    region: "us-east-1",
  },
  captureMetadata: true,       // Auto-attach pid, platform, arch, runtime (default: true)
  captureSource: true,         // Auto-capture caller file/line as `source` (default: true)
});

Child loggers

Inherit all settings and merge extra persistent fields without re-initialising:

const requestLogger = logger.child({ requestId: "req_xyz", userId: "u_123" });

requestLogger.info("Request received", { method: "POST", path: "/checkout" });
requestLogger.error("Payment failed", { reason: "insufficient_funds" });

Custom transport

Swap the HTTP transport for a custom implementation — useful for testing or alternative backends:

import { CedtechLogger, type Transport } from "@cedtech/logger";

class ConsoleTransport implements Transport {
  async sendLogs(batch) {
    for (const log of batch) console.log(`[${log.level}] ${log.message}`);
  }
  async sendEvents(batch) {
    for (const evt of batch) console.log(`[event] ${evt.name}`);
  }
}

const logger = new CedtechLogger({ transport: new ConsoleTransport() });

Lifecycle

Logs are buffered and flushed automatically on an interval or when the batch size is reached. Call destroy() before your process exits to flush remaining entries:

// Node / Bun
process.on("beforeExit", () => logger.destroy());

// Alternatively, flush manually at any time
await logger.flush();

License

MIT