1 Commits

Author SHA1 Message Date
Mikhail Chusavitin
f9230e12f3 Update README and CLAUDE docs for current Redfish workflow 2026-02-04 19:49:05 +03:00
2 changed files with 182 additions and 267 deletions

199
CLAUDE.md
View File

@@ -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.<ext>`
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/<tag>.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).

250
README.md
View File

@@ -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.<ext>`
Пример:
`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`.