plugin-logger.js

/**
 * @module kadence/logger
 */

'use strict';

const { Transform } = require('node:stream');
const bunyan = require('bunyan');


/**
 * Logs all incoming messages
 */
class IncomingMessageLogger extends Transform {

  /**
   * @constructor
   * @param {AbstractNode~logger} logger - Logger to use
   */
  constructor(logger) {
    super({ objectMode: true });
    this.logger = logger;
  }

  /**
   * @private
   */
  _transform(data, enc, callback) {
    let [rpc, ident] = data;

    if (!ident.payload.params[0] || !ident.payload.params[1]) {
      return callback();
    }

    if (rpc.payload.method) {
      this.logger.info(
        `received ${rpc.payload.method} (${rpc.payload.id}) from ` +
        `${ident.payload.params[0]} ` +
        `(${ident.payload.params[1].hostname}:` +
        `${ident.payload.params[1].port})`
      );
    } else {
      this.logger.info(
        `received response from ${ident.payload.params[0]} to ` +
        `${rpc.payload.id}`
      );
    }

    callback(null, data);
  }

}

/**
 * Logs all outgoing messages
 */
class OutgoingMessageLogger extends Transform {

  /**
   * @constructor
   * @param {AbstractNode~logger} logger - Logger to use
   */
  constructor(logger) {
    super({ objectMode: true });
    this.logger = logger;
  }

  /**
   * @private
   */
  _transform(data, enc, callback) {
    let [rpc,, recv] = data;

    if (!recv[0] || !recv[1]) {
      return callback();
    }

    if (rpc.method) {
      this.logger.info(
        `sending ${rpc.method} (${rpc.id}) to ${recv[0]} ` +
        `(${recv[1].hostname}:${recv[1].port})`
      );
    } else {
      this.logger.info(
        `sending response to ${recv[0]} for ${rpc.id}`
      );
    }

    callback(null, data);
  }

}

/**
 * Attaches a verbose logger to a {@link AbstractNode}
 * @param {AbstractNode~logger} [logger] - Custom logger
 */
module.exports = function(logger) {
  logger = logger = bunyan.createLogger({ name: 'kadence' });

  return function(node) {
    node.rpc.deserializer.append(() => new IncomingMessageLogger(logger));
    node.rpc.serializer.prepend(() => new OutgoingMessageLogger(logger));

    return logger;
  };
};

module.exports.IncomingMessage = IncomingMessageLogger;
module.exports.OutgoingMessage = OutgoingMessageLogger;