simple-logger

A lightweight and minimal logging system for typescript projects.

View on GitHub

Simple Logger

A lightweight, flexible logging system for CourseBook that supports namespace-based logging with different log levels.

Features:

Installation

npm install @madooei/simple-logger

Usage

A lightweight, flexible logging system for CourseBook that supports namespace-based logging with different log levels.

Basic Usage

import { LogManagerImpl, type Logger } from "@madooei/simple-logger";

// Get the logger instance
const logManager = LogManagerImpl.getInstance();

// Create a logger for your component
const logger: Logger = logManager.getLogger("myapp:component");

// Log at different levels
logger.trace("Detailed debugging");
logger.info("General information");

Setting Log Levels

// Set level for specific namespace
logManager.setLogLevel("myapp:component", "info");

// Set level for all components in 'myapp'
logManager.setLogLevel("myapp:*", "info");

// Use regex pattern
logManager.setLogLevel(/test:\d+/, "trace");

// Set default level for everything
logManager.setLogLevel("*", "info");

Namespace Patterns

Log Levels

  1. trace - Verbose debugging information
  2. info - Informational messages and errors

When you set a log level, all levels of equal or higher severity will be logged:

Why Only Two Log Levels?

info is the default level for regular logging. It covers everything you would normally output with console.log, including warnings and errors that should be visible in production. trace is solely for debugging and is typically enabled only for a specific namespace during development. Restricting the hierarchy to these two levels keeps configuration simple while still letting you turn on detailed logs without flooding the console.

Enable/Disable Logging

// Disable all logging
logManager.disable();

// Re-enable logging
logManager.enable();

Object Logging

Objects are automatically pretty-printed:

logger.info("Processing config", {
  server: "localhost",
  port: 3000,
});

// Output:
// [INFO] [myapp:component] Processing config {
//   "server": "localhost",
//   "port": 3000
// }

Example Component Integration

export class FileManager {
  private logger: Logger;

  constructor() {
    this.logger = LogManagerImpl.getInstance().getLogger("filemanager");
  }

  async readFile(path: string): Promise<Buffer> {
    this.logger.trace("Reading file:", path);
    try {
      const content = await readFile(path);
      this.logger.info("Successfully read file:", path);
      return content;
    } catch (error) {
      this.logger.info("Failed to read file:", path, error);
      throw error;
    }
  }
}

Custom Log Functions

You can customize how logs are output by providing a custom log function:

import { LogManagerImpl, type LogFunction } from "@madooei/simple-logger";

const logManager = LogManagerImpl.getInstance();

// Custom log function that formats differently
const customLogFunction: LogFunction = (level, namespace, ...args) => {
  const timestamp = new Date().toISOString();
  const message = `${timestamp} [${level.toUpperCase()}] ${namespace}: ${args.join(" ")}`;
  console.log(message);
};

// Set the custom log function
logManager.setLogFunction(customLogFunction);

// Now all loggers will use your custom function
const logger = logManager.getLogger("myapp");
logger.info("This will use custom formatting");

// Reset to default console.log behavior
logManager.resetLogFunction();

VSCode Extension Example

import * as vscode from "vscode";
import { LogManagerImpl, type LogFunction } from "@madooei/simple-logger";

const vscodeLogFunction: LogFunction = (level, namespace, ...args) => {
  const message = `[${level.toUpperCase()}] [${namespace}] ${args.join(" ")}`;
  vscode.window.showInformationMessage(message);
};

const logManager = LogManagerImpl.getInstance();
logManager.setLogFunction(vscodeLogFunction);

// Now logs appear as VSCode information messages
const logger = logManager.getLogger("extension:main");
logger.info("Extension activated!");

Custom Formatting Examples

// Colorized console output
const colorLogFunction: LogFunction = (level, namespace, ...args) => {
  const colors = { trace: "\x1b[36m", info: "\x1b[32m" };
  const reset = "\x1b[0m";
  const color = colors[level] || "";

  console.log(
    `${color}[${level.toUpperCase()}]${reset} ${namespace}:`,
    ...args,
  );
};

// JSON structured logging
const jsonLogFunction: LogFunction = (level, namespace, ...args) => {
  const logEntry = {
    timestamp: new Date().toISOString(),
    level: level.toUpperCase(),
    namespace,
    message: args.join(" "),
  };
  console.log(JSON.stringify(logEntry));
};

// Multiple outputs
const multiOutputLogFunction: LogFunction = (level, namespace, ...args) => {
  const message = `[${level.toUpperCase()}] [${namespace}] ${args.join(" ")}`;

  console.log(message); // Console
  sendToLogServer(message); // External logging
  writeToFile(message); // File logging
};

Features

Cloning the Repository

To make your workflow more organized, it’s a good idea to clone this repository into a directory named simple-logging-workspace. This helps differentiate the workspace from the simple-logger located in the packages directory.

git clone https://github.com/madooei/simple-logger simple-logging-workspace

cd simple-logging-workspace

Repository Structure

How to Use This Repo

Using a VSCode Multi-root Workspace

With Visual Studio Code, you can enhance your development experience by using a multi-root workspace to access packages, examples, and playgrounds simultaneously. This approach is more efficient than opening the root directory, or each package or example separately.

To set up a multi-root workspace:

  1. Open Visual Studio Code.
  2. Navigate to File > Open Workspace from File....
  3. Select the simple-logger.code-workspace file located at the root of the repository. This action will open all specified folders in one workspace.

The simple-logger.code-workspace file can be customized to include different folders or settings. Here’s a typical configuration:

{
  "folders": [
    {
      "path": "packages/simple-logger"
    },
    {
      "path": "examples/simple"
    },
    {
      "path": "playgrounds/empty"
    }
  ],
  "settings": {
    // Add any workspace-specific settings here, for example:
    "git.openRepositoryInParentFolders": "always"
  }
}

Developing the Package

Change to the package directory and install dependencies:

cd packages/simple-logger
npm install

Package Management

When you are ready to publish your package:

npm run release

This single command will:

[!TIP] For detailed information about package publishing, versioning, and local development workflows, see the NPM Package Management Guide.