fix syntax and json parsing

This commit is contained in:
Mayuresh Gaitonde
2020-01-29 17:27:56 -08:00
parent b6f865bb73
commit 62279ab31a

View File

@@ -5,8 +5,10 @@ import (
"fmt" "fmt"
"github.com/golang/glog" "github.com/golang/glog"
"net/http" "net/http"
"net/url"
"os" "os"
"strings" "strings"
"time"
) )
const ( const (
@@ -18,8 +20,9 @@ const (
) )
type ConsulMon struct { type ConsulMon struct {
addr string addr string
node string node string
client *http.Client
} }
type ConsulServiceData struct { type ConsulServiceData struct {
@@ -44,13 +47,13 @@ func NewConsulMon(addr string) (*ConsulMon, error) {
if node == "" { if node == "" {
return nil, fmt.Errorf("%s env variable not set", consulNodeEnv) return nil, fmt.Errorf("%s env variable not set", consulNodeEnv)
} }
return &ConsulMon{addr: addr, node: node}, nil return &ConsulMon{addr: addr, node: node, client: &http.Client{Timeout: 10 * time.Second}}, nil
} }
func (c *ConsulMon) queryServices() ([]*App, error) { func (c *ConsulMon) queryServices() ([]*App, error) {
var apps []*App var apps []*App
addr := c.addr + fmt.Sprintf("%s/%s", nodeURL, c.node) addr := c.addr + fmt.Sprintf("%s/%s", nodeURL, c.node)
resp, err := http.Get(addr) resp, err := c.client.Get(addr)
if err != nil { if err != nil {
return apps, err return apps, err
} }
@@ -98,51 +101,46 @@ func (c *ConsulMon) queryServices() ([]*App, error) {
return apps, nil return apps, nil
} }
// Returns a *Response to mimic http.Get with some minimal error handling.
// https://golang.org/pkg/net/http/#Get for docs on Get.
func getResp(addr) (resp *Response) {
resp, err := http.Get(addr)
if err != nil {
glog.V(2).Errorf("Error getting %s with %s", addr, err)
}
defer resp.Body.Close()
return resp
}
// healthCheckLocal queries a node's local consul agent to perform service healthchecks // healthCheckLocal queries a node's local consul agent to perform service healthchecks
// This is the underlying api call: https://www.consul.io/api/agent/check.html // This is the underlying api call: https://www.consul.io/api/agent/check.html
func (c *ConsulMon) healthCheckLocal(service string) (bool, error) { func (c *ConsulMon) healthCheckLocal(service string) (bool, error) {
addr := c.addr + fmt.Sprintf("%s/%s", localHealthCheckurl, service) params := url.Values{}
resp, err = getResp(addr) params.Add("filter", "enable_gocast in ServiceTags")
addr := c.addr + fmt.Sprintf("%s?%s", localHealthCheckurl, params.Encode())
var data interface{} resp, err := c.client.Get(addr)
if err := json.NewDecoder(resp.Body).Decode(&data); err != nil { if err != nil {
glog.V(2).Infof("Error getting %s with %s", addr, err)
return false, err return false, err
} }
defer resp.Body.Close()
services := data.(map[string]interface{}) var services map[string]interface{}
for _, serviceInfo := range services { if err := json.NewDecoder(resp.Body).Decode(&services); err != nil {
s := serviceInfo.(map[string]interface{}) return false, err
serviceName := s["ServiceName"].(string) }
if serviceName == service { for _, sInfo := range services {
status := s["Status"].(string) serviceInfo := sInfo.(map[string]interface{})
if serviceInfo["ServiceName"].(string) == service {
status := serviceInfo["Status"].(string)
if status == "passing" { if status == "passing" {
return true, nil return true, nil
} }
glog.V(2).Infof("Consul local healthcheck returned %s status", status) glog.V(2).Infof("Consul local healthcheck returned %s status", status)
return false, nil return false, nil
} }
node := serviceReport["Node"].(string)
return false, fmt.Errorf("No local healcheck info found for service %s on node %s in consul", service, node)
} }
return false, fmt.Errorf("No local healcheck info found for service %s on node %s in consul", service, c.node)
} }
// healthCheckRemote queries the consul cluster's healthcheck endpoint to perform service healthchecks // healthCheckRemote queries the consul cluster's healthcheck endpoint to perform service healthchecks
// This is the underlying api call: https://www.consul.io/api/health.html // This is the underlying api call: https://www.consul.io/api/health.html
func (c *ConsulMon) healthCheckRemote(service string) (bool, error) { func (c *ConsulMon) healthCheckRemote(service string) (bool, error) {
addr := c.addr + fmt.Sprintf("%s/%s", remoteHealthCheckurl, service) addr := c.addr + fmt.Sprintf("%s/%s", remoteHealthCheckurl, service)
resp, err = getResp(addr) resp, err := c.client.Get(addr)
if err != nil {
glog.V(2).Infof("Error getting %s with %s", addr, err)
return false, err
}
defer resp.Body.Close()
var data []interface{} var data []interface{}
if err := json.NewDecoder(resp.Body).Decode(&data); err != nil { if err := json.NewDecoder(resp.Body).Decode(&data); err != nil {
return false, err return false, err
@@ -165,8 +163,8 @@ func (c *ConsulMon) healthCheckRemote(service string) (bool, error) {
// If the address contains "localhost", then it presumes that the local agent is to be used. // If the address contains "localhost", then it presumes that the local agent is to be used.
func (c *ConsulMon) healthCheck(service string) (bool, error) { func (c *ConsulMon) healthCheck(service string) (bool, error) {
usingLocalAgent := strings.Contains(c.addr, "localhost") usingLocalAgent := strings.Contains(c.addr, "localhost")
if (usingLocalAgent) { if usingLocalAgent {
return c.healthCheckLocal(service) return c.healthCheckLocal(service)
} }
return c.healthCheckRemote(service) return c.healthCheckRemote(service)
} }