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>
31 * The source of the context data is implementation-specific. The default source for context data is the ThreadContext.
32 * </p><p>
33 * In some asynchronous models, work may be delegated to several threads, while conceptually this work shares the same
34 * context. In such models, storing context data in {@code ThreadLocal} variables is not convenient or desirable.
35 * Users can configure the {@code ContextDataInjectorFactory} to provide custom {@code ContextDataInjector} objects,
36 * in order to initialize log events with context data from any arbitrary context.
37 * </p><p>
38 * When providing a custom {@code ContextDataInjector}, be aware that the {@code ContextDataInjectorFactory} may be
39 * invoked multiple times and the various components in Log4j that need access to context data may each have their own
40 * instance of {@code ContextDataInjector}.
41 * This includes the object(s) that populate log events, but also various lookups and filters that look at
42 * context data to determine whether an event should be logged.
43 * </p><p>
44 * Implementors should take particular note of how the different methods in the interface have different thread-safety
45 * guarantees to enable optimal performance.
46 * </p>
47 *
48 * @see StringMap
49 * @see ReadOnlyStringMap
50 * @see ContextDataInjectorFactory
51 * @see org.apache.logging.log4j.ThreadContext
52 * @see ThreadContextDataInjector
53 * @since 2.7
54 */
55 public interface ContextDataInjector {
56 /**
57 * Returns a {@code StringMap} object initialized with the specified properties and the appropriate
58 * context data. The returned value may be the specified parameter or a different object.
59 * <p>
60 * This method will be called for each log event to initialize its context data and implementors should take
61 * care to make this method as performant as possible while preserving at least the following thread-safety
62 * guarantee.
63 * </p><p>
64 * Thread-safety note: The returned object can safely be passed off to another thread: future changes in the
65 * underlying context data will not be reflected in the returned object.
66 * </p><p>
67 * Example implementation:
68 * </p>
69 * <pre>
70 * public StringMap injectContextData(List<Property> properties, StringMap reusable) {
71 * if (properties == null || properties.isEmpty()) {
72 * // assume context data is stored in a copy-on-write data structure that is safe to pass to another thread
73 * return (StringMap) rawContextData();
74 * }
75 * // first copy configuration properties into the result
76 * ThreadContextDataInjector.copyProperties(properties, reusable);
77 *
78 * // then copy context data key-value pairs (may overwrite configuration properties)
79 * reusable.putAll(rawContextData());
80 * return reusable;
81 * }
82 * </pre>
83 *
84 * @param properties Properties from the log4j configuration to be added to the resulting ReadOnlyStringMap. May be
85 * {@code null} or empty
86 * @param reusable a {@code StringMap} instance that may be reused to avoid creating temporary objects
87 * @return a {@code StringMap} instance initialized with the specified properties and the appropriate
88 * context data. The returned value may be the specified parameter or a different object.
89 * @see ThreadContextDataInjector#copyProperties(List, StringMap)
90 */
91 StringMap injectContextData(final List<Property> properties, final StringMap reusable);
92
93 /**
94 * Returns a {@code ReadOnlyStringMap} object reflecting the current state of the context. Configuration properties
95 * are not included in the result.
96 * <p>
97 * This method may be called multiple times for each log event by Filters and Lookups and implementors should take
98 * care to make this method as performant as possible while preserving at least the following thread-safety
99 * guarantee.
100 * </p><p>
101 * Thread-safety note: The returned object can only be safely used <em>in the current thread</em>. Changes in the
102 * underlying context may or may not be reflected in the returned object, depending on the context data source and
103 * the implementation of this method. It is not safe to pass the returned object to another thread.
104 * </p>
105 * @return a {@code ReadOnlyStringMap} object reflecting the current state of the context, may not return {@code null}
106 */
107 ReadOnlyStringMap rawContextData();
108 }