summaryrefslogtreecommitdiff
path: root/clients/healthclient.go
diff options
context:
space:
mode:
authorPaul Bütow <pbuetow@mimecast.com>2020-01-09 20:30:15 +0000
committerPaul Bütow <pbuetow@mimecast.com>2020-01-09 20:30:15 +0000
commit3755a9911ecb05886577095f2b8cc8b9e4066a3a (patch)
tree86e24bc466986cb5c9c6d167a918e6064defeafc /clients/healthclient.go
Release of DTail v1.0.0v1.0.0
Diffstat (limited to 'clients/healthclient.go')
-rw-r--r--clients/healthclient.go96
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))
+}