Glossary of domain terms used in this codebase. Terms here have a single, agreed meaning; do not redefine them locally.
- Highlight Entry (
HighlightEntry) — One search-text rule plus the visual styling and trigger flags applied to lines that match it. Belongs to exactly one Highlight Group. - Highlight Group (
HighlightGroup) — A named, ordered list of Highlight Entries. The Log Window evaluates lines against the currently selected group. - Trigger — A side-effecting action attached to a Highlight Entry that fires when a line matches. Current triggers: Set Bookmark, Stop Tail, Don't Dirty LED, Plugin (keyword action), and Audio Alert.
- Action Entry (
ActionEntry) — Plugin name + parameters bound to the Plugin trigger of a Highlight Entry. - Tail trigger path — The single code path in
LogWindow.CheckFilterAndHighlight(one unified loop since the Filter Engine extraction) that evaluates highlight entries against newly appended lines. Triggers that have user-perceivable side effects (currently: Audio Alert) fire only on this path; bulk/scanner paths intentionally skip them — enforced by construction, since the bulkHighlightBookmarkScannerhas no access to the side-effecting triggers.
- Hide-line rule — A Highlight Entry with
IsHideLineset. A line is a Hidden Line when any matching hide-line rule of the active Highlight Group matches it (HighlightEvaluator.IsHidden); no other entry can cancel that, whatever the order. Display state only: hidden lines stay in the reader and remain eligible for Log Search, the Window Filter, Filter Pipes and triggers. Temporary search-hit entries never hide. Rules match the whole line, as for triggers, even when word mode paints only matches inside columns. - Original logical line — A line index of the Logfile Reader, before hiding. Reader access, bookmarks, timestamps, row heights, sessions and markers use it.
- Visible row — A row of the Log Window's main grid after hiding. Only grid
code deals in rows; convert with
RowToLine/LineToRow. - Line Visibility Map (
LineVisibilityMap) — The immutable mapping between visible rows and original logical lines, owned by the Line Visibility Tracker (LineVisibilityTracker), which rebuilds it on a cancellable background scan and extends it on the tail path. Visibility scans never fire triggers. - Show hidden lines — The per-window, transient override that displays hidden lines without changing any rule. Explicit navigation to a hidden line (Go to Line, bookmarks, Log Search, filter results, markers, the command-line target, the window a time sync starts from) turns it on; tailing, Stop Tail, windows following a time sync and restoring saved positions never do — they select the nearest visible line instead. Explicit navigation made before the load's first visibility scan finishes waits for it.
Avoid: "filtered out" for hidden lines (filtering is the Window Filter), "row" when an original logical line is meant.
- Marker Bar — A compact overview beside a Log Window that shows where highlights, bookmarks, Log Search hits, and Window Filter hits occur across the loaded file.
- Marker — An indicator in the Marker Bar representing one or more matching Log Lines. Markers are grouped by category; they do not create or replace Bookmarks.
- Marker Snapshot — An immutable collection of highlight or Log Search matches discovered for the Marker Bar, together with how many Log Lines have been scanned and any discovery failure.
- Bookmark — A user- or auto-generated annotation attached to a specific Log Line, carrying optional comment text and an overlay. A Bookmark can be represented by a Marker in the bookmark category; the two terms are not synonyms.
Avoid: "marker" when referring to the underlying Bookmark annotation; bare "snapshot" when the distinction between Marker Snapshot, Columnizer Snapshot, and Session Snapshot matters.
- Audio Alert — A sound played when a tail-only highlight match occurs.
Toggled per Highlight Entry via
AlertOnHit. - Sound File (
SoundFilePath) — Per-entry absolute path to an audio file (WAV/MP3/WMA/AIFF, anything NAudio can decode). Empty path means "default system beep". A missing or unreadable file falls back silently to the system beep and is logged at warn level. - Cooldown (
CooldownSeconds) — Per-entry minimum seconds between two audio alerts.0disables throttling. - Active Cooldown — The cooldown value of the most recently played alert. It gates every subsequent attempt across the whole application until it expires, regardless of which entry's cooldown was passed in for the new attempt. See ADR 0001.
- Audio Player (
LogExpert.Audio.AudioPlayer) — Static, process-wide fire-and-forget player. Owns the single global last-played timestamp and active-cooldown state.
- Session (
.lxj) — Persisted workspace: a list of log file paths plus a tab/window layout XML blob. Loading a session reopens those files in their saved arrangement. Per-file state (bookmarks, filters, columnizer, …) is not in the session — it loads independently from each file's Session File (.lxp). A session is created or restored only by explicit user action ("Save Project" / "Load Project" menu items, to be renamed to Session terminology). - Session File (
.lxp) — JSON file saved beside (or in a central directory next to) a log file, restoring per-file state on reload: columnizer name, bookmarks, filter pipes, highlight group, multi-file state, follow-tail, encoding. Created automatically on save; one per log file. Composed by a Session via itsFileNameslist. The columnizer field of a Session File is one of several sources that can be selected by Columnizer Selection Priority; the other fields always load when the Session File exists. - Session Snapshot (
SessionSnapshot) — A neutral, UI-free capture of one Log Window's persistable state. Gathered by the Log Window when a Session File is saved and applied back in two phases when one is loaded (pre-load: options like encoding, multi-file, columnizer, panel layout; post-load: content-dependent state like bookmarks, scroll position, filters). Recursive: carries a child snapshot per filter-pipe tab. - Session File Composer (
SessionFileComposer) — The pure Core module besidePersisterthat owns the field mapping between a Session Snapshot and a Session File's serialized form, in both directions (compose on save, decompose on load), plus the Rollover staleness rule. It never does I/O, shows UI, or has side effects; the Log Window owns gathering, applying, timing, and error display. - Rollover staleness rule — The predicate declaring a Session Snapshot stale because it was saved against a longer file than the one on disk (the saved line count exceeds the current one) — i.e. the log file has rolled over since the save. A stale snapshot's post-load state (bookmarks, scroll, filters) is discarded; the pre-load options still apply. Owned by the Session File Composer.
Avoid: "project" / "project file" / "workspace" (use Session), "persistence file" / "per-file persistence" (use Session File), bare "session file" when you mean the workspace (that's a Session), "options-only load" (a Session File is always read whole; the options/full split is two apply phases of the Session Snapshot, not a partial read).
- Control Character Substitution — Display-only replacement of selected
control characters with visible glyphs, performed inside
LogWindow.PaintCell. Never modifies raw column data, never affects search, filter, highlight regex, or columnizer parsing. Off by default. See ADR 0003. - Substitution Style — One of five rendering modes applied globally to
every enabled control character: Caret notation (
^G), C escape (\a/\xNN), Abbreviation (BEL), Unicode Control Pictures (␇), ISO 2047 (⍾). Default: Control Pictures. - Enabled Code Points (
ControlCharSettings.EnabledCodepoints) — The subset of C0 + DEL the user has opted in to substituting. First-time default is the "non-whitespace preset": all 33 characters exceptHT,LF,CR. - Substitution Style Fallback — Per-style rule for characters the style
has no defined glyph for. C escape falls back to
\xNN; ISO 2047 falls back to the Control Pictures glyph; the other three styles cover all 33 in-scope characters. - Copy Displayed Form (
ControlCharSettings.CopyDisplayedForm) — Opt-in setting that makes clipboard copy (and other "export selection" paths) use the substituted text instead of the raw bytes. Default: off, i.e. clipboard always carries raw data.
Avoid: "control char rendering" (use Substitution), "escape" alone (ambiguous between the C escape style and the general concept).
- Filter Engine (
IFilterEngine) — A Core module that executes one full Filter Run over a log file. Two engines implement the seam — the Serial and the Parallel engine (SerialFilterEngine,ParallelFilterEngine, the latter wrappingFilterStarter's chunk-and-merge) — selected by theMultiThreadFilterpreference and held to an identical, equivalence-test-pinned contract: sorted-ascending duplicate-free output,FilterParamsand line count snapshotted at entry, failures and cancellation narrated as outcomes, never thrown or shown by the engine. - Filter Run (
FilterRun) — One execution of a Filter Engine and its result: result lines, hit lines, the spread history (handed to the tail path to continue from), and an outcome — Completed, Cancelled (partial lists stand), or Failed (carries the exception; the Log Window narrates it on the status line). - Filter Accumulator (
FilterAccumulator) — The single owner of the per-hit accumulation recipe (hit → spread expansion → append to results/history → trim history). Used inside the Serial engine, per line by the Log Window's tail filter path, and per hit by Filter Pipes — all three adopt existing lists, so a Filter Run's history is continued in place. - Window Filter (
LogWindow._filterParams) — The one filter a Log Window currently holds in its filter panel. Per-window state: it is what a Session File saves and restores, and it is not an entry of the Saved Filter List. A Filter Pipe tab gets its own, cloned when the tab is created. - Saved Filter List (
Settings.FilterList) — The application-wide list of filters the user explicitly saved from the filter panel, shown in the filter save list. Global, never per-window, and never restored from a Session File. (Session Files written before the Window Filter change stored a copy of it instead, of which only the first entry was ever restored.) - Filter Spread — Context expansion around a filter hit: Back Spread
(
FilterParams.SpreadBefore) lines before and Fore Spread (FilterParams.SpreadBehind) lines after the hit are included in the filter result, deduplicated against recently emitted lines and clamped to the file's line range (line 0 is a valid context line). Owned byLogExpert.Core.Classes.Filter.FilterSpread— the single home of the expansion, history-trim, and rollover-shift rules; the serial filter, the parallel filter, and Filter Pipes all delegate to it. The maximum UI-configurable spread (99) and the duplicate-suppression window (2 × 99) derive fromFilterSpread.SPREAD_MAX, which bounds the UI spread knobs (FilterParamsitself does not clamp its values).
Avoid: "spread" alone when ambiguous (say Back Spread / Fore Spread), "additional filter results" (the old internal name — use Filter Spread), "multi-threaded filter" as a concept name (it is a preference selecting the Parallel Filter Engine), "FilterFx" (legacy delegate name, deleted), "the filter list" when the Window Filter is meant (the list is the Saved Filter List).
- Log Search — The Ctrl+F / F3 / Shift+F3 search-in-file feature of a
Log Window: finds the next or previous line matching a search text
(plain or regex, case-sensitive or not), wrapping around the file
boundary once before giving up. Executed by
LogExpert.Core.Classes.Search.LogSearcher, the single owner of direction resolution (forward / find-next / Shift+F3), the wrap-around-once rule, and the matching; the Log Window narrates the returnedSearchResult(status line, progress bar, scrolling).Findsnapshots itsSearchParamsat entry, so mutating the shared instance (F3) never affects a run in flight.
Avoid: bare "search" when the filter panel is meant (that is
filtering — the FilterSearch methods in the code belong to the
filter path, not Log Search), "find dialog" (use Search dialog).
- Timestamp Locator (
LogExpert.Core.Classes.Timestamp.TimestampLocator) — Timestamp lookup over a Logfile Reader and the active Columnizer: what time is the line at N (FindBackward,FindForward), and which line carries time T (FindLine, plus the raw binary-search primitiveFindNearestLineused directly by the Time Spread calculator). Pure — no dependency on the Log Window control, only onITimestampSource(below). Backs both time-sync (drag-to-scroll, "scroll all tabs to timestamp", the sync-group worker) and the Time Spread bar; the worker threads, grid selection, and cross-window coordination stay in the Log Window andTimeSyncList— only the lookup was extracted. - Timestamp Source (
ITimestampSource) — The narrow seam a Timestamp Locator runs against: a Logfile Reader, the active Columnizer, a positionable Columnizer callback, and the lock guarding Columnizer swaps. Every member is read live rather than captured, because a Log Window replaces its Logfile Reader on load/reload/rollover and swaps its Columnizer whenever the user picks a different one; a consumer like the Time Spread calculator outlives both events. Implemented by the Log Window itself. - Negated near-miss — The miss convention of
FindNearestLine, the raw binary-search primitive: when no line carries the exact timestamp searched for, it returns the nearest line's number negated, and callers flip the sign back themselves (TimeSpreadCalculatordoes).FindLine, the high-level lookup, does not expose this: it flips a miss back to a normal positive line number, so callers scroll to the nearest line instead of doing nothing — cross-window time-sync compares timestamps at millisecond precision, making the near-miss its common case. (Getting this wrong silently no-opped "scroll all tabs to timestamp" and time-sync; regression-pinned inTimestampLocatorTests.FindLine_NoExactMatchMidFile_*.) A near-miss that lands on line 0 is indistinguishable from a hit at line 0 (-0 == 0) — a ported quirk of the original binary search, preserved rather than fixed; seeTimestampLocatorTests.FindLine_TimestampBeforeTheFirstLine_*.
- Tail Follow Engine (
LogExpert.Core.Classes.Tail.TailFollowEngine) — The Core module that owns the tail-event queue and its single worker thread: file-size-changed events from the Logfile Reader arePost()ed in (any thread) and delivered in order as Tail Follow Sink callbacks on the worker thread. Owns the dispatch policies: rollover shift before content for the same event, the never-die guard (a failing dispatch is logged and the loop continues — the #634 contract), abandoned-sink exit, and the bounded (2 s) teardown join. It does not own the reader subscription: the Log Window swaps its Logfile Reader on load/reload/rollover, so it keeps forwardingFileSizeChangedinto the engine. Watcher ownership is revisited with the LogfileReader decomposition. - Tail Follow Sink (
ITailFollowSink) — The rendering side of the seam, implemented by the Log Window:OnRolloverShift(shift bookmarks, row heights, filter pipes),OnTailLines(grid update + the tail trigger path),OnLineCountChanged(Time Spread bar),IsAbandoned(window disposed/closing — the engine exits). Callbacks arrive on the engine's worker thread; the sink marshals to the UI thread itself. Pinned quirks, preserved from the original worker: the rollover shift runs even for an abandoned sink, andOnLineCountChangedfires even whenOnTailLinesfailed non-fatally.
Avoid: "LogEventWorker" (the pre-extraction thread and method name — the module is the Tail Follow Engine), "tail thread" (say the engine's worker thread).
Avoid: "GetTimestampForLine" / "GetTimestampForLineForward" /
"FindTimestampLineInternal" as concept names — those were the pre-extraction
Log Window method names (candidate 6 of
docs/improve/logwindow-architecture-review.html); the Core module is the
Timestamp Locator.
- Log Line Source (
ILogLineSource) — Read access to a loaded log file's lines: line count, line memory, and the per-line physical file name (multi-file mode). The role of the Log Window that the columnizer callbacks (ColumnizerCallback,ColumnizerCallbackMemory) and the paint context consume — a three-member fake is all a Core test needs. Also the Core-visible face of the paint context: the UI'sILogPaintContextUIextends it with fonts, colors, and highlight lookup (the old emptyILogPaintContextmarker is deleted). - Line Selectable (
ILineSelectable) — A Log Window in which a line can be selected programmatically (SelectLine). Held by a Filter Pipe for its origin window (FilterPipe.OriginWindow): "Locate line in original file". - Session Snapshot Source (
ISessionSnapshotSource) — A window whose persistable state can be gathered as a Session Snapshot. Held by a Filter Pipe for the window displaying its results (FilterPipe.ResultWindow); saving a Session File recurses through it. ILogWindow— Now purely the composition of the three roles above, with no members of its own. Kept for holders that need only the window's identity (the filter-list / highlight-group changed event args). New Core consumers take the single role they need, never the composition.
Avoid: adding members to ILogWindow directly (add to — or carve — a role
interface instead), "the ILogWindow seam" (name the specific role).
Two layers announce bookmark changes, and they deliberately differ in granularity — do not "unify" them:
- Bookmark Data Provider events (
BookmarkDataProvider.BookmarkAdded/.BookmarkRemoved/.AllBookmarksRemoved) — Core-level, and they do keep add and remove apart. Pinned by tests for fire-once and add-vs-remove semantics. - Bookmarks Changed (
LogWindow.BookmarksChanged) — The UI-level relay to the shell: this window's bookmark set changed, somehow. Add and remove are deliberately not distinguished, because every consumer only re-reads the set (the Tool Window Coordinator just callsUpdateView()). Bookmark text edits stay separate (BookmarkTextChanged) — they carry the bookmark.
Avoid: adding BookmarkAdded / BookmarkRemoved to the Log Window (that
granularity belongs to the provider), "bookmark event" unqualified (say which
layer).
-
Columnizer (
ILogLineMemoryColumnizer) — A plugin that parses a log line into columns. Each loaded log window has exactly one active columnizer at a time. The set of available columnizers is owned byPluginRegistry. -
Columnizer Snapshot — An independent Columnizer with the active Columnizer's configuration and detected column layout, ready for Marker Bar discovery. Its parsing state is separate from the active Columnizer's.
-
Columnizer Mask Entry (
ColumnizerMaskEntry) — One user-configured row on the Settings → Columnizers tab. Pairs a Mask, a Mask Type, and a Columnizer Name. Stored inPreferences.ColumnizerMaskList. -
Mask Type —
GloborRegex. Glob uses*and?wildcards and matches against the short file name; Regex uses .NET regular-expression syntax. New rows default toGlob; rows that existed insettings.jsonbefore this field was introduced deserialize asRegexfor backward compatibility. See ADR 0004. -
Stale Mask Entry — A Columnizer Mask Entry whose
ColumnizerNamedoes not resolve to any currently-registered columnizer. Stale entries are skipped at match time (the loop continues to the next entry), kept in the settings file (the plugin may return), and flagged in the Settings dialog with a leading warning icon. -
Columnizer History — Auto-maintained list (
Settings.ColumnizerHistoryList, capped at 40 entries) recording the columnizer last used per absolute file path. Stale entries (columnizer no longer registered) are removed on lookup; this list, unlike the Mask list, is not user-curated. -
Columnizer Selection Priority (
ColumnizerSelectionPriorityenum) — The user-configured rule that orders the four sources of a "which columnizer should this file open with?" decision: Session File, Columnizer History, Columnizer Mask Entry, and AutoPick. Three modes, mutually exclusive:HistoryThenMask(default; today's behaviour) — Session File → History → Mask → AutoPick → built-in default.MaskThenHistory— Session File → Mask → History → AutoPick → default.MaskOverridesPersistence— Mask → Session File → History → AutoPick → default. The only mode in which a matching mask outranks an existing Session File. Only the columnizer field of the Session File is overridden; bookmarks, filters, etc. still restore.
See ADR 0005. Replaces the deprecated
Preferences.MaskPriobool. (Note: the enum member nameMaskOverridesPersistenceretains the old "Persistence" wording for backward compatibility of serialized settings; the user-facing concept is Session File.) -
AutoPick (
Preferences.AutoPick) — When on, runsColumnizerPicker.FindBetterMemoryColumnizeragainst the loaded file content to auto-detect a columnizer. Fires only when the Columnizer Selection Priority chain above produced no result — never overrides an explicit Mask, History, or Session File hit.
Avoid: "file mask" alone (ambiguous between glob and regex — say Glob Mask or Regex Mask), "mask priority" (use Columnizer Selection Priority).
- "session file" was used by old UI resource keys (e.g.
LoadProject_UI_Message_Error_Title_FailedToUpdateSessionFile) to mean the workspace (.lxj). Resolved: from now on Session File =.lxp(per-file state) and Session =.lxj(workspace). Existing resource keys named*SessionFile*today refer to the workspace and need renaming. - "project" / "project file" historically referred to
.lxj. Resolved: use Session. TheProjectFileHandler/ProjectPersistertype names andOnLoadProjectToolStripMenuItemClickhandler are scheduled for renaming. - "Per-file Persistence" was the prior term for
.lxp. Resolved: use Session File. The enum memberColumnizerSelectionPriority.MaskOverridesPersistencekeeps its old name for serialization compatibility — internal name only, not a domain term.
Log Window: The control that displays, tails, and filters a single log file. One Log Window per open file. Avoid: Tab, panel, view
Session: A named set of Log Windows and their layout, persisted to disk and restored together. Avoid: Project, workspace, profile
Columnizer: A plugin that parses a raw log line into typed columns for structured display. Avoid: Parser, formatter
Highlight Group: A named set of rules that colour-code log lines by content pattern. Avoid: Colour scheme, filter rule
External Tool: A user-configured command-line program that LogExpert can launch from the Tool Launcher Bar, optionally with Sysout Capture. Avoid: Plugin, script
Sysout Capture: A mode for an External Tool where the tool's stdout is redirected to a temp file and opened as a live Log Window. Avoid: Stdout pipe, output redirect
Tool Launcher Bar: The toolbar strip populated from the configured External Tool entries. Avoid: Toolbar, tool strip
Defined in the Sessions section above: Session = .lxj (workspace),
Session File = .lxp (per-file state) — see also the flagged-ambiguity
resolution. (This section previously redefined both terms the pre-resolution
way; removed 2026-07-11.)