fix syntax and json parsing
This commit is contained in:
@@ -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)
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user