From 1f3c7af8e841a1077c8c5b76b2ba3213fad2fc12 Mon Sep 17 00:00:00 2001 From: David Leal Date: Sat, 12 Jul 2025 19:05:53 -0400 Subject: [PATCH 1/2] Improved TYPEDOC documentation and minor changes --- CHANGELOG.md | 6 + README.md | 24 +- docs/typedoc/assets/highlight.css | 43 +- docs/typedoc/assets/search.js | 2 +- docs/typedoc/classes/AbstractAppender.html | 94 ++- docs/typedoc/classes/ConsoleAppender.html | 110 +-- docs/typedoc/classes/ExcelAppender.html | 156 ++-- docs/typedoc/classes/LayoutImpl.html | 77 +- docs/typedoc/classes/LogEventImpl.html | 55 +- docs/typedoc/classes/LoggerImpl.html | 202 +++--- docs/typedoc/classes/ScriptError.html | 34 +- docs/typedoc/classes/Utility.html | 13 +- docs/typedoc/enums/LOG_EVENT.html | 22 +- docs/typedoc/interfaces/Appender.html | 31 +- docs/typedoc/interfaces/Layout.html | 13 +- docs/typedoc/interfaces/LogEvent.html | 32 +- docs/typedoc/interfaces/Logger.html | 62 +- docs/typedoc/types/LayoutFormatter.html | 6 +- docs/typedoc/types/LogEventExtraFields.html | 10 +- docs/typedoc/types/LogEventFactory.html | 2 +- src/logger.ts | 745 ++++++++++++-------- test/main.ts | 3 +- 22 files changed, 1031 insertions(+), 711 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e82a166..9ecbd21 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,12 @@ 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.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'`. +### Changed +- In `Logger`, `LoggerImpl` changed the name of the method `hasMessages` to `hasCriticalEvents` since it is more consistent with the purpose of the method +- Improved TYPEDOC documentation for `src/logger.ts` file. ## [2.1.1] – 2025-07-08 ### Changed diff --git a/README.md b/README.md index f8e1f3b..65f2905 100644 --- a/README.md +++ b/README.md @@ -76,7 +76,7 @@ function main(workbook: ExcelScript.Workbook) { - **Default ConsoleAppender:** - If you log a message and no appender has been added, a `ConsoleAppender` will be automatically created and added to ensure logs are not lost. - **Default Layout:** - - If the layout was not previously set, then all log events sent to all appenders will use the default layout: `[YYYY-MM-DD hh:mm:ss,XXX] [TYPE] message`, where `XXX` represents milliseconds. The format is set via the `Logger.format(event: LogEvent)` method. + - If the layout was not previously set, then all log events sent to all appenders will use the default layout: `[YYYY-MM-DD hh:mm:ss,SSS] [TYPE] message`, where `SSS` represents milliseconds. The format is set via the `Layout` interface. - **Default factory for log event:** - If the log event factory was not previously set via `AbstractAppender.setLogEventFactory(logEventFactory: LogEventFactory)`, then the log event will be built via: `new LogEventImpl(message: string, type: LOG_EVENT)`. @@ -98,7 +98,7 @@ Set the **maximum verbosity level** of messages to be logged: - `Logger.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) @@ -128,8 +128,8 @@ Set the **maximum verbosity level** of messages to be logged: - Get an array of all error/warning events: `logger.getCriticalEvents()` - Get error/warning counts: `logger.getErrCnt()`, `logger.getWarnCnt()` - Clear state (messages, counters, but not appenders): `logger.reset()` (production-safe, resets counters and critical event messages only) -- Export state: `logger.exportState()` -- Check if any error/warning log event has been sent to the appenders: `logger.hasErrors()`, `logger.hasWarnings()`, or `logger.hasMessages()` +- Export state: `logger.exportState()`, serializes the current state of the logger to a plain object. , useful for capturing logs and metrics for post-run analysis. +- Check if any error/warning log event has been sent to the appenders: `logger.hasErrors()`, `logger.hasWarnings()`, or `logger.hasCriticalEvents()` ### Resetting for Tests or Automation @@ -207,7 +207,8 @@ If you want to change all log messages globally (e.g., to add an environment pre ```typescript // Custom LogEventFactory: prefix all messages with [PROD] for production environment -const prodPrefixFactory: LogEventFactory = (msg: string, type: LOG_EVENT) => new LogEventImpl(`[PROD] ${msg}`, type) +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) @@ -250,7 +251,7 @@ Produces the following: #### How it works -- The third argument to all logging methods is `extraFields`: +- The second argument to all logging methods is `extraFields`(optional): - `Logger.info(message, extraFields?)` - `Logger.warn(message, extraFields?)` - `Logger.error(message, extraFields?)` @@ -278,7 +279,8 @@ 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", extraFields={"user":"admin","sessionId":"123"}} +event(extra fields)=LogEventImpl: {timestamp="2025-06-19 19:10:34,586", type="INFO", message="Showing toString", + extraFields={"user":"admin","sessionId":"123"}} event=LogEventImpl: {timestamp="2025-06-19 19:10:34,586", type="INFO", message="Showing toString"} ``` @@ -360,11 +362,11 @@ This ensures the logging framework is robust and reliable across both developmen ## Troubleshooting & FAQ -- **What if I call Logger methods before getInstance()?** +- **What if I call Logger methods before `getInstance()`?** Lazy initialization means logging always works, with default config and console output. - **What happens if I don’t add an appender?** - Logger auto-adds a `ConsoleAppender`. + Logger auto-adds a `ConsoleAppender`when sending the first log event. - **Can I log to both console and Excel?** Yes, just add both appenders. @@ -382,7 +384,7 @@ This ensures the logging framework is robust and reliable across both developmen - **Why can't I send a different message to different appenders?** By design, all channels (appenders) receive the same log event message for consistency. -- **Why does the output for ExcelAppender override the previous message?** +- **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`. - **Why am I getting unexpected results when running some tests in Office Scripts compared to Node.js/TypeScript?** @@ -413,7 +415,7 @@ This ensures the logging framework is robust and reliable across both developmen - For debug setup, see [docs/VSCode Debugging.md](docs/VSCode%20Debugging.md) - TypeDoc documentation: [TYPEDOC](https://dlealv.github.io/officescripts-logging-framework/typedoc/) - 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 current repository. Check repository's details for more information. +- 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. ## License diff --git a/docs/typedoc/assets/highlight.css b/docs/typedoc/assets/highlight.css index e1a75ec..61c405b 100644 --- a/docs/typedoc/assets/highlight.css +++ b/docs/typedoc/assets/highlight.css @@ -5,24 +5,26 @@ --dark-hl-1: #569CD6; --light-hl-2: #000000; --dark-hl-2: #D4D4D4; - --light-hl-3: #001080; - --dark-hl-3: #9CDCFE; - --light-hl-4: #267F99; - --dark-hl-4: #4EC9B0; - --light-hl-5: #795E26; - --dark-hl-5: #DCDCAA; - --light-hl-6: #AF00DB; - --dark-hl-6: #C586C0; - --light-hl-7: #A31515; - --dark-hl-7: #CE9178; - --light-hl-8: #000000; - --dark-hl-8: #C8C8C8; - --light-hl-9: #0070C1; - --dark-hl-9: #4FC1FF; - --light-hl-10: #000000FF; - --dark-hl-10: #D4D4D4; - --light-hl-11: #098658; - --dark-hl-11: #B5CEA8; + --light-hl-3: #0070C1; + --dark-hl-3: #4FC1FF; + --light-hl-4: #795E26; + --dark-hl-4: #DCDCAA; + --light-hl-5: #001080; + --dark-hl-5: #9CDCFE; + --light-hl-6: #A31515; + --dark-hl-6: #CE9178; + --light-hl-7: #098658; + --dark-hl-7: #B5CEA8; + --light-hl-8: #267F99; + --dark-hl-8: #4EC9B0; + --light-hl-9: #AF00DB; + --dark-hl-9: #C586C0; + --light-hl-10: #000000; + --dark-hl-10: #C8C8C8; + --light-hl-11: #000000FF; + --dark-hl-11: #D4D4D4; + --light-hl-12: #CD3131; + --dark-hl-12: #F44747; --light-code-background: #FFFFFF; --dark-code-background: #1E1E1E; } @@ -40,6 +42,7 @@ --hl-9: var(--light-hl-9); --hl-10: var(--light-hl-10); --hl-11: var(--light-hl-11); + --hl-12: var(--light-hl-12); --code-background: var(--light-code-background); } } @@ -56,6 +59,7 @@ --hl-9: var(--dark-hl-9); --hl-10: var(--dark-hl-10); --hl-11: var(--dark-hl-11); + --hl-12: var(--dark-hl-12); --code-background: var(--dark-code-background); } } @@ -72,6 +76,7 @@ --hl-9: var(--light-hl-9); --hl-10: var(--light-hl-10); --hl-11: var(--light-hl-11); + --hl-12: var(--light-hl-12); --code-background: var(--light-code-background); } @@ -88,6 +93,7 @@ --hl-9: var(--dark-hl-9); --hl-10: var(--dark-hl-10); --hl-11: var(--dark-hl-11); + --hl-12: var(--dark-hl-12); --code-background: var(--dark-code-background); } @@ -103,4 +109,5 @@ .hl-9 { color: var(--hl-9); } .hl-10 { color: var(--hl-10); } .hl-11 { color: var(--hl-11); } +.hl-12 { color: var(--hl-12); } pre, code { background: var(--code-background); } diff --git a/docs/typedoc/assets/search.js b/docs/typedoc/assets/search.js index 0537a06..eabe3ce 100644 --- a/docs/typedoc/assets/search.js +++ b/docs/typedoc/assets/search.js @@ -1 +1 @@ -window.searchData = "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"; \ No newline at end of file +window.searchData = "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"; \ No newline at end of file diff --git a/docs/typedoc/classes/AbstractAppender.html b/docs/typedoc/classes/AbstractAppender.html index 4633faf..9f952e2 100644 --- a/docs/typedoc/classes/AbstractAppender.html +++ b/docs/typedoc/classes/AbstractAppender.html @@ -1,13 +1,18 @@ AbstractAppender | officescripts-logging-framework
officescripts-logging-framework
    Preparing search index...

    Class AbstractAppenderAbstract

    Abstract base class for all log appenders. This class defines shared utility methods to standardize log formatting, label generation, and event validation across concrete appender implementations.

    -

    It relies on a LogEventFactory function to create log events, enabling flexible -and customizable event creation strategies. The LogEventFactory is validated on +

    It relies on a LogEventFactory function to create log events, enabling flexible +and customizable event creation strategies. The LogEventFactory is validated on construction to ensure it meets the expected signature. This design allows users to supply custom event creation logic if needed.

    -

    Appenders such as 'ConsoleAppender' and 'ExcelAppender' should extend this class -to inherit consistent logging behavior and event creation via the LogEventFactory.

    -

    Hierarchy (View Summary)

    Implements

    Index

    Constructors

    constructor +

    Appenders such as ConsoleAppender and ExcelAppender should extend this class +to inherit consistent logging behavior and event creation via the LogEventFactory.

    +
      +
    • Appender for the interface definition.
    • +
    • 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

    • Constructs a new AbstractAppender instance. Nothing is initialized, because the class only has static properties +

    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 the last log event

      -

      Returns void

    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.

        +

      Returns void

      ScriptError if: +- arg1 is a string but arg2 is not provided or is not a valid LOG_EVENT. +- arg1 is not a valid LogEvent. +- The log event factory is not set or is not a valid function.

      +
        +
      • If arg1 is a string, it creates a new LogEvent using the provided message and event type.
      • +
      • If arg1 is already a LogEvent, it validates the event and sends it directly.
      • +
      • The method uses the static layout to format the log event before sending it to the appenders.
      • +
      • The arg3 parameter is optional and can be used to provide additional fields for the log event.
      • +
      • It relays on abstract method sendEvent to send the log event to the appropriate destination.
      • +
      +
      // 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 event is not a valid LogEvent.

      -
    • Send the 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, +- 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

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

      -

      Returns void

    • 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. 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.

      +

      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. +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.

      -

      Parameters

      • logEventFactory: LogEventFactory

        A factory function to create LogEvent instances. -Must have the signature (message: string, eventType: LOG_EVENT) => LogEvent. +

      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.

        -

      Returns void

      ScriptError if the log event factory is not a valid function with the expected signature.

      -
      // 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 +

    Returns void

    ScriptError if the log event factory is not a valid function with the expected signature.

    +
    // 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 2b63a00..fbf9d22 100644 --- a/docs/typedoc/classes/ConsoleAppender.html +++ b/docs/typedoc/classes/ConsoleAppender.html @@ -1,16 +1,22 @@ -ConsoleAppender | officescripts-logging-framework
    officescripts-logging-framework
      Preparing search index...

      Class ConsoleAppender

      Singleton appender that logs messages to the Office Script console. It is used as default appender, +ConsoleAppender | officescripts-logging-framework

      officescripts-logging-framework
        Preparing search index...

        Class ConsoleAppender

        Singleton appender that logs messages to the console. It is used as default appender, if no other appender is defined. The content of the message event sent can be customized via -any Layout implementation, but by default it uses the LayoutImpl. +any Layout implementation, but by default it uses the LayoutImpl. Usage:

          -
        • Call ConsoleAppender.getInstance() to get the appender
        • +
        • Call ConsoleAppender.getInstance() to get the appender
        • Automatically used if no other appender is defined Warning: The console appender is a singleton, so it should not be instantiated multiple times. -@example: -// Add console appender to the Logger -Logger.addAppender(ConsoleAppender.getInstance())
        • +@example:
        -

        Hierarchy (View Summary)

        Implements

        Index

        Properties

        defaultLogEventFactoryFun +
        // Add console appender to the Logger
        Logger.addAppender(ConsoleAppender.getInstance()) +
        + +
          +
        • Appender for the interface definition.
        • +
        • 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

        Properties

        defaultLogEventFactoryFun: LogEventFactory

        Methods

        • Internal method to send the event to the console.

          +

        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.

            +

          Returns void

          ScriptError if: +- arg1 is a string but arg2 is not provided or is not a valid LOG_EVENT. +- arg1 is not a valid LogEvent. +- The log event factory is not set or is not a valid function.

          +
            +
          • If arg1 is a string, it creates a new LogEvent using the provided message and event type.
          • +
          • If arg1 is already a LogEvent, it validates the event and sends it directly.
          • +
          • The method uses the static layout to format the log event before sending it to the appenders.
          • +
          • The arg3 parameter is optional and can be used to provide additional fields for the log event.
          • +
          • It relays on abstract method sendEvent to send the log event to the appropriate destination.
          • +
          +
          // 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. +

        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, +

        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

          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).

          -
          There is no way to empty the last message sent after the instance was created unless
          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: "" +
        • 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: ""
          -
        • Gets the singleton instance of the class.

          +

          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.

          +

          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.

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

          +

          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. +

          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.

            -

          Returns void

          ScriptError if the log event factory is not a valid function with the expected signature.

          -
          // 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 +

        Returns void

        ScriptError if the log event factory is not a valid function with the expected signature.

        +
        // 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 4d3f399..0458adc 100644 --- a/docs/typedoc/classes/ExcelAppender.html +++ b/docs/typedoc/classes/ExcelAppender.html @@ -1,17 +1,32 @@ ExcelAppender | officescripts-logging-framework
        officescripts-logging-framework
          Preparing search index...

          Class ExcelAppender

          Singleton appender that logs messages to a specified Excel cell. -Logs messages in color based on the LOG_EVENT enum:

          +Logs messages in color based on the LOG_EVENT enum:

            -
          • ERROR: red, WARN: orange, INFO: green, TRACE: gray (defaults can be customized) +
          • ERROR: red, WARN: orange, INFO: green, TRACE: gray (defaults can be customized) Usage:
          • -
          • Must call ExcelAppender.getInstance(range) once with a valid single cell range
          • +
          • Must call ExcelAppender.getInstance(range) once with a valid single cell range
          • range is used to display log messages -Warning: The Excel appender is a singleton, so it should not be instantiated multiple times. -@example:
          • +Warning: The Excel appender is a singleton, so it should not be instantiated multiple times.
          -
          const range = workbook.getWorksheet("Log").getRange("A1")
          Logger.addAppender(ExcelAppender.getInstance(range)) // Add appender to the Logger +
          const range = workbook.getWorksheet("Log").getRange("A1")
          Logger.addAppender(ExcelAppender.getInstance(range)) // Add appender to the Logger
          -

          Hierarchy (View Summary)

          Implements

          Index

          Properties

            +
          • The appender requires a single cell range to display log messages.
          • +
          • The colors for each log event type can be customized by passing a map of LOG_EVENT types to hex color strings.
          • +
          • The appender clears the cell content if it is not empty before writing a new log message.
          • +
          • The appender uses the ExcelScript.Range API to write messages, so it is designed to work in Office Scripts.
          • +
          • The appender is a singleton, so it should not be instantiated multiple times.
          • +
          • The appender uses a private constructor to prevent user instantiation, and the instance is created via the static getInstance method.
          • +
          • The appender validates the input range and colors when creating the instance.
          • +
          +
            +
          • Appender for the interface definition.
          • +
          • AbstractAppender for the base class documentation.
          • +
          • LogEvent for the structure of log events.
          • +
          • 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

          Properties

          DEFAULT_EVENT_FONTS: Readonly<
              { "1": "9c0006"; "2": "ed7d31"; "3": "548235"; "4": "7f7f7f" },
          > = ...

          Default colors for log events, used if no custom colors are provided. -These colors are defined as hex strings (without the # prefix). -The colors can be customized by passing a map of LOG_EVENT types to hex color strings +These colors are defined as hex strings (without the # prefix). +The colors can be customized by passing a map of LOG_EVENT types to hex color strings when calling getInstance(). Default colors are:

            -
          • ERROR: "9c0006" (red)
          • -
          • WARN: "ed7d31" (orange)
          • -
          • INFO: "548235" (green)
          • -
          • TRACE: "7f7f7f" (gray)
          • +
          • ERROR: 9c0006 red
          • +
          • WARN: ed7d31 orange
          • +
          • INFO: 548235 green
          • +
          • TRACE: 7f7f7f gray
          -
          defaultLogEventFactoryFun: LogEventFactory

          Methods

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

            +
          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 any

            The ExcelScript.Range object representing the message cell range.

            -

            This is the cell where log messages will be displayed.

            -
          • Sets the value of the cell, with the event message, using the font defined for the event type, +

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

            +
          • 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.

              +

            Returns void

            ScriptError if: +- arg1 is a string but arg2 is not provided or is not a valid LOG_EVENT. +- arg1 is not a valid LogEvent. +- The log event factory is not set or is not a valid function.

            +
              +
            • If arg1 is a string, it creates a new LogEvent using the provided message and event type.
            • +
            • If arg1 is already a LogEvent, it validates the event and sends it directly.
            • +
            • The method uses the static layout to format the log event before sending it to the appenders.
            • +
            • The arg3 parameter is optional and can be used to provide additional fields for the log event.
            • +
            • It relays on abstract method sendEvent to send the log event to the appropriate destination.
            • +
            +
            // 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 event to the appropriate destination.

            +

            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, +

          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

            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).

            -
            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 +
          • 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
            -
          • Returns the singleton ExcelAppender instance, creating it if it doesn't exist. +

            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.

            +

            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 +color customizations for different log events (LOG_EVENT). Subsequent calls ignore parameters and return the existing instance.

            Parameters

            • msgCellRng: any

              Excel range where log messages will be written. Must be a single cell and -not null or undefined.

              -
            • eventFonts: Record<LOG_EVENT, string> = ExcelAppender.DEFAULT_EVENT_FONTS

              Optional. A map of LOG_EVENT types to hex color codes for the font colors. -If not provided, defaults to the predefined colors in DEFAULT_EVENT_FONTS. +not null or undefined.

              +
            • eventFonts: Record<LOG_EVENT, string> = ExcelAppender.DEFAULT_EVENT_FONTS

              Optional. A map of LOG_EVENT types to hex color codes for the font colors. +If not provided, defaults to the predefined colors in DEFAULT_EVENT_FONTS. The user can provide just the colors they want to customize, the rest will use the default colors.

              -

            Returns ExcelAppender

            The singleton ExcelAppender instance.

            -

            ScriptError if msgCellRng was not defined or if the range covers multiple cells +

          Returns ExcelAppender

          The singleton ExcelAppender instance.

          +

          ScriptError if msgCellRng was not defined or if the range covers multiple cells or if it is not a valid Excel range. if the font colors are not valid hexadecimal values for colors

          -
          const range = workbook.getWorksheet("Log").getRange("A1")
          const excelAppender = ExcelAppender.getInstance(range)
          ExcelAppender.getInstance(range, "ff0000") // ignored if called again +
          const range = workbook.getWorksheet("Log").getRange("A1")
          const excelAppender = ExcelAppender.getInstance(range)
          ExcelAppender.getInstance(range, "ff0000") // ignored if called again
          -

          DEFAULT_EVENT_FONTS

          -
          • 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.

            +

            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. +

            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.

              -

            Returns void

            ScriptError if the log event factory is not a valid function with the expected signature.

            -
            // 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 +

          Returns void

          ScriptError if the log event factory is not a valid function with the expected signature.

          +
          // 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 f53d80a..b36df46 100644 --- a/docs/typedoc/classes/LayoutImpl.html +++ b/docs/typedoc/classes/LayoutImpl.html @@ -1,11 +1,15 @@ -LayoutImpl | officescripts-logging-framework
          officescripts-logging-framework
            Preparing search index...

            Class LayoutImpl

            Default implementation of the 'Layout' interface. +LayoutImpl | officescripts-logging-framework

            officescripts-logging-framework
              Preparing search index...

              Class LayoutImpl

              Default implementation of the Layout interface. Formats log events into a string using a provided or default formatting function.

              • Uses the Strategy Pattern for extensibility: you can pass a custom formatting function (strategy) to the constructor.
              • -
              • All events are validated to conform to the LogEvent interface before formatting.
              • -
              • Throws ScriptError if the event does not conform to the expected LogEvent interface.
              • +
              • All events are validated to conform to the LogEvent interface before formatting.
              • +
              • Throws ScriptError if the event does not conform to the expected LogEvent interface.
              -

              Implements

              Index

              Constructors

                +
              • Layout for the interface definition.
              • +
              • LogEvent for the structure of log events.
              • +
              +

              Implements

              Index

              Constructors

              • Constructs a new LayoutImpl.

                -

                Parameters

                • Optionalformatter: LayoutFormatter

                  Optional. A function that formats a LogEvent as a string. -If not provided, a default formatter is used: "[timestamp] [type] message". -The formatter function synchronous and must accept a single LogEvent +

              Constructors

              • Constructs a new LayoutImpl.

                +

                Parameters

                • Optionalformatter: LayoutFormatter

                  Optional. A function that formats a LogEvent as a string. +If not provided, a default formatter is used: [timestamp] [type] message. +The formatter function synchronous and must accept a single LogEvent parameter and return a string.

                Returns LayoutImpl

                Strategy Pattern to allow flexible formatting via formatter function. Pass a custom function to change the formatting logic at runtime.

                ScriptError if: -- The formatter is not a function or does not have the expected arity (1 parameter). -- The formatter is null or undefined. -- The instance object is undefined or null (if subclassed or mutated in ways that break the interface).

                -
                // 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}`}) +- The formatter is not a function or does not have the expected arity (1 parameter). +- The formatter is null or undefined. +- The instance object is undefined or null (if subclassed or mutated in ways that break the interface).

                +
                // 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

              Convninient static property to define a long formatter used as default.

              -

              LayoutImpl.defaultFormatterFun

              -
              shortFormatterFun: LayoutFormatter

              Convninience static property to define a short formatter.

              -

              LayoutImpl.shortFormatterFun

              -

              Methods

              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

              • 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. -Checks for the public 'format' method (should be a function taking one argument). -Also validates the internal '_formatter' property if present, by calling validateFormatter. +

              • 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. +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.

                -

                Parameters

                • layout: Layout

                  The object to validate as a Layout implementation

                  -
                • Optionalcontext: string

                  (Optional) Additional context for error messages

                  +

                  Parameters

                  • layout: Layout

                    The object to validate as a Layout implementation.

                    +
                  • Optionalcontext: string

                    (Optional) Additional context for error messages.

                  Returns void

                  ScriptError if:

                    -
                  • layout is null or undefined
                  • -
                  • 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
                  • +
                  • layout is null or undefined.
                  • +
                  • 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 8929e01..9149d42 100644 --- a/docs/typedoc/classes/LogEventImpl.html +++ b/docs/typedoc/classes/LogEventImpl.html @@ -1,7 +1,17 @@ LogEventImpl | officescripts-logging-framework
              officescripts-logging-framework
                Preparing search index...

                Class LogEventImpl

                Implements the LogEvent interface, providing a concrete representation of a log event. It includes properties for the event type, message, and timestamp, along with methods to manage the layout used for formatting log events before sending them to appenders.

                -

                Implements

                Index

                Constructors

                  +
                • This class is immutable after construction, ensuring that all properties are set at creation time.
                • +
                • It validates the input parameters to ensure they conform to expected types and constraints.
                • +
                • 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.
                • +
                +
                  +
                • LogEvent for the interface definition.
                • +
                • LOG_EVENT for the enumeration of log event types.
                • +
                +

                Implements

                Index

                Constructors

                Accessors

                extraFields message timestamp @@ -9,23 +19,36 @@

                Methods

                Constructors

                Constructors

                • Constructs a new LogEventImpl instance. Validates the input parameters to ensure they conform to expected types and constraints.

                  Parameters

                  • message: string

                    The message to log.

                    -
                  • type: LOG_EVENT

                    The type of the log event (from LOG_EVENT enum).

                    +
                  • type: LOG_EVENT

                    The type of the log event (from LOG_EVENT enum).

                  • OptionalextraFields: LogEventExtraFields

                    (Optional) Additional fields for the log event, can include strings, numbers, dates, or functions.

                  • timestamp: Date = ...

                    (Optional) The timestamp of the event, defaults to current time.

                    -

                  Returns LogEventImpl

                  ScriptError if validation fails.

                  -

                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), +

                Returns LogEventImpl

                ScriptError if validation fails:

                +
                  +
                • type is not a valid LOG_EVENT enum value.
                • +
                • message is not a non-empty string.
                • +
                • timestamp is not a valid Date.
                • +
                • extraFields is not a plain object or contains reserved keys.
                • +
                +
                  +
                • This class is immutable after construction, ensuring that all properties are set at creation time.
                • +
                • It validates the input parameters to ensure they conform to expected types and constraints.
                • +
                • 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

                • 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 stardard 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]'.

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

                  -

                  Parameters

                  • event: unknown
                  • Optionalcontext: string

                  Returns void

                  ScriptError if event is invalid.

                  -
                +

                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).

                  +

                  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 9e39c3f..e975794 100644 --- a/docs/typedoc/classes/LoggerImpl.html +++ b/docs/typedoc/classes/LoggerImpl.html @@ -1,31 +1,37 @@ LoggerImpl | officescripts-logging-framework
                officescripts-logging-framework
                  Preparing search index...

                  Class LoggerImpl

                  Singleton class that manages application logging through appenders. -Supports the following log events: ERROR, WARN, INFO, TRACE (LOG_EVENT enum). -Supports the level of information (verbose) to show via Logger.LEVEL: OFF, ERROR, WARN, INFO, TRACE. -If the level of information (LEVEL) is OFF, no log events will be sent to the appenders. -Supports the action to take in case of ERROR, WARN log events: the script can -continue ('Logger.ACTION.CONTINUE'), or abort ('Logger.ACTION.EXIT'). Such actions only take effect -if the LEVEL is not Logger.LEVEL.OFF. +Supports the following log events: ERROR, WARN, INFO, TRACE (LOG_EVENT enum). +Supports the level of information (verbose) to show via Logger.LEVEL: OFF, ERROR, WARN, INFO, TRACE. +If the level of information (LEVEL) is OFF, no log events will be sent to the appenders. +Supports the action to take in case of ERROR, WARN log events: the script can +continue (Logger.ACTION.CONTINUE), or abort (Logger.ACTION.EXIT). Such actions only take effect +if the LEVEL is not Logger.LEVEL.OFF. Allows defining appenders, controlling the channels the events are sent to. -Collects error/warning sent by the appenders via getMessages().

                  +Collects error/warning sent by the appenders via getCriticalEvents().

                  Usage:

                    -
                  • Initialize with Logger.getInstance(level, action)
                  • -
                  • Add one or more appenders (e.g. ConsoleAppender, ExcelAppender)
                  • -
                  • Use Logger.error(), warn(), info(), or trace() to log
                  • +
                  • Initialize with Logger.getInstance(level, action).
                  • +
                  • Add one or more appenders (e.g. ConsoleAppender, ExcelAppender)
                  • +
                  • Use logger.error(), logger.warn(), logger.info(), or logger.trace() to log.

                  Features:

                    -
                  • If no appender is added, ConsoleAppender is used by default
                  • -
                  • Logs are routed through all registered appenders
                  • -
                  • Collects a summary of error/warning messages and counts -If no appender is defined when a log event occurs, LoggerImpl will automatically create and add a ConsoleAppender. +
                  • If no appender is added, ConsoleAppender is used by default.
                  • +
                  • Logs are routed through all registered appenders.
                  • +
                  • Collects a summary of error/warning messages and counts. +If no appender is defined when a log event occurs, LoggerImpl will automatically create and add a ConsoleAppender. This ensures that log messages are not silently dropped. -You may replace or remove this appender at any time using setAppenders() or removeAppender().
                  • +You may replace or remove this appender at any time using setAppenders() or removeAppender().
                  -
                  // Minimal logger usage; ConsoleAppender is auto-added if none specified
                  LoggerImpl.getInstance().info("This message will appear in the console by default."); +
                  // Minimal logger usage; ConsoleAppender is auto-added if none specified
                  LoggerImpl.getInstance().info("This message will appear in the console by default.
                  -

                  Implements

                  Index

                  Properties

                    +
                  • Logger for the interface definition.
                  • +
                  • Appender for the interface definition of the appenders
                  • +
                  • ConsoleAppender for the implementation details of the console appender.
                  • +
                  • LogEvent for the structure of log events.
                  • +
                  +

                  Implements

                  Index

                  Properties

                  ACTION: Readonly<{ CONTINUE: 0; EXIT: 1 }> = ...
                  LEVEL: Readonly<{ OFF: number } & typeof LOG_EVENT> = ...

                  Methods

                  • Adds an appender to the list of appenders.

                    +

                  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 +match the values of LOG_EVENT. Note: enum can't be defined inside a class

                  +

                  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, +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.

                    -

                    setAppenders

                    -
                  • 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. +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.

                    • OptionalextraFields: LogEventExtraFields

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

                    Returns void

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

                    -

                    ScriptError Only if level is greater than Logger.LEVEL.OFF and the action is Logger.ACTION.EXIT.

                    -
                  • Serializes the current state of the logger to a plain object, useful for +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 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, criticalEvents.

                    +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. -it includes all previous levels. For example: Logger.WARN includes warnings and errors since -Logger.ERROR is lower.

                    +
                  • 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 an error log event was sent to 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

                    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.

                    +

                  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, message summary). 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.

                    +

                  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.

                    +

                    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, +

                  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 addAppender.

                  -

                  addAppender

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

                    -

                    Returns string

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

                    -
                  • Override toString method.

                    -

                    Returns string

                    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.

                    +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.

                    +

                    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

                    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. +

                  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.

                    • OptionalextraFields: LogEventExtraFields

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

                      -

                    Returns void

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

                    -

                    ScriptError Only if level is greater than Logger.LEVEL.ERROR and the action is Logger.ACTION.EXIT.

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

                    +

                  Returns void

                  ScriptError If level is greater than Logger.LEVEL.ERROR and the action is Logger.ACTION.EXIT. +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.

                    Returns void

                    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). -It doesn't set the appenders to null, so the appenders are not cleared.

                    -

                    ScriptError If the singleton was not instantiated.

                    -
                    // 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
                    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.getInstance(LEVEL.WARN, ACTION.CONTINUE);
                    Logger.error("error event"); // Output: "error event" (no ScriptError was thrown) +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.

                    +

                    ScriptError If the singleton was not instantiated.

                    +
                    // 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.

                    +

                    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. +If neither is set, returns UNKNOWN.

                    +
                    LoggerImpl.getActionLabel(LoggerImpl.ACTION.CONTINUE) // Returns "CONTINUE"
                    LoggerImpl.getActionLabel() // Returns the current logger instance's action label
                    -
                  • Returns the label for a log action value. -If no parameter is provided, uses the current logger instance's action. -Returns "UNKNOWN" if the value is not found or logger is not initialized.

                    -

                    Parameters

                    • Optionalaction: 0 | 1

                    Returns string

                  • 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' +

                  • 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

                      Initial log level (default: Logger.LEVEL.WARN). Controls verbosity. +

                      Parameters

                      • level: number = LoggerImpl.DEFAULT_LEVEL

                        The verbosity level (default: Logger.LEVEL.WARN). Controls verbosity. Sends events to the appenders up to the defined level of verbosity. The level of verbosity is incremental, except for value -Logger.LEVEL.OFF, which suppresses all messages sent to the appenders. -For example: Logger.LEVEL.INFO allows sending errors, warnings, and information events, +Logger.LEVEL.OFF, which suppresses all messages sent to the appenders. +For example: Logger.LEVEL.INFO allows sending errors, warnings, and information events, but excludes trace events.

                        -
                      • action: 0 | 1 = LoggerImpl.DEFAULT_ACTION

                        Action on error/warning (default: Logger.ACTION.EXIT). +

                      • action: 0 | 1 = LoggerImpl.DEFAULT_ACTION

                        The action on error/warning (default: Logger.ACTION.EXIT). Determines if the script should continue or abort. -If the value is Logger.ACTION.EXIT, throws a ScriptError exception, -i.e. aborts the Script. If the action is Logger.ACTION.CONTINUE, the -script continues.

                        +If the value is Logger.ACTION.EXIT, throws a ScriptError exception, +i.e. aborts the Script. If the action is Logger.ACTION.CONTINUE, the +script continues. It only takes effect if the level is not Logger.LEVEL.OFF.

                      Returns LoggerImpl

                      The singleton Logger instance.

                      Subsequent calls ignore these parameters and return the existing instance.

                      -

                      ScriptError If the level input value was not defined in Logger.LEVEL.

                      -
                      // 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 +

                      ScriptError If the level input value was not defined in Logger.LEVEL or it doesn't +match the LOG_EVENT enum values in the specified order. +If the action input value was not defined in Logger.ACTION.

                      +
                      // 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
                      -

                      AbstractAppender.constructor for more information on how to use the logEventFactory.

                      -
                  • 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".

                    -
                  +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 464129c..8b1b1c7 100644 --- a/docs/typedoc/classes/ScriptError.html +++ b/docs/typedoc/classes/ScriptError.html @@ -1,13 +1,13 @@ ScriptError | officescripts-logging-framework
                  officescripts-logging-framework
                    Preparing search index...

                    Class ScriptError

                    A custom error class for domain-specific or script-level exceptions. Designed to provide clarity and structure when handling expected or controlled failures in scripts (e.g., logging or validation errors). It supports error chaining -through an optional 'cause' parameter, preserving the original stack trace. -Prefer using 'ScriptError' for intentional business logic errors to distinguish them +through an optional cause parameter, preserving the original stack trace. +Prefer using ScriptError for intentional business logic errors or internal errors to distinguish them from unexpected system-level failures.

                    -
                    const original = new Error("Missing field")
                    throw new ScriptError("Validation failed", original) +
                    const original = new Error("Missing field")
                    throw new ScriptError("Validation failed", original)
                    -

                    Hierarchy

                    • Error
                      • ScriptError
                    Index

                    Constructors

                    Hierarchy

                    • Error
                      • ScriptError
                    Index

                    Constructors

                    Properties

                    Constructors

                    • Constructs a new 'ScriptError'.

                      +

                    Constructors

                    • Constructs a new ScriptError.

                      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 refernece to the cause

                        -

                      Returns ScriptError

                    Properties

                    cause?: Error

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

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

                    The Error.stackTraceLimit property specifies the number of stack frames +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. +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 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 will affect any stack trace captured after the value has been changed.

                    If set to a non-number value, or set to a negative number, stack traces will not capture any frames.

                    -

                    Methods

                    • Utility method to rethrow the deepest original cause if present, -otherwise rethrows this 'ScriptError' itself. +

                    Methods

                    • Utility method to rethrow the deepest original cause if present, +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` +
                      const myObject = {};
                      Error.captureStackTrace(myObject);
                      myObject.stack; // Similar to `new Error().stack`

                      The first line of the trace will be prefixed with @@ -53,8 +53,8 @@ generated stack trace.

                      The constructorOpt argument is useful for hiding implementation details of error generation from the user. For instance:

                      -
                      function a() {
                      b();
                      }

                      function b() {
                      c();
                      }

                      function c() {
                      // Create an error without stack trace to avoid calculating the stack trace twice.
                      const { stackTraceLimit } = Error;
                      Error.stackTraceLimit = 0;
                      const error = new Error();
                      Error.stackTraceLimit = stackTraceLimit;

                      // Capture the stack trace above function b
                      Error.captureStackTrace(error, b); // Neither function c, nor b is included in the stack trace
                      throw error;
                      }

                      a(); +
                      function a() {
                      b();
                      }

                      function b() {
                      c();
                      }

                      function c() {
                      // Create an error without stack trace to avoid calculating the stack trace twice.
                      const { stackTraceLimit } = Error;
                      Error.stackTraceLimit = 0;
                      const error = new Error();
                      Error.stackTraceLimit = stackTraceLimit;

                      // Capture the stack trace above function b
                      Error.captureStackTrace(error, b); // Neither function c, nor b is included in the stack trace
                      throw error;
                      }

                      a();
                      -

                      Parameters

                      • targetObject: object
                      • OptionalconstructorOpt: Function

                      Returns void

                    +

                    Parameters

                    • targetObject: object
                    • OptionalconstructorOpt: Function

                    Returns void

                    diff --git a/docs/typedoc/classes/Utility.html b/docs/typedoc/classes/Utility.html index b546ecf..770fd90 100644 --- a/docs/typedoc/classes/Utility.html +++ b/docs/typedoc/classes/Utility.html @@ -1,12 +1,15 @@ 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

                      • Helpder to format the local date as a string. Ouptut in standard format: YYYY-MM-DD HH:mm:ss,SSS

                        -

                        Parameters

                        • date: Date

                        Returns string

                      • Helper method to check for an empty array.

                        -

                        Type Parameters

                        • T

                        Parameters

                        • arr: T[]

                        Returns boolean

                      • Validates a log event factory is a function.

                        +

                      Constructors

                      Methods

                      • Helper method to format the local date as a string. Output in standard format: YYYY-MM-DD HH:mm:ss,SSS. +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.

                        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 87bbb9f..85bd879 100644 --- a/docs/typedoc/enums/LOG_EVENT.html +++ b/docs/typedoc/enums/LOG_EVENT.html @@ -1,19 +1,19 @@ LOG_EVENT | officescripts-logging-framework
                      officescripts-logging-framework
                        Preparing search index...

                        Enumeration LOG_EVENT

                        Enum representing log event types. Each value corresponds to a the level of verbosity and is used internally to filter messages. -Logger.LEVEL static constants was implemented in a way to align with the order of the enum -LOG_EVENT, so ther order on how the LOG_EVENT values are defined matters. -Important:

                        +Logger.LEVEL static constants was implemented in a way to align with the order of the enum +LOG_EVENT, so the order on how the LOG_EVENT values are defined matters.

                        +

                        Important:

                          -
                        • If new values are added, update the logic in related classes (e.g. ExcelAppender, Logger, etc.).
                        • -
                        • Don't start the LOG_EVENT enum with 0, this value is reserved for Logger.LEVEL -for not sending log events (Logger.LEVEL.OFF). -It ensures the verbose level values are aligned with the LOG_EVENT enum. -Logger.LEVEL is built based on LOG_EVENT, just adding as first value 0, i.e. -Logger.OFF, therefore the verbosity respects the same order of the LOG_EVENT.
                        • +
                        • If new values are added, update the logic in related classes (e.g. ExcelAppender, Logger, etc.).
                        • +
                        • Don't start the LOG_EVENT enum with 0, this value is reserved for Logger.LEVEL +for not sending log events (Logger.LEVEL.OFF). +It ensures the verbose level values are aligned with the LOG_EVENT enum. +Logger.LEVEL is built based on LOG_EVENT, just adding as first value 0, i.e. +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 e2ad186..4bf4f75 100644 --- a/docs/typedoc/interfaces/Appender.html +++ b/docs/typedoc/interfaces/Appender.html @@ -1,5 +1,5 @@ -Appender | officescripts-logging-framework
                        officescripts-logging-framework
                          Preparing search index...

                          Interface Appender

                          Interface for all appenders (log destinations).

                          -

                          An appender delivers log events to a specific output channel (e.g., console, Excel, file, remote service).

                          +Appender | officescripts-logging-framework
                          officescripts-logging-framework
                            Preparing search index...

                            Interface Appender

                            Interface for all appenders (log destinations). +An appender delivers log events to a specific output channel (e.g., console, Excel, file, remote service).

                            • Implementations must provide both:
                                @@ -7,28 +7,35 @@
                              • Convenience logging via log(msg: string, event: LOG_EVENT)
                            • -
                            • Appenders are responsible for sending log events, not formatting (core formatting is handled by the Layout).
                            • +
                            • Appenders are responsible for sending log events, not formatting (core formatting is handled by the Layout interface).
                            • Implementations should be stateless or minimize instance state except for tracking the last sent event.
                            • -
                            • Common formatting and event creation concerns (such as layout or logEventFactory) are handled by the AbstractAppender base class and are not part of the interface contract.
                            • +
                            • Common formatting and event creation concerns (such as layout or logEventFactory) are handled by the AbstractAppender base class +and are not part of the interface contract.
                            • getLastLogEvent() is primarily for diagnostics, testing, or error reporting.
                            • toString() must return diagnostic information about the appender and its last log event.
                            • Provides to log methods sending a LogEvent object or a message with an event type and optional extra fields. This allows flexibility in how log events are created and sent.
                            -
                            interface Appender {
                                getLastLogEvent(): LogEvent;
                                log(event: LogEvent): void;
                                log(msg: string, type: LOG_EVENT, extraFields?: object): void;
                                toString(): string;
                            }

                            Implemented by

                            Index

                            Methods

                              +
                            • AbstractAppender for a base class that implements this interface.
                            • +
                            • LogEvent for the structure of log events.
                            • +
                            • 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

                            Methods

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

                              -

                              Returns LogEvent

                              The last LogEvent object delivered, or null.

                              +

                            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).

                              +
                            • 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 447cd8e..17ada04 100644 --- a/docs/typedoc/interfaces/Layout.html +++ b/docs/typedoc/interfaces/Layout.html @@ -4,15 +4,16 @@ but strictly for the canonical, consistent string representation of the log event.

                            • Implementations must provide consistent, stateless formatting for all log events.
                            • -
                            • Layout should be deterministic and MUST NOT mutate the event.
                            • +
                            • Layout should be deterministic and MUST NOT mutate the event.
                            • Typical implementations may provide static/shared instances for consistency.
                            • Layouts are intended for core message structure, not for display/presentation logic.
                            -
                            interface Layout {
                                format(event: LogEvent): string;
                                toString(): string;
                            }

                            Implemented by

                            Index

                            Methods

                            LogEvent for the structure of log events.

                            +
                            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.

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

                              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. Used for diagnostics or debugging.

                              -

                              Returns string

                            +

                            Returns string

                            diff --git a/docs/typedoc/interfaces/LogEvent.html b/docs/typedoc/interfaces/LogEvent.html index 731c58b..7a5b90e 100644 --- a/docs/typedoc/interfaces/LogEvent.html +++ b/docs/typedoc/interfaces/LogEvent.html @@ -1,19 +1,23 @@ LogEvent | officescripts-logging-framework
                            officescripts-logging-framework
                              Preparing search index...

                              Interface LogEvent

                              Interface for all log events to be sent to appenders. Defines the structure of a log event and is intended to be immutable.

                                -
                              • The layout (see getLayout/setLayout in concrete implementations) is used to configure +
                              • The layout of the event is not defined in this interface. +Instead, it is defined via appenders (see AbstractAppender.getLayout/AbstractAppender.setLayout) is used to configure the core content formatting of the log event output. All appenders (listeners) will output the same formatted log content, ensuring consistency. Appenders may apply their own additional presentation (e.g., colors or styles) without altering the event message itself.
                              • -
                              • getLayout/setLayout are static methods, from AbstractAppender class, share among -all subclasses.
                              • Implementations of this interface (including user extensions) must ensure all properties are assigned during construction and remain immutable.
                              • -
                              • Framework code may validate any object passed as a LogEvent to ensure all invariants hold. +
                              • Framework code may validate any object passed as a LogEvent to ensure all invariants hold. If you implement this interface directly, you are responsible for upholding these invariants.
                              -
                              interface LogEvent {
                                  extraFields: LogEventExtraFields;
                                  message: string;
                                  timestamp: Date;
                                  type: LOG_EVENT;
                                  toString(): string;
                              }

                              Implemented by

                              Index

                              Properties

                                +
                              • LOG_EVENT for the enumeration of log event types.
                              • +
                              • 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

                              extraFields message timestamp type @@ -21,12 +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. -This field is immutable. It must not be null, undefined, or an empty string.

                              -
                              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. +

                              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. +This field is immutable and must be a valid Date instance.

                              +
                              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, -including all relevant fields.

                                -

                                Returns string

                              +

                              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 ac00d2e..610b9f7 100644 --- a/docs/typedoc/interfaces/Logger.html +++ b/docs/typedoc/interfaces/Logger.html @@ -2,7 +2,13 @@ Provides methods for logging messages, querying log state, managing appenders, and exporting logger state. Implementations should ensure they should not maintain global mutable state outside the singleton and efficient log event handling.

                              -
                              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;
                                  hasErrors(): boolean;
                                  hasMessages(): 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

                                +
                              • LogEvent for the structure of log events.
                              • +
                              • Appender for the interface that handles sending log events to output channels.
                              • +
                              • 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

                              Parameters

                              • appender: Appender

                                The Appender instance to add.

                              Returns void

                              ScriptError if - The singleton instance is not available (not instantiated). -- The appender is null or undefined. +- The appender is null or undefined. - The appender is already registered in the logger.

                              -

                              Logger.setAppenders() for setting multiple appenders at once and for more details +

                              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.

                                -

                                Returns number

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

                                +
                              • 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 +

                              • 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 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 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.

                                +

                                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.

                                +- 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 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 1fd4a5a..c61b039 100644 --- a/docs/typedoc/types/LayoutFormatter.html +++ b/docs/typedoc/types/LayoutFormatter.html @@ -1 +1,5 @@ -LayoutFormatter | officescripts-logging-framework
                              officescripts-logging-framework
                                Preparing search index...

                                Type Alias LayoutFormatter

                                LayoutFormatter: (event: LogEvent) => string

                                Type declaration

                                +LayoutFormatter | officescripts-logging-framework
                                officescripts-logging-framework
                                  Preparing search index...

                                  Type Alias LayoutFormatter

                                  LayoutFormatter: (event: LogEvent) => string

                                  Type for a function that formats a log event into a string. +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 2c90836..1975120 100644 --- a/docs/typedoc/types/LogEventExtraFields.html +++ b/docs/typedoc/types/LogEventExtraFields.html @@ -1 +1,9 @@ -LogEventExtraFields | officescripts-logging-framework
                                  officescripts-logging-framework
                                    Preparing search index...

                                    Type Alias LogEventExtraFields

                                    LogEventExtraFields: { [key: string]: string | number | Date | (() => string) }

                                    Type declaration

                                    • [key: string]: string | number | Date | (() => string)
                                    +LogEventExtraFields | officescripts-logging-framework
                                    officescripts-logging-framework
                                      Preparing search index...

                                      Type Alias LogEventExtraFields

                                      LogEventExtraFields: { [key: string]: string | number | Date | (() => string) }

                                      Type for additional fields in a log event. +It is a plain object with string, number, Date, or function values. +Functions are expected to return a string when called. +This allows for dynamic content in log events.

                                      +

                                      Type declaration

                                      • [key: string]: string | number | Date | (() => string)
                                        +
                                      • 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 d499b34..fe29ea4 100644 --- a/docs/typedoc/types/LogEventFactory.html +++ b/docs/typedoc/types/LogEventFactory.html @@ -2,4 +2,4 @@

                                      Type declaration

                                      +
                                      diff --git a/src/logger.ts b/src/logger.ts index 1579e92..02e1b2c 100644 --- a/src/logger.ts +++ b/src/logger.ts @@ -45,15 +45,16 @@ /** * Enum representing log event types. * Each value corresponds to a the level of verbosity and is used internally to filter messages. - * Logger.LEVEL static constants was implemented in a way to align with the order of the enum - * LOG_EVENT, so ther *order* on how the LOG_EVENT values are defined matters. + * `Logger.LEVEL` static constants was implemented in a way to align with the order of the enum + * `LOG_EVENT`, so the *order* on how the `LOG_EVENT` values are defined matters. + * * Important: - * - If new values are added, update the logic in related classes (e.g. ExcelAppender, Logger, etc.). - * - Don't start the LOG_EVENT enum with 0, this value is reserved for Logger.LEVEL - * for not sending log events (Logger.LEVEL.OFF). - * It ensures the verbose level values are aligned with the LOG_EVENT enum. - * Logger.LEVEL is built based on LOG_EVENT, just adding as first value 0, i.e. - * Logger.OFF, therefore the verbosity respects the same order of the LOG_EVENT. + * - If new values are added, update the logic in related classes (e.g. `ExcelAppender`, `Logger`, etc.). + * - Don't start the `LOG_EVENT` enum with `0`, this value is reserved for `Logger.LEVEL` + * for not sending log events (`Logger.LEVEL.OFF`). + * It ensures the verbose level values are aligned with the `LOG_EVENT` enum. + * `Logger.LEVEL` is built based on `LOG_EVENT`, just adding as first value `0`, i.e. + * `Logger.OFF`, therefore the verbosity respects the same order of the `LOG_EVENT`. * @remarks It was defined as an independent entity since it is used by appenders and by the Logger. */ enum LOG_EVENT { @@ -73,9 +74,24 @@ enum LOG_EVENT { * @returns A LogEvent object. */ type LogEventFactory = (message: string, eventType: LOG_EVENT, extraFields?: LogEventExtraFields) => LogEvent +/** + * Type for additional fields in a log event. + * It is a plain object with string, number, Date, or function values. + * Functions are expected to return a string when called. + * This allows for dynamic content in log events. + * @remarks + * - 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. + */ type LogEventExtraFields = { [key: string]: string | number | Date | (() => string) } +/** + * Type for a function that formats a log event into a string. + * This is used by appenders to format log events before sending them to output channels. + * @param event - The log event to format. + * @returns A formatted string representation of the log event. + */ type LayoutFormatter = (event: LogEvent) => string // #endregion enum and types @@ -91,34 +107,36 @@ type LayoutFormatter = (event: LogEvent) => string * Defines the structure of a log event and is intended to be immutable. * * @remarks - * - The layout (see getLayout/setLayout in concrete implementations) is used to configure + * - The layout of the event is not defined in this interface. + * Instead, it is defined via appenders (see {@link AbstractAppender.getLayout}/{@link AbstractAppender.setLayout}) is used to configure * the core content formatting of the log event output. All appenders (listeners) will output * the same formatted log content, ensuring consistency. * Appenders may apply their own additional presentation (e.g., colors or styles) without altering * the event message itself. - * - getLayout/setLayout are static methods, from AbstractAppender class, share among - * all subclasses. * - Implementations of this interface (including user extensions) must ensure all properties * are assigned during construction and remain immutable. - * - Framework code may validate any object passed as a LogEvent to ensure all invariants hold. + * - Framework code may validate any object passed as a `LogEvent` to ensure all invariants hold. * If you implement this interface directly, you are responsible for upholding these invariants. + * @see {@link LOG_EVENT} for the enumeration of log event types. + * @see {@link Layout} for the layout used to format log events before sending them to appenders. + * @see {@link Appender} for the interface that handles sending log events to output channels. */ interface LogEvent { /** - * The event type from the LOG_EVENT enum. + * The event type from the {@link LOG_EVENT} enum. * This field is immutable and must be set at construction. */ readonly type: LOG_EVENT /** - * The log message to be sent. - * This field is immutable. It must not be null, undefined, or an empty string. + * The log message to be sent to the appenders. + * This field is immutable. It must not be `null`, `undefined`, or an empty string. */ readonly message: string /** * The timestamp when the event was created. - * This field is immutable and must be a valid Date instance. + * This field is immutable and must be a valid `Date` instance. */ readonly timestamp: Date @@ -131,7 +149,9 @@ interface LogEvent { /** * Returns a string representation of the log event in a human-readable, single-line format, - * including all relevant fields. + * including all relevant fields. It is expected to be implemented in a standardized way + * across all implementations. + * @returns A string representation of the log event. */ toString(): string } @@ -144,41 +164,46 @@ interface LogEvent { * * @remarks * - Implementations must provide consistent, stateless formatting for all log events. - * - Layout should be deterministic and MUST NOT mutate the event. + * - `Layout` should be deterministic and MUST NOT mutate the event. * - Typical implementations may provide static/shared instances for consistency. * - Layouts are intended for core message structure, not for display/presentation logic. + * @see {@link LogEvent} for the structure of log events. */ interface Layout { /** * Formats the given log event into its core string representation. - * @param event - The log event to format (must be a valid, immutable LogEvent). - * @returns The formatted string representing the event's core content. + * @param event - The log event to format (must be a valid, immutable `LogEvent`). + * @returns The formatted string representing the event's core content. The formatted event will be the output of the appender. */ - format(event: LogEvent): string; + format(event: LogEvent): string /** * Returns a string describing the layout, ideally including the formatter function name or configuration. * Used for diagnostics or debugging. */ - toString(): string; + toString(): string } /** * Interface for all appenders (log destinations). - * * An appender delivers log events to a specific output channel (e.g., console, Excel, file, remote service). * * @remarks * - Implementations must provide both: * - Structured logging via `log(event: LogEvent)` * - Convenience logging via `log(msg: string, event: LOG_EVENT)` - * - Appenders are responsible for sending log events, not formatting (core formatting is handled by the Layout). + * - Appenders are responsible for sending log events, not formatting (core formatting is handled by the `Layout` interface). * - Implementations should be stateless or minimize instance state except for tracking the last sent event. - * - Common formatting and event creation concerns (such as layout or logEventFactory) are handled by the AbstractAppender base class and are not part of the interface contract. + * - Common formatting and event creation concerns (such as layout or logEventFactory) are handled by the `AbstractAppender` base class + * and are not part of the interface contract. * - `getLastLogEvent()` is primarily for diagnostics, testing, or error reporting. * - `toString()` must return diagnostic information about the appender and its last log event. * - Provides to log methods sending a LogEvent object or a message with an event type and optional extra fields. * This allows flexibility in how log events are created and sent. + * @see {@link AbstractAppender} for a base class that implements this interface. + * @see {@link LogEvent} for the structure of log events. + * @see {@link Layout} for the layout used to format log events before sending them to appenders. + * @see {@link LOG_EVENT} for the enumeration of log event types. */ interface Appender { /** @@ -191,14 +216,14 @@ interface Appender { /** * Sends a log message to the appender, specifying the event type and optional structured extra fields. * @param msg - The message to log. - * @param type - The type of log event (from LOG_EVENT enum). + * @param type - The type of log event (from `LOG_EVENT` enum). * @param extraFields - Optional structured data (object) to attach to the log event (e.g., context info, tags). */ log(msg: string, type: LOG_EVENT, extraFields?: object): void /** - * Returns the last LogEvent delivered to the appender, or null if none sent yet. - * @returns The last LogEvent object delivered, or null. + * Returns the last `LogEvent` delivered to the appender, or `null` if none sent yet. + * @returns The last `LogEvent` object delivered, or `null`. * @throws ScriptError if the appender instance is unavailable. */ getLastLogEvent(): LogEvent | null @@ -216,6 +241,10 @@ interface Appender { * Provides methods for logging messages, querying log state, managing appenders, and exporting logger state. * Implementations should ensure they should not maintain global mutable state outside the singleton and efficient * log event handling. + * @see {@link LogEvent} for the structure of log events. + * @see {@link Appender} for the interface that handles sending log events to output channels. + * @see {@link LOG_EVENT} for the enumeration of log event types. + * @see {@link Layout} for the layout used to format log events before sending them to appenders. */ interface Logger { /** @@ -277,14 +306,14 @@ interface Logger { /** * Gets the current action setting for error/warning events. - * @returns The action value (e.g., CONTINUE or EXIT). + * @returns The action value (e.g., `CONTINUE` or `EXIT`). * @throws ScriptError if the singleton instance is not available (not instantiated). */ getAction(): number /** * Gets the current log level setting. - * @returns The log level value (e.g., OFF, ERROR, WARN, INFO, TRACE). It refers to the level of verbosity to show + * @returns The log level value (e.g., `OFF`, `ERROR`, `WARN`, `INFO`, `TRACE`). It refers to the level of verbosity to show * during the logging process. * @throws ScriptError if the singleton instance is not available (not instantiated). */ @@ -303,7 +332,7 @@ interface Logger { * @throws 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 + * - appender is `null` or `undefined` or has `null` or `undefined` elements */ setAppenders(appenders: Appender[]): void @@ -312,9 +341,9 @@ interface Logger { * @param appender - The Appender instance to add. * @throws ScriptError if * - The singleton instance is not available (not instantiated). - * - The appender is null or undefined. + * - The appender is `null` or `undefined`. * - The appender is already registered in the logger. - * @see Logger.setAppenders() for setting multiple appenders at once and for more details + * @see {@link Logger.setAppenders} for setting multiple appenders at once and for more details * on the validation of the appenders. */ addAppender(appender: Appender): void @@ -345,7 +374,7 @@ interface Logger { * @returns True if at least one error or warning event has been sent; otherwise, false. * @throws ScriptError if the singleton instance is not available (not instantiated). */ - hasMessages(): boolean + hasCriticalEvents(): boolean /** * Clears the logger's history of error and warning events and resets counters. @@ -380,14 +409,13 @@ interface Logger { // CLASSES // -------------------- - // #region ScriptError /** * A custom error class for domain-specific or script-level exceptions. * Designed to provide clarity and structure when handling expected or controlled * failures in scripts (e.g., logging or validation errors). It supports error chaining - * through an optional 'cause' parameter, preserving the original stack trace. - * Prefer using 'ScriptError' for intentional business logic errors to distinguish them + * through an optional `cause` parameter, preserving the original stack trace. + * Prefer using `ScriptError` for intentional business logic errors or internal errors to distinguish them * from unexpected system-level failures. * @example * ```ts @@ -397,10 +425,10 @@ interface Logger { */ class ScriptError extends Error { /** - * Constructs a new 'ScriptError'. + * Constructs a new `ScriptError`. * @param message A description of the error. * @param cause (Optional) The original error that caused this one. - * If provided the exception message will have a refernece to the cause + * If provided the exception message will have a reference to the cause. */ constructor(message: string, public cause?: Error) { super(message) @@ -411,7 +439,7 @@ class ScriptError extends Error { /** * Utility method to rethrow the deepest original cause if present, - * otherwise rethrows this 'ScriptError' itself. + * otherwise rethrows this `ScriptError` itself. * Useful for deferring a controlled exception and then * surfacing the root cause explicitly. */ @@ -433,6 +461,7 @@ class ScriptError extends Error { * 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. + * @override */ public toString(): string { const stack = this.cause?.stack ? this.cause.stack : this.stack @@ -446,7 +475,10 @@ class ScriptError extends Error { * Utility class providing static helper methods for logging operations. */ class Utility { - /**Helpder to format the local date as a string. Ouptut in standard format: YYYY-MM-DD HH:mm:ss,SSS + /**Helper method to format the local date as a string. Output in standard format: `YYYY-MM-DD HH:mm:ss,SSS`. + * where `SSS` is the milliseconds part padded to `3` digits. + * @param date - The date to format. + * @returns A string representation of the date in the format `YYYY-MM-DD HH:mm:ss,SSS`. */ public static date2Str(date: Date): string { // Defensive: handle null, undefined, or non-Date input @@ -461,12 +493,12 @@ class Utility { }:${pad(date.getMinutes()) }:${pad(date.getSeconds()) },${pad(date.getMilliseconds(), 3) - }`; + }` } /** Helper method to check for an empty array. */ public static isEmptyArray(arr: T[]): boolean { - return (!Array.isArray(arr) || !arr.length) ? true : false; + return (!Array.isArray(arr) || !arr.length) ? true : false } /** @@ -481,20 +513,26 @@ class Utility { funName?: string, context?: string ): void { - const PREFIX = context ? `[${context}]: ` : ''; + const PREFIX = context ? `[${context}]: ` : '' if (typeof factory !== 'function') { - throw new ScriptError(`${PREFIX}Invalid ${funName || ""}: Not a function`); + throw new ScriptError(`${PREFIX}Invalid ${funName || ""}: Not a function`) } } } - // #region LogEventImpl /** * Implements the LogEvent interface, providing a concrete representation of a log event. * It includes properties for the event type, message, and timestamp, along with methods to manage * the layout used for formatting log events before sending them to appenders. + * @remarks + * - This class is immutable after construction, ensuring that all properties are set at creation time. + * - It validates the input parameters to ensure they conform to expected types and constraints. + * - 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. + * @see {@link LogEvent} for the interface definition. + * @see {@link LOG_EVENT} for the enumeration of log event types. */ class LogEventImpl implements LogEvent { private readonly _type: LOG_EVENT @@ -507,13 +545,22 @@ class LogEventImpl implements LogEvent { /** - * Constructs a new LogEventImpl instance. + * Constructs a new `LogEventImpl` instance. * Validates the input parameters to ensure they conform to expected types and constraints. - * @param type - The type of the log event (from LOG_EVENT enum). + * @param type - The type of the log event (from `LOG_EVENT` enum). * @param message - The message to log. * @param timestamp - (Optional) The timestamp of the event, defaults to current time. * @param extraFields - (Optional) Additional fields for the log event, can include strings, numbers, dates, or functions. - * @throws ScriptError if validation fails. + * @throws ScriptError if validation fails: + * - `type` is not a valid `LOG_EVENT` enum value. + * - `message` is not a non-empty string. + * - `timestamp` is not a valid `Date`. + * - `extraFields` is not a plain object or contains reserved keys. + * @remarks + * - This class is immutable after construction, ensuring that all properties are set at creation time. + * - It validates the input parameters to ensure they conform to expected types and constraints. + * - 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. */ constructor(message: string, type: LOG_EVENT, extraFields?: LogEventExtraFields, timestamp: Date = new Date(), ) { @@ -532,7 +579,7 @@ class LogEventImpl implements LogEvent { } /** - * @returns The event type from LOG_EVENT enum (immutable). + * @returns The event type from `LOG_EVENT` enum (immutable). * @override */ public get type(): LOG_EVENT { return this._type } @@ -551,7 +598,7 @@ class LogEventImpl implements LogEvent { /** * Gets the extra fields of the log event. - * @returns Returns a shallow copy of custom fields for this event. These are immutable (Object.freeze), + * @returns 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. * @override */ @@ -560,8 +607,8 @@ class LogEventImpl implements LogEvent { } /** - * Validates if the input object conforms to the LogEvent interface (for any implementation). - * @throws ScriptError if event is invalid. + * Validates if the input object conforms to the `LogEvent` interface (for any implementation). + * @throws ScriptError if log event is invalid. */ public static validateLogEvent(event: unknown, context?: string): void { const PREFIX = context ? `[${context}]: ` : `[${LogEventImpl.name}.validateLogEvent]: ` @@ -584,7 +631,7 @@ class LogEventImpl implements LogEvent { } /** - * @returns A string representation of the log event in stardard toString format + * @returns A string representation of the log event in standard `toString` format * @override */ public toString(): string { @@ -599,8 +646,9 @@ class LogEventImpl implements LogEvent { /** * Returns a standardized label for the given log event. - * @param type - The event type from 'LOG_EVENT' enum. - * @returns A string label, e.g., '[INFO]', '[ERROR]'. + * @param type - The event type from `LOG_EVENT` enum. + * @returns A string label, e.g., `[INFO]`, `[ERROR]`. + * @throws ScriptError if the type is not a valid `LOG_EVENT` enum value. */ public static eventTypeToLabel(type: LOG_EVENT): string { const event = { type, message: "dummy", timestamp: new Date(), extraFields: {} } as LogEvent // Create a dummy message to pass the message validation @@ -620,41 +668,41 @@ class LogEventImpl implements LogEvent { extraFields?: unknown, context?: string ): void { - const PREFIX = context ? `[${context}]: ` : `[${LogEventImpl.name}.validateLogEventAttrs]: `; + const PREFIX = context ? `[${context}]: ` : `[${LogEventImpl.name}.validateLogEventAttrs]: ` // Validate type if (typeof attrs.type !== 'number') { - throw new ScriptError(`${PREFIX}LogEvent.type='${attrs.type}' property must be a number (LOG_EVENT enum value).`); + throw new ScriptError(`${PREFIX}LogEvent.type='${attrs.type}' property must be a number (LOG_EVENT enum value).`) } if (!Object.values(LOG_EVENT).includes(attrs.type as LOG_EVENT)) { - throw new ScriptError(`${PREFIX}LogEvent.type='${attrs.type}' property is not defined in the LOG_EVENT enum.`); + throw new ScriptError(`${PREFIX}LogEvent.type='${attrs.type}' property is not defined in the LOG_EVENT enum.`) } // Validate message if (typeof attrs.message !== 'string') { - throw new ScriptError(`${PREFIX}LogEvent.message='${attrs.message}' property must be a string.`); + throw new ScriptError(`${PREFIX}LogEvent.message='${attrs.message}' property must be a string.`) } if (attrs.message.trim().length === 0) { - throw new ScriptError(`${PREFIX}LogEvent.message cannot be empty.`); + throw new ScriptError(`${PREFIX}LogEvent.message cannot be empty.`) } // Validate timestamp if (!(attrs.timestamp instanceof Date)) { - throw new ScriptError(`${PREFIX}LogEvent.timestamp='${attrs.timestamp}' property must be a Date.`); + throw new ScriptError(`${PREFIX}LogEvent.timestamp='${attrs.timestamp}' property must be a Date.`) } // Validate extraFields if provided if (extraFields !== undefined) { if (typeof extraFields !== "object" || extraFields === null || Array.isArray(extraFields)) { - throw new ScriptError(`${PREFIX}extraFields must be a plain object.`); + throw new ScriptError(`${PREFIX}extraFields must be a plain object.`) } for (const [k, v] of Object.entries(extraFields)) { if (v === undefined) { - throw new ScriptError(`${PREFIX}extraFields[${k}] must not be undefined.`); + throw new ScriptError(`${PREFIX}extraFields[${k}] must not be undefined.`) } if (typeof v !== "string" && typeof v !== "number" && !(v instanceof Date) && typeof v !== "function") { - throw new ScriptError(`${PREFIX}extraFields[${k}] has invalid type: ${typeof v}. Must be string, number, Date, or function.`); + throw new ScriptError(`${PREFIX}extraFields[${k}] has invalid type: ${typeof v}. Must be string, number, Date, or function.`) } } } @@ -666,24 +714,24 @@ class LogEventImpl implements LogEvent { // #region LayoutImpl /** - * Default implementation of the 'Layout' interface. + * Default implementation of the `Layout` interface. * Formats log events into a string using a provided or default formatting function. - * * @remarks * - Uses the Strategy Pattern for extensibility: you can pass a custom formatting function (strategy) to the constructor. - * - All events are validated to conform to the LogEvent interface before formatting. - * - Throws ScriptError if the event does not conform to the expected LogEvent interface. + * - All events are validated to conform to the `LogEvent` interface before formatting. + * - Throws `ScriptError` if the event does not conform to the expected `LogEvent` interface. + * @see {@link Layout} for the interface definition. + * @see {@link LogEvent} for the structure of log events. */ class LayoutImpl implements Layout { - /**Convninience static property to define a short formatter. - * @see LayoutImpl.shortFormatterFun - */ + /**Convenience static property to define a short formatter, e.g. `[type] message`. + */ public static shortFormatterFun: LayoutFormatter - /**Convninient static property to define a long formatter used as default. - * @see LayoutImpl.defaultFormatterFun + /**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. */ public static defaultFormatterFun: LayoutFormatter @@ -694,19 +742,19 @@ class LayoutImpl implements Layout { private readonly _formatter: LayoutFormatter /** - * Constructs a new LayoutImpl. - * - * @param formatter - Optional. A function that formats a LogEvent as a string. - * If not provided, a default formatter is used: "[timestamp] [type] message". - * The formatter function synchronous and must accept a single LogEvent - * parameter and return a string. + * Constructs a new `LayoutImpl`. * + * @param formatter - Optional. A function that formats a `LogEvent` as a string. + * If not provided, a default formatter is used: `[timestamp] [type] message`. + * The formatter function synchronous and must accept a single `LogEvent` + * parameter and return a string. + * * @remarks Strategy Pattern to allow flexible formatting via formatter function. * Pass a custom function to change the formatting logic at runtime. * @throws ScriptError if: - * - The formatter is not a function or does not have the expected arity (1 parameter). - * - The formatter is null or undefined. - * - The instance object is undefined or null (if subclassed or mutated in ways that break the interface). + * - The formatter is not a function or does not have the expected arity (`1` parameter). + * - The formatter is `null` or `undefined`. + * - The instance object is `undefined` or `null` (if subclassed or mutated in ways that break the interface). * @example * // Using the default formatter: * const layout = new LayoutImpl() @@ -737,9 +785,9 @@ class LayoutImpl implements Layout { /** * Formats the given log event as a string. - * @param event - The event to format. + * @param event - The log event to format. * @returns A string representation of the log event. - * @throws ScriptError if the event does not conform to the LogEvent interface. + * @throws ScriptError if the event does not conform to the `LogEvent` interface. * @override */ public format(event: LogEvent): string { @@ -759,16 +807,16 @@ class LayoutImpl implements Layout { /** * 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. + * 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. * - * @param layout - The object to validate as a Layout implementation - * @param context - (Optional) Additional context for error messages + * @param layout - The object to validate as a Layout implementation. + * @param context - (Optional) Additional context for error messages. * @throws ScriptError if: - * - layout is null or undefined - * - 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 + * - layout is `null` or `undefined`. + * - 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`. */ static validateLayout(layout: Layout, context?: string) { const PREFIX = context ? `[${context}]: ` : "[LayoutImpl.validateLayout]: " @@ -779,7 +827,7 @@ class LayoutImpl implements Layout { throw new ScriptError( `{PREFIX} Invalid Layout: The 'format' method must be a function accepting a single LogEvent argument. ` + `See LayoutImpl documentation for usage.` - ); + ) } if (layout instanceof LayoutImpl) { LayoutImpl.validateFormatter(layout._formatter, context) @@ -788,21 +836,21 @@ class LayoutImpl implements Layout { /** * 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. + * 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. * - * @param formatter - The candidate formatter function to validate - * @param context - (Optional) Additional context for error messages - * @throws ScriptError if formatter is missing, not a function, doesn't have arity 1, - * or returns null/empty string for a sample event. + * @param formatter - The candidate formatter function to validate. + * @param context - (Optional) Additional context for error messages. + * @throws ScriptError if formatter is missing, not a function, doesn't have arity `1`, + * or returns `null`/empty string for a sample event. */ static validateFormatter(formatter: LayoutFormatter, context?: string) { - const PREFIX = context ? `[${context}]: ` : "[LayoutImpl.validateFormatter]: "; + const PREFIX = context ? `[${context}]: ` : "[LayoutImpl.validateFormatter]: " if (typeof formatter !== "function" || formatter.length !== 1) { throw new ScriptError( PREFIX + "Invalid Layout: The internal '_formatter' property must be a function accepting a single LogEvent argument. See LayoutImpl documentation for usage." - ); + ) } // Try calling with a mock event const mockEvent: LogEvent = { @@ -810,8 +858,8 @@ class LayoutImpl implements Layout { message: "test", timestamp: new Date(), extraFields: {}, - }; - const result = formatter(mockEvent); + } + const result = formatter(mockEvent) if ( typeof result !== "string" || result === "" || @@ -821,7 +869,7 @@ class LayoutImpl implements Layout { PREFIX + "Formatter function must return a non-empty string for a valid LogEvent. Got: " + (result === "" ? "empty string" : String(result)) - ); + ) } } @@ -832,7 +880,7 @@ class LayoutImpl implements Layout { * 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} + * Example: `[ERROR] Something bad happened {"user":"dlealv","id":42}`. * Defined as a named function to ensure toString() returns the function name. */ @@ -846,10 +894,10 @@ LayoutImpl.shortFormatterFun = Object.freeze(function shortLayoutFormatterFun(ev }) /** - * 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. + * 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} + * 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. */ @@ -872,13 +920,16 @@ LayoutImpl.defaultFormatterFun = Object.freeze(function defaultLayoutFormatterFu * This class defines shared utility methods to standardize log formatting, * label generation, and event validation across concrete appender implementations. * - * It relies on a LogEventFactory function to create log events, enabling flexible - * and customizable event creation strategies. The LogEventFactory is validated on + * It relies on a `LogEventFactory` function to create log events, enabling flexible + * and customizable event creation strategies. The `LogEventFactory` is validated on * construction to ensure it meets the expected signature. This design allows users * to supply custom event creation logic if needed. - * - * Appenders such as 'ConsoleAppender' and 'ExcelAppender' should extend this class - * to inherit consistent logging behavior and event creation via the LogEventFactory. + * + * Appenders such as `ConsoleAppender` and `ExcelAppender` should extend this class + * to inherit consistent logging behavior and event creation via the `LogEventFactory`. + * @see {@link Appender} for the interface definition. + * @see {@link LogEventFactory} for the factory function type used to create log events. + * @see {@link Layout} for the layout used to format log events before sending them to appenders. */ abstract class AbstractAppender implements Appender { // Default factory function to create LogEvent instances, if was not set before. @@ -890,7 +941,7 @@ abstract class AbstractAppender implements Appender { private _lastLogEvent: LogEvent | null = null // The last event sent by the appender /** - * Constructs a new AbstractAppender instance. Nothing is initialized, because the class only has static properties + * Constructs a new `AbstractAppender` instance. Nothing is initialized, because the class only has static properties * that are lazy initialized or set by the user. */ protected constructor() { } @@ -909,9 +960,9 @@ abstract class AbstractAppender implements Appender { } /** - * Sets the log event factory function used to create LogEvent instances if it was not set before. - * @param logEventFactory - A factory function to create LogEvent instances. - * Must have the signature (message: string, eventType: LOG_EVENT) => LogEvent. + * Sets the log event factory function used to create `LogEvent` instances if it was not set before. + * @param logEventFactory - A factory function to create `LogEvent` instances. + * Must have the signature `(message: string, eventType: LOG_EVENT) => LogEvent`, i.e. {@link LogEventFactory} type. * If not provided, a default factory function is used. * @throws ScriptError if the log event factory is not a valid function with the expected signature. * @example @@ -929,7 +980,8 @@ abstract class AbstractAppender implements Appender { } } - /** 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 The log event factory function. */ public static getLogEventFactory(): LogEventFactory { @@ -953,10 +1005,29 @@ abstract class AbstractAppender implements Appender { } /** - * Log a message or event. - * @param arg1 - LogEvent or message string. - * @param arg2 - LOG_EVENT, only required if arg1 is a string. - * @param arg3 - extraFields, only used if arg1 is a string. + * Log a message or log event. + * @param arg1 - `LogEvent` or message string. + * @param arg2 - `LOG_EVENT`, only required if `arg1` is a string. + * @param arg3 - `extraFields`, only used if `arg1` is a string. + * @throws ScriptError if: + * - `arg1` is a string but `arg2` is not provided or is not a valid `LOG_EVENT`. + * - `arg1` is not a valid `LogEvent`. + * - The log event factory is not set or is not a valid function. + * @remarks + * - If `arg1` is a string, it creates a new `LogEvent` using the provided message and event type. + * - If `arg1` is already a `LogEvent`, it validates the event and sends it directly. + * - The method uses the static layout to format the log event before sending it to the appenders. + * - The `arg3` parameter is optional and can be used to provide additional fields for the log event. + * - It relays on abstract method `sendEvent` to send the log event to the appropriate destination. + * @example + * ```ts + * // 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 + * ``` * @override */ @@ -984,14 +1055,20 @@ abstract class AbstractAppender implements Appender { } // #TEST-ONLY-START - /** Sets to null the static layout, useful for running different scenarios.*/ + /** Sets to `null` the static layout, useful for running different scenarios. + * @remarks 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). + */ public static clearLayout(): void { AbstractAppender._layout = null // Force full re-init } // #TEST-ONLY-END // #TEST-ONLY-START - /** Sets to null the log event factory, useful for running different scenarios.*/ + /** Sets to `null` the log event factory, useful for running different scenarios. + * @remarks 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). + */ public static clearLogEventFactory(): void { AbstractAppender._logEventFactory = null // Force full re-init } @@ -1014,19 +1091,21 @@ abstract class AbstractAppender implements Appender { } /** - * Send the event to the appropriate destination. The event is stored based on the + * 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.). * @param event - The log event to be sent. * @param context - (Optional) A string to provide additional context in case of an error. * @throws ScriptError if - * - The event is not a valid LogEvent. + * - The log event is not a valid `LogEvent`. */ protected abstract sendEvent(event: LogEvent, context?: string): void /** - * Send the event to the appropriate destination. + * Send the log event to the appropriate destination. * @param event - The log event to be sent. * @throws ScriptError if - * - The event is not a valid LogEvent. + * - The event is not a valid `LogEvent`. * @remarks * Subclasses **must** call `setLastLogEvent(event)` after successfully sending the event, * otherwise `getLastLogEvent()` will not reflect the most recent log event. @@ -1038,7 +1117,10 @@ abstract class AbstractAppender implements Appender { } // #TEST-ONLY-START - /**To ensure when invoking clearInstance in a sub-class it also clear the last log event */ + /**To ensure when invoking clearInstance in a sub-class it also clear (`null`) the last log event. + * @remarks 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). + */ protected clearLastLogEvent(): void { this._lastLogEvent = null } @@ -1056,15 +1138,25 @@ abstract class AbstractAppender implements Appender { funName?: string, context?: string ): void { - const PREFIX = context ? `[${context}]: ` : ''; + const PREFIX = context ? `[${context}]: ` : '' if (typeof factory !== 'function') { - throw new ScriptError(`${PREFIX}Invalid ${funName || ""}: Not a function`); + throw new ScriptError(`${PREFIX}Invalid ${funName || ""}: Not a function`) } } } // Functions outside of the class: +/** + * 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) @@ -1076,16 +1168,21 @@ AbstractAppender.defaultLogEventFactoryFun = Object.freeze( // #region ConsoleAppender /** - * Singleton appender that logs messages to the Office Script console. It is used as default appender, + * Singleton appender that logs messages to the console. It is used as default appender, * if no other appender is defined. The content of the message event sent can be customized via - * any Layout implementation, but by default it uses the LayoutImpl. + * any `Layout` implementation, but by default it uses the `LayoutImpl`. * Usage: - * - Call ConsoleAppender.getInstance() to get the appender + * - Call `ConsoleAppender.getInstance()` to get the appender * - Automatically used if no other appender is defined * Warning: The console appender is a singleton, so it should not be instantiated multiple times. * @example: + * ```ts * // Add console appender to the Logger * Logger.addAppender(ConsoleAppender.getInstance()) + * ``` + * @see {@link Appender} for the interface definition. + * @see {@link AbstractAppender} for the base class documentation. + * @see {@link Layout} for the layout used to format log events before sending them to the console. */ class ConsoleAppender extends AbstractAppender implements Appender { private static _instance: ConsoleAppender | null = null // Instance of the singleton pattern @@ -1098,7 +1195,7 @@ class ConsoleAppender extends AbstractAppender implements Appender { super() // Call the parent constructor without layout } - /**Override toString method. Show the last message event sent + /**Override `toString` method. Show the last message event sent. * @throws ScriptError If the singleton was not instantiated */ public toString(): string { @@ -1119,18 +1216,20 @@ class ConsoleAppender extends AbstractAppender implements Appender { } // #TEST-ONLY-START - /** 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. - * @remarks 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 singleton instance, useful for running different scenarios. + * It also sets to `null` the parent property `lastLogEvent`, so the last log event is cleared. * @example There is no way to empty the last message sent after the instance was created unless * you reset it. + * ```ts * 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: "" + * ``` + * @remarks 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). */ public static clearInstance(): void { if (ConsoleAppender._instance) { @@ -1141,11 +1240,11 @@ class ConsoleAppender extends AbstractAppender implements Appender { // #TEST-ONLY-END /** - * Internal method to send the event to the console. + * Protected method to send the event to the console. At this point is where the event is formatted before sending it to the console. * @param event - The log event to output. * @param context - (Optional) A string to provide additional context in case of an error. * @throws ScriptError if - * The event is not a valid LogEvent. + * The event is not a valid `LogEvent`. * The instance is not available (not instantiated). * @override */ @@ -1181,49 +1280,64 @@ class ConsoleAppender extends AbstractAppender implements Appender { // #region ExcelAppender /** * Singleton appender that logs messages to a specified Excel cell. - * Logs messages in color based on the LOG_EVENT enum: - * - ERROR: red, WARN: orange, INFO: green, TRACE: gray (defaults can be customized) + * Logs messages in color based on the `LOG_EVENT` enum: + * - `ERROR`: red, `WARN`: orange, `INFO`: green, `TRACE`: gray (defaults can be customized) * Usage: - * - Must call ExcelAppender.getInstance(range) once with a valid single cell range + * - Must call `ExcelAppender.getInstance(range)` once with a valid single cell range * - range is used to display log messages * Warning: The Excel appender is a singleton, so it should not be instantiated multiple times. - * @example: + * @example * ```ts * const range = workbook.getWorksheet("Log").getRange("A1") * Logger.addAppender(ExcelAppender.getInstance(range)) // Add appender to the Logger * ``` + * @remarks + * - The appender requires a single cell range to display log messages. + * - The colors for each log event type can be customized by passing a map of `LOG_EVENT` types to hex color strings. + * - The appender clears the cell content if it is not empty before writing a new log message. + * - The appender uses the `ExcelScript.Range` API to write messages, so it is designed to work in Office Scripts. + * - The appender is a singleton, so it should not be instantiated multiple times. + * - The appender uses a private constructor to prevent user instantiation, and the instance is created via the static `getInstance` method. + * - The appender validates the input range and colors when creating the instance. + * @see {@link Appender} for the interface definition. + * @see {@link AbstractAppender} for the base class documentation. + * @see {@link LogEvent} for the structure of log events. + * @see {@link Layout} for the layout used to format log events before sending them to Excel. + + * @see {@link ConsoleAppender} for an example of a console appender that logs messages to the console. */ class ExcelAppender extends AbstractAppender implements Appender { /** * Default colors for log events, used if no custom colors are provided. - * These colors are defined as hex strings (without the # prefix). - * The colors can be customized by passing a map of LOG_EVENT types to hex color strings + * These colors are defined as hex strings (without the `#` prefix). + * The colors can be customized by passing a map of `LOG_EVENT` types to hex color strings * when calling getInstance(). Default colors are: - * - ERROR: "9c0006" (red) - * - WARN: "ed7d31" (orange) - * - INFO: "548235" (green) - * - TRACE: "7f7f7f" (gray) + * - `ERROR`: `9c0006` red + * - `WARN`: `ed7d31` orange + * - `INFO`: `548235` green + * - `TRACE`: `7f7f7f` gray */ public static readonly DEFAULT_EVENT_FONTS = Object.freeze({ [LOG_EVENT.ERROR]: "9c0006", // RED [LOG_EVENT.WARN]: "ed7d31", // ORANGE [LOG_EVENT.INFO]: "548235", // GREEN [LOG_EVENT.TRACE]: "7f7f7f" // GRAY - } as const); + } as const) /** * Instance-level font map for current appender configuration. - * Maps LOG_EVENT types to hex font strings. + * Maps `LOG_EVENT` types to hex font strings. */ private readonly _eventFonts: Record - /* Regular expression to validate hexadecimal fonts */ + /* Regular expression to validate hexadecimal fonts. */ private static readonly HEX_REGEX = Object.freeze(/^#?[0-9A-Fa-f]{6}$/) - private static _instance: ExcelAppender | null = null; // Instance of the singleton pattern + private static _instance: ExcelAppender | null = null // Instance of the singleton pattern private readonly _msgCellRng: ExcelScript.Range - /* Required for Office Script limitation, only use getAddress, the first time _msgCellRng is assigned, then - use this property. Calling this._msgCellRng.getAddress() fails in toString(). The workaround is to create + + /* Required for Office Script limitation, only use `getAddress`, the first time `_msgCellRng` is assigned, then + use this property. Calling `this._msgCellRng.getAddress()` fails in toString(). The workaround is to create this artificial property. */ private _msgCellRngAddress: string @@ -1236,7 +1350,6 @@ class ExcelAppender extends AbstractAppender implements Appender { ) { super() this._msgCellRng = msgCellRng - this.clearCellIfNotEmpty() // it can't be called in the construtor due to Office Script limitations this._eventFonts = eventFonts } @@ -1244,15 +1357,15 @@ class ExcelAppender extends AbstractAppender implements Appender { /** * Returns the map of event types to font colors used by this appender. * @returns A defensive copy of the event fonts map. - * @remarks The keys are LOG_EVENT enum values, and the values are hex color strings. + * @remarks The keys are `LOG_EVENT` enum values, and the values are hex color strings. */ public getEventFonts(): Record { - return { ...this._eventFonts }; // Defensive copy + return { ...this._eventFonts } // Defensive copy } /** * Returns the Excel range where log messages are written. - * @returns The ExcelScript.Range object representing the message cell range. + * @returns The `ExcelScript.Range` object representing the message cell range. * @remarks This is the cell where log messages will be displayed. */ public getMsgCellRng(): ExcelScript.Range { @@ -1260,18 +1373,18 @@ class ExcelAppender extends AbstractAppender implements Appender { } /** - * Returns the singleton ExcelAppender instance, creating it if it doesn't exist. + * 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 + * color customizations for different log events (`LOG_EVENT`). Subsequent calls ignore parameters * and return the existing instance. * @param msgCellRng - Excel range where log messages will be written. Must be a single cell and - * not null or undefined. - * @param eventFonts - Optional. A map of LOG_EVENT types to hex color codes for the font colors. - * If not provided, defaults to the predefined colors in DEFAULT_EVENT_FONTS. + * not `null` or `undefined`. + * @param eventFonts - Optional. A map of `LOG_EVENT` types to hex color codes for the font colors. + * If not provided, defaults to the predefined colors in `DEFAULT_EVENT_FONTS`. * The user can provide just the colors they want to customize, * the rest will use the default colors. - * @returns The singleton ExcelAppender instance. - * @throws ScriptError if msgCellRng was not defined or if the range covers multiple cells + * @returns The singleton `ExcelAppender` instance. + * @throws ScriptError if `msgCellRng` was not defined or if the range covers multiple cells * or if it is not a valid Excel range. * if the font colors are not valid hexadecimal values for colors * @example @@ -1280,7 +1393,7 @@ class ExcelAppender extends AbstractAppender implements Appender { * const excelAppender = ExcelAppender.getInstance(range) * ExcelAppender.getInstance(range, "ff0000") // ignored if called again * ``` - * @see DEFAULT_EVENT_FONTS + * @see {@link ExcelAppender.DEFAULT_EVENT_FONTS} */ public static getInstance( msgCellRng: ExcelScript.Range, eventFonts: Record = ExcelAppender.DEFAULT_EVENT_FONTS @@ -1288,11 +1401,11 @@ class ExcelAppender extends AbstractAppender implements Appender { const PREFIX = `[${ExcelAppender.name}.getInstance]: ` if (!ExcelAppender._instance) { if (!msgCellRng || !msgCellRng.setValue) { - const MSG = `${PREFIX}A valid ExcelScript.Range for input argument msgCellRng is required.`; + const MSG = `${PREFIX}A valid ExcelScript.Range for input argument msgCellRng is required.` throw new ScriptError(MSG) } if (msgCellRng.getCellCount() != 1) { - const MSG = `${PREFIX}Input argument msgCellRng must represent a single Excel cell.`; + const MSG = `${PREFIX}Input argument msgCellRng must represent a single Excel cell.` throw new ScriptError(MSG) } // Enhanced Excel Range check in getInstance: @@ -1305,14 +1418,14 @@ class ExcelAppender extends AbstractAppender implements Appender { } // Checking valid hexadecimal color ExcelAppender.validateLogEventMappings() // Validate all LOG_EVENT mappings for fonts - const CONTEXT = `${ExcelAppender.name}.getInstance`; + const CONTEXT = `${ExcelAppender.name}.getInstance` // Merge defaults with user-provided values (user takes precedence) const fonts: Record = { ...ExcelAppender.DEFAULT_EVENT_FONTS, ...(eventFonts ?? {}) - }; + } for (const [event, font] of Object.entries(fonts)) { - const label = LOG_EVENT[Number(event)]; + const label = LOG_EVENT[Number(event)] ExcelAppender.validateFont(font, label, CONTEXT) } ExcelAppender._instance = new ExcelAppender(msgCellRng, fonts) @@ -1326,10 +1439,8 @@ class ExcelAppender extends AbstractAppender implements Appender { // #TEST-ONLY-START /** - * 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. - * @remarks 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 singleton instance, useful for running different scenarios. + * It also sets to `null` the parent property `lastLogEvent`, so the last log event is cleared. * @example * ```ts * const activeSheet = workbook.getActiveWorksheet() // workbook is input argument of main @@ -1341,10 +1452,13 @@ class ExcelAppender extends AbstractAppender implements Appender { * appender.clearInstance() * appender = ExcelAppender.getInstance(null) // throws a ScriptError * ``` + * @remarks 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). + * */ public static clearInstance(): void { if (ExcelAppender._instance) { - ExcelAppender._instance.clearLastLogEvent(); + ExcelAppender._instance.clearLastLogEvent() } ExcelAppender._instance = null // Clear the singleton instance } @@ -1361,7 +1475,7 @@ class ExcelAppender extends AbstractAppender implements Appender { const EVENT_COLORS = Object.entries(this._eventFonts).map( ([key, value]) => `${LOG_EVENT[Number(key)]}="${value}"` - ).join(","); + ).join(",") const output = `${super.toString()} ${NAME}: {msgCellRng(address)="${this._msgCellRngAddress}", ` + `eventfonts={${EVENT_COLORS}}}` return output @@ -1370,8 +1484,8 @@ class ExcelAppender extends AbstractAppender implements Appender { /** * 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. - * @param event a value from enum LOG_EVENT. - * @throws ScriptError in case event is not a valid LOG_EVENT enum value. + * @param event a value from enum `LOG_EVENT`. + * @throws ScriptError in case event is not a valid `LOG_EVENT` enum value. * @override */ protected sendEvent(event: LogEvent, context?: string): void { @@ -1395,7 +1509,7 @@ class ExcelAppender extends AbstractAppender implements Appender { const PREFIX = context ? `[${context}]: ` : `[${ExcelAppender.name}]: ` // If the instance is not defined, throw an error if (!ExcelAppender._instance) { - const MSG = `${PREFIX}A singleton instance can't be undefined or null. Please invoke getInstance first`; + const MSG = `${PREFIX}A singleton instance can't be undefined or null. Please invoke getInstance first` throw new ScriptError(MSG) } } @@ -1406,9 +1520,9 @@ class ExcelAppender extends AbstractAppender implements Appender { * @param color - The color string to validate. * @param name - The name of the event type (e.g., "error", "warning", etc.). * @param context - (Optional) Additional context for error messages. - * @throws ScriptError if the color is not a valid 6-digit hexadecimal color. - * @remarks The color must be in 'RRGGBB' or '#RRGGBB' format. - * If the color is not valid, it throws a ScriptError with a message indicating the issue. + * @throws ScriptError if the color is not a valid `6`-digit hexadecimal color. + * @remarks The color must be in `RRGGBB` or `#RRGGBB` format. + * If the color is not valid, it throws a `ScriptError` with a message indicating the issue. */ private static validateFont(color: string, name: string, context?: string): void { const PREFIX = context ? `[${context}]: ` : `[${ExcelAppender.name}.assertColor]: ` @@ -1430,7 +1544,7 @@ class ExcelAppender extends AbstractAppender implements Appender { if (missingColor.length > 0) { throw new ScriptError( `[ExcelAppender]: LOG_EVENT enum is not fully mapped in DEFAULT_EVENT_FONTS. Missing: color=${missingColor.map(ev => LOG_EVENT[ev]).join(", ")}` - ); + ) } } @@ -1452,65 +1566,62 @@ class ExcelAppender extends AbstractAppender implements Appender { // #region LoggerImpl /** * Singleton class that manages application logging through appenders. - * Supports the following log events: ERROR, WARN, INFO, TRACE (LOG_EVENT enum). - * Supports the level of information (verbose) to show via Logger.LEVEL: OFF, ERROR, WARN, INFO, TRACE. - * If the level of information (LEVEL) is OFF, no log events will be sent to the appenders. - * Supports the action to take in case of ERROR, WARN log events: the script can - * continue ('Logger.ACTION.CONTINUE'), or abort ('Logger.ACTION.EXIT'). Such actions only take effect - * if the LEVEL is not Logger.LEVEL.OFF. + * Supports the following log events: `ERROR`, `WARN`, `INFO`, `TRACE` (`LOG_EVENT` enum). + * Supports the level of information (verbose) to show via `Logger.LEVEL`: `OFF`, `ERROR`, `WARN`, `INFO`, `TRACE`. + * If the level of information (`LEVEL`) is `OFF`, no log events will be sent to the appenders. + * Supports the action to take in case of `ERROR`, `WARN` log events: the script can + * continue (`Logger.ACTION.CONTINUE`), or abort (`Logger.ACTION.EXIT`). Such actions only take effect + * if the `LEVEL` is not `Logger.LEVEL.OFF`. * Allows defining appenders, controlling the channels the events are sent to. - * Collects error/warning sent by the appenders via getMessages(). + * Collects error/warning sent by the appenders via `getCriticalEvents()`. * * Usage: - * - Initialize with Logger.getInstance(level, action) - * - Add one or more appenders (e.g. ConsoleAppender, ExcelAppender) - * - Use Logger.error(), warn(), info(), or trace() to log - * + * - Initialize with `Logger.getInstance(level, action)`. + * - Add one or more appenders (e.g. `ConsoleAppender`, `ExcelAppender`) + * - Use `logger.error()`, `logger.warn()`, `logger.info()`, or `logger.trace()` to log. + * * Features: - * - If no appender is added, ConsoleAppender is used by default - * - Logs are routed through all registered appenders - * - Collects a summary of error/warning messages and counts - * If no appender is defined when a log event occurs, LoggerImpl will automatically create and add a ConsoleAppender. + * - If no appender is added, `ConsoleAppender` is used by default. + * - Logs are routed through all registered appenders. + * - Collects a summary of error/warning messages and counts. + * If no appender is defined when a log event occurs, `LoggerImpl` will automatically create and add a `ConsoleAppender`. * This ensures that log messages are not silently dropped. - * You may replace or remove this appender at any time using setAppenders() or removeAppender(). + * You may replace or remove this appender at any time using `setAppenders()` or `removeAppender()`. * @example + * ```ts * // Minimal logger usage; ConsoleAppender is auto-added if none specified - * LoggerImpl.getInstance().info("This message will appear in the console by default."); + * LoggerImpl.getInstance().info("This message will appear in the console by default. + * ``` + * @see {@link Logger} for the interface definition. + * @see {@link Appender} for the interface definition of the appenders + * @see {@link ConsoleAppender} for the implementation details of the console appender. + * @see {@link LogEvent} for the structure of log events. + * @override */ class LoggerImpl implements Logger { + // Constants - public static ACTION = Object.freeze({ + /** Static constant (enum pattern) for log event types. */ + public static readonly ACTION = Object.freeze({ CONTINUE: 0, // In case of error/warning log events, the script continues EXIT: 1, // In case of error/warning log event, throws a ScriptError error } as const) - /* 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 */ + /** 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 */ public static readonly LEVEL = Object.freeze(Object.assign({ OFF: 0 }, LOG_EVENT)) - // Equivalent labels from LEVEL - private static readonly LEVEL_LABELS = Object.entries(LoggerImpl.LEVEL).reduce((acc, [key, value]) => { - acc[value] = key - return acc - }, {} as Record) - - // Equivalent labels from ACTION - private static readonly ACTION_LABELS = Object.entries(LoggerImpl.ACTION).reduce((acc, [key, value]) => { - acc[value] = key; - return acc; - }, {} as Record) - // Attributes - private static _instance: LoggerImpl | null = null; // Instance of the singleton pattern + private static _instance: LoggerImpl | null = null // Instance of the singleton pattern private static readonly DEFAULT_LEVEL = LoggerImpl.LEVEL.WARN private static readonly DEFAULT_ACTION = LoggerImpl.ACTION.EXIT private readonly _level: typeof LoggerImpl.LEVEL[keyof typeof LoggerImpl.LEVEL] = LoggerImpl.DEFAULT_LEVEL private readonly _action: typeof LoggerImpl.ACTION[keyof typeof LoggerImpl.ACTION] = LoggerImpl.DEFAULT_ACTION - private _criticalEvents: LogEvent[] = []; // Collects all ERROR and WARN events only - private _errCnt = 0; // Counts the number of error events found - private _warnCnt = 0; // Counts the number of warning events found - private _appenders: Appender[] = []; // List of appenders + private _criticalEvents: LogEvent[] = [] // Collects all ERROR and WARN events only + private _errCnt = 0 // Counts the number of error events found + private _warnCnt = 0 // Counts the number of warning events found + private _appenders: Appender[] = [] // List of appenders // Private constructor to prevent user instantiation private constructor( @@ -1523,11 +1634,10 @@ class LoggerImpl implements Logger { // Getters /** - * @returns An array with error and warning event messages only. + * @returns An array with error and warning event messages only sent to the appenders. * @throws ScriptError If the singleton was not instantiated. * @override */ - public getCriticalEvents(): LogEvent[] { LoggerImpl.validateInstance("LoggerImpl.getCriticalEvents") return this._criticalEvents @@ -1565,8 +1675,8 @@ class LoggerImpl implements Logger { /** * 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. + * it includes all previous levels. For example: `Logger.WARN` includes warnings and errors since + * `Logger.ERROR` is lower. * @returns The current log level. * @throws ScriptError If the singleton was not instantiated. * @override @@ -1591,12 +1701,11 @@ class LoggerImpl implements Logger { * Sets the array of appenders with the input argument appenders. * @param appenders Array with all appenders to set. * @throws ScriptError If the singleton was not instantiated, - * if appenders is null or undefined, or contains - * null or undefined entries, + * 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 addAppender. + * by appender class. See JSDoc from {@link LoggerImpl.addAppender} for more details. * @override - * @see addAppender */ public setAppenders(appenders: Appender[]) { const CONTEXT = `${LoggerImpl.name}.setAppenders` @@ -1609,11 +1718,11 @@ class LoggerImpl implements Logger { * Adds an appender to the list of appenders. * @param appender The appender to add. * @throws ScriptError If the singleton was not instantiated, - * if the input argument is null or undefined, + * 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. + * All appenders must be from a different implementation of the `Appender` class. * @override - * @see setAppenders + * @see {@link LoggerImpl.setAppenders} */ public addAppender(appender: Appender): void { LoggerImpl.validateInstance("LoggerImpl.addAppender") // Validate the instance @@ -1629,32 +1738,33 @@ class LoggerImpl implements Logger { /** * 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' + * If the `Logger` is created during this call, the provided `level` and `action` * parameters initialize the log level and error-handling behavior. * @remarks Subsequent calls ignore these parameters and return the existing instance. - * @param level Initial log level (default: Logger.LEVEL.WARN). Controls verbosity. + * @param level The verbosity level (default: `Logger.LEVEL.WARN`). Controls verbosity. * Sends events to the appenders up to the defined level of verbosity. * The level of verbosity is incremental, except for value - * Logger.LEVEL.OFF, which suppresses all messages sent to the appenders. - * For example: Logger.LEVEL.INFO allows sending errors, warnings, and information events, + * `Logger.LEVEL.OFF`, which suppresses all messages sent to the appenders. + * For example: `Logger.LEVEL.INFO` allows sending errors, warnings, and information events, * but excludes trace events. - * @param action Action on error/warning (default: Logger.ACTION.EXIT). + * @param action The action on error/warning (default: `Logger.ACTION.EXIT`). * Determines if the script should continue or abort. - * If the value is Logger.ACTION.EXIT, throws a ScriptError exception, - * i.e. aborts the Script. If the action is Logger.ACTION.CONTINUE, the - * script continues. + * If the value is `Logger.ACTION.EXIT`, throws a `ScriptError` exception, + * i.e. aborts the Script. If the action is `Logger.ACTION.CONTINUE`, the + * script continues. It only takes effect if the level is not `Logger.LEVEL.OFF`. * @returns The singleton Logger instance. - * @throws ScriptError If the level input value was not defined in Logger.LEVEL. + * @throws ScriptError If the level input value was not defined in `Logger.LEVEL` or it doesn't + * match the `LOG_EVENT` enum values in the specified order. + * If the action input value was not defined in `Logger.ACTION`. * @example * ```ts * // Initialize logger at INFO level, continue on errors/warnings - * const logger = Logger.getInstance(Logger.LEVEL.INFO, Logger.ACTION.CONTINUE); + * 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 + * 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 * ``` - * @see AbstractAppender.constructor for more information on how to use the logEventFactory. */ public static getInstance( level: typeof LoggerImpl.LEVEL[keyof typeof LoggerImpl.LEVEL] = LoggerImpl.DEFAULT_LEVEL, @@ -1665,7 +1775,7 @@ class LoggerImpl implements Logger { LoggerImpl.assertValidLevel(level, CONTEXT) // Validate the level this._instance = new LoggerImpl(level, action) } - return this._instance; + return this._instance } /** @@ -1687,14 +1797,15 @@ class LoggerImpl implements Logger { /** * 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. + * 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. * @param msg - The error message to log. * @param extraFields - Optional structured data to attach to the log event (e.g., context info, tags). * @remarks * If no singleton was defined, it does lazy initialization with default configuration. - * If no appender was defined, it does lazy initialization to ConsoleAppender. - * @throws ScriptError Only if level is greater than Logger.LEVEL.OFF and the action is Logger.ACTION.EXIT. + * If no appender was defined, it does lazy initialization to `ConsoleAppender`. + * @throws 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. */ public error(msg: string, extraFields?: LogEventExtraFields): void { this.log(msg, LOG_EVENT.ERROR, extraFields) @@ -1702,14 +1813,16 @@ class LoggerImpl implements Logger { /** * 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. + * 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. * @param msg - The warning message to log. * @param extraFields - Optional structured data to attach to the log event (e.g., context info, tags). + * @throws ScriptError If level is greater than `Logger.LEVEL.ERROR` and the action is `Logger.ACTION.EXIT`. + * If any internal error occurs while sending the event to the appenders. * @remarks * If no singleton was defined, it does lazy initialization with default configuration. - * If no appender was defined, it does lazy initialization to ConsoleAppender. - * @throws ScriptError Only if level is greater than Logger.LEVEL.ERROR and the action is Logger.ACTION.EXIT. + * If no appender was defined, it does lazy initialization to `ConsoleAppender`. + */ public warn(msg: string, extraFields?: LogEventExtraFields): void { this.log(msg, LOG_EVENT.WARN, extraFields) @@ -1717,12 +1830,13 @@ class LoggerImpl implements Logger { /** * 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. + * The level has to be greater than or equal to `Logger.LEVEL.INFO` to send this event to the appenders. * @param msg - The informational message to log. * @param extraFields - Optional structured data to attach to the log event (e.g., context info, tags). + * @throws ScriptError If any internal error occurs while sending the event to the appenders. * @remarks * If no singleton was defined, it does lazy initialization with default configuration. - * If no appender was defined, it does lazy initialization to ConsoleAppender. + * If no appender was defined, it does lazy initialization to `ConsoleAppender`. */ public info(msg: string, extraFields?: LogEventExtraFields): void { this.log(msg, LOG_EVENT.INFO, extraFields) @@ -1730,12 +1844,13 @@ class LoggerImpl implements Logger { /** * 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. + * The level has to be greater than or equal to `Logger.LEVEL.TRACE` to send this event to the appenders. * @param msg - The trace message to log. * @param extraFields - Optional structured data to attach to the log event (e.g., context info, tags). + * @throws ScriptError If any internal error occurs while sending the event to the appenders. * @remarks * If no singleton was defined, it does lazy initialization with default configuration. - * If no appender was defined, it does lazy initialization to ConsoleAppender. + * If no appender was defined, it does lazy initialization to `ConsoleAppender`. */ public trace(msg: string, extraFields?: LogEventExtraFields): void { this.log(msg, LOG_EVENT.TRACE, extraFields) @@ -1765,14 +1880,14 @@ class LoggerImpl implements Logger { * @returns true if some error or warning event has been sent by the appenders, otherwise false. * @throws ScriptError If the singleton was not instantiated. */ - public hasMessages(): boolean { + public hasCriticalEvents(): boolean { const CONTEXT = `${LoggerImpl.name}.hasMessages` LoggerImpl.validateInstance(CONTEXT) return this._criticalEvents.length > 0 } /** - * Resets the Logger history, i.e., state (errors, warnings, message summary). 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. * @throws ScriptError If the singleton was not instantiated. */ public reset(): void { @@ -1790,7 +1905,7 @@ class LoggerImpl implements Logger { * For persisting logs into Excel, JSON, or another external system. * @throws ScriptError If the singleton was not instantiated. * @returns A structure with key information about the logger, such as: - * level, action, errorCount, warningCount, criticalEvents. + * `level`, `action`, `errorCount`, `warningCount`, and `criticalEvents`. */ public exportState(): { level: string, @@ -1800,9 +1915,9 @@ class LoggerImpl implements Logger { criticalEvents: LogEvent[] } { const CONTEXT = `${LoggerImpl.name}.exportState` - LoggerImpl.validateInstance(CONTEXT); // Validate the instance - const levelKey = Object.keys(LoggerImpl.LEVEL).find(k => LoggerImpl.LEVEL[k as keyof typeof LoggerImpl.LEVEL] === this._level); - const actionKey = Object.keys(LoggerImpl.ACTION).find(k => LoggerImpl.ACTION[k as keyof typeof LoggerImpl.ACTION] === this._action); + LoggerImpl.validateInstance(CONTEXT) // Validate the instance + const levelKey = Object.keys(LoggerImpl.LEVEL).find(k => LoggerImpl.LEVEL[k as keyof typeof LoggerImpl.LEVEL] === this._level) + const actionKey = Object.keys(LoggerImpl.ACTION).find(k => LoggerImpl.ACTION[k as keyof typeof LoggerImpl.ACTION] === this._action) return { level: levelKey ?? "UNKNOWN", @@ -1815,8 +1930,15 @@ class LoggerImpl implements Logger { /** * Returns the label for a log action value. - * If no parameter is provided, uses the current logger instance's action. - * Returns "UNKNOWN" if the value is not found or logger is not initialized. + * @param action - The log action to get the label for. + * @returns The label for the action. + * If `action` is `undefined`, returns the label for the current logger instance's action. + * If neither is set, returns `UNKNOWN`. + * @example + * ```ts + * LoggerImpl.getActionLabel(LoggerImpl.ACTION.CONTINUE) // Returns "CONTINUE" + * LoggerImpl.getActionLabel() // Returns the current logger instance's action label + * ``` */ public static getActionLabel(action?: typeof LoggerImpl.ACTION[keyof typeof LoggerImpl.ACTION]): string { const val = action !== undefined ? action : LoggerImpl._instance?._action @@ -1824,15 +1946,20 @@ class LoggerImpl implements Logger { if (val === undefined) return UNKNOWN const label = Object.keys(LoggerImpl.ACTION).find( key => LoggerImpl.ACTION[key as keyof typeof LoggerImpl.ACTION] === val - ); + ) return label ?? UNKNOWN } /** * Returns the label for the given log level. * @returns 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". + * If `level` is `undefined`, returns the label for the current logger instance's level. + * If neither is set, returns `UNKNOWN`. + * @example + * ```ts + * LoggerImpl.getLevelLabel(LoggerImpl.LEVEL.INFO) // Returns "INFO" + * LoggerImpl.getLevelLabel() // Returns the current logger instance's level label + * ``` */ public static getLevelLabel(level?: typeof LoggerImpl.LEVEL[keyof typeof LoggerImpl.LEVEL]): string { const val = level !== undefined ? level : LoggerImpl._instance?._level @@ -1840,12 +1967,12 @@ class LoggerImpl implements Logger { if (val === undefined) return UNKNOWN const label = Object.keys(LoggerImpl.LEVEL).find( key => LoggerImpl.LEVEL[key as keyof typeof LoggerImpl.LEVEL] === val - ); + ) return label ?? UNKNOWN } /** - * Override toString method. + * @returns A string representation of the logger instance. * @throws ScriptError If the singleton was not instantiated. * @override */ @@ -1864,12 +1991,13 @@ class LoggerImpl implements Logger { return `${NAME}: {${scalarInfo}, appenders: ${appendersString}}` } - /**Short version fo the toString() which exludes the appenders details - * @returns Similar to toString, but showing the list of appenders name only. + /**Short version fo the `toString()` which exludes the appenders details. + * @returns Similar to `toString`, but showing the list of appenders name only. + * @throws ScriptError If the singleton was not instantiated. */ public toShortString(): string { const CONTEXT = `${LoggerImpl.name}.toString` - LoggerImpl.validateInstance(CONTEXT); // Validate the instance + LoggerImpl.validateInstance(CONTEXT) // Validate the instance const NAME = this.constructor.name const levelTk = Object.keys(LoggerImpl.LEVEL).find(key => LoggerImpl.LEVEL[key as keyof typeof LoggerImpl.LEVEL] === this._level) @@ -1884,10 +2012,10 @@ class LoggerImpl implements Logger { // #TEST-ONLY-START /** - * Sets the singleton instance to null, useful for running different scenarios. + * Sets the singleton instance to `null`, useful for running different scenarios. * @remarks 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). - * It doesn't set the appenders to null, so the appenders are not cleared. + * 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. * @throws ScriptError If the singleton was not instantiated. * @example * ```ts @@ -1895,12 +2023,12 @@ class LoggerImpl implements Logger { * // 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 - * Logger.getInstance(); // LEVEL: WARN, ACTION: EXIT - * logger.error("error event"); // Output: "error event" and ScriptError + * 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.getInstance(LEVEL.WARN, ACTION.CONTINUE); - * Logger.error("error event"); // Output: "error event" (no ScriptError was thrown) + * Logger.clearInstance() // Clear the singleton + * logger = Logger.getInstance(LEVEL.WARN, ACTION.CONTINUE) + * logger.error("error event") // Output: "error event" (no ScriptError was thrown) * ``` */ public static clearInstance(): void { @@ -1917,20 +2045,20 @@ class LoggerImpl implements Logger { * This ensures all logs are delivered to at least one output channel. * - The message and extraFields are forwarded to all appenders, which may handle or display them differently (e.g., console, Excel, etc.). * - The message is only dispatched if the current log level allows it. - * - If the event is of type 'ERROR' or 'WARN', it is recorded internally and counted. - * - If the configured action is 'Logger.ACTION.EXIT', a 'ScriptError' is thrown for errors and warnings. - * + * - If the event is of type `ERROR` or `WARN`, it is recorded internally and counted. + * - If the configured action is `Logger.ACTION.EXIT`, a `ScriptError` is thrown for errors and warnings. + * * @param msg - The log message to send. * @param type - The log event type (LOG_EVENT). * @param extraFields - Optional structured data to attach to the log event (e.g., context info, tags). * * @remarks - * If no appenders are defined, a ConsoleAppender will be created and added automatically. - * This guarantees that log messages are always delivered to at least one output channel. - * Extra fields are forwarded to the log event factory and may be included in custom layouts, exports, or external integrations. - * - * @throws ScriptError In case the action defined for the logger is Logger.ACTION.EXIT and the event type - * is LOG_EVENT.ERROR or LOG_EVENT.WARN. + * - If no appenders are defined, a `ConsoleAppender` will be created and added automatically. + * - This guarantees that log messages are always delivered to at least one output channel. + * - Extra fields are forwarded to the `log` method of the appenders and may be included in custom layouts, exports, or external integrations. + * + * @throws ScriptError In case the action defined for the logger is `Logger.ACTION.EXIT` and the event type + * is `LOG_EVENT.ERROR` or `LOG_EVENT.WARN`. Any other internal error will throw a `ScriptError` as well. */ private log(msg: string, type: LOG_EVENT, extraFields?: LogEventExtraFields): void { LoggerImpl.initIfNeeded("LoggerImpl.log") // lazy initialization of the singleton with default parameters @@ -1951,7 +2079,8 @@ class LoggerImpl implements Logger { const appender = this._appenders[0] const lastEvent = appender.getLastLogEvent() if (!lastEvent) {// internal error - throw new Error("[LoggerImpl.log] Appender did not return a LogEvent for getLastLogEvent()") + const PREFIX = `[${this.constructor.name}.log]: ` + throw new ScriptError(`${PREFIX}Appender did not return a LogEvent for getLastLogEvent()`) } this._criticalEvents.push(lastEvent) if (this._action === LoggerImpl.ACTION.EXIT) { @@ -1985,8 +2114,8 @@ class LoggerImpl implements Logger { } /* Checks level has one of the valid values. It is required, because the way Logger.LEVEL was built, - i.e. based on LOG_EVENT, so it doesn't check for non-valid values during compilation. That is not the - case for Logger.ACTION. */ + i.e. based on `LOG_EVENT`, so it doesn't check for non-valid values during compilation. That is not the + case for `Logger.ACTION`. */ private static assertValidLevel(level: typeof LoggerImpl.LEVEL[keyof typeof LoggerImpl.LEVEL], context?: string): void { if (!Object.values(LoggerImpl.LEVEL).includes(level)) { // level not part of Logger.LEVEL const PREFIX = context ? `[${context}]: ` : `[${LoggerImpl.name}.assertValidLevel]: ` @@ -1995,7 +2124,7 @@ class LoggerImpl implements Logger { } } - /** Validates that all appenders are of unique class types, with no null or undefined entries. + /** Validates that all appenders are of unique class types, with no `null` or `undefined` entries. * The uniqueness is based on the constructor of the appender, .i.e. that two different * instances of the same appender class are not allowed */ @@ -2005,7 +2134,7 @@ class LoggerImpl implements Logger { throw new ScriptError(`${PREFIX}Invalid input: the input argument 'appenders' must be a non-null array.`) } - const seen = new Set(); // ensure unique elements only + const seen = new Set() // ensure unique elements only for (const appender of appenders) { if (!appender) { throw new ScriptError(`${PREFIX}Input argument appenders array contains null or undefined entry.`) @@ -2022,7 +2151,7 @@ class LoggerImpl implements Logger { /** * Validates that the LEVEL enum values are strictly increasing. * This ensures that the log levels are ordered correctly: - * OFF < ERROR < WARN < INFO < TRACE. + * `OFF` < `ERROR` < `WARN` < `INFO` < `TRACE`. * @throws ScriptError if the enum values are not strictly increasing. * @remarks This is a safeguard to ensure the integrity of the LEVEL enum. */ @@ -2066,41 +2195,41 @@ class LoggerImpl implements Logger { if (typeof globalThis !== "undefined") { if (typeof LOG_EVENT !== "undefined") { // @ts-ignore - globalThis.LOG_EVENT = LOG_EVENT; + globalThis.LOG_EVENT = LOG_EVENT } if (typeof LogEventImpl !== "undefined") { // @ts-ignore - globalThis.LogEventImpl = LogEventImpl; + globalThis.LogEventImpl = LogEventImpl } if (typeof LayoutImpl !== "undefined") { // @ts-ignore - globalThis.LayoutImpl = LayoutImpl; + globalThis.LayoutImpl = LayoutImpl } if (typeof AbstractAppender !== "undefined") { // @ts-ignore - globalThis.AbstractAppender = AbstractAppender; + globalThis.AbstractAppender = AbstractAppender } if (typeof ConsoleAppender !== "undefined") { // @ts-ignore - globalThis.ConsoleAppender = ConsoleAppender; + globalThis.ConsoleAppender = ConsoleAppender } if (typeof ExcelAppender !== "undefined") { // @ts-ignore - globalThis.ExcelAppender = ExcelAppender; + globalThis.ExcelAppender = ExcelAppender } if (typeof ScriptError !== "undefined") { // @ts-ignore - globalThis.ScriptError = ScriptError; + globalThis.ScriptError = ScriptError } if (typeof LoggerImpl !== "undefined") { // @ts-ignore - globalThis.LoggerImpl = LoggerImpl; + globalThis.LoggerImpl = LoggerImpl } if (typeof Utility !== "undefined") { // @ts-ignore - globalThis.Utility = Utility; + globalThis.Utility = Utility } } diff --git a/test/main.ts b/test/main.ts index 78019fe..92dec07 100644 --- a/test/main.ts +++ b/test/main.ts @@ -305,6 +305,7 @@ class TestCase { Assert.equals(actualNum, expectedNum, `getCriticalEvents())--no log events sent${SUFFIX}`) Assert.equals(logger.hasErrors(), false, `hasErrors()--no errors logged${SUFFIX}`) Assert.equals(logger.hasWarnings(), false, `hasWarnings()--no warnings logged${SUFFIX}`) + Assert.isFalse(logger.hasCriticalEvents(), `hasMessages()--no messages logged${SUFFIX}`) // Checking the last log event sent via AbstractAppender Assert.isNull(appender.getLastLogEvent(), `getLastLogEvent()-is null${SUFFIX}`) return // No need to continue, since no log events will be sent @@ -1864,7 +1865,7 @@ class TestCase { new LogEventImpl(warnMsg, LOG_EVENT.WARN)]) let actualArr = TestCase.simplifyLogEvents(logger.getCriticalEvents()) Assert.equals(actualArr, expectedArr, "loggerImplCounters(getMessages)") - Assert.equals(logger.hasMessages(), true, "loggerImplCounters(hasMessages)") + Assert.equals(logger.hasCriticalEvents(), true, "loggerImplCounters(hasMessages)") // Testing other events, don't affect the counters let msg = "Info event doesn't count testing counters for LoggerImpl" logger.info(msg) From ac97c1eac9cfc8fd10928ae8a1da5fe4f8186c38 Mon Sep 17 00:00:00 2001 From: David Leal Date: Sat, 12 Jul 2025 19:09:23 -0400 Subject: [PATCH 2/2] Updated package.json version --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 0961d45..6fe6b59 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "officescripts-logging-framework", - "version": "2.1.1", + "version": "2.1.2", "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": {