1616
1717package org .springframework .boot .logging .log4j2 ;
1818
19+ import java .io .FileNotFoundException ;
1920import java .io .IOException ;
2021import java .util .ArrayList ;
2122import java .util .Collections ;
7980 */
8081public class Log4J2LoggingSystem extends AbstractLoggingSystem {
8182
82- private static final org .apache .logging .log4j .Logger STATUS_LOGGER = StatusLogger .getLogger ();
83-
8483 private static final String OPTIONAL_PREFIX = "optional:" ;
8584
8685 /**
@@ -93,8 +92,6 @@ public class Log4J2LoggingSystem extends AbstractLoggingSystem {
9392 */
9493 static final String LOG4J_LOG_MANAGER = "org.apache.logging.log4j.jul.LogManager" ;
9594
96- private static final SpringEnvironmentPropertySource propertySource = new SpringEnvironmentPropertySource ();
97-
9895 static final String ENVIRONMENT_KEY = Conventions .getQualifiedAttributeName (Log4J2LoggingSystem .class ,
9996 "environment" );
10097
@@ -115,6 +112,10 @@ public class Log4J2LoggingSystem extends AbstractLoggingSystem {
115112
116113 private static final Filter FILTER = DenyAllFilter .newBuilder ().build ();
117114
115+ private static final SpringEnvironmentPropertySource propertySource = new SpringEnvironmentPropertySource ();
116+
117+ private static final org .apache .logging .log4j .Logger statusLogger = StatusLogger .getLogger ();
118+
118119 private final LoggerContext loggerContext ;
119120
120121 /**
@@ -127,34 +128,15 @@ public class Log4J2LoggingSystem extends AbstractLoggingSystem {
127128 this .loggerContext = loggerContext ;
128129 }
129130
130- /**
131- * Create a new {@link Log4J2LoggingSystem} instance.
132- * @param classLoader the class loader to use
133- * @return a new {@link Log4J2LoggingSystem} instance
134- * @throws IllegalStateException if Log4j Core is not the active Log4j API provider.
135- */
136- private static Log4J2LoggingSystem createLoggingSystem (ClassLoader classLoader ) {
137- org .apache .logging .log4j .spi .LoggerContext loggerContext = LogManager .getContext (classLoader , false );
138- if (loggerContext instanceof LoggerContext ) {
139- return new Log4J2LoggingSystem (classLoader , (LoggerContext ) loggerContext );
140- }
141- throw new IllegalStateException ("Log4j Core is not the active Log4j API provider" );
142- }
143-
144- /**
145- * {@inheritDoc}
146- * @deprecated Since 4.0.0, in favor of the {@link ConfigurationFactory} SPI.
147- */
148131 @ Override
149- @ Deprecated (since = "4.0.0" , forRemoval = true )
150132 protected String [] getStandardConfigLocations () {
151- return new String [] { "log4j2.xml" };
133+ // With Log4J2 we use the ConfigurationFactory
134+ throw new IllegalStateException ("Standard config locations cannot be used with Log4J2" );
152135 }
153136
154137 @ Override
155138 protected @ Nullable String getSelfInitializationConfig () {
156- Configuration currentConfiguration = getLoggerContext ().getConfiguration ();
157- return getConfigLocation (currentConfiguration );
139+ return getConfigLocation (getLoggerContext ().getConfiguration ());
158140 }
159141
160142 @ Override
@@ -167,24 +149,25 @@ protected String[] getStandardConfigLocations() {
167149 return (configLocation != null && configLocation .contains ("-spring" )) ? configLocation : null ;
168150 }
169151 catch (ConfigurationException ex ) {
170- STATUS_LOGGER .warn ("Could not load Spring-specific Log4j Core configuration" , ex );
152+ statusLogger .warn ("Could not load Spring-specific Log4j Core configuration" , ex );
171153 return null ;
172154 }
173155 }
174156
157+ /**
158+ * Return the configuration location. The result may be:
159+ * <ul>
160+ * <li>{@code null}: if DefaultConfiguration is used (no explicit config loaded)</li>
161+ * <li>A file path: if provided explicitly by the user</li>
162+ * <li>A URI: if loaded from the classpath default or a custom location</li>
163+ * </ul>
164+ * @param configuration the source configuration
165+ * @return the config location or {@code null}
166+ */
175167 private @ Nullable String getConfigLocation (Configuration configuration ) {
176- // The location may be:
177- // - null: if DefaultConfiguration is used (no explicit config loaded)
178- // - a file path: if provided explicitly by the user
179- // - a URI: if loaded from the classpath default or a custom location
180168 return configuration .getConfigurationSource ().getLocation ();
181169 }
182170
183- @ Deprecated (since = "4.0.0" , forRemoval = true )
184- protected boolean isClassAvailable (String className ) {
185- return ClassUtils .isPresent (className , getClassLoader ());
186- }
187-
188171 @ Override
189172 public void beforeInitialize () {
190173 LoggerContext loggerContext = getLoggerContext ();
@@ -315,22 +298,18 @@ private void reconfigure(String location, List<String> overrides) {
315298 this .loggerContext .reconfigure (mergeConfigurations (configurations ));
316299 }
317300 catch (Exception ex ) {
318- String message = "Could not initialize Log4J2 logging from " + location ;
319- if (!overrides .isEmpty ()) {
320- message += " with overrides " + overrides ;
321- }
322- throw new IllegalStateException (message , ex );
301+ throw new IllegalStateException ("Could not initialize Log4J2 logging from %s%s" .formatted (location ,
302+ (overrides .isEmpty () ? "" : " with overrides " + overrides )), ex );
323303 }
324304 }
325305
326306 private Configuration load (ResourceLoader resourceLoader , String location ) throws IOException {
327- ConfigurationFactory factory = ConfigurationFactory .getInstance ();
307+ ConfigurationFactory configurationFactory = ConfigurationFactory .getInstance ();
328308 Resource resource = resourceLoader .getResource (location );
329- Configuration configuration = factory .getConfiguration (getLoggerContext (), null , resource .getURI (),
309+ Configuration configuration = configurationFactory .getConfiguration (getLoggerContext (), null , resource .getURI (),
330310 getClassLoader ());
331- // The error handling in Log4j Core 2.25.x is not consistent:
332- // some loading and parsing errors result in a null configuration,
333- // others in an exception.
311+ // The error handling in Log4j Core 2.25.x is not consistent, some loading and
312+ // parsing errors result in a null configuration, others in an exception.
334313 if (configuration == null ) {
335314 throw new ConfigurationException ("Could not load Log4j Core configuration from " + location );
336315 }
@@ -344,8 +323,7 @@ private Configuration load(ResourceLoader resourceLoader, String location) throw
344323 try {
345324 return (resource .exists ()) ? load (resourceLoader , actualLocation ) : null ;
346325 }
347- catch (ConfigurationException | IOException ex ) {
348- STATUS_LOGGER .debug ("Could not load optional Log4j2 override from {}" , actualLocation , ex );
326+ catch (FileNotFoundException ex ) {
349327 return null ;
350328 }
351329 }
@@ -362,8 +340,6 @@ private Configuration mergeConfigurations(List<Configuration> configurations) {
362340 @ Override
363341 protected void reinitialize (LoggingInitializationContext initializationContext ) {
364342 String currentLocation = getSelfInitializationConfig ();
365- // `reinitialize` is only triggered when `getSelfInitializationConfig` returns a
366- // non-null value
367343 Assert .notNull (currentLocation , "'currentLocation' must not be null" );
368344 load (initializationContext , currentLocation , null );
369345 }
@@ -544,19 +520,18 @@ protected String getDefaultLogCorrelationPattern() {
544520 @ Order (0 )
545521 public static class Factory implements LoggingSystemFactory {
546522
547- private static final String LOG4J_CORE_CONTEXT_FACTORY = "org.apache.logging.log4j.core.impl.Log4jContextFactory" ;
523+ static final String LOG4J_CORE_CONTEXT_FACTORY = "org.apache.logging.log4j.core.impl.Log4jContextFactory" ;
548524
549525 private static final boolean PRESENT = ClassUtils .isPresent (LOG4J_CORE_CONTEXT_FACTORY ,
550526 Factory .class .getClassLoader ());
551527
552528 @ Override
553529 public @ Nullable LoggingSystem getLoggingSystem (ClassLoader classLoader ) {
554530 if (PRESENT ) {
555- try {
556- return createLoggingSystem (classLoader );
557- }
558- catch (IllegalStateException ex ) {
559- // Log4j Core is not the active Log4j API provider
531+ org .apache .logging .log4j .spi .LoggerContext spiLoggerContext = LogManager .getContext (classLoader , false );
532+ Assert .state (spiLoggerContext instanceof LoggerContext , "" );
533+ if (spiLoggerContext instanceof LoggerContext coreLoggerContext ) {
534+ return new Log4J2LoggingSystem (classLoader , coreLoggerContext );
560535 }
561536 }
562537 return null ;
0 commit comments