Files
logpile/bible-local/07-exporters.md
T
Mikhail ChusavitinandClaude Sonnet 5 a63bb17438 feat(sanitize): in-place, length-preserving log de-identification
Adds internal/sanitize: rewrites the customer-identifying spans that
internal/privacy detects (domain/FQDN/e-mail/AD/public-IP/timezone) with
same-length neutral fillers, in place, without changing the file format.

- Fillers keep byte length: "sigma.sbrf.ru" -> "xxxxx.xxxx.xx", IP ->
  "00.000.000.00", "Europe/Moscow" -> "Etc/Universal" (same-length valid
  neutral IANA zone), offset "180" -> "000". Timestamps are not recomputed.
- Lossless recursive archive walk (tar/.sds/gz/tgz/zip): entry names, modes,
  and all embedded timestamps preserved; untouched zip entries copied raw;
  member payload length unchanged so tar headers stay byte-identical; only the
  .gz/.zip compression layer is rebuilt. 0 redactions -> byte-identical output.
- privacy.FindSpans is the one matcher shared by detection and redaction;
  fillers are recognised by isRedactionFiller so a re-scan / second pass is a
  no-op. New privacy FPs fixed along the way: syslog selectors (local7.info),
  "MEVersion" firmware quads, *.conf_bak vendor templates, bundled viewer
  domains.
- Binary members (FRU.bin, localtime, redis-dump.rdb, SOL captures) and
  unreadable nested archives are reported in Result.SkippedBinary, never edited.
- Surfaces: POST /api/sanitize (+ GET /api/sanitize/download), the "Обезличить
  и скачать копию" button in the Customer-data panel, and
  logpile -sanitize <file> (restores mtime/atime).

Verified: re-parsing a sanitized Dell TSR / xFusion / Inspur onekeylog / H3C
.sds yields the identical hardware inventory; re-scan is clean. ADL-067,
bible-local/docs/log-sanitization.md.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-02 18:05:27 +03:00

115 lines
5.9 KiB
Markdown

# 07 — Exporters
## Export surfaces
| Endpoint | Output | Purpose |
|----------|--------|---------|
| `GET /api/export/csv` | CSV | Serial-number export |
| `GET /api/export/json` | raw-export ZIP bundle | Reopen and re-analyze later |
| `GET /api/export/reanimator` | JSON | Reanimator hardware payload |
| `GET /chart/current?print=true` | HTML (auto-print) | Print/PDF version of the report — opens in new tab, calls `window.print()` |
| `POST /api/convert` | async ZIP artifact | Batch archive-to-Reanimator conversion |
| `POST /api/sanitize` + `GET /api/sanitize/download` | same-format file | De-identified copy of the upload (`docs/log-sanitization.md`) |
## Raw export
Raw export is not a final report dump.
It is a replayable artifact that preserves enough source data for future parser improvements.
Current bundle contents:
- `raw_export.json`
- `collect.log`
- `parser_fields.json`
- `privacy_report.json` (only when the customer-data scan produced findings; see `docs/privacy-scan.md`)
Design rules:
- raw source is authoritative
- uploads of raw export must replay from raw source
- parsed snapshots inside the bundle are diagnostic only
## Reanimator export
Implementation files:
- `internal/exporter/reanimator_models.go`
- `internal/exporter/reanimator_converter.go`
- `internal/server/handlers.go`
- `bible-local/docs/hardware-ingest-contract.md`
Conversion rules:
- canonical source is merged canonical inventory derived from `hardware.devices` plus legacy hardware slices
- output must conform to the strict Reanimator ingest contract in `docs/hardware-ingest-contract.md`
- local mirror currently tracks upstream contract `v2.7`
- timestamps are RFC3339
- status is normalized to Reanimator-friendly values
- missing component serial numbers must stay absent; LOGPile must not synthesize fake serials for Reanimator export
- CPU `firmware` field means CPU microcode, not generic processor firmware inventory
- `NULL`-style board manufacturer/product values are treated as absent
- optional component telemetry/health fields are exported when LOGPile already has the data
- partial `hardware.devices` must not suppress components still present only in legacy parser/collector fields
- `present` is not serialized for exported components; presence is expressed by the existence of the component record itself
- Reanimator ingest may apply its own server-side fallback serial rules for CPU and PCIe when LOGPile leaves serials absent
## Inclusion rules
Included:
- PCIe-class devices when the component itself is present, even if serial number is missing
- contract `v2.7` component telemetry and health fields when source data exists
- hardware sensors grouped into `fans`, `power`, `temperatures`, `other` only when the sensor has a real numeric reading
- sensor `location` is not exported; LOGPile keeps only sensor `name` plus measured values and status
- Redfish linked metric docs that carry component telemetry: `ProcessorMetrics`, `MemoryMetrics`, `DriveMetrics`, `EnvironmentMetrics`, `Metrics`
- `pcie_devices.slot` is treated as the canonical PCIe address; `bdf` is used only as an internal fallback/dedupe key and is not serialized in the payload
- `event_logs` are exported only from normalized parser/collector events that can be mapped to contract sources `host` / `bmc` / `redfish` without synthesizing content
- `manufactured_year_week` is exported only as a reliable passthrough when the parser/collector already extracted a valid `YYYY-Www` value
Excluded:
- storage endpoints from `pcie_devices`; disks and NVMe drives export only through `hardware.storage`
- fake serial numbers for PCIe-class devices; any fallback serial generation belongs to Reanimator ingest, not LOGPile
- sensors without a real numeric reading
- events with internal-only or unmappable sources such as LOGPile internal warnings
- memory with missing serial number
- memory with `present=false` or `status=Empty`
- CPUs with `present=false`
- storage without `serial_number`
- storage with `present=false`
- power supplies without `serial_number`
- power supplies with `present=false`
- non-present network adapters
- non-present PCIe / GPU devices
- device-bound firmware duplicated at top-level firmware list
- any field not present in the strict ingest contract
## Batch convert
`POST /api/convert` accepts multiple supported files and produces a ZIP with:
- one `*.reanimator.json` file per successful input
- `convert-summary.txt`
Behavior:
- unsupported filenames are skipped
- each file is parsed independently
- one bad file must not fail the whole batch if at least one conversion succeeds
- result artifact is temporary and deleted after download
## CSV export
`GET /api/export/csv` uses the same merged canonical inventory as Reanimator export,
with legacy network-card fallback kept only for records that still have no canonical device match.
## CPU identity audit CLI
`go run ./cmd/logpile-cpu-audit -input <dump-or-directory> -output <directory>` recursively parses
supported dump files and writes one `*.cpu-audit.json` report per input plus `_summary.json`.
Reports contain only parser provenance and CPU identity fields needed to audit the PPIN-to-serial
fallback. Parse failures are isolated per input and recorded in both the file report and summary.
Directory scans exclude standalone `.txt` and `.log` files by default so unpacked dump contents are
not treated as separate dumps. Use `-include-plain` when the input tree intentionally contains whole
single-file diagnostic logs. `-workers` controls bounded concurrent parsing and defaults to at most
four workers.
For direct Reanimator ingest, add `-reanimator -prefix <dataset>`. This mode writes a flat set of
`*.reanimator.json` files and skips inputs without CPUs or without the required board identity. Each
payload keeps the required top-level `collected_at`, `filename`, and `hardware.board`, while
`hardware` contains no component section except `cpus`. No audit/summary JSON is written into that
directory, so every JSON file there is an ingest payload.