LoggerPro¶
Diagnostics and user bug reports for people who build Unity Editor tools¶
LoggerPro is two things that work together:
- A diagnostics workshop for you — a categorised Editor console plus 20+ scanners for asmdef hygiene, update hooks, static memory, define symbols, project structure and more.
- A support channel for your users — LoggerProLite, a small console you ship inside your own asset, which gives your customers a filtered log window and a one-click bug report that lands back in LoggerPro with the environment details already filled in.
You keep your existing logging calls. You do not need conditional compilation.
Requires Unity 2022.3 LTS or newer. No third-party packages, and no render pipeline dependency. See the written guide.
Quick start¶
Tools ▸ LoggerPro ▸ Console
Log from anywhere in your own project:
using RevGaming.LoggerPro.Shared;
DevLog.Info("Import", "Parsing 42 meshes");
DevLog.Warning("Import", "Mesh has no UVs", mesh); // context object is clickable
DevLog.Error("Export", "Write failed");
Categories are created on first use and appear in the left panel, where they can be toggled, filtered, saved as presets and synced.
Publishing an asset? Do not use the above in shipped code — it binds you to LoggerPro's assembly. Run Tools ▸ LoggerPro ▸ Lite Integration ▸ Prepare Lite For My Asset and see Ship a support channel.
It shows everything the Unity console shows¶
LoggerPro mirrors Unity's own log stream, so this console is a replacement rather than a companion: third-party asset output, unhandled exceptions, and compiler errors all land here — categorised, filterable, deduplicated, and with clickable stack frames.
Captured logs are grouped by where they came from, so you can mute one noisy asset without muting your own code:
| Category | Source |
|---|---|
Unity.<Folder> | first folder under Assets/ in the stack trace |
Unity.Packages | anything under Packages/ |
Unity.Compiler | compiler warnings and errors |
Unity | engine output with no identifiable project frame |
On by default; both toggles live in the Settings tab. Compiler messages never raise log callbacks, so they come through CompilationPipeline separately.
The report loop¶
| Your user hits a bug | opens Tools ▸ Developer Log Console (branded with your asset name) |
| They click Send Report | reviews a preview, paths and user name scrubbed by default |
You receive a .loggerproarchive | Tools ▸ LoggerPro ▸ Import Report |
| You see | their logs with categories, severities and timestamps intact — plus Unity version, build target, scripting backend, API level, render pipeline, colour space, define symbols, installed packages, and which version of your asset they were running |
The report format is documented in ImportExport/LoggerProArchive.cs. Its field names are a compatibility contract with every already-shipped copy of Lite — add fields, never rename them.
Diagnostics suite¶
Audit your asset before your users do. These scanners look for what breaks an asset once it is installed in someone else's project — leaked statics, update hooks that never unsubscribe, asmdef mistakes, orphaned files. Point each tool's Scan Folder at your own asset rather than at Assets.
They will scan anything you aim them at, including LoggerPro itself, and nothing is filtered out. Findings in code you do not own are information rather than a task list, and several checks are heuristics — a result is a lead to confirm, not a defect proven.
Memory & cache — Cache Scanner · Static Memory Scanner Hooks — Update Hook Scanner · SceneView.RepaintAll scanner · EditorUtility.SetDirty scanner Structure & quality — Asmdef Optimizer · Folder Structure Validator · Namespace Validator · Script Inheritance · Empty Script Detector · Stray Script Scanner · Missing [Serializable] Detector · Define Symbol Scanner · Project Cleaner · Unused Script Detector · Big Asset Detector Performance — Script Reload Cost Estimator · startup checks for layout, serialization and versioning Visualisation — Asmdef dependency graph
New tools are discovered automatically: implement IDiagnosticTool and it appears in the sidebar. No registration step.
Architecture¶
| Folder | Purpose |
|---|---|
Runtime/ | The logging API game code calls — the LoggerPro facade, DevLog, categories, the in-memory store, configuration and LoggerProBridge. The one part that is not editor-only |
Runtime/Interfaces/ | ILoggerStorage, ILogFormatter, ILogExporter, ICategoryManager, ILoggerProContext |
Runtime/Storage/ | In-memory store with dedup and per-category caps |
Core/ | Mirroring Unity's own console into LoggerPro, and the Unity.* categories it files messages under |
Category/ | Category view presets — saving and applying a set of enabled categories |
Common/ | Trash, write guard, ignore list, stack-trace navigation, scan progress |
ImportExport/ | Report format, environment capture, redaction, TXT/JSON/Markdown/Archive |
Editor/ | Console window, menus, startup checks |
Diagnostics/ | Scanners and their UIs |
Tools/ | The structural tools: asmdef graph, folder and namespace checks, cleaner, stray scripts, serialized fields |
Shared/ | Error screenshots and the editor theme |
LoggerProLite/ | The drop-in you ship with your own asset |
LoggerProTools/ | The Lite branding tool |
Tests/ | NUnit coverage — see Tests/README.md for what is and is not covered |
Services are injected through ILoggerProContext, so storage, formatting, export and category management can all be replaced — see LoggerPro.Initialize(...).
What ships in your build¶
The console, the diagnostics and everything that writes a file are editor-only: LoggerPro.asmdef sets "includePlatforms": ["Editor"], so none of it is compiled into a player.
LoggerPro.Runtime is the exception, and it has to be — it is the assembly holding the API your game code calls, so it is built for all platforms. It is small: the logging facade, categories, the capped in-memory store, and the configuration types. In a player the calls still work and write to the Unity player log, but no configuration is read or written, no files are created on the player's machine, and none of the console, diagnostics or export code is present.
So the cost in a build is a small assembly and a bounded list, not zero. To remove it entirely, wrap your calls:
#if UNITY_EDITOR
LoggerPro.Log("Spawner", $"Spawning {count} enemies");
#endif
As of 2.0 the package contains no Resources/ folder, either — Unity includes the contents of any Resources folder in every player build regardless of which assembly reads them, so a tool with one is quietly costing its users build size.
Documentation/README.md has the full assembly table.
Where your settings live¶
ProjectSettings/LoggerPro.json — your category list and export settings.
Outside Assets/, so an Asset Store update physically cannot overwrite it. Outside builds. Readable in a diff and checked into version control, so a team shares one category list.
Before 2.0 this lived in LoggerPro/Resources/LoggerProConfig.asset, inside the package's own folder. Every update reimported it and wiped whatever categories you had, and Resources.Load("LoggerProConfig") returns the first match project-wide, so any same-named asset elsewhere in the project silently shadowed it.
Alongside it:
ProjectSettings/LoggerProPresets/ | saved category filter presets |
LoggerProExports/ | exported logs, reports and archives |
_LoggerProTrash/ | what the cleanup tools removed, recoverable, self-ignoring |
All outside Assets, so an update cannot reach them and Unity does not import them. Exports in particular are artifacts rather than assets — there is no reason for Unity to generate a .meta for every log file you write.
Upgrading is automatic. On first load LoggerPro looks for the old assets — by type, so it finds them even if you moved the package — imports your categories and paths, writes the new file, and logs what it found. The old assets are left alone and are then safe to delete.
Notes for anyone upgrading from 1.0.x¶
- Timestamps in JSON and archive exports were being lost.
JsonUtilitycannot serializeSystem.DateTime, so every exported timestamp came back as year 0001. Timestamps are now ISO-8601 strings. Old archives still import; their timestamps are simply unknown. - JSON exports could not be re-imported. The exporter wrote
{"entries":[…]}and the importer only recognised a bare[. Both are accepted now. - Imported logs no longer lose their category. Every entry used to be re-tagged
"Imported". - Error screenshots are opt-in. They previously fired on every error and opened a file browser window each time. They are now off by default, play-mode only and rate limited.
#if LOGGERPROis gone. Nothing ever defined that symbol, so the Lite→Pro routing never actually happened. It is a runtime lookup now.- LoggerProLite is a generated per-vendor drop-in, not a shared assembly. Two assets shipping the old shared version broke the user's project with duplicate assembly and type names. Re-run the branding tool to regenerate your copy.
EditorPrefsConfigProvideris nowResourcesConfigProvider(it never used EditorPrefs).RegisterCategories(IEnumerable<string>, bool)registers several at once.
Test coverage¶
Tests/ runs against an injected in-memory context, so the suite no longer writes to the shipped LoggerProConfig asset. Covered: category gating, auto-registration, dedup by severity, per-category cap eviction order, cap isolation between categories, Clear() resetting its accounting, JSON round-trip fidelity, and path redaction.
Rev + Rab Lite for your users. Pro for you. One report format between them.