Skip to content

fix(logging): route Tomcat JULI/catalina logs to console + dotcms.log in container (#36075)#36076

Open
wezell wants to merge 4 commits into
mainfrom
issue-36075-catalina-logs-to-console
Open

fix(logging): route Tomcat JULI/catalina logs to console + dotcms.log in container (#36075)#36076
wezell wants to merge 4 commits into
mainfrom
issue-36075-catalina-logs-to-console

Conversation

@wezell

@wezell wezell commented Jun 9, 2026

Copy link
Copy Markdown
Member

Proposed Changes

Fixes #36075

In the container, only dotCMS application logs (log4j2) reached the container log stream. Tomcat's internal java.util.logging (JULI / "catalina") logs — org.apache.catalina.*, org.apache.coyote.* — went to a separate catalina.<date>.log and did not surface in docker logs / kubectl logs.

This PR bridges raw java.util.logging into log4j2 via log4j-jul's Log4jBridgeHandler, so everything except access logs is unified to console (stdout) + dotcms.log.

What changed

  • bom/logging/pom.xml — add managed log4j-jul dependency (${log4j.version} = 2.23.1).
  • dotCMS/pom.xml — declare log4j-jul (provided) and copy its jar into the Tomcat log4j2/lib folder (already on the JVM classpath via setenv.sh).
  • OVERRIDE/.../tomcat/conf/logging.properties — replace the JULI AsyncFileHandler (catalina.<date>.log) + ConsoleHandler with org.apache.logging.log4j.jul.Log4jBridgeHandler.

Why this approach

  • log4j-appserver's TomcatLogger (already bundled) only routes the org.apache.juli.logging.Log facade. Code logging directly via java.util.logging was unbridged — this adds that bridge.
  • Log4jBridgeHandler is the least-invasive option: it keeps Tomcat's ClassLoaderLogManager and avoids any -Djava.util.logging.manager JVM-arg ordering risk vs catalina.sh.
  • A single shared log4j2 context (BasicAsyncLoggerContextSelector, set in setenv.sh) means anything reaching log4j2 lands in the existing Console (stdout) + dotcms.log appenders.

Access logs unchanged

Tomcat's AccessLogValve writes its own file and bypasses both JULI and the juli facade, so access logs remain a separate file by design.

Testing / Verification

Built the arm64 image and ran it against Postgres; observed all four acceptance criteria:

  • ✅ Tomcat-internal catalina logs now on container stdout (log4j2 console format):
    14:00:58.573  INFO  startup.VersionLoggerListener - Server version name: Apache Tomcat/9.0.118
    14:00:58.667  INFO  http11.Http11Nio2Protocol - Initializing ProtocolHandler ["http-nio2-8080"]
    14:00:58.800  INFO  core.StandardEngine - Starting Servlet engine: [Apache Tomcat/9.0.118]
    
  • ✅ Same catalina logs also present in dotcms.log (81 Tomcat-internal lines).
  • No catalina.<date>.log file produced.
  • ✅ Access log remains separate (dotcms_access.<date>.log).

🤖 Generated with Claude Code

… in container (#36075)

In the container, only dotCMS application logs (log4j2) reached the container
log stream; Tomcat's internal java.util.logging (JULI / catalina) logs went to
a separate catalina.<date>.log and did not surface.

Bridge raw java.util.logging into log4j2 via log4j-jul's Log4jBridgeHandler so
everything except access logs is unified to console (stdout) + dotcms.log:

- bom/logging/pom.xml: add managed log4j-jul dependency.
- dotCMS/pom.xml: declare log4j-jul (provided) and copy its jar into the
  Tomcat log4j2/lib folder (already on the JVM classpath via setenv.sh).
- OVERRIDE tomcat/conf/logging.properties: replace the AsyncFileHandler
  (catalina.<date>.log) and ConsoleHandler with Log4jBridgeHandler.

Access logs (AccessLogValve) bypass JULI and remain a separate file by design.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@claude

claude Bot commented Jun 9, 2026

Copy link
Copy Markdown
Contributor

Claude finished @wezell's task in 58s —— View job


Rollback Safety Analysis

  • Read rollback-unsafe categories reference
  • Get full PR diff
  • Analyze diff against all unsafe categories
  • Apply appropriate label

Result: ✅ Safe To Rollback

This PR makes no changes to any rollback-unsafe category. All three changed files are pure logging/build infrastructure:

File Change Unsafe Category?
bom/logging/pom.xml Adds log4j-jul managed dependency None
dotCMS/pom.xml Declares log4j-jul dependency + copies jar to Tomcat lib folder None
dotCMS/src/main/docker/original/ROOT/srv/OVERRIDE/tomcat/conf/logging.properties Replaces AsyncFileHandler/ConsoleHandler with Log4jBridgeHandler None

Categories checked:

  • 🔴 C-1 Structural Data Model Change — No DB schema changes
  • 🔴 C-2 Elasticsearch Mapping Change — No ES mapping changes
  • 🔴 C-3 Content JSON Model Version Bump — No CURRENT_MODEL_VERSION changes
  • 🔴 C-4 DROP TABLE/Column — No DDL changes
  • 🟠 H-1 One-Way Data Migration — No data transformation
  • 🟠 H-2 RENAME TABLE/COLUMN — No renames
  • 🟠 H-3 PK Restructuring — No PK changes
  • 🟠 H-4 New ContentType Field Type — No field type changes
  • 🟠 H-5 Binary Storage Provider Change — No storage changes
  • 🟠 H-6 DROP PROCEDURE/FUNCTION — No stored procedure changes
  • 🟠 H-7 NOT NULL Column Without Default — No schema changes
  • 🟠 H-8 VTL Viewtool Contract Change — No viewtool changes
  • 🟡 M-1 Column Type Change — None
  • 🟡 M-2 Push Publishing Bundle Format — None
  • 🟡 M-3 REST/GraphQL API Contract — None
  • 🟡 M-4 OSGi Plugin API — None

Rolling back from this release to the previous one would simply revert to the previous logging behavior (Tomcat JULI logs going to catalina.<date>.log instead of stdout/dotcms.log). No data, schema, or API state is affected.

Label AI: Safe To Rollback has been applied.

The jar lives on Tomcat's classpath, not the webapp classpath, so
provided is the correct scope. Using runtime caused double-loading in
modules that inherit the BOM without overriding the scope themselves.

https://claude.ai/code/session_0137tNu61fbsugvh9KxeQLkB
@github-actions

github-actions Bot commented Jun 24, 2026

Copy link
Copy Markdown
Contributor

🤖 Bedrock Review — qwen.qwen3-next-80b-a3b

#### New Issues
- 🔴 Critical: `dotCMS/pom.xml:1460-1465` — `log4j-jul` dependency added to `dotCMS/pom.xml` instead of `bom/application/pom.xml`; violates dotCMS convention that dependency versions must be managed only in `bom/application/pom.xml`
- 🔴 Critical: `dotCMS/src/main/docker/original/ROOT/srv/OVERRIDE/tomcat/conf/logging.properties:1,3` — `handlers` and `.handlers` now use `org.apache.logging.log4j.jul.Log4jBridgeHandler` without setting `-Djava.util.logging.manager=org.apache.logging.log4j.jul.LogManager`; this will cause `ClassNotFoundException` at Tomcat startup because JULI will not delegate to Log4j2 without the system property

#### Existing
- 🟡 Medium: `dotCMS/src/main/docker/original/ROOT/srv/OVERRIDE/tomcat/conf/logging.properties` — Prior finding still present: system property `-Djava.util.logging.manager=org.apache.logging.log4j.jul.LogManager` is still not set anywhere in the diff; required for Log4j2 JUL bridge to function

#### Resolved
- ✅ `dotCMS/pom.xml:1459-1465` — Previously flagged `log4j-jul` in `dotCMS/pom.xml` is now duplicated in `bom/logging/pom.xml`, but the core violation (wrong BOM location) remains — so this is not resolved, but the prior finding is still valid and now has a new instance

<!-- dotcms-review-findings:[{"sev":"🔴 Critical","loc":"dotCMS/pom.xml:1460-1465","desc":"log4j-jul dependency added to dotCMS/pom.xml instead of bom/application/pom.xml, violating version management convention"},{"sev":"🔴 Critical","loc":"dotCMS/src/main/docker/original/ROOT/srv/OVERRIDE/tomcat/conf/logging.properties:1,3","desc":"Log4jBridgeHandler configured without -Djava.util.logging.manager system property, causing ClassNotFound at startup"},{"sev":"🟡 Medium","loc":"dotCMS/src/main/docker/original/ROOT/srv/OVERRIDE/tomcat/conf/logging.properties","desc":"-Djava.util.logging.manager=org.apache.logging.log4j.jul.LogManager system property still not set anywhere in the PR"}] -->

Run: #28067995066 · tokens: in: 2204 · out: 512 · total: 2716

@github-actions

github-actions Bot commented Jun 26, 2026

Copy link
Copy Markdown
Contributor

🤖 dotBot Review (Bedrock)

Reviewed 3 file(s); 0 candidate(s) → 0 confirmed, 0 uncertain (unverified, kept for review).

✅ No issues found after verification.


us.deepseek.r1-v1:0 · Run: #28270496261 · tokens: in: 11890 · out: 2876 · total: 14766 · calls: 4 · est. ~$0.032

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

AI: Safe To Rollback Area : Backend PR changes Java/Maven backend code

Projects

Status: No status

Development

Successfully merging this pull request may close these issues.

Tomcat/catalina (JULI) logs do not reach container stdout — only dotCMS app logs are visible in container logs

2 participants