1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.apache.logging.log4j.spi;
18
19 import org.apache.logging.log4j.LogManager;
20 import org.apache.logging.log4j.Logger;
21 import org.apache.logging.log4j.ThreadContext;
22 import org.apache.logging.log4j.status.StatusLogger;
23 import org.apache.logging.log4j.util.Constants;
24 import org.apache.logging.log4j.util.PropertiesUtil;
25 import org.apache.logging.log4j.util.ProviderUtil;
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48 public final class ThreadContextMapFactory {
49 private static final Logger LOGGER = StatusLogger.getLogger();
50 private static final String THREAD_CONTEXT_KEY = "log4j2.threadContextMap";
51 private static final String GC_FREE_THREAD_CONTEXT_KEY = "log4j2.garbagefree.threadContextMap";
52
53 private static boolean GcFreeThreadContextKey;
54 private static String ThreadContextMapName;
55
56 static {
57 initPrivate();
58 }
59
60
61
62
63
64 public static void init() {
65 CopyOnWriteSortedArrayThreadContextMap.init();
66 GarbageFreeSortedArrayThreadContextMap.init();
67 DefaultThreadContextMap.init();
68 initPrivate();
69 }
70
71
72
73
74
75 private static void initPrivate() {
76 final PropertiesUtil properties = PropertiesUtil.getProperties();
77 ThreadContextMapName = properties.getStringProperty(THREAD_CONTEXT_KEY);
78 GcFreeThreadContextKey = properties.getBooleanProperty(GC_FREE_THREAD_CONTEXT_KEY);
79 }
80
81 private ThreadContextMapFactory() {
82 }
83
84 public static ThreadContextMap createThreadContextMap() {
85 final ClassLoader cl = ProviderUtil.findClassLoader();
86 ThreadContextMap result = null;
87 if (ThreadContextMapName != null) {
88 try {
89 final Class<?> clazz = cl.loadClass(ThreadContextMapName);
90 if (ThreadContextMap.class.isAssignableFrom(clazz)) {
91 result = (ThreadContextMap) clazz.newInstance();
92 }
93 } catch (final ClassNotFoundException cnfe) {
94 LOGGER.error("Unable to locate configured ThreadContextMap {}", ThreadContextMapName);
95 } catch (final Exception ex) {
96 LOGGER.error("Unable to create configured ThreadContextMap {}", ThreadContextMapName, ex);
97 }
98 }
99 if (result == null && ProviderUtil.hasProviders() && LogManager.getFactory() != null) {
100 final String factoryClassName = LogManager.getFactory().getClass().getName();
101 for (final Provider provider : ProviderUtil.getProviders()) {
102 if (factoryClassName.equals(provider.getClassName())) {
103 final Class<? extends ThreadContextMap> clazz = provider.loadThreadContextMap();
104 if (clazz != null) {
105 try {
106 result = clazz.newInstance();
107 break;
108 } catch (final Exception e) {
109 LOGGER.error("Unable to locate or load configured ThreadContextMap {}",
110 provider.getThreadContextMap(), e);
111 result = createDefaultThreadContextMap();
112 }
113 }
114 }
115 }
116 }
117 if (result == null) {
118 result = createDefaultThreadContextMap();
119 }
120 return result;
121 }
122
123 private static ThreadContextMap createDefaultThreadContextMap() {
124 if (Constants.ENABLE_THREADLOCALS) {
125 if (GcFreeThreadContextKey) {
126 return new GarbageFreeSortedArrayThreadContextMap();
127 }
128 return new CopyOnWriteSortedArrayThreadContextMap();
129 }
130 return new DefaultThreadContextMap(true);
131 }
132 }