Apereo CAS - Externalized Log4j2 Configuration via Spring Boot

Posted by Misagh Moayyed on October 04, 2024 · 6 mins read ·
Content Unavailable
Your browser is blocking content on this website. Please check your browser settings and try again.

The primary logging technology and framework in Apereo CAS deployments is backed by Apache Log4j. This is a versatile, industrial-grade logging framework composed of an API, its implementation, and components to assist CAS deployments for many advanced use cases. The main log configuration file presents itself as a log4j2.xml file that contains various elements that control how data is captured and at which level, where that data is sent and how it’s transformed etc.

In this post, we’ll take a look at how configuration settings and properties found in the log4j2.xml file can be externalized using a Spring-managed Environment. Our starting position is based on:

Spring’s Environment

In a CAS deployment, all application settings are managed and loaded via Spring Boot using PropertySource components. Such settings can come from anywhere, really, and are most often housed inside a flat cas.properties file commonly found at /etc/cas/config. This file, among many other things, could for example, control the location of the logging configuration file:

logging.config=file:/etc/cas/config/log4j2.xml

Regardless of where configuration properties are and their owner or source, all settings eventually are packaged inside a Spring container called the Environment. This is the main entry point for an application such as CAS to figure out what settings are loaded and how they may be fed into various other components. For example, you can ask the Environment to tell you the value assigned to the logging.config configuration key:

var config = environment.getProperty("logging.config");

What we want here is the ability to use the same construct when configuring settings inside the log4j2.xml file.

Logging Configuration

Elements defined in the log4j2.xml file can be tweaked and adjusted using a variety of settings. For example, you may want to control the logging level of a particular namespace:

<Logger name="org.apereo.cas" level="info" />

If you want to refer to properties from the Spring Environment, you can use spring: prefixed lookups. Doing so can be useful if you want to access values from the cas.properties file or any other configuration source in the Log4j2 configuration. For example, let’s imagine that we have the following property defined in cas.properties:

my.log.level=warn

To reference this setting in the logging configuration file, we can use:

<Logger name="org.apereo.cas" level="${spring:my.log.level}" />

This construct works with any and all other settings whose value can be derived from an existing configuration key in the Spring Environment. Remember that the lookup key, such as my.property-name, should be specified in the kebab case when needed.

Framework Support

Log4j’s Lookup support for Spring and Spring Boot is, in fact, offered out of the box by Spring Boot, and there is no other change to make or dependency to include. However, this was not always the case. To be exact, CAS versions that rely on Spring Boot 2.x do require the external dependency org.apache.logging.log4j:log4j-spring-boot, and this, unfortunately, ships by default with newer CAS versions. If your CAS version is based on Spring Boot 3.x, such as any version of CAS 7.x and beyond, you need to make sure to remove and exclude this dependency from your Gradle build.

Note that while this may work as is even with the external dependency included, not doing so could cause a conflict between the external dependency and what ships now out of the box. The org.apache.logging.log4j:log4j-spring-boot will be eventually removed from newer CAS releases or upcoming patch releases that are still in maintenance and rely on Spring Boot 3.x.

Need Help?

If you have questions about the contents and the topic of this blog post, or if you need additional guidance and support, feel free to send us a note and ask about consulting and support services.

Finale

I hope this review was of some help to you and I am sure that both this post as well as the functionality it attempts to explain can be improved in any number of ways. Please feel free to engage and contribute as best as you can.

Misagh Moayyed