git » chasquid » commit 33446fd

monitoring: Reorganize index structure

author Alberto Bertogli
2020-07-08 22:07:43 UTC
committer Alberto Bertogli
2020-07-08 22:23:17 UTC
parent a08b86a6637c17a48e5673c27a172953517962af

monitoring: Reorganize index structure

This patch improves the organization of the monitoring index page:

- Include the hostname (both OS and configured) for convenience.
- Round the uptime presentation for readability.
- Add a tiny CSS for consistency with the traces.
- Re-arrange the list of links for readability.

chasquid.go +1 -1
monitoring.go +65 -41

diff --git a/chasquid.go b/chasquid.go
index bbbccff..dbd16a6 100644
--- a/chasquid.go
+++ b/chasquid.go
@@ -91,7 +91,7 @@ func main() {
 	go signalHandler()
 
 	if conf.MonitoringAddress != "" {
-		launchMonitoringServer(conf.MonitoringAddress)
+		launchMonitoringServer(conf)
 	}
 
 	s := smtpsrv.NewServer()
diff --git a/monitoring.go b/monitoring.go
index f91b54c..dbb0371 100644
--- a/monitoring.go
+++ b/monitoring.go
@@ -5,25 +5,33 @@ import (
 	"fmt"
 	"html/template"
 	"net/http"
+	"os"
 	"time"
 
+	"blitiri.com.ar/go/chasquid/internal/config"
 	"blitiri.com.ar/go/log"
 
 	// To enable live profiling in the monitoring server.
 	_ "net/http/pprof"
 )
 
-func launchMonitoringServer(addr string) {
-	log.Infof("Monitoring HTTP server listening on %s", addr)
+func launchMonitoringServer(conf *config.Config) {
+	log.Infof("Monitoring HTTP server listening on %s", conf.MonitoringAddress)
+
+	osHostname, _ := os.Hostname()
 
 	indexData := struct {
 		Version    string
 		SourceDate time.Time
 		StartTime  time.Time
+		Config     *config.Config
+		Hostname   string
 	}{
 		Version:    version,
 		SourceDate: sourceDate,
 		StartTime:  time.Now(),
+		Config:     conf,
+		Hostname:   osHostname,
 	}
 
 	http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
@@ -36,70 +44,86 @@ func launchMonitoringServer(addr string) {
 		}
 	})
 
-	flags := dumpFlags()
-	http.HandleFunc("/debug/flags", func(w http.ResponseWriter, r *http.Request) {
-		_, _ = w.Write([]byte(flags))
-	})
+	http.HandleFunc("/debug/flags", debugFlagsHandler)
+
+	go http.ListenAndServe(conf.MonitoringAddress, nil)
+}
 
-	go http.ListenAndServe(addr, 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(
-	template.FuncMap{"since": time.Since}).Parse(
-	`<!DOCTYPE html>
+var monitoringHTMLIndex = template.Must(
+	template.New("index").Funcs(tmplFuncs).Parse(
+		`<!DOCTYPE html>
 <html>
-  <head>
-    <title>chasquid monitoring</title>
-  </head>
-  <body>
-    <h1>chasquid monitoring</h1>
 
-	chasquid {{.Version}}<br>
-	source date {{.SourceDate.Format "2006-01-02 15:04:05 -0700"}}<p>
+<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>
+
+chasquid {{.Version}}<br>
+source date {{.SourceDate.Format "2006-01-02 15:04:05 -0700"}}<p>
 
-	started {{.StartTime.Format "Mon, 2006-01-02 15:04:05 -0700"}}<br>
-	up since {{.StartTime | since}}<p>
+started {{.StartTime.Format "Mon, 2006-01-02 15:04:05 -0700"}}<br>
+up for {{.StartTime | since | roundDuration}}<br>
+os hostname <i>{{.Hostname}}</i><p>
 
+<ul>
+  <li><a href="/debug/queue">queue</a>
+  <li>monitoring
     <ul>
-      <li><a href="/debug/queue">queue</a>
+      <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="/debug/vars">exported variables</a>
-	       <small><a href="https://golang.org/pkg/expvar/">(ref)</a></small>
-	  <li>traces <small><a href="https://godoc.org/golang.org/x/net/trace">
-            (ref)</a></small>
-        <ul>
-          <li><a href="/debug/requests?exp=1">requests (short-lived)</a>
-          <li><a href="/debug/events?exp=1">events (long-lived)</a>
-        </ul>
+        <small><a href="https://golang.org/pkg/expvar/">(ref)</a></small>
+    </ul>
+  <li>execution
+    <ul>
       <li><a href="/debug/flags">flags</a>
-      <li><a href="/debug/pprof">pprof</a>
-          <small><a href="https://golang.org/pkg/net/http/pprof/">
-            (ref)</a></small>
-        <ul>
-          <li><a href="/debug/pprof/goroutine?debug=1">goroutines</a>
-        </ul>
+      <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>
-  </body>
+</ul>
+</body>
+
 </html>
 `))
 
-// dumpFlags to a string, for troubleshooting purposes.
-func dumpFlags() string {
-	s := ""
+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) {
-		s += fmt.Sprintf("-%s=%s\n", f.Name, f.Value.String())
+		fmt.Fprintf(w, "-%s=%s\n", f.Name, f.Value.String())
 		visited[f.Name] = true
 	})
 
-	s += "\n"
+	fmt.Fprintf(w, "\n")
+
 	flag.VisitAll(func(f *flag.Flag) {
 		if !visited[f.Name] {
-			s += fmt.Sprintf("-%s=%s\n", f.Name, f.Value.String())
+			fmt.Fprintf(w, "-%s=%s\n", f.Name, f.Value.String())
 		}
 	})
+}
 
-	return s
+func roundDuration(d time.Duration) time.Duration {
+	return d.Round(time.Second)
 }