fix: исправлена проблема с нулевыми значениями в коллекторе proxcluster

- Улучшена логика определения статуса ноды - локальные ноды теперь считаются онлайн по умолчанию
- Улучшена функция checkNodeOnline - добавлена поддержка разных вариантов ping и fallback
- Улучшено получение IP адреса - добавлены альтернативные способы определения IP
- Исправлена проблема с пустыми значениями для локальных нод
- Добавлен fallback на localhost если IP не удается определить

Автор: Сергей Антропов, сайт: https://devops.org.ru
This commit is contained in:
Sergey Antropoff 2025-09-11 17:08:30 +03:00
parent 8dd2df72b6
commit 7f2b25e94d

View File

@ -535,6 +535,8 @@ func collectDetailedNodesInfo(ctx context.Context, clusterName, clusterUUID stri
if hostname, err := os.Hostname(); err == nil { if hostname, err := os.Hostname(); err == nil {
// Получаем IP адрес текущей ноды // Получаем IP адрес текущей ноды
var nodeIP string var nodeIP string
// Пробуем разные способы получения IP
if out, err := exec.CommandContext(ctx, "hostname", "-I").Output(); err == nil { if out, err := exec.CommandContext(ctx, "hostname", "-I").Output(); err == nil {
ips := strings.Fields(string(out)) ips := strings.Fields(string(out))
if len(ips) > 0 { if len(ips) > 0 {
@ -542,6 +544,31 @@ func collectDetailedNodesInfo(ctx context.Context, clusterName, clusterUUID stri
} }
} }
// Если hostname -I не сработал, пробуем ip addr
if nodeIP == "" {
if out, err := exec.CommandContext(ctx, "ip", "addr", "show").Output(); err == nil {
lines := strings.Split(string(out), "\n")
for _, line := range lines {
line = strings.TrimSpace(line)
if strings.HasPrefix(line, "inet ") && !strings.Contains(line, "127.0.0.1") {
parts := strings.Fields(line)
if len(parts) >= 2 {
ip := strings.Split(parts[1], "/")[0]
if ip != "127.0.0.1" && ip != "::1" {
nodeIP = ip
break
}
}
}
}
}
}
// Если все еще нет IP, используем localhost
if nodeIP == "" {
nodeIP = "127.0.0.1"
}
combinedNodes = []NodeInfo{ combinedNodes = []NodeInfo{
{ {
NodeID: 1, NodeID: 1,
@ -578,8 +605,13 @@ func collectDetailedNodesInfo(ctx context.Context, clusterName, clusterUUID stri
} }
} }
// Проверяем доступность ноды через ping // Определяем статус ноды
isOnline := checkNodeOnline(ctx, nodeIP) isOnline := true // По умолчанию считаем ноду онлайн
// Если это не локальная нода, проверяем доступность через ping
if !isLocal {
isOnline = checkNodeOnline(ctx, nodeIP)
}
// Создаем структуру ноды с правильным порядком полей // Создаем структуру ноды с правильным порядком полей
node := map[string]any{ node := map[string]any{
@ -822,12 +854,27 @@ func combineNodeInfo(nodes, status []NodeInfo) []NodeInfo {
// checkNodeOnline проверяет доступность ноды через ping // checkNodeOnline проверяет доступность ноды через ping
func checkNodeOnline(ctx context.Context, nodeIP string) bool { func checkNodeOnline(ctx context.Context, nodeIP string) bool {
if nodeIP == "" {
return false
}
// Создаем контекст с таймаутом для ping // Создаем контекст с таймаутом для ping
pingCtx, cancel := context.WithTimeout(ctx, 3*time.Second) pingCtx, cancel := context.WithTimeout(ctx, 2*time.Second)
defer cancel() defer cancel()
// Выполняем ping с 1 пакетом // Пробуем разные варианты ping в зависимости от системы
cmd := exec.CommandContext(pingCtx, "ping", "-c", "1", "-W", "1", nodeIP) var cmd *exec.Cmd
if _, err := exec.LookPath("ping"); err == nil {
// Linux ping
cmd = exec.CommandContext(pingCtx, "ping", "-c", "1", "-W", "1", nodeIP)
} else if _, err := exec.LookPath("ping6"); err == nil {
// IPv6 ping
cmd = exec.CommandContext(pingCtx, "ping6", "-c", "1", "-W", "1", nodeIP)
} else {
// Если ping недоступен, считаем ноду онлайн
return true
}
err := cmd.Run() err := cmd.Run()
return err == nil return err == nil
} }