From c87c5ec1bcae04bc48032b251b040a8cd13d6a6f Mon Sep 17 00:00:00 2001 From: Alberto Bertogli Date: Sat, 22 Oct 2016 09:32:06 +0100 Subject: [PATCH] chasquid: Include build and version information This patch adds the possibility of setting build and version information, which will be exported and displayed in the monitoring http server. --- chasquid.go | 67 ++++++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 64 insertions(+), 3 deletions(-) diff --git a/chasquid.go b/chasquid.go index 3d34785..b07c993 100644 --- a/chasquid.go +++ b/chasquid.go @@ -1,14 +1,17 @@ package main import ( + "expvar" "flag" "fmt" + "html/template" "io/ioutil" "math/rand" "net" "os" "os/signal" "path/filepath" + "strconv" "syscall" "time" @@ -30,11 +33,35 @@ import ( var ( configDir = flag.String("config_dir", "/etc/chasquid", "configuration directory") + showVer = flag.Bool("version", false, "show version and exit") +) + +// Build information, overridden at build time using +// -ldflags="-X main.version=blah". +var ( + version = "undefined" + sourceDateTs = "0" +) + +var ( + versionVar = expvar.NewString("chasquid/version") + + sourceDate time.Time + sourceDateVar = expvar.NewString("chasquid/sourceDateStr") + sourceDateTsVar = expvar.NewInt("chasquid/sourceDateTimestamp") ) func main() { flag.Parse() + parseVersionInfo() + if *showVer { + fmt.Printf("chasquid %s (source date: %s)\n", version, sourceDate) + return + } + + glog.Infof("chasquid starting (version %s)", version) + setupSignalHandling() defer glog.Flush() @@ -223,15 +250,40 @@ func mustReadDir(path string) []os.FileInfo { return dirs } +func parseVersionInfo() { + versionVar.Set(version) + + sdts, err := strconv.ParseInt(sourceDateTs, 10, 0) + if err != nil { + panic(err) + } + + sourceDate = time.Unix(sdts, 0) + sourceDateVar.Set(sourceDate.Format("2006-01-02 15:04:05 -0700")) + sourceDateTsVar.Set(sdts) +} + func launchMonitoringServer(addr string) { glog.Infof("Monitoring HTTP server listening on %s", addr) + indexData := struct { + Version string + SourceDate time.Time + StartTime time.Time + }{ + Version: version, + SourceDate: sourceDate, + StartTime: time.Now(), + } + http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { if r.URL.Path != "/" { http.NotFound(w, r) return } - w.Write([]byte(monitoringHTMLIndex)) + if err := monitoringHTMLIndex.Execute(w, indexData); err != nil { + glog.Infof("monitoring handler error: %v", err) + } }) flags := dumpFlags() @@ -243,13 +295,22 @@ func launchMonitoringServer(addr string) { } // Static index for the monitoring website. -const monitoringHTMLIndex = ` +var monitoringHTMLIndex = template.Must(template.New("index").Funcs( + template.FuncMap{"since": time.Since}).Parse( + ` chasquid monitoring

chasquid monitoring

+ + chasquid {{.Version}}
+ source date {{.SourceDate.Format "2006-01-02 15:04:05 -0700"}}

+ + started {{.StartTime.Format "Mon, 2006-01-02 15:04:05 -0700"}}
+ up since {{.StartTime | since}}

+

-` +`)) // dumpFlags to a string, for troubleshooting purposes. func dumpFlags() string {