Decode manifest value maps and unbox event-record properties#617
Merged
Conversation
Contributor
There was a problem hiding this comment.
Pull request overview
This PR improves event description rendering accuracy and reduces per-event allocations by (1) decoding provider manifest valueMap/bitMap definitions from the provider’s WEVT_TEMPLATE resource and applying them during formatting, and (2) replacing boxed object event properties with an unboxed EventProperty struct.
Changes:
- Parse
WEVT_TEMPLATEto recover value/bit maps, resolve their entry strings viaEvtFormatMessage, and injectmap=attributes back into templates for analysis/formatting. - Unbox event record properties into
IReadOnlyList<EventProperty>and update formatting logic to use kind-tagged packed values. - Add unit tests covering map extraction/decoding, template analysis, property packing, and resolver formatting output.
Reviewed changes
Copilot reviewed 20 out of 20 changed files in this pull request and generated 4 comments.
Show a summary per file
| File | Description |
|---|---|
| tests/Unit/EventLogExpert.Provider.Tests/Resolution/ValueMapDefinitionTests.cs | Adds coverage for valueMap/bitMap decoding behavior. |
| tests/Unit/EventLogExpert.Eventing.Tests/Resolvers/TemplateAnalyzerTests.cs | Tests extraction of map= attributes and visible/all alignment. |
| tests/Unit/EventLogExpert.Eventing.Tests/Resolvers/EventResolverBaseTests.cs | Adds resolver regression tests for map decoding and unboxed property formatting. |
| tests/Unit/EventLogExpert.Eventing.Tests/Readers/EventPropertyTests.cs | Validates EventProperty kind tagging, equality, and unsigned-bit extraction. |
| tests/Unit/EventLogExpert.Eventing.Tests/PublisherMetadata/WevtTemplateReaderTests.cs | Tests parsing WEVT_TEMPLATE binaries and map recovery. |
| tests/Unit/EventLogExpert.Eventing.Tests/PublisherMetadata/EventMessageProviderTests.cs | Tests map= injection behavior into templates. |
| tests/Shared/EventLogExpert.Eventing.TestUtils/EventUtils.cs | Updates test helper to accept EventProperty lists. |
| src/EventLogExpert.Provider/Resolution/ValueMapDefinition.cs | Introduces map definition/entry types and decoding logic. |
| src/EventLogExpert.Provider/Resolution/ProviderDetails.cs | Adds Maps to provider details for runtime decoding. |
| src/EventLogExpert.Provider.Database/Context/ProviderDbContext.cs | Excludes Maps from EF persistence (runtime-only). |
| src/EventLogExpert.Eventing/Resolvers/TemplateMetadata.cs | Extends template metadata to include per-<data> map names. |
| src/EventLogExpert.Eventing/Resolvers/TemplateAnalyzer.cs | Extracts map= attributes alongside outType= and tracks visible/all arrays. |
| src/EventLogExpert.Eventing/Resolvers/DescriptionFormatter.cs | Uses EventProperty + template maps to format/decode values and bit flags. |
| src/EventLogExpert.Eventing/Readers/EventRecord.cs | Switches Properties to IReadOnlyList<EventProperty>. |
| src/EventLogExpert.Eventing/Readers/EventProperty.cs | Adds 16-byte readonly struct for unboxed event properties. |
| src/EventLogExpert.Eventing/PublisherMetadata/WevtTemplateReader.cs | Implements WEVT_TEMPLATE parsing and runtime map extraction. |
| src/EventLogExpert.Eventing/PublisherMetadata/ProviderMetadata.cs | Exposes publisher GUID/resource path and message-by-id formatting helper. |
| src/EventLogExpert.Eventing/PublisherMetadata/EventMessageProvider.cs | Populates maps from WEVT_TEMPLATE and injects map= attributes into templates. |
| src/EventLogExpert.Eventing/Interop/NativeMethods.Evt.cs | Adds ConvertVariantToProperty and updates property rendering to unboxed list. |
| src/EventLogExpert.Eventing/Interop/NativeMethods.cs | Adds FindResourceW interop for string-typed resource lookup. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
706d56b to
156e810
Compare
156e810 to
5c82986
Compare
NikTilton
approved these changes
Jun 22, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Two resolver changes that improve description accuracy and cut per-event allocation, with byte-identical output verified against a golden corpus.
1. Decode manifest value maps and bit maps
Event descriptions now decode
valueMap/bitMapparameters from the provider manifest, matching what Windows (Get-WinEvent/EvtFormatMessage) shows. Windows exposes no API for the map definitions and strips themap=attribute from rendered templates, so the maps are parsed directly from the provider'sWEVT_TEMPLATEPE resource (newWevtTemplateReader). Raw values likeBus Type: 10now resolve toBus Type: SAS; bitmap flag sets and GUID braces are handled too.2. Unbox event-record properties
EventRecord.Propertiesbecomes anIReadOnlyList<EventProperty>, whereEventPropertyis a 16-byte readonly struct that eliminates the per-property boxing the previousIList<object>forced. Numeric, boolean andDateTimevalues pack into the struct behind a shared per-kind sentinel; reference values stay in the object slot. This cuts per-event resolution allocation by roughly 776 B/event on numeric-heavy logs (for example Ntfs/Operational), with no measurable change on string-heavy logs.Resolution output is byte-for-byte identical before and after both changes, verified by a golden diff over 86,353 real events across four event logs.
Known limitation
Value-map decoding applies on the live-provider resolution path only. Providers resolved from a cached provider database (
.db) fall back to raw values, because the database does not persist map definitions. This matches the existing DB-path behavior (it showed raw values before this change too). Adding database support is planned as a follow-up.Testing