
Windows XML Event Log (EVTX) 형식을 위한 빠르고 (안전한) 파서
Windows XML 이벤트 로그 형식을 위한 크로스 플랫폼 파서

설치가 필요 없는 옵션을 선호하시나요? 동일한 Rust 코어를 WebAssembly로 컴파일하여 브라우저에서 바로 실행되는 완전한 기능의 EVTX 탐색기를 사용할 수 있습니다.
👉 지금 사용해보세요: https://omerbenamram.github.io/evtx/
모든 작업은 로컬에서 이루어지며, 파일이 기기를 떠나지 않습니다. 주요 기능:
.evtx 파일 드래그 앤 드롭 (또는 클릭하여 찾아보기) — 매우 큰 로그도 처리 가능!EventData 필드에 대한 패싯 필터 — 모두 DuckDB-WASM으로 구동뷰어는 GitHub Pages에서 정적으로 제공되며, 첫 로드 후 완전히 오프라인에서 작동합니다.
cargo install evtx를 사용하세요.evtx_dump (바이너리 유틸리티):이 크레이트와 함께 제공되는 주요 바이너리 유틸리티는 evtx_dump이며, .evtx 파일을 다양한 출력 형식으로 빠르게 변환할 수 있습니다.
몇 가지 예:
evtx_dump <evtx_file> — evtx 레코드의 내용을 XML로 덤프합니다.evtx_dump -o json <evtx_file> — evtx 레코드의 내용을 JSON으로 덤프합니다.evtx_dump -f <output_file> -o json <input_file> — evtx 레코드의 내용을 JSON으로 지정된 파일에 덤프합니다.cat <evtx_file> | evtx_dump -o jsonl - — stdin에서 EVTX 파일을 읽습니다 (파이핑/압축 해제에 유용).evtx_dump는 fd와 결합하여 파일을 편리하게 일괄 처리할 수 있습니다:
fd -e evtx -x evtx_dump -o jsonl — 폴더를 스캔하고 모든 evtx 파일을 단일 jsonlines 파일로 덤프합니다.fd -e evtx -x evtx_dump '{}' -f '{.}.xml' — 폴더의 모든 파일에 대해 각 evtx 파일 옆에 xml 파일을 생성합니다!xargs(mac에서는 gxargs)와 jq를 사용할 수 있습니다: fd -a -e evtx | xargs -I input sh -c "evtx_dump -o jsonl input | jq --arg path "input" '. + {path: \$path}'"참고: 기본적으로 evtx_dump는 멀티스레딩을 사용하려고 시도하므로 레코드가 순서 없이 반환될 수 있습니다.
단일 스레드 사용을 강제하려면(순서가 보장됨) -t 1을 전달하세요.
EVTX 레코드는 공급자 바이너리(EXE/DLL/SYS)에 저장된 템플릿 정의를 참조할 수 있습니다. evtx_dump는 해당 템플릿을 오프라인 캐시로 추출하고 렌더링 시간에 사용할 수 있습니다.
참고: 이 기능을 사용하려면 Cargo 기능 wevt_templates로 evtx_dump를 빌드해야 합니다 (릴리스 바이너리에 이미 포함되어 있을 수 있음).
.wevtcache 파일):
evtx_dump extract-wevt-templates --input <provider.dll> --output /tmp/wevt_cache.wevtcache --overwriteevtx_dump --wevt-cache /tmp/wevt_cache.wevtcache <log.evtx>디버깅 도우미:
TemplateInstance 대체 값 덤프 (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>자세한 내용과 배경은 docs/wevt_templates.md를 참조하세요 (이슈 #103).
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),
}
}
병렬 버전은 "multithreading" 기능(기본 활성화)으로 컴파일할 때 활성화됩니다.
멀티스레딩을 사용할 때 — evtx는 다른 어떤 파서보다 훨씬 빠릅니다. 단일 코어 성능의 경우, XML과 JSON 출력을 모두 지원하는 유일한 크로스 플랫폼 파서이면서도 가장 빠릅니다.
성능은 hyperfine(통계 측정 도구)을 사용하여 제 머신에서 측정되었습니다.
테스트는 12코어 AMD Ryzen 3900X에서 실행했습니다.
벤치 실행: 2026년 6월 (evtx 0.12.2).
시스템: Arch Linux (Linux 7.0.11-arch1-1 x86_64).
벤치마크 커밋: 99a6def.
evtx 열 — 그리고 동일한 Rust 코어를 래핑하는 자체 Python 바인딩인 pyevtx-rs — 는 컴파일된 템플릿 재작성 후 (자세한 내용은 docs/compiled-templates.html 참조) 2026년 6월 동일한 머신에서 재측정되었습니다. 둘 다 Linux/macOS용으로 제공되는 PGO 빌드입니다 (릴리스 바이너리 및 PyPI 휠; 자세한 내용은 아래 참조). pyevtx-rs는 파서보다는 레코드당 Python 마샬링(레코드당 하나의 dict)에 의해 제한되므로 전체 코어 속도 향상을 보지 못합니다. 나머지 경쟁사 수치(libevtx, velocidex/evtx, golang-evtx, python-evtx)는 동일한 하드웨어에서 2026년 1월 실행에서 변경되지 않은 상태로 유지됩니다. 외부 도구의 성능은 변경되지 않았습니다.
벤치마크 대상 라이브러리:
python-evtx(https://github.com/williballenthin/python-evtx) - CPython 및 PyPy 사용pyevtx-rs(https://github.com/omerbenamram/pyevtx-rs) / evtx(https://pypi.org/project/evtx/) - 이 라이브러리의 Python 바인딩libevtx(https://github.com/libyal/libevtx)golang-evtx(https://github.com/0xrawsec/golang-evtx.git) - JSON만 지원(멀티스레딩 사용)evtx(https://github.com/Velocidex/evtx) - JSON만 지원.evtx (이 라이브러리)참고: 표시된 숫자는 실시간 측정값입니다(호출 완료까지의 시간). 멀티스레딩/멀티프로세싱을 더 많이 사용하면 동기화 오버헤드로 인해 사용자 시간 측정값이 더 높아집니다.
8개 스레드에서 XML 로그를 덤프할 때 evtx는 python-evtx보다 7000배 이상 빠릅니다.
이제 30MB 샘플에서 처리량은 약 8개 스레드에서 포화 상태에 도달합니다. 단일 스레드 파싱은 2026년 1월 수치보다 약 3.8배 빨라져서 24개 논리 코어를 모두 바쁘게 유지할 만큼의 작업이 30MB에 포함되어 있지 않게 되었습니다(24개 스레드는 8개 스레드보다 빠르지 않으며, 측정 노이즈 내에 있으므로 표에서는 8개 스레드 열을 포화 지점으로 강조). 이 시점에서 evtx는 유사한 멀티스레딩 전략을 사용하는 golang-evtx보다 약 65배 빠릅니다.
위의 수치는 프로필 기반 빌드(./build_pgo.sh)에서 나온 것입니다. 계측된 바이너리를 샘플 코퍼스로 학습시킨 후 해당 프로필로 다시 빌드합니다. CI는 Linux (x86_64) 및 macOS 릴리스 바이너리에 대해 이 작업을 실행하므로 표는 대부분의 사람들이 다운로드하는 아티팩트를 반영합니다(출력은 일반 빌드와 바이트 단위로 동일). PGO는 일반 cargo build --release --features fast-alloc보다 단일 스레드 처리량에서 대략 2~5% 정도 가치가 있습니다(JSON 77.6 → 75 ms, XML 73.0 → 71 ms). 8개 이상의 스레드에서는 워크로드가 포화 상태이므로 PGO는 측정 노이즈 내에 있습니다.
파서가 이러한 노드에서 오류를 발생시키면, 샘플과 함께 이슈를 열거나 이메일을 보내주세요.
다음 중 하나에 따라 라이선스가 부여됩니다:
선택 사항입니다.
달리 명시하지 않는 한, Apache-2.0 라이선스에 정의된 대로 귀하가 의도적으로 작업에 제출한 모든 기여는 추가 약관이나 조건 없이 위와 같이 이중 라이선스가 부여됩니다.
| evtx (1 스레드) | evtx (8 스레드) | evtx (24 스레드) | libevtx (C) | velocidex/evtx (go) | golang-evtx (멀티프로세싱 사용) | 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 | 지원 안 함 | 지원 안 함 | 204.6 ms ± 5.7 ms | 2m41.075s (1회 실행) | 40.096s (1회 실행) |
| 30MB evtx (JSON) | 75.1 ms ± 2.1 ms | 20.5 ms ± 0.8 ms | 20.1 ms ± 0.9 ms | 지원 안 함 | 5.467 s ± 0.038 s | 1.344 s ± 0.005 s | 223.1 ms ± 4.7 ms | 지원 안 함 | 지원 안 함 |