1 /* 2 * Licensed to the Apache Software Foundation (ASF) under one or more 3 * contributor license agreements. See the NOTICE file distributed with 4 * this work for additional information regarding copyright ownership. 5 * The ASF licenses this file to You under the Apache license, Version 2.0 6 * (the "License"); you may not use this file except in compliance with 7 * the License. You may obtain a copy of the License at 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the license for the specific language governing permissions and 15 * limitations under the license. 16 */ 17 package org.apache.logging.log4j.core; 18 19 import java.util.List; 20 21 import org.apache.logging.log4j.core.config.Property; 22 import org.apache.logging.log4j.core.impl.ContextDataInjectorFactory; 23 import org.apache.logging.log4j.core.impl.ThreadContextDataInjector; 24 import org.apache.logging.log4j.util.ReadOnlyStringMap; 25 import org.apache.logging.log4j.util.StringMap; 26 27 /** 28 * Responsible for initializing the context data of LogEvents. Context data is data that is set by the application to be 29 * included in all subsequent log events. 30 * <p><b>NOTE: It is no longer recommended that custom implementations of this interface be provided as it is 31 * difficult to do. Instead, provide a custom ContextDataProvider.</b></p> 32 * <p> 33 * <p> 34 * The source of the context data is implementation-specific. The default source for context data is the ThreadContext. 35 * </p><p> 36 * In some asynchronous models, work may be delegated to several threads, while conceptually this work shares the same 37 * context. In such models, storing context data in {@code ThreadLocal} variables is not convenient or desirable. 38 * Users can configure the {@code ContextDataInjectorFactory} to provide custom {@code ContextDataInjector} objects, 39 * in order to initialize log events with context data from any arbitrary context. 40 * </p><p> 41 * When providing a custom {@code ContextDataInjector}, be aware that the {@code ContextDataInjectorFactory} may be 42 * invoked multiple times and the various components in Log4j that need access to context data may each have their own 43 * instance of {@code ContextDataInjector}. 44 * This includes the object(s) that populate log events, but also various lookups and filters that look at 45 * context data to determine whether an event should be logged. 46 * </p><p> 47 * Implementors should take particular note of how the different methods in the interface have different thread-safety 48 * guarantees to enable optimal performance. 49 * </p> 50 * 51 * @see StringMap 52 * @see ReadOnlyStringMap 53 * @see ContextDataInjectorFactory 54 * @see org.apache.logging.log4j.ThreadContext 55 * @see ThreadContextDataInjector 56 * @since 2.7 57 */ 58 public interface ContextDataInjector { 59 /** 60 * Returns a {@code StringMap} object initialized with the specified properties and the appropriate 61 * context data. The returned value may be the specified parameter or a different object. 62 * <p> 63 * This method will be called for each log event to initialize its context data and implementors should take 64 * care to make this method as performant as possible while preserving at least the following thread-safety 65 * guarantee. 66 * </p><p> 67 * Thread-safety note: The returned object can safely be passed off to another thread: future changes in the 68 * underlying context data will not be reflected in the returned object. 69 * </p><p> 70 * Example implementation: 71 * </p> 72 * <pre> 73 * public StringMap injectContextData(List<Property> properties, StringMap reusable) { 74 * if (properties == null || properties.isEmpty()) { 75 * // assume context data is stored in a copy-on-write data structure that is safe to pass to another thread 76 * return (StringMap) rawContextData(); 77 * } 78 * // first copy configuration properties into the result 79 * ThreadContextDataInjector.copyProperties(properties, reusable); 80 * 81 * // then copy context data key-value pairs (may overwrite configuration properties) 82 * reusable.putAll(rawContextData()); 83 * return reusable; 84 * } 85 * </pre> 86 * 87 * @param properties Properties from the log4j configuration to be added to the resulting ReadOnlyStringMap. May be 88 * {@code null} or empty 89 * @param reusable a {@code StringMap} instance that may be reused to avoid creating temporary objects 90 * @return a {@code StringMap} instance initialized with the specified properties and the appropriate 91 * context data. The returned value may be the specified parameter or a different object. 92 * @see ThreadContextDataInjector#copyProperties(List, StringMap) 93 */ 94 StringMap injectContextData(final List<Property> properties, final StringMap reusable); 95 96 /** 97 * Returns a {@code ReadOnlyStringMap} object reflecting the current state of the context. Configuration properties 98 * are not included in the result. 99 * <p> 100 * This method may be called multiple times for each log event by Filters and Lookups and implementors should take 101 * care to make this method as performant as possible while preserving at least the following thread-safety 102 * guarantee. 103 * </p><p> 104 * Thread-safety note: The returned object can only be safely used <em>in the current thread</em>. Changes in the 105 * underlying context may or may not be reflected in the returned object, depending on the context data source and 106 * the implementation of this method. It is not safe to pass the returned object to another thread. 107 * </p> 108 * @return a {@code ReadOnlyStringMap} object reflecting the current state of the context, may not return {@code null} 109 */ 110 ReadOnlyStringMap rawContextData(); 111 }