Some checks failed
release / release (push) Has been cancelled
- Makefile: cross-compile to linux/{amd64,arm64}, darwin/{amd64,arm64},
windows/amd64 into dist/ with SHA256SUMS. Version is stamped via
-ldflags '-X main.version=...'.
- .gitea/workflows/release.yml: on tag push (v*) the workflow runs
`make dist`, creates a Gitea release for the tag and uploads every
artefact from dist/ via the Gitea API.
- main.go: `rb-search version` / --version prints the stamped version.
- README: new "Готовые бинари" section with curl/Invoke-WebRequest
install snippets and a checksum-verify hint.
269 lines
12 KiB
Markdown
269 lines
12 KiB
Markdown
# rb-search
|
||
|
||
Консольная утилита для поиска по сообщениям в очередях RabbitMQ **без их потребления**.
|
||
|
||
## Что делает
|
||
|
||
1. Считывает глубину очереди `N` через `queue.declare-passive`.
|
||
2. Делает `N` раз `basic.get` с `autoAck=false` — сообщения становятся `unacked`,
|
||
для других консьюмеров очередь выглядит пустой, но физически они остаются на брокере.
|
||
3. В памяти проверяет каждое тело на подстроку и печатает совпадения (или все
|
||
сообщения, если фильтр не задан).
|
||
4. Делает `basic.nack(requeue=true)` по delivery-тегам **в обратном порядке** —
|
||
каждое `nack` возвращает сообщение в голову очереди, и после прохода
|
||
очередь восстанавливается в исходном виде. Без дублей, без потери
|
||
`properties` / `headers` (сообщения ни разу не публикуются заново — это те же
|
||
фреймы с другим ack-состоянием).
|
||
|
||
На любой ветке выхода (ошибка, Ctrl+C, паника) defer гарантирует reverse-nack
|
||
до закрытия канала. Если по какой-то причине nack не успел — закрытие канала
|
||
автоматически возвращает unacked-сообщения, но порядок в этом случае не
|
||
гарантируется.
|
||
|
||
## Установка
|
||
|
||
### Готовые бинари (рекомендуется)
|
||
|
||
Собранные релизы лежат на странице
|
||
[Releases](https://git.arx.ru/shuricken/rb-search/releases) — Linux/macOS/Windows,
|
||
amd64 и arm64. Скачать соответствующий файл, проверить контрольную сумму
|
||
из `SHA256SUMS` и положить на `PATH`:
|
||
|
||
```bash
|
||
# Linux/macOS, под свою архитектуру
|
||
curl -LO https://git.arx.ru/shuricken/rb-search/releases/download/vX.Y.Z/rb-search-vX.Y.Z-linux-amd64
|
||
curl -LO https://git.arx.ru/shuricken/rb-search/releases/download/vX.Y.Z/SHA256SUMS
|
||
sha256sum --ignore-missing -c SHA256SUMS
|
||
chmod +x rb-search-*
|
||
sudo mv rb-search-* /usr/local/bin/rb-search
|
||
```
|
||
|
||
```powershell
|
||
# Windows PowerShell
|
||
Invoke-WebRequest -OutFile rb-search.exe `
|
||
https://git.arx.ru/shuricken/rb-search/releases/download/vX.Y.Z/rb-search-vX.Y.Z-windows-amd64.exe
|
||
Move-Item rb-search.exe $env:USERPROFILE\bin\
|
||
```
|
||
|
||
Проверка установки: `rb-search version` → печатает версию.
|
||
|
||
### Из исходников
|
||
|
||
Нужен Go 1.22+. Бинарь самодостаточный, без внешних зависимостей в рантайме.
|
||
|
||
#### Любая ОС
|
||
|
||
```bash
|
||
git clone ssh://git@git.arx.ru:2222/shuricken/rb-search.git
|
||
cd rb-search
|
||
go build -o rb-search .
|
||
```
|
||
|
||
Готовый бинарь — `./rb-search`. Положить на `PATH`:
|
||
|
||
- Linux/macOS: `install -m 0755 rb-search ~/.local/bin/` или `sudo mv rb-search /usr/local/bin/`
|
||
- Windows (PowerShell): `Move-Item rb-search.exe $env:USERPROFILE\bin\`
|
||
|
||
#### Через `go install`
|
||
|
||
```bash
|
||
go install git.arx.ru/shuricken/rb-search@latest
|
||
```
|
||
|
||
Бинарь окажется в `$(go env GOBIN)` (по умолчанию `~/go/bin`). Добавить в `PATH`:
|
||
|
||
- bash/zsh: `export PATH="$PATH:$(go env GOPATH)/bin"` в `~/.bashrc` / `~/.zshrc`
|
||
- fish: `fish_add_path (go env GOPATH)/bin`
|
||
- Windows: `setx PATH "%PATH%;%USERPROFILE%\go\bin"` (новые терминалы)
|
||
|
||
#### Arch Linux
|
||
|
||
```bash
|
||
sudo pacman -S go
|
||
go install git.arx.ru/shuricken/rb-search@latest
|
||
```
|
||
|
||
#### Debian / Ubuntu
|
||
|
||
```bash
|
||
sudo apt install golang-go
|
||
go install git.arx.ru/shuricken/rb-search@latest
|
||
```
|
||
|
||
Если в репозитории старый Go (< 1.22) — собрать из исходников после установки
|
||
`go` через `snap` или `gvm`.
|
||
|
||
#### macOS
|
||
|
||
```bash
|
||
brew install go
|
||
go install git.arx.ru/shuricken/rb-search@latest
|
||
```
|
||
|
||
#### Windows
|
||
|
||
1. Поставить Go с https://go.dev/dl/.
|
||
2. В PowerShell: `go install git.arx.ru/shuricken/rb-search@latest`.
|
||
3. Бинарь окажется в `%USERPROFILE%\go\bin\rb-search.exe`.
|
||
|
||
#### Кросс-компиляция
|
||
|
||
С Linux собрать под другую платформу:
|
||
|
||
```bash
|
||
GOOS=darwin GOARCH=arm64 go build -o rb-search-darwin-arm64 .
|
||
GOOS=windows GOARCH=amd64 go build -o rb-search.exe .
|
||
```
|
||
|
||
## Конфигурация
|
||
|
||
Два независимых источника (приоритет — конфиг-файл, если он есть).
|
||
|
||
### JSON-конфиг
|
||
|
||
Путь поиска: `--config` → `$RB_SEARCH_CONFIG` → `$XDG_CONFIG_HOME/rb-search/config.json`
|
||
→ `~/.config/rb-search/config.json`.
|
||
|
||
Создать шаблон:
|
||
|
||
```bash
|
||
rb-search init
|
||
```
|
||
|
||
Формат:
|
||
|
||
```json
|
||
{
|
||
"default": "prod",
|
||
"servers": {
|
||
"local": {
|
||
"url": "amqp://guest:guest@localhost:5672/"
|
||
},
|
||
"prod": {
|
||
"url": "amqp://admin:secret@rabbit.prod:5672/myvhost"
|
||
},
|
||
"arx": {
|
||
"url": "amqp://admin:REDACTED@10.49.150.156:5672/"
|
||
}
|
||
}
|
||
}
|
||
```
|
||
|
||
Управление:
|
||
|
||
```bash
|
||
rb-search list # показать серверы, default помечен *
|
||
rb-search set-default prod # сменить default
|
||
```
|
||
|
||
### Переменные окружения
|
||
|
||
Если конфиг-файла нет и заданы переменные — синтезируется сервер `env`, он же
|
||
default:
|
||
|
||
```bash
|
||
export EVENTBUS_AMQP_HOST=10.49.150.156 # обязательная
|
||
export EVENTBUS_AMQP_USER=admin
|
||
export EVENTBUS_AMQP_PASS=REDACTED
|
||
export EVENTBUS_AMQP_PORT=5672 # опционально, по умолчанию 5672
|
||
export EVENTBUS_AMQP_VHOST= # опционально, по умолчанию /
|
||
rb-search --queue event
|
||
```
|
||
|
||
Существующий конфиг полностью имеет приоритет — env в этом случае игнорируется,
|
||
чтобы поведение было однозначным.
|
||
|
||
## Использование
|
||
|
||
```text
|
||
rb-search [flags] # читать default-сервер
|
||
rb-search --server NAME --queue Q # выбрать сервер вручную
|
||
rb-search list # список серверов
|
||
rb-search set-default NAME # сменить default
|
||
rb-search init # создать sample-конфиг
|
||
```
|
||
|
||
Флаги:
|
||
|
||
| Флаг | Назначение |
|
||
|----------------|-----------------------------------------------------------------------------------------------------|
|
||
| `--config PATH`| Путь к конфигу. |
|
||
| `--server NAME`| Имя сервера из конфига (override default). |
|
||
| `--queue NAME` | Очередь для сканирования (обязательный). |
|
||
| `--search S` | Подстрока для поиска в теле. Пусто — печатать все. |
|
||
| `--full` | Печатать полный конверт (exchange, routing-key, headers, properties). По умолчанию — только тело. |
|
||
| `--json` | Машинный вывод. С `--full` — объект-конверт; без `--full` — стрим тел. |
|
||
| `--max-body N` | Обрезать тело до N байт при печати (`0` — без ограничения). |
|
||
| `--timeout D` | Таймаут подключения, например `15s`. По умолчанию `30s`. |
|
||
|
||
### Матрица режимов вывода
|
||
|
||
| Флаги | stdout |
|
||
|-------------------|---------------------------------------------------------------------|
|
||
| `(default)` | Тело, pretty-print если JSON, маркер `--- #N tag=… ---` в stderr. |
|
||
| `--full` | Конверт + тело (тело pretty-print если JSON), человекочитаемо. |
|
||
| `--json` | Стрим тел: компактный JSON (если тело — JSON) или JSON-строка. |
|
||
| `--json --full` | Один JSON-объект на строку с полным конвертом; `body` — вложенный JSON, если разбирается. |
|
||
|
||
Диагностика (`queue "…" depth=N`, `scanned=N matched=M`, маркеры сообщений)
|
||
идёт в **stderr**, чтобы stdout оставался парсимым `jq`/файлом.
|
||
|
||
### Примеры
|
||
|
||
```bash
|
||
# Все сообщения как pretty JSON
|
||
rb-search --queue event
|
||
|
||
# Поиск с подсветкой (ANSI inverse video)
|
||
rb-search --queue event --search "OLV-3643"
|
||
|
||
# Полный конверт в человекочитаемом виде
|
||
rb-search --queue event --full
|
||
|
||
# Стрим тел через jq
|
||
rb-search --queue event --json | jq
|
||
|
||
# Собрать тела в массив
|
||
rb-search --queue event --json | jq -s .
|
||
|
||
# Извлечь поле из каждого тела
|
||
rb-search --queue event --json --search change | jq '.offerAcceptance.id'
|
||
|
||
# Полные сообщения с разобранным body
|
||
rb-search --queue event --json --full | jq '.body.action'
|
||
|
||
# Только тела в файл
|
||
rb-search --queue event > bodies.txt # маркеры остались в терминале (stderr)
|
||
|
||
# Без болтовни
|
||
rb-search --queue event --json 2>/dev/null | jq
|
||
|
||
# Другой сервер из конфига
|
||
rb-search --server prod --queue billing.events --search "invoice-42"
|
||
|
||
# С env-переменными, без конфиг-файла
|
||
EVENTBUS_AMQP_HOST=10.49.150.156 EVENTBUS_AMQP_USER=admin EVENTBUS_AMQP_PASS=REDACTED \
|
||
rb-search --queue event
|
||
```
|
||
|
||
### Коды выхода
|
||
|
||
- `0` — успех (включая отсутствие совпадений).
|
||
- `1` — ошибка рантайма (нет коннекта, не существует очередь, ошибка AMQP, …).
|
||
- `2` — неверное использование флагов.
|
||
|
||
## Ограничения
|
||
|
||
- Очередь должна существовать. `queue.declare-passive` сначала пробуется как
|
||
`durable`, при mismatch — переоткрывается канал и пробуется как
|
||
non-durable. Декларация с `auto-delete=true` / `exclusive=true` может не
|
||
совпасть — это редко мешает на практике.
|
||
- `basic.get` читает только то, что есть в очереди на момент старта. Сообщения,
|
||
пришедшие во время сканирования, будут увидены при следующем запуске.
|
||
- Поиск — побайтовый `Contains` по сырому телу. Если тело сжато
|
||
(`content-encoding: gzip`), искать нужно по сжатому представлению или
|
||
разжимать руками.
|
||
- Параллельно работающие консьюмеры на этой же очереди в момент сканирования
|
||
будут видеть очередь как «пустую» — это нормально, после reverse-nack
|
||
обычная работа возобновится.
|