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

@morescreens/log-collector

v0.0.8

Published

Structured logging library for client applications.

Readme

@morescreens/log-collector

Structured logging library for client applications.

Features

  • Multiple log types — standard logs, watching activity telemetry, and push notification logging
  • Log levels — Debug, Info, Warn, Error, Critical with configurable minimum level
  • Two-phase init — construct with minimal config, call configure() later when remaining fields are available
  • Singleton — create once, retrieve anywhere with Logger.getInstance()
  • Session tracking — auto-generated session ID per Logger instance, included in standard log payloads for grouping logs from the same session
  • Auto-retry with priority buffer — failed sends are buffered and retried with configurable buffer size
  • TypeScript-first — full type definitions, ESM only

Installation

npm install @morescreens/log-collector

Quick Start

import { Logger, LogLevel, LogValidationError } from "@morescreens/log-collector"
import type { LoggerOptions, LogEntry, WatchActivityEntry } from "@morescreens/log-collector"

// 1. Create the singleton (only logSource is required)
const logger = new Logger({ logSource: "my-app" })

// 2. Configure remaining fields when available
logger.configure({
  collectorUrl: "https://collector.example.com/log",
  installation: "abc-123",
  uuid: "device-uuid",
  applicationInstallationId: "42",
  applicationPublicationId: "pub-1",
  cappVersion: "1.0.0",
  timezone: "Europe/Sarajevo",
  logLevel: LogLevel.Warn,
})

// 3. Send logs
logger.warn({ message: "Retry attempt failed" })
logger.error({ message: "Something failed", tag: "network" })

// 4. Retrieve the singleton from anywhere
const same = Logger.getInstance()

Log Types

Standard Logs

General-purpose application logging with five severity levels. Messages below the configured logLevel are discarded.

| Method | Level | Enum Value | | ---------- | -------- | ---------- | | debug | Debug | 2 | | info | Info | 3 | | warn | Warn | 4 | | error | Error | 5 | | critical | Critical | 6 |

logger.debug({ message: "EPG data loaded" })
logger.info({ message: "Channel changed", tag: "ZappLog" })
logger.warn({ message: "Retry attempt failed", valueStr1: url, valueInt1: retryCount })
logger.error({ message: "API request failed", valueStr1: "GET /api/channels", valueStr2: "503" })
logger.critical({ message: `${err.message} stack: ${err.stack}` })

Each method accepts a LogEntry:

| Field | Type | Required | | ------------ | -------- | -------- | | message | string | Yes | | tag | string | No | | targetIndex| string | No |

Additional optional fields:

| Field | Type | | ---------------------------------- | -------- | | valueInt1valueInt4 | number | | valueStr1valueStr4 | string |

Watching Activity

Content viewing telemetry sent via sendWatchingActivity(). Used to track what users are watching, with metadata about the content and series. Automatically sets targetIndex to "watching_activity_log".

logger.sendWatchingActivity({
  message: "PLAY",
  contentId: "12345",
  contentKind: "vod",
  intervalDuration: 30,
})

| Field | Type | Required | | ---------------------- | --------- | -------- | | message | string | Yes | | contentId | string | Yes | | contentExternalId | string | No | | contentAssetType | string | No | | contentKind | string | No | | contentAudioOnly | boolean | No | | contentOriginalTitle | string | No | | contentProviderName | string | No | | contentSeriesId | string | No | | deliveryMethod | string | No | | seriesTitle | string | No | | seriesOriginalTitle | string | No | | seriesSeason | number | No | | seriesEpisode | number | No | | epgId | string | No | | epgTitle | string | No | | intervalDuration | number | No | | catchupTime | number | No | | partnerName | string | No | | valueInt | number | No | | valueStr | string | No |

Push Notifications

Logs push notification events via sendPushNotification(). Automatically sets targetIndex to "push_notification_log".

logger.sendPushNotification({ message: "Notification received" })

Accepts the same LogEntry shape as standard logs.

API Reference

new Logger(options)

Creates the singleton Logger instance. Only logSource is required at construction; all other fields can be set later via configure(). Calling new Logger() again replaces the singleton.

Logger.getInstance()

Returns the singleton instance. Throws if no Logger has been created yet.

configure(partial)

Merges additional options into the current configuration. Validates the merged result. Can be called multiple times — each call merges on top of the previous state, so you can progressively provide fields as they become available.

// Set URL early
logger.configure({ collectorUrl: "https://collector.example.com/log" })

// Add user context later when available
logger.configure({ profileId: "user-42", subscriberId: "sub-7" })

Configuration

All fields in LoggerOptions. Fields marked "Required at send" must be set (via constructor or configure()) before calling any send method — otherwise a LogValidationError is thrown.

| Field | Type | Required at init | Required at send | Default | | --------------------------- | ---------- | ---------------- | ---------------- | ------- | | logSource | string | Yes | Yes | — | | collectorUrl | string | No | Yes | — | | installation | string | No | Yes | — | | uuid | string | No | Yes | — | | applicationInstallationId | string | No | Yes | — | | applicationPublicationId | string | No | Yes | — | | cappVersion | string | No | Yes | — | | timezone | string | No | Yes | — | | logLevel | LogLevel | No | No | Info | | enableConsoleLog | boolean | No | No | false | | maxBufferSize | number | No | No | 100 | | profileId | string | No | No | — | | subscriberId | string | No | No | — |

Buffering & Retry

Failed HTTP sends are automatically buffered and retried on the next send attempt. The buffer holds up to maxBufferSize entries (default: 100) and can be configured via the constructor or configure():

const logger = new Logger({ logSource: "my-app", maxBufferSize: 200 })

When the buffer is full, low-priority logs (below Error) are evicted first to preserve error and critical entries. If the buffer is entirely error/critical, the oldest entry is evicted to make room for new high-priority logs.

When buffered messages are retried, they are sent with [buffered][datetime] appended to the original message, making them identifiable in the logs.

Error Handling

The library throws LogValidationError when options or entries contain invalid values. It extends Error and includes:

  • field — the name of the invalid field
  • value — the offending value
import { LogValidationError } from "@morescreens/log-collector"

try {
  logger.info({ message: 123 as any })
} catch (err) {
  if (err instanceof LogValidationError) {
    console.error(err.field) // "message"
    console.error(err.value) // 123
  }
}