Skip to content

DSpace9.3/fix(logging): write dspace.log inside the container again (port of #1392) - #1410

Merged
Kasinhou merged 1 commit into
dtq-dev-9-basefrom
ufal/port-1392-dspace-log-9-base
Aug 11, 2026
Merged

DSpace9.3/fix(logging): write dspace.log inside the container again (port of #1392)#1410
Kasinhou merged 1 commit into
dtq-dev-9-basefrom
ufal/port-1392-dspace-log-9-base

Conversation

@Kasinhou

Copy link
Copy Markdown

Port of #1392 (MENDELU/fix-dspace-log-to-file, merged to customer/mendelu) to dtq-dev-9-base.

Problem

Everything the backend logs comes out as container stdout, and [dspace.dir]/log/dspace.log is never created. Anything that expects dspace.log — support tickets, grep-based debugging, log shipping, the reflex of every DSpace admin — has nothing to read.

This is not theoretical on this branch. Diagnosing a live CLARIN 9.3 issue on dev-6 (dspace8603) hit exactly this wall:

$ docker exec dspace8603 sh -c "ls -la /dspace/log/"
checker.log
dspace-cli.log
dspace-cli.log-2026-07-20 … dspace-cli.log-2026-08-10
handle-server.log
        ← no dspace.log

The code under investigation (SpecialItemService.getUploadedMetadata()) swallows exceptions into a log.error(e) and returns an empty document, so the failure is only visible in the log — and the log was not where anyone would look for it.

Cause

The container is started with

LOGGING_CONFIG: ${LOGGING_CONFIG:-/dspace/config/log4j2-container.xml}

(docker/docker-compose-rest.yml:54 in the dtq-dev-9-base frontend stack, and docker-compose-ci.yml:35). Spring Boot maps LOGGING_CONFIGlogging.config and hands that file to Log4j2.

log4j2-container.xml is console-only by design upstream — its own header says "matches log4j2.xml but to console, removing file refs & most comments", and both of its appenders are type='Console'. The file destination is not misconfigured; it simply does not exist in that config. Note this is only the Spring Boot webapp: log4j2-cli.xml is untouched and already writes dspace-cli.log / checker.log, which is exactly why /dspace/log exists in the container but has no dspace.log in it.

Fix

log4j2-container.xml now carries the same RollingFile appender that log4j2.xml uses on this branch, and echoes the same events to stdout through a separate appender, so docker logs dspace8603 keeps working exactly as it does today.

before after
/dspace/log/dspace.log never created full log, daily rollover
docker logs dspace8603 full log same, tunable via env
log levels / checker appender unchanged

Two knobs, both optional and both defaulting to current behaviour:

  • DSPACE_LOG_DIR — log directory, default /dspace/log. That is where dspace.dir points in the image (Dockerfile: ENV dspace__P__dir=/dspace), so the default is correct as shipped.
  • DSPACE_LOG_CONSOLE_LEVEL — level of the stdout copy, default INFO. Set it to WARN or OFF to stop duplicating everything into the Docker json-file log once dspace.log is being collected. dspace.log always receives everything regardless.

Log levels, the checksum-checker appender and the blocked org.dspace.* loggers are deliberately left alone.

Adapted from #1392 for this branch

One deliberate difference. #1392 rolls over to dspace.log-yyyy-MM-dd.gz; this branch's own dspace/config/log4j2.xml rolls over to plain dspace.log-yyyy-MM-dd:

<!-- dspace/config/log4j2.xml on dtq-dev-9-base -->
filePattern="${log.dir}/dspace.log-%d{yyyy-MM-dd}"

Since the whole point is parity with log4j2.xml, the .gz suffix is dropped here and the commented-out sample deletion policy glob was adjusted to match (dspace.log-*). The existing dspace-cli.log-* files in the container are uncompressed too, so this is also consistent with what is already on disk.

Everything else is identical to #1392.

Verified on this branch

  • log4j.version is 2.25.4 in pom.xml — the same version MENDELU/fix(logging): write dspace.log inside the container again #1392 was verified against, so its testing carries over.
  • Dockerfile sets ENV dspace__P__dir=/dspace, so the /dspace/log default resolves correctly as shipped.
  • docker/docker-compose-rest.yml:54 does set LOGGING_CONFIG to this file, so the change takes effect on this stack rather than being inert.
  • The baseline log4j2-container.xml is byte-identical on dtq-dev and dtq-dev-9-base, so the port applies to the same starting point MENDELU/fix(logging): write dspace.log inside the container again #1392 patched.
  • The config is well-formed and parses; the three appenders resolve as A1:RollingFile, STDOUT:Console, A2:Console, with fileName=${log.dir}/dspace.log and filePattern=${log.dir}/dspace.log-%d{yyyy-MM-dd}. Worth stating explicitly because this file is strict='true' — a parse failure would silently fall back to a default console config.

Follow-up (required for this to be useful beyond the current container)

/dspace/log is still in the container's writable layer, so dspace.log is wiped on every recreate — i.e. exactly when you redeploy after an incident. Making it outlive the container needs a volume in the frontend stack's compose for this instance; that is out of scope here. This PR is correct and safe on its own, it just cannot make the file persistent by itself.

Also worth checking after merge: if the deploy overlay on dev-6 (/opt/dspace-envs/8603/docker-compose-rest.yml) pins LOGGING_CONFIG to something else, it wins over the compose default and this change will have no effect there.

Port of #1392 (MENDELU/fix-dspace-log-to-file, merged to customer/mendelu)
to dtq-dev-9-base.

Everything the backend logs comes out as container stdout only, and
[dspace.dir]/log/dspace.log is never created. log4j2-container.xml is
console-only by design upstream -- its header says "matches log4j2.xml but
to console, removing file refs" and both appenders are type='Console'.
log4j2-cli.xml is untouched and already writes dspace-cli.log/checker.log,
which is why /dspace/log exists in the container but holds no dspace.log.

A1 becomes the same RollingFile appender log4j2.xml uses on this branch,
and a separate STDOUT appender echoes the same events to the console so
"docker logs" keeps working unchanged.

Adapted from #1392 for this branch: filePattern has no ".gz" suffix, to
match dspace/config/log4j2.xml here, which rolls over to plain
dspace.log-yyyy-MM-dd. The commented-out sample deletion policy glob was
adjusted to match.

Two optional knobs, both defaulting to current behaviour:
- DSPACE_LOG_DIR             log directory, default /dspace/log
- DSPACE_LOG_CONSOLE_LEVEL   level of the stdout copy, default INFO

Log levels, the checksum-checker appender and the blocked org.dspace.*
loggers are left alone.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@Kasinhou
Kasinhou requested a lite review from Copilot August 11, 2026 14:20
@Kasinhou Kasinhou self-assigned this Aug 11, 2026
@Kasinhou
Kasinhou requested a review from jr-rk August 11, 2026 14:20

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Restores file-based logging inside the container by updating the container-specific Log4j2 configuration to write dspace.log (with daily rollover) while still mirroring logs to container stdout for docker logs compatibility.

Changes:

  • Add a RollingFile appender to log4j2-container.xml to create/write ${log.dir}/dspace.log with daily rollover.
  • Add a separate STDOUT console appender with a configurable threshold (DSPACE_LOG_CONSOLE_LEVEL) to control verbosity of mirrored container output.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread dspace/config/log4j2-container.xml
@Kasinhou
Kasinhou merged commit 2a1b41b into dtq-dev-9-base Aug 11, 2026
14 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants