Wikantik Logging Configuration Guide

Understanding `jspwiki.use.external.logconfig`

The Logging Stack

Your Wikantik 3.0.2 uses this logging architecture:

```

Application Code → SLF4J API → log4j-slf4j-impl → Log4j2 Core

log4j-1.2-api (legacy bridge)

```

The JARs in your `/opt/tomcat/webapps/ROOT/WEB-INF/lib/`:

- `slf4j-api-2.0.17.jar` - Facade API

- `log4j-slf4j-impl-2.25.2.jar` - Routes SLF4J to Log4j2

- `log4j-api-2.25.2.jar` - Log4j2 API

- `log4j-core-2.25.2.jar` - Log4j2 implementation

- `log4j-1.2-api-2.25.2.jar` - Bridges old Log4j 1.x calls

How `jspwiki.use.external.logconfig` Works

When Wikantik starts, `WikiBootstrapServletContextListener.initWikiLoggingFramework()` reads this property:

**When `false` (default):**

1. Wikantik reads all properties from `wikantik.properties` / `wikantik-custom.properties`

2. It filters properties starting with: `appender`, `logger`, `rootLogger`, `filter`, `status`, `dest`, `name`, `properties`, `property`, or `log4j2`

3. These are fed into Log4j2's `PropertiesConfigurationFactory`

4. Log4j2 is reconfigured programmatically

**When `true`:**

1. Wikantik does nothing with logging configuration

2. Log4j2 uses its standard automatic configuration mechanism

3. It searches the classpath for: `log4j2-test.xml`, `log4j2.xml`, `log4j2.properties`

4. Or you can specify `-Dlog4j2.configurationFile=/path/to/config.xml`

---

External XML Configuration Setup

Use a separate `log4j2.xml` file with full Log4j2 capabilities.

Step 1: Set in wikantik-custom.properties

```properties

jspwiki.use.external.logconfig = true

```

Also remove any existing broken logging lines (log4j.* properties are Log4j 1.x syntax and will be ignored).

Step 2: Create /opt/tomcat/lib/log4j2.xml

```xml

<?xml version="1.0" encoding="UTF-8"?>

<Configuration status="WARN" name="Wikantik-Production">

<Properties>

<Property name="logDir">/var/log/jspwiki</Property>

<Property name="pattern">%d{yyyy-MM-dd HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n</Property>

</Properties>

<Appenders>

<!-- Console for catalina.out -->

<Console name="Console" target="SYSTEM_OUT">

<PatternLayout pattern="%highlight{[%-5level]} %d{HH:mm:ss.SSS} [%t] %c{1.} - %msg%n"/>

</Console>

<!-- Main application log with daily rotation -->

<RollingFile name="AppLog" fileName="${logDir}/jspwiki.log" filePattern="${logDir}/jspwiki-%d{yyyy-MM-dd}-%i.log.gz">

<PatternLayout pattern="${pattern}"/>

<Policies>

<TimeBasedTriggeringPolicy interval="1"/>

<SizeBasedTriggeringPolicy size="50MB"/>

</Policies>

<DefaultRolloverStrategy max="30"/>

</RollingFile>

<!-- Security audit log -->

<RollingFile name="SecurityLog" fileName="${logDir}/security.log" filePattern="${logDir}/security-%d{yyyy-MM-dd}.log.gz">

<PatternLayout pattern="%d{ISO8601} %level %msg%n"/>

<Policies>

<TimeBasedTriggeringPolicy interval="1"/>

</Policies>

<DefaultRolloverStrategy max="90"/>

</RollingFile>

<!-- Access log for page views -->

<RollingFile name="AccessLog" fileName="${logDir}/access.log" filePattern="${logDir}/access-%d{yyyy-MM-dd}.log.gz">

<PatternLayout pattern="%d{ISO8601} %msg%n"/>

<Policies>

<TimeBasedTriggeringPolicy interval="1"/>

</Policies>

</RollingFile>

</Appenders>

<Loggers>

<!-- Wikantik core -->

<Logger name="com.wikantik" level="INFO" additivity="false">

<AppenderRef ref="Console"/>

<AppenderRef ref="AppLog"/>

</Logger>

<!-- Security events (login, logout, access denied) -->

<Logger name="SecurityLog" level="INFO" additivity="false">

<AppenderRef ref="SecurityLog"/>

</Logger>

<!-- Page access tracking via WikiServlet -->

<Logger name="com.wikantik.WikiServlet" level="INFO" additivity="false">

<AppenderRef ref="Console"/>

<AppenderRef ref="AccessLog"/>

</Logger>

<!-- Database connection issues -->

<Logger name="org.apache.tomcat.dbcp" level="WARN"/>

<!-- Lucene search indexing -->

<Logger name="com.wikantik.search" level="INFO"/>

<!-- Root: catch-all -->

<Root level="WARN">

<AppenderRef ref="Console"/>

</Root>

</Loggers>

</Configuration>

```

Step 3: Create the log directory

```bash

sudo mkdir -p /var/log/jspwiki

sudo chown tomcat:tomcat /var/log/jspwiki

```

Step 4: Restart Tomcat

```bash

sudo systemctl restart tomcat

```

Step 5: Verify

```bash

Check catalina.out for startup messages

tail -f /opt/tomcat/logs/catalina.out

Check new log files are created

ls -la /var/log/jspwiki/

```

---

Customizing the Log Directory for Different Environments

The log directory is defined in the `<Properties>` section at the top of the XML file:

```xml

<Properties>

<Property name="logDir">/var/log/jspwiki</Property> <!-- Change this path -->

<Property name="pattern">%d{yyyy-MM-dd HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n</Property>

</Properties>

```

The `logDir` property is referenced throughout the config as `${logDir}`, so changing it in one place updates all appenders:

```xml

fileName="${logDir}/jspwiki.log"

filePattern="${logDir}/jspwiki-%d{yyyy-MM-dd}-%i.log.gz"

```

Recommended Paths by Environment

| Environment | Path | Notes |

|-------------|------|-------|

| Production | `/var/log/jspwiki` | Standard Linux log location |

| Development | `/tmp/jspwiki-logs` | Easy access, cleared on reboot |

| Testing | `/opt/tomcat/logs/jspwiki` | Keeps logs with Tomcat |

| Portable | `${sys:catalina.base}/logs/jspwiki` | Relative to Tomcat install |

| Java temp | `${sys:java.io.tmpdir}/jspwiki` | Uses Java's temp directory |

Using System Property Lookups

The `${sys:...}` syntax references Java system properties, making configs portable across environments:

| Lookup | Description | Example Value |

|--------|-------------|---------------|

| `${sys:catalina.base}` | Tomcat base directory | `/opt/tomcat` |

| `${sys:catalina.home}` | Tomcat home directory | `/opt/tomcat` |

| `${sys:java.io.tmpdir}` | Java temp directory | `/tmp` |

| `${sys:user.home}` | User home directory | `/home/tomcat` |

**Example for development/testing:**

```xml

<Properties>

<Property name="logDir">${sys:catalina.base}/logs/jspwiki</Property>

<Property name="pattern">%d{yyyy-MM-dd HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n</Property>

</Properties>

```

Environment Variables

You can also use environment variables with the `${env:...}` syntax:

```xml

<Property name="logDir">${env:JSPWIKI_LOG_DIR:-/var/log/jspwiki}</Property>

```

This uses `$JSPWIKI_LOG_DIR` if set, otherwise falls back to `/var/log/jspwiki`.

Important Reminders

1. **Permissions**: Ensure the `tomcat` user has write permission to the chosen directory

2. **Create directory**: The directory must exist before Tomcat starts (Log4j2 won't create parent directories)

3. **Disk space**: Choose a location with adequate space for log rotation

```bash

Example setup for testing environment

sudo mkdir -p /opt/tomcat/logs/jspwiki

sudo chown tomcat:tomcat /opt/tomcat/logs/jspwiki

```

---

Log4j2 Configuration Reference

Log Levels (in order of severity)

| Level | Description |

|-------|-------------|

| TRACE | Finest-grained debug information |

| DEBUG | Detailed debug information |

| INFO | General operational messages |

| WARN | Warning conditions |

| ERROR | Error conditions |

| FATAL | Critical errors causing shutdown |

Common Pattern Layout Tokens

| Token | Description |

|-------|-------------|

| `%d{pattern}` | Date/time with specified format |

| `%t` | Thread name |

| `%p` or `%level` | Log level |

| `%c{n}` | Logger name (n = precision) |

| `%C{n}` | Class name |

| `%M` | Method name |

| `%L` | Line number |

| `%m` or `%msg` | Log message |

| `%n` | Newline |

| `%x` | Thread context (NDC) |

| `%X{key}` | Thread context map (MDC) value |

| `%highlight{pattern}` | ANSI color highlighting |

Useful Wikantik Logger Names

| Logger | Purpose |

|--------|---------|

| `com.wikantik` | All Wikantik classes |

| `com.wikantik.WikiServlet` | Page request handling |

| `com.wikantik.auth` | Authentication/authorization |

| `com.wikantik.search` | Lucene search indexing |

| `com.wikantik.providers` | Page/attachment providers |

| `SecurityLog` | Security audit events |

| `SpamLog` | Spam filter events |

---

Advanced Features

Hot Reload Configuration

Add `monitorInterval` to automatically reload config changes:

```xml

<Configuration status="WARN" monitorInterval="30">

```

Async Logging (Performance)

Wrap appenders for non-blocking logging:

```xml

<Appenders>

<RollingFile name="AppLogFile" .../>

<Async name="AppLog">

<AppenderRef ref="AppLogFile"/>

</Async>

</Appenders>

```

Syslog Appender (Centralized Logging)

```xml

<Syslog name="Syslog"

host="logserver.example.com"

port="514"

protocol="UDP"

facility="LOCAL0"

appName="jspwiki"/>

```

Filter Sensitive Data

```xml

<RollingFile name="AppLog" ...>

<RegexFilter regex=".*password.*" onMatch="DENY" onMismatch="ACCEPT"/>

<PatternLayout .../>

</RollingFile>

```

---

Sources

- [Wikantik Releases - Log4j2 configuration notes](https://github.com/apache/jspwiki/releases)

- [Wikantik Dockerfile - External log config setup](https://github.com/apache/jspwiki/blob/master/Dockerfile)

- [Log4j2 Configuration Manual](https://logging.apache.org/log4j/2.x/manual/configuration.html)

- [External Log4j2 Configuration](https://gangmax.me/blog/2024/11/15/use-external-log4j2-configuration-file/)

- [Wikantik wikantik.properties defaults](https://github.com/apache/jspwiki/blob/master/wikantik-main/src/main/resources/ini/wikantik.properties)