Docker check

This commit is contained in:
Magnus Root 2026-02-26 12:47:28 +03:00
parent efb980d47f
commit e1ddd0b656
2 changed files with 47 additions and 31 deletions

View file

@ -12,6 +12,7 @@
| `-m` | Проверка совпадений портов Angie ↔ Docker (+ проверка запуска контейнеров) |
| `-l` | Проверка обновления файлов PT AF access logs |
| `-sv` | Проверка работоспособности служб |
| `-dv` или `-d` | Проверка работоспособности контейнеров |
## Структура проекта
@ -33,7 +34,9 @@ auspex/
│ └── matchcheck/
│ | └── matchcheck.go # -m: совпадения Angie ↔ Docker
│ └── servicecheck/
│ └── servicecheck.go # -sv: проверка работоспособности служб
│ | └── servicecheck.go # -sv: проверка работоспособности служб
│ └── dockercheck/
│ └── dockercheck.go # -dv или -d: проверка работоспособности служб
├── go.mod
├── Makefile
└── README.md
@ -59,7 +62,8 @@ go build -o auspex
./auspex -m # Проверка Angie ↔ Docker (все клиенты)
./auspex -m client_name # Проверка конкретного клиента
./auspex -l # Проверка свежести логов
./auspex -sw # Проверка работоспособности служб
./auspex -sv # Проверка работоспособности служб
./auspex -dv или -d # Проверка работоспособности контейнеров
./auspex -h # Справка
./auspex -v # Версия
```
@ -68,17 +72,7 @@ go build -o auspex
Все настройки находятся в `config.go`.
### Текущий режим: хардкод
Значения прописаны прямо в коде. Для изменения — отредактируйте переменные и пересоберите.
### Переключение на переменные окружения
В файле `config.go` рядом с каждым хардкод-значением есть закомментированные строки
для чтения из переменных окружения. Для переключения:
1. Раскомментируйте нужные строки в `config.go`
2. Или вызовите `config.InitFromEnvOverrides()` в `main.go` (строка уже есть, закомментирована)
### Переменные окружения (при включении)
### Переменные окружения
| Переменная | Описание | Значение по умолчанию |
|------------|----------|----------------------|
@ -101,6 +95,7 @@ go build -o auspex
| `cfgDBPort` | Порт БД | `5432` |
| `cfgPrimaryDBHost` | Основная БД | `10.100.10.8` |
| `cfgSecondaryDBHost` | Резервная БД | `10.100.13.5` |
| `SERVICES_TO_CHECK ` | Службы для проверки | `ansible,docker` |
## Зависимости

View file

@ -173,22 +173,24 @@ func runDockerCheck() error {
// ── Получение контейнеров ────────────────────────────────────────────────────
func dcCheckDockerAvailable() error {
err := exec.Command("docker", "info").Run()
cmd := exec.Command("docker", "info")
out, err := cmd.CombinedOutput()
if err != nil {
return fmt.Errorf("docker info завершился с ошибкой: %v", err)
return fmt.Errorf("docker info завершился с ошибкой: %v\n%s", err, string(out))
}
return nil
}
func dcGetContainers() ([]dcContainerInfo, error) {
// Получаем все контейнеры (включая не-running) через Go-шаблон
// Поля: ID, Name, Status, Health, Image — разделитель |
out, err := exec.Command(
// Шаг 1: получаем ID, Name, Status, Image без .Health — оно доступно
// только через docker inspect и отсутствует у контейнеров без healthcheck.
cmd := exec.Command(
"docker", "ps", "-a",
"--format", "{{.ID}}|{{.Names}}|{{.Status}}|{{.Health}}|{{.Image}}",
).Output()
"--format", "{{.ID}}|{{.Names}}|{{.Status}}|{{.Image}}",
)
out, err := cmd.CombinedOutput()
if err != nil {
return nil, fmt.Errorf("docker ps завершился с ошибкой: %v", err)
return nil, fmt.Errorf("docker ps завершился с ошибкой: %v\n%s", err, string(out))
}
var containers []dcContainerInfo
@ -196,28 +198,47 @@ func dcGetContainers() ([]dcContainerInfo, error) {
if line == "" {
continue
}
parts := strings.SplitN(line, "|", 5)
if len(parts) != 5 {
parts := strings.SplitN(line, "|", 4)
if len(parts) != 4 {
continue
}
c := dcContainerInfo{
ID: strings.TrimSpace(parts[0]),
Name: strings.TrimSpace(parts[1]),
Image: strings.TrimSpace(parts[4]),
Health: strings.ToLower(strings.TrimSpace(parts[3])),
ID: strings.TrimSpace(parts[0]),
Name: strings.TrimSpace(parts[1]),
Image: strings.TrimSpace(parts[3]),
}
// Status из docker ps выглядит как "Up 2 hours" или "Exited (1) 3 minutes ago"
// Нормализуем до короткого статуса
c.Status = dcNormalizeStatus(parts[2])
containers = append(containers, c)
}
// Шаг 2: получаем health отдельно через docker inspect для каждого контейнера.
// Контейнеры без healthcheck вернут пустую строку — это нормально.
for i := range containers {
containers[i].Health = dcGetHealth(containers[i].ID)
}
return containers, nil
}
// dcGetHealth возвращает health статус контейнера через docker inspect.
// Если healthcheck не настроен или inspect завершился с ошибкой — возвращает "none".
func dcGetHealth(containerID string) string {
out, err := exec.Command(
"docker", "inspect",
"--format", "{{if .State.Health}}{{.State.Health.Status}}{{else}}none{{end}}",
containerID,
).Output()
if err != nil {
return "none"
}
health := strings.ToLower(strings.TrimSpace(string(out)))
if health == "" {
return "none"
}
return health
}
// dcNormalizeStatus приводит вывод docker ps к короткому статусу
func dcNormalizeStatus(raw string) string {
raw = strings.TrimSpace(raw)