From f6a27973c6c63032eb983ba05cacb75b5b073359 Mon Sep 17 00:00:00 2001 From: prasanthVijayy Date: Thu, 17 Oct 2024 15:08:46 +0530 Subject: [PATCH] Logging system solution --- .../logging-system.md | 44 +++++++++++++ .../logging-system/log.js | 66 +++++++++++++++++++ .../logging-system/main.js | 17 +++++ 3 files changed, 127 insertions(+) create mode 100644 Learning_2.0/Problems/Behavioural-pattern-problems/logging-system.md create mode 100644 Learning_2.0/Solutions/Behavioural-pattern-solutions/logging-system/log.js create mode 100644 Learning_2.0/Solutions/Behavioural-pattern-solutions/logging-system/main.js diff --git a/Learning_2.0/Problems/Behavioural-pattern-problems/logging-system.md b/Learning_2.0/Problems/Behavioural-pattern-problems/logging-system.md new file mode 100644 index 0000000..7f3c71f --- /dev/null +++ b/Learning_2.0/Problems/Behavioural-pattern-problems/logging-system.md @@ -0,0 +1,44 @@ +# Chain of Responsibility Pattern: Logging System + +## Overview + +This project implements a **Logging System** using the **Chain of Responsibility Pattern**. The system allows log messages to be processed dynamically by different log handlers based on the severity level of the logs (e.g., Info, Warning, Error). Each handler can either log the message, pass it to the next handler, or perform a specific action based on the log type. + +## Features + +- **Multi-Level Logging**: Supports different levels of logging (Info, Warning, Error) with appropriate handlers for each level. +- **Dynamic Log Handling**: Each log handler can decide whether to process the log message or escalate it to the next handler based on its severity. +- **Customizable Log Flow**: The logging flow can be easily modified by adding or removing log handlers from the chain. +- **Flexible Output**: Log messages can be output to different destinations (console, file, external service) depending on the handler configuration. + +## Internal Structure + +1. **Handler (LogHandler)** + + - Defines the interface for processing log messages. + - Contains a reference to the next handler in the chain. + +2. **Concrete Handlers (ConsoleLogger, FileLogger, ErrorLogger)** + + - Implements logging logic for different severity levels: + - **ConsoleLogger**: Handles Info logs and prints them to the console. + - **FileLogger**: Handles Warning logs and writes them to a log file. + - **ErrorLogger**: Handles Error logs and sends them to an external monitoring service. + +3. **LogMessage (Log)** + + - Represents a log message with details such as severity level, timestamp, and message content. + +4. **Client Code** + - Creates a chain of log handlers and submits log messages for processing. + +## How to Use + +1. **Create Log Handlers**: Initialize different log handlers and set their responsibilities in the chain. +2. **Create Log Messages**: Instantiate log messages with appropriate severity levels. +3. **Process Log Messages**: Pass the log messages to the first handler in the chain for processing. +4. **View Logs**: Check the output destinations (console, file, monitoring service) for logged messages. + +## Solution + +You can find the solution to this problem in the [solution folder](/Learning_2.0/Solutions/Behavioural-pattern-solutions/logging-system/). diff --git a/Learning_2.0/Solutions/Behavioural-pattern-solutions/logging-system/log.js b/Learning_2.0/Solutions/Behavioural-pattern-solutions/logging-system/log.js new file mode 100644 index 0000000..d733262 --- /dev/null +++ b/Learning_2.0/Solutions/Behavioural-pattern-solutions/logging-system/log.js @@ -0,0 +1,66 @@ +const fs = require("fs"); + +// Abstract log class +class Log { + constructor(level, message) { + this.level = level; + this.message = message; + this.timestamp = new Date(); + } +} + +// Log handler +class LogHandler { + constructor(nextHandler = null) { + this.nextHandler = nextHandler; // Next handler in chain + } + + handle(log) { + if (this.nextHandler) { + this.nextHandler.handle(log); + } + } +} + +// Chains (types) of log handlers +class ConsoleLogger extends LogHandler { + handle(log) { + if (log.level === "info") { + console.log(`[INFO] - ${log.timestamp} - ${log.message}`); + } else { + super.handle(log); // pass to the next hanaler + } + } +} + +class FileLogger extends LogHandler { + handle(log) { + if (log.level === "Warning") { + const logMessage = `[WARNING] - ${log.timestamp} - ${log.message} \n`; + fs.appendFile("warnings.log", logMessage, (err) => { + if (err) { + console.log("Failed to write to file", err); + } + }); + } else { + super.handle(log); // pass to the next hanaler + } + } +} + +class ErrorLogger extends LogHandler { + handle(log) { + if (log.level === "Error") { + console.error(`[ERROR] ${log.timestamp}: ${log.message}`); // error console log + } else { + super.handle(log); // Pass to the next handler + } + } +} + +module.exports = { + Log, + ConsoleLogger, + FileLogger, + ErrorLogger, +}; diff --git a/Learning_2.0/Solutions/Behavioural-pattern-solutions/logging-system/main.js b/Learning_2.0/Solutions/Behavioural-pattern-solutions/logging-system/main.js new file mode 100644 index 0000000..1f9dde5 --- /dev/null +++ b/Learning_2.0/Solutions/Behavioural-pattern-solutions/logging-system/main.js @@ -0,0 +1,17 @@ +// main.js +const { Log, ConsoleLogger, FileLogger, ErrorLogger } = require("./log"); + +// Create the chain of log handlers +const errorLogger = new ErrorLogger(); +const fileLogger = new FileLogger(errorLogger); +const consoleLogger = new ConsoleLogger(fileLogger); + +// Create log messages +const infoLog = new Log("Info", "This is an info message."); +const warningLog = new Log("Warning", "This is a warning message."); +const errorLog = new Log("Error", "This is an error message."); + +// Process log messages +consoleLogger.handle(infoLog); // Console Logger handles it +consoleLogger.handle(warningLog); // File Logger handles it +consoleLogger.handle(errorLog); // Error Logger handles it