Package org.apache.sis.util.logging

## Class MonolineFormatter

- Object
- - Formatter
  - - MonolineFormatter

-     public class MonolineFormatter
      extends Formatter

  A formatter writing log messages on a single line. Compared to the JDK `SimpleFormatter`, this formatter uses only one line per message instead of two. For example messages formatted by `MonolineFormatter` may look like:

  > Logging example
  > `00:01` | `CONFIG` | `[MyApplication] Read configuration from “my-application/setup.xml”.`
  > `00:03` | `INFO` | `[EPSGFactory] Connected to the EPSG database version 9.1 on Derby 10.14.`
  > `00:12` | `WARNING` | `[DefaultTemporalExtent] This operation requires the “sis-temporal” module.`

  By default, `MonolineFormatter` shows only the level and the message. One or two additional fields can be inserted between the level and the message if the `setTimeFormat(String)` or `setSourceFormat(String)` methods are invoked with o non-null argument. Examples:
  - `setTimeFormat("HH:mm:ss")` for formatting the time like `00:00:04"`, as time elapsed since the `MonolineFormatter` creation time.
  - `setSourceFormat("logger:long")` for formatting the full logger name (e.g. `"org​.apache​.sis​.storage​.netcdf"`).
  - `setSourceFormat("class:short")` for formatting the short class name, without package (e.g. `"NetcdfStore"`).
  Configuration from `logging​.properties`
  The format can also be set from the `jre/lib/logging​.properties` file. For example, user can cut and paste the following properties into `logging​.properties`:

  >     ###########################################################################
  >     # Properties for the apache.sis.org's MonolineFormatter.
  >     # By default, the monoline formatter display only the level
  >     # and the message. Additional fields can be specified here:
  >     #
  >     #  time:   If set, writes the time elapsed since the initialization.
  >     #          The argument specifies the output pattern. For example, the
  >     #          pattern "HH:mm:ss.SSSS" displays the hours, minutes, seconds
  >     #          and milliseconds.
  >     #
  >     #  source: If set, writes the source logger name or the source class name.
  >     #          Valid argument values are "none", "logger:short", "logger:long",
  >     #          "class:short", "class:long" and "class.method".
  >     ###########################################################################
  >     org.apache.sis.util.logging.MonolineFormatter.time = HH:mm:ss.SSS
  >     org.apache.sis.util.logging.MonolineFormatter.source = class:short

  See `setTimeFormat(String)` and `setSourceFormat(String)` for more information about the above `time` and `source` properties. Encoding and logging level are configured separately, typically on the JDK `ConsoleHandler` like below:

  >     java.util.logging.ConsoleHandler.encoding = UTF-8
  >     java.util.logging.ConsoleHandler.level = FINE

  Thread safety
  The same `MonolineFormatter` instance can be safely used by many threads without synchronization on the part of the caller. Subclasses should make sure that any overridden methods remain safe to call from multiple threads.
  Since:
    0.3
  See Also:
    `SimpleFormatter`, `Handler​.setFormatter(Formatter)`

  Defined in the `sis-utility` module

- - ### Constructor Summary

    Constructors
    Constructor | Description
    --- | ---
    `MonolineFormatter()` | Constructs a default `MonolineFormatter`.
    `MonolineFormatter​(Handler handler)` | Constructs a `MonolineFormatter` configured for the given handler.

  - ### Method Summary

    All Methods Static Methods Instance Methods Concrete Methods
    Modifier and Type | Method | Description
    --- | --- | ---
    `String` | `format​(LogRecord record)` | Formats the given log record and returns the formatted string.
    `String` | `formatMessage​(LogRecord record)` | Returns the localized message from the given log record.
    `String` | `getHeader()` | Returns the string to write on the left side of the first line of every log records, or `null` if none.
    `String` | `getLevelColor​(Level level)` | Returns the color used for the given level, or `null` if none.
    `String` | `getSourceFormat()` | Returns the format for the source, or `null` is the source is not shown.
    `String` | `getTimeFormat()` | Returns the format for elapsed time, or `null` if the time is not shown.
    `static MonolineFormatter` | `install()` | Installs a `MonolineFormatter` for the root logger, or returns the existing instance if any.
    `static MonolineFormatter` | `install​(Logger logger, Level level)` | Installs a `MonolineFormatter` for the specified logger, or returns the existing instance if any.
    `void` | `resetLevelColors​(boolean enabled)` | Resets the colors setting to its default value.
    `void` | `setHeader​(String header)` | Sets the string to write on the left side of the first line of every log records.
    `void` | `setLevelColor​(Level level, String color)` | Sets the color to use for the given level, or `null` for removing colorization.
    `void` | `setSourceFormat​(String format)` | Sets the format for displaying the source, or hides the source field.
    `void` | `setTimeFormat​(String pattern)` | Sets the format for elapsed time, or hides the time field.

    - ### Methods inherited from class Formatter

      `getHead, getTail`

    - ### Methods inherited from class Object

      `clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait`

- - ### Constructor Detail

    - #### MonolineFormatter

          public MonolineFormatter()

      Constructs a default `MonolineFormatter`. This no-argument constructor is invoked by the logging system if the `logging​.properties` file contains the following line:

      >     java.util.logging.ConsoleHandler.formatter = org.apache.sis.util.logging.MonolineFormatter

      Since:
        1.0

    - #### MonolineFormatter

          public MonolineFormatter​(Handler handler)

      Constructs a `MonolineFormatter` configured for the given handler.
      Auto-configuration from the handler
      Formatters are often associated to a particular handler. If this handler is known, giving it at construction time can help this formatter to configure itself. This handler is only a hint - it will not be modified, and no reference to that handler will be kept by this constructor.
      Parameters:
        `handler` - The handler to be used with this formatter, or `null` if unknown.
      See Also:
        `Handler​.setFormatter(Formatter)`

  - ### Method Detail

    - #### getHeader

          public String getHeader()

      Returns the string to write on the left side of the first line of every log records, or `null` if none. This is a string to be shown just before the level.
      Returns:
        the string to write on the left side of the first line of every log records, or `null` if none.

    - #### setHeader

          public void setHeader​(String header)

      Sets the string to write on the left side of the first line of every log records.
      Parameters:
        `header` - The string to write on the left side of the first line of every log records, or `null` if none.

    - #### getTimeFormat

          public String getTimeFormat()

      Returns the format for elapsed time, or `null` if the time is not shown. This method returns the pattern specified by the last call to the `setTimeFormat(String)` method, or the patten specified by the `org​.apache​.sis​.util​.logging​.MonolineFormatter​.time` property in the `jre/lib/logging​.properties` file.
      Returns:
        the time pattern, or `null` if elapsed time is not formatted.

    - #### setTimeFormat

          public void setTimeFormat​(String pattern)
                             throws IllegalArgumentException

      Sets the format for elapsed time, or hides the time field. The pattern must matches the format specified in `SimpleDateFormat`, but for the time part only (no date).
      Example: The `"HH:mm:ss​.SSS"` pattern will display the elapsed time in hours, minutes, seconds and milliseconds.
      Parameters:
        `pattern` - the time pattern, or `null` to disable time formatting.
      Throws:
        `IllegalArgumentException` - if the given pattern is invalid.

    - #### getSourceFormat

          public String getSourceFormat()

      Returns the format for the source, or `null` is the source is not shown. This method returns the source format specified by the last call to the `setSourceFormat(String)` method, or the format specified by the `org​.apache​.sis​.util​.logging​.MonolineFormatter​.source` property in the `jre/lib/logging​.properties` file.
      Returns:
        the source format, or `null` if source is not formatted.

    - #### setSourceFormat

          public void setSourceFormat​(String format)
                               throws IllegalArgumentException

      Sets the format for displaying the source, or hides the source field. The given format can be any of the following values, from more verbose to less verbose:
      - `null` for hiding the source field.
      - `"class:long"` for the source class name
      - `"logger:long"` for the logger name
      - `"class:short"` for the source class name without the package part.
      - `"logger:short"` for the logger name without the package part.
      - `"class​.method"` for the short class name followed by the source method name
      The source class name usually contains the logger name since (by convention) logger names are package names, but this is not mandatory neither enforced.
      Parameters:
        `format` - the format for displaying the source, or `null` if the source shall not be formatted.
      Throws:
        `IllegalArgumentException` - if the given argument is not one of the recognized format names.

    - #### getLevelColor

          public String getLevelColor​(Level level)

      Returns the color used for the given level, or `null` if none. The current set of supported colors are `"red"`, `"green"`, `"yellow"`, `"blue"`, `"magenta"`, `"cyan"` and `"gray"`. This set may be extended in any future SIS version.
      Parameters:
        `level` - the level for which to get the color.
      Returns:
        the color for the given level, or `null` if none.

    - #### setLevelColor

          public void setLevelColor​(Level level,
                                    String color)
                             throws IllegalArgumentException

      Sets the color to use for the given level, or `null` for removing colorization. This method should be invoked only if this formatter is associated to a `Handler` writing to a terminal supporting ANSI escape codes (a.k.a. ECMA-48, ISO/IEC 6429 and X3.64 standards).

      The given `color` argument shall be one of the values documented in the `getLevelColor(Level)` method.

      Parameters:
        `level` - the level for which to set a new color.
        `color` - the case-insensitive new color, or `null` if none.
      Throws:
        `IllegalArgumentException` - if the given color is not one of the recognized values.

    - #### resetLevelColors

          public void resetLevelColors​(boolean enabled)

      Resets the colors setting to its default value.
      - If `enabled` is `true`, then this method defines a default set of colors.
      - If `enabled` is `false`, then this method resets the formatting to plain text.
      This method does not check if ANSI escape codes are supported or not. This check must be done by the caller.
      Parameters:
        `enabled` - `true` for defining a default set of colors, or `false` for removing all colors.

    - #### format

          public String format​(LogRecord record)

      Formats the given log record and returns the formatted string. See the class javadoc for information on the log format.
      Specified by:
        `format` in class `Formatter`
      Parameters:
        `record` - the log record to be formatted.
      Returns:
        a formatted log record.

    - #### formatMessage

          public String formatMessage​(LogRecord record)

      Returns the localized message from the given log record. First this method gets the raw message from the given record. Then there is choices:
      - If the given record specifies a resource bundle, then the message is used as a key for fetching the localized resources in the given bundle.
      - If the given record specifies one or more parameters and if the message seems to use the `MessageFormat` syntax, then the message is formatted by `MessageFormat`.
      Overrides:
        `formatMessage` in class `Formatter`
      Parameters:
        `record` - The log record from which to get a localized message.
      Returns:
        the localized message.

    - #### install

          @Configuration
          public static MonolineFormatter install()
                                           throws SecurityException

      Installs a `MonolineFormatter` for the root logger, or returns the existing instance if any. This method performs the following choices:
      - If a `ConsoleHandler` is associated to the root logger, then:
        - If that handler already uses a `MonolineFormatter`, then the existing formatter is returned.
        - Otherwise the `ConsoleHandler` formatter is replaced by a new `MonolineFormatter` instance, and that new instance is returned. We perform this replacement in order to avoid sending twice the same records to the console.
      - Otherwise a new `ConsoleHandler` using a new `MonolineFormatter` is created and added to the root logger.
      Implementation note: The current implementation does not check for duplicated `ConsoleHandler` instances, and does not check if any child logger has a `ConsoleHandler`.
      Returns:
        the new or existing `MonolineFormatter`. The formatter output can be configured using the `setTimeFormat(String)` and `setSourceFormat(String)` methods.
      Throws:
        `SecurityException` - if this method does not have the permission to install the formatter.

    - #### install

          @Debug
          @Configuration
          public static MonolineFormatter install​(Logger logger,
                                                  Level level)
                                           throws SecurityException

      Installs a `MonolineFormatter` for the specified logger, or returns the existing instance if any. This method performs the following steps:
      - If a `ConsoleHandler` is associated to the given logger, then:
        - If that handler already uses a `MonolineFormatter`, then the existing formatter is returned.
        - Otherwise the `ConsoleHandler` formatter is replaced by a new `MonolineFormatter` instance, and that new instance is returned. We perform this replacement in order to avoid sending twice the same records to the console.
      - Otherwise:
        - The `Logger​.setUseParentHandlers(boolean)` flag is set to `false` for avoiding duplicated loggings if a `ConsoleHandler` instance exists in the parent handlers.
        - Parent handlers that are not `ConsoleHandler` instances are added to the given logger in order to preserve similar behavior as before the call to `setUseParentHandlers(false)`.
        - A new `ConsoleHandler` using a new `MonolineFormatter` is created and added to the given logger.
      Implementation note: The current implementation does not check for duplicated `ConsoleHandler` instances, and does not check if any child logger has a `ConsoleHandler`.
      Specifying a log level
      This method can opportunistically set the handler level. If the given level is non-null, then the `ConsoleHandler` using the `MonolineFormatter` will be set to that level. This is mostly a convenience for temporary increase of logging verbosity for debugging purpose. This functionality should not be used in production environment, since it overwrite user's level setting.
      Parameters:
        `logger` - the base logger to apply the change on.
        `level` - the desired level, or `null` if no level should be set.
      Returns:
        the new or existing `MonolineFormatter`. The formatter output can be configured using the `setTimeFormat(String)` and `setSourceFormat(String)` methods.
      Throws:
        `SecurityException` - if this method does not have the permission to install the formatter.