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

mr-log

v0.1.1

Published

Type-safe client for sending project logs to the MR Logs service.

Readme

mr-log

mr-log is a type-safe client for sending application logs to the MR Logs service.

It sets the log severity from the method you call, so consumers cannot send a mismatched type value. Configure a project ID and application ID once; then send Fatal, Error, Warning, or Success logs with the event details and the user who caused the event.

Install

After the package has been published to your npm registry:

npm i mr-log

For local development in this workspace:

npm i ../mr-log

mr-log requires Node.js 18 or newer because it uses the built-in fetch API.

Quick Start

Configure the logger once when your application starts. The package uses the public ingestion gateway internally, so neither the gateway nor the private backend address belongs in application configuration. Copy the project ID and application ID from MR Logs, then pass actor with each log because the person or service performing the action can change during the lifetime of an application.

import { log, LogEnvironment } from 'mr-log';

log.configure({
  projectId: 12,
  applicationId: 34,
  environment: LogEnvironment.NonProd,
});

Write logs anywhere after configuration:

await log.Success({
  actor: 'S9107544',
  message: 'Inventory import completed',
  location: '/api/imports/inventory',
  action: 'POST',
});

Severity Methods

Each method chooses the only allowed severity for its log record. Do not pass a type field; the package sets it for you.

LogType is exported as an immutable runtime object and as a TypeScript union derived from that object. Use the same types in application contracts instead of maintaining separate message-type constants:

import { LogType, isLogType } from 'mr-log';

const severity: LogType = LogType.Error;

The named values are LogType.Fatal, LogType.Error, LogType.Warning, and LogType.Success.

isLogType(value) validates unknown data and narrows it to LogType. Only fatal, error, warning, and success are accepted. Legacy values such as Failure are not log types. This does not change severity methods: log.Success(details) still sets the severity itself.

import { log } from 'mr-log';

await log.Fatal({
  actor: 'S9107544',
  message: 'The inventory database is unavailable',
  location: '/api/inventory/sync',
  action: 'POST',
});

await log.Error({
  actor: 'S9107544',
  message: 'Unable to save stock adjustment',
  location: '/api/inventory/adjustments/42',
  action: 'PATCH',
});

await log.Warning({
  actor: 'S9107544',
  message: 'Supplier response exceeded the expected duration',
  location: '/api/suppliers',
  action: 'GET',
});

await log.Success({
  actor: 'S9107544',
  message: 'Stock adjustment saved',
  location: '/api/inventory/adjustments/42',
  action: 'PATCH',
});

These calls create the following values for the Logs table:

| Table field | Source | | --- | --- | | project_id | projectId from log.configure() | | service_domain_id | applicationId from log.configure() | | application | Current title of the application ID | | actor | Required actor supplied to the severity method | | occurred_at | Current UTC time, or occurredAt supplied to the method | | message | Required message supplied to the method | | type | Determined by Fatal, Error, Warning, or Success | | location | Optional location supplied to the method; it can be a route or file path. | | action | Optional typed action supplied to the method |

Configuration

import { log, LogEnvironment } from 'mr-log';

log.configure({
  projectId: 12,
  applicationId: 34,
  environment: LogEnvironment.Prod,
  timeoutMs: 3_000,
});

| Option | Required | Description | | --- | --- | --- | | projectId | Yes | Positive integer ID of the destination project. | | applicationId | Yes | Positive integer ID of the application in that project. | | environment | Yes | Service environment: LogEnvironment.NonProd, LogEnvironment.PreProd, or LogEnvironment.Prod. | | timeoutMs | No | Request timeout in milliseconds. Defaults to 5000. |

LogEnvironment is exported for both TypeScript and JavaScript consumers, with values nonprod, preprod, and prod. Missing or unsupported environments are rejected at configuration time. The environment is currently stored in client configuration only; it does not change the ingestion URL or add a field to the log payload.

Log Details

Every severity method accepts the same type-safe object:

await log.Warning({
  actor: 'S9107544',
  message: 'The source system was slow',
  location: '/api/suppliers',
  action: 'GET',
  occurredAt: new Date('2026-08-31T10:15:00.000Z'),
});

| Field | Required | Description | | --- | --- | --- | | actor | Yes | Person or service that performed the action. Maximum 120 characters. | | message | Yes | Log message. | | location | No | Related request route or file path. Maximum 2048 characters. | | action | No | One of GET, POST, PUT, PATCH, DELETE, HEAD, or OPTIONS. | | occurredAt | No | Date or parseable ISO date string. Defaults to the current UTC time. |

TypeScript prevents unsupported action values and does not expose a type field in the details object:

await log.Error({
  actor: 'S9107544',
  message: 'Invalid payload',
  action: 'POST',
  // type: 'success', // TypeScript error: the package controls log type.
});

Error Handling

Logging methods return a Promise<void>. Await a log when the caller needs to detect delivery failures; use void when logging must not interrupt the calling workflow.

import { log, MrLogConfigurationError, MrLogRequestError } from 'mr-log';

try {
  await log.Error({
    actor: 'S9107544',
    message: 'Could not retrieve inventory items',
    location: '/api/inventory/items',
    action: 'GET',
  });
} catch (error) {
  if (error instanceof MrLogConfigurationError) {
    // The logger was not configured or received invalid data.
  } else if (error instanceof MrLogRequestError) {
    // The Logs service returned a non-2xx response.
    console.error(error.status);
  }
}

For non-blocking logging:

void log.Success({
  actor: 'S9107544',
  message: 'Background task completed',
}).catch(() => undefined);

Multiple Configurations

The exported log value is a singleton. For isolated configurations, such as a multi-tenant worker or a test, create individual loggers:

import { createLogger, LogEnvironment } from 'mr-log';

const partnerLogger = createLogger();
partnerLogger.configure({
  projectId: 27,
  applicationId: 45,
  environment: LogEnvironment.PreProd,
});

await partnerLogger.Success({
  actor: 'PARTNER-WORKER',
  message: 'Partner import completed',
});

Project Examples

Create one logger for each service domain. Each logger keeps its own project and application IDs, while actor remains specific to the action being logged.

import { createLogger, LogEnvironment } from 'mr-log';

const inventoryLogger = createLogger();
inventoryLogger.configure({
  projectId: 12,
  applicationId: 34,
  environment: LogEnvironment.Prod,
});

await inventoryLogger.Success({
  actor: 'S9107544',
  message: 'Inventory import completed',
  location: '/api/imports/inventory',
  action: 'POST',
});

const ordersLogger = createLogger();
ordersLogger.configure({
  projectId: 27,
  applicationId: 56,
  environment: LogEnvironment.Prod,
});

await ordersLogger.Error({
  actor: 'S1234567',
  message: 'Unable to create order',
  location: '/api/orders',
  action: 'POST',
});

Browser Use

Use mr-log from a trusted backend service. Browser requests can reveal the public ingestion route and should be sent through your own backend instead.