← Back to list

Enhancing iTwin.js Logging with Bunyan and Seq for Better Observability

Effective logging is crucial for monitoring and debugging modern applications. In iTwin.js applications, leveraging structured logging can…

Asad Bukhari · 2025-02-28 09:50 · 0 claps · 2.9 min read
#itwinjs #itwin-platform #seq #digital-twin
Open on Medium ↗
Wiki topics: RAG · RAG & Retrieval 💻 · Programming

Enhancing iTwin.js Logging with Bunyan and Seq for Better Observability

Effective logging is crucial for monitoring and debugging modern applications. In iTwin.js applications, leveraging structured logging can significantly improve the observability of backend services. This blog explores how to integrate Bunyan and Seq with iTwin.js — the library for developing infrastructure digital twin applications — to establish a efficient logging mechanism.

Seq integration with iTwin.js

Seq integration with iTwin.js

Why Use Bunyan and Seq?

Bunyan is a high-performance, JSON-based logger for Node.js that provides structured logs. Seq is a structured logging server that allows real-time search and analysis of logs with a rich query interface. Integrating these tools enhances log management by enabling structured logging with minimal performance overhead.

Here are the steps to implement logging in an iTwin.js application using Bunyan and Seq.

1. Setup Seq and Project

2. Install Dependencies

To get started, install the required dependencies:

npm install bunyan bunyan-seq @itwin/core-bentley dotenv
npm install --save-dev @types/bunyan

3. Configure Logging

Create a Logger.config.json file with the following content to define log levels:

{
  "loggerConfig": {
     "defaultLevel": "${LOG_LEVEL}",
     "categoryLevels": [
         {"category": "Logging.SeqIntegrated", "logLevel": "Trace"}
     ]
   }
}

Create a BackendLogger.ts file to initialize logging:

import { Logger, LoggerLevelsConfig } from "@itwin/core-bentley";
import bunyan from "bunyan";
import seq from "bunyan-seq";
import config from "./Logger.config.json";

/**
 * Creates and configures the Bunyan logger.
 */
function createBunyanLogger(): bunyan {
  return bunyan.createLogger({
    name: process.env.APP_NAME || "SeqLogger",
    streams: [
      {
        stream: process.stdout,
        level: process.env.LOG_LEVEL?.toLowerCase() as bunyan.LogLevel || "error",
      },
      seq.createStream({
        serverUrl: process.env.SEQ_URL || "http://127.0.0.1:5341",
        apiKey: process.env.SEQ_API_KEY || "",
        level: process.env.LOG_LEVEL?.toLowerCase() as bunyan.LogLevel || "error"
      })
    ]
  });
}

/**
 * Initializes logging for the application.
 */
export function initializeLogging(logLevel: string = "Error"): void {

  const bunyanLogger = createBunyanLogger();

  const bunyanLogFunction = (category: string, message: string, meta: any, level: string) => {
    switch (level.toLowerCase()) {
      case "error":
        bunyanLogger.error({ category, ...meta }, message);
        break;
      case "warn":
        bunyanLogger.warn({ category, ...meta }, message);
        break;
      case "info":
        bunyanLogger.info({ category, ...meta }, message);
        break;
      case "trace":
        bunyanLogger.trace({ category, ...meta }, message);
        break;
      default:
        bunyanLogger.info({ category, ...meta }, message);
        break;
    }
  };

  /*
   Note: The initialize will set the default log level to undefined and category to empty 
   Its important to set the default log level and configure after calling initialize
   */
  Logger.initialize(
    (category, message, meta) => bunyanLogFunction(category, message, meta, "error"),
    (category, message, meta) => bunyanLogFunction(category, message, meta, "warn"),
    (category, message, meta) => bunyanLogFunction(category, message, meta, "info"),
    (category, message, meta) => bunyanLogFunction(category, message, meta, "trace")
  );

  if ("loggerConfig" in config) {
    config.loggerConfig.defaultLevel = logLevel;
    Logger.validateProps(config.loggerConfig);
    Logger.configureLevels(config.loggerConfig as LoggerLevelsConfig);
  }
}

Note: The Logger initialize will set the default log level to undefined and category to empty. Its important to set the default log level and configure after calling initialize.

4. Initialize Logging

Create/Modify index.ts file to load environment variables and initialize logging:

import { Logger } from "@itwin/core-bentley";
import * as dotenv from "dotenv";
import { initializeLogging } from "./BackendLogger";

// Load environment variables from .env file
dotenv.config();

/**
 * Main function initializing logging
 * @async
 * @function main
 * @returns {Promise<void>}
 */
(() => {

  initializeLogging(process.env.LOG_LEVEL);

  Logger.logError("Logging.SeqIntegrated", "Logging Seq Error");
  Logger.logWarning("Logging.SeqIntegrated", "Logging Seq Warning");
  Logger.logInfo("Logging.SeqIntegrated", "Logging Seq Info");
  Logger.logTrace("Logging.SeqIntegrated", "Logging Seq Trace");

})();

5. Define Environment Variables

Create/update .env file to specify logging configurations:

APP_NAME=SeqIntegratedLogger
LOG_LEVEL=Trace
SEQ_URL=http://127.0.0.1:5341
SEQ_API_KEY=your-seq-api-key

You can generate SEQ_API_KEY from Seq admin API keys.

6. Build and Run the application

Build and run the application

npm run build
npm run start

Now, you should be able to find the logs in Seq.

Seq Logs

Seq Logs

Conclusion

By integrating Bunyan and Seq with iTwin.js, you can achieve powerful, structured logging for your backend services. This setup not only enhances debugging but also provides deep insights into application performance. For a full working example, visit the GitHub repository: SeqIntegrated Logging Sample.

Try implementing this in your iTwin.js project and take your logging capabilities to the next level!


메타데이터
post_id
bc0f54db9707
slug
enhancing-itwin-js-logging-with-bunyan-and-seq-for-better-observability-bc0f54db9707
url
https://medium.com/@asad_bukhari/enhancing-itwin-js-logging-with-bunyan-and-seq-for-better-observability-bc0f54db9707
canonical_url
https://medium.com/@asad_bukhari/enhancing-itwin-js-logging-with-bunyan-and-seq-for-better-observability-bc0f54db9707
author_url
https://medium.com/@asad_bukhari
status
ok
fetched_at
2026-06-26 06:47:43