1.2.1 • Published 3 months ago

@leaflink/snitch v1.2.1

Weekly downloads
-
License
MIT
Repository
github
Last release
3 months ago

@leaflink/snitch

Contact Us Released via semantic-release

Simple and extensible browser logging, inspired by Winston.

Table of Contents

Installation

$ npm i @leaflink/snitch

Transports

Transports are a way of routing log messages to multiple destinations, with the ability to pre-process or format the message. @leaflink/snitch includes three transports by default (console, Sentry, and Datadog), but they can be extended using the Transport type exported by the logger.

Log Levels

Transports can be created with a log level to only handle messages with a certain severity. Log levels supported by @leaflink/snitch, in decreasing order by severity, are:

  • error
  • warn
  • info
  • debug

These levels cascade up, so a transport created with level debug will handle logs with that level as well as info, warn, and error, but a transport created with level error will not handle logs with the levels warn, info, or debug.

The level a log was called at is passed to transports to help determine how a message should be handled (for example, logging with console.<level> in the console transport).

Usage

Singleton Logger

The default export exposed by @leaflink/snitch is a singleton logger instance with no initial transports, which can be shared between modules easily. It does not include any transports by default to allow flexibility in per-environment transports.

import logger from '@leaflink/snitch';
import { ConsoleTransport } from '@leaflink/snitch/transports/console';

if (config.debug) {
  logger.addTransport(new ConsoleTransport());
}

New Logger

NameDefaultDescription
transports[]Define transports when creating new logger instead of adding with .addTransport

In other situations, you may want to have a logger instance (or multiple instances) created and managed inside your application. To support this, @leaflink/snitch also exports a Logger class that can be used to create logger instances, optionally with predefined transports.

import { Logger } from '@leaflink/snitch';
import { ConsoleTransport } from '@leaflink/snitch/transports/console';

const loggerInstance = new Logger({
  transports: [new ConsoleTransport()],
});

// `logger.log` is an alias for `logger.info` for convenience
loggerInstance.log('Example log message');

Console Transport

Parameters:

NameDefaultDescription
leveldebugMinimum log level to handle.

main.ts

import logger from '@leaflink/snitch';
import { ConsoleTransport } from '@leaflink/snitch/transports/console';

logger.addTransport(new ConsoleTransport());

call in component file

import logger from '@leaflink/snitch';

try {
  await someErroringMethod()
} catch (err) {
  logger.error(err)
}

Sentry Transport

Parameters:

NameDefaultDescription
leveldebugMinimum log level to handle.
sentryInstanceN/A, requiredInitialized Sentry logger instance.

main.ts

import * as Sentry from '@sentry/vue';
import logger from '@leaflink/snitch';
import { SentryTransport } from '@leaflink/snitch/transports/sentry';

// Important: init Sentry instance before creating transport
Sentry.init({
  // ...
});
logger.addTransport(new SentryTransport({
  sentryInstance: Sentry,
}));

call in component file

import logger from '@leaflink/snitch';

try {
  await someErroringMethod()
} catch (err) {
  // optional error context object
  const errorContext: Record<string, any> = getErrorContext();
  // `err` is Error | string
  logger.error(err, errorContext);
}

Datadog Logs Transport

Parameters:

NameDefaultDescription
levelinfoMinimum log level to handle.
datadogLogsInstanceN/A, requiredInitialized Datadog Logs instance.

See Datadog Logs documentation for more on custom logging with Datadog.

main.ts

import { datadogLogs } from '@datadog/browser-logs';
import logger from '@leaflink/snitch';
import { DatadogTransport } from '@leaflink/snitch/transports/datadog';

// Important: init Datadog logs instance before creating transport
datadogLogs.init({
  // ...
});
logger.addTransport(new DatadogTransport({
  datadogLogsInstance: datadogLogs,
}));

call in component file

import logger from '@leaflink/snitch';

logger.info('File loaded!');

try {
  await someErroringMethod()
} catch (err) {
  // If an Error is passed as the message, this is captured as an exception in Datadog
  logger.error(err, { id: 123 });
}

With Log Level

main.ts

import logger from '@leaflink/snitch';
import { ConsoleTransport } from '@leaflink/snitch/transports/console';

logger.addTransport(new ConsoleTransport({
  level: 'info'
}));

Custom Transports

custom-transport.ts

import { LogLevel, Transport } from '@leaflink/snitch';
// imagine this has a `report(options<{message, context}>)` method
import CustomDestinationInstance from '@example/destination';

interface CustomTransportOptions {
  level?: LogLevel;
}

export class CustomTransport implements Transport {
  level: LogLevel;
  log: (message: string | object, meta: Record<string, unknown> | undefined, level: LogLevel) => void;

  constructor(opts?: ConsoleTransportOptions) {
    this.level = opts?.level || 'debug';
    this.log = (message, meta) => {
      CustomDestinationInstance.report({
        message,
        context: 'meta',
      })
    };
  }
}

main.ts

import logger from '@leaflink/snitch';
import { CustomTransport } from './custom-transport';

logger.add(new CustomTransport());

Note: You can add a custom transport in your project, but consider opening a PR in this repo instead!

Testing

Stubbing snitch

When there's a need to mock this logger or you want to test if a specific log was printed, you can just mock it inside you test file:

import logger from '@leaflink/snitch';

vi.mock('@leaflink/snitch');

it('should redirect to error page if fetching the user profile fails', async () => {
  // ...
  expect(logger.error).toHaveBeenCalled();
})
1.2.1

3 months ago

1.2.0

5 months ago

1.1.1

12 months ago

0.0.0-PR-9--485911b

12 months ago

1.1.0

1 year ago

1.0.1

1 year ago

1.0.0

1 year ago