A single-file, fully offline decoder for Windows event logs. Paste a raw event, get a readable verdict — who did what, to whom, from where — plus every field, with the option to build a correlated timeline across an incident and export a factual summary.
It's one .html file. No install, no server, no build step. Download it and open it in a browser.
- What it is
- Why no AI
- Privacy / offline
- Quick start
- Try it now
- Features
- Supported input formats
- Knowledge base / event coverage
- Scope
- Limitations
- Cases — persistence
- Browser support
- Contributing
- Acknowledgments
- License
You paste a Windows event — from Event Viewer, PowerShell, or a SIEM export — and EventLens reads the raw fields and produces a plain-English verdict: who did what, to whom, from where. Every field is shown alongside it, exactly as it appeared in the source. If you're working an incident, switch to the Case tab to collect events into a timeline, pivot across them by account/IP/host/process, and export a factual summary for handover.
EventLens does not use an LLM, and makes no inference calls of any kind. The decoding is deterministic: a hand-built knowledge base maps known event IDs to plain-language verdict templates, filled in from the event's own fields. This is what makes the offline guarantee possible in the first place — there's no model to call out to, so there's nothing to call out to. It also means the same event always produces the same verdict, which matters for anything you might cite in an investigation.
EventLens makes no network requests of any kind — no telemetry, no CDNs, no web fonts, no analytics. Everything you paste or drop stays in your browser. The only thing it writes is localStorage, and only two keys: your light/dark theme preference and your current case. Nothing is ever sent anywhere.
You don't have to take this on faith:
- Open DevTools → Network tab and use the tool. It stays empty.
- View Source. It's one inline
<script>block — no<script src>tags, no external references of any kind.
- Download
eventlens.html. - Open it in a browser (double-click, or drag it into a tab).
- Paste an event, or drag a log file onto the page.
No log handy? Paste this into EventLens — it's a sample failed-logon event with fictional data:
<Event xmlns='http://schemas.microsoft.com/win/2004/08/events/event'><System><Provider Name='Microsoft-Windows-Security-Auditing' Guid='{54849625-5478-4994-a5ba-3e3b0328c30d}'/><EventID>4625</EventID><Version>0</Version><Level>Information</Level><Task>Logon</Task><Opcode>Info</Opcode><Keywords>Audit Failure</Keywords><TimeCreated SystemTime='2026-06-15T22:14:07.4412310Z'/><EventRecordID>884512</EventRecordID><Correlation/><Execution ProcessID='712' ThreadID='4188'/><Channel>Security</Channel><Computer>WIN10-FIN-04.corp.example.local</Computer><Security/></System><EventData><Data Name='SubjectUserSid'>S-1-0-0</Data><Data Name='SubjectUserName'>-</Data><Data Name='SubjectDomainName'>-</Data><Data Name='SubjectLogonId'>0x0</Data><Data Name='TargetUserSid'>S-1-0-0</Data><Data Name='TargetUserName'>jsmith</Data><Data Name='TargetDomainName'>CORP</Data><Data Name='Status'>0xC000006D</Data><Data Name='FailureReason'>%%2313</Data><Data Name='SubStatus'>0xC000006A</Data><Data Name='LogonType'>10</Data><Data Name='LogonProcessName'>NtLmSsp </Data><Data Name='AuthenticationPackageName'>NTLM</Data><Data Name='WorkstationName'>KALI</Data><Data Name='IpAddress'>185.220.101.47</Data><Data Name='IpPort'>52133</Data></EventData></Event>(The tool also ships with a "Load sample" button covering 10 events across XML/JSON/text, if you'd rather click than paste.)
-
Verdict line — a plain-English, one-line summary built from the event's own fields.
-
Visual priority colour-coding — Routine / Notable / Investigate / High concern. This is about how much an event should stand out at a glance (a cleared log is louder than a routine logon), not a threat or severity judgement about whether something is malicious.
-
Provider-aware decoding — the same event number is read correctly depending on its source (Security, System/SCM, Sysmon, PowerShell, Defender).
-
Decoded annotations — logon types, failure/Kerberos status codes, and similar values are translated to plain language. These annotate the source; they never replace the raw value.
-
Decode filter box — once more than a couple of events are decoded, a filter box appears so you can narrow the list by event ID, account, IP, or any field value, without building a case.
-
Cases (opt-in tab) — collect events into a UTC timeline, click any row to open it in a detail pane, and pivot across the case by entity (account, IP, host, process, ProcessGUID, logon session, object handle). The pivoted field is highlighted in the detail pane so it's easy to spot inside a verbose card.
-
Export summary — a neutral, factual write-up of a case: timeline plus the unique accounts/IPs/hosts involved. No assessments, no recommendations — the right response depends entirely on your environment.
-
Light / dark theme, remembered per machine.
-
Drag-and-drop file loading.
-
In-app guide — click the
?button for a full walkthrough.
EventLens auto-detects what you paste and shows a "Detected: …" indicator.
| Format | Sources | Reliability |
|---|---|---|
| XML | Event Viewer "XML View", wevtutil /f:xml |
Best |
| JSON | Get-WinEvent | ConvertTo-Json, Winlogbeat/winlog, EvtxECmd — single object, array, or JSON Lines |
Best |
| Text | Event Viewer "General"/Copy text, Get-WinEvent | Format-List |
Best-effort — localised, so non-US date formats may not produce a sortable timestamp and the event lands under "Undated" in the timeline |
Prefer XML or JSON when you have the choice.
You can also paste multiple formats together in a single block — each event is detected and decoded with its own parser, in the order you pasted them, and the indicator shows the mix.
~129 mapped event types across Security, System/SCM, Sysmon, PowerShell, and Defender (click to expand)
Authentication & Logon: 4624, 4625, 4634, 4647, 4648, 4672, 4776, 4778, 4779, 4964, RDP 1149
Kerberos: 4768, 4769, 4771
Account management: 4720, 4722–4726, 4738, 4740, 4741, 4743, 4767, 4781, 4782, 4794, 4765, 4766
Group management: 4727/4731/4754 (create), 4728/4732/4756 (add member), 4729/4733/4757 (remove member), 4730/4734/4758 (delete), 4737, 4764
Privilege / policy / directory: 4717, 4718, 4719, 4713, 4739, 4670, 4662 (includes DCSync detection), 5136
Object access: 4656, 4663, 4660
Process & service: 4688, 4689, 4697, 7045, 7036, 7040, 7031, 7034
Scheduled tasks: 4698, 4699, 4702 (Security channel), plus 106, 140, 141 (Task Scheduler operational log)
File shares: 5140, 5145, 5142, 5143, 5144
Recon: 4798, 4799
Firewall / filtering: 4946, 4947, 4948, 5157
Log tampering & system: 1102, 104, 1100, 1104, 4616, 6008, 6416
Sysmon: 1, 2, 3, 5, 6, 7, 8, 9, 10, 11, 12, 13, 15, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28
PowerShell: 400, 600, 800, 4103, 4104 (script-block logging, with suspicious-token detection)
Microsoft Defender: 1006, 1015, 1116, 1117, 1118, 1119, 1121, 5001, 5007, 5010, 5012, 5013
Events outside this set still parse fully and show every field — they're just labelled "Unmapped event." This is a curated quick-reference set built around the IDs analysts hit most often, not an exhaustive enumeration of every Windows event.
EventLens decodes Windows event logs. It does not handle:
- Binary
.evtxfiles — export to XML or JSON first (Event Viewer,wevtutil, or PowerShell) - Syslog
- Non-Windows logs
- Cloud / Entra / Azure audit logs
- Generic or arbitrary log formats
Not planned, by design — not just "not yet built": loading a custom/user-supplied event dictionary, a backend or sync service of any kind, and built-in detections or scoring beyond visual priority. Keeping the tool single-file and inference-free is the point.
- The verdict line and "next step" hints are heuristic, generic tradecraft — they speed up triage, but they are not detections and don't replace your own analysis or your team's procedures.
- Visual priority is a presentation choice, not a threat verdict.
- This is an analyst working tool, not a chain-of-custody system. Your SIEM/EDR platform remains the source of truth.
- Text-format parsing is localised and best-effort; field names and dates come from the rendered message text.
A case autosaves to the browser it's open in. For shift handover or a durable record, use Export to save it as a .json file, and Import to load it back — on this machine or another. The autosave is a convenience, not the system of record.
Any current Chromium, Firefox, or Safari release. Runs directly from file:// — no server needed.
Issues and PRs are welcome — most useful contribution is probably new event ID coverage. Each knowledge-base entry follows the same shape:
'4625':{c:'Logon',s:'warning',t:'Failed logon',f:d=>`Failed logon for ${tgt(d)} — ${logonDesc(d)}${src(d)}. Reason: <b>${esc(decodeStatus(pick(d,'SubStatus','Status')))}</b>.`,wf:'Pivot on IpAddress + TargetUserName. Many failures followed by a 4624 success = likely successful brute force.'}c = category, s = visual priority (info/notice/warning/critical), t = title, f = a function returning the verdict HTML (always wrap field values in esc()), wf = an optional "next step" hint. Find the right map (SEC, SYSMON, PWSH, or DEFENDER) for the event's provider and add your entry alongside the existing ones.
Event coverage was cross-checked against Microsoft's own event documentation, the Invictus-IR Windows Event Log Analyst Reference, and the community-maintained awesome-event-ids list — credit to those projects and their maintainers for keeping this knowledge public.
MIT — see LICENSE.
EventLens is an independent, community tool and is not affiliated with or endorsed by Microsoft. Product and service names mentioned (Windows, Sysmon, PowerShell, Microsoft Defender, etc.) are trademarks of their respective owners, used here descriptively to identify the log sources this tool decodes.
