Skip to content

Recommended template: early DevServer/RemoteControlClient Trace logs are lost — UseLogging configures the ambient ILoggerFactory too late (OnLaunched) vs blank (Main) #3170

Description

@dr1rrb

Summary

With the recommended unoapp template, Uno.UI.RemoteControl.RemoteControlClient Trace/Debug logs emitted during early app startup (the DevServer connection attempts: Connecting to [ws://…], OnRemoteControlClientAvailable, etc.) are never captured, even with a correct filter (SetMinimumLevel(Trace) + AddFilter("Uno.UI", LogLevel.Trace)).

The same filter on the blank template captures them fine.

Root cause is timing/ordering, not filtering: the recommended template configures logging via IHostBuilder.UseLogging(...) inside App.OnLaunched (the host is built during MainWindow.InitializeNavigationAsync(...) => builder.Build()). That runs after the RemoteControl client has already started connecting and emitted its early logs. At that point Uno.Extensions.LogExtensionPoint.AmbientLoggerFactory is still unset, so those early records are dropped.

The blank template does not have the problem because it sets the ambient factory as the first line of Program.Main() (App.InitializeLogging()), before the Uno host runs.

Environment

  • Uno.Sdk 6.7.16, Uno.Templates 6.7.16
  • .NET SDK 10.0.111 (net10.0)
  • Reproduced on Desktop (Skia/X11). Originally reported on iOS. The ordering issue is platform-independent (only the required log provider differs per head: AddDebug() on iOS to reach the VS Output window, AddConsole() on Desktop).

Repro

  1. dotnet new install Uno.Templates::6.7.16
  2. dotnet new unoapp -preset recommended -platforms desktop
  3. In App.xaml.cs, inside .UseLogging(configure: (context, logBuilder) => { ... }):
    logBuilder
        .SetMinimumLevel(LogLevel.Trace)
        .CoreLogLevel(LogLevel.Warning);
    logBuilder.AddFilter("Uno.UI", LogLevel.Trace);
  4. Run the app.

Expected: Uno.UI.RemoteControl.RemoteControlClient connection traces appear (they are LogTrace/LogDebug).
Actual: they never appear. In fact no Uno.UI.RemoteControl.* category is logged at all.

Evidence

Category Uno.UI.RemoteControl.RemoteControlClient occurrences in captured output (same machine, same Uno.Sdk 6.7.16, Trace + Uno.UI filter applied in both):

Template RemoteControlClient category lines
blank (factory set in Main()) 11
recommended (UseLogging in OnLaunched) 0

First categories logged, in chronological order:

  • blank: Uno.UI.Hosting.UnoPlatformHostBuilder…X11InputMethodDetectorUno.UI.RemoteControl.RemoteControlClient (3rd — captured very early) → …
  • recommended: Uno.UI.Xaml.Core.VisualTreeBaseWindowImplementationActivationWrapper → … (RemoteControlClient never present — it already ran before the factory existed).

Higher-severity records from the same subsystem do show in recommended (e.g. LogError "DevServer isn't able to connect" from Uno.UI.HotDesign.Client.Logic.DevServer.RemoteControlService), which is what makes the problem confusing: users see some DevServer errors but never the early client traces — purely a level+timing artifact.

Note: uncommenting the template's logBuilder.HotReloadCoreLogLevel(LogLevel.Trace) group helper does not surface these logs either (still 0 lines) — the late-configuration timing dominates regardless of the filter used.

Proposed fix / discussion

The ambient ILoggerFactory should be established before the Uno host and its DevServer/RemoteControl client start, so early Trace/Debug records are not lost. Options:

  • Establish LogExtensionPoint.AmbientLoggerFactory (a lightweight bootstrap factory using the same UseLogging configuration) before host.Run() in the generated Program.cs, then hand off to the DI-built factory — instead of only wiring it inside OnLaunched.
  • Or expose a documented early-logging hook in the recommended template so the DevServer client traces are captureable via the standard configuration.

Current workaround (set an early ambient factory in Program.Main, before building/running the Uno host — mirrors what the blank template does):

var earlyFactory = LoggerFactory.Create(b =>
{
    b.AddDebug();            // iOS -> VS Output; use AddConsole() on Desktop
    b.SetMinimumLevel(LogLevel.Trace);
    b.AddFilter("Uno.UI", LogLevel.Trace);
});
global::Uno.Extensions.LogExtensionPoint.AmbientLoggerFactory = earlyFactory;

With this in place, the Uno.UI.RemoteControl.RemoteControlClient early traces are captured on the recommended template as well.

Activity

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions