/
uptime_handler.go
93 lines (76 loc) · 2.92 KB
/
uptime_handler.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
// Copyright 2016 IBM Corporation
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package uptime
import (
"math"
"net/http"
"time"
"github.com/ant0ine/go-json-rest/rest"
"github.com/shirou/gopsutil/load"
"github.com/amalgam8/amalgam8/pkg/version"
"github.com/amalgam8/amalgam8/registry/utils/health"
)
func uptimeHandler(w rest.ResponseWriter, r *rest.Request) {
uHandler.ServeHTTP(w.(http.ResponseWriter), r.Request)
}
// healthyHandler implements an ever-healthy HTTP handler which always returns HTTP 200.
// This is used for several cloud environments in which a URL endpoint (normally, "/") is periodically polled
// to indicate healthness for an auto-recovery mechanism.
func healthyHandler(w rest.ResponseWriter, r *rest.Request) {
w.WriteHeader(http.StatusOK)
}
// uptimeHealthCheck implements an ever-healthy health.CheckerFunc that records the current process uptime and load.
func uptimeHealthCheck() health.Status {
info := currentSysInfo()
return health.StatusHealthyWithProperties(
map[string]interface{}{
"uptime": info.Uptime.String(),
"load_1m": info.LastMinute,
"load_5m": info.LastFive,
"load_15m": info.LastFifteen,
"build_version": version.Build.Version,
"build_revision": version.Build.GitRevision,
"build_date": version.Build.BuildDate,
"build_goversion": version.Build.GoVersion,
})
}
type uptimeInfo struct {
Uptime time.Duration `json:"uptime"`
LastMinute float64 `json:"load_1m"`
LastFive float64 `json:"load_5m"`
LastFifteen float64 `json:"load_15m"`
}
func currentSysInfo() *uptimeInfo {
// see http://www.linuxquestions.org/questions/programming-9/%27load-average%27-return-values-from-sysinfo-309720/
const loadScale = 65536.0 // magic conversion factor 2^16
info := &uptimeInfo{}
load, _ := load.Avg()
info.Uptime = time.Now().UTC().Sub(startTime)
info.LastMinute = fixedPrecision(load.Load1/loadScale, 3)
info.LastFive = fixedPrecision(load.Load5/loadScale, 3)
info.LastFifteen = fixedPrecision(load.Load15/loadScale, 3)
return info
}
func round(num float64) int {
return int(num + math.Copysign(0.5, num))
}
func fixedPrecision(num float64, precision int) float64 {
output := math.Pow(10, float64(precision))
return float64(round(num*output)) / output
}
var startTime = time.Now().UTC()
var uHandler = health.Handler()
func init() {
health.RegisterFunc("UPTIME", uptimeHealthCheck)
}