@leaflink/snitch v1.6.1
@leaflink/snitch
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:
errorwarninfodebug
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
| Name | Default | Description |
|---|---|---|
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:
| Name | Default | Description |
|---|---|---|
level | debug | Minimum 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:
| Name | Default | Description |
|---|---|---|
level | debug | Minimum log level to handle. |
sentryInstance | N/A, required | Initialized 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:
| Name | Default | Description |
|---|---|---|
level | info | Minimum log level to handle. |
datadogLogsInstance | N/A, required | Initialized 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();
})12 months ago
11 months ago
10 months ago
12 months ago
12 months ago
9 months ago
9 months ago
11 months ago
12 months ago
11 months ago
12 months ago
12 months ago
9 months ago
10 months ago
12 months ago
11 months ago
9 months ago
9 months ago
11 months ago
9 months ago
12 months ago
12 months ago
10 months ago
10 months ago
12 months ago
12 months ago
10 months ago
12 months ago
12 months ago
12 months ago
10 months ago
12 months ago
10 months ago
12 months ago
12 months ago
12 months ago
12 months ago
11 months ago
12 months ago
9 months ago
12 months ago
11 months ago
9 months ago
12 months ago
11 months ago
11 months ago
9 months ago
10 months ago
12 months ago
12 months ago
9 months ago
10 months ago
12 months ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago