Skip to content

feat(plugins): wire host logger factories so plugin load stops being silent#27

Merged
dhkatz merged 1 commit into
mainfrom
feat/plugin-host-logging
May 25, 2026
Merged

feat(plugins): wire host logger factories so plugin load stops being silent#27
dhkatz merged 1 commit into
mainfrom
feat/plugin-host-logging

Conversation

@dhkatz
Copy link
Copy Markdown
Contributor

@dhkatz dhkatz commented May 25, 2026

Summary

Follow-up to #26. Both CLI and UI were calling PluginHost.Initialize without a logger factory, which fell back to NullLoggerFactory and dropped every plugin discovery/load event. That's how the UE deploy regression went unnoticed until someone opened the Explorer dropdown — plugins were failing to load and there was no visible trace.

Changes

CLI

Constructs a console-backed LoggerFactory at Information level and passes it to PluginHost.Initialize. Plugin load events flow into stderr alongside the rest of the CLI output, matching how conversion progress is already surfaced.

info: GMConverter.Plugins.PluginLoader[2001]
      Loaded plugin gmconverter.unrealengine v0.1.0

UI

Adds GMConverter.UI/Services/PluginLogFileProvider.cs — a minimal file-backed ILoggerProvider that writes to %TEMP%/GMConverter.Plugins.log. The provider is independent of Avalonia's readiness state (plugin load runs in Program.Main before the UI thread dispatcher exists, so it cannot route through UiLogSink at that point in the lifecycle without restructuring). Plugin load failures land in a known file the user (and future support requests) can grep when the in-app behavior doesn't match expectations.

Sample file output:

# GMConverter plugin log | pid 41824 | started 2026-05-25T04:28:33...
[2026-05-25T04:28:33...] [Information] GMConverter.Plugins.PluginLoader: Loaded plugin gmconverter.unrealengine v0.1.0

Out of scope

Plumbing plugin events into UiLogSink so they show in the in-app console panel is the obviously-better UX. It requires restructuring UiLogSink's lifecycle (currently field-initialized inside MainWindowViewModel, depends on Dispatcher.UIThread which isn't ready at plugin-load time) and is a follow-up — not gating Source plugin migration on it.

Test plan

  • dotnet build GMConverter.slnx -c Release → 0 warnings, 0 errors
  • dotnet format --verify-no-changes → clean
  • CLI prints plugin load info on every run
  • UI writes to %TEMP%\GMConverter.Plugins.log on every launch
  • Reviewer can intentionally break the plugin (rename plugins/unrealengine/plugin.json, etc.) and confirm the error appears in stderr (CLI) and in the log file (UI)

🤖 Generated with Claude Code

…so plugin load failures stop being silent

Both CLI and UI previously called PluginHost.Initialize without a logger factory,
which fell back to NullLoggerFactory and dropped every plugin discovery/load event
on the floor. The recent UE deploy regression (#26) was silent for that reason —
plugins failed to load and the user only noticed because the Explorer dropdown was
missing entries.

CLI
- Constructs a console-backed LoggerFactory at Information level and passes it to
  PluginHost.Initialize. Plugin load events flow into stderr alongside the rest of
  the CLI's output, matching how conversion progress is already surfaced.

UI
- Adds GMConverter.UI/Services/PluginLogFileProvider.cs — a minimal file-backed
  ILoggerProvider that writes to %TEMP%/GMConverter.Plugins.log. The provider is
  Avalonia-readiness-independent (plugin load runs before the UI thread dispatcher
  exists, so it cannot route through UiLogSink at this point in the lifecycle).
  Plugin load failures land in a known file the user (and future support requests)
  can grep when the in-app behavior doesn't match expectations.
- Plumbing the file into UiLogSink so plugin events show in the in-app console
  panel is a worthwhile follow-up but requires restructuring UiLogSink's lifecycle
  (it currently field-initializes inside MainWindowViewModel) and is out of scope
  here.

Verified:
- CLI: running with any input now prints
  "info: GMConverter.Plugins.PluginLoader[2001] Loaded plugin gmconverter.unrealengine v0.1.0"
  before the conversion error or success message.
- UI: %TEMP%/GMConverter.Plugins.log now contains a startup header plus the
  Loaded plugin entry every time the UI launches.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Comment thread GMConverter.UI/Services/PluginLogFileProvider.cs Dismissed
@dhkatz dhkatz merged commit c83d164 into main May 25, 2026
4 checks passed
@dhkatz dhkatz deleted the feat/plugin-host-logging branch May 25, 2026 11:34
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant