adityamparikh opened a new pull request, #189:
URL: https://github.com/apache/solr-mcp/pull/189
## The bug
`logback-spring.xml` is never loaded. HTTP mode therefore runs with **no
appenders at all** — no console logging and no OTLP log export — and any
startup failure exits 1 printing nothing but the Spring banner.
Reproduce on `main`:
```bash
PROFILES=http ./gradlew bootRun
```
Output is the banner, four JVM `Unsafe` warnings, then:
```
> Task :bootRun FAILED
> Process 'command '.../bin/java'' finished with non-zero exit value 1
```
No stack trace, no failure analyzer, no `APPLICATION FAILED TO START`. Force
the config and the real error appears:
```bash
LOGGING_CONFIG=classpath:logback-spring.xml PROFILES=http ./gradlew bootRun
# 0 log lines before -> 34 after, including:
# The following 1 profile is active: "http"
```
## Root cause
Spring Boot's `AbstractLoggingSystem.initializeWithConventions()` checks the
**standard** Logback locations first (`logback-test.xml`, `logback.xml`, …). If
it finds one and `logging.file.name` is unset, it calls `reinitialize()` and
**returns early** — `logback-spring.xml` is never consulted.
This repo shipped both files. `logback.xml` contains only a
`NopStatusListener` and no appenders, so it won a race it was never meant to
enter, and the `<springProfile>` blocks holding CONSOLE and OTEL silently
disappeared.
```
LoggerFactory first touch
└─► logback auto-config picks logback.xml (statusListener only, no
appenders)
Spring Boot ApplicationEnvironmentPreparedEvent
└─► AbstractLoggingSystem.initializeWithConventions()
├─ getSelfInitializationConfig() -> logback.xml FOUND
├─ reinitialize() <-- reloads logback.xml
└─ return <-- logback-spring.xml never loaded
CONSOLE + OTEL never exist
```
This is Boot's documented rule, not an edge case:
> We recommend that you use the `-spring` variant for your logging
configuration (for example, `logback-spring.xml` rather than `logback.xml`). If
you use standard configuration locations, Spring cannot completely control log
initialization.
> [Logback extensions] cannot be used in the standard `logback.xml` file
because it is loaded too early.
## The fix
Delete `logback.xml`; `logback-spring.xml` becomes the single logging
configuration. The `NopStatusListener` was **already declared** in
`logback-spring.xml`, so deleting the other file activates the suppression
rather than removing it.
Also in this PR:
- Use Boot's own `console-appender.xml` instead of a hand-rolled
`ConsoleAppender`, so `logging.pattern.console` / `logging.charset.console` /
`logging.threshold.console` behave as in a stock Boot app. The hand-rolled
encoder's fallback was already dead code: `defaults.xml` defines
`CONSOLE_LOG_PATTERN`, so `${CONSOLE_LOG_PATTERN:-…}` always resolved to Boot's
pattern — the rendered format is unchanged.
- Register `logback-spring.xml` (not `logback.xml`) as a native-image
resource in `SolrNativeHints`.
- Add `LoggingConfigurationTest`, which fails the build if any
standard-location Logback file reappears.
- Correct the Logging Architecture section of `AGENTS.md`, which claimed
*"`logback-spring.xml` — Loaded by Spring Boot, overrides `logback.xml`."* That
was the intent, not the behaviour.
## Why removing logback.xml is safe for STDIO
`logback.xml` was justified as *"Required for native image where logback
falls through to `BasicConfigurator`."* The STDIO transport's stdout
cleanliness is directly covered by `McpClientStdioIntegrationTest`, which
spawns the real `java -jar` and runs the full MCP JSON-RPC workflow — a single
stray stdout line fails it.
## Verification
| Check | Result |
|---|---|
| `./gradlew build` | ✅ 391 tests, **0 failures**, 7 skipped |
| `McpClientStdioIntegrationTest` (real jar, MCP over stdout) | ✅ 39/39, 0
skipped |
| `LoggingConfigurationTest` | ✅ 2/2 (fails on `main`) |
| `PROFILES=http ./gradlew bootRun`, no override | ✅ 34 log lines (0 before)
|
| `./gradlew nativeTest -Pnative` | ⏳ running locally; will report |
Reviewers: the native path is the one place I have not yet confirmed green —
happy to hold merge on that result.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
https://claude.ai/code/session_01Bbs8w62uwcx12ZE8E2xg8P
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]