Class MetadataProcessor


  • public abstract class MetadataProcessor
    extends Object
    Processor combining scope and log-site metadata into a single view. This is necessary when backends wish to combine metadata without incurring the cost of building maps etc. While it is not strictly necessary to use this processor when handling metadata, it is recommended.

    The expected usage pattern for this class is that:

    1. The logger backend creates one or more stateless MetadataHandler instances as static constants. These should be immutable and thread safe since they include only code.
    2. When handling a log statement, the logger backend generates a MetadataProcessor in the logging thread for the current scope and log-site metadata.
    3. The processor can then be repeatedly used to dispatch calls to one or more of the handlers, potentially with different mutable context instances.

    By splitting the various life-cycles (handler, processor, contexts) this approach should help minimize the cost of processing metadata per log statement.

    Instances of MetadataProcessor are reusable, but not thread safe. All metadata processing must be done in the logging thread.

    See Also:
    Original Java code of Google Flogger
    • Method Detail

      • forScopeAndLogSite

        public static MetadataProcessor forScopeAndLogSite​(Metadata scopeMetadata,
                                                           Metadata logMetadata)
        Returns a new processor for the combined scope and log-site metadata. Note that this returned instance may read directly from the supplied metadata during processing, so the supplied metadata must not be modified while the processor instance is being used.
        Parameters:
        scopeMetadata - Metadata for the current scope (i.e., from ScopedLoggingContext)
        logMetadata - Metadata extracted from the current log statement (i.e., from LogData)
        Returns:
        a processor to handle a unified view of the data
      • process

        public abstract <C> void process​(MetadataHandler<C> handler,
                                         C context)
        Processes a combined view of the scope and log-site metadata in this processor by invoking the given handler for each distinct metadata key. The handler method invoked depends on whether the key is single valued or repeated.

        Rules for merging scope and log-site metadata are as follows:

        • Distinct keys are iterated in the order they were first declared, with scope keys preceding log-site keys.
        • For singleton keys, a log-site value replaces any value supplied in the scope.
        • For repeated keys, all values are collected in declaration order, with scope values preceding log-site values.

        Note that equal or identical repeated values are permitted, and no "deduplication" is performed. This is very much in contrast to the Tags mechanism, which de-duplicates mappings and reorders keys and values to generate a minimal, canonical representation.

        Furthermore, scope-supplied tags will be a single value in the scope metadata, keyed with the TAGS key.

        Parameters:
        handler - the metadata handler to be called back
        context - arbitrary context instance to be passed into each callback.
      • handle

        public abstract <C> void handle​(FloggerMetadataKey<?> key,
                                        MetadataHandler<C> handler,
                                        C context)
        Invokes the given handler for the combined scope and log-site metadata for a specified key. The handler method invoked depends on whether the key is single valued or repeated. If no metadata is present for the given key, the handler is not invoked.
      • getSingleValue

        public abstract <T> T getSingleValue​(FloggerMetadataKey<T> key)
        Returns the unique value for a single valued key, or null if not present.
        Throws:
        IllegalArgumentException - if passed a repeatable key (even if that key has one value).
      • keyCount

        public abstract int keyCount()
        Returns the number of unique keys represented by this processor. This is the same as the size of keySet(), but a separate method to avoid needing to allocate anything just to know the number of keys.
      • keySet

        public abstract Set<FloggerMetadataKey<?>> keySet()
        Returns the set of FloggerMetadataKeys known to this processor, in the order in which they will be processed. Note that this implementation is lightweight, but not necessarily performant for things like containment testing.