krkr
5/23/2016 - 2:27 PM

Service checks collector - #poc

Service checks collector - #poc

package main

import (
	"net/http"
	"sync"

	"github.com/gin-gonic/gin"
)

func main() {
	r := gin.Default()

	r.GET("/service/check", ListChecks)
	r.POST("/service/check", AddCheck)
	r.DELETE("/service/check/:service/:host", RmCheck)

	r.Run(":8080")
}

type ServiceCheck struct {
	Timestamp int    `json:"timestamp"`
	Service   string `json:"service"`
	Hostname  string `json:"hostname"`
	Status    int    `json:"status"`
	Output    string `json:"output"`
}

var (
	mutex  sync.RWMutex
	checks = map[string]ServiceCheck{}
)

func ListChecks(c *gin.Context) {
	mutex.RLock()
	defer mutex.RUnlock()

	c.JSON(http.StatusOK, checks)
}

func AddCheck(c *gin.Context) {
	mutex.Lock()
	defer mutex.Unlock()

	var check ServiceCheck
	if !bindJSON(c, &check) {
		return
	}

	checks[check.Service+"@"+check.Hostname] = check

	c.JSON(http.StatusOK, check)
}

func RmCheck(c *gin.Context) {
	mutex.Lock()
	defer mutex.Unlock()

	service := c.Param("service")
	hostname := c.Param("hostname")

	if _, ok := checks[service+"@"+hostname]; !ok {
		c.JSON(http.StatusBadRequest, gin.H{
			"message": "No check found for " + service + "/" + hostname,
		})
	}

	delete(checks, service+hostname)

	c.JSON(http.StatusNoContent, nil)
}

func bindJSON(c *gin.Context, obj interface{}) bool {
	err := c.BindJSON(&obj)
	isError := err != nil
	if isError {
		c.JSON(http.StatusBadRequest, gin.H{
			"message": err.Error(),
		})
	}
	return !isError
}