0
# LogManager Integration
1
2
The LogManager integration provides complete replacement of JUL's LogManager with Log4j's implementation, offering optimal performance by redirecting all JUL logging calls directly to Log4j without the overhead of handler-based bridging.
3
4
## Setup
5
6
Enable LogManager integration by setting the system property:
7
8
```java
9
System.setProperty("java.util.logging.manager", "org.apache.logging.log4j.jul.LogManager");
10
```
11
12
Or via JVM arguments:
13
```bash
14
-Djava.util.logging.manager=org.apache.logging.log4j.jul.LogManager
15
```
16
17
## Usage
18
19
Once configured, all standard JUL API calls are transparently redirected to Log4j:
20
21
```java
22
// Standard JUL API - automatically uses Log4j
23
java.util.logging.Logger logger = java.util.logging.Logger.getLogger("com.example.MyClass");
24
25
// All logging methods work as expected
26
logger.severe("Error message");
27
logger.warning("Warning message");
28
logger.info("Info message");
29
logger.fine("Debug message");
30
logger.finest("Trace message");
31
32
// Parameterized messages
33
logger.log(java.util.logging.Level.INFO, "Processing {0} items", 42);
34
35
// Exception logging
36
try {
37
// some operation
38
} catch (Exception e) {
39
logger.log(java.util.logging.Level.SEVERE, "Operation failed", e);
40
}
41
```
42
43
## Logger Adapter Selection
44
45
The LogManager automatically selects the most appropriate logger adapter:
46
47
1. **Custom Adapter**: If `log4j.jul.LoggerAdapter` property is set
48
2. **CoreLoggerAdapter**: If log4j-core is available (provides enhanced features)
49
3. **ApiLoggerAdapter**: Fallback when only log4j-api is available
50
51
```java
52
// Override adapter selection
53
System.setProperty("log4j.jul.LoggerAdapter", "com.example.CustomLoggerAdapter");
54
```
55
56
## API Reference
57
58
### LogManager Class
59
60
```java { .api }
61
public class LogManager extends java.util.logging.LogManager {
62
/**
63
* Creates new LogManager instance with automatic adapter selection.
64
* Selects CustomAdapter -> CoreLoggerAdapter -> ApiLoggerAdapter (fallback).
65
*/
66
public LogManager();
67
68
/**
69
* Returns logger for the given name, creating if necessary.
70
* Handles recursive calls and delegates to the selected adapter.
71
*
72
* @param name the logger name
73
* @return Logger instance backed by Log4j
74
*/
75
public Logger getLogger(String name);
76
77
/**
78
* Returns enumeration of all logger names from the adapter context.
79
*
80
* @return enumeration of logger names
81
*/
82
public Enumeration<String> getLoggerNames();
83
84
/**
85
* Always returns false to prevent registration of non-bridged loggers.
86
* All loggers must be obtained through getLogger(name).
87
*
88
* @param logger the logger to add
89
* @return always false
90
*/
91
public boolean addLogger(Logger logger);
92
}
93
```
94
95
### Configuration Properties
96
97
```java { .api }
98
public final class Constants {
99
/**
100
* Property name for overriding the AbstractLoggerAdapter implementation.
101
* Set to fully qualified class name with default constructor.
102
*/
103
public static final String LOGGER_ADAPTOR_PROPERTY = "log4j.jul.LoggerAdapter";
104
}
105
```
106
107
## Logger Implementations
108
109
The LogManager creates different logger implementations based on available Log4j components:
110
111
### When log4j-core is Available
112
- Uses `CoreLoggerAdapter` creating `CoreLogger` instances
113
- Provides full JUL API support including level management
114
- Enhanced performance and functionality
115
116
### When Only log4j-api is Available
117
- Uses `ApiLoggerAdapter` creating `ApiLogger` instances
118
- Limited functionality due to API constraints
119
- Methods like `setLevel()` and `getParent()` have limitations
120
121
## Thread Safety
122
123
The LogManager implementation is fully thread-safe:
124
- Uses `ThreadLocal<Set<String>>` to detect and prevent recursive logger creation
125
- Returns `NoOpLogger` for recursive calls to prevent infinite loops
126
- Adapter selection is performed once during construction
127
128
## Performance Considerations
129
130
- **Optimal Performance**: Direct delegation without handler overhead
131
- **Lazy Logger Creation**: Loggers created on-demand through adapter
132
- **Context Isolation**: Uses appropriate LoggerContext based on classloader
133
- **Recursive Call Prevention**: Minimal overhead for recursive call detection
134
135
## Error Handling
136
137
The LogManager gracefully handles various error conditions:
138
139
```java
140
// Recursive calls are detected and logged
141
logger.warn("Recursive call to getLogger for {} ignored.", name);
142
143
// Custom adapter loading failures fall back to default
144
logger.error("Specified LoggerAdapter [{}] is incompatible.", className, exception);
145
```
146
147
## Integration with Log4j Configuration
148
149
The LogManager respects all Log4j configuration settings:
150
- Logger levels from log4j2.xml or log4j2.properties
151
- Appender configurations
152
- Filter configurations
153
- Custom message factories and contexts
154
155
## Migration Notes
156
157
When migrating from standard JUL to LogManager integration:
158
159
1. **No Code Changes**: Existing JUL code works unchanged
160
2. **Configuration**: Log4j configuration replaces JUL configuration
161
3. **Performance**: Significant improvement over standard JUL
162
4. **Features**: Access to advanced Log4j features like async logging
163
5. **Compatibility**: Full compatibility with JUL API contracts