diff options
| author | Paul Bütow <pbuetow@mimecast.com> | 2020-01-09 20:30:15 +0000 |
|---|---|---|
| committer | Paul Bütow <pbuetow@mimecast.com> | 2020-01-09 20:30:15 +0000 |
| commit | 3755a9911ecb05886577095f2b8cc8b9e4066a3a (patch) | |
| tree | 86e24bc466986cb5c9c6d167a918e6064defeafc /clients/healthclient.go | |
Release of DTail v1.0.0v1.0.0
Diffstat (limited to 'clients/healthclient.go')
| -rw-r--r-- | clients/healthclient.go | 96 |
1 files changed, 96 insertions, 0 deletions
diff --git a/clients/healthclient.go b/clients/healthclient.go new file mode 100644 index 0000000..1fae99c --- /dev/null +++ b/clients/healthclient.go @@ -0,0 +1,96 @@ +package clients + +import ( + "dtail/clients/handlers" + "dtail/clients/remote" + "dtail/config" + "dtail/omode" + "fmt" + "runtime" + "strings" + "sync" + "time" + + gossh "golang.org/x/crypto/ssh" +) + +// HealthClient is used for health checking (e.g. via Nagios) +type HealthClient struct { + // Client operating mode + mode omode.Mode + // The remote server address + server string + // SSH user name + userName string + // SSH auth methods to use to connect to the remote servers. + sshAuthMethods []gossh.AuthMethod +} + +// NewHealthClient returns a new healh client. +func NewHealthClient(mode omode.Mode) (*HealthClient, error) { + c := HealthClient{ + mode: mode, + server: fmt.Sprintf("%s:%d", config.Server.SSHBindAddress, config.Common.SSHPort), + userName: config.ControlUser, + } + c.initSSHAuthMethods() + + return &c, nil +} + +// Start the health client. +func (c *HealthClient) Start(wg *sync.WaitGroup) (status int) { + defer wg.Done() + receive := make(chan string) + + throttleCh := make(chan struct{}, runtime.NumCPU()) + statsCh := make(chan struct{}, 1) + + conn := remote.NewOneOffConnection(c.server, c.userName, c.sshAuthMethods) + conn.Handler = handlers.NewHealthHandler(c.server, receive) + conn.Commands = []string{c.mode.String()} + + go conn.Start(throttleCh, statsCh) + defer conn.Stop() + + for { + select { + case data := <-receive: + // Parse recieved data. + s := strings.Split(data, "|") + message := s[len(s)-1] + if strings.HasPrefix(message, "done;") { + return + } + + // Set severity. + s = strings.Split(message, ":") + switch s[0] { + case "OK": + case "WARNING": + if status < 1 { + status = 1 + } + case "CRITICAL": + status = 2 + case "UNKNOWN": + status = 3 + default: + fmt.Printf("CRITICAL: Unexpected server response: '%s'\n", message) + status = 2 + return + } + fmt.Print(message) + + case <-time.After(time.Second * 2): + status = 2 + fmt.Println("CRITICAL: Could not communicate with DTail server") + return + } + } +} + +// Initialize SSH auth methods. +func (c *HealthClient) initSSHAuthMethods() { + c.sshAuthMethods = append(c.sshAuthMethods, gossh.Password(config.ControlUser)) +} |
