From 0976a506170912b592c5bc0551b51da1ceaee48f Mon Sep 17 00:00:00 2001 From: David Leal Date: Wed, 16 Jul 2025 09:28:44 -0400 Subject: [PATCH] documentation improvements --- CHANGELOG.md | 5 + README.md | 145 +++++++++++++++----- dist/logger.ts | 10 +- docs/typedoc/classes/AbstractAppender.html | 28 ++-- docs/typedoc/classes/ConsoleAppender.html | 32 ++--- docs/typedoc/classes/ExcelAppender.html | 36 ++--- docs/typedoc/classes/LayoutImpl.html | 18 +-- docs/typedoc/classes/LogEventImpl.html | 18 +-- docs/typedoc/classes/LoggerImpl.html | 54 ++++---- docs/typedoc/classes/ScriptError.html | 10 +- docs/typedoc/classes/Utility.html | 8 +- docs/typedoc/enums/LOG_EVENT.html | 4 +- docs/typedoc/interfaces/Appender.html | 10 +- docs/typedoc/interfaces/Layout.html | 6 +- docs/typedoc/interfaces/LogEvent.html | 12 +- docs/typedoc/interfaces/Logger.html | 40 +++--- docs/typedoc/types/LayoutFormatter.html | 2 +- docs/typedoc/types/LogEventExtraFields.html | 2 +- docs/typedoc/types/LogEventFactory.html | 2 +- package.json | 2 +- src/logger.ts | 10 +- 21 files changed, 267 insertions(+), 187 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9ecbd21..092c689 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,11 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). --- +## [2.1.3] – 2025-07-15 +### Changed +- Updated `README.md` with minor corrections about extra field output +- Updated the `README.md` including external function documentation + ## [2.1.2] – 2025-07-12 ### Fixed - Removed the call `this.clearCellIfNotEmpty("")` in `ExcelAppender.constructor` since it produces an error in Office Script indicating: `Unexpected token 'this'`. diff --git a/README.md b/README.md index 65f2905..34302c3 100644 --- a/README.md +++ b/README.md @@ -32,7 +32,7 @@ Copy the contents of `dist/logger.ts` into your script in the Office Scripts edi ```typescript // Set verbosity level up to INFO events, and continue on error/warning -let logger = Logger.getInstance(Logger.LEVEL.INFO, Logger.ACTION.CONTINUE) +const logger = LoggerImpl.getInstance(LoggerImpl.LEVEL.INFO, LoggerImpl.ACTION.CONTINUE) logger.addAppender(ConsoleAppender.getInstance()) // Add console appender ``` > If you skip this step and just call `logger.info("...")`, the logger will be created with default settings (`WARN` level, `EXIT` action) and a console appender will be used automatically. @@ -58,9 +58,9 @@ Display log output directly in a cell while your script runs: ```typescript function main(workbook: ExcelScript.Workbook) { // Set up logger to send logs to cell B1 - const cell = workbook.getActiveWorksheet().getRange("B1") - let logger = Logger.getInstance(Logger.LEVEL.INFO, Logger.ACTION.CONTINUE) - logger.addAppender(ExcelAppender.getInstance(cell)) + const cellRng = workbook.getActiveWorksheet().getRange("B1") + const logger = LoggerImpl.getInstance(LoggerImpl.LEVEL.INFO, LoggerImpl.ACTION.CONTINUE) + logger.addAppender(ExcelAppender.getInstance(cellRng)) logger.info("Log written to Excel!") // Output in cell B1: [2025-06-25 23:41:10,586] [INFO] Log written to Excel! (green text) logger.trace("Trace event in cell") // Output in cell B1: [2025-06-25 23:41:10,586] [TRACE] Trace event in cell (gray text) @@ -91,25 +91,25 @@ You can start logging immediately, but for best results (and explicit configurat Set the **maximum verbosity level** of messages to be logged: -- `Logger.LEVEL.OFF`: No logs -- `Logger.LEVEL.ERROR`: Only errors -- `Logger.LEVEL.WARN`: Errors and warnings (default) -- `Logger.LEVEL.INFO`: Errors, warnings, and info -- `Logger.LEVEL.TRACE`: All messages (most verbose) +- `LoggerImpl.LEVEL.OFF`: No logs +- `LoggerImpl.LEVEL.ERROR`: Only errors +- `LoggerImpl.LEVEL.WARN`: Errors and warnings (default) +- `LoggerImpl.LEVEL.INFO`: Errors, warnings, and info +- `LoggerImpl.LEVEL.TRACE`: All messages (most verbose) ### Error/Warning Handling Action In the event of sending an error/warning the following behaviour can be configured: -- `Logger.ACTION.CONTINUE`: Log the event, continue script execution -- `Logger.ACTION.EXIT`: Log the event and throw a `ScriptError`, terminating the script (default) +- `LoggerImpl.ACTION.CONTINUE`: Log the event, continue script execution +- `LoggerImpl.ACTION.EXIT`: Log the event and throw a `ScriptError`, terminating the script (default) -> If the log level is `Logger.LEVEL.OFF`, no messages will be sent to any appender, and the action configuration does not take effect. +> If the log level is `LoggerImpl.LEVEL.OFF`, no messages will be sent to any appender, and the action configuration does not take effect. ### Appenders - `ConsoleAppender`: Output to the Office Scripts console - `Logger.addAppender(ConsoleAppender.getInstance())` + `logger.addAppender(ConsoleAppender.getInstance())` - `ExcelAppender`: Output to a specified Excel cell, with color coding - `Logger.addAppender(ExcelAppender.getInstance(cellRange))` + `logger.addAppender(ExcelAppender.getInstance(cellRange))` --- @@ -142,7 +142,7 @@ ExcelAppender.clearInstance() AbstractAppender.clearLayout() AbstractAppender.clearLogEventFactory() ``` -> The `clear*` family of methods (`clearInstance`, `clearLayout`, `clearLogEventFactory`) are available in the source files (`src/`). They are omitted from production builds (`dist/`). +> The `clear*` family of methods are available in the source files (`src/`). They are omitted from production builds (`dist/`). > `logger.reset()` is always available in production and only resets error/warning counters and critical messages, not the logger/appender singletons or layout/factory. --- @@ -152,11 +152,14 @@ AbstractAppender.clearLogEventFactory() You can customize how log messages are formatted or how log events are constructed. This is useful for integrating with other systems, outputting logs in a specific structure (e.g., JSON, XML), or adapting the logger for unique workflows. > **Important:** -> All customization via `AbstractAppender.setLayout()` or `AbstractAppender.setLogEventFactory()` must happen before any logger or appender is initialized or any log event is sent. These setters will not override existing configuration once logging has begun. When a log method is invoked it does lazy initialization for layout and log event factory, when they are required. That is why it is advised to change the configuration before logging begins. +> - All customization using `AbstractAppender.setLayout()` or `AbstractAppender.setLogEventFactory()` **must be performed before** any logger or appender is initialized, or before any log event is sent. Once logging has started, these setters will not override the existing configuration. +> - **Why?** Both layout and log event factory are initialized lazily—when a log method is called, the framework checks if these are set and, if not, assigns the default implementations. Therefore, to ensure your custom configuration is applied, set them **before any logging occurs**. +> - `AbstractAppender.getLayout()` returns the current layout if already set; otherwise, it initializes and returns the default layout (`new LayoutImpl()` i.e. using `LayoutImpl.defaultFormatterFun` as `formatter`). See section *External Functions*. +> - `AbstractAppender.getLogEventFactory()` returns the current log event factory if already set; otherwise, it initializes and returns the default factory (`AbstractAppender.defaultLogEventFactoryFun`). See section *External Functions*. ### Customizing Layout (Log Message Format) -The content and structure of log messages sent to appenders are controlled by a `LayoutImpl` object. By default, a standard layout is used, but you can inject your own formatting logic **once** at the start of your script. +The content and structure of log messages sent to appenders are controlled by a `Layout/LayoutImpl` interface/object. By default, a standard layout is used, but you can inject your own formatting logic **once** at the start of your script. #### Example: Short Layout (No Timestamp) @@ -167,7 +170,7 @@ The content and structure of log messages sent to appenders are controlled by a const shortLayout = new LayoutImpl(LayoutImpl.shortFormatterFun) AbstractAppender.setLayout(shortLayout) -let logger = Logger.getInstance(Logger.LEVEL.INFO, Logger.ACTION.CONTINUE) +const logger = LoggerImpl.getInstance(LoggerImpl.LEVEL.INFO, LoggerImpl.ACTION.CONTINUE) logger.addAppender(ConsoleAppender.getInstance()) logger.info("Script started.") @@ -189,7 +192,7 @@ Sample log output: const jsonLayout = new LayoutImpl(event => JSON.stringify(event)) AbstractAppender.setLayout(jsonLayout) -let logger = Logger.getInstance(Logger.LEVEL.INFO, Logger.ACTION.CONTINUE) +const logger = LoggerImpl.getInstance(LoggerImpl.LEVEL.INFO, LoggerImpl.ACTION.CONTINUE) logger.addAppender(ConsoleAppender.getInstance()) logger.info("Structured log output") @@ -211,7 +214,7 @@ const prodPrefixFactory: LogEventFactory = (msg: string, type: LOG_EVENT) => new LogEventImpl(`[PROD] ${msg}`, type) AbstractAppender.setLogEventFactory(prodPrefixFactory) -let logger = Logger.getInstance(Logger.LEVEL.INFO, Logger.ACTION.CONTINUE) +const logger = LoggerImpl.getInstance(LoggerImpl.LEVEL.INFO, LoggerImpl.ACTION.CONTINUE) logger.addAppender(ConsoleAppender.getInstance()) logger.info("Script started.") @@ -220,7 +223,7 @@ Sample output (default layout): ``` [2025-06-15 05:34:08,123] [INFO] [PROD] Script started. ``` -> A custom factory is useful for tagging logs or integrating with external systems, without having to change every log message call. +> A custom factory is useful for tagging logs or integrating with external systems, without having to change every log message. --- @@ -228,7 +231,7 @@ Sample output (default layout): The `extraFields` parameter is an advanced feature allowing you to attach additional structured data to any log event. This is useful for tagging logs with context (like function names, user IDs, or custom metadata) and for downstream integrations (e.g., exporting logs as JSON). -You can pass an object with arbitrary key-value pairs as the `extraFields` argument to any logging method. These fields will be included in the underlying `LogEventImpl` instance and are available in custom layouts, factories, or appenders. +You can pass an object with arbitrary key-value pairs as the `extraFields` argument to any logging method. These fields will be included in the underlying `LogEventImpl` instance and are available in custom layouts, factories, loggers or appenders. #### Example: Adding custom fields to a log entry @@ -238,7 +241,7 @@ logger.info("Processing started", { step: "init", user: "alice@example.com" }) ``` Produces the following output: ``` -[INFO] Processing started extraFields: { step: "init", user: "alice@example.com" } +[INFO] Processing started {step:"init",user:"alice@example.com"} ``` and ```typescript @@ -246,7 +249,7 @@ logger.error("Failed to save", { errorCode: 42, item: "Budget2025" }) ``` Produces the following: ``` -[ERROR] Failed to save (extraFields: { errorCode: 42, item: "Budget2025" }) +[ERROR] Failed to save {errorCode:42,item:"Budget2025"} ``` #### How it works @@ -258,6 +261,7 @@ Produces the following: - `Logger.trace(message, extraFields?)` - `extraFields` can be any object (e.g., `{ key: value, ... }`). - If you use a custom layout or export logs, you can access these fields from the `LogEvent` interface. +- `log` method for appenders allows extra fields too. #### Example: Exporting logs with extraFields @@ -272,16 +276,16 @@ state.criticalEvents.forEach(event => { ``` Extra fields, if present, will be part of the `toString()` method for the `LogEvent`: ```typescript -let event = new LogEventImpl("Showing toString", LOG_EVENT.INFO, {user: "admin", sessionId: "123"}) +let event = new LogEventImpl("Event with extrra fields", LOG_EVENT.INFO, {user: "admin", sessionId: "123"}) console.log(`event(extra fields)=${event.toString()}`) -event = new LogEventImpl("Showing toString", LOG_EVENT.INFO) +event = new LogEventImpl("Standard event", LOG_EVENT.INFO) console.log(`event=${event.toString()}`) ``` Here is the `toString()` output (first line: info event with extra fields, second line: without extra fields): ``` -event(extra fields)=LogEventImpl: {timestamp="2025-06-19 19:10:34,586", type="INFO", message="Showing toString", +event(extra fields)=LogEventImpl: {timestamp="2025-06-19 19:10:34,586", type="INFO", message="Event with extra fields", extraFields={"user":"admin","sessionId":"123"}} -event=LogEventImpl: {timestamp="2025-06-19 19:10:34,586", type="INFO", message="Showing toString"} +event=LogEventImpl: {timestamp="2025-06-19 19:10:34,586", type="INFO", message="Standard event"} ``` --- @@ -301,22 +305,24 @@ function main(workbook: ExcelScript.Workbook) { // AbstractAppender.setLogEventFactory(prodPrefixFactory) // Set verbosity up to TRACE and continue on error/warning - let logger = Logger.getInstance(Logger.LEVEL.TRACE, Logger.ACTION.CONTINUE) + const logger = LoggerImpl.getInstance(LoggerImpl.LEVEL.TRACE, LoggerImpl.ACTION.CONTINUE) // Add appenders logger.addAppender(ConsoleAppender.getInstance()) - const logCell = workbook.getActiveWorksheet().getRange("C2") - logger.addAppender(ExcelAppender.getInstance(logCell)) + const cellRng = workbook.getActiveWorksheet().getRange("C2") + logger.addAppender(ExcelAppender.getInstance(cellRng)) // Logging (with short layout, output shown as comments): logger.info("Script started.") // [INFO] Script started. - logger.trace("This is a trace message.") // [TRACE] This is a trace message. - logger.warn("This is a warning.") // [WARN] This is a warning. + logger.trace("This is a trace message") // [TRACE] This is a trace message + logger.warn("This is a warning") // [WARN] This is a warning logger.error("This is an error!") // [ERROR] This is an error! (if ACTION.EXIT, aborts script) // ExcelAppender outputs in cell C2: with default layout // [2025-06-26 00:38:10,688] [INFO] Script started (green text) // [2025-06-26 00:38:10,688] [TRACE] This is a trace message (gray text) + // [2025-06-26 00:38:10,688] [WARN] This is a warning (orange text) + // [2025-06-26 00:38:10,688] [TRACE] This is an error (red text) } ``` > You can set the layout or log event factory only before any logger or appender is initialized, or before any log event is sent. This ensures consistent formatting and event structure throughout execution. @@ -372,11 +378,11 @@ This ensures the logging framework is robust and reliable across both developmen Yes, just add both appenders. - **How do I change log level or action after initialization?** - In non-production/test-only scenarios, use `Logger.clearInstance()` and then call `getInstance()` with new options. + In non-production/test-only scenarios, use `LoggerImpl.clearInstance()` and then call `LoggerImpl.getInstance()` with new options. - **Why do I get a `ScriptError`?** - If you send an error or warning log event and `Logger.ACTION.EXIT` is set (and `Logger.LEVEL != LEVEL.OFF`), the logger will throw and abort the script. - `ScriptError` is also thrown for internal errors, such as invalid input arguments or incorrect configuration. + If you send an error or warning log event and `LoggerImpl.ACTION.EXIT` is set (and `LoggerImpl.LEVEL != LoggerImpl.LEVEL.OFF`), the logger will throw and abort the script. + `ScriptError` is also thrown for internal errors, in case any internal validation fails or incorrect configuration. - **Why can I only add one of each appender type?** To avoid duplicate logs on the same channel; each appender represents a unique output. @@ -385,7 +391,7 @@ This ensures the logging framework is robust and reliable across both developmen By design, all channels (appenders) receive the same log event message for consistency. - **Why does the output for `ExcelAppender` override the previous message?** - By design, the use case for `ExcelAppender` was intended for the default configuration (i.e., a logger with `WARN` level and action `EXIT`). You may want the script to stop if there is any warning or error. Adding more than one event in the same cell (e.g., concatenating via `\n`) is possible, but this defeats the purpose of highlighting each event type with color, since the color will affect the entire cell content. To display each log event in its own cell, you would need to adjust or extend `ExcelAppender`. + By design, the use case for `ExcelAppender` was intended for the default configuration (i.e., a logger with `WARN` level and action `EXIT`). You may want the script to stop if there is any warning or error. Adding more than one event in the same cell (e.g., concatenating via `\n`) is possible, but this defeats the purpose of highlighting each event type with color, since the color will affect the entire cell content (`ExcelScript` doesn't allow to color a portion of a cell content). To display each log event in its own cell, you would need to adjust or extend `ExcelAppender`. - **Why am I getting unexpected results when running some tests in Office Scripts compared to Node.js/TypeScript?** This can happen because Office Scripts executes code asynchronously, meaning some operations (like logging or cell updates) may not complete in strict sequence. As a result, test outcomes may differ from those in Node.js/TypeScript, which runs synchronously and flushes operations immediately. @@ -417,6 +423,71 @@ This ensures the logging framework is robust and reliable across both developmen - Git basic documentation: [docs/git-basics](docs/git-basics.md) - Unit testing framework repository: [officescripts-unit-test-framework](https://github.com/dlealv/officescripts-unit-test-framework) from the same author. Used for testing the current repository. Check repository's details for more information. +### External Functions External Functions +The following functions are defined outside of their respective classes in `src/logger.ts` due to Office Scripts limitations, which prevent initializing class properties with function definitions inside the class body. As a result, these functions are not included in TYPEDOC-generated documentation, since TYPEDOC only documents class members. For completeness, their source code and documentation are provided below. + +#### Functions related to `LayoutImpl` + +```typescript +/** + * Convenience public constant to help users to define a short format for log events. + * Formats a log event as a short string as follows '[type] message'. + * If extraFields are present in the event, they will be appended as a JSON object (surrounded by braces) to the output. + * Example: `[ERROR] Something bad happened {"user":"dlealv","id":42}`. + * Defined as a named function to ensure `toString()` of `LayoutImpl` returns the function name. + * @param event - The log event to format. + * @returns A formatted string representation of the log event, as it will be sent to the appenders. + */ +LayoutImpl.shortFormatterFun = Object.freeze(function shortLayoutFormatterFun(event: LogEvent): string { + const sType = LOG_EVENT[event.type] + let extraFieldsStr = "" + if (event.extraFields && Object.keys(event.extraFields).length > 0) { + extraFieldsStr = ` ${JSON.stringify(event.extraFields)}` // JSON.stringify includes the braces + } + return `[${sType}] ${event.message}${extraFieldsStr}` +}) + +/** + * Default formatter function. Created as a named function. Formats a log event as `[timestamp] [type] message`. + * The timestamp is formatted as `YYYY-MM-DD HH:mm:ss,SSS`. + * If extraFields are present in the event, they will be appended as a JSON object (surrounded by braces) to the output. + * Example: `[2025-06-19 15:06:41,123] [ERROR] Something bad happened {"user":"dlealv","id":42}`. + * Defined as a named function to ensure `toString()` of `LayoutImpl` returns the function name. + * @param event - The log event to format. + * @returns A formatted string representation of the log event, as it will be sent to the appenders. + */ +LayoutImpl.defaultFormatterFun = Object.freeze(function defaultLayoutFormatterFun(event: LogEvent): string { + const sDATE = Utility.date2Str(event.timestamp) + const sType = LOG_EVENT[event.type] + let extraFieldsStr = "" + if (event.extraFields && Object.keys(event.extraFields).length > 0) { + extraFieldsStr = ` ${JSON.stringify(event.extraFields)}` // JSON.stringify includes the braces + } + return `[${sDATE}] [${sType}] ${event.message}${extraFieldsStr}` +}) +``` + +#### Functions related to `AbstractAppender` +```typescript +/** + * Default log event factory function used by the `AbstractAppender`. + * It creates a new `LogEventImpl` instance with the provided message, event type, and optional extra fields. + * This function is frozen to prevent modifications at runtime. + * @param message - The message to log. + * @param eventType - The type of the log event (from `LOG_EVENT` enum). + * @param extraFields - Optional additional fields for the log event. + * @returns A new `LogEventImpl` instance. + * @throws ScriptError if the parameters are invalid. + */ +AbstractAppender.defaultLogEventFactoryFun = Object.freeze( + function defaultLogEventFactoryFun(message: string, eventType: LOG_EVENT, extraFields?: LogEventExtraFields) { + return new LogEventImpl(message, eventType, extraFields) + } +) +``` + +--- + ## License See [LICENSE](LICENSE) for details. diff --git a/dist/logger.ts b/dist/logger.ts index 9dcb689..d14a0dd 100644 --- a/dist/logger.ts +++ b/dist/logger.ts @@ -881,9 +881,10 @@ class LayoutImpl implements Layout { * Formats a log event as a short string as follows '[type] message'. * If extraFields are present in the event, they will be appended as a JSON object (surrounded by braces) to the output. * Example: `[ERROR] Something bad happened {"user":"dlealv","id":42}`. - * Defined as a named function to ensure toString() returns the function name. + * Defined as a named function to ensure `toString()` of `LayoutImpl` returns the function name. + * @param event - The log event to format. + * @returns A formatted string representation of the log event, as it will be sent to the appenders. */ - LayoutImpl.shortFormatterFun = Object.freeze(function shortLayoutFormatterFun(event: LogEvent): string { const sType = LOG_EVENT[event.type] let extraFieldsStr = "" @@ -898,9 +899,10 @@ LayoutImpl.shortFormatterFun = Object.freeze(function shortLayoutFormatterFun(ev * The timestamp is formatted as `YYYY-MM-DD HH:mm:ss,SSS`. * If extraFields are present in the event, they will be appended as a JSON object (surrounded by braces) to the output. * Example: `[2025-06-19 15:06:41,123] [ERROR] Something bad happened {"user":"dlealv","id":42}`. - * Defined as a named function to ensure toString() returns the function name. + * Defined as a named function to ensure `toString()` of `LayoutImpl` returns the function name. + * @param event - The log event to format. + * @returns A formatted string representation of the log event, as it will be sent to the appenders. */ - LayoutImpl.defaultFormatterFun = Object.freeze(function defaultLayoutFormatterFun(event: LogEvent): string { const sDATE = Utility.date2Str(event.timestamp) const sType = LOG_EVENT[event.type] diff --git a/docs/typedoc/classes/AbstractAppender.html b/docs/typedoc/classes/AbstractAppender.html index 9f952e2..7cb1614 100644 --- a/docs/typedoc/classes/AbstractAppender.html +++ b/docs/typedoc/classes/AbstractAppender.html @@ -12,7 +12,7 @@
  • LogEventFactory for the factory function type used to create log events.
  • Layout for the layout used to format log events before sending them to appenders.
  • -

    Hierarchy (View Summary)

    Implements

    Index

    Constructors

    Hierarchy (View Summary)

    Implements

    Index

    Constructors

    • Constructs a new AbstractAppender instance. Nothing is initialized, because the class only has static properties that are lazy initialized or set by the user.

      -

      Returns AbstractAppender

    Properties

    defaultLogEventFactoryFun: LogEventFactory

    Methods

    • To ensure when invoking clearInstance in a sub-class it also clear (null) the last log event.

      +

      Returns AbstractAppender

    Properties

    defaultLogEventFactoryFun: LogEventFactory

    Methods

    • To ensure when invoking clearInstance in a sub-class it also clear (null) the last log event.

      Returns void

      Mainly intended for testing purposes. The state of the singleton will be lost. This method only exist in src folder, it won't be deployed in dist folder (production).

      -
    • Log a message or log event.

      Parameters

      • arg1: string | LogEvent

        LogEvent or message string.

      • Optionalarg2: LOG_EVENT

        LOG_EVENT, only required if arg1 is a string.

      • Optionalarg3: LogEventExtraFields

        extraFields, only used if arg1 is a string.

        @@ -50,40 +50,40 @@
        // Example: Log an error message with a custom event type and extra fields.
        const appender = new ConsoleAppender() // Assuming ConsoleAppender extends AbstractAppender
        appender.log("An error occurred", LOG_EVENT.ERROR, { user: "dlealv", id: 42 })
        // Example: Log a warning event directly.
        const warningEvent = new LogEventImpl("This is a warning", LOG_EVENT.WARNING)
        appender.log(warningEvent) // Directly log a LogEvent instance
        -
    • Send the log event to the appropriate destination. This method must be implemented by subclasses to define how the log event is sent. It is responsible for sending the log event to the appropriate destination (e.g., console, file, etc.).

      Parameters

      • event: LogEvent

        The log event to be sent.

      • Optionalcontext: string

        (Optional) A string to provide additional context in case of an error.

      Returns void

      ScriptError if - The log event is not a valid LogEvent.

      -
    • Send the log event to the appropriate destination.

      Parameters

      • event: LogEvent

        The log event to be sent.

      Returns void

      ScriptError if - The event is not a valid LogEvent.

      Subclasses must call setLastLogEvent(event) after successfully sending the event, otherwise getLastLogEvent() will not reflect the most recent log event.

      -
    • Returns a string representation of the appender. +

    • Returns a string representation of the appender. It includes the information from the base class plus the information of the current class, so far this class doesn't have additional properties to show.

      Returns string

      A string representation of the appender.

      -
    • Sets to null the static layout, useful for running different scenarios.

      Returns void

      Mainly intended for testing purposes. The state of the singleton will be lost. This method only exist in src folder, it won't be deployed in dist folder (production).

      -
    • Sets to null the log event factory, useful for running different scenarios.

      +
    • Sets to null the log event factory, useful for running different scenarios.

      Returns void

      Mainly intended for testing purposes. The state of the singleton will be lost. This method only exist in src folder, it won't be deployed in dist folder (production).

      -
    • Returns Layout

      The layout associated to all events. Used to format the log event before sending it to the appenders. +

    • Returns Layout

      The layout associated to all events. Used to format the log event before sending it to the appenders. If the layout was not set, it returns a default layout (lazy initialization). The layout is shared by all events and all appenders, so it is static.

      Static, shared by all log events. Singleton.

      -
    • Gets the log event factory function used to create LogEvent instances. If it was not set before, it returns the default factory function. +

    • Gets the log event factory function used to create LogEvent instances. If it was not set before, it returns the default factory function. The logEventFactory is shared by all events and all appenders, so it is static.

      Returns LogEventFactory

      The log event factory function.

      -
    • Sets the layout associated to all events, the layout is assigned only if it was not set before.

      +
    • Sets the layout associated to all events, the layout is assigned only if it was not set before.

      Parameters

      • layout: Layout

        The layout to set.

      Returns void

      ScriptError if the layout is not a valid Layout implementation.

      -
    • Sets the log event factory function used to create LogEvent instances if it was not set before.

      +
    • Sets the log event factory function used to create LogEvent instances if it was not set before.

      Parameters

      • logEventFactory: LogEventFactory

        A factory function to create LogEvent instances. Must have the signature (message: string, eventType: LOG_EVENT) => LogEvent, i.e. LogEventFactory type. If not provided, a default factory function is used.

        @@ -91,4 +91,4 @@
        // Example: Custom LogEvent to be used to specify the environment where the log event was created.
        let prodLogEventFactory: LogEventFactory
        = function prodLogEventFactoryFun(message: string, eventType: LOG_EVENT) {
        return new LogEventImpl("PROD-" + message, eventType) // add environment prefix
        }
        AbstractAppender.setLogEventFactory(prodLogEventFactory) // Now all appenders will use ProdLogEvent
        -
    +
    diff --git a/docs/typedoc/classes/ConsoleAppender.html b/docs/typedoc/classes/ConsoleAppender.html index fbf9d22..1e90806 100644 --- a/docs/typedoc/classes/ConsoleAppender.html +++ b/docs/typedoc/classes/ConsoleAppender.html @@ -16,7 +16,7 @@
  • AbstractAppender for the base class documentation.
  • Layout for the layout used to format log events before sending them to the console.
  • -

    Hierarchy (View Summary)

    Implements

    Index

    Hierarchy (View Summary)

    Implements

    Index

    Properties

    defaultLogEventFactoryFun: LogEventFactory

    Methods

    • To ensure when invoking clearInstance in a sub-class it also clear (null) the last log event.

      +

    Properties

    defaultLogEventFactoryFun: LogEventFactory

    Methods

    • To ensure when invoking clearInstance in a sub-class it also clear (null) the last log event.

      Returns void

      Mainly intended for testing purposes. The state of the singleton will be lost. This method only exist in src folder, it won't be deployed in dist folder (production).

      -
    • Log a message or log event.

      Parameters

      • arg1: string | LogEvent

        LogEvent or message string.

      • Optionalarg2: LOG_EVENT

        LOG_EVENT, only required if arg1 is a string.

      • Optionalarg3: LogEventExtraFields

        extraFields, only used if arg1 is a string.

        @@ -53,21 +53,21 @@
        // Example: Log an error message with a custom event type and extra fields.
        const appender = new ConsoleAppender() // Assuming ConsoleAppender extends AbstractAppender
        appender.log("An error occurred", LOG_EVENT.ERROR, { user: "dlealv", id: 42 })
        // Example: Log a warning event directly.
        const warningEvent = new LogEventImpl("This is a warning", LOG_EVENT.WARNING)
        appender.log(warningEvent) // Directly log a LogEvent instance
        -
    • Protected method to send the event to the console. At this point is where the event is formatted before sending it to the console.

      Parameters

      • event: LogEvent

        The log event to output.

      • Optionalcontext: string

        (Optional) A string to provide additional context in case of an error.

      Returns void

      ScriptError if The event is not a valid LogEvent. The instance is not available (not instantiated).

      -
    • Send the log event to the appropriate destination.

      Parameters

      • event: LogEvent

        The log event to be sent.

      Returns void

      ScriptError if - The event is not a valid LogEvent.

      Subclasses must call setLastLogEvent(event) after successfully sending the event, otherwise getLastLogEvent() will not reflect the most recent log event.

      -
    • Sets to null the singleton instance, useful for running different scenarios. It also sets to null the parent property lastLogEvent, so the last log event is cleared.

      Returns void

      you reset it.

      appender:ConsoleAppender = ConsoleAppender.getInstance()
      appender = ConsoleAppender.log("info event", LOG_EVENT.INFO)
      appender.getLastLogEvent().message // Output: info event"
      ConsoleAppender.clearInstance() // clear the singleton
      appender = ConsoleAppender.getInstance() // restart the singleton
      appender.getLastLogEvent().message // Output: "" @@ -75,26 +75,26 @@

      Mainly intended for testing purposes. The state of the singleton will be lost. This method only exist in src folder, it wont be deployed in dist folder (production).

      -
    • Sets to null the static layout, useful for running different scenarios.

      +
    • Sets to null the static layout, useful for running different scenarios.

      Returns void

      Mainly intended for testing purposes. The state of the singleton will be lost. This method only exist in src folder, it won't be deployed in dist folder (production).

      -
    • Sets to null the log event factory, useful for running different scenarios.

      Returns void

      Mainly intended for testing purposes. The state of the singleton will be lost. This method only exist in src folder, it won't be deployed in dist folder (production).

      -
    • Returns Layout

      The layout associated to all events. Used to format the log event before sending it to the appenders. +

    • Returns Layout

      The layout associated to all events. Used to format the log event before sending it to the appenders. If the layout was not set, it returns a default layout (lazy initialization). The layout is shared by all events and all appenders, so it is static.

      Static, shared by all log events. Singleton.

      -
    • Sets the layout associated to all events, the layout is assigned only if it was not set before.

      Parameters

      • layout: Layout

        The layout to set.

      Returns void

      ScriptError if the layout is not a valid Layout implementation.

      -
    • Sets the log event factory function used to create LogEvent instances if it was not set before.

      Parameters

      • logEventFactory: LogEventFactory

        A factory function to create LogEvent instances. Must have the signature (message: string, eventType: LOG_EVENT) => LogEvent, i.e. LogEventFactory type. If not provided, a default factory function is used.

        @@ -102,4 +102,4 @@
        // Example: Custom LogEvent to be used to specify the environment where the log event was created.
        let prodLogEventFactory: LogEventFactory
        = function prodLogEventFactoryFun(message: string, eventType: LOG_EVENT) {
        return new LogEventImpl("PROD-" + message, eventType) // add environment prefix
        }
        AbstractAppender.setLogEventFactory(prodLogEventFactory) // Now all appenders will use ProdLogEvent
        -
    +
    diff --git a/docs/typedoc/classes/ExcelAppender.html b/docs/typedoc/classes/ExcelAppender.html index 0458adc..f0c68d5 100644 --- a/docs/typedoc/classes/ExcelAppender.html +++ b/docs/typedoc/classes/ExcelAppender.html @@ -26,7 +26,7 @@
  • Layout for the layout used to format log events before sending them to Excel.
  • ConsoleAppender for an example of a console appender that logs messages to the console.
  • -

    Hierarchy (View Summary)

    Implements

    Index

    Hierarchy (View Summary)

    Implements

    Index

    Properties

    Methods

    clearLastLogEvent getEventFonts @@ -54,17 +54,17 @@
  • INFO: 548235 green
  • TRACE: 7f7f7f gray
  • -
    defaultLogEventFactoryFun: LogEventFactory

    Methods

    • To ensure when invoking clearInstance in a sub-class it also clear (null) the last log event.

      +
    defaultLogEventFactoryFun: LogEventFactory

    Methods

    • To ensure when invoking clearInstance in a sub-class it also clear (null) the last log event.

      Returns void

      Mainly intended for testing purposes. The state of the singleton will be lost. This method only exist in src folder, it won't be deployed in dist folder (production).

      -
    • Returns the map of event types to font colors used by this appender.

      Returns Record<LOG_EVENT, string>

      A defensive copy of the event fonts map.

      The keys are LOG_EVENT enum values, and the values are hex color strings.

      -
    • Returns the Excel range where log messages are written.

      +
    • Returns the Excel range where log messages are written.

      Returns any

      The ExcelScript.Range object representing the message cell range.

      This is the cell where log messages will be displayed.

      -
    • Log a message or log event.

      Parameters

      • arg1: string | LogEvent

        LogEvent or message string.

      • Optionalarg2: LOG_EVENT

        LOG_EVENT, only required if arg1 is a string.

      • Optionalarg3: LogEventExtraFields

        extraFields, only used if arg1 is a string.

        @@ -82,32 +82,32 @@
        // Example: Log an error message with a custom event type and extra fields.
        const appender = new ConsoleAppender() // Assuming ConsoleAppender extends AbstractAppender
        appender.log("An error occurred", LOG_EVENT.ERROR, { user: "dlealv", id: 42 })
        // Example: Log a warning event directly.
        const warningEvent = new LogEventImpl("This is a warning", LOG_EVENT.WARNING)
        appender.log(warningEvent) // Directly log a LogEvent instance
        -
    • Sets the value of the cell, with the event message, using the font defined for the event type, if not font was defined it doesn't change the font of the cell.

      Parameters

      • event: LogEvent

        a value from enum LOG_EVENT.

      • Optionalcontext: string

      Returns void

      ScriptError in case event is not a valid LOG_EVENT enum value.

      -
    • Send the log event to the appropriate destination.

      Parameters

      • event: LogEvent

        The log event to be sent.

      Returns void

      ScriptError if - The event is not a valid LogEvent.

      Subclasses must call setLastLogEvent(event) after successfully sending the event, otherwise getLastLogEvent() will not reflect the most recent log event.

      -
    • Sets to null the singleton instance, useful for running different scenarios. It also sets to null the parent property lastLogEvent, so the last log event is cleared.

      Returns void

      const activeSheet = workbook.getActiveWorksheet() // workbook is input argument of main
      const msgCellRng = activeSheet.getRange("C2")
      appender = ExcelAppender.getInstance(msgCellRng) // with default log event colors
      appender.info("info event") // Output: In Excel in cell C2 with green color shows: "info event"
      // Now we want to test how getInstance() can throw a ScriptError,
      // but we can't because the instance was already created and it is a singleton we need clearInstance
      appender.clearInstance()
      appender = ExcelAppender.getInstance(null) // throws a ScriptError

      Mainly intended for testing purposes. The state of the singleton will be lost. This method only exist in src folder, it wont be deployed in dist folder (production).

      -
    • Sets to null the static layout, useful for running different scenarios.

      +
    • Sets to null the static layout, useful for running different scenarios.

      Returns void

      Mainly intended for testing purposes. The state of the singleton will be lost. This method only exist in src folder, it won't be deployed in dist folder (production).

      -
    • Sets to null the log event factory, useful for running different scenarios.

      Returns void

      Mainly intended for testing purposes. The state of the singleton will be lost. This method only exist in src folder, it won't be deployed in dist folder (production).

      -
    • Returns the singleton ExcelAppender instance, creating it if it doesn't exist. On first call, requires a valid single cell Excel range to display log messages and optional color customizations for different log events (LOG_EVENT). Subsequent calls ignore parameters and return the existing instance.

      @@ -125,17 +125,17 @@
    • Returns Layout

      The layout associated to all events. Used to format the log event before sending it to the appenders. +

    • Returns Layout

      The layout associated to all events. Used to format the log event before sending it to the appenders. If the layout was not set, it returns a default layout (lazy initialization). The layout is shared by all events and all appenders, so it is static.

      Static, shared by all log events. Singleton.

      -
    • Sets the layout associated to all events, the layout is assigned only if it was not set before.

      Parameters

      • layout: Layout

        The layout to set.

      Returns void

      ScriptError if the layout is not a valid Layout implementation.

      -
    • Sets the log event factory function used to create LogEvent instances if it was not set before.

      Parameters

      • logEventFactory: LogEventFactory

        A factory function to create LogEvent instances. Must have the signature (message: string, eventType: LOG_EVENT) => LogEvent, i.e. LogEventFactory type. If not provided, a default factory function is used.

        @@ -143,4 +143,4 @@
        // Example: Custom LogEvent to be used to specify the environment where the log event was created.
        let prodLogEventFactory: LogEventFactory
        = function prodLogEventFactoryFun(message: string, eventType: LOG_EVENT) {
        return new LogEventImpl("PROD-" + message, eventType) // add environment prefix
        }
        AbstractAppender.setLogEventFactory(prodLogEventFactory) // Now all appenders will use ProdLogEvent
        -
    +
    diff --git a/docs/typedoc/classes/LayoutImpl.html b/docs/typedoc/classes/LayoutImpl.html index b36df46..f9cfd56 100644 --- a/docs/typedoc/classes/LayoutImpl.html +++ b/docs/typedoc/classes/LayoutImpl.html @@ -9,7 +9,7 @@
  • Layout for the interface definition.
  • LogEvent for the structure of log events.
  • -

    Implements

    Index

    Constructors

    Implements

    Index

    Constructors

    Properties

    Methods

    format @@ -31,25 +31,25 @@
    // Using the default formatter:
    const layout = new LayoutImpl()
    // Using a custom formatter for JSON output:
    const jsonLayout = new LayoutImpl(event => JSON.stringify(event))
    // Using a formatter for XML output:
    const xmlLayout = new LayoutImpl(event =>
    `<log><type>${event.type}</type><message>${event.message}</message></log>`
    )
    // Using a shorter format [type] [message]:
    const shortLayout = new LayoutImpl(e => `[${LOG_EVENT[e.type]}] ${e.message}`)
    // Using a custom formatter with a named function, so in toString() shows the name of the formatter.
    let shortLayoutFun: Layout = new LayoutImpl(
    function shortLayoutFun(e:LogEvent):string{return `[${LOG_EVENT[e.type]}] ${e.message}`})
    -

    Properties

    defaultFormatterFun: LayoutFormatter

    Convenience static property to define a long formatter used as default, e.g. [timestamp] [type] message. +

    Properties

    defaultFormatterFun: LayoutFormatter

    Convenience static property to define a long formatter used as default, e.g. [timestamp] [type] message. This is the default formatter used if no custom formatter is provided.

    -
    shortFormatterFun: LayoutFormatter

    Convenience static property to define a short formatter, e.g. [type] message.

    -

    Methods

    shortFormatterFun: LayoutFormatter

    Convenience static property to define a short formatter, e.g. [type] message.

    +

    Methods

    • Formats the given log event as a string.

      Parameters

      • event: LogEvent

        The log event to format.

      Returns string

      A string representation of the log event.

      ScriptError if the event does not conform to the LogEvent interface.

      -
    • Returns string

      A string representation of the layout. +

    • Returns string

      A string representation of the layout. If the formatter is a function, it returns the name of the function.

      -
    • Validates that the provided value is a valid formatter function for use in LayoutImpl (_formatter property). The formatter must be a function accepting a single LogEvent argument and must return a non-empty, non-null string.

      Parameters

      • formatter: LayoutFormatter

        The candidate formatter function to validate.

      • Optionalcontext: string

        (Optional) Additional context for error messages.

      Returns void

      ScriptError if formatter is missing, not a function, doesn't have arity 1, or returns null/empty string for a sample event.

      -
    • Asserts that the provided object implements the Layout interface. +

    • Asserts that the provided object implements the Layout interface. Checks for the public format method (should be a function taking one argument). Also validates the internal _formatter property if present, by calling validateFormatter. Used by appenders to validate layout objects at runtime.

      @@ -61,4 +61,4 @@
    • format is not a function or doesn't have arity 1.
    • _formatter is present and is missing, not a function, or doesn't have arity 1.
    -
    +
    diff --git a/docs/typedoc/classes/LogEventImpl.html b/docs/typedoc/classes/LogEventImpl.html index 9149d42..b7c0b75 100644 --- a/docs/typedoc/classes/LogEventImpl.html +++ b/docs/typedoc/classes/LogEventImpl.html @@ -11,7 +11,7 @@
  • LogEvent for the interface definition.
  • LOG_EVENT for the enumeration of log event types.
  • -

    Implements

    Index

    Constructors

    Implements

    Index

    Constructors

    Accessors

    extraFields message timestamp @@ -38,17 +38,17 @@
  • The extraFields property allows for extensibility, enabling additional metadata to be attached to log events.
  • The toString() method provides a standardized string representation of the log event.
  • -

    Accessors

    Accessors

    • get extraFields(): Readonly<LogEventExtraFields>

      Gets the extra fields of the log event.

      Returns Readonly<LogEventExtraFields>

      Returns a shallow copy of custom fields for this event. These are immutable (Object.freeze), but if you allow object values in the future, document that deep mutation is not prevented.

      -

    Methods

    • Returns string

      A string representation of the log event in standard toString format

      -

    Methods

    • Returns string

      A string representation of the log event in standard toString format

      +
    • Returns a standardized label for the given log event.

      Parameters

      • type: LOG_EVENT

        The event type from LOG_EVENT enum.

      Returns string

      A string label, e.g., [INFO], [ERROR].

      ScriptError if the type is not a valid LOG_EVENT enum value.

      -
    • Validates if the input object conforms to the LogEvent interface (for any implementation).

      +
    • Validates if the input object conforms to the LogEvent interface (for any implementation).

      Parameters

      • event: unknown
      • Optionalcontext: string

      Returns void

      ScriptError if log event is invalid.

      -
    +
    diff --git a/docs/typedoc/classes/LoggerImpl.html b/docs/typedoc/classes/LoggerImpl.html index e975794..7bdbdcf 100644 --- a/docs/typedoc/classes/LoggerImpl.html +++ b/docs/typedoc/classes/LoggerImpl.html @@ -31,7 +31,7 @@
  • ConsoleAppender for the implementation details of the console appender.
  • LogEvent for the structure of log events.
  • -

    Implements

    Index

    Properties

    Implements

    Index

    Properties

    Methods

    Properties

    ACTION: Readonly<{ CONTINUE: 0; EXIT: 1 }> = ...

    Static constant (enum pattern) for log event types.

    -
    LEVEL: Readonly<{ OFF: number } & typeof LOG_EVENT> = ...

    Static constant. It generates the same sequence as LOG_EVENT, but adding the zero case with OFF. It ensures the numeric values +

    LEVEL: Readonly<{ OFF: number } & typeof LOG_EVENT> = ...

    Static constant. It generates the same sequence as LOG_EVENT, but adding the zero case with OFF. It ensures the numeric values match the values of LOG_EVENT. Note: enum can't be defined inside a class

    -

    Methods

    Methods

    • Adds an appender to the list of appenders.

      Parameters

      Returns void

      ScriptError If the singleton was not instantiated, if the input argument is null or undefined, or if it breaks the class uniqueness of the appenders. All appenders must be from a different implementation of the Appender class.

    • Sends an error log message (with optional structured extra fields) to all appenders if the level allows it. The level has to be greater than or equal to Logger.LEVEL.ERROR to send this event to the appenders. After the message is sent, it updates the error counter.

      Parameters

      • msg: string

        The error message to log.

        @@ -76,66 +76,66 @@ If no appender was defined, it does lazy initialization to ConsoleAppender.

        ScriptError If level is greater than Logger.LEVEL.OFF and the action is Logger.ACTION.EXIT. If any internal error occurs while sending the event to the appenders.

        -
    • Serializes the current state of the logger to a plain object, useful for +

    • Serializes the current state of the logger to a plain object, useful for capturing logs and metrics for post-run analysis. For testing/debugging: Compare expected vs actual logger state. For persisting logs into Excel, JSON, or another external system.

      Returns {
          action: string;
          criticalEvents: LogEvent[];
          errorCount: number;
          level: string;
          warningCount: number;
      }

      A structure with key information about the logger, such as: level, action, errorCount, warningCount, and criticalEvents.

      ScriptError If the singleton was not instantiated.

      -
    • Returns 0 | 1

      The action to take in case of errors or warning log events.

      ScriptError If the singleton was not instantiated.

      -
    • Returns number

      Total number of error message events sent to the appenders.

      ScriptError If the singleton was not instantiated.

      -
    • Returns the level of verbosity allowed in the Logger. The levels are incremental, i.e. +

    • Returns the level of verbosity allowed in the Logger. The levels are incremental, i.e. it includes all previous levels. For example: Logger.WARN includes warnings and errors since Logger.ERROR is lower.

      Returns number

      The current log level.

      ScriptError If the singleton was not instantiated.

      -
    • Returns number

      Total number of warning events sent to the appenders.

      ScriptError If the singleton was not instantiated.

      -
    • Returns boolean

      true if some error or warning event has been sent by the appenders, otherwise false.

      +
    • Returns boolean

      true if some error or warning event has been sent by the appenders, otherwise false.

      ScriptError If the singleton was not instantiated.

      -
    • Returns boolean

      true if an error log event was sent to the appenders, otherwise false.

      ScriptError If the singleton was not instantiated.

      -
    • Returns boolean

      true if a warning log event was sent to the appenders, otherwise false.

      +
    • Returns boolean

      true if a warning log event was sent to the appenders, otherwise false.

      ScriptError If the singleton was not instantiated.

      -
    • Sends an info log message (with optional structured extra fields) to all appenders if the level allows it. The level has to be greater than or equal to Logger.LEVEL.INFO to send this event to the appenders.

      Parameters

      • msg: string

        The informational message to log.

      • OptionalextraFields: LogEventExtraFields

        Optional structured data to attach to the log event (e.g., context info, tags).

      Returns void

      ScriptError If any internal error occurs while sending the event to the appenders.

      If no singleton was defined, it does lazy initialization with default configuration. If no appender was defined, it does lazy initialization to ConsoleAppender.

      -
    • If the list of appenders is not empty, removes the appender from the list.

      Parameters

      • appender: Appender

        The appender to remove.

      Returns void

      ScriptError If the singleton was not instantiated.

      -
    • Resets the Logger history, i.e., state (errors, warnings, including the list of critical events). It doesn't reset the appenders.

      +
    • Resets the Logger history, i.e., state (errors, warnings, including the list of critical events). It doesn't reset the appenders.

      Returns void

      ScriptError If the singleton was not instantiated.

      -
    • Sets the array of appenders with the input argument appenders.

      Parameters

      • appenders: Appender[]

        Array with all appenders to set.

      Returns void

      ScriptError If the singleton was not instantiated, if appenders is null or undefined, or contains null or undefined entries, or if the appenders to add are not unique by appender class. See JSDoc from LoggerImpl.addAppender for more details.

      -
    • Short version fo the toString() which exludes the appenders details.

      Returns string

      Similar to toString, but showing the list of appenders name only.

      ScriptError If the singleton was not instantiated.

      -
    • Returns string

      A string representation of the logger instance.

      +
    • Returns string

      A string representation of the logger instance.

      ScriptError If the singleton was not instantiated.

      -
    • Sends a trace log message (with optional structured extra fields) to all appenders if the level allows it. The level has to be greater than or equal to Logger.LEVEL.TRACE to send this event to the appenders.

      Parameters

      • msg: string

        The trace message to log.

      • OptionalextraFields: LogEventExtraFields

        Optional structured data to attach to the log event (e.g., context info, tags).

      Returns void

      ScriptError If any internal error occurs while sending the event to the appenders.

      If no singleton was defined, it does lazy initialization with default configuration. If no appender was defined, it does lazy initialization to ConsoleAppender.

      -
    • Sends a warning log message (with optional structured extra fields) to all appenders if the level allows it. The level has to be greater than or equal to Logger.LEVEL.WARN to send this event to the appenders. After the message is sent, it updates the warning counter.

      Parameters

      • msg: string

        The warning message to log.

        @@ -144,7 +144,7 @@ If any internal error occurs while sending the event to the appenders.

        If no singleton was defined, it does lazy initialization with default configuration. If no appender was defined, it does lazy initialization to ConsoleAppender.

        -
    • Sets the singleton instance to null, useful for running different scenarios.

      +
    • Sets the singleton instance to null, useful for running different scenarios.

      Returns void

      Mainly intended for testing purposes. The state of the singleton will be lost. This method only exist in src folder, it won't be deployed in dist folder (production). It doesn't set the appenders to null, so the appenders are not cleared.

      @@ -152,7 +152,7 @@
      // Testing how the logger works with default configuration, and then changing the configuration.
      // Since the class doesn't define setter methods to change the configuration, you can use
      // clearInstance to reset the singleton and instantiate it with different configuration.
      // Testing default configuration
      let logger = Logger.getInstance() // LEVEL: WARN, ACTION: EXIT
      logger.error("error event") // Output: "error event" and ScriptError
      // Now we want to test with the following configuration: Logger.LEVEL:WARN, Logger.ACTION:CONTINUE
      Logger.clearInstance() // Clear the singleton
      logger = Logger.getInstance(LEVEL.WARN, ACTION.CONTINUE)
      logger.error("error event") // Output: "error event" (no ScriptError was thrown)
      -
    • Returns the label for a log action value.

      +
    • Returns the label for a log action value.

      Parameters

      • Optionalaction: 0 | 1

        The log action to get the label for.

      Returns string

      The label for the action. If action is undefined, returns the label for the current logger instance's action. @@ -160,7 +160,7 @@

      LoggerImpl.getActionLabel(LoggerImpl.ACTION.CONTINUE) // Returns "CONTINUE"
      LoggerImpl.getActionLabel() // Returns the current logger instance's action label
      -
    • Returns the singleton Logger instance, creating it if it doesn't exist. +

    • Returns the singleton Logger instance, creating it if it doesn't exist. If the Logger is created during this call, the provided level and action parameters initialize the log level and error-handling behavior.

      Parameters

      • level: number = LoggerImpl.DEFAULT_LEVEL

        The verbosity level (default: Logger.LEVEL.WARN). Controls verbosity. @@ -182,11 +182,11 @@

        // Initialize logger at INFO level, continue on errors/warnings
        const logger = Logger.getInstance(Logger.LEVEL.INFO, Logger.ACTION.CONTINUE)
        // Subsequent calls ignore parameters, return the same instance
        const sameLogger = Logger.getInstance(Logger.LEVEL.ERROR, Logger.ACTION.EXIT)
        logger.info("Starting the Script") // Send this message to all appenders
        logger.trace("Step one") // Doesn't send because of Logger.LEVEL value: INFO
        -
    • Returns the label for the given log level.

      +
    • Returns the label for the given log level.

      Parameters

      • Optionallevel: number

      Returns string

      The label for the log level. If level is undefined, returns the label for the current logger instance's level. If neither is set, returns UNKNOWN.

      LoggerImpl.getLevelLabel(LoggerImpl.LEVEL.INFO) // Returns "INFO"
      LoggerImpl.getLevelLabel() // Returns the current logger instance's level label
      -
    +
    diff --git a/docs/typedoc/classes/ScriptError.html b/docs/typedoc/classes/ScriptError.html index 8b1b1c7..44fd45b 100644 --- a/docs/typedoc/classes/ScriptError.html +++ b/docs/typedoc/classes/ScriptError.html @@ -7,7 +7,7 @@
    const original = new Error("Missing field")
    throw new ScriptError("Validation failed", original)
    -

    Hierarchy

    • Error
      • ScriptError
    Index

    Constructors

    Hierarchy

    • Error
      • ScriptError
    Index

    Constructors

    Properties

    cause? message name @@ -21,9 +21,9 @@

    Parameters

    • message: string

      A description of the error.

    • Optionalcause: Error

      (Optional) The original error that caused this one. If provided the exception message will have a reference to the cause.

      -

    Returns ScriptError

    Properties

    cause?: Error

    (Optional) The original error that caused this one. +

    Returns ScriptError

    Properties

    cause?: Error

    (Optional) The original error that caused this one. If provided the exception message will have a reference to the cause.

    -
    message: string
    name: string
    stack?: string
    stackTraceLimit: number

    The Error.stackTraceLimit property specifies the number of stack frames +

    message: string
    name: string
    stack?: string
    stackTraceLimit: number

    The Error.stackTraceLimit property specifies the number of stack frames collected by a stack trace (whether generated by new Error().stack or Error.captureStackTrace(obj)).

    The default value is 10 but may be set to any valid JavaScript number. Changes @@ -34,13 +34,13 @@ otherwise rethrows this ScriptError itself. Useful for deferring a controlled exception and then surfacing the root cause explicitly.

    -

    Returns never

    • Override toString() method.

      +

      Returns never

    • Override toString() method.

      Returns string

      The name and the message on the first line, then on the second line the Stack trace section name, i.e. 'Stack trace:'. Starting on the third line the stack trace information. If a cause was provided the stack trace will refer to the cause otherwise to the original exception.

      -
    • Creates a .stack property on targetObject, which when accessed returns +

    • Creates a .stack property on targetObject, which when accessed returns a string representing the location in the code at which Error.captureStackTrace() was called.

      const myObject = {};
      Error.captureStackTrace(myObject);
      myObject.stack; // Similar to `new Error().stack` diff --git a/docs/typedoc/classes/Utility.html b/docs/typedoc/classes/Utility.html index 770fd90..eb7c322 100644 --- a/docs/typedoc/classes/Utility.html +++ b/docs/typedoc/classes/Utility.html @@ -1,5 +1,5 @@ Utility | officescripts-logging-framework
      officescripts-logging-framework
        Preparing search index...

        Class Utility

        Utility class providing static helper methods for logging operations.

        -
        Index

        Constructors

        Index

        Constructors

        Methods

        date2Str isEmptyArray validateLogEventFactory @@ -7,9 +7,9 @@ where SSS is the milliseconds part padded to 3 digits.

        Parameters

        • date: Date

          The date to format.

        Returns string

        A string representation of the date in the format YYYY-MM-DD HH:mm:ss,SSS.

        -
      • Helper method to check for an empty array.

        -

        Type Parameters

        • T

        Parameters

        • arr: T[]

        Returns boolean

      • Validates a log event factory is a function.

        +
      • Helper method to check for an empty array.

        +

        Type Parameters

        • T

        Parameters

        • arr: T[]

        Returns boolean

      • Validates a log event factory is a function.

        Parameters

        • factory: unknown

          The factory function to validate.

        • OptionalfunName: string

          Used to identify the function name in the error message.

        • Optionalcontext: string

        Returns void

        ScriptError if the log event factory is not a function.

        -
      +
      diff --git a/docs/typedoc/enums/LOG_EVENT.html b/docs/typedoc/enums/LOG_EVENT.html index 85bd879..6c6d902 100644 --- a/docs/typedoc/enums/LOG_EVENT.html +++ b/docs/typedoc/enums/LOG_EVENT.html @@ -12,8 +12,8 @@ Logger.OFF, therefore the verbosity respects the same order of the LOG_EVENT.

      It was defined as an independent entity since it is used by appenders and by the Logger.

      -
      Index

      Enumeration Members

      Index

      Enumeration Members

      Enumeration Members

      ERROR: 1
      INFO: 3
      TRACE: 4
      WARN: 2
      +

      Enumeration Members

      ERROR: 1
      INFO: 3
      TRACE: 4
      WARN: 2
      diff --git a/docs/typedoc/interfaces/Appender.html b/docs/typedoc/interfaces/Appender.html index 4bf4f75..91d7dc5 100644 --- a/docs/typedoc/interfaces/Appender.html +++ b/docs/typedoc/interfaces/Appender.html @@ -22,20 +22,20 @@
    • Layout for the layout used to format log events before sending them to appenders.
    • LOG_EVENT for the enumeration of log event types.
    • -
      interface Appender {
          getLastLogEvent(): LogEvent;
          log(event: LogEvent): void;
          log(msg: string, type: LOG_EVENT, extraFields?: object): void;
          toString(): string;
      }

      Implemented by

      Index
      interface Appender {
          getLastLogEvent(): LogEvent;
          log(event: LogEvent): void;
          log(msg: string, type: LOG_EVENT, extraFields?: object): void;
          toString(): string;
      }

      Implemented by

      Index

      Methods

      • Returns the last LogEvent delivered to the appender, or null if none sent yet.

        Returns LogEvent

        The last LogEvent object delivered, or null.

        ScriptError if the appender instance is unavailable.

        -
      • Sends a structured log event to the appender.

        Parameters

        • event: LogEvent

          The log event object to deliver.

        Returns void

        ScriptError if the event is invalid or cannot be delivered.

        -
      • Sends a log message to the appender, specifying the event type and optional structured extra fields.

        +
      • Sends a log message to the appender, specifying the event type and optional structured extra fields.

        Parameters

        • msg: string

          The message to log.

        • type: LOG_EVENT

          The type of log event (from LOG_EVENT enum).

        • OptionalextraFields: object

          Optional structured data (object) to attach to the log event (e.g., context info, tags).

          -

        Returns void

      • Returns a string summary of the appender's state, typically including its type and last event.

        +

      Returns void

      • Returns a string summary of the appender's state, typically including its type and last event.

        Returns string

        A string describing the appender and its most recent activity.

        ScriptError if the appender instance is unavailable.

        -
      +
      diff --git a/docs/typedoc/interfaces/Layout.html b/docs/typedoc/interfaces/Layout.html index 17ada04..b4c5ce2 100644 --- a/docs/typedoc/interfaces/Layout.html +++ b/docs/typedoc/interfaces/Layout.html @@ -9,11 +9,11 @@
    • Layouts are intended for core message structure, not for display/presentation logic.
    • LogEvent for the structure of log events.

      -
      interface Layout {
          format(event: LogEvent): string;
          toString(): string;
      }

      Implemented by

      Index

      Methods

      interface Layout {
          format(event: LogEvent): string;
          toString(): string;
      }

      Implemented by

      Index

      Methods

      • Formats the given log event into its core string representation.

        Parameters

        • event: LogEvent

          The log event to format (must be a valid, immutable LogEvent).

        Returns string

        The formatted string representing the event's core content. The formatted event will be the output of the appender.

        -
      • Returns a string describing the layout, ideally including the formatter function name or configuration. +

      • Returns a string describing the layout, ideally including the formatter function name or configuration. Used for diagnostics or debugging.

        -

        Returns string

      +

      Returns string

      diff --git a/docs/typedoc/interfaces/LogEvent.html b/docs/typedoc/interfaces/LogEvent.html index 7a5b90e..e8578ab 100644 --- a/docs/typedoc/interfaces/LogEvent.html +++ b/docs/typedoc/interfaces/LogEvent.html @@ -17,7 +17,7 @@
    • Layout for the layout used to format log events before sending them to appenders.
    • Appender for the interface that handles sending log events to output channels.
    • -
      interface LogEvent {
          extraFields: LogEventExtraFields;
          message: string;
          timestamp: Date;
          type: LOG_EVENT;
          toString(): string;
      }

      Implemented by

      Index

      Properties

      interface LogEvent {
          extraFields: LogEventExtraFields;
          message: string;
          timestamp: Date;
          type: LOG_EVENT;
          toString(): string;
      }

      Implemented by

      Index

      Properties

      extraFields message timestamp type @@ -25,14 +25,14 @@

      Properties

      extraFields: LogEventExtraFields

      Additional metadata for the log event, for extension and contextual purposes. This field is immutable and must be a plain object. Intended for extensibility—avoid storing sensitive or large data here.

      -
      message: string

      The log message to be sent to the appenders. +

      message: string

      The log message to be sent to the appenders. This field is immutable. It must not be null, undefined, or an empty string.

      -
      timestamp: Date

      The timestamp when the event was created. +

      timestamp: Date

      The timestamp when the event was created. This field is immutable and must be a valid Date instance.

      -
      type: LOG_EVENT

      The event type from the LOG_EVENT enum. +

      type: LOG_EVENT

      The event type from the LOG_EVENT enum. This field is immutable and must be set at construction.

      -

      Methods

      • Returns a string representation of the log event in a human-readable, single-line format, +

      Methods

      • Returns a string representation of the log event in a human-readable, single-line format, including all relevant fields. It is expected to be implemented in a standardized way across all implementations.

        Returns string

        A string representation of the log event.

        -
      +
      diff --git a/docs/typedoc/interfaces/Logger.html b/docs/typedoc/interfaces/Logger.html index 610b9f7..6fbbca4 100644 --- a/docs/typedoc/interfaces/Logger.html +++ b/docs/typedoc/interfaces/Logger.html @@ -8,7 +8,7 @@
    • LOG_EVENT for the enumeration of log event types.
    • Layout for the layout used to format log events before sending them to appenders.
    • -
      interface Logger {
          addAppender(appender: Appender): void;
          error(msg: string, extraFields?: object): void;
          exportState(): {
              action: string;
              criticalEvents: LogEvent[];
              errorCount: number;
              level: string;
              warningCount: number;
          };
          getAction(): number;
          getAppenders(): Appender[];
          getCriticalEvents(): LogEvent[];
          getErrCnt(): number;
          getLevel(): number;
          getWarnCnt(): number;
          hasCriticalEvents(): boolean;
          hasErrors(): boolean;
          hasWarnings(): boolean;
          info(msg: string, extraFields?: object): void;
          removeAppender(appender: Appender): void;
          reset(): void;
          setAppenders(appenders: Appender[]): void;
          toString(): string;
          trace(msg: string, extraFields?: object): void;
          warn(msg: string, extraFields?: object): void;
      }

      Implemented by

      Index

      Methods

      interface Logger {
          addAppender(appender: Appender): void;
          error(msg: string, extraFields?: object): void;
          exportState(): {
              action: string;
              criticalEvents: LogEvent[];
              errorCount: number;
              level: string;
              warningCount: number;
          };
          getAction(): number;
          getAppenders(): Appender[];
          getCriticalEvents(): LogEvent[];
          getErrCnt(): number;
          getLevel(): number;
          getWarnCnt(): number;
          hasCriticalEvents(): boolean;
          hasErrors(): boolean;
          hasWarnings(): boolean;
          info(msg: string, extraFields?: object): void;
          removeAppender(appender: Appender): void;
          reset(): void;
          setAppenders(appenders: Appender[]): void;
          toString(): string;
          trace(msg: string, extraFields?: object): void;
          warn(msg: string, extraFields?: object): void;
      }

      Implemented by

      Index

      Methods

      addAppender error exportState getAction @@ -35,69 +35,69 @@ - The appender is already registered in the logger.

      Logger.setAppenders for setting multiple appenders at once and for more details on the validation of the appenders.

      -
      • Sends an error log event with the provided message and optional extraFields to all appenders.

        +
      • Sends an error log event with the provided message and optional extraFields to all appenders.

        Parameters

        • msg: string

          The error message to log.

        • OptionalextraFields: object

          Optional structured data (object) to attach to the log event. May include metadata, context, etc.

        Returns void

        ScriptError if - The singleton instance is not available (not instantiated) - The logger is configured to exit on critical events.

        -
      • Exports the current state of the logger, including level, action, error/warning counts, and critical events.

        +
      • Exports the current state of the logger, including level, action, error/warning counts, and critical events.

        Returns {
            action: string;
            criticalEvents: LogEvent[];
            errorCount: number;
            level: string;
            warningCount: number;
        }

        An object containing the logger's state.

        ScriptError if the singleton instance is not available (not instantiated).

        -
      • Gets the current action setting for error/warning events.

        +
      • Gets the current action setting for error/warning events.

        Returns number

        The action value (e.g., CONTINUE or EXIT).

        ScriptError if the singleton instance is not available (not instantiated).

        -
      • Gets the array of appenders currently registered with the logger.

        Returns Appender[]

        An array of Appender instances.

        ScriptError if the singleton instance is not available (not instantiated).

        -
      • Gets an array of all error and warning log events sent.

        Returns LogEvent[]

        An array of LogEvent objects representing error and warning events.

        ScriptError if the singleton instance is not available (not instantiated).

        -
      • Gets the total number of error log events sent.

        +
      • Gets the total number of error log events sent.

        Returns number

        The count of error events.

        ScriptError if the singleton instance is not available (not instantiated).

        -
      • Gets the current log level setting.

        Returns number

        The log level value (e.g., OFF, ERROR, WARN, INFO, TRACE). It refers to the level of verbosity to show during the logging process.

        ScriptError if the singleton instance is not available (not instantiated).

        -
      • Gets the total number of warning log events sent.

        +
      • Gets the total number of warning log events sent.

        Returns number

        The count of warning events.

        ScriptError if the singleton instance is not available (not instantiated).

        -
      • Checks if any error or warning log events have been sent.

        +
      • Checks if any error or warning log events have been sent.

        Returns boolean

        True if at least one error or warning event has been sent; otherwise, false.

        ScriptError if the singleton instance is not available (not instantiated).

        -
      • Checks if any error log events have been sent.

        +
      • Checks if any error log events have been sent.

        Returns boolean

        True if at least one error event has been sent; otherwise, false.

        ScriptError if the singleton instance is not available (not instantiated).

        -
      • Checks if any warning log events have been sent.

        +
      • Checks if any warning log events have been sent.

        Returns boolean

        True if at least one warning event has been sent; otherwise, false.

        ScriptError if the singleton instance is not available (not instantiated).

        -
      • Sends an informational log event with the provided message and optional extraFields to all appenders.

        +
      • Sends an informational log event with the provided message and optional extraFields to all appenders.

        Parameters

        • msg: string

          The informational message to log.

        • OptionalextraFields: object

          Optional structured data (object) to attach to the log event.

        Returns void

        ScriptError if the singleton instance is not available (not instantiated).

        -
      • Removes an appender from the logger, if the resulting array of appenders appender is not empty.

        +
      • Removes an appender from the logger, if the resulting array of appenders appender is not empty.

        Parameters

        • appender: Appender

          The Appender instance to remove.

        Returns void

        ScriptError if the singleton instance is not available (not instantiated).

        -
      • Clears the logger's history of error and warning events and resets counters.

        +
      • Clears the logger's history of error and warning events and resets counters.

        Returns void

        ScriptError if the singleton instance is not available (not instantiated).

        -
      • Sets the array of appenders for the logger.

        Parameters

        • appenders: Appender[]

          The array of Appender instances to set.

        Returns void

        ScriptError if - The singleton instance is not available (not instantiated). - The resulting array doesn't contain unique implementations of Appender. - appender is null or undefined or has null or undefined elements

        -
      • Returns a string representation of the logger's state, including level, action, and message counts.

        +
      • Returns a string representation of the logger's state, including level, action, and message counts.

        Returns string

        A string describing the logger's current state.

        ScriptError if the singleton instance is not available (not instantiated).

        -
      • Sends a trace log event with the provided message and optional extraFields to all appenders.

        +
      • Sends a trace log event with the provided message and optional extraFields to all appenders.

        Parameters

        • msg: string

          The trace message to log.

        • OptionalextraFields: object

          Optional structured data (object) to attach to the log event.

        Returns void

        ScriptError if the singleton instance is not available (not instantiated).

        -
      • Sends a warning log event with the provided message and optional extraFields to all appenders.

        +
      • Sends a warning log event with the provided message and optional extraFields to all appenders.

        Parameters

        • msg: string

          The warning message to log.

        • OptionalextraFields: object

          Optional structured data (object) to attach to the log event.

        Returns void

        ScriptError if - The singleton instance is not available (not instantiated) - The logger is configured to exit on critical events.

        -
      +
      diff --git a/docs/typedoc/types/LayoutFormatter.html b/docs/typedoc/types/LayoutFormatter.html index c61b039..5efe079 100644 --- a/docs/typedoc/types/LayoutFormatter.html +++ b/docs/typedoc/types/LayoutFormatter.html @@ -2,4 +2,4 @@ This is used by appenders to format log events before sending them to output channels.

      Type declaration

        • (event: LogEvent): string
        • Parameters

          • event: LogEvent

            The log event to format.

          Returns string

          A formatted string representation of the log event.

          -
      +
      diff --git a/docs/typedoc/types/LogEventExtraFields.html b/docs/typedoc/types/LogEventExtraFields.html index 1975120..aa44283 100644 --- a/docs/typedoc/types/LogEventExtraFields.html +++ b/docs/typedoc/types/LogEventExtraFields.html @@ -6,4 +6,4 @@
    • Functions should be used for dynamic values that need to be evaluated at the time of logging.
    • Avoid using complex objects or large data structures to keep log events lightweight.
    • -
      +
      diff --git a/docs/typedoc/types/LogEventFactory.html b/docs/typedoc/types/LogEventFactory.html index fe29ea4..9120a6d 100644 --- a/docs/typedoc/types/LogEventFactory.html +++ b/docs/typedoc/types/LogEventFactory.html @@ -2,4 +2,4 @@

      Type declaration

      +
      diff --git a/package.json b/package.json index 6fe6b59..dc0aa46 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "officescripts-logging-framework", - "version": "2.1.2", + "version": "2.1.3", "description": "Lightweight, extensible logging framework for Office Scripts, inspired by libraries like Log4j. Enables structured logging via a singleton 'Logger', supporting multiple log levels ('Logger.LEVEL') and pluggable output targets through the 'Appender' interface", "main": "index.js", "directories": { diff --git a/src/logger.ts b/src/logger.ts index 02e1b2c..6adb3b8 100644 --- a/src/logger.ts +++ b/src/logger.ts @@ -881,9 +881,10 @@ class LayoutImpl implements Layout { * Formats a log event as a short string as follows '[type] message'. * If extraFields are present in the event, they will be appended as a JSON object (surrounded by braces) to the output. * Example: `[ERROR] Something bad happened {"user":"dlealv","id":42}`. - * Defined as a named function to ensure toString() returns the function name. + * Defined as a named function to ensure `toString()` of `LayoutImpl` returns the function name. + * @param event - The log event to format. + * @returns A formatted string representation of the log event, as it will be sent to the appenders. */ - LayoutImpl.shortFormatterFun = Object.freeze(function shortLayoutFormatterFun(event: LogEvent): string { const sType = LOG_EVENT[event.type] let extraFieldsStr = "" @@ -898,9 +899,10 @@ LayoutImpl.shortFormatterFun = Object.freeze(function shortLayoutFormatterFun(ev * The timestamp is formatted as `YYYY-MM-DD HH:mm:ss,SSS`. * If extraFields are present in the event, they will be appended as a JSON object (surrounded by braces) to the output. * Example: `[2025-06-19 15:06:41,123] [ERROR] Something bad happened {"user":"dlealv","id":42}`. - * Defined as a named function to ensure toString() returns the function name. + * Defined as a named function to ensure `toString()` of `LayoutImpl` returns the function name. + * @param event - The log event to format. + * @returns A formatted string representation of the log event, as it will be sent to the appenders. */ - LayoutImpl.defaultFormatterFun = Object.freeze(function defaultLayoutFormatterFun(event: LogEvent): string { const sDATE = Utility.date2Str(event.timestamp) const sType = LOG_EVENT[event.type]