feta/process/handlers.go

116 lines
2.7 KiB
Go
Raw Normal View History

2019-12-19 14:24:26 +00:00
package process
2019-11-05 23:32:09 +00:00
2020-03-27 23:02:36 +00:00
import (
"encoding/json"
"fmt"
"net/http"
"runtime"
"strings"
"time"
2019-11-05 23:32:09 +00:00
2020-03-27 23:02:36 +00:00
"github.com/gin-gonic/gin"
)
2019-11-05 23:32:09 +00:00
type hash map[string]interface{}
2019-12-19 14:24:26 +00:00
func (a *Server) instances() []hash {
2019-11-05 23:32:09 +00:00
resp := make([]hash, 0)
now := time.Now()
2019-12-19 14:24:26 +00:00
for _, v := range a.feta.manager.ListInstances() {
2019-11-05 23:32:09 +00:00
i := make(hash)
// FIXME figure out why a very short lock here deadlocks
v.Lock()
2019-12-19 14:24:26 +00:00
i["hostname"] = v.Hostname
i["nextCheck"] = v.NextFetch.UTC().Format(time.RFC3339)
i["nextCheckAfter"] = (-1 * now.Sub(v.NextFetch)).String()
i["successCount"] = v.SuccessCount
i["errorCount"] = v.ErrorCount
i["identified"] = v.Identified
2019-11-06 07:03:42 +00:00
i["status"] = v.Status()
2019-11-05 23:32:09 +00:00
i["software"] = "unknown"
i["version"] = "unknown"
2019-12-19 14:24:26 +00:00
if v.Identified {
i["software"] = v.ServerImplementationString
i["version"] = v.ServerVersionString
2019-11-05 23:32:09 +00:00
}
v.Unlock()
resp = append(resp, i)
}
return resp
}
2019-12-19 14:24:26 +00:00
func (a *Server) instanceSummary() map[string]int {
2019-11-06 07:03:42 +00:00
resp := make(map[string]int)
2019-12-19 14:24:26 +00:00
for _, v := range a.feta.manager.ListInstances() {
2019-11-06 07:03:42 +00:00
v.Lock()
resp[fmt.Sprintf("STATUS_%s", v.Status())]++
2019-12-19 14:24:26 +00:00
if v.ServerImplementationString != "" {
2019-11-06 07:03:42 +00:00
//FIXME(sneak) sanitize this to a-z0-9, it is server-provided
2019-12-19 14:24:26 +00:00
resp[fmt.Sprintf("SOFTWARE_%s", strings.ToUpper(v.ServerImplementationString))]++
2019-11-06 07:03:42 +00:00
}
v.Unlock()
}
return resp
}
2019-12-19 14:24:26 +00:00
func (a *Server) getInstanceListHandler() http.HandlerFunc {
2019-11-06 07:03:42 +00:00
return func(w http.ResponseWriter, r *http.Request) {
result := &gin.H{
"instances": a.instances(),
}
json, err := json.Marshal(result)
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
w.Header().Set("Content-Type", "application/json")
w.Write(json)
}
}
2019-12-19 14:24:26 +00:00
func (a *Server) getIndexHandler() http.HandlerFunc {
2019-11-05 23:32:09 +00:00
return func(w http.ResponseWriter, r *http.Request) {
index := &gin.H{
2019-11-06 01:21:30 +00:00
"server": &gin.H{
"now": time.Now().UTC().Format(time.RFC3339),
"uptime": a.feta.uptime().String(),
2019-11-06 01:21:30 +00:00
"goroutines": runtime.NumGoroutine(),
"goversion": runtime.Version(),
"version": a.feta.version,
"buildarch": a.feta.buildarch,
},
2019-11-06 07:03:42 +00:00
"instanceSummary": a.instanceSummary(),
2019-11-05 23:32:09 +00:00
}
json, err := json.Marshal(index)
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
w.Header().Set("Content-Type", "application/json")
w.Write(json)
}
}
2019-12-19 14:24:26 +00:00
func (a *Server) getHealthCheckHandler() http.HandlerFunc {
2019-11-05 23:32:09 +00:00
return func(w http.ResponseWriter, r *http.Request) {
resp := &gin.H{
"status": "ok",
"now": time.Now().UTC().Format(time.RFC3339),
"uptime": a.feta.uptime().String(),
2019-11-05 23:32:09 +00:00
}
json, err := json.Marshal(resp)
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
w.Header().Set("Content-Type", "application/json")
w.Write(json)
}
}