ostrio:logger

v2.1.1Published 4 months ago

support support

Isomorphic logging driver

Logger driver for Meteor.js with different adapters. To use this package install an adapter (separately):

  • File - Store application log messages into the file (FS), log rotation included;
  • Mongo - Store application log messages into MongoDB;
  • Console - Print Client's application log messages to Server's console, messages colorized for better readability.

Features:

  • 👷‍♂️ 100% tests coverage;
  • 💪 Flexible log level filters, ex: write FATAL, ERROR, and WARN to file, DEBUG to console, and all other to MongoDB;
  • 👨‍💻 userId is automatically passed and logged, data is associated with logged-in user;
  • 📟 Pass logs from Client to Server;
  • 🕷 Catch all browser's errors.

Meteor Logger Library

Installation:

meteor add ostrio:logger

ES6 Import:

1import { Logger } from 'meteor/ostrio:logger';

Usage

Initiate a logger and pass it into the adapter constructor

Logger [Isomorphic]

1const log = new Logger();
2
3/* Activate adapters with default settings */
4/* meteor add ostrio:loggerfile */
5new LoggerFile(log).enable();
6/* meteor add ostrio:loggermongo */
7new LoggerMongo(log).enable();
8/* meteor add ostrio:loggerconsole */
9new LoggerConsole(log).enable();
10
11/* Log message
12 * message {String|Number} - Any text message
13 * data    {Object} - [optional] Any additional info as object
14 * userId  {String} - [optional] Current user id
15 */
16log.info(message, data, userId);
17log.debug(message, data, userId);
18log.error(message, data, userId);
19log.fatal(message, data, userId);
20log.warn(message, data, userId);
21log.trace(message, data, userId);
22log._(message, data, userId); //--> Plain shortcut
23
24/* Use with throw */
25throw log.error(message, data, userId);

Catch-all Client's errors example: [CLIENT]

1/* Store original window.onerror */
2const _GlobalErrorHandler = window.onerror;
3
4window.onerror = function (msg, url, line) {
5  log.error(msg, {file: url, onLine: line});
6  if (_GlobalErrorHandler) {
7    _GlobalErrorHandler.apply(this, arguments);
8  }
9};

Catch-all Server's errors example: [Server]

1const bound = Meteor.bindEnvironment((callback) => {callback();});
2process.on('uncaughtException', function (err) {
3  bound(() => {
4    log.error('Server Crashed!', err);
5    console.error(err.stack);
6    process.exit(7);
7  });
8});

Catch-all Meteor's errors example: [Server]

1// store original Meteor error
2const originalMeteorDebug = Meteor._debug;
3Meteor._debug = (message, stack) => {
4  const error = new Error(message);
5  error.stack = stack;
6  log.error('Meteor Error!', error);
7  return originalMeteorDebug.apply(this, arguments);
8};

Register new adapter [Isomorphic]

Mainly should be used by adapter developers, a.k.a. developer API.

1/**
2 * Logger#add() — register new adapter
3 * 
4 *  Emitter function
5 * name        {String}    - Adapter name
6 * emitter     {Function}  - Function called on Meteor.log...
7 * init        {Function}  - Adapter initialization function
8 * denyClient  {Boolean}   - Strictly deny execution on client
9 * denyServer  {Boolean}   - Strictly deny execution on server
10 * Example: log.add(name, emitter, init, denyClient, denyServer);
11 */
12
13const emitter = (level, message, data, userId) => {
14  /* .. do something with a message .. */
15};
16
17const init = () => {
18  /* Initialization function */
19  /* For example create a collection */
20  log.collection = new Meteor.Collection('logs');
21};
22
23log.add('AdapterName', emitter, init, true, false);

Enable/disable adapter and set its settings [Isomorphic]

1/**
2 * Logger#rule() — register adapter default rules
3 *
4 * name    {String} - Adapter name
5 * options {Object} - Settings object, accepts next properties:
6 * options.enable {Boolean} - Enable/disable adapter
7 * options.filter {Array}   - Array of strings, accepts:
8 *                            'ERROR', 'FATAL', 'WARN', 'DEBUG', 'INFO', '*'
9 *                            in lowercase and uppercase
10 *                            default: ['*'] - Accept all
11 * options.client {Boolean} - Allow execution on Client
12 * options.server {Boolean} - Allow execution on Server
13 * Example: log.rule(name, options);
14 */
15
16/* Example: */
17log.rule('AdapterName', {
18  enable: true,
19  filter: ['ERROR', 'FATAL', 'WARN'],
20  client: false, /* Allow to call, but not execute on Client */
21  server: true   /* Calls from client will be executed on Server */
22});

Running Tests

  1. Clone this package
  2. In Terminal (Console) go to directory where package is cloned
  3. Then run:

Meteor/Tinytest

# Default
meteor test-packages ./

# With custom port
meteor test-packages ./ --port 8888

# With local MongoDB and custom port
MONGO_URL="mongodb://127.0.0.1:27017/logger-tests" meteor test-packages ./ --port 8888

Support our open source contribution: