Skip to main content

awesome-log-data

A pipeline that ingests security log datasets from multiple sources — Windows event logs, cloud audit trails, Linux auditd, network logs, and more — and normalizes them into one consistent record format. The goal is a single, straightforward way to pull structured, high-signal security log data into a downstream project (e.g. for embedding/ML work) without hand-rolling a parser per dataset.

Each dataset keeps its original field structure — records aren't remapped to a shared schema — but every record is wrapped the same way and indexed the same way, so consuming five different log formats looks the same from the calling code's perspective.

Datasets

dataset_id What it is License Labeled
otrf OTRF Security Datasets — Windows/cloud event logs (Sysmon, Windows Event Log, CloudTrail) generated by simulated attack techniques, plus raw Linux auditd logs and some Zeek network logs GPL-3.0 yes
evtx_attack_samples EVTX-ATTACK-SAMPLES — raw Windows .evtx event log files, one or more per attack technique GPL-3.0 yes
flaws_cloud flaws.cloud — real AWS CloudTrail logs from a public cloud-security CTF unspecified yes
ait_lds AIT Log Data Set v2 — Apache access logs, Linux auditd logs, Suricata NIDS events, and Metricbeat/ECS JSON from simulated multi-host attack scenarios CC-BY-NC-SA-4.0 no
elastic_fixtures elastic/integrations test fixtures — real-world sample logs for hundreds of vendor products (AWS, Okta, Auth0, Microsoft 365, CrowdStrike, and more), used by Elastic to test their own ingest pipelines Elastic-2.0 no
splunk_attack_data Splunk attack_data — Windows Event XML, Linux auditd, and cloud/SaaS JSON logs generated per MITRE ATT&CK technique Apache-2.0 yes

"Labeled" means each record can be tied back to the specific attack technique that produced it (per the manifest's labeled field) — useful if you want ground truth for a specific behavior, not just a corpus of logs.

Each dataset's exact source URL and license are also recorded per-file in data/manifest.jsonl after ingestion (see Manifest below) — the table above is a summary, not the source of truth.

Requirements

  • Python 3.14+
  • uv

Install dependencies:

uv sync

Fetching raw data

scripts/fetch_datasets.sh list              # list available dataset_ids
scripts/fetch_datasets.sh <dataset_id>       # fetch one dataset
scripts/fetch_datasets.sh all                # fetch every dataset

This downloads each dataset's raw files into data/raw/<dataset_id>/ (gitignored — raw data isn't checked into the repo). Requires git and curl; ait_lds additionally requires jq, and splunk_attack_data additionally requires git-lfs (its raw samples are stored via LFS; the fetch script pulls a scoped subset of the ~23GB upstream repo rather than the whole thing — only files whose extension could plausibly be a format the adapter supports).

Ingesting a dataset

Once a dataset's raw files are on disk (via the fetch script, or placed there yourself), run the CLI:

uv run python -m awesome_log_data.cli <dataset_id> <path-to-raw-files>

For example:

uv run python -m awesome_log_data.cli otrf data/raw/otrf

This walks the raw files, extracts archives as needed, parses every recognized log file, and writes:

  • data/manifest.jsonl — one entry per ingested source file (see Manifest).
  • data/parsed/<dataset_id>/ — the parsed records themselves, sharded across fixed-size JSONL files with a shard_index.parquet (plus a small source_ids.jsonl sidecar) for random access (see Reading parsed data).

Re-running the same command is safe and incremental: files already recorded in the manifest (by checksum) are skipped, so only newly added raw files get parsed and appended.

Record format

Each shard file holds the bare parsed record on every line, in that dataset's native field structure — not remapped to a common schema, and not wrapped in any envelope, so the shard files can be read directly as the training corpus:

{"eventName": "GetObject", "...": "..."}

Provenance for each record lives alongside it in shard_index.parquet, not in the record itself (see Reading parsed data):

  • source_id — an int identifying the raw file this record came from. It's an index into source_ids.jsonl (one JSON string per line, line number = id) rather than the string itself, to avoid repeating that string once per record — a source file's records are otherwise identical strings repeated thousands of times over. Look the string up via dataset.source_ids[source_id], then that string (<dataset_id>/<file_name>, or <dataset_id>/<file_name>#<hash> if two different files happened to share a file_name — see the manifest's collision handling) in data/manifest.jsonl for the file's source URL, license, checksum, etc.
  • record_ref — an offset back into the original raw file (byte offset, array index, or Windows event record ID depending on the format) that can re-derive this exact record from source, independent of the parsed/sharded copy.

Manifest

data/manifest.jsonl has one entry per ingested raw file:

{
  "source_id": "otrf/ec2_proxy_s3_exfiltration/ec2_proxy_s3_exfiltration_2020-09-14011940.json",
  "dataset_id": "otrf",
  "file_name": "ec2_proxy_s3_exfiltration/ec2_proxy_s3_exfiltration_2020-09-14011940.json",
  "source_url": "https://github.com/OTRF/Security-Datasets",
  "license": "GPL-3.0",
  "ingested_at": "2026-08-09",
  "checksum_sha256": "...",
  "bytes": 106600,
  "record_count": 103,
  "labeled": true,
  "record_ref_type": "byte_offset",
  "notes": ""
}

Reading parsed data

Use ShardedDataset for indexed, random-access reads over a dataset's already-parsed records — no need to load the whole corpus into memory:

from awesome_log_data.sharded_dataset import ShardedDataset

dataset = ShardedDataset(Path("data/parsed/otrf"))

len(dataset)             # total record count
dataset[0]                # {"eventName": "GetObject", "...": "..."} - the bare parsed record
dataset.indices_for_source("otrf/ec2_proxy_s3_exfiltration/...json")  # all record indices from one raw file

Each record's provenance is a separate ShardIndexEntry at the same index in dataset.index — source_id (an int; resolve the string via dataset.source_ids, then cross-reference against data/manifest.jsonl) and record_ref (to re-derive the record from its original raw file):

from awesome_log_data.manifest import ManifestStore

manifest = ManifestStore(Path("data/manifest.jsonl"))
entry = manifest.get(dataset.source_ids[dataset.index[0].source_id])
entry.source_url, entry.license, entry.labeled

To re-derive a record directly from its original raw file instead of the parsed copy (e.g. to see the exact original bytes, not just the parsed fields), use the registered adapter's parser together with the manifest entry's record_ref_type and dataset.index[0].record_ref:

from awesome_log_data.adapters import get_adapter

adapter = get_adapter(entry.dataset_id)
source = next(
    s for s in adapter.discover(Path("data/raw/otrf"))
    if s.file_name == entry.file_name
)
source.parser.resolve(source.path, dataset.index[0].record_ref)

This requires the original raw files (data/raw/<dataset_id>/) still present on disk — ShardedDataset alone is sufficient for everything else.

Metadata

Release files for awesome-log-data 0.1.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for awesome-log-data 0.1.0
File Size Uploaded
awesome_log_data-0.1.0.tar.gz 22.2 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for awesome-log-data 0.1.0
File Interpreter ABI Platform
awesome_log_data-0.1.0-py3-none-any.whl Python 3 none any Details

Total release size: 56.4 kB

Release files / awesome_log_data-0.1.0.tar.gz

Download URL awesome_log_data-0.1.0.tar.gz
Size 22.2 kB
Tags Source
SHA-256 checksum
How to use checksums
27583aae3490b5e217f1974959ea2adf9060ee70757119843128ca16705340f7
BLAKE2b-256 checksum
How to use checksums
3067f7380a91eb2fd7d15e5c1e7a63a0537683933a8632f224b50d32d1f6028e
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via uv/0.12.5 {"installer":{"name":"uv","version":"0.12.5","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Aug 25, 2026.

Transparency log

Release files / awesome_log_data-0.1.0-py3-none-any.whl

Download URL awesome_log_data-0.1.0-py3-none-any.whl
Size 34.2 kB
Tags Python 3
SHA-256 checksum
How to use checksums
c660b6e83c948c1d30844903423ce1dcf432cd0cef0acb3a024c6cced1c1474f
BLAKE2b-256 checksum
How to use checksums
42a5e63f1df477deb27d54d22306ad0d4c591e598c068ad023d5b2b2d21ad437
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via uv/0.12.5 {"installer":{"name":"uv","version":"0.12.5","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Aug 25, 2026.

Transparency log

Release history Release notifications | RSS feed

0.1.1

2 release files

This release

0.1.0 This release

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page