1
0
mirror of https://blitiri.com.ar/repos/chasquid synced 2025-12-17 14:37:02 +00:00
Files
go-chasquid-smtp/monitoring.go
Alberto Bertogli 48c37b5687 monitoring: Show the go version used to build the binary
This patch makes the monitoring web server index show the go compiler
version used to build the binary, which can be convenient when
troubleshooting.
2020-09-11 12:34:36 +01:00

153 lines
3.6 KiB
Go

package main
import (
"flag"
"fmt"
"html/template"
"net/http"
"os"
"runtime"
"time"
"blitiri.com.ar/go/chasquid/internal/config"
"blitiri.com.ar/go/chasquid/internal/expvarom"
"blitiri.com.ar/go/log"
"google.golang.org/protobuf/encoding/prototext"
// To enable live profiling in the monitoring server.
_ "net/http/pprof"
)
func launchMonitoringServer(conf *config.Config) {
log.Infof("Monitoring HTTP server listening on %s", conf.MonitoringAddress)
osHostname, _ := os.Hostname()
indexData := struct {
Version string
GoVersion string
SourceDate time.Time
StartTime time.Time
Config *config.Config
Hostname string
}{
Version: version,
GoVersion: runtime.Version(),
SourceDate: sourceDate,
StartTime: time.Now(),
Config: conf,
Hostname: osHostname,
}
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
if r.URL.Path != "/" {
http.NotFound(w, r)
return
}
if err := monitoringHTMLIndex.Execute(w, indexData); err != nil {
log.Infof("monitoring handler error: %v", err)
}
})
http.HandleFunc("/metrics", expvarom.MetricsHandler)
http.HandleFunc("/debug/flags", debugFlagsHandler)
http.HandleFunc("/debug/config", debugConfigHandler(conf))
go http.ListenAndServe(conf.MonitoringAddress, nil)
}
// Functions available inside the templates.
var tmplFuncs = template.FuncMap{
"since": time.Since,
"roundDuration": roundDuration,
}
// Static index for the monitoring website.
var monitoringHTMLIndex = template.Must(
template.New("index").Funcs(tmplFuncs).Parse(
`<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>{{.Hostname}}: chasquid monitoring</title>
<style type="text/css">
body {
font-family: sans-serif;
}
</style>
</head>
<body>
<h1>chasquid @{{.Config.Hostname}}</h1>
<p>
chasquid {{.Version}}<br>
source date {{.SourceDate.Format "2006-01-02 15:04:05 -0700"}}<br>
built with {{.GoVersion}}<br>
</p>
<p>
started {{.StartTime.Format "Mon, 2006-01-02 15:04:05 -0700"}}<br>
up for {{.StartTime | since | roundDuration}}<br>
os hostname <i>{{.Hostname}}</i><br>
</p>
<ul>
<li><a href="/debug/queue">queue</a>
<li>monitoring
<ul>
<li><a href="/debug/requests?exp=1">requests (short-lived)</a>
<li><a href="/debug/events?exp=1">events (long-lived)</a>
<li><a href="https://blitiri.com.ar/p/chasquid/monitoring/#variables">
exported variables</a>:
<a href="/debug/vars">expvar</a>
<small><a href="https://golang.org/pkg/expvar/">(ref)</a></small>,
<a href="/metrics">openmetrics</a>
<small><a href="https://openmetrics.io/">(ref)</a></small>
</ul>
<li>execution
<ul>
<li><a href="/debug/flags">flags</a>
<li><a href="/debug/config">config</a>
<li><a href="/debug/pprof/cmdline">command line</a>
</ul>
<li><a href="/debug/pprof">pprof</a>
<small><a href="https://golang.org/pkg/net/http/pprof/">(ref)</a></small>
<ul>
</ul>
</ul>
</body>
</html>
`))
func debugFlagsHandler(w http.ResponseWriter, r *http.Request) {
visited := make(map[string]bool)
// Print set flags first, then the rest.
flag.Visit(func(f *flag.Flag) {
fmt.Fprintf(w, "-%s=%s\n", f.Name, f.Value.String())
visited[f.Name] = true
})
fmt.Fprintf(w, "\n")
flag.VisitAll(func(f *flag.Flag) {
if !visited[f.Name] {
fmt.Fprintf(w, "-%s=%s\n", f.Name, f.Value.String())
}
})
}
func debugConfigHandler(conf *config.Config) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
_, _ = w.Write([]byte(prototext.Format(conf)))
}
}
func roundDuration(d time.Duration) time.Duration {
return d.Round(time.Second)
}