diff --git a/Makefile b/Makefile index ccd14c5..bcf7c79 100644 --- a/Makefile +++ b/Makefile @@ -1,13 +1,32 @@ -.PHONY: clean run +## +# +.DEFAULT_GOAL := help -linux: - GOOS=linux GOARCH=amd64 go build -o output/mystrom-exporter_linux-amd64 -mac: - GOOS=darwin GOARCH=amd64 go build -o output/mystrom-exporter_mac-amd64 +version := $(shell git describe --tags --always) +revision := $(shell git rev-parse HEAD) +branch := $(shell git rev-parse --abbrev-ref HEAD) +builduser := $(shell whoami) +builddate := $(shell date '+%FT%T_%Z') + +versionPkgPrefix := mystrom-exporter/pkg/version + +LDFLAGS := -w -s \ + -X $(versionPkgPrefix).Version=${version} \ + -X $(versionPkgPrefix).Revision=${revision} \ + -X $(versionPkgPrefix).Branch=${branch} \ + -X $(versionPkgPrefix).BuildUser=${builduser} \ + -X $(versionPkgPrefix).BuildDate=${builddate} +GOFLAGS := -v + +linux: ## builds the linux version of the exporter + GOOS=linux GOARCH=amd64 go build $(GOFLAGS) -ldflags '$(LDFLAGS)' +mac: ## builds the macos version of the exporter + GOOS=darwin GOARCH=amd64 go build $(GOFLAGS) -ldflags '$(LDFLAGS)' arm64: - GOOS=linux GOARCH=arm64 go build -o output/mystrom-exporter_linux-arm64 + GOOS=linux GOARCH=arm64 go build $(GOFLAGS) -ldflags '$(LDFLAGS)' arm: - GOOS=linux GOARCH=arm go build -o output/mystrom-exporter_linux-arm + GOOS=linux GOARCH=arm go build $(GOFLAGS) -ldflags '$(LDFLAGS)' - -all: linux mac arm64 arm \ No newline at end of file +# -- +help: + @grep -E '^[a-zA-Z_-]+:.*?## .*$$' $(MAKEFILE_LIST) | sort | awk 'BEGIN {FS = ":.*?## "}; {printf "\033[36m%-30s\033[0m %s\n", $$1, $$2}' diff --git a/main.go b/main.go index f7f11ec..2379284 100644 --- a/main.go +++ b/main.go @@ -12,6 +12,8 @@ import ( "github.com/prometheus/client_golang/prometheus" "github.com/prometheus/client_golang/prometheus/promhttp" + + "mystrom-exporter/pkg/version" ) type switchReport struct { @@ -30,6 +32,8 @@ var ( "Path under which to expose metrics") switchIP = flag.String("switch.ip-address", "", "IP address of the switch you try to monitor") + showVersion = flag.Bool("version", false, + "Show version information.") up = prometheus.NewDesc( prometheus.BuildFQName(namespace, "", "up"), @@ -169,14 +173,36 @@ func main() { flag.Parse() + // Show version information + if *showVersion { + v, err := version.Print("mystrom_exporter") + if err != nil { + log.Fatalf("Failed to print version information: %#v", err) + } + + fmt.Fprintln(os.Stdout, v) + os.Exit(0) + } + if *switchIP == "" { flag.Usage() fmt.Println("\nNo switch.ip-address provided") os.Exit(1) } + // make the build information is available through a metric + buildInfo := prometheus.NewGaugeVec( + prometheus.GaugeOpts{ + Namespace: "scripts", + Name: "build_info", + Help: "A metric with a constant '1' value labeled by build information.", + }, + []string{"version", "revision", "branch", "goversion", "builddate", "builduser"}, + ) + buildInfo.WithLabelValues(version.Version, version.Revision, version.Branch, version.GoVersion, version.BuildDate, version.BuildUser).Set(1) + exporter := NewExporter(*switchIP) - prometheus.MustRegister(exporter) + prometheus.MustRegister(exporter, buildInfo) http.Handle(*metricsPath, promhttp.Handler()) http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { diff --git a/pkg/version/version.go b/pkg/version/version.go new file mode 100644 index 0000000..5d52c04 --- /dev/null +++ b/pkg/version/version.go @@ -0,0 +1,60 @@ +package version + +import ( + "bytes" + "fmt" + "runtime" + "strings" + "text/template" +) + +// Build information. Populated at build-time. +var ( + Version string + Revision string + Branch string + BuildUser string + BuildDate string + GoVersion = runtime.Version() +) + +// versionInfoTmpl contains the template used by Print. +var versionInfoTmpl = ` +{{.program}}, version {{.version}} (branch: {{.branch}}, revision: {{.revision}}) + build user: {{.buildUser}} + build date: {{.buildDate}} + go version: {{.goVersion}} +` + +// Print returns version information. +func Print(program string) (string, error) { + m := map[string]string{ + "program": program, + "version": Version, + "revision": Revision, + "branch": Branch, + "buildUser": BuildUser, + "buildDate": BuildDate, + "goVersion": GoVersion, + } + t, err := template.New("version").Parse(versionInfoTmpl) + if err != nil { + return "", err + } + + var buf bytes.Buffer + if err := t.ExecuteTemplate(&buf, "version", m); err != nil { + return "", err + } + return strings.TrimSpace(buf.String()), nil +} + +// Info returns version, branch and revision information. +func Info() string { + return fmt.Sprintf("(version=%s, branch=%s, revision=%s)", Version, Branch, Revision) +} + +// BuildContext returns goVersion, buildUser and buildDate information. +func BuildContext() string { + return fmt.Sprintf("(go=%s, user=%s, date=%s)", GoVersion, BuildUser, BuildDate) +}