Root logger does not get log level from command line in backend
logging
In my Theia-based application, the convention is to use the `console` object for all error, warning, information, and debug logging in the backend and the frontend. Launching my application with `--log-level=debug`, I get debug logs on the console from the frontend but not from the backend. The reason is quoted below as originally reported in comment on another issue.
> This problem persists in my application because the logger server only finds out about the log level configured by the CLI via the `DispatchingLoggerClient`, which isn't yet set into the logger server at the time when we need it.
>
> Should we reopen this issue or raise a new one? What I'm observing is like so:
>
> 1. The root `Logger` instance is created during `BackendApplication` initialization.
> 2. At the moment that root `Logger`'s `@postConstruct init()` runs, `LogLevelCliContribution._defaultLogLevel` is still `LogLevel.INFO`. So, the `_logLevel` promise resolves to `INFO` and sticks.
> 3. `LogLevelCliContribution.setArguments(...)` runs later, updates `_defaultLogLevel` to `DEBUG`, and fires `logConfigChangedEvent`.
> 4. The event is *supposed* to propagate via the client: `ConsoleLoggerServer.init()` subscribes and calls `this.client?.onLogConfigChanged()`. But `this.client` is set by `onActivation` via `server.setClient(dispatchingLoggerClient)` — and Inversify runs `onActivation` *after* `@postConstruct`, so inside `init()` the closure captures `this` (not the client), and fires against whatever `this.client` is at event-fire time.
> 5. The event is lost when it fires before the full subscription chain (`cli → server → DispatchingLoggerClient → LoggerWatcher → Logger._logLevel`) is wired. Because the root `Logger` is constructed *by the same `initialize()` step* that would enable that chain, any `logConfigChangedEvent` that has already fired from `setArguments` is missed.
> 6. Child loggers work because they are constructed later, via `LoggerFactory`. By then `_defaultLogLevel` is already `DEBUG`, so the child's `_logLevel` cache resolves to `DEBUG` without needing the refresh event.
>
> I see at least a couple of simple ways to fix this. Either
>
> - have `ConsoleLoggerServer` buffer the last `logConfigChangedEvent` that fires before `setClient` is called, and forward on activation, or
> - have `LogLevelCliContribution` keep the "initial loggers already constructed" flag and re-fire `logConfigChangedEvent` once the first `ILoggerClient` attaches (via an explicit "ready" hook).
>
_Originally posted by @cdamus in [#15695](https://github.com/eclipse-theia/theia/issues/15695#issuecomment-4289032798)_
0 条评论