2.2.0 • Published 25 days ago

typescript-logging-node-channel v2.2.0

Weekly downloads
-
License
Apache-2.0
Repository
github
Last release
25 days ago

Typescript Logging Node Channel

This channel can be used for node and provides support for log files and rollover of files. The channel is new since 2.2.0 (feedback is welcome).

Getting started

Before the channel can be used, you should first install typescript-logging and a style. For example:

npm install --save typescript-logging  # Core is always required
npm install --save typescript-logging-category-style # One style is required

For more details about the logging library and/or flavors, please see: typescript-logging.

With the logging library installed, you can then install this node channel:

npm install --save typescript-logging-node-channel

The node channel is a custom channel which can be configured for typescript-logging library (again please look in the documentation of the main logging library for details).

The following example defines a log configuration to be used for node, that configures and uses the node LogChannel.

// LogConfig.ts
import {LogLevel} from "typescript-logging";
import {Category, CategoryProvider} from "typescript-logging-category-style";
import {NodeChannelProvider} from "typescript-logging-node-channel";

// Create the node channel, which writes the log files to a dist/log directory. Uses default settings.
const channel = NodeChannelProvider.createLogChannel(
  NodeChannelProvider.createRetentionStrategyMaxFiles({
    directory: "dist/log"
  })
);

// Create a provider
const provider = CategoryProvider.createProvider("TestProvider", {
  level: LogLevel.Info,
  channel
});

// Export function which creates a logger with given name
export function getLogger(name: string): Category {
  return provider.getCategory(name);
}

The following node-express example gets a new logger, and logs for two end points.

// app.ts (node-express example)
import express, {Express, Request, Response} from "express";
import {getLogger} from "./config/LogConfig.js";

const app: Express = express();
const port = process.env.PORT || 3000;

const log = getLogger("app.ts");

app.get("/", (req: Request, res: Response) => {
  log.info(() => "This is a logging message for / endpoint");

  res.send("Some nice response");
});

app.get("/test", (req: Request, res: Response) => {
  log.info(() => "This is a logging message for /test endpoint");

  res.send(`Write a response`);
});

app.listen(port, () => {
  console.log(`[server]: Server is running at http://localhost:${port}`);
});

Configuration

There are two node channels available:

  • LogChannel, can be created using NodeChannelProvider.createLogChannel(..)
  • RawLogChannel, can be created using NodeChannelProvider.createRawLogChannel(..)

LogChannel uses a pre-defined way of how log messages are written.

RawLogChannel instead allows full customization of the log message. For details on channels please see the main documentation of typescript-logging.

The created channel must be passed along to the log provider you originally picked (CategoryServiceProvider in the example here).

RetentionStrategy

When creating a node channel you must pass along a RetentionStrategy. The channel ships with one out of the box which can be created using: NodeChannelProvider.createRetentionStrategyMaxFiles(..). The RetentionStrategy determines where to log files, the naming, the size and rollover of files.

The following shows the options available (from source):

/**
 * Specifies the retention options to use when logging to files. Only directory is required, the others have sane
 * defaults but can be set differently if needed. See respective properties for details.
 *
 * Defaults to: maximum 10 files, 1 file maximum size of 10 MegaBytes, encoding utf-8, namePrefix: application, extension: .log .
 *
 * Default logs to: [directory]/[namePrefix][number][extension] (e.g. application1.log, application2.log etc. based on defaults).
 */
export interface RetentionStrategyMaxFilesOptions {
  /**
   * Directory to write the log files in, if it does not exist an attempt is made to create the path. If that fails
   * the logging will bail out with an Error as logging would be impossible.
   */
  readonly directory: string;

  /**
   * The encoding to use to read/write log files, default is utf-8.
   */
  readonly encoding?: BufferEncoding;

  /**
   * The prefix name for a file, the default is 'application'
   */
  readonly namePrefix?: string;

  /**
   * The extension of the file, the default is '.log'
   */
  readonly extension?: string;

  /**
   * The maximum size of a file, defaults to 10 MB (MegaBytes). When full (or the next written log line does not fit) rolls over to the next file.
   */
  readonly maxFileSize?: FileSize;

  /**
   * The maximum number of log files to keep around, defaults to 10. When the maximum is reached, the oldest file is deleted and writing starts
   * anew for that file.
   */
  readonly maxFiles?: number;
}

Only directory needs to be specified, the rest uses defaults.

Custom retention

If you'd like a different strategy, you can implement the RetentionStrategy interface.

/**
 * Retention strategy used by the NodeLogChannel.
 */
export interface RetentionStrategy {
  /**
   * The maximum file size allowed (when writing something > than this threshold a rollover will happen)
   */
  maxFileSize: FileSize;

  /**
   * Encoding to use for writing files (or listing them)
   */
  encoding: BufferEncoding;

  /**
   * Called when the NodeLogChannel wants to write a message the first time, this is only called once and allows for initialization/cleanup if needed.
   *
   * @param onRollOver Optional rollover function to be called when rollover occurs (when the user specified one when creating a channel, undefined otherwise.
   *                   Note that the actual function may not be what the user set as it can and will be wrapped in the default implementation.
   */
  initialize(onRollOver?: (path: fs.PathLike) => void): void;

  /**
   * Called by the channel when it needs the next file to write to, *must* return the next file path to write to as well as
   * the current size of it when it exists, 0 if it doesn't exist (or empty file).
   *
   * @param mustRollOver When mustRollOver is true must rollover to the next file, even if the last file is not full yet.
   */
  nextFile(mustRollOver: boolean): [path: fs.PathLike, size: number];
}

Please read the respective documentation of this interface, on what is expected exactly.