Herdr UI
Herdr의 TUI가 뛰어나며, 창을 통해 추가되는 기능
Windows XML 이벤트 로그(EVTX) 형식을 빠르고 안전하게 파싱합니다
A Fast (and safe) parser for the Windows XML Event Log (EVTX) format
개발 도구Rust · TypeScriptGitHub @omerbenamram직접 설치운영자 미확인
써 보셨어요? 한 번만 눌러 주세요. 로그인은 필요 없어요.
메이커가 쓴 소개는 위의 한 줄이 전부입니다. 더 자세한 내용은 저장소 README에서 읽을 수 있습니다. 저장소 README ↗
README 전체를 불러오는 중입니다.
README 전문 보기 ↗Prefer a zero-install option? A fully-featured EVTX explorer runs right in your browser, powered by the same Rust core compiled to WebAssembly.
👉 Try it now: https://omerbenamram.github.io/evtx/
Everything happens locally – files never leave your machine. Highlights:
.evtx files (or click to browse) – handles very large logs!EventData fields – all backed by DuckDB-WASMThe viewer is served statically from GitHub Pages; after the first load it works completely offline.
cargo install evtxevtx_dump (Binary utility):The main binary utility provided with this crate is evtx_dump, and it provides a quick way to convert .evtx files to
different output formats.
Some examples
evtx_dump <evtx_file> will dump contents of evtx records as xml.evtx_dump -o json <evtx_file> will dump contents of evtx records as JSON.evtx_dump -f <output_file> -o json <input_file> will dump contents of evtx records as JSON to a given file.cat <evtx_file> | evtx_dump -o jsonl - will read the EVTX file from stdin (useful for piping/decompression).evtx_dump can be combined with fd for convenient batch processing of files:
fd -e evtx -x evtx_dump -o jsonl will scan a folder and dump all evtx files to a single jsonlines file.fd -e evtx -x evtx_dump '{}' -f '{.}.xml' will create an xml file next to each evtx file, for all files in folder recursively!xargs (or gxargs on mac) and jq can be used: fd -a -e evtx | xargs -I input sh -c "evtx_dump -o jsonl input | jq --arg path "input" '. + {path: \$path}'"Note: by default, evtx_dump will try to utilize multithreading, this means that the records may be returned out of order.
To force single threaded usage (which will also ensure order), -t 1 can be passed.
EVTX records can reference template definitions stored in provider binaries (EXE/DLL/SYS). evtx_dump can extract those templates into an offline cache and use them at render time.
Note: this functionality requires building evtx_dump with the Cargo feature wevt_templates (release binaries may already include it).
.wevtcache file):
evtx_dump extract-wevt-templates --input <provider.dll> --output /tmp/wevt_cache.wevtcache --overwriteevtx_dump --wevt-cache /tmp/wevt_cache.wevtcache <log.evtx>Debugging helpers:
TemplateInstance substitution values (JSONL):
evtx_dump dump-template-instances --input <log.evtx> --record-id <ID> | head -n1evtx_dump apply-wevt-cache --cache /tmp/wevt_cache.wevtcache --template-guid <GUID> --evtx <log.evtx> --record-id <ID>See docs/wevt_templates.md for details and background (issue #103).
.MTA filesWhen a log is saved with display information (Event Viewer's Save All Events As, or wevtutil al), Windows also writes the event messages and the level, task, opcode and keyword names to LocaleMetaData\<log>_<LCID>.MTA next to the .evtx. evtx_dump can add them to each record as a RenderingInfo element, like the one forwarded events have:
evtx_dump --mta LocaleMetaData/Security_1033.MTA Security.evtxIn the library, this is ParserSettings::mta (see the evtx::mta module). See docs/mta.md for the file format and how Windows matches its strings to events.
use evtx::EvtxParser;
use std::path::PathBuf;
// Change this to a path of your .evtx sample.
let fp = PathBuf::from(format!("{}/samples/security.evtx", std::env::var("CARGO_MANIFEST_DIR").unwrap()));
let mut parser = EvtxParser::from_path(fp).unwrap();
for record in parser.records() {
match record {
Ok(r) => println!("Record {}\n{}", r.event_record_id, r.data),
Err(e) => eprintln!("{}", e),
}
}
The parallel version is enabled when compiling with feature "multithreading" (enabled by default).
When using multithreading - evtx is significantly faster than any other parser available.
For single core performance, it is both the fastest and the only cross-platform parser than supports both xml and JSON outputs.
Performance was benched on my machine using hyperfine (statistical measurements tool).
I'm running tests on a 12-Core AMD Ryzen 3900X.
Bench run: June 2026 (evtx 0.12.2).
System: Arch Linux (Linux 7.0.11-arch1-1 x86_64).
Benchmark commit: 99a6def.
The evtx columns — and pyevtx-rs, our own Python bindings, which wrap the same Rust core — were re-measured in June 2026 on this same machine, after the compiled-template rewrite landed (see docs/compiled-templates.html). Both are the PGO builds that ship for Linux/macOS (the release binary and the PyPI wheel; details below). pyevtx-rs is bound by per-record Python marshaling (one dict per record) rather than the parser, so it does not see the full core speedup. The remaining competitor figures (libevtx, velocidex/evtx, golang-evtx, python-evtx) are carried over unchanged from the January 2026 run on the same hardware — external tools whose performance has not changed.
Libraries benched:
python-evtx(https://github.com/williballenthin/python-evtx) - With CPython and PyPypyevtx-rs(https://github.com/omerbenamram/pyevtx-rs) / evtx(https://pypi.org/project/evtx/) - Python bindings for this librarylibevtx(https://github.com/libyal/libevtx)golang-evtx(https://github.com/0xrawsec/golang-evtx.git) - only JSON (uses multithreading)evtx(https://github.com/Velocidex/evtx) - only JSON.evtx (This library)| evtx (1 thread) | evtx (8 threads) | evtx (24 threads) | libevtx (C) | velocidex/evtx (go) | golang-evtx (uses multiprocessing) | pyevtx-rs (CPython 3.14.5) | python-evtx (CPython 3.13.11) | python-evtx (PyPy 7.3.19) | |
|---|---|---|---|---|---|---|---|---|---|
| 30MB evtx (XML) | 71.6 ms ± 1.8 ms | 20.7 ms ± 1.0 ms | 22.1 ms ± 1.7 ms | 2.439 s ± 0.035 s | No support | No support | 204.6 ms ± 5.7 ms | 2m41.075s (ran once) | 40.096s (ran once) |
| 30MB evtx (JSON) | 75.1 ms ± 2.1 ms | 20.5 ms ± 0.8 ms | 20.1 ms ± 0.9 ms | No support | 5.467 s ± 0.038 s | 1.344 s ± 0.005 s | 223.1 ms ± 4.7 ms | No support | No support |
Note: numbers shown are real-time measurements (time it takes for invocation to complete). user-time measurements are higher when more using multithreading/multiprocessing, because of the synchronization overhead.
With 8 threads - evtx is more than 7000x faster than python-evtx when dumping xml logs.
Throughput now saturates at around 8 threads on this 30MB sample: single-threaded parsing got fast enough (~3.8x faster than the January 2026 numbers, on the same machine) that 30MB no longer holds enough work to keep all 24 logical cores busy — 24 threads is no faster than 8 (the two are within measurement noise, so the table highlights the 8-thread column as the saturation point). At that point evtx is about 65x faster than golang-evtx, which uses a similar multithreading strategy.
The numbers above come from a profile-guided build (./build_pgo.sh): it trains an instrumented binary on the sample corpus, then rebuilds with that profile. CI runs this for the Linux (x86_64) and macOS release binaries, so the table reflects the artifact most people download (output is byte-identical to a normal build). PGO is worth roughly 2–5% of single-threaded throughput over a plain cargo build --release --features fast-alloc (JSON 77.6 → 75 ms, XML 73.0 → 71 ms); at 8+ threads the workload is saturation-bound, so PGO there is within measurement noise.
If the parser errors on any of these nodes, feel free to open an issue or drop me an email with a sample.
Licensed under either of
at your option.
Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions.