Fix
This commit is contained in:
parent
e1ddd0b656
commit
f28ccce6a0
1 changed files with 52 additions and 11 deletions
|
|
@ -36,6 +36,7 @@ const (
|
|||
dcKindStatusChanged dcChangeKind = "status_changed"
|
||||
dcKindHealthChanged dcChangeKind = "health_changed"
|
||||
dcKindDisappeared dcChangeKind = "disappeared"
|
||||
dcKindAppeared dcChangeKind = "appeared"
|
||||
)
|
||||
|
||||
type dcStateChange struct {
|
||||
|
|
@ -58,6 +59,10 @@ func (ch dcStateChange) isProblem() bool {
|
|||
return false
|
||||
}
|
||||
|
||||
func (ch dcStateChange) isNew() bool {
|
||||
return ch.Kind == dcKindAppeared
|
||||
}
|
||||
|
||||
func (ch dcStateChange) isRecovery() bool {
|
||||
switch ch.Kind {
|
||||
case dcKindStatusChanged:
|
||||
|
|
@ -108,6 +113,7 @@ func runDockerCheck() error {
|
|||
|
||||
// Загружаем предыдущее состояние
|
||||
prevState := dcLoadState()
|
||||
isFirstRun := len(prevState.Containers) == 0
|
||||
|
||||
// Строим map текущего состояния
|
||||
current := make(map[string]dcContainerInfo, len(containers))
|
||||
|
|
@ -116,7 +122,7 @@ func runDockerCheck() error {
|
|||
}
|
||||
|
||||
// Сравниваем
|
||||
changes := dcCompareStates(prevState.Containers, current)
|
||||
changes := dcCompareStates(prevState.Containers, current, isFirstRun)
|
||||
|
||||
// Статистика
|
||||
runningCount := 0
|
||||
|
|
@ -140,6 +146,8 @@ func runDockerCheck() error {
|
|||
for _, ch := range changes {
|
||||
arrow := dcChangeArrow(ch)
|
||||
switch ch.Kind {
|
||||
case dcKindAppeared:
|
||||
log.Printf(" %s %-30s | появился (%s) | %s", arrow, ch.Name, ch.CurrState.Status, ch.Image)
|
||||
case dcKindDisappeared:
|
||||
log.Printf(" %s %-30s | исчез (был: %s)", arrow, ch.Name, ch.PrevState.Status)
|
||||
case dcKindStatusChanged:
|
||||
|
|
@ -265,7 +273,7 @@ func dcNormalizeStatus(raw string) string {
|
|||
|
||||
// ── Сравнение состояний ──────────────────────────────────────────────────────
|
||||
|
||||
func dcCompareStates(prev map[string]dcContainerState, curr map[string]dcContainerInfo) []dcStateChange {
|
||||
func dcCompareStates(prev map[string]dcContainerState, curr map[string]dcContainerInfo, isFirstRun bool) []dcStateChange {
|
||||
var changes []dcStateChange
|
||||
|
||||
// Проверяем текущие контейнеры
|
||||
|
|
@ -273,7 +281,16 @@ func dcCompareStates(prev map[string]dcContainerState, curr map[string]dcContain
|
|||
prevInfo, existed := prev[name]
|
||||
|
||||
if !existed {
|
||||
// Новый контейнер — не алертим, просто добавится в state
|
||||
if !isFirstRun {
|
||||
// Новый контейнер появился после первого запуска — алертим
|
||||
changes = append(changes, dcStateChange{
|
||||
Name: name,
|
||||
Kind: dcKindAppeared,
|
||||
PrevState: dcContainerState{},
|
||||
CurrState: dcContainerState{Status: currInfo.Status, Health: currInfo.Health},
|
||||
Image: currInfo.Image,
|
||||
})
|
||||
}
|
||||
continue
|
||||
}
|
||||
|
||||
|
|
@ -365,29 +382,34 @@ func dcSaveState(current map[string]dcContainerInfo) {
|
|||
// ── Отправка алерта ──────────────────────────────────────────────────────────
|
||||
|
||||
func dcSendAlert(hostname string, changes []dcStateChange) {
|
||||
var problems, recoveries []dcStateChange
|
||||
var problems, recoveries, appeared []dcStateChange
|
||||
for _, ch := range changes {
|
||||
if ch.isRecovery() {
|
||||
switch {
|
||||
case ch.isNew():
|
||||
appeared = append(appeared, ch)
|
||||
case ch.isRecovery():
|
||||
recoveries = append(recoveries, ch)
|
||||
} else if ch.isProblem() {
|
||||
case ch.isProblem():
|
||||
problems = append(problems, ch)
|
||||
}
|
||||
}
|
||||
|
||||
// Если нет ни проблем, ни восстановлений — молчим
|
||||
if len(problems) == 0 && len(recoveries) == 0 {
|
||||
// Если нет никаких изменений — молчим
|
||||
if len(problems) == 0 && len(recoveries) == 0 && len(appeared) == 0 {
|
||||
return
|
||||
}
|
||||
|
||||
// Заголовок по наиболее критичному событию
|
||||
var header string
|
||||
switch {
|
||||
case len(problems) > 0 && len(recoveries) > 0:
|
||||
header = "⚠️ <b>Изменения в состоянии контейнеров</b>"
|
||||
case len(problems) > 0:
|
||||
header = "🚨 <b>АЛЕРТ: Проблемы с контейнерами!</b>"
|
||||
default:
|
||||
case len(recoveries) > 0 && len(appeared) > 0:
|
||||
header = "⚠️ <b>Изменения в состоянии контейнеров</b>"
|
||||
case len(recoveries) > 0:
|
||||
header = "✅ <b>Контейнеры восстановлены</b>"
|
||||
default:
|
||||
header = "ℹ️ <b>Новые контейнеры</b>"
|
||||
}
|
||||
|
||||
message := fmt.Sprintf(
|
||||
|
|
@ -458,6 +480,20 @@ func dcSendAlert(hostname string, changes []dcStateChange) {
|
|||
}
|
||||
}
|
||||
|
||||
// Новые контейнеры
|
||||
if len(appeared) > 0 {
|
||||
message += "━━━━━━━━━━━━━━━━━━━━━━━━━━━\n"
|
||||
message += fmt.Sprintf("🆕 <b>Появились (%d):</b>\n\n", len(appeared))
|
||||
for _, ch := range appeared {
|
||||
message += fmt.Sprintf(
|
||||
"🆕 <b>%s</b>\n"+
|
||||
" 📌 Статус: <code>%s</code>\n"+
|
||||
" 🐳 <code>%s</code>\n\n",
|
||||
ch.Name, ch.CurrState.Status, ch.Image,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
message += "━━━━━━━━━━━━━━━━━━━━━━━━━━━\n"
|
||||
message += "💡 <i>docker ps -a | docker logs <имя> --tail 50</i>"
|
||||
|
||||
|
|
@ -492,6 +528,8 @@ func dcStatusEmoji(status, health string) string {
|
|||
|
||||
func dcChangeEmoji(ch dcStateChange) string {
|
||||
switch ch.Kind {
|
||||
case dcKindAppeared:
|
||||
return "🆕"
|
||||
case dcKindDisappeared:
|
||||
return "👻"
|
||||
case dcKindHealthChanged:
|
||||
|
|
@ -510,6 +548,9 @@ func dcChangeEmoji(ch dcStateChange) string {
|
|||
}
|
||||
|
||||
func dcChangeArrow(ch dcStateChange) string {
|
||||
if ch.isNew() {
|
||||
return "🆕"
|
||||
}
|
||||
if ch.isRecovery() {
|
||||
return "✅"
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue