Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(notifier): refactor selfstate heartbeaters #1117

Open
wants to merge 11 commits into
base: feat/add-emergency-contacts-allowed-list
Choose a base branch
from
9 changes: 5 additions & 4 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ require (
require github.com/prometheus/common v0.37.0

require (
github.com/go-playground/validator/v10 v10.4.1
github.com/go-playground/validator/v10 v10.22.1
github.com/hashicorp/golang-lru/v2 v2.0.7
github.com/mattermost/mattermost/server/public v0.1.1
github.com/mitchellh/mapstructure v1.5.0
Expand Down Expand Up @@ -173,19 +173,20 @@ require (
github.com/blang/semver/v4 v4.0.0 // indirect
github.com/dyatlov/go-opengraph/opengraph v0.0.0-20220524092352-606d7b1e5f8a // indirect
github.com/fatih/color v1.16.0 // indirect
github.com/gabriel-vasile/mimetype v1.4.3 // indirect
github.com/go-openapi/jsonpointer v0.20.0 // indirect
github.com/go-openapi/jsonreference v0.20.2 // indirect
github.com/go-openapi/spec v0.20.9 // indirect
github.com/go-openapi/swag v0.22.4 // indirect
github.com/go-playground/locales v0.13.0 // indirect
github.com/go-playground/universal-translator v0.17.0 // indirect
github.com/go-playground/locales v0.14.1 // indirect
github.com/go-playground/universal-translator v0.18.1 // indirect
github.com/hashicorp/go-hclog v1.6.3 // indirect
github.com/hashicorp/go-plugin v1.6.0 // indirect
github.com/hashicorp/yamux v0.1.1 // indirect
github.com/huandu/xstrings v1.3.3 // indirect
github.com/imdario/mergo v0.3.11 // indirect
github.com/josharian/intern v1.0.0 // indirect
github.com/leodido/go-urn v1.2.0 // indirect
github.com/leodido/go-urn v1.4.0 // indirect
github.com/mailru/easyjson v0.7.7 // indirect
github.com/mitchellh/copystructure v1.0.0 // indirect
github.com/mitchellh/go-testing-interface v1.14.1 // indirect
Expand Down
17 changes: 12 additions & 5 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -238,6 +238,8 @@ github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4
github.com/fsnotify/fsnotify v1.5.4/go.mod h1:OVB6XrOHzAwXMpEM7uPOzcehqUV2UqJxmVXmkdnm1bU=
github.com/fsnotify/fsnotify v1.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nosvA=
github.com/fsnotify/fsnotify v1.7.0/go.mod h1:40Bi/Hjc2AVfZrqy+aj+yEI+/bRxZnMJyTJwOpGvigM=
github.com/gabriel-vasile/mimetype v1.4.3 h1:in2uUcidCuFcDKtdcBxlR0rJ1+fsokWf+uqxgUFjbI0=
github.com/gabriel-vasile/mimetype v1.4.3/go.mod h1:d8uq/6HKRL6CGdk+aubisF/M5GcPfT7nKyLpA0lbSSk=
github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
github.com/gliderlabs/ssh v0.1.1/go.mod h1:U7qILu1NlMHj9FlMhZLlkCdDnU1DBEAqr0aevW3Awn0=
github.com/go-asn1-ber/asn1-ber v1.5.5 h1:MNHlNMBDgEKD4TcKr36vQN68BA00aDfjIt3/bD50WnA=
Expand Down Expand Up @@ -279,14 +281,18 @@ github.com/go-openapi/swag v0.19.15/go.mod h1:QYRuS/SOXUCsnplDa677K7+DxSOj6IPNl/
github.com/go-openapi/swag v0.22.3/go.mod h1:UzaqsxGiab7freDnrUUra0MwWfN/q7tE4j+VcZ0yl14=
github.com/go-openapi/swag v0.22.4 h1:QLMzNJnMGPRNDCbySlcj1x01tzU8/9LTTL9hZZZogBU=
github.com/go-openapi/swag v0.22.4/go.mod h1:UzaqsxGiab7freDnrUUra0MwWfN/q7tE4j+VcZ0yl14=
github.com/go-playground/assert/v2 v2.0.1 h1:MsBgLAaY856+nPRTKrp3/OZK38U/wa0CcBYNjji3q3A=
github.com/go-playground/assert/v2 v2.0.1/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4=
github.com/go-playground/locales v0.13.0 h1:HyWk6mgj5qFqCT5fjGBuRArbVDfE4hi8+e8ceBS/t7Q=
github.com/go-playground/assert/v2 v2.2.0 h1:JvknZsQTYeFEAhQwI4qEt9cyV5ONwRHC+lYKSsYSR8s=
github.com/go-playground/assert/v2 v2.2.0/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4=
github.com/go-playground/locales v0.13.0/go.mod h1:taPMhCMXrRLJO55olJkUXHZBHCxTMfnGwq/HNwmWNS8=
github.com/go-playground/universal-translator v0.17.0 h1:icxd5fm+REJzpZx7ZfpaD876Lmtgy7VtROAbHHXk8no=
github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/oXslEjJA=
github.com/go-playground/locales v0.14.1/go.mod h1:hxrqLVvrK65+Rwrd5Fc6F2O76J/NuW9t0sjnWqG1slY=
github.com/go-playground/universal-translator v0.17.0/go.mod h1:UkSxE5sNxxRwHyU+Scu5vgOQjsIJAF8j9muTVoKLVtA=
github.com/go-playground/validator/v10 v10.4.1 h1:pH2c5ADXtd66mxoE0Zm9SUhxE20r7aM3F26W0hOn+GE=
github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJnYK9S473LQFuzCbDbfSFY=
github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY=
github.com/go-playground/validator/v10 v10.4.1/go.mod h1:nlOn6nFhuKACm19sB/8EGNn9GlaMV7XkbRSipzJ0Ii4=
github.com/go-playground/validator/v10 v10.22.1 h1:40JcKH+bBNGFczGuoBYgX4I6m/i27HYW8P9FDk5PbgA=
github.com/go-playground/validator/v10 v10.22.1/go.mod h1:dbuPbCMFw/DrkbEynArYaCwl3amGuJotoKCe95atGMM=
github.com/go-redis/redis v6.15.9+incompatible h1:K0pv1D7EQUjfyoMql+r/jZqCLizCGKFlFgcHWWmHQjg=
github.com/go-redis/redis v6.15.9+incompatible/go.mod h1:NAIEuMOZ/fxfXJIrKDQDz8wamY7mA7PouImQ2Jvg6kA=
github.com/go-redis/redis/v7 v7.4.0 h1:7obg6wUoj05T0EpY0o8B59S9w5yeMWql7sw2kwNW1x4=
Expand Down Expand Up @@ -527,8 +533,9 @@ github.com/kr/pty v1.1.3/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
github.com/leodido/go-urn v1.2.0 h1:hpXL4XnriNwQ/ABnpepYM/1vCLWNDfUNts8dX3xTG6Y=
github.com/leodido/go-urn v1.2.0/go.mod h1:+8+nEpDfqqsY+g338gtMEUOtuK+4dEMhiQEgxpxOKII=
github.com/leodido/go-urn v1.4.0 h1:WT9HwE9SGECu3lg4d/dIA+jxlljEa1/ffXKmRjqdmIQ=
github.com/leodido/go-urn v1.4.0/go.mod h1:bvxc+MVxLKB4z00jd1z+Dvzr47oO32F/QSNjSBOlFxI=
github.com/lib/pq v1.10.9 h1:YXG7RB+JIjhP29X+OtkiDnYaXQwpS4JEWq7dtCCRUEw=
github.com/lib/pq v1.10.9/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
github.com/lomik/og-rek v0.0.0-20170411191824-628eefeb8d80 h1:KVyDGUXjVOdHQt24wIgY4ZdGFXHtQHLWw0L/MAK3Kb0=
Expand Down
63 changes: 25 additions & 38 deletions mock/heartbeat/heartbeat.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

72 changes: 42 additions & 30 deletions notifier/selfstate/heartbeat/database.go
Original file line number Diff line number Diff line change
@@ -1,52 +1,64 @@
package heartbeat

import (
"fmt"
"time"

"github.com/moira-alert/moira"
"github.com/moira-alert/moira/datatypes"
)

type databaseHeartbeat struct{ heartbeat }
// Verify that databaseHeartbeater matches the Heartbeater interface.
var _ Heartbeater = (*databaseHeartbeater)(nil)

func GetDatabase(delay int64, logger moira.Logger, database moira.Database) Heartbeater {
if delay > 0 {
return &databaseHeartbeat{heartbeat{
logger: logger,
database: database,
delay: delay,
lastSuccessfulCheck: time.Now().Unix(),
}}
}
return nil
// DatabaseHeartbeaterConfig structure describing the databaseHeartbeater configuration.
type DatabaseHeartbeaterConfig struct {
HeartbeaterBaseConfig

RedisDisconnectDelay time.Duration `validate:"required_if=Enabled true,gte=0"`
}

func (check *databaseHeartbeat) Check(nowTS int64) (int64, bool, error) {
_, err := check.database.GetChecksUpdatesCount()
if err == nil {
check.lastSuccessfulCheck = nowTS
return 0, false, nil
}
type databaseHeartbeater struct {
*heartbeaterBase

if check.lastSuccessfulCheck < nowTS-check.delay {
check.logger.Error().
String("error", check.GetErrorMessage()).
Int64("time_since_successful_check", nowTS-check.heartbeat.lastSuccessfulCheck).
Msg("Send message")
cfg DatabaseHeartbeaterConfig
}

return nowTS - check.lastSuccessfulCheck, true, nil
// NewDatabaseHeartbeater is a function that creates a new databaseHeartbeater.
func NewDatabaseHeartbeater(cfg DatabaseHeartbeaterConfig, base *heartbeaterBase) (*databaseHeartbeater, error) {
AleksandrMatsko marked this conversation as resolved.
Show resolved Hide resolved
if err := moira.ValidateStruct(cfg); err != nil {
return nil, fmt.Errorf("database heartbeater configuration error: %w", err)
}

return 0, false, nil
return &databaseHeartbeater{
heartbeaterBase: base,
cfg: cfg,
}, nil
}

func (databaseHeartbeat) NeedTurnOffNotifier() bool {
return true
// Check is a function that checks if the database is working correctly.
func (heartbeater *databaseHeartbeater) Check() (State, error) {
now := heartbeater.clock.NowUTC()

_, err := heartbeater.database.GetChecksUpdatesCount()
if err == nil {
heartbeater.lastSuccessfulCheck = now
return StateOK, nil
}

if now.Sub(heartbeater.lastSuccessfulCheck) > heartbeater.cfg.RedisDisconnectDelay {
return StateError, nil
}

return StateOK, err
}

func (databaseHeartbeat) NeedToCheckOthers() bool {
return false
// Type is a function that returns the current heartbeat type.
func (databaseHeartbeater) Type() datatypes.HeartbeatType {
return datatypes.HeartbeatDatabase
}

func (databaseHeartbeat) GetErrorMessage() string {
return "Redis disconnected"
// AlertSettings is a function that returns the current settings for alerts.
func (heartbeater databaseHeartbeater) AlertSettings() AlertConfig {
return heartbeater.cfg.AlertCfg
}
Loading
Loading