LoggerPro — Runtime/Core¶
The public API surface, the data model, and where configuration lives.
Everything here compiles into player builds — see Runtime/README.md for what that costs and what it rules out.
The facade¶
LoggerPro.cs — what game code and tool code call. Log, LogWarning, LogError, LogSuccess, LogDebug, LogTrace, category registration and removal, and the EditorPrefs-backed display toggles.
Two things worth knowing before changing it:
TryAutoInitialize()sits at the top of every log call, so its early-out has to come first. It once built a config provider and hitResources.Loadbefore checking whether it had anything to do, which meant oneResources.Loadper visible console row per repaint.MaxLogsPerCategoryreadsEditorPrefsonly on the main thread and reuses the last value elsewhere. Storage applies the cap on whichever thread logged, andEditorPrefsis a native editor API that fails off the main thread.
LoggerProBridge.cs — the stable name LoggerProLite binds to by reflection. Lite ships inside other people's assets and cannot reference this assembly, so it locates this type by full name and binds a delegate. That handshake is the whole integration: no scripting defines, no assembly reference, no setup step for the vendor or their users. Renaming this type or its Log method breaks every already-shipped copy of Lite.
LoggerProHooks.cs — the one-way seam to the editor assembly. Exporter factory, the error-logged event, the export-format defaults, and the storage revision counter an open console watches to know it should repaint. Resolved lazily, on first use rather than at initialisation, because [InitializeOnLoad] ordering between classes is undefined.
The data model¶
LoggerProLogEntry.cs — one entry. Every serialized field is JsonUtility-safe because this is the payload of a .loggerproarchive, the report an end user sends back. Timestamps are ISO-8601 strings: JsonUtility cannot serialize DateTime and silently wrote an empty object, which is why older archives came back with every timestamp set to year 0001.
timestamp is first sighting and never moves. lastSeen moves on every repeat, and is what eviction sorts by — a deduplicated entry keeps its position in the list, so ordering by position threw out the error that was still happening and kept the one-offs above it.
LogSeverity.cs — the six severities and their tokens. Severity is stored in reports as a string so an archive written by a newer build still parses on an older one.
LoggerProCategoryNaming.cs — which categories LoggerPro invented rather than someone choosing. Defined here rather than beside the capture code because the store applies the rule and the editor-only capture produces the names; one definition, not a copy on each side.
Configuration¶
LoggerProStore.cs — owns ProjectSettings/LoggerPro.json, deliberately outside Assets so an Asset Store update cannot overwrite a team's category list, and outside player builds.
The hard-won parts:
- Writes go through a temporary file and replace the real one, so the file on disk is the old content or the new one, never half of either.
File.Replacefalls back to delete-then-move because on Windows an antivirus scanner or the search indexer holds a transient handle often enough to fail it in a normal session. - The on-disk timestamp is remembered, so a hand edit made while the editor was open is copied aside rather than silently overwritten from stale memory.
- An unreadable file is never replaced blind — it is copied first, because it is the only record of the categories the team had.
- Saves are marked, not performed:
MarkDirtyruns on whatever thread logged, and a main-thread pump does the writing. - Auto-derived
Unity.*categories are filtered out of the write. They are per-machine, named after whichever folders happened to log first, and this file is committed.
LoggerProConfig.cs / LoggerProSettings.cs — the category list and the export settings, still ScriptableObject types and still the public API, hydrated from JSON rather than loaded as assets. Neither has a CreateAssetMenu any more: an asset created from one was read by nothing.
LoggerProSettingsUtility.cs — the accessor pair, GetOrCreateSettings() and Save().
LoggerProPrefs.cs — EditorPrefs, reachable from an assembly that also compiles into players. Outside the editor the values are held in memory for the session; writing user preferences into a player's registry would be worse than forgetting them.
LoggerProExportFormats.cs — the export-format registry. Available() rebuilds the built-ins if it ever finds the registry empty, because nothing else repopulates it until the next domain reload and an empty registry means a toolbar with no export buttons at all.
Also here¶
Context/—LoggerProRuntimeand the context instance that holds the injected servicesAssemblyInfo.cs—InternalsVisibleTo("LoggerPro.Tests"), so the migration logic can be tested; it runs once against a user's real data and there is no second chance