From f9230e12f3374f9cbd19f4881c2046c8bb931d14 Mon Sep 17 00:00:00 2001 From: Mikhail Chusavitin Date: Wed, 4 Feb 2026 19:49:05 +0300 Subject: [PATCH] Update README and CLAUDE docs for current Redfish workflow --- CLAUDE.md | 199 ++++++++++++++++++------------------------- README.md | 250 ++++++++++++++++++++++-------------------------------- 2 files changed, 182 insertions(+), 267 deletions(-) diff --git a/CLAUDE.md b/CLAUDE.md index 6cf6117..eeae9a3 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -1,130 +1,95 @@ -# LOGPile - Инструкции для Claude Code +# LOGPile - Engineering Notes (for Claude/Codex) -## Что это за проект +## Project summary -LOGPile - standalone Go-приложение для анализа BMC/IPMI диагностических архивов с веб-интерфейсом. -Приложение запускает локальный HTTP-сервер, парсит архив, автоматически выбирает подходящий parser по vendor и показывает результат в UI + экспортирует данные. +LOGPile is a standalone Go app for BMC diagnostics analysis with embedded web UI. -## Актуальная архитектура +Current product modes: +1. Upload and parse vendor archives / JSON snapshots. +2. Collect live data via Redfish and analyze/export it. -- Язык: Go 1.22+ -- HTTP: стандартный `net/http` + `http.ServeMux` -- UI: embedded (`//go:embed`) HTML/CSS/Vanilla JS -- Бинарник: один executable, без внешних зависимостей на runtime -- Порт по умолчанию: `8082` (а не 8080) +## Runtime architecture -## Реальная структура репозитория +- Go + `net/http` (`http.ServeMux`) +- Embedded UI (`web/embed.go`, `//go:embed templates static`) +- In-memory state (`Server.result`, `Server.detectedVendor`) +- Job manager for live collect status/logs -``` -logpile/ -├── cmd/logpile/main.go -├── internal/ -│ ├── analyzer/ -│ ├── exporter/ -│ ├── models/ -│ ├── parser/ -│ │ └── vendors/ -│ │ ├── generic/ -│ │ ├── inspur/ -│ │ ├── nvidia/ -│ │ ├── nvidia_bug_report/ -│ │ └── supermicro/ -│ └── server/ -├── web/ -│ ├── static/ -│ └── templates/ -├── Makefile -└── go.mod -``` +Default port: `8082`. -## CLI и запуск (актуально) +## Key flows + +### Upload flow (`POST /api/upload`) +- Accepts multipart file field `archive`. +- If file looks like JSON, parsed as `models.AnalysisResult` snapshot. +- Otherwise passed to archive parser (`parser.NewBMCParser().ParseFromReader(...)`). +- Result stored in memory and exposed by API/UI. + +### Live flow (`POST /api/collect`) +- Validates request (`host/protocol/port/username/auth_type/tls_mode`). +- Runs collector asynchronously with progress callback. +- On success: + - source metadata set (`source_type=api`, protocol/host/date), + - result becomes current in-memory dataset. +- On failed/canceled previous dataset stays unchanged. + +## Collectors + +Registry: `internal/collector/registry.go` + +- `redfish` (real collector): + - dynamic discovery of Systems/Chassis/Managers, + - CPU/RAM/Storage/GPU/PSU/NIC/PCIe/Firmware mapping, + - raw Redfish snapshot (`result.RawPayloads["redfish_tree"]`) for offline future analysis, + - progress logs include active collection stage and snapshot progress. +- `ipmi` is currently a mock collector scaffold. + +## Export behavior + +Endpoints: +- `/api/export/csv` +- `/api/export/json` +- `/api/export/txt` + +Filename pattern for all exports: +`YYYY-MM-DD (SERVER MODEL) - SERVER SN.` + +Notes: +- JSON export contains full `AnalysisResult`, including `raw_payloads`. +- TXT export is tabular and mirrors UI sections (no raw JSON section). + +## CLI flags (`cmd/logpile/main.go`) + +- `--port` +- `--file` (reserved/preload, not active workflow) +- `--version` +- `--no-browser` +- `--hold-on-crash` (default true on Windows) — keeps console open on fatal crash for debugging. + +## Build / release + +- `make build` -> single local binary (`CGO_ENABLED=0`). +- `make build-all` -> cross-platform binaries. +- Tags/releases are published with `tea`. +- Release notes live in `docs/releases/.md`. + +## Testing expectations + +Before merge: ```bash -# Сборка -make build - -# Запуск (авто-открытие браузера включено) -./bin/logpile - -# Явный порт -./bin/logpile --port 8082 - -# Не открывать браузер автоматически -./bin/logpile --no-browser - -# Версия -./bin/logpile --version +go test ./... ``` -Важно: сейчас **нет** subcommand `serve`, запуск идёт напрямую через флаги. +If touching collectors/handlers, prefer adding or updating tests in: +- `internal/collector/*_test.go` +- `internal/server/*_test.go` -## Основной runtime-flow +## Practical coding guidance -1. `main.go` регистрирует embedded web FS и запускает сервер. -2. `POST /api/upload` принимает архив и передаёт его в `parser.BMCParser`. -3. `DetectFormat()` выбирает parser с максимальным confidence. -4. Результат сохраняется в памяти (`Server.result`) и отдаётся через API. -5. `POST /api/collect` запускает in-memory mock lifecycle live-сбора (`queued -> running -> success|failed`, поддерживается `cancel`). -6. Для live-flow `AnalysisResult` обновляется только на `success` (при `failed/canceled` остаётся предыдущий результат). -7. UI строит вкладки: конфигурация, прошивки, сенсоры, серийники, события. - -## Поддерживаемые parser modules - -- `supermicro` - Supermicro parser -- `inspur` - Inspur/Kaytus parser -- `nvidia` - NVIDIA Field Diagnostics parser -- `nvidia_bug_report` - parser для `nvidia-bug-report.sh` -- `generic` - fallback parser - -Реестр parser-ов: `internal/parser/registry.go`, подключение модулей: `internal/parser/vendors/vendors.go`. - -## API (фактически в коде) - -``` -POST /api/upload -POST /api/collect -GET /api/collect/{id} -POST /api/collect/{id}/cancel -GET /api/status -GET /api/parsers -GET /api/events -GET /api/sensors -GET /api/config -GET /api/serials -GET /api/firmware -GET /api/export/csv -GET /api/export/json -GET /api/export/txt -DELETE /api/clear -POST /api/shutdown -``` - -## Форматы данных и экспорт - -- `AnalysisResult` агрегирует: events, sensors, FRU, hardware. -- Экспорт реализован в `internal/exporter/exporter.go`: - - CSV: серийные номера компонентов - - JSON: полный `AnalysisResult` - - TXT: человекочитаемый отчёт - -## Важные текущие ограничения (чтобы не ошибаться в задачах) - -- Upload через `/api/upload` использует `ParseFromReader()`, где сейчас поддержаны `.tar`, `.tar.gz`, `.tgz`. -- Код распаковки `.zip` есть, но в текущем upload-пути `zip` не обрабатывается. -- Флаг `--file` присутствует в CLI-конфиге, но preload в `Server.Run()` сейчас не выполняется. -- Данные хранятся только в памяти процесса; перезапуск очищает состояние. -- Live-сбор пока mock-only (реальные Redfish/IPMI коннекторы ещё не подключены). - -## Практические рекомендации для доработок - -- Если меняется parser-логика, обновляй `Version()` соответствующего parser-модуля. -- Новые vendor-парсеры регистрируй через import в `internal/parser/vendors/vendors.go`. -- Для API/контрактов проверяй согласованность `handlers.go` и `web/static/js/app.js`. -- Для UI-изменений не забывай, что ассеты embedded через `web/embed.go`. - -## Приоритетные следующие шаги - -1. Довести поддержку `zip` в upload path (`ParseFromReader`). -2. Реализовать preload из `--file`. -3. Добавить/актуализировать автотесты для parser и HTTP handlers. -4. Расширить vendor coverage (Dell/HPE/Lenovo) по реальным дампам. +- Keep API contracts stable with frontend (`web/static/js/app.js`). +- When adding Redfish mappings, prefer tolerant/fallback parsing: + - alternate collection paths, + - `@odata.id` references and embedded members, + - deduping by serial/BDF/slot+model. +- Avoid breaking snapshot backward compatibility (`AnalysisResult` JSON shape). diff --git a/README.md b/README.md index f7d3ef8..5299596 100644 --- a/README.md +++ b/README.md @@ -1,123 +1,79 @@ # LOGPile -**LOGPile** - это инструмент для анализа диагностической информации с BMC серверов (IPMI). -Представляет собой standalone Go-бинарник со встроенным веб-интерфейсом, который позволяет анализировать и визуализировать данные из архивов BMC. +LOGPile — standalone Go-приложение для анализа диагностических данных BMC. -## Особенности +Поддерживает два сценария: +1. Загрузка архивов/снапшотов и оффлайн-анализ в веб-интерфейсе. +2. Live-сбор через Redfish API с последующим экспортом и повторной загрузкой оффлайн. -- **Поддержка различных производителей**: Supermicro, Inspur/Kaytus, Nvidia и другие -- **Анализ различных типов данных**: - - System Event Log (SEL) - журнал событий IPMI - - Field Replaceable Unit (FRU) - серийные номера компонентов - - Конфигурация сервера (CPU, RAM, диски, и т.д.) -- **Встроенный веб-интерфейс**: Человекочитаемая визуализация данных -- **Экспорт данных**: Поддержка экспорта в CSV, JSON и TXT форматы -- **Автоматическое определение формата**: Для upload path сейчас поддержаны tar.gz/tgz/tar (zip в плане доработки upload) +## Что умеет + +- Standalone бинарник с embedded UI (без внешних статических файлов). +- Парсинг vendor-архивов (Supermicro, Inspur/Kaytus, NVIDIA, fallback generic). +- Live-сбор по Redfish (`/api/collect`) с прогрессом и журналом шагов. +- Расширенный Redfish snapshot: + - нормализованные данные (CPU/RAM/Storage/GPU/PSU/NIC/PCIe/Firmware), + - сырой `redfish_tree` для будущего анализа. +- Загрузка JSON snapshot обратно через `/api/upload` для оффлайн-работы. +- Экспорт в CSV / JSON / TXT. ## Требования - Go 1.22+ -## Установка - -### Сборка из исходников +## Сборка ```bash -# Клонирование репозитория -git clone https://git.mchus.pro/mchus/logpile.git -cd logpile - -# Сборка make build ``` -### Быстрая установка (Linux) +Бинарник будет в `bin/logpile`. + +Для кросс-сборки: ```bash -# Скачать последнюю версию -curl -L https://git.mchus.pro/mchus/logpile/-/releases/latest/download/logpile-linux-amd64.tar.gz | tar xz - -# Запуск -./logpile +make build-all ``` -## Быстрый старт +Артефакты: +- `bin/logpile-linux-amd64` +- `bin/logpile-linux-arm64` +- `bin/logpile-darwin-amd64` +- `bin/logpile-darwin-arm64` +- `bin/logpile-windows-amd64.exe` + +## Запуск ```bash -# Запуск веб-сервера ./bin/logpile - -# Открыть в браузере -open http://localhost:8082 - -# С указанием порта -./bin/logpile --port 9000 - -# Не открывать браузер автоматически +./bin/logpile --port 8082 ./bin/logpile --no-browser +./bin/logpile --version ``` -## Функционал +Отладка падений (чтобы консоль не закрывалась): -### 1. Анализ архивов -- Поддержка upload path: tar.gz/tgz/tar -- Автоматическое определение производителя -- Извлечение всех доступных данных из архива - -### 2. Парсинг данных IPMI -- **System Event Log (SEL)**: Анализ событий системы -- **Field Replaceable Unit (FRU)**: Сбор серийных номеров компонентов -- **Конфигурация сервера**: CPU, RAM, диски, PCIe устройства, сетевые карты и т.д. - -### 3. Визуализация данных -- Интерактивный веб-интерфейс -- Отображение событий в хронологическом порядке -- Таблицы с конфигурацией сервера -- Списки серийных номеров -- Показания сенсоров - -### 4. Экспорт данных -- **CSV**: Экспорт серийных номеров в формате CSV -- **JSON**: Экспорт конфигурации и событий в формате JSON -- **TXT**: Экспорт текстового отчета - -## Поддерживаемые производители - -- **Supermicro** -- **Inspur/Kaytus** -- **Nvidia** -- **Generic** (fallback для неизвестных форматов) - -## API Endpoints - -``` -POST /api/upload # Загрузить архив -POST /api/collect # Создать задачу live-сбора -GET /api/collect/{id} # Получить статус задачи live-сбора -POST /api/collect/{id}/cancel # Отменить задачу live-сбора -GET /api/status # Получить статус парсинга -GET /api/parsers # Получить список доступных парсеров -GET /api/events # Получить список событий -GET /api/sensors # Получить показания сенсоров -GET /api/config # Получить конфигурацию -GET /api/serials # Получить серийные номера -GET /api/firmware # Получить версии прошивок -GET /api/export/csv # Экспорт в CSV -GET /api/export/json # Экспорт в JSON -GET /api/export/txt # Экспорт текстового отчета -DELETE /api/clear # Очистить загруженные данные -POST /api/shutdown # Завершить работу приложения +```bash +./bin/logpile --hold-on-crash ``` -`/api/status` и `/api/config` теперь возвращают унифицированные метаданные источника: -- `source_type`: `archive` или `api` -- `protocol`: `redfish` | `ipmi` (для архивов может быть пустым) -- `target_host`: BMC host для live-сбора -- `collected_at`: timestamp времени получения данных +> На Windows `--hold-on-crash` включён по умолчанию. -### Контракты live-сбора (`/api/collect`) +## Форматы загрузки -`POST /api/collect` принимает JSON: +`POST /api/upload` принимает: +- архивы: `.tar`, `.tar.gz`, `.tgz` +- JSON snapshot (`AnalysisResult`) + +## Live Redfish + +Запуск live-сбора: + +```http +POST /api/collect +``` + +Пример body: ```json { @@ -127,75 +83,69 @@ POST /api/shutdown # Завершить работу приложени "username": "admin", "auth_type": "password", "password": "secret", - "tls_mode": "strict" + "tls_mode": "insecure" } ``` -- Обязательные поля: `host`, `protocol`, `port`, `username`, `auth_type`, `tls_mode` -- `protocol`: `redfish` или `ipmi` -- `auth_type`: `password` или `token` -- `tls_mode`: `strict` или `insecure` -- При `auth_type=password` обязателен `password`, при `auth_type=token` — `token` +Жизненный цикл задачи: +`queued -> running -> success|failed|canceled` -Ответ `202 Accepted`: +Статус и прогресс: +- `GET /api/collect/{id}` +- `POST /api/collect/{id}/cancel` -```json -{ - "job_id": "job_a1b2c3d4e5f6g7h8", - "status": "queued", - "message": "Collection job accepted", - "created_at": "2026-02-04T10:15:20Z" -} +## Экспорт + +- `GET /api/export/csv` — серийные номера +- `GET /api/export/json` — полный `AnalysisResult` (включая `raw_payloads`) +- `GET /api/export/txt` — табличный отчёт по разделам UI + +Имена экспортируемых файлов: + +`YYYY-MM-DD (SERVER MODEL) - SERVER SN.` + +Пример: +`2026-02-04 (SYS-421GE-TNHR2) - C8X123456789.json` + +## API + +```text +POST /api/upload +POST /api/collect +GET /api/collect/{id} +POST /api/collect/{id}/cancel +GET /api/status +GET /api/parsers +GET /api/events +GET /api/sensors +GET /api/config +GET /api/serials +GET /api/firmware +GET /api/export/csv +GET /api/export/json +GET /api/export/txt +DELETE /api/clear +POST /api/shutdown ``` -`GET /api/collect/{id}` возвращает `200 OK` со статусом задачи: +`/api/status` и `/api/config` содержат метаданные источника: +- `source_type`: `archive` | `api` +- `protocol`: `redfish` | `ipmi` (для архивов может быть пустым) +- `target_host` +- `collected_at` -```json -{ - "job_id": "job_a1b2c3d4e5f6g7h8", - "status": "queued", - "progress": 0, - "logs": ["Задача поставлена в очередь"], - "created_at": "2026-02-04T10:15:20Z", - "updated_at": "2026-02-04T10:15:20Z" -} -``` +## Структура -`POST /api/collect/{id}/cancel` возвращает `200 OK` и переводит задачу в `canceled`. -Жизненный цикл задачи: `queued -> running -> success|failed|canceled`. - -### Подключаемые коннекторы live-сбора - -- `redfish`: реальный сбор конфигурации с BMC по REST API (`/redfish/v1/...`) -- `ipmi`: временный mock-коннектор (каркас для последующей замены на реальный IPMI) - -`host` можно передавать как обычный hostname (например, `bmc01.example.local`) или как полный URL (`https://10.0.0.10:8443`). -`AnalysisResult` для API-сценария обновляется на `success`; при `failed/canceled` предыдущие загруженные данные сохраняются. - -## Структура проекта - -``` -logpile/ -├── cmd/logpile/main.go # Точка входа -├── internal/ -│ ├── parser/ # Парсинг архивов и IPMI данных -│ ├── models/ # Модели данных -│ ├── analyzer/ # Логика анализа -│ ├── exporter/ # Экспорт данных -│ └── server/ # HTTP сервер и handlers -├── web/ # Embedded веб-интерфейс -│ ├── static/ # CSS, JS, изображения -│ └── templates/ # HTML шаблоны -├── testdata/ # Примеры архивов для тестов -├── go.mod -├── Makefile -└── README.md +```text +cmd/logpile/main.go # entrypoint +internal/collector/ # live collectors (redfish, ipmi mock) +internal/parser/ # archive parsers +internal/server/ # HTTP handlers +internal/exporter/ # CSV/JSON/TXT export +internal/models/ # data contracts +web/ # embedded templates/static ``` ## Лицензия -Этот проект лицензирован под MIT License - смотрите файл [LICENSE](LICENSE) для получения подробной информации. - -## Автор - -[https://mchus.pro](https://mchus.pro) +MIT — см. `LICENSE`.