Class AbstractLogRecord

  • All Implemented Interfaces:
    java.io.Serializable
    Direct Known Subclasses:
    SimpleLogRecord

    public abstract class AbstractLogRecord
    extends java.util.logging.LogRecord
    Abstract base class for java.util.logging compatible log records produced by Flogger backends. This class behaves externally like LogRecord but supports more memory efficient message formatting via the appendFormattedMessageTo(StringBuilder) method.

    This class supports three distinct modes of operation, depending on the state of the message and/or parameters:

    Null message, null or empty parameters

    This is the initial state of the log record, and indicates that the log message has not been formatted. This is a non-visible, internal state, since any attempt to read the message string will result it it being formatted and subsequently cached.

    In this state the formatted message can still be appended to a buffer via appendFormattedMessageTo(StringBuilder) without retaining a cached string copy. If the log record is expected to be formatted only once during logging, this will save an extraneous string copy from being made, which in some systems could save a lot of allocations and memory copying.

    Non-null message, null or empty parameters

    This state is reached either when getMessage() is first called, or if an explicit non-null message is set via setMessage(String) (without setting any parameters). In this state, the message is considered to be formatted, and just returned via getMessage().

    Non-null message, non-empty parameters

    This state is only reached if a user calls both setMessage(String) and setParameters(Object[]). In this state the message is treated as is it were a brace-format log message, and no formatting is attempted. Any relationship between this value and the log message implied by the contained LogData and Metadata is lost.

    For many reasons it is never a good idea for users to modify unknown LogRecord instances, but this does happen occasionally, so this class supports that in a best effort way, but users are always recommended to copy LogRecord instances if they need to modify them.

    Corollary

    Because of the defined states above there are a few small, but necessary, changes to behaviour in this class as compared to the "vanilla" JDK LogRecord.

    • Since the "message" field being null indicates a private state, calling setMessage(null) from outside this class is equivalent to calling setMessage(""), and will not reset the instance to its initial "unformatted" state. This is within specification for LogRecord since the documentation for getMessage() says that a return value of null is equivalent to the empty string.
    • Setting the parameters to null from outside this class will reset the parameters to a static singleton empty array. From outside this class, LogRecord.getParameters() is never observed to contain null. This is also within specification for LogRecord.
    • Setting parameters from outside this class (to any value) will also result in the log message being formatted and cached (if it hadn't been set already). This is to avoid situations in which parameters are set, but the underlying message is still null.
    • ResourceBundles are not supported by AbstractLogRecord and any attempt to set them is ignored.
    See Also:
    Serialized Form
    • Constructor Summary

      Constructors 
      Modifier Constructor Description
      protected AbstractLogRecord​(com.google.common.flogger.backend.LogData data, com.google.common.flogger.backend.Metadata scope)
      Constructs a log record for normal logging without filling in format specific fields.
      protected AbstractLogRecord​(java.lang.RuntimeException error, com.google.common.flogger.backend.LogData data, com.google.common.flogger.backend.Metadata scope)
      Constructs a log record in response to an exception during a previous logging attempt.
    • Method Summary

      All Methods Instance Methods Concrete Methods 
      Modifier and Type Method Description
      java.lang.StringBuilder appendFormattedMessageTo​(java.lang.StringBuilder buffer)
      Appends the formatted log message to the given buffer.
      java.lang.String getFormattedMessage()
      Returns the formatted log message, caching the result in the common case.
      com.google.common.flogger.backend.LogData getLogData()
      Returns the LogData instance encapsulating the current fluent log statement.
      protected com.google.common.flogger.backend.LogMessageFormatter getLogMessageFormatter()
      Returns the formatter used when formatting LogData.
      java.lang.String getMessage()  
      com.google.common.flogger.backend.MetadataProcessor getMetadataProcessor()
      Returns the immutable MetadataProcessor which provides a unified view of scope and log site metadata.
      void setMessage​(java.lang.String message)  
      void setParameters​(java.lang.Object[] parameters)  
      void setResourceBundle​(java.util.ResourceBundle bundle)  
      void setResourceBundleName​(java.lang.String name)  
      java.util.logging.LogRecord toMutableLogRecord()
      Returns a snapshot of this log record, copied and flattened to a plain, mutable LogRecord instance.
      java.lang.String toString()  
      • Methods inherited from class java.util.logging.LogRecord

        getInstant, getLevel, getLoggerName, getMillis, getParameters, getResourceBundle, getResourceBundleName, getSequenceNumber, getSourceClassName, getSourceMethodName, getThreadID, getThrown, setInstant, setLevel, setLoggerName, setMillis, setSequenceNumber, setSourceClassName, setSourceMethodName, setThreadID, setThrown
      • Methods inherited from class java.lang.Object

        clone, equals, finalize, getClass, hashCode, notify, notifyAll, wait, wait, wait
    • Constructor Detail

      • AbstractLogRecord

        protected AbstractLogRecord​(com.google.common.flogger.backend.LogData data,
                                    com.google.common.flogger.backend.Metadata scope)
        Constructs a log record for normal logging without filling in format specific fields. Subclasses calling this constructor are expected to additionally call LogRecord.setThrown(java.lang.Throwable) and perhaps setMessage(java.lang.String) (depending on whether eager message caching is desired).
      • AbstractLogRecord

        protected AbstractLogRecord​(java.lang.RuntimeException error,
                                    com.google.common.flogger.backend.LogData data,
                                    com.google.common.flogger.backend.Metadata scope)
        Constructs a log record in response to an exception during a previous logging attempt. A synthetic error message is generated from the original log data and the given exception is set as the cause. The level of this record is the maximum of WARNING or the original level.
    • Method Detail

      • getLogMessageFormatter

        protected com.google.common.flogger.backend.LogMessageFormatter getLogMessageFormatter()
        Returns the formatter used when formatting LogData. This is not used if the log message was set explicitly, and can be overridden to supply a different formatter without necessarily requiring a new field in this class (to cut down on instance size).
      • setParameters

        public final void setParameters​(java.lang.Object[] parameters)
        Overrides:
        setParameters in class java.util.logging.LogRecord
      • setMessage

        public final void setMessage​(java.lang.String message)
        Overrides:
        setMessage in class java.util.logging.LogRecord
      • getMessage

        public final java.lang.String getMessage()
        Overrides:
        getMessage in class java.util.logging.LogRecord
      • appendFormattedMessageTo

        public final java.lang.StringBuilder appendFormattedMessageTo​(java.lang.StringBuilder buffer)
        Appends the formatted log message to the given buffer. In idiomatic usage, this method will avoid making a separate copy of the formatted message, and instead append directly into the given buffer. In cases where are log record is only formatted once, this can save a lot of needless string copying.

        If #getMessage() has been called on this log record before calling this method, the cached result will appended instead (though the effect will be the same).

        If this log record has had a message and parameters explicitly set, it is formatted as if by the default implementation of Formatter.formatMessage(LogRecord), and the result is not cached.

      • getFormattedMessage

        public final java.lang.String getFormattedMessage()
        Returns the formatted log message, caching the result in the common case. This method only differs from getMessage() if this log record was modified externally after creation by resetting the log message or parameters.

        Use appendFormattedMessageTo(StringBuilder) whenever a buffer is already available.

      • setResourceBundle

        public final void setResourceBundle​(java.util.ResourceBundle bundle)
        Overrides:
        setResourceBundle in class java.util.logging.LogRecord
      • setResourceBundleName

        public final void setResourceBundleName​(java.lang.String name)
        Overrides:
        setResourceBundleName in class java.util.logging.LogRecord
      • toMutableLogRecord

        public final java.util.logging.LogRecord toMutableLogRecord()
        Returns a snapshot of this log record, copied and flattened to a plain, mutable LogRecord instance. The log message of the new log record is the formatted message from this instance, so the new new log record never has any parameters.

        Since AbstractLogRecord has synthetic fields, it's not safely mutable itself. Once copied, the plain LogRecord will not benefit from some of the potential optimizations which AbstractLogRecord can be subject to.

      • getLogData

        public final com.google.common.flogger.backend.LogData getLogData()
        Returns the LogData instance encapsulating the current fluent log statement.

        The LogData instance is effectively owned by this log record but must still be considered immutable by anyone using it (as it may be processed by multiple log handlers).

      • getMetadataProcessor

        public final com.google.common.flogger.backend.MetadataProcessor getMetadataProcessor()
        Returns the immutable MetadataProcessor which provides a unified view of scope and log site metadata. This should be used in preference to Metadata available from LogData which represents only the log site.
      • toString

        public java.lang.String toString()
        Overrides:
        toString in class java.lang.Object