# DD Poker Logging Framework: Apache Log4j 2 Configuration and Setup

> Learn how to configure Apache Log4j 2 for DD Poker. Discover centralized logging with the LoggingConfig class and property file overrides.

- Repository: [Doug Donohoe/ddpoker](https://github.com/dougdonohoe/ddpoker)
- Tags: how-to-guide
- Published: 2026-02-28

---

**DD Poker uses Apache Log4j 2 version 2.25.3, which is configured through the centralized `LoggingConfig` class that selects type-specific property files and merges them according to a strict override hierarchy.**

The DD Poker open-source codebase implements a sophisticated logging architecture centered on Apache Log4j 2. Understanding how this logging framework is configured requires examining the bootstrap process in [`LoggingConfig.java`](https://github.com/dougdonohoe/ddpoker/blob/main/LoggingConfig.java) and its hierarchical property resolution strategy that supports multiple application types.

## Apache Log4j 2 Version and Dependencies

DD Poker declares its logging framework dependency in the root Maven POM at [`code/pom.xml`](https://github.com/dougdonohoe/ddpoker/blob/main/code/pom.xml) using the property `log4j2.version` set to **2.25.3**. All Java classes throughout the codebase import from `org.apache.logging.log4j.*` to obtain `Logger` and `LogManager` instances.

## The LoggingConfig Initialization Flow

The framework initialization is orchestrated by `com.donohoedigital.config.LoggingConfig`, located at [`code/common/src/main/java/com/donohoedigital/config/LoggingConfig.java`](https://github.com/dougdonohoe/ddpoker/blob/main/code/common/src/main/java/com/donohoedigital/config/LoggingConfig.java). When an application starts, it instantiates `LoggingConfig` with an application name and `ApplicationType` enum value (CLIENT, WEBAPP, SERVER, or CMDLINE), then invokes the `init()` method.

### Application Type Selection

The `init()` method first selects the base configuration file based on the `ApplicationType` passed to the constructor. It looks for `log4j2.client.properties`, `log4j2.webapp.properties`, `log4j2.server.properties`, or `log4j2.cmdline.properties` accordingly.

### Configuration File Resolution Hierarchy

The system looks for overrides in descending order of precedence:

1. **User-specific overrides**: `config/override/<username>.log4j2.properties` or `config/override/<username>.<type>.properties`
2. **Application-specific files**: `config/<appName>/<type>.properties`
3. **Default type-specific files**: `config/common/<type>.properties`
4. **Classpath fallback**: Generic `log4j2.properties`
5. **Basic console**: Default console configuration if no files are found

All discovered property files are merged into a single `PropertiesConfiguration` before initialization.

### System Property Injection and Directory Setup

Before re-initializing Log4j 2, the `init()` method creates the log directory at `<runtime-home>/log` and sets system properties that the property files reference:
- `log4j-logfile`
- `log4j-logpath`
- `log4j-appname`
- `log4j-username`
- `log4j-hostname`
- `log4j-start`

### Framework Initialization

Finally, the method invokes `Configurator.initialize(...)` to re-initialize Log4j 2 with the merged configuration and logs a startup message indicating which configuration files were loaded.

## Configuration Hierarchy and File Locations

The default property files are stored in `code/common/src/main/resources/config/common/`, while application-specific overrides reside in paths like `code/pokerserver/src/main/resources/config/poker/`. Runtime user overrides are read from `config/override/` at execution time.

## Practical Implementation Examples

### Initializing Logging for a Server Application

```java
import com.donohoedigital.config.LoggingConfig;
import com.donohoedigital.config.ApplicationType;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

public class PokerServerMain {
    public static void main(String[] args) {
        // Initialise Log4j2 for a SERVER application named "poker"
        new LoggingConfig("poker", ApplicationType.SERVER).init();

        // From here on you can obtain loggers normally
        Logger logger = LogManager.getLogger(PokerServerMain.class);
        logger.info("Poker server started");
    }
}

```

### Using Loggers in Application Classes

```java
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

public class GameEngine {
    private static final Logger logger = LogManager.getLogger(GameEngine.class);

    public void startGame() {
        logger.debug("Starting new game");
        // game logic …
        logger.info("Game started successfully");
    }
}

```

### Creating User-Specific Configuration Overrides

To override default settings, create a file at `config/override/jdoe.log4j2.server.properties`:

```properties
logger.com.donohoedigital.games.poker.server=DEBUG
appender.chat.fileName = /tmp/custom_chat.log

```

When `LoggingConfig` runs, it detects this file and applies these overrides before loading the default server properties.

### Sample Server Configuration File

The default server configuration at `code/pokerserver/src/main/resources/config/poker/log4j2.server.properties` defines a rolling file appender for chat logs:

```properties

# poker server log4j2.properties

# Separate logger for chat server

logger.chatserver.name = com.donohoedigital.games.poker.server.ChatServer
logger.chatserver.level = DEBUG
logger.chatserver.additivity = false
logger.chatserver.appenderRef.ChatLogger.ref = ChatLogger

# Rolling file appender for chat logs

appender.chat.name = ChatLogger
appender.chat.type = RollingFile
appender.chat.fileName = ${sys:log4j-logpath}/chat.log
appender.chat.filePattern = ${sys:log4j-logpath}/chat.log.%i
appender.chat.policies.type = Policies
appender.chat.policies.size.type = SizeBasedTriggeringPolicy
appender.chat.policies.size.size = 4025KB
appender.chat.strategy.type = DefaultRolloverStrategy
appender.chat.strategy.max = 10
appender.chat.layout.type = PatternLayout
appender.chat.layout.pattern = CHAT %d{yyyy/MMM/dd kk:mm:ss.SSS} %m%n

```

## Key Source Files and Locations

- **[`code/pom.xml`](https://github.com/dougdonohoe/ddpoker/blob/main/code/pom.xml)**: Declares the Log4j 2 version (`2.25.3`) and manages dependencies.
- **[`code/common/src/main/java/com/donohoedigital/config/LoggingConfig.java`](https://github.com/dougdonohoe/ddpoker/blob/main/code/common/src/main/java/com/donohoedigital/config/LoggingConfig.java)**: Central bootstrap class that selects configuration files, sets system properties, and initializes the framework.
- **`code/common/src/main/resources/config/common/log4j2.*.properties`**: Default property templates for each `ApplicationType`.
- **`code/pokerserver/src/main/resources/config/poker/log4j2.server.properties`**: Server-specific configuration defining appenders and rolling policies.
- **`config/override/`** (runtime): Directory for user-specific configuration overrides.

## Summary

- **DD Poker uses Apache Log4j 2 version 2.25.3** as its logging framework according to the source code in [`code/pom.xml`](https://github.com/dougdonohoe/ddpoker/blob/main/code/pom.xml).
- The **`LoggingConfig`** class centralizes initialization and supports four application types: CLIENT, WEBAPP, SERVER, and CMDLINE.
- Configuration follows a **strict override hierarchy**: user-specific → application-specific → common defaults → classpath fallback.
- The system sets **six system properties** (`log4j-logpath`, `log4j-appname`, etc.) dynamically at runtime for use in property files.
- Log files are written to `<runtime-home>/log` with support for rolling file appenders and custom chat loggers as defined in the server configuration.

## Frequently Asked Questions

### What version of Log4j 2 does DD Poker use?

DD Poker uses **Apache Log4j 2 version 2.25.3**. This version is declared in the `log4j2.version` property in [`code/pom.xml`](https://github.com/dougdonohoe/ddpoker/blob/main/code/pom.xml) and imported throughout the Java codebase via `org.apache.logging.log4j.*`.

### How do I override the default logging configuration for a specific user?

Create a properties file in `config/override/<username>.log4j2.properties` or `config/override/<username>.<type>.properties` on the classpath. According to the resolution logic in [`LoggingConfig.java`](https://github.com/dougdonohoe/ddpoker/blob/main/LoggingConfig.java), these files take highest precedence and their settings are merged over the default configurations.

### What is the purpose of the ApplicationType enum in logging configuration?

The `ApplicationType` enum (CLIENT, WEBAPP, SERVER, CMDLINE) determines which base property file (`log4j2.client.properties`, etc.) the `LoggingConfig` class loads initially. This allows different logging behaviors for desktop clients versus server processes versus command-line tools.

### Where are the log files physically written at runtime?

The `LoggingConfig.init()` method creates a `log` directory at `<runtime-home>/log` and sets the `log4j-logpath` system property to this location. Appenders in the properties files reference this property (e.g., `${sys:log4j-logpath}/chat.log`) to determine output paths dynamically.