Skip to content

Stop generating logback-spring.xml by default; add opt-in Logback Configuration Forge feature#15757

Open
codeconsole wants to merge 6 commits into
apache:8.0.xfrom
codeconsole:remove-skeleton-logback-spring-xml
Open

Stop generating logback-spring.xml by default; add opt-in Logback Configuration Forge feature#15757
codeconsole wants to merge 6 commits into
apache:8.0.xfrom
codeconsole:remove-skeleton-logback-spring-xml

Conversation

@codeconsole

@codeconsole codeconsole commented Jun 23, 2026

Copy link
Copy Markdown
Contributor

Summary

Stops scaffolding grails-app/conf/logback-spring.xml into newly created Grails
applications, in both app-generation paths:

  • Profile skeleton — deletes
    grails-profiles/base/skeleton/grails-app/conf/logback-spring.xml.
  • Grails Forge — the Logback feature no longer emits a
    logback-spring.xml template; it keeps adding the grails-logging
    dependency. Removes the now-unused logback.rocker.raw template and updates
    LogbackSpec to assert the file is not generated.

Logging keeps working with zero configuration. The base profile declares
spring-boot-starter-logging (grails-profiles/base/profile.yml) and Forge adds
org.apache.grails:grails-logging (which pulls in the Boot logging starter), so
Logback and Spring Boot's own default Logback configuration are on the
classpath and apply automatically when the app supplies no config of its own.
The generated file is therefore not required — and, as shown below, it actively
works against Spring Boot 4.x conventions.

Why this file should not be created automatically

1. Spring Boot already provides a complete default configuration

When the Boot logging starter is present and no user config is found, Spring
Boot loads its bundled Logback setup from the spring-boot jar:

  • org/springframework/boot/logging/logback/base.xml — top-level wiring
  • …/defaults.xml — default levels and conversion rules
  • …/console-appender.xml — the standard console pattern (with ANSI color when
    the console supports it)
  • …/file-appender.xml — activated only when logging.file.name /
    logging.file.path is set

This is the explicit, documented "it just works with zero config" contract of
Spring Boot. Shipping a hand-written logback-spring.xml in the generated app
opts every new app out of that contract on day one and replaces a
well-maintained, version-matched default with a static file the framework must
keep in sync with Boot.

2. The file we generate degrades the out-of-the-box defaults

The generated file does three things that surprise users:

<root level="ERROR">
    <appender-ref ref="CONSOLE"/>
</root>
  • Forces the root level to ERROR. Spring Boot's default is INFO. With
    this file, a brand-new app silently swallows all WARN and INFO output —
    including framework startup warnings and the logging developers expect while
    building. This is one of the most common "why isn't my app logging anything?"
    papercuts.
  • Hard-codes the console appender's Jansi setting, overriding the ANSI
    coloring Boot enables automatically on capable terminals.
  • Is mostly commented-out boilerplate — a file-appender block and sample
    loggers (org.hibernate.SQL, org.springframework.security, …) that are all
    disabled. A freshly generated project starts life with a config file that is
    ~70% dead, commented code.

None of this is configuration a new project needs. It is configuration a new
project has to understand and undo.

3. It matches the Spring Boot 4.x convention

The modern Spring Boot convention (and what start.spring.io produces) is to
ship no logging config file at all. A generated Spring Boot 4.x app relies
on Boot's defaults and adds a logback-spring.xml only when it genuinely needs
to customize. Removing this file brings Grails app generation in line with that
convention and with what Spring/Boot developers already expect.

4. Nothing depends on the file existing

For the skeleton, the only in-repo references to
grails-app/conf/logback-spring.xml are documentation that describes it as a
place you can configure logging — not a file that must be present. profile.yml
copies the skeleton directory wholesale; it does not enumerate individual files.
For Forge, the only references were the Logback feature and its spec, both
updated here. The grails-logging dependency (and its test) is unchanged, so
the logging library is still added to generated apps.

Best practices: configuring logging in Grails 8 / Spring Boot 4.x

With this change, the recommended workflow for a new app is:

1. Do nothing — logging already works. Boot's defaults give you an INFO root
logger and a colorized console pattern with no files to manage.

2. Tune levels and patterns from application.yml (no XML required):

logging:
  level:
    root: INFO
    com.example.myapp: DEBUG          # your packages
    org.springframework.web: DEBUG    # framework packages
    org.hibernate.SQL: DEBUG          # see generated SQL
  pattern:
    console: "%d{HH:mm:ss.SSS} %-5level %logger{36} - %msg%n"
  file:
    name: logs/myapp.log              # setting this activates Boot's file appender

3. Add a config file only when properties aren't enough — custom appenders,
JSON/structured output, per-profile routing, etc. When you do, create
grails-app/conf/logback-spring.xml (the -spring variant, not plain
logback.xml), because it is processed by Boot and unlocks <springProfile>
and <springProperty>. A minimal, additive file that builds on the defaults
rather than replacing them:

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
    <!-- inherit Boot's console appender, pattern and conversion rules -->
    <include resource="org/springframework/boot/logging/logback/base.xml"/>

    <!-- environment-specific tweaks, layered on top of the defaults -->
    <springProfile name="development">
        <logger name="org.hibernate.SQL" level="DEBUG"/>
    </springProfile>
</configuration>

4. Keep environment-specific logging in <springProfile> blocks so a single
file serves dev / test / prod, driven by the active Spring profile.

The guiding principle is the Spring Boot one: start from zero config, add only
the delta you need, and build on Boot's defaults instead of overriding them.

Changes

  • Delete grails-profiles/base/skeleton/grails-app/conf/logback-spring.xml.
  • Logback Forge feature: stop adding the logback-spring.xml template; keep
    the grails-logging dependency.
  • Delete the unused logback.rocker.raw Forge template.
  • LogbackSpec: assert logback-spring.xml is not generated; the
    grails-logging dependency assertion is unchanged.

Test plan

  • grails-forge-core LogbackSpec passes: every application type still gets the
    grails-logging dependency and no longer gets grails-app/conf/logback-spring.xml.
  • Generating an app from the base profile no longer produces the file; the app
    starts and logs via Spring Boot's default Logback configuration (INFO root,
    colorized console).
  • Adding logging.level.* to application.yml adjusts levels as expected with
    no XML present.

Update: opt-in Logback Configuration Forge feature

Removing the file from the default is no longer a one-way door — this PR now also
adds a way to get it back when you actually want it.

Grails Forge gains a new, visible logging feature —
logback-config ("Logback Configuration") — that generates
grails-app/conf/logback-spring.xml on demand. Previously, searching the Forge
feature list for "log" returned No matching features; the feature is now
discoverable and selectable.

Behavior

  • Defaults are unchanged. With nothing selected, apps still get
    grails-logging (Logback via Spring Boot's logging starter) and no config
    file — Spring Boot's zero-config defaults apply, exactly as the rest of this PR
    describes.
  • Opt in for an XML config. Selecting Logback Configuration generates a
    starter logback-spring.xml for projects that prefer to manage Logback in XML.
  • It is a mutually-exclusive LoggingFeature (OneOfFeature), so selecting it
    supersedes the default Logback feature and re-declares grails-logging to keep
    Logback on the classpath. The dependency is therefore identical either way; the
    only user-visible difference is the generated file.

Implementation

  • LogbackConfig — visible OneOf LoggingFeature that adds the grails-logging
    dependency and renders the logback-spring.xml template.
  • Restores the logback.rocker.raw template (removed earlier in this PR) used to
    render the file.
  • LogbackSpec — covers feature visibility, file generation across all application
    types, and that grails-logging is declared exactly once.

Note on generated content

The opt-in feature currently reproduces the original template verbatim (root level
ERROR, hardcoded withJansi, and a Hibernate BasicBinder logger name that
changed in Hibernate 6+). It can instead emit the additive config recommended
above (keep Boot's INFO root, drop the Jansi override, build on defaults.xml)
if reviewers prefer.

Stop scaffolding grails-app/conf/logback-spring.xml into newly created
applications. The base profile already declares
spring-boot-starter-logging, so Logback and Spring Boot's default
configuration (base.xml -> defaults.xml + console-appender.xml) are on
the classpath and apply automatically when no user config is present.

A generated config file is therefore not required for logging to work,
and the one we ship overrides Boot's sensible defaults out of the gate:

* Root level is forced to ERROR, hiding WARN/INFO that Boot shows by
  default and that most apps want during development.
* It pins a CONSOLE appender with withJansi=false, opting every new app
  out of ANSI color that Boot enables automatically on capable consoles.
* Most of the file is commented-out boilerplate (file appender, sample
  loggers), which reads as clutter in a brand-new project.

This matches Spring Boot 4.x conventions: apps log correctly with zero
config, and users add grails-app/conf/logback-spring.xml only when they
need to customize. Levels and patterns remain configurable from
application.yml via logging.level.*, logging.pattern.* and
logging.file.* without any XML.
@codeconsole codeconsole force-pushed the remove-skeleton-logback-spring-xml branch from 52cc29c to 94067b6 Compare June 23, 2026 23:19
The Logback feature now only adds the grails-logging dependency and no
longer renders grails-app/conf/logback-spring.xml. grails-logging brings
spring-boot-starter-logging, so Logback and Spring Boot's default
configuration apply automatically when the generated app supplies no
config, matching Spring Boot 4.x's zero-config logging convention.

Removes the now-unused logback.rocker.raw template and updates
LogbackSpec to assert the file is not generated. The grails-logging
dependency assertion is unchanged.
@codeconsole codeconsole changed the title Remove logback-spring.xml from the app skeleton (match Spring Boot 4.x zero-config logging) Stop generating logback-spring.xml in new apps (match Spring Boot 4.x zero-config logging) Jun 23, 2026
@codeconsole

Copy link
Copy Markdown
Contributor Author

#15756

@codeconsole codeconsole requested review from jamesfredley, jdaugherty, matrei and sbglasius and removed request for jdaugherty June 24, 2026 07:11

@sbglasius sbglasius left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

This needs to be documented, both in the upgrade notes and under configuration, since this will come as a surprise to seasoned Grails developers (I would be one of them).

@jdaugherty jdaugherty left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I would be ok to stop generating, but we need to do the following:

  1. document this change in the upgrade guide
  2. add a forge feature to revert the behavior

@jamesfredley

Copy link
Copy Markdown
Contributor

Unless it can do <springProfile name="development"> somehow, I am a no on this. Environment specific logging config is an expected feature in Grails.

There were so many tickets when Logback nuked the groovy config and I don't want us back in that situation. This PR is just for application generator and we want new users to have a excellent out of the box experience.

@jamesfredley jamesfredley left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

See above

@jamesfredley

Copy link
Copy Markdown
Contributor

A quick round with AI leads me to believe the environment/spring profile specific logging is only possible via logback-spring.xml. So at a max I would only be OK stripping parts of that file that are no longer needed and are explicitly duplicative of spring default and continuing to generate a logback-spring.xml that provides the same historical environment specific logging, low default level in dev, as expected.

Adds a visible `logback-config` logging feature that generates
grails-app/conf/logback-spring.xml for projects that prefer to manage
their Logback configuration in XML.

Logback remains available in every generated app via Spring Boot's
zero-config logging (the default Logback feature adds grails-logging);
this feature only emits an editable starter config file. As a
mutually-exclusive logging feature it supersedes the default when
selected, so it re-declares grails-logging to keep Logback on the
classpath.

- LogbackConfig: visible OneOf LoggingFeature that adds the
  logback-spring.xml template and grails-logging dependency.
- Restore the logback.rocker.raw template used to render the file.
- LogbackSpec: cover feature visibility, file generation across all
  application types, and that grails-logging is declared exactly once.
@codeconsole codeconsole changed the title Stop generating logback-spring.xml in new apps (match Spring Boot 4.x zero-config logging) Stop generating logback-spring.xml by default; add opt-in Logback Configuration Forge feature Jun 26, 2026
…guration feature

Addresses review feedback that the change must be documented in both the
upgrade guide and the configuration reference.

- upgrading80x.adoc: add section 27 explaining that new apps no longer
  generate grails-app/conf/logback-spring.xml, that logging works via
  Spring Boot's zero-config defaults, how to tune it from application.yml,
  how to add a logback-spring.xml for custom/environment-specific logging,
  and that existing apps are unaffected.
- logging.adoc: document zero-config logging, application.yml tuning, when
  to add logback-spring.xml, and the Grails Forge Logback Configuration
  feature that generates a starter file.
@codeconsole

Copy link
Copy Markdown
Contributor Author

@sbglasius Good call — this is now documented in both places:

  • Upgrade guide (upgrading80x.adoc): new section "Logback Configuration No Longer Generated by Default" covering what changed, that logging still works out of the box via Spring Boot's zero-config defaults, how to tune levels/patterns from application.yml, and how/when to add a logback-spring.xml for custom or environment-specific logging. It also notes that existing applications are unaffected.
  • Configuration reference (conf/config/logging.adoc): now documents zero-config logging, application.yml tuning, and when to add logback-spring.xml.

Both in ed420b1.

@codeconsole

Copy link
Copy Markdown
Contributor Author

@jdaugherty Both points are addressed:

  1. Documented in the upgrade guide — new section in upgrading80x.adoc (ed420b1).
  2. Forge feature to revert the behavior — added a visible "Logback Configuration" feature that generates grails-app/conf/logback-spring.xml on demand (0eea153). It's a mutually-exclusive logging feature, so selecting it supersedes the default feature and re-declares grails-logging — the dependency is identical either way; the only difference is the generated file.

@jamesfredley

Copy link
Copy Markdown
Contributor

I would be onboard if the logback-spring.xml feature in forge was default and could be unselected to achieve the desired idea for this PR, since I think the majority of users of forge would want logback-spring.xml

@codeconsole

codeconsole commented Jun 26, 2026

Copy link
Copy Markdown
Contributor Author

I would be onboard if the logback-spring.xml feature in forge was default and could be unselected to achieve the desired idea for this PR, since I think the majority of users of forge would want logback-spring.xml

@jamesfredley per the description, logback-spring.xml still works. It just isn't needed. We should focus on making new apps as lightweight as possible while still allowing power users to customize like you are suggesting. The default shouldn't be kitchen sink.

What about "default and could be unselected" like you suggest for 8.0 and then consider defaulting to off in 9.0?

…ack-spring-xml

# Conflicts:
#	grails-doc/src/en/guide/upgrading/upgrading80x.adoc
…block

Environment-specific log levels do not require logback-spring.xml: the Grails
environments block in application.yml (and a profile-specific
application-development.yml) drive per-environment levels with no XML, because
Grails environments map to Spring profiles. Document this in both the upgrade
guide and the logging configuration reference, and reframe logback-spring.xml
as needed only for things properties cannot express (custom appenders,
structured output, per-environment appender routing).
@jamesfredley

Copy link
Copy Markdown
Contributor

@codeconsole I understand why you want it off by default, but I don't think that is the majority use case for generated apps on forge, which in theory are greenfield. I'd love to be able to deselect it for your use case but have default long term, since having more detailed logs in dev is expected behavior and having less detailed logs in prod is also.

@codeconsole

codeconsole commented Jun 26, 2026

Copy link
Copy Markdown
Contributor Author

@jamesfredley Completely agree env-specific logging is expected and we must not regress it. I tested it on Grails 8 (Spring Boot 4): generated an app, booted it in development, and checked the effective level of loggers configured three different ways.

Mechanism Result in development
environments: development: logging.level… in application.yml ✅ applied
application-development.yml with logging.level… ✅ applied
logback-spring.xml <springProfile name="development"> ✅ applied (still works under Spring Boot 4)

Two takeaways:

  1. <springProfile> still works in Grails 8 / Spring Boot 4 — this is not a repeat of the Logback-killed-Groovy-config situation; nothing regressed.
  2. Environment-specific log levels don't require logback-spring.xml at all. The Grails environments block in application.yml — which every app already has — drives per-environment levels with zero XML. logback-spring.xml is still the answer for env-specific appenders / patterns, which properties can't express.

Given that, I'd argue against generating a replacement file. The old generated logback-spring.xml was largely commented-out placeholders, and seeding any "default" env logging is just config a new app has to read and undo — the same papercut the PR is removing. So instead of shipping a file:

  • Logging works out of the box (Spring Boot defaults), and env-specific logging is fully available with no file — e.g. dev-verbose for your own package:
    environments:
        development:
            logging:
                level:
                    com.example: DEBUG
  • For anyone who wants the XML / <springProfile> route (custom appenders, structured output), the PR adds an opt-in Logback Configuration feature in Forge that generates a starter logback-spring.xml.
  • The upgrade guide and logging reference now document all of this.

Does that address the concern? If you'd still prefer a generated app to demonstrate env logging, we could seed a commented environments/logging.level example rather than active config — though I lean against shipping anything the user didn't ask for.

@testlens-app

testlens-app Bot commented Jun 26, 2026

Copy link
Copy Markdown

✅ All tests passed ✅

🏷️ Commit: 3f3732e
▶️ Tests: 26239 executed
⚪️ Checks: 44/44 completed


Learn more about TestLens at testlens.app.

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

Labels

None yet

Projects

Status: No status

Development

Successfully merging this pull request may close these issues.

4 participants