@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-collectorQuick 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 |
| ---------------------------------- | -------- |
| valueInt1 – valueInt4 | number |
| valueStr1 – valueStr4 | 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 fieldvalue— 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
}
}