blob: 53512451e353160c7c1ee992621449616dad2478 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache license, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the license for the specific language governing permissions and
* limitations under the license.
*/
package org.apache.logging.log4j.core;
import java.util.List;
import org.apache.logging.log4j.core.config.Property;
import org.apache.logging.log4j.core.impl.ContextDataInjectorFactory;
import org.apache.logging.log4j.core.impl.ThreadContextDataInjector;
import org.apache.logging.log4j.util.ReadOnlyStringMap;
import org.apache.logging.log4j.util.StringMap;
/**
* Responsible for initializing the context data of LogEvents. Context data is data that is set by the application to be
* included in all subsequent log events.
* <p>
* The source of the context data is implementation-specific. The default source for context data is the ThreadContext.
* </p><p>
* In some asynchronous models, work may be delegated to several threads, while conceptually this work shares the same
* context. In such models, storing context data in {@code ThreadLocal} variables is not convenient or desirable.
* Users can configure the {@code ContextDataInjectorFactory} to provide custom {@code ContextDataInjector} objects,
* in order to initialize log events with context data from any arbitrary context.
* </p><p>
* When providing a custom {@code ContextDataInjector}, be aware that the {@code ContextDataInjectorFactory} may be
* invoked multiple times and the various components in Log4j that need access to context data may each have their own
* instance of {@code ContextDataInjector}.
* This includes the object(s) that populate log events, but also various lookups and filters that look at
* context data to determine whether an event should be logged.
* </p><p>
* Implementors should take particular note of how the different methods in the interface have different thread-safety
* guarantees to enable optimal performance.
* </p>
*
* @see StringMap
* @see ReadOnlyStringMap
* @see ContextDataInjectorFactory
* @see org.apache.logging.log4j.ThreadContext
* @see ThreadContextDataInjector
* @since 2.7
*/
public interface ContextDataInjector {
/**
* Returns a {@code StringMap} object initialized with the specified properties and the appropriate
* context data. The returned value may be the specified parameter or a different object.
* <p>
* This method will be called for each log event to initialize its context data and implementors should take
* care to make this method as performant as possible while preserving at least the following thread-safety
* guarantee.
* </p><p>
* Thread-safety note: The returned object can safely be passed off to another thread: future changes in the
* underlying context data will not be reflected in the returned object.
* </p><p>
* Example implementation:
* </p>
* <pre>
* public StringMap injectContextData(List<Property> properties, StringMap reusable) {
* if (properties == null || properties.isEmpty()) {
* // assume context data is stored in a copy-on-write data structure that is safe to pass to another thread
* return (StringMap) rawContextData();
* }
* // first copy configuration properties into the result
* ThreadContextDataInjector.copyProperties(properties, reusable);
*
* // then copy context data key-value pairs (may overwrite configuration properties)
* reusable.putAll(rawContextData());
* return reusable;
* }
* </pre>
*
* @param properties Properties from the log4j configuration to be added to the resulting ReadOnlyStringMap. May be
* {@code null} or empty
* @param reusable a {@code StringMap} instance that may be reused to avoid creating temporary objects
* @return a {@code StringMap} instance initialized with the specified properties and the appropriate
* context data. The returned value may be the specified parameter or a different object.
* @see ThreadContextDataInjector#copyProperties(List, StringMap)
*/
StringMap injectContextData(final List<Property> properties, final StringMap reusable);
/**
* Returns a {@code ReadOnlyStringMap} object reflecting the current state of the context. Configuration properties
* are not included in the result.
* <p>
* This method may be called multiple times for each log event by Filters and Lookups and implementors should take
* care to make this method as performant as possible while preserving at least the following thread-safety
* guarantee.
* </p><p>
* Thread-safety note: The returned object can only be safely used <em>in the current thread</em>. Changes in the
* underlying context may or may not be reflected in the returned object, depending on the context data source and
* the implementation of this method. It is not safe to pass the returned object to another thread.
* </p>
* @return a {@code ReadOnlyStringMap} object reflecting the current state of the context, may not return {@code null}
*/
ReadOnlyStringMap rawContextData();
}