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

@zerilog/opentelemetryzink

v1.0.0

Published

A zink for shipping logs over [OTLP](https://opentelemetry.io/docs/specs/otlp/) (the OpenTelemetry Protocol) using `zerilog`.

Readme

📡 @zerilog/opentelemetryzink

A zink for shipping logs over OTLP (the OpenTelemetry Protocol) using zerilog.

OTLP is a vendor-neutral standard, so this zink works with any OTLP/HTTP receiver — an OpenTelemetry Collector, or a backend that ingests OTLP directly such as Berserk, Grafana, Honeycomb, and others. It sends each log event as an OTLP/HTTP log record; no Collector is required in between.

Getting Started

npm install zerilog @zerilog/opentelemetryzink
pnpm add zerilog @zerilog/opentelemetryzink
yarn add zerilog @zerilog/opentelemetryzink

Usage

import { LoggerConfiguration } from "zerilog";
import OpenTelemetryZink from "@zerilog/opentelemetryzink";

const logger = new LoggerConfiguration()
  .writeTo.zink(
    new OpenTelemetryZink({
      endpoint: "https://otelcol:4318",
      headers: { Authorization: "Bearer <token>" },
      resourceAttributes: {
        "service.name": "my-api",
        "deployment.environment": "prod",
      },
    }),
  )
  .createLogger();

logger.information("Hello {Name}!", "World");

Configuration

| Option | Required | Default | Description | | -------------------- | -------- | -------- | ----------------------------------------------------------------------------------------------------------------- | | endpoint | ✅ | — | Base URL of the OTLP receiver. For http the logs path (/v1/logs) is appended; for grpc the scheme selects TLS (https://) vs insecure (http://). | | protocol | | "http" | "http" (OTLP/JSON, typically port 4318) or "grpc" (LogsService/Export, typically port 4317). | | headers | | {} | Sent with every request: HTTP headers, or gRPC metadata. E.g. { Authorization: "Bearer <token>" }. | | resourceAttributes | | {} | OTLP resource attributes attached to every batch (e.g. service.name, or backend routing keys). | | batchSizeLimit | | 50 | Maximum number of log records sent in a single batch. | | batchTimeout | | 5000 | How often (ms) the batch is flushed. | | maxRetries | | 3 | Times a failed batch is retried before its events are dropped. |

How It Works

Events are buffered in memory and flushed either when batchSizeLimit records accumulate or every batchTimeout milliseconds — over HTTP (POST /v1/logs, port 4318) or gRPC (LogsService/Export, port 4317) depending on protocol. Each Zerilog level maps to the matching OTLP severity number (Information9/INFO, Error17/ERROR, …), the rendered message becomes the log record body, and message properties become OTLP log attributes. Failed batches are requeued and retried up to maxRetries times before being dropped.

Flushing on shutdown

Before a short-lived process exits, make sure the last buffered batch is sent. await flush() sends it and waits for delivery; await using does the same automatically when the binding goes out of scope:

await using zink = new OpenTelemetryZink({ endpoint: "…", protocol: "grpc" });
// … log … ; the batch is flushed and the transport closed at end of scope.

Plain using (or [Symbol.dispose]()) is best-effort only — it can't await the final send, so over gRPC the channel may close before it completes.

Example: Berserk

Berserk ingests OTLP directly. Authenticate with an ingest token and route to a table via the bzrk.table resource attribute. Hosted Berserk ingresses commonly expose gRPC (4317) rather than HTTP (4318):

new OpenTelemetryZink({
  protocol: "grpc",
  endpoint: "https://ingest.bzrk.dev:4317",
  headers: { Authorization: "Bearer ing_YOUR_INGEST_TOKEN" },
  resourceAttributes: { "bzrk.table": "default" },
});

Create an ingest token with the Berserk CLI (it's only shown once):

bzrk ingest-token create --table default my-token

Verify data is flowing:

bzrk search "default | take 10" --since "5m ago"

Contact