0
# Logger Context Management
1
2
Utilities for managing LoggerContext instances in web applications, including context retrieval, lifecycle management, and execution wrapping for async operations. These components ensure thread-safe logging context handling in multi-threaded servlet environments.
3
4
## Capabilities
5
6
### WebLoggerContextUtils
7
8
Utility class providing static methods for LoggerContext management in servlet environments. Handles context retrieval, lifecycle operations, and execution wrapping for proper thread-local context binding.
9
10
```java { .api }
11
/**
12
* Utility methods for retrieving and managing LoggerContext in servlet environments.
13
* Provides thread-safe access to LoggerContext instances and execution wrapping.
14
*/
15
public final class WebLoggerContextUtils {
16
17
/**
18
* Retrieves the LoggerContext associated with a ServletContext.
19
* Returns null if no LoggerContext is found.
20
*
21
* @param servletContext ServletContext to locate LoggerContext for
22
* @return LoggerContext instance or null if not found
23
*/
24
public static LoggerContext getWebLoggerContext(ServletContext servletContext);
25
26
/**
27
* Retrieves the LoggerContext with validation that it exists.
28
* Never returns null - throws exception if LoggerContext is not found.
29
*
30
* @param servletContext ServletContext to locate LoggerContext for
31
* @return LoggerContext instance (never null)
32
* @throws IllegalStateException if no LoggerContext found in ServletContext
33
*/
34
public static LoggerContext getRequiredWebLoggerContext(ServletContext servletContext);
35
36
/**
37
* Finds or initializes the Log4jWebLifeCycle singleton for the ServletContext.
38
* Thread-safe singleton pattern with lazy initialization.
39
*
40
* @param servletContext ServletContext to get the Log4jWebLifeCycle for
41
* @return Log4jWebLifeCycle instance for the ServletContext
42
*/
43
public static Log4jWebLifeCycle getWebLifeCycle(ServletContext servletContext);
44
45
/**
46
* Wraps a Runnable with proper LoggerContext management.
47
* Sets context before execution, clears after execution.
48
* Essential for async servlet operations.
49
*
50
* @param servletContext ServletContext to locate LoggerContext for
51
* @param runnable Runnable to wrap with logging context
52
* @return Wrapped Runnable with automatic context management
53
*/
54
public static Runnable wrapExecutionContext(ServletContext servletContext, Runnable runnable);
55
56
57
/**
58
* Gets the current ServletContext from thread-bound LoggerContext.
59
* Returns null if no ServletContext is available.
60
*
61
* @return Current ServletContext or null if not available
62
*/
63
public static ServletContext getServletContext();
64
}
65
```
66
67
**Usage Examples:**
68
69
```java
70
// Get LoggerContext with validation
71
ServletContext servletContext = request.getServletContext();
72
LoggerContext loggerContext = WebLoggerContextUtils.getRequiredWebLoggerContext(servletContext);
73
74
// Wrap async task with proper context
75
Runnable asyncTask = WebLoggerContextUtils.wrapExecutionContext(servletContext, () -> {
76
Logger logger = LogManager.getLogger();
77
logger.info("Executing with proper logging context");
78
});
79
80
// Execute in separate thread
81
executor.submit(asyncTask);
82
```
83
84
### Log4jWebSupport Interface
85
86
Primary interface defining the contract for web application Log4j integration. Provides methods for context management and execution wrapping.
87
88
```java { .api }
89
/**
90
* Interface for setting and clearing thread-bound LoggerContext in web applications.
91
* Defines contract for Log4j web integration components.
92
*/
93
public interface Log4jWebSupport {
94
95
/**
96
* Sets the logger context for the current thread.
97
* Enables easy access to loggers via LogManager.getLogger().
98
*/
99
void setLoggerContext();
100
101
/**
102
* Clears the logger context set up in setLoggerContext().
103
* Should be called in finally blocks to ensure cleanup.
104
*/
105
void clearLoggerContext();
106
107
/**
108
* Convenience method that wraps Runnable execution with context management.
109
* Calls setLoggerContext(), executes runnable, then calls clearLoggerContext().
110
*
111
* @param runnable Runnable to execute with configured logger context
112
*/
113
void wrapExecution(Runnable runnable);
114
}
115
```
116
117
**Context Management Constants:**
118
119
```java { .api }
120
public interface Log4jWebSupport {
121
/** ServletContext parameter name for LoggerContext name */
122
String LOG4J_CONTEXT_NAME = "log4jContextName";
123
124
/** ServletContext parameter name for configuration location */
125
String LOG4J_CONFIG_LOCATION = "log4jConfiguration";
126
127
/** ServletContext parameter name for JNDI flag */
128
String IS_LOG4J_CONTEXT_SELECTOR_NAMED = "isLog4jContextSelectorNamed";
129
130
/** ServletContext parameter name for auto-initialization disable flag */
131
String IS_LOG4J_AUTO_INITIALIZATION_DISABLED = "isLog4jAutoInitializationDisabled";
132
133
/** ServletContext parameter name for auto-shutdown disable flag */
134
String IS_LOG4J_AUTO_SHUTDOWN_DISABLED = "isLog4jAutoShutdownDisabled";
135
136
/** ServletContext attribute key for Log4jWebSupport instance */
137
String SUPPORT_ATTRIBUTE = "org.apache.logging.log4j.web.Log4jWebSupport.INSTANCE";
138
139
/** ServletContext attribute key for LoggerContext instance */
140
String CONTEXT_ATTRIBUTE = "org.apache.logging.log4j.spi.LoggerContext.INSTANCE";
141
}
142
```
143
144
### Log4jWebLifeCycle Interface
145
146
Extended interface combining Log4jWebSupport with LifeCycle management. Provides complete lifecycle control for Log4j in web applications.
147
148
```java { .api }
149
/**
150
* Internal interface for initializing and deinitializing Log4j in web applications.
151
* Combines context management with lifecycle operations.
152
* This is a package-private interface used internally by Log4j web components.
153
* Users should access lifecycle functionality through WebLoggerContextUtils.getWebLifeCycle().
154
*/
155
// Note: This interface is package-private and not directly accessible to application code
156
interface Log4jWebLifeCycle extends Log4jWebSupport, LifeCycle {
157
158
/**
159
* Starts up Log4j in the web application.
160
* Calls setLoggerContext() after initialization is complete.
161
*
162
* @throws IllegalStateException if JNDI config location specified but no name provided
163
*/
164
@Override
165
void start();
166
167
/**
168
* Shuts down Log4j in the web application.
169
* Calls clearLoggerContext() immediately before deinitialization begins.
170
*/
171
@Override
172
void stop();
173
}
174
```
175
176
## Context Binding Patterns
177
178
### Manual Context Management
179
180
```java
181
Log4jWebSupport webSupport = (Log4jWebSupport) servletContext.getAttribute(
182
Log4jWebSupport.SUPPORT_ATTRIBUTE);
183
184
// Manual context binding
185
webSupport.setLoggerContext();
186
try {
187
Logger logger = LogManager.getLogger();
188
logger.info("Logging with proper context");
189
} finally {
190
webSupport.clearLoggerContext();
191
}
192
```
193
194
### Automatic Context Wrapping
195
196
```java
197
Log4jWebSupport webSupport = WebLoggerContextUtils.getWebLifeCycle(servletContext);
198
199
// Automatic wrapping
200
webSupport.wrapExecution(() -> {
201
Logger logger = LogManager.getLogger();
202
logger.info("Context automatically managed");
203
});
204
```
205
206
### Async Request Processing
207
208
```java
209
@WebServlet(urlPatterns = "/async", asyncSupported = true)
210
public class AsyncServlet extends HttpServlet {
211
212
@Override
213
protected void doGet(HttpServletRequest request, HttpServletResponse response)
214
throws ServletException, IOException {
215
216
AsyncContext asyncContext = request.startAsync();
217
ServletContext servletContext = request.getServletContext();
218
219
// Wrap async task with proper logging context
220
Runnable asyncTask = WebLoggerContextUtils.wrapExecutionContext(servletContext, () -> {
221
try {
222
// Async processing with proper logging context
223
Logger logger = LogManager.getLogger();
224
logger.info("Processing async request");
225
226
// Simulate async work
227
Thread.sleep(1000);
228
229
asyncContext.getResponse().getWriter().write("Async complete");
230
asyncContext.complete();
231
} catch (Exception e) {
232
logger.error("Async processing failed", e);
233
asyncContext.complete();
234
}
235
});
236
237
// Execute in thread pool
238
executor.submit(asyncTask);
239
}
240
}
241
```
242
243
## Thread Safety
244
245
All utility methods in `WebLoggerContextUtils` are thread-safe:
246
247
- **Singleton Management**: Uses `ReentrantLock` for thread-safe lazy initialization
248
- **Context Retrieval**: Safe concurrent access to ServletContext attributes
249
- **Execution Wrapping**: Creates independent context-managed Runnable instances
250
251
The thread-local context binding ensures proper isolation between concurrent requests while maintaining performance.