Dynamic Logging in dotCMS: Enhancing Runtime Flexibility

Dynamic Logging in dotCMS: Enhancing Runtime Flexibility
Author image

Jonathan Sanchez

Software Architect

Share this article on:

Introduction

Logging is an integral part of any enterprise-grade platform, and dotCMS is no exception. It provides a powerful logging mechanism that helps developers and administrators monitor, debug, and maintain applications. Traditionally, logging levels in dotCMS were configured using the log4j2.xml file before the server started (See official documentation). However, in dynamic and high-demand environments, where issues need to be diagnosed in real time, the inability to modify logging levels without restarting the server could lead to delays, downtime, and inefficiencies.

To address this, dotCMS introduced the capability to dynamically change logging levels at runtime using a REST API. This innovative feature allows administrators and developers to adjust logging levels on the fly, enabling more efficient debugging and monitoring without disrupting application availability.

Motivation

The ability to change logging levels dynamically is critical in modern, agile environments where:

  1. Downtime is Unacceptable: Restarting the server to change a logging level can lead to service disruptions, impacting business operations and user experiences.

  2. Real-Time Debugging is Crucial: Diagnosing and resolving issues in production environments often requires switching logging levels to DEBUG or TRACE without delay.

  3. Efficient Issue Resolution: Dynamic logging reduces the time required to reproduce and troubleshoot problems by allowing focused logging at the class or package level.

  4. Operational Flexibility: This feature empowers administrators to fine-tune logging granularity as needed, making it easier to identify and address specific issues without overwhelming logs with unnecessary data.

How to Dynamically Change Logging Levels in dotCMS

Step 1: Retrieve the Current Loggers

To identify the currently registered loggers and their levels, you can use the provided REST API. This helps you locate the specific logger you want to modify.

Command:

curl --location --request GET 'http://localhost:8080/api/v1/logger'

Example Response:

{

   "entity": [

       {

           "level": "INFO",

           "name": "org.apache.felix.framework.OSGIUtil"

       },

       {

           "level": "INFO",

           "name": "com.dotcms.cluster.business.ServerAPIImpl"

       },

       {

           "level": "INFO",

           "name": "com.dotcms.enterprise.rules.g"

       }

   ]

}

  • The response contains all the loggers currently active in dotCMS, including their logging levels and class names.

Step 2: Update the Logging Level for a Specific Logger

Once you identify the logger you want to modify, you can use a PUT request to update its logging level dynamically. For example, to set the logging level of com.dotmarketing.common.db.DotConnect to DEBUG:

Command:

curl --location --request PUT 'http://localhost:8080/api/v1/logger/' \

--header 'Content-Type: application/json' \

--data-raw '{

       "level": "DEBUG",

       "name": "com.dotmarketing.common.db.DotConnect"

}'

Explanation:

  • level: Specifies the desired logging level (DEBUG, INFO, WARN, etc.).

  • name: Specifies the class or package name whose logging level you want to modify.

Effect:

  • The specified logger’s level is updated in real time, and any subsequent log messages from this class will follow the new level.

  • Note 1: Changes made using this API are runtime-only and will not persist after a server restart.

  • Note 2: Depending on the version, the changes will be cluster-wide, which means the change made in one node will be propagated to all of them.

Step 3: Best Practices for Logger Usage

When writing logs in dotCMS, it is recommended to use string-based logger references instead of directly referencing classes. This ensures compatibility with dynamic logging.

Example:

Logger.debug("com.dotmarketing.common.db.DotConnect", () -> "Executing a SQL command");

Why Use Strings?

  • In OSGi environments, classpaths are often encapsulated, and using class references directly may lead to logger unavailability.

  • By using a string-based logger, the logger will always be registered and accessible in the dotCMS logging system, enabling dynamic changes using the API.

Conclusion

The introduction of dynamic logging in dotCMS significantly enhances operational flexibility and efficiency. By allowing administrators to modify logging levels at runtime without requiring a server restart, dotCMS enables real-time debugging and reduces downtime. This feature is particularly beneficial in production environments, where responsiveness and agility are critical.

To leverage this capability effectively, it’s essential to follow best practices, such as using string-based loggers and familiarizing yourself with the logging API. With these tools, dotCMS empowers teams to maintain robust logging practices while adapting dynamically to the challenges of modern application development and operations.