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]

Reply via email to