2424import java .lang .annotation .RetentionPolicy ;
2525import java .lang .annotation .Target ;
2626import java .net .ProtocolException ;
27+ import java .util .ArrayList ;
28+ import java .util .Collections ;
2729import java .util .EnumSet ;
2830import java .util .LinkedHashMap ;
2931import java .util .List ;
3032import java .util .Map ;
3133import java .util .logging .Handler ;
3234import java .util .logging .Level ;
35+ import java .util .stream .Stream ;
3336
3437import com .fasterxml .jackson .databind .ObjectMapper ;
3538import org .apache .commons .logging .Log ;
3841import org .apache .logging .log4j .Logger ;
3942import org .apache .logging .log4j .core .LoggerContext ;
4043import org .apache .logging .log4j .core .config .Configuration ;
41- import org .apache .logging .log4j .core .config .ConfigurationFactory ;
4244import org .apache .logging .log4j .core .config .LoggerConfig ;
4345import org .apache .logging .log4j .core .config .Reconfigurable ;
4446import org .apache .logging .log4j .core .config .composite .CompositeConfiguration ;
47+ import org .apache .logging .log4j .core .config .json .JsonConfigurationFactory ;
4548import org .apache .logging .log4j .core .config .plugins .util .PluginRegistry ;
49+ import org .apache .logging .log4j .core .config .properties .PropertiesConfigurationBuilder ;
50+ import org .apache .logging .log4j .core .config .properties .PropertiesConfigurationFactory ;
4651import org .apache .logging .log4j .core .config .xml .XmlConfiguration ;
52+ import org .apache .logging .log4j .core .config .yaml .YamlConfigurationFactory ;
4753import org .apache .logging .log4j .core .util .ShutdownCallbackRegistry ;
4854import org .apache .logging .log4j .jul .Log4jBridgeHandler ;
4955import org .apache .logging .log4j .status .StatusListener ;
5359import org .junit .jupiter .api .BeforeEach ;
5460import org .junit .jupiter .api .Test ;
5561import org .junit .jupiter .api .extension .ExtendWith ;
62+ import org .junit .jupiter .params .ParameterizedTest ;
63+ import org .junit .jupiter .params .provider .Arguments ;
64+ import org .junit .jupiter .params .provider .MethodSource ;
5665import org .slf4j .MDC ;
5766
5867import org .springframework .boot .logging .AbstractLoggingSystemTests ;
8998 * @author Andy Wilkinson
9099 * @author Ben Hale
91100 * @author Madhura Bhave
101+ * @author Piotr P. Karwasz
92102 */
93103@ ExtendWith (OutputCaptureExtension .class )
94104@ ClassPathExclusions ("logback-*.jar" )
@@ -105,6 +115,8 @@ class Log4J2LoggingSystemTests extends AbstractLoggingSystemTests {
105115
106116 private Configuration configuration ;
107117
118+ private String contextName ;
119+
108120 @ BeforeEach
109121 void setup () {
110122 PluginRegistry .getInstance ().clear ();
@@ -115,6 +127,7 @@ void setup() {
115127 this .configuration = loggerContext .getConfiguration ();
116128 this .loggingSystem .cleanUp ();
117129 this .logger = LogManager .getLogger (getClass ());
130+ this .contextName = loggerContext .getName ();
118131 }
119132
120133 @ AfterEach
@@ -293,54 +306,79 @@ void loggingThatUsesJulIsCaptured(CapturedOutput output) {
293306 assertThat (output ).contains ("Hello world" );
294307 }
295308
296- @ Test
297- void configLocationsWithNoExtraDependencies () {
298- assertThat (this .loggingSystem .getStandardConfigLocations ()).contains ("log4j2-test.properties" ,
299- "log4j2-test.xml" , "log4j2.properties" , "log4j2.xml" );
300- }
301-
302- @ Test
303- void configLocationsWithJacksonDatabind () {
304- this .loggingSystem .availableClasses (ObjectMapper .class .getName ());
305- assertThat (this .loggingSystem .getStandardConfigLocations ()).containsExactly ("log4j2-test.properties" ,
306- "log4j2-test.json" , "log4j2-test.jsn" , "log4j2-test.xml" , "log4j2.properties" , "log4j2.json" ,
307- "log4j2.jsn" , "log4j2.xml" );
308- }
309-
310- @ Test
311- void configLocationsWithJacksonDataformatYaml () {
312- this .loggingSystem .availableClasses ("com.fasterxml.jackson.dataformat.yaml.YAMLParser" );
313- assertThat (this .loggingSystem .getStandardConfigLocations ()).containsExactly ("log4j2-test.properties" ,
314- "log4j2-test.yaml" , "log4j2-test.yml" , "log4j2-test.xml" , "log4j2.properties" , "log4j2.yaml" ,
315- "log4j2.yml" , "log4j2.xml" );
316- }
317-
318- @ Test
319- void configLocationsWithJacksonDatabindAndDataformatYaml () {
320- this .loggingSystem .availableClasses ("com.fasterxml.jackson.dataformat.yaml.YAMLParser" ,
321- ObjectMapper .class .getName ());
322- assertThat (this .loggingSystem .getStandardConfigLocations ()).containsExactly ("log4j2-test.properties" ,
323- "log4j2-test.yaml" , "log4j2-test.yml" , "log4j2-test.json" , "log4j2-test.jsn" , "log4j2-test.xml" ,
324- "log4j2.properties" , "log4j2.yaml" , "log4j2.yml" , "log4j2.json" , "log4j2.jsn" , "log4j2.xml" );
309+ static Stream <String > configLocationsWithConfigurationFileSystemProperty () {
310+ return Stream .of ("log4j2.configurationFile" , "log4j.configuration.location" );
325311 }
326312
327- @ Test
328- void configLocationsWithConfigurationFileSystemProperty () {
329- System .setProperty (ConfigurationFactory .CONFIGURATION_FILE_PROPERTY , "custom-log4j2.properties" );
313+ @ ParameterizedTest
314+ @ MethodSource
315+ void configLocationsWithConfigurationFileSystemProperty (String propertyName ) {
316+ System .setProperty (propertyName , "custom-log4j2.properties" );
330317 try {
331- assertThat (this .loggingSystem .getStandardConfigLocations ()).containsExactly ("log4j2-test.properties" ,
332- "log4j2-test.xml" , "log4j2.properties" , "log4j2.xml" , "custom-log4j2.properties" );
318+ assertThat (this .loggingSystem .getStandardConfigLocations ()).containsExactly ("custom-log4j2.properties" ,
319+ "log4j2-test" + this .contextName + ".xml" , "log4j2-test.xml" , "log4j2" + this .contextName + ".xml" ,
320+ "log4j2.xml" );
333321 }
334322 finally {
335- System .clearProperty (ConfigurationFactory . CONFIGURATION_FILE_PROPERTY );
323+ System .clearProperty (propertyName );
336324 }
337325 }
338326
327+ static Stream <Arguments > standardConfigLocations () {
328+ // For each configuration file format we make "available" to the
329+ // Log4j2LoggingSystem:
330+ // - The Log4j Core `ConfigurationFactory` class
331+ // - The tree parser used internally by that configuration factory
332+ return Stream .of (
333+ // No classes, only XML
334+ Arguments .of (Collections .emptyList (), List .of (".xml" )),
335+ // Log4j Core 2
336+ Arguments .of (List .of (JsonConfigurationFactory .class .getName (), ObjectMapper .class .getName ()),
337+ List .of (".json" , ".jsn" , ".xml" )),
338+ Arguments .of (List .of (PropertiesConfigurationFactory .class .getName (),
339+ PropertiesConfigurationBuilder .class .getName ()), List .of (".properties" , ".xml" )),
340+ Arguments .of (List .of (YamlConfigurationFactory .class .getName (),
341+ "com.fasterxml.jackson.dataformat.yaml.YAMLMapper" ), List .of (".yaml" , ".yml" , ".xml" )),
342+ Arguments .of (List .of (JsonConfigurationFactory .class .getName (), ObjectMapper .class .getName (),
343+ PropertiesConfigurationFactory .class .getName (), PropertiesConfigurationBuilder .class .getName (),
344+ YamlConfigurationFactory .class .getName (), "com.fasterxml.jackson.dataformat.yaml.YAMLMapper" ),
345+ List .of (".properties" , ".yaml" , ".yml" , ".json" , ".jsn" , ".xml" )),
346+ // Log4j Core 3
347+ Arguments .of (List .of (JsonConfigurationFactory .class .getName (),
348+ "org.apache.logging.log4j.kit.json.JsonReader" ), List .of (".json" , ".jsn" , ".xml" )),
349+ Arguments .of (List .of ("org.apache.logging.log4j.config.properties.JavaPropsConfigurationFactory" ,
350+ "tools.jackson.dataformat.javaprop.JavaPropsMapper" ), List .of (".properties" , ".xml" )),
351+ Arguments .of (List .of ("org.apache.logging.log4j.config.yaml.YamlConfigurationFactory" ,
352+ "tools.jackson.dataformat.yaml.YAMLMapper" ), List .of (".yaml" , ".yml" , ".xml" )),
353+ Arguments .of (
354+ List .of (JsonConfigurationFactory .class .getName (),
355+ "org.apache.logging.log4j.kit.json.JsonReader" ,
356+ "org.apache.logging.log4j.config.properties.JavaPropsConfigurationFactory" ,
357+ "tools.jackson.dataformat.javaprop.JavaPropsMapper" ,
358+ "org.apache.logging.log4j.config.yaml.YamlConfigurationFactory" ,
359+ "tools.jackson.dataformat.yaml.YAMLMapper" ),
360+ List .of (".properties" , ".yaml" , ".yml" , ".json" , ".jsn" , ".xml" )));
361+ }
362+
363+ @ ParameterizedTest
364+ @ MethodSource
365+ void standardConfigLocations (List <String > availableClasses , List <String > expectedSuffixes ) {
366+ this .loggingSystem .availableClasses (availableClasses .toArray (new String [0 ]));
367+ String [] locations = this .loggingSystem .getStandardConfigLocations ();
368+ assertThat (locations ).hasSize (4 * expectedSuffixes .size ());
369+ List <String > expected = new ArrayList <>();
370+ expectedSuffixes .forEach ((s ) -> expected .add ("log4j2-test" + this .contextName + s ));
371+ expectedSuffixes .forEach ((s ) -> expected .add ("log4j2-test" + s ));
372+ expectedSuffixes .forEach ((s ) -> expected .add ("log4j2" + this .contextName + s ));
373+ expectedSuffixes .forEach ((s ) -> expected .add ("log4j2" + s ));
374+ assertThat (locations ).containsExactlyElementsOf (expected );
375+ }
376+
339377 @ Test
340378 void springConfigLocations () {
341379 String [] locations = getSpringConfigLocations (this .loggingSystem );
342- assertThat (locations ).containsExactly ("log4j2-test-spring.properties" , "log4j2-test -spring.xml" ,
343- "log4j2-spring.properties " , "log4j2-spring.xml" );
380+ assertThat (locations ).containsExactly ("log4j2-test" + this . contextName + " -spring.xml" ,
381+ "log4j2-test- spring.xml" , "log4j2" + this . contextName + "-spring.xml " , "log4j2-spring.xml" );
344382 }
345383
346384 @ Test
0 commit comments