diff --git a/README.md b/README.md index 2dd33bda..5a9e978e 100644 --- a/README.md +++ b/README.md @@ -6,42 +6,40 @@ A Windows Event Log viewer for tech support and IT professionals. ## Key features -* Quickly load huge .evtx files. File -> Open and select multiple files, or just drag-and-drop them into the view. The tool will happily load multiple .evtx files concurrently. -* View multiple .evtx files in an interleaved combined view and examine how events line up across multiple servers. -* See event description previews right in the table without having to open each individual event. -* Filter using friendly drop-downs, use Advanced Filter and enter a LINQ expression, or combine both. -* Create an event database to view .evtx files on computers that don't have the same product installed. For example, view Exchange Server or SQL Server logs on a user workstation. -* Can be used as a replacement for Event Viewer to view live event logs. Choose Continuously Update on the View menu and watch new events appear in real time. +* Loads `.evtx` files concurrently — `File` → `Open`, drag-and-drop, or open every `.evtx` in a folder in one step. +* Combined view interleaves events from any mix of file and live logs by time across multiple machines. +* Configurable event-table columns (visibility, ordering, sort) with per-row highlight colors driven by your filters. +* Filter pane with Basic (category × evaluator) filters, sub-filters joined with `AND` / `OR`, Date filter, Advanced Dynamic LINQ expressions, and Exclusion filters. +* Filter Cache (Favorites + Recent) and named, importable / exportable Filter Groups. +* Live event channels with auto-discovery (admin-only channels disabled when not elevated), `Continuously Update`, and a `Load New Events` buffered mode. +* Provider Databases — load `.db` files captured on another machine so its `.evtx` files resolve descriptions and task categories correctly. +* In-line description previews in the table; on-demand event XML in the Details pane. +* Configurable Ctrl+C copy mode (`Default`, `Simple`, `XML`, `Full`); System / Light / Dark theme. +* In-app Release Notes and Debug Log viewer; opt-in pre-release update channel. For more information, check our [docs](docs/Home.md). ## Quick Start -### Windows 10 or 11 +Download the `EventLogExpert__x64.appinstaller` (or the matching `EventLogExpert__x64.msix`) from the latest release and run it: . -Simply download the `EventLogExpert*.msix` file from the latest and run it: [https://github.com/microsoft/EventLogExpert/releases/latest/](https://github.com/microsoft/EventLogExpert/releases/latest/). +The `.appinstaller` declares its dependency on the Windows App Runtime (currently `Microsoft.WindowsAppRuntime.1.7.msix`, also published in the same release) so App Installer fetches the runtime automatically on a clean machine. Updates are checked on launch. -### Windows Server 2019 or 2022 +If you'd rather install the runtime manually first, grab `Microsoft.WindowsAppRuntime.1.7.msix` from the release and install it with: -Note: Auto-updates do not work on 2019. +``` +Add-AppxPackage $home\Downloads\Microsoft.WindowsAppRuntime.1.7.msix +``` -* Download the `EventLogExpert*.msix`. -* Windows 2019 will also need the `Microsoft.WindowsAppRuntime*.msix` unless it was already installed by something else. You'll find this file in the release with the `EventLogExpert*.msix`. -* Enable sideloading: +Then install the app: - `Set-ItemProperty -Path HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\AppModelUnlock -Name AllowAllTrustedApps -Value 1` - -* Install the runtime with Add-AppxPackage. Example: - - `Add-AppxPackage $home\Downloads\Microsoft.WindowsAppRuntime.1.2.msix` - -* Install EventLogExpert: - - `Add-AppxPackage $home\Downloads\EventLogExpert_23.5.19.1256_x64.msix` +``` +Add-AppxPackage $home\Downloads\EventLogExpert__x64.msix +``` ### First time setup -Head over to our [docs](docs/Home.md). +Head over to our [docs](docs/Settings.md). ## Contributing diff --git a/docs/.images/debug-log-modal.png b/docs/.images/debug-log-modal.png new file mode 100644 index 00000000..f08080fe Binary files /dev/null and b/docs/.images/debug-log-modal.png differ diff --git a/docs/.images/filter-cache-modal.png b/docs/.images/filter-cache-modal.png new file mode 100644 index 00000000..4dc0d598 Binary files /dev/null and b/docs/.images/filter-cache-modal.png differ diff --git a/docs/.images/filter-groups-modal.png b/docs/.images/filter-groups-modal.png new file mode 100644 index 00000000..482354ef Binary files /dev/null and b/docs/.images/filter-groups-modal.png differ diff --git a/docs/.images/settings-modal.png b/docs/.images/settings-modal.png new file mode 100644 index 00000000..44c2ff3d Binary files /dev/null and b/docs/.images/settings-modal.png differ diff --git a/docs/Filtering.md b/docs/Filtering.md index 636241a0..d7010e83 100644 --- a/docs/Filtering.md +++ b/docs/Filtering.md @@ -2,38 +2,99 @@ ## Filtering -There are three ways to filter. All filters apply to all logs open in that window. +The Filter pane sits above the event table. Every event in the active log set is evaluated against the applied filters; non-matches are hidden. The pane has five `Add` buttons across the top: -### Add filter +| Button | Adds | +| --- | --- | +| `Add Basic Filter` | A category × evaluator × value comparison against a single resolved-event field. | +| `Add Date Filter` | A `Before` / `After` time-window filter. Only one date filter exists at a time; the button is hidden once one is added. | +| `Add Advanced Filter` | A free-form Dynamic LINQ expression evaluated against `ResolvedEvent`. | +| `Add Cached Filter` | Picks a string from the Filter Cache (Favorites + Recent) and adds it as a Cached filter row. See [Saved Filters](Saved-Filters.md). | +| `Add Exclusion` | A Basic filter row in the excluded state — same category × evaluator × value shape as `Add Basic Filter`, but matching events are hidden instead of shown. Any saved row can be flipped between included and excluded later via the chrome `Exclude` / `Include` button. | -This button provides drop-down menus for easy filtering. +Each saved row carries a chrome strip with `Edit`, `Exclude` (or `Include` when the row is already an exclusion), `Remove`, and a `Disable` / `Enable` toggle. While editing, the chrome shows `Save` and `Cancel`. Non-exclusion rows also show a highlight-color picker (`Highlight Color`) before the comparison content. When any filter is being applied, the pane shows `[Applying Filters]` with a spinner; otherwise it shows `[Active Filters: N]`. The pane can be collapsed via the caret in the top-right corner. + +`Edit` → `Clear All Filters` removes every filter row and the date filter from the pane in one step. `Edit` → `Save All Filters` persists only the filter rows — the date filter is not part of a saved group. See [Keyboard and Copy](Keyboard-And-Copy.md). `View` → `Show All Events` (`Ctrl+H`) suspends evaluation without removing any filters. + +### Basic filters + +Pick a category, pick an evaluator, then enter or pick a comparison value. Optionally add one or more sub-filters joined to the parent with `AND` or `OR`. + +**Categories** (`FilterCategory`): + +| Label | Source field | +| --- | --- | +| `Event ID` | event id (int) | +| `Activity ID` | activity id GUID (string-equal) | +| `Level` | resolved level string (`Information`, `Warning`, `Error`, `Critical`, `Verbose`) | +| `Keywords` | display keywords | +| `Source` | provider name | +| `Task Category` | resolved task name | +| `Process ID` | process id | +| `Thread ID` | thread id | +| `User ID` | SID string | +| `Description` | resolved description text | +| `Xml` | raw XML (forces eager XML resolution; see caveat) | + +**Evaluators** (`FilterEvaluator`): + +| Label | Behavior | +| --- | --- | +| `Equals` | Exact match. Numeric for ID-typed fields; case-sensitive string compare for everything except `Keywords`, which is case-insensitive. | +| `Contains` | Case-insensitive substring match. | +| `Not Equal` | Negated `Equals` (same case-sensitivity rules). | +| `Not Contains` | Negated `Contains` (case-insensitive). | +| `Multi Select` | Matches any value in the supplied set. The category determines which set is offered (e.g., `Level` → checkboxes for the five level values; `Source` → the providers seen in the active logs). | + +Sub-filters live underneath the parent and can be combined freely. `AND` requires the sub-filter to also match; `OR` matches if either the parent or the sub-filter matches. ### Date filter -Any events falling outside of the starting and ending time specified here are hidden. - -### Advanced filter - -This button displays a textbox allowing a LINQ expression for filtering. Filterable properties are: - -Property Name|Type --|- -ComputerName|string -Description|string -Id|int -KeywordDisplayNames|IEnumerable -Keywords|long? -LogName|string -OwningLog|string -Qualifiers|int? -RecordId|long? -SeverityLevel|Enum? (Error == 2, Warning == 3, Information == 4) -Source|string -TaskCategory|string -Template|string? -TimeCreated|DateTime -Xml|string - -Note that Xml is generated when requested, so filters against Xml may be slower than filters against other properties. +`After` / `Before` timestamps in the configured time zone (see [Settings](Settings.md) → `Time Zone`). Only one date filter is allowed; removing it lets `Add Date Filter` reappear. Right-clicking an event in the table and choosing `Exclude Events Before` / `Exclude Events After` is a shortcut that sets a date filter using the right-clicked event's timestamp as the boundary. + +### Advanced filters (Dynamic LINQ) + +Free-form expression evaluated against the `ResolvedEvent` record using [Dynamic LINQ](https://dynamic-linq.net/). The placeholder shown in the input is: + +``` +(Id == 1000 || Id == 1001) && Description.Contains('Fault') +``` + +Available properties: + +| Property | Type | Notes | +| --- | --- | --- | +| `Id` | `int` | Event id. | +| `ActivityId` | `Guid?` | Nullable. | +| `Level` | `string` | `Information`, `Warning`, `Error`, `Critical`, `Verbose`. | +| `Keywords` | `IReadOnlyList` | Use `.Contains("...")`. | +| `KeywordsDisplayName` | `string` | Comma-separated keywords. | +| `Source` | `string` | Provider name. | +| `TaskCategory` | `string` | | +| `ProcessId` | `int?` | | +| `ThreadId` | `int?` | | +| `UserId` | `SecurityIdentifier?` | Use `.ToString()` to compare. | +| `TimeCreated` | `DateTime` | The raw `ResolvedEvent` value — the table and Details pane render it in the configured time zone, but expressions see the underlying value. | +| `LogName` | `string` | Source log channel as reported by the event reader. | +| `OwningLog` | `string` | The file path or live-channel name as displayed in the tab strip. | +| `LogPathType` | `LogPathType` | `File` or `Channel`. | +| `ComputerName` | `string` | | +| `RecordId` | `long?` | | +| `Description` | `string` | Resolved description text. | +| `Xml` | `string` | Raw event XML. **See XML caveat.** | + +**XML caveat.** When a filter expression references `Xml`, the underlying `EventLogReader` is opened with XML rendering enabled, which is meaningfully slower than the default. Adding an XML-referencing filter against logs already loaded without XML triggers a one-time re-read of those logs (only the logs that lack XML — logs already loaded with XML are untouched). Removing or disabling an XML filter does not trigger another reload because the in-memory XML is harmless to keep. Filters that don't reference `Xml` operate on already-resolved fields and stay fast. + +### Excluded filters + +Either an `Add Exclusion` row from the start, or any Basic / Advanced row toggled with the `Exclude` chrome button. Matching events are hidden. Excluded filters are evaluated independently of `View` → `Show All Events`: the show-all toggle disables only the inclusion side, so exclusions and the date filter remain in effect when it's on. `Edit` → `Clear All Filters` removes every filter from the pane (including the date filter and exclusions) — there's no built-in way to reversibly suspend everything at once. + +### Cached filters + +Quick-access strings for repeat use. See [Saved Filters](Saved-Filters.md) for how the cache is populated and managed. + +### Highlighting + +Each non-excluded filter row exposes a `Highlight Color` picker in its chrome. When set, every event matching that filter is rendered with that background color in the event table. When multiple filters with different colors match the same event, the first matching enabled, non-excluded filter in pane order wins (a filter with `Highlight Color` set to `None` still counts as a match and suppresses any later highlight). Selection styling beats highlight while a row is selected. Highlight colors persist with the filter — saving a group preserves its colors. [Docs home](Home.md) diff --git a/docs/FirstTimeSetup.md b/docs/FirstTimeSetup.md deleted file mode 100644 index 81329be2..00000000 --- a/docs/FirstTimeSetup.md +++ /dev/null @@ -1,23 +0,0 @@ -# [EventLogExpert](Home.md) - -## First time setup - -After installing EventLogExpert, there are a few settings you may want to change. - -### Set the time zone - -From Tools -> Options, the time zone can be changed at any time. Any .evtx files that are opened will be adjusted to show in the selected time zone. This allows the Combined view to line up events from machines in different time zones. It can also be helpful to set this to the time of a particular server, or to the time zone of a customer you are working with, so you can view the event logs as if you were in their time zone. - -### Opt in to prerelease builds - -As of this writing, the tool is under active development. In Tools -> Options, you can opt in to prereleases to test the latest features. - -### Choose the Description pane behavior - -By default, the Description pane at the bottom will pop open the first time an event is selected. If the user collapses it, it will then stay closed until it is manually expanded again. Tools -> Options has a setting that makes this pane always pop open when the selection is changed. - -### Import provider databases - -If you have created event databases, they can be imported in Tools -> Options. See [Provider Databases](ProviderDatabases.md). - -[Docs home](Home.md) diff --git a/docs/Home.md b/docs/Home.md index 3fa68046..7bdcef68 100644 --- a/docs/Home.md +++ b/docs/Home.md @@ -1,8 +1,16 @@ # EventLogExpert +A Windows Event Log viewer for tech support and IT professionals. Reads `.evtx` files and live event channels, with provider-database support so events captured on one machine resolve correctly on another. + +Runs on supported versions of Windows: Windows 11, Windows Server 2022, Windows Server 2025. + ## Topics -* [First time setup](FirstTimeSetup.md) - Customizing your experience. -* [Filtering](Filtering.md) - How to use the various filter options. -* [Viewing events](Viewing.md) - Things to know about viewing, selecting, scrolling, and reading events. -* [Provider databases](ProviderDatabases.md) - Viewing event descriptions on machines that don't have the requisite software installed. +- [Opening Logs](Opening-Logs.md) — Opening files, folders, and live channels. +- [Viewing Events](Viewing-Events.md) — Tab strip, configurable table columns, details pane. +- [Filtering](Filtering.md) — Basic, Date, Advanced (Dynamic LINQ), Cached, Exclusion filters and highlighting. +- [Saved Filters](Saved-Filters.md) — Filter cache (Favorites + Recent) and Filter groups. +- [Provider Databases](Provider-Databases.md) — Why event databases exist and the `eventdbtool` CLI. +- [Settings](Settings.md) — Time zone, databases, theme, copy mode, log level, pre-release builds. +- [Keyboard and Copy](Keyboard-And-Copy.md) — Ctrl+C copy formats and other keyboard bindings. +- [Updates and Diagnostics](Updates-And-Diagnostics.md) — Docs, Submit an Issue, Check for Updates, Release Notes and View Debug Logs. diff --git a/docs/Keyboard-And-Copy.md b/docs/Keyboard-And-Copy.md new file mode 100644 index 00000000..3445943f --- /dev/null +++ b/docs/Keyboard-And-Copy.md @@ -0,0 +1,45 @@ +# [EventLogExpert](Home.md) + +## Keyboard and Copy + +### Copy formats + +The `Edit` menu always lists all four copy formats: + +| Edit menu item | Format | Output | +| --- | --- | --- | +| `Copy Selected` | `Default` | One quoted, space-separated field per visible event-table column, plus the description. | +| `Copy Selected (Simple)` | `Simple` | Five quoted, space-separated fields: level, timestamp, source, event id, description. | +| `Copy Selected (XML)` | `Xml` | The event's XML, pretty-printed when parseable. | +| `Copy Selected (Full)` | `Full` | A multi-line block with labeled fields (`Log Name`, `Source`, `Date`, `Event ID`, `Task Category`, `Level`, `Keywords`, `User`, `Computer`, `Description`, `Event Xml`). | + +`Ctrl+C` invokes whichever format `Tools` → `Settings` → `Keyboard Copy Behavior` is set to. The `Ctrl+C` shortcut hint in the `Edit` menu moves to that entry so the keyboard binding is always visible. `Full` is the initial setting on a fresh install. + +Multi-selection is honored — every selected row is included in the copied payload in the order they appear. + +`Save All Filters` and `Clear All Filters` also live on the `Edit` menu. `Save All Filters` prompts for a `Group Name` (default `New Filter Section\New Filter Group`) and saves the current filter rows as a named filter group — the date filter is not included. See [Saved Filters](Saved-Filters.md). `Clear All Filters` removes every filter row and the date filter from the pane in one step. + +### Menu navigation + +The menu bar follows WAI-ARIA menubar conventions. Once a menu-bar button has focus (Tab in from elsewhere or click one open): + +| Key | Action | +| --- | --- | +| `ArrowLeft` / `ArrowRight` | Move between top-level menus. Wraps. If a menu is open, switches to the new menu. | +| `Home` / `End` | Jump to the first or last top-level menu. | +| `ArrowDown` | Open the focused menu, with focus on the first item. | +| `ArrowUp` | Open the focused menu, with focus on the last item. | +| `Enter` / `Space` | Open the focused menu (alternative to `ArrowDown`). | +| `Escape` | Close the open menu. | + +Hovering a different top-level menu while a menu is open switches to that menu — same as Win32 menubars. + +### Other shortcuts + +| Shortcut | Action | +| --- | --- | +| `Ctrl+O` | `File` → `Open` → `File`. Standalone open; not the `Combine` variant. | +| `Ctrl+H` | Toggle `View` → `Show All Events`. Suspends inclusion-filter evaluation so any event not blocked by an exclusion or by the date filter becomes visible. Toggling again resumes filtering against the same set. | +| `Ctrl+C` | Copy selected events using the `Keyboard Copy Behavior` format. | + +[Docs home](Home.md) diff --git a/docs/Opening-Logs.md b/docs/Opening-Logs.md new file mode 100644 index 00000000..d361473c --- /dev/null +++ b/docs/Opening-Logs.md @@ -0,0 +1,56 @@ +# [EventLogExpert](Home.md) + +## Opening Logs + +The `File` menu is the primary entry point for opening logs. There are three sources, all available under both `File` → `Open` (replace the active log set) and `File` → `Combine` (overlay on top of what's already open). The `Combine` submenu is greyed out until at least one log is open. + +`.evtx` files can also be opened by drag-and-drop onto the window or by passing them as command-line arguments at launch. Both routes always combine — they add to the current log set rather than replacing it. + +### File + +`File` → `Open` → `File` (`Ctrl+O`) opens the system file picker filtered to `.evtx`. Pick one file or many — every selected `.evtx` is loaded concurrently as a separate log. The same applies for `File` → `Combine` → `File`, which adds the picked files to the existing log set. + +### Folder + +`File` → `Open` → `Folder` opens a folder picker. Every `.evtx` in the picked folder (top-level only, no recursion) is loaded as a separate log. + +Use this when you've been handed a folder of `.evtx` exports from one or more machines and want to load the lot in one step. + +### Live + +`File` → `Open` → `Live` opens a Windows event channel as a live log — the channel is read in real time as opposed to a static snapshot. + +The submenu always lists `Application`, `System`, and `Security`. Below them, an `Other Logs` submenu is built from the channels actually registered on the local machine, presented as a hierarchical tree (`Microsoft` → `Windows` → `` → ``, etc.). The list is discovered once per app session and cached after the first menu open or background prewarm; channels added or removed during the session aren't reflected until the app restarts. + +**Admin-only channels.** Some channels can't be read without elevation. When the app isn't running as Administrator, `Security` (and other elevation-gated channels surfaced under `Other Logs`) appear in the menu but are disabled. Re-launching the app as Administrator enables them. The disabled state is the only signal — there's no popup. Anything that opens fine without elevation stays enabled. + +### Combining logs + +`File` → `Combine` is the same submenu as `Open`, but adds the picked source(s) to the currently-open log set instead of replacing it. With two or more logs open, an extra `Combined` tab appears in the tab strip showing all events from all open logs interleaved by time — see [Viewing Events](Viewing-Events.md). + +`Combine` works for any mix of file logs and live channels. Combining `.evtx` exports from machines in different time zones produces a coherent timeline because the event table renders timestamps in the time zone configured under [Settings](Settings.md). A live channel combined with a file log behaves the same — the live side simply keeps appending events as they arrive (when continuously updating) or filling the buffer (when not). + +### Live log behavior + +Two `View` menu items only matter while a live log is open: + +- **`Continuously Update`** is a toggle. When `on`, new events stream into the table as they arrive. When `off`, new events accumulate in a buffer and the table view stays put. +- **`Load New Events`** drains the buffer into the table once. Useful when `Continuously Update` is off but you want to catch up to "now" before going back to a static view. + +The status bar surfaces both: + +| Status bar token | Condition | +| --- | --- | +| `Continuously Updating` | At least one live log is open and `Continuously Update` is on. | +| `New Events: ` | At least one live log is open and `Continuously Update` is off; `` is the buffer size. | +| `Buffer Full` | The new-event buffer reached its cap. Live watchers are stopped while this is set, so no further events arrive until either `Load New Events` drains the buffer or `Continuously Update` is turned on (both clear the buffer and restart the watchers). | + +### Close All + +`File` → `Close All` removes every open log (file or live) and clears the tab strip. There's no per-tab close from the `File` menu — the per-tab `×` button on each tab in the tab strip closes a single log. Combined tabs can't be closed individually; they disappear automatically when the tab strip drops below two source logs. + +### Exit + +`File` → `Exit` closes the application. + +[Docs home](Home.md) diff --git a/docs/Provider-Databases.md b/docs/Provider-Databases.md new file mode 100644 index 00000000..84b5403f --- /dev/null +++ b/docs/Provider-Databases.md @@ -0,0 +1,123 @@ +# [EventLogExpert](Home.md) + +## Provider Databases + +Windows event descriptions and task categories aren't stored inside an `.evtx` file. They live in resource DLLs registered against the provider name on whichever machine produced the events. Open an `.evtx` from another machine on yours, and Windows can usually only render a placeholder like `The description for Event ID … cannot be found`. + +Provider databases solve that. A `.db` file contains the resolved provider metadata (descriptions, task categories, level / keyword names, parameter strings) for a set of providers, snapshotted from a machine that does have the providers installed. Load that database into EventLogExpert and `.evtx` files captured on the source machine resolve as if you were running on the source machine. + +When at least one database is enabled in `Tools` → `Settings`, providers are resolved in this order: + +1. For an `.evtx` opened from a folder that also contains its sibling `LocaleMetaData/*.MTA` files, those files are consulted first (this is the primary path for self-contained exports). +2. Then the enabled databases, in load order — the first database that knows the provider wins. +3. Then the local machine's installed providers as a fallback. + +Disabling a database skips it from step 2 only. Exported logs that ship with sibling `LocaleMetaData/*.MTA` files still resolve via those (step 1), and any provider not resolved by databases still falls through to local providers (step 3). + +### Lifecycle (Settings → Databases) + +`Tools` → `Settings` → `Databases` lists every database the app knows about. The full lifecycle is covered in [Settings](Settings.md). The states a row can be in: + +| Status | Behavior | +| --- | --- | +| `Ready` | Loaded and used to resolve events. | +| `Classifying…` | Initial classification pass hasn't reached this row yet. The enable / disable toggle is suppressed until classification completes. The same state is reflected by the top-of-list `Classifying databases…` banner. | +| `Upgrade required` | Schema is older than the running build but in-place upgrade is supported. The row's `Upgrade` button performs the migration in place; a backup of the original is kept on disk. | +| `Upgrade failed` | Most recent upgrade attempt failed. Use `Retry Upgrade`, re-import, or remove. | +| `Recovery required` | A previous upgrade left a backup; the original is still safe but the row needs reconciliation before going back to `Ready`. | +| `Unrecognized` | Not a database produced by this tool. | +| `Obsolete` | A v1 / v2 schema database from a long-superseded build. Not upgradable in place; recreate with `eventdbtool create`. | +| `Classification failed` | Initial classification threw. Details in `View Logs` (see [Updates and Diagnostics](Updates-And-Diagnostics.md)). | + +A `Classifying databases…` banner appears during the initial pass on app startup. + +## eventdbtool + +Provider databases are produced and maintained by `eventdbtool`, a CLI shipped alongside EventLogExpert in the same release as `eventdbtool.zip`. The tool runs on a Windows machine that has the providers you want captured (an Exchange Server, a SQL Server, a fresh OS install — whatever produces the events you need to read elsewhere). + +Root description (verbatim from `--help`): + +> Tool used to create and modify databases for use with EventLogExpert + +Five subcommands. + +### `eventdbtool show` + +``` +eventdbtool show [] [--filter ] [--verbose] +``` + +> List event providers. When no source is supplied, lists providers on the local machine. When a source is supplied, it may be a .db file created with this tool, an exported .evtx file (resolved via its sibling LocaleMetaData/*.MTA files), or a folder containing either. + +| Argument / option | Description | +| --- | --- | +| `source` (optional) | A `.db` file, an exported `.evtx` file, or a folder containing `.db` and/or `.evtx` files (top-level only). | +| `--filter` | `Filter for provider names matching the specified regex string.` | +| `--verbose` | `Verbose logging. May be useful for troubleshooting.` | + +### `eventdbtool create` + +``` +eventdbtool create [] [--filter ] [--skip-providers-in-file ] [--verbose] +``` + +> Creates a new event database. + +The `` argument must end in `.db` and must not already exist. + +| Argument / option | Description | +| --- | --- | +| `file` | `File to create. Must have a .db extension.` | +| `source` (optional) | `Optional provider source: a .db file, an exported .evtx file, or a folder containing .db and/or .evtx files (top-level only). When omitted, local providers on this machine are used. When supplied, ONLY the source is used (no fallback to local providers).` | +| `--filter` | `Only providers matching specified regex string will be added to the database.` | +| `--skip-providers-in-file` | `Any providers found in the specified source (a .db file, an exported .evtx file, or a folder containing them, top-level only) will not be included in the new database. For example, when creating a database of event providers for Exchange Server, it may be useful to provide a database of all providers from a fresh OS install with no other products. That way, all the OS providers are skipped, and only providers added by Exchange or other installed products would be saved in the new database.` | +| `--verbose` | `Enable verbose logging. May be useful for troubleshooting.` | + +### `eventdbtool merge` + +``` +eventdbtool merge [--overwrite] [--verbose] +``` + +> Copies providers from a source into a target database. + +The target must already exist and be at the current schema version (run `upgrade` first if not). + +| Argument / option | Description | +| --- | --- | +| `source` | `The provider source: a .db file, an exported .evtx file, or a folder containing .db and/or .evtx files (top-level only).` | +| `target db` | `The target database.` | +| `--overwrite` | `When a provider from the source already exists in the target, overwrite the target data with the source data. The default is to skip providers that already exist.` | +| `--verbose` | `Enable verbose logging. May be useful for troubleshooting.` | + +### `eventdbtool diff` + +``` +eventdbtool diff [--verbose] +``` + +> Given two provider sources (each may be a .db, an exported .evtx, or a folder containing them), produces a database containing all providers from the second source which are not in the first source. + +| Argument / option | Description | +| --- | --- | +| `first source` | `The first source to compare: a .db, an exported .evtx, or a folder containing .db and/or .evtx files (top-level only).` | +| `second source` | `The second source to compare: a .db, an exported .evtx, or a folder containing .db and/or .evtx files (top-level only).` | +| `new db` | `The new database containing only the providers in the second source which are not in the first source. Must have a .db extension.` | +| `--verbose` | `Verbose logging. May be useful for troubleshooting.` | + +### `eventdbtool upgrade` + +``` +eventdbtool upgrade [--verbose] +``` + +> Upgrades the database schema + +No-op when the database is already at the current version. v1 / v2 databases are not upgradable in place — recreate them with `eventdbtool create`. + +| Argument / option | Description | +| --- | --- | +| `file` | `The database file to upgrade.` | +| `--verbose` | `Verbose logging. May be useful for troubleshooting.` | + +[Docs home](Home.md) diff --git a/docs/ProviderDatabases.md b/docs/ProviderDatabases.md deleted file mode 100644 index d5556f34..00000000 --- a/docs/ProviderDatabases.md +++ /dev/null @@ -1,25 +0,0 @@ -# [EventLogExpert](Home.md) - -## Provider databases - -EventLogExpert can be used to view event descriptions for events generated by products that are not installed on the user's workstation. An event database must be created to enable this functionality. - -By default, EventLogExpert will simply use the event provider DLLs available on the local machine to resolve event descriptions. If EventLogExpert is being used on a user workstation, and the Application event log from an Exchange Server is opened, many of the events will not have descriptions, because those provider DLLs are not present. In order to view those events, use the following steps: - -* Download eventdbtool.exe from the latest GitHub release. -* Copy eventdbtool to a machine with the product installed, such as Exchange Server in this example. -* Create a database for that server and give the file a name that indicates where it came from. For example: - - `eventdbtool create "C:\EXCH1.db"` - -* This database contains the provider information for everything on that server, including Windows, Exchange Server, and anything else installed. If you like, you can use the database as-is. -* eventdbtool also provides the ability to diff databases against each other. This can be useful to separate OS databases from product databases. For example, in our example here, if Exchange 2019 is installed on a Windows 2019 server, we might want to diff the database we just created against a database from a plain Windows 2019 server with nothing else on it. This would produce a database that only has event providers for Exchange. This can be done with a command such as: - - `.\eventdbtool diff "C:\Windows 2019.db" "C:\EXCH1.db" "C:\Exchange 2019.db"` - -* Now we have Exchange 2019.db that only has event providers which were not present in the Windows 2019 database, so it is a database just for that product (and any other products that were installed on that machine). This step is optional. -* Go to Tools -> Settings -> Add Provider and choose the database to import. - -As long as at least one database is enabled in Tools -> Options, EventLogExpert will only use those databases for event resolution and will ignore any provider DLLs on the local machine. To switch back to local machine providers, disable all the databases in Tools -> Options. - -[Docs home](Home.md) diff --git a/docs/Saved-Filters.md b/docs/Saved-Filters.md new file mode 100644 index 00000000..bbdf7950 --- /dev/null +++ b/docs/Saved-Filters.md @@ -0,0 +1,59 @@ +# [EventLogExpert](Home.md) + +## Saved Filters + +Two separate persisted surfaces, both reached from the `View` menu: + +- `View` → `Show Cached Filters` opens the **filter cache** modal — a flat list of single-expression filter strings split into `Favorite Filters` and `Recent Filters` sections. +- `View` → `Show Filter Groups` opens the **filter groups** modal — named, structured collections of full filters (with categories, evaluators, comparison values, and per-filter highlight colors). + +The two have different shapes and different intended uses. The cache is a one-string-per-entry shortcut for the comparison values you keep typing. Groups are reusable filter sets you assemble once and reapply or share. + +### Filter cache (`Show Cached Filters`) + + ![Filter cache modal](.images/filter-cache-modal.png) + +**`Recent Filters`.** Every time a filter with a non-empty comparison value is added (basic, advanced, or exclusion), the comparison string is enqueued into the recent list. The list caps at 20 entries; older entries roll off. When the same string is added again it isn't re-added. Empty when no filter has been added yet (`No Recent Filters`). + +**`Favorite Filters`.** A separately-tracked list with no size cap. Click the outline-star on a recent entry to promote it to favorites; click the filled-star on a favorite entry to demote it back to the recent list. Stars only ever copy a string into favorites — the recent entry is left in place; if the favorite is later un-starred, the same string ends up back in the recent queue. + +**Apply.** The `+` button on any entry adds a new `Cached` filter row to the filter pane using that string as the value, then closes the modal. + +**Import / Export.** The footer's `Import` and `Export` buttons read and write a JSON list of strings — only the favorites snapshot. Imported entries are merged into the existing favorites (no duplicates added). + +The cache persists across app sessions in user preferences. + +### Filter groups (`Show Filter Groups`) + + ![Filter groups modal](.images/filter-groups-modal.png) + +A filter group is a named collection of full filters — each with its own category / evaluator / comparison text / highlight color and any sub-filters. Groups can be organized into sections (the section name is the prefix before `\` in the group name, e.g. `Exchange\HUB Server` lives under section `Exchange` with display name `HUB Server`). Groups with no `\` in the name appear at the modal's top level. + +Per-group buttons (when the group is not in edit mode): + +| Button | Behavior | +| --- | --- | +| `Apply Filters` | Adds this group's filters to the current filter pane, skipping any whose comparison text + include/exclude flag already exists in the pane. Closes the modal afterwards. Existing pane filters are not touched. | +| `Copy` | Copies the group's filter expressions to the clipboard. With multiple filters, each is wrapped in parentheses and joined with the Dynamic LINQ OR operator so the result is a single Advanced expression you can paste back into the filter pane. | +| `Export` | Saves the entire group (name + filters) as a JSON file. | +| `Edit` | Switches the group into edit mode (per-row controls, `Add Filter`, `Save`, `Cancel`, `Import`, `Remove`). | +| `Remove` | Deletes the group. | + +In edit mode each filter row gets the same chrome as the filter pane (toggle enable/exclusion, edit, save, remove); plus per-row highlight color picker. `Save` writes back when no row is mid-edit and no draft is unsaved. + +The pencil icon next to the group name renames it. Empty names are rejected. The new name's `\` segment becomes the new section prefix. + +`Create Group` at the bottom of the modal creates a new group named `New Filter Section\New Filter Group` (in section `New Filter Section`); rename it before saving filters into it. Group creation also seeds the `Save All Filters` flow on the `Edit` menu — that command prompts for a `Group Name` and saves the current filter rows as a new group with that name. Saved groups persist filter rows only; the date filter is stored separately and is not part of a group. + +**Modal-level Import / Export.** The footer reads and writes JSON files containing the **entire** groups list. `Export` saves every group; `Import` reads a list of groups and adds them to whatever's already there (no merge by name, so re-importing the same file produces duplicates). + +**Per-group `Export`** (button in the row's chrome) saves a single group as JSON. **Per-group `Import`** (in edit mode) replaces *this* group's name and filters with the contents of the picked file — useful for swapping the body of an existing group without creating a new one. + +Filter groups persist across app sessions in user preferences. + +### Cache vs. Groups: when to use which + +- A single comparison string you keep retyping into the same one-field basic filter → cache it. Use `Add Cached Filter` from the filter pane and pick the value from the cache dropdown. +- A reusable set of filters that belongs together (e.g., "Exchange transport service errors") → make a group. Apply from the group row; share with `Export` / `Import`. + +[Docs home](Home.md) diff --git a/docs/Settings.md b/docs/Settings.md new file mode 100644 index 00000000..35dac16d --- /dev/null +++ b/docs/Settings.md @@ -0,0 +1,66 @@ +# [EventLogExpert](Home.md) + +## Settings + +`Tools` → `Settings` opens the Settings modal. + +`Save` writes the form fields and any pending enable/disable toggles you've made on database rows; `Exit` discards them. `Remove` and `Upgrade` are immediate side effects that persist regardless of `Save` / `Exit`. `Import Database` is also immediate, but a successful import additionally applies any pending form fields and toggles and closes the modal — make any other changes you want to keep before clicking it. + + ![Settings modal](.images/settings-modal.png) + +### Time Zone + +Drop-down of every system time zone. Event timestamps in the table, the Details pane, and the Date filter are all rendered in the selected zone. Changing this re-renders open logs in place; it doesn't reload them. + +Set this to match the source machine, the customer's locale, or your own — whatever lines up most clearly with the events you're reading. Combined views from machines in different zones use this single zone for sorting and display. + +### Databases + +Lists every imported provider database with its current status and per-row controls (enable / disable, Upgrade when offered, Remove). The `Import Database` button opens a multi-file picker that accepts `.db` files and `.zip` archives containing them; conflicting filenames prompt to overwrite or skip. + +A row badge shows the current state. While the initial pass is running, a `Classifying databases…` banner sits above the list: + +| Badge | Meaning | +| --- | --- | +| (none) | `Ready` (loaded and usable) — or `Upgrade required`, in which case the row's `Upgrade` button replaces the badge as the visible affordance. | +| `Classifying…` | Initial classification hasn't reached this row yet (also reflected in the top-of-list banner). The enable / disable toggle is suppressed until classification completes. | +| `Upgrade failed` | The most recent upgrade attempt failed; the row offers `Retry Upgrade`. Re-import or remove if the retry keeps failing. | +| `Recovery required` | A previous upgrade left a backup file in place; the original is still safe but needs reconciliation before the row goes back to `Ready`. | +| `Unrecognized` | The file isn't a database produced by this tool. | +| `Obsolete` | A v1 / v2 database from a long-superseded build of the tool; not upgradable in place — recreate with `eventdbtool create`. | +| `Classification failed` | Initial classification threw; details surface in `View Logs`. | + +Enabling or disabling a database is a pending change — closing the modal afterwards prompts to reload all open logs so resolution reflects the new set. `Remove` is immediate: removing a `Ready` and enabled database while logs are open prompts a confirmation that warns affected log views will be closed and reopened, and the reload happens right then (no modal-close prompt afterwards). Removing a database that's disabled or not `Ready` only asks for confirmation and skips the reload. + +See [Provider Databases](Provider-Databases.md) for the rationale and the `eventdbtool` CLI reference. + +### Expand Display Pane On Selection Change + +When `True`, the Details pane re-expands every time the selection changes, even if it was manually collapsed for the previous event. When `False`, a manual collapse stays collapsed until the pane is re-expanded by hand. + +### Theme + +`Follow System` (default), `Light`, or `Dark`. `Follow System` tracks the current Windows app-mode preference and switches with it. + +### Keyboard Copy Behavior + +Selects which copy format Ctrl+C uses on the event table: + +| Value | Output | +| --- | --- | +| `Default` | One quoted, space-separated field per visible event-table column, plus the description. | +| `Simple` | Five quoted, space-separated fields: level, timestamp, source, event id, description. | +| `Xml` | The event's XML, pretty-printed when parseable. | +| `Full` | A multi-line block with labeled fields (`Log Name`, `Source`, `Date`, `Event ID`, `Task Category`, `Level`, `Keywords`, `User`, `Computer`, `Description`, `Event Xml`). | + +The Edit menu always exposes all four formats explicitly (`Copy Selected`, `Copy Selected (Simple)`, `Copy Selected (XML)`, `Copy Selected (Full)`); the `Ctrl+C` shortcut hint moves to whichever entry matches the current setting. See [Keyboard and Copy](Keyboard-And-Copy.md). + +### Logging Level + +The threshold for what gets written to the in-app debug log surfaced by `Help` → `View Logs`. Anything less verbose than the chosen level is dropped: `Trace` records everything; `Critical` records only the most severe entries. Set this lower (`Debug` or `Trace`) before reproducing an issue you intend to report so the relevant detail is captured; raise it back up after to keep the log small. + +### Pre-release Builds + +A footer toggle. When `True`, `Help` → `Check for Updates` includes pre-release GitHub releases as candidates. Stable releases are always considered regardless of this setting. + +[Docs home](Home.md) diff --git a/docs/Updates-And-Diagnostics.md b/docs/Updates-And-Diagnostics.md new file mode 100644 index 00000000..69aada4a --- /dev/null +++ b/docs/Updates-And-Diagnostics.md @@ -0,0 +1,51 @@ +# [EventLogExpert](Home.md) + +## Updates and Diagnostics + +The `Help` menu hosts everything related to the build you're running and its diagnostic surface. + +### Docs + +Opens this docs site in the default browser. + +### Submit an Issue + +Opens the GitHub issue tracker in the default browser, with the new-issue form pre-selected. No data leaves the app — the form is blank, you fill it in. + +### Check for Updates + +Triggers an immediate check against the GitHub releases feed. Stable releases are always considered. When `Tools` → `Settings` → `Pre-release Builds` is enabled, pre-release tags are also considered. + +The `.appinstaller` distributed with each release also wires up app-installer-driven background update checks on every launch, so this entry is mostly for "what's the latest right now" — the app finds new releases on its own. + +### Release Notes + +Opens the Release Notes modal, which renders the markdown body of the published GitHub release for the running build. The modal can only render notes that the most recent `Check for Updates` succeeded in fetching for the running version — that means the running version was the newest applicable release at the time of the check. When the running build is behind (a newer release exists), when the version isn't published on GitHub, or when no update check has completed yet, an alert titled `Release Notes Failure` appears instead and the modal stays closed. Run `Check for Updates` first when in doubt. + +### View Logs + +Opens the Debug Log modal — the in-app view of the rolling diagnostic log written by the running session. The same log is also accessible as a file under the per-user app data directory; `View Logs` is the in-app surface. + + ![Debug Log modal](.images/debug-log-modal.png) + +Filter bar: + +| Control | Behavior | +| --- | --- | +| `Level` operator | `Equals`, `Not Equal`, or `Multi Select`. | +| `Level` value | Single dropdown when the operator is `Equals` or `Not Equal` (with `All` to disable the filter); multi-select dropdown when the operator is `Multi Select`. | +| `Filter messages...` | Free-text substring filter applied to the message column. Case-insensitive. | + +Footer: + +| Control | Behavior | +| --- | --- | +| `Export` | Saves the currently-filtered rows to a file (file dialog). | +| `Copy` | Copies the currently-filtered rows to the clipboard. | +| ` of entries` | Live counter — filtered rows over total rows. | +| `Refresh` | Re-reads the on-disk log file. | +| `Clear` | Truncates the on-disk log file and the in-memory view. There is no confirmation. | + +Set `Tools` → `Settings` → `Logging Level` to a more verbose value before reproducing an issue you intend to report; both `Export` and `Copy` honor whatever the filter bar is currently showing, so narrow to the relevant rows first. + +[Docs home](Home.md) diff --git a/docs/Viewing-Events.md b/docs/Viewing-Events.md new file mode 100644 index 00000000..bf8d5346 --- /dev/null +++ b/docs/Viewing-Events.md @@ -0,0 +1,52 @@ +# [EventLogExpert](Home.md) + +## Viewing Events + +The main view has three regions: the **tab strip** (one tab per open log, plus a `Combined` tab when more than one log is open), the **event table**, and the **Details pane** (collapsible, bottom). The status bar runs along the very bottom — see [Opening Logs](Opening-Logs.md#live-log-behavior) for what it shows for live logs. + + ![Main view: tabs, event table, Details pane](.images/EventLogExpert-CombinedView.png) + +### Tab strip + +- One tab per open log. The tab label is the log's short name (file name for `.evtx`, channel name for live logs). The tab tooltip shows the full path / channel name. +- A `Combined` tab appears when two or more logs are open. It shows every event from every open log interleaved by time and rendered in the configured time zone. +- Click a tab to switch to it. The `×` on each per-log tab closes just that log; `Combined` has no close button and disappears on its own when the open-log count drops below two. +- A tab spinner appears next to the label while a log is loading. + +### Event table + +The table is virtualized — only the rows currently in view are rendered, so loading large `.evtx` files stays responsive. + +**Configurable columns.** Right-click a column header to open the column menu: + +- A toggle per column (checked = visible). The available columns are `Level`, `Date and Time`, `Activity ID`, `Log`, `Computer Name`, `Source`, `Event ID`, `Task Category`, `Keywords`, `Process ID`, `Thread ID`, and `User`. The `Description` column is fixed and always rightmost. +- An `Order By` submenu pinned to the same set of columns. The checked column is the current sort key. +- `Reset Column Defaults` returns the visibility, ordering, and sort to first-launch state. + +The current sort indicator (a caret) appears in the active column header; clicking it flips between ascending and descending. + +**Column reordering.** Drag a column header sideways to drop it before or after another column. The new order persists across sessions until `Reset Column Defaults` (in the column menu) restores it. + +**Column sizing.** Drag a column-header edge to resize. Sizes persist across sessions; `Reset Column Defaults` restores the built-in widths along with visibility, ordering, and sort. + +**Per-row highlighting.** When a filter has a `Highlight Color` set, every event matching that filter is rendered with that background color. The configured colors live alongside the filter — see [Filtering](Filtering.md). When several enabled, non-excluded filters could highlight the same row, the first one in pane order wins. + +**Selection.** Click to select. Ctrl+Click toggles individual rows. Shift+Click selects a range from the anchor to the clicked row. Arrow keys, Page Up / Page Down, Home, and End move within the table; Shift + those keys extends the selection. `Ctrl+A` selects every visible row; `Escape` clears the selection. The selection drives both the `Ctrl+C` clipboard copy (see [Keyboard and Copy](Keyboard-And-Copy.md)) and the Details pane. + +**Right-click on a row.** Opens a context menu: + +- `Copy Selected` / `Copy Selected (Simple)` / `Copy Selected (XML)` / `Copy Selected (Full)` — same four formats as the `Edit` menu. +- `Exclude Events Before` / `Exclude Events After` — sets a date filter using the right-clicked event's timestamp as the boundary. +- `Include` and `Exclude` submenus — each lists the filter categories applicable to a single field comparison. Picking one creates a new basic filter (or exclusion) for that field equal to the right-clicked event's value. Today this works for `Event ID`, `Activity ID`, `Level`, `Keywords`, `Source`, and `Task Category`; the `Process ID`, `Thread ID`, and `User ID` items are present in the menu but produce empty filter values, so they currently no-op. + +### Details pane + +The Details pane sits at the bottom of the window. It hides itself when no event is selected. The header expand/collapse arrow shows the same content; behavior on selection-change is governed by `Tools` → `Settings` → `Expand Display Pane On Selection Change`. + +The top of the pane shows the same fields as a Windows Event Viewer details view: `Log Name`, `Source`, `Event Id`, `Level`, `Keywords` (only when present), and `Date and Time`. Below those, the `Description` paragraph is the resolved event description text (the same text the table previews in the `Description` column). + +Below the description, an `XML` toggle expands the raw event XML. The XML is resolved on demand the first time the toggle is opened for a given event — the placeholder text is `Resolving XML...` until resolution completes. Events with no XML available render `No XML available for this event.`. + +The pane can be resized vertically by dragging the splitter at the top. + +[Docs home](Home.md) diff --git a/docs/Viewing.md b/docs/Viewing.md deleted file mode 100644 index 253e94ef..00000000 --- a/docs/Viewing.md +++ /dev/null @@ -1,28 +0,0 @@ -# [EventLogExpert](Home.md) - -## Selecting, scrolling, and reading events - -* Events can be selected with a mouse click. -* Tab moves the selection to the next event. -* Shift-Tab moves the selection to the previous event. -* Arrow keys can be used to scroll the view up or down. -* Page Up/Page Down can also be used to scroll the view up or down. -* When an event is selected, the Description of that event appears in the pane at the bottom of the window. -* The arrow toggle at the very bottom right shows the XML for the event. -* The bottom pane can be resized by dragging. -* The bottom pane can be collapsed with the arrow toggle at the top right of that pane. - -## Viewing multiple log files at once - -* When more than one log is opened in the same window, a Combined tab appears which shows all the event logs combined, normalized ot the same time zone, and sorted by time. -* To help distinguish between events from different logs, the View menu has two options: - * Show Log Name Column - adds a column showing the file name of the log, if it is a file, or the log name of the live log. - * Show Computer Name column - adds a column showing the computer name stored in the event log. - -## Viewing live logs - -* When a live log is open, new events arriving from that log will be stored in a buffer. This is indicated by the New Events number shown in the status bar at the bottom of the window. -* From the View menu, choose Load New Events to add those new events to the view. -* Choosing Continuously Update from the View menu will cause those events to be added to the view immediately as they arrive. - -[Docs home](Home.md)