From 26b5c8e767ac17a40dbee3a5ef4c8e720a2ee5f6 Mon Sep 17 00:00:00 2001 From: ricoberger Date: Thu, 4 Jul 2019 20:45:23 +0200 Subject: [PATCH 1/4] Add new test case The new test case use use the new 'direct run' feature --- Makefile | 2 +- cmd/curltest/curltest.go | 25 +++++++++++++++++++++++++ config.yaml | 2 ++ 3 files changed, 28 insertions(+), 1 deletion(-) create mode 100644 cmd/curltest/curltest.go diff --git a/Makefile b/Makefile index 37db174..dd4acfa 100644 --- a/Makefile +++ b/Makefile @@ -1,4 +1,4 @@ -WHAT := script_exporter +WHAT := curltest script_exporter BUILDTIME := $(shell date +%FT%T%Z) VERSION=`git describe --tags` COMMIT=`git rev-parse HEAD` diff --git a/cmd/curltest/curltest.go b/cmd/curltest/curltest.go new file mode 100644 index 0000000..162a535 --- /dev/null +++ b/cmd/curltest/curltest.go @@ -0,0 +1,25 @@ +package main + +import ( + "fmt" + "net/http" + "os" +) + +func main() { + if len(os.Args) != 2 { + os.Exit(1) + } + + t := os.Args[1] + res, err := http.Get(t) + if err != nil { + os.Exit(1) + } + + defer res.Body.Close() + + fmt.Printf("# HELP curl_status_code returns the status code of the target\n") + fmt.Printf("# TYPE curl_status_code gauge\n") + fmt.Printf("curl_status_code{target=\"%s\"} %d\n", t, res.StatusCode) +} diff --git a/config.yaml b/config.yaml index 524fc83..17bd5b2 100644 --- a/config.yaml +++ b/config.yaml @@ -19,3 +19,5 @@ scripts: script: ./examples/ping.sh - name: helloworld script: ./examples/helloworld.sh test + - name: curltest + script: ./bin/curltest From 0d5797877b749afb009fda159afbaae0e0e0684b Mon Sep 17 00:00:00 2001 From: ricoberger Date: Thu, 4 Jul 2019 20:47:45 +0200 Subject: [PATCH 2/4] Fix the check if the script is available We checked if the provided script parameter is empty instead of the returned script. --- cmd/script_exporter/script_exporter.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmd/script_exporter/script_exporter.go b/cmd/script_exporter/script_exporter.go index 6c76025..6385ff6 100644 --- a/cmd/script_exporter/script_exporter.go +++ b/cmd/script_exporter/script_exporter.go @@ -82,7 +82,7 @@ func metricsHandler(w http.ResponseWriter, r *http.Request) { // Get and run script script := exporterConfig.GetScript(scriptName) - if scriptName == "" { + if script == "" { log.Printf("Script not found\n") http.Error(w, "Script not found", http.StatusBadRequest) return From f6527cbb641629f712abf331630da4da277edd6e Mon Sep 17 00:00:00 2001 From: ricoberger Date: Thu, 4 Jul 2019 21:03:10 +0200 Subject: [PATCH 3/4] Improve versioning --- Makefile | 77 ++++++++++++++++++-------- cmd/script_exporter/script_exporter.go | 28 +++++----- pkg/version/version.go | 61 +++++++++++++++----- 3 files changed, 116 insertions(+), 50 deletions(-) diff --git a/Makefile b/Makefile index dd4acfa..096cabd 100644 --- a/Makefile +++ b/Makefile @@ -1,45 +1,78 @@ WHAT := curltest script_exporter -BUILDTIME := $(shell date +%FT%T%Z) -VERSION=`git describe --tags` -COMMIT=`git rev-parse HEAD` -BUILDUSER := $(shell id -un) -.PHONY: build build-darwin-amd64 build-linux-amd64 build-windows-amd64 release +PROJECT ?= script_exporter +REPO ?= github.com/ricoberger/script_exporter +PWD ?= $(shell pwd) +VERSION ?= $(shell git describe --tags) +REVISION ?= $(shell git rev-parse HEAD) +BRANCH ?= $(shell git rev-parse --abbrev-ref HEAD) +BUILDUSER ?= $(shell id -un) +BUILDTIME ?= $(shell date '+%Y%m%d-%H:%M:%S') + +.PHONY: build build-darwin-amd64 build-linux-amd64 build-windows-amd64 clean release release-major release-minor release-patch build: for target in $(WHAT); do \ - go build -ldflags "-X github.com/ricoberger/script_exporter/pkg/version.GitCommit=${COMMIT} \ - -X github.com/ricoberger/script_exporter/pkg/version.Version=${VERSION} \ - -X github.com/ricoberger/script_exporter/pkg/version.BuildTime=${BUILDTIME} \ - -X github.com/ricoberger/script_exporter/pkg/version.BuildUser=${BUILDUSER}" \ + go build -ldflags "-X ${REPO}/pkg/version.Version=${VERSION} \ + -X ${REPO}/pkg/version.Revision=${REVISION} \ + -X ${REPO}/pkg/version.Branch=${BRANCH} \ + -X ${REPO}/pkg/version.BuildUser=${BUILDUSER} \ + -X ${REPO}/pkg/version.BuildDate=${BUILDTIME}" \ -o ./bin/$$target ./cmd/$$target; \ done build-darwin-amd64: for target in $(WHAT); do \ - CGO_ENABLED=0 GOARCH=amd64 GOOS=darwin go build -a -installsuffix cgo -ldflags "-X github.com/ricoberger/script_exporter/pkg/version.GitCommit=${COMMIT} \ - -X github.com/ricoberger/script_exporter/pkg/version.Version=${VERSION} \ - -X github.com/ricoberger/script_exporter/pkg/version.BuildTime=${BUILDTIME} \ - -X github.com/ricoberger/script_exporter/pkg/version.BuildUser=${BUILDUSER}" \ + CGO_ENABLED=0 GOARCH=amd64 GOOS=darwin go build -a -installsuffix cgo -ldflags "-X ${REPO}/pkg/version.Version=${VERSION} \ + -X ${REPO}/pkg/version.Revision=${REVISION} \ + -X ${REPO}/pkg/version.Branch=${BRANCH} \ + -X ${REPO}/pkg/version.BuildUser=${BUILDUSER} \ + -X ${REPO}/pkg/version.BuildDate=${BUILDTIME}" \ -o ./bin/$$target-${VERSION}-darwin-amd64 ./cmd/$$target; \ done build-linux-amd64: for target in $(WHAT); do \ - CGO_ENABLED=0 GOARCH=amd64 GOOS=linux go build -a -installsuffix cgo -ldflags "-X github.com/ricoberger/script_exporter/pkg/version.GitCommit=${COMMIT} \ - -X github.com/ricoberger/script_exporter/pkg/version.Version=${VERSION} \ - -X github.com/ricoberger/script_exporter/pkg/version.BuildTime=${BUILDTIME} \ - -X github.com/ricoberger/script_exporter/pkg/version.BuildUser=${BUILDUSER}" \ + CGO_ENABLED=0 GOARCH=amd64 GOOS=linux go build -a -installsuffix cgo -ldflags "-X ${REPO}/pkg/version.Version=${VERSION} \ + -X ${REPO}/pkg/version.Revision=${REVISION} \ + -X ${REPO}/pkg/version.Branch=${BRANCH} \ + -X ${REPO}/pkg/version.BuildUser=${BUILDUSER} \ + -X ${REPO}/pkg/version.BuildDate=${BUILDTIME}" \ -o ./bin/$$target-${VERSION}-linux-amd64 ./cmd/$$target; \ done build-windows-amd64: for target in $(WHAT); do \ - CGO_ENABLED=0 GOARCH=amd64 GOOS=windows go build -a -installsuffix cgo -ldflags "-X github.com/ricoberger/script_exporter/pkg/version.GitCommit=${COMMIT} \ - -X github.com/ricoberger/script_exporter/pkg/version.Version=${VERSION} \ - -X github.com/ricoberger/script_exporter/pkg/version.BuildTime=${BUILDTIME} \ - -X github.com/ricoberger/script_exporter/pkg/version.BuildUser=${BUILDUSER}" \ + CGO_ENABLED=0 GOARCH=amd64 GOOS=windows go build -a -installsuffix cgo -ldflags "-X ${REPO}/pkg/version.Version=${VERSION} \ + -X ${REPO}/pkg/version.Revision=${REVISION} \ + -X ${REPO}/pkg/version.Branch=${BRANCH} \ + -X ${REPO}/pkg/version.BuildUser=${BUILDUSER} \ + -X ${REPO}/pkg/version.BuildDate=${BUILDTIME}" \ -o ./bin/$$target-${VERSION}-windows-amd64.exe ./cmd/$$target; \ done -release: build-darwin-amd64 build-linux-amd64 build-windows-amd64 +clean: + rm -rf ./bin + +release: clean build-darwin-amd64 build-linux-amd64 build-windows-amd64 + +release-major: + $(eval MAJORVERSION=$(shell git describe --tags --abbrev=0 | sed s/v// | awk -F. '{print "v"$$1+1".0.0"}')) + git checkout master + git pull + git tag -a $(MAJORVERSION) -m 'release $(MAJORVERSION)' + git push origin --tags + +release-minor: + $(eval MINORVERSION=$(shell git describe --tags --abbrev=0 | sed s/v// | awk -F. '{print "v"$$1"."$$2+1".0"}')) + git checkout master + git pull + git tag -a $(MINORVERSION) -m 'release $(MINORVERSION)' + git push origin --tags + +release-patch: + $(eval PATCHVERSION=$(shell git describe --tags --abbrev=0 | sed s/v// | awk -F. '{print "v"$$1"."$$2"."$$3+1}')) + git checkout master + git pull + git tag -a $(PATCHVERSION) -m 'release $(PATCHVERSION)' + git push origin --tags diff --git a/cmd/script_exporter/script_exporter.go b/cmd/script_exporter/script_exporter.go index 6385ff6..7b5ac82 100644 --- a/cmd/script_exporter/script_exporter.go +++ b/cmd/script_exporter/script_exporter.go @@ -135,16 +135,14 @@ func main() { // Parse command-line flags flag.Parse() - // Format build time - buildTime, _ := time.Parse("2006-01-02T15:04:05MST", version.BuildTime) - // Show version information if *showVersion { - fmt.Printf("script_exporter, version %s, by %s\n", version.Version, version.Author) - fmt.Printf(" build user: %s\n", version.BuildUser) - fmt.Printf(" build date: %s\n", buildTime.Format(time.RFC1123)) - fmt.Printf(" build commit: %s\n", version.GitCommit) - fmt.Printf(" go version: %s\n", version.GoVersion) + v, err := version.Print("script_exporter") + if err != nil { + log.Fatalf("Failed to print version information: %#v", err) + } + + fmt.Fprintln(os.Stdout, v) os.Exit(0) } @@ -166,9 +164,9 @@ func main() { } // Start exporter - log.Printf("Starting script_exporter, version %s\n", version.Version) - log.Printf("Build go=%s, user=%s, date=%s, commit=%s\n", version.GoVersion, version.BuildUser, buildTime.Format(time.RFC1123), version.GitCommit) - log.Printf("Listening on %s\n", *listenAddress) + fmt.Printf("Starting server %s\n", version.Info()) + fmt.Printf("Build context %s\n", version.BuildContext()) + fmt.Printf("script_exporter listening on %s\n", *listenAddress) http.HandleFunc(*metricsPath, use(metricsHandler, auth)) http.HandleFunc("/", use(func(w http.ResponseWriter, r *http.Request) { @@ -179,11 +177,11 @@ func main() {

Metrics

  • version: ` + version.Version + `
  • -
  • author: ` + version.Author + `
  • -
  • build user: ` + version.BuildUser + `
  • -
  • build date: ` + buildTime.Format(time.RFC1123) + `
  • -
  • build commit: ` + version.GitCommit + `
  • +
  • branch: ` + version.Branch + `
  • +
  • revision: ` + version.Revision + `
  • go version: ` + version.GoVersion + `
  • +
  • build user: ` + version.BuildUser + `
  • +
  • build date: ` + version.BuildDate + `

`)) diff --git a/pkg/version/version.go b/pkg/version/version.go index a1a2612..5d52c04 100644 --- a/pkg/version/version.go +++ b/pkg/version/version.go @@ -1,25 +1,60 @@ package version import ( + "bytes" + "fmt" "runtime" + "strings" + "text/template" ) +// Build information. Populated at build-time. var ( - // Version contains the version which is defined in the MAKEFILE - Version string + Version string + Revision string + Branch string + BuildUser string + BuildDate string + GoVersion = runtime.Version() +) - // BuildTime is the time when the binaries where build - BuildTime string +// 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}} +` - // BuildUser is the name of the user which build the binaries - BuildUser string +// 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 + } - // GitCommit is the git commit on which the binaries where build - GitCommit string + var buf bytes.Buffer + if err := t.ExecuteTemplate(&buf, "version", m); err != nil { + return "", err + } + return strings.TrimSpace(buf.String()), nil +} - // GoVersion is the version of go with which the program was build - GoVersion = runtime.Version() +// Info returns version, branch and revision information. +func Info() string { + return fmt.Sprintf("(version=%s, branch=%s, revision=%s)", Version, Branch, Revision) +} - // Author hold author information - Author = "Rico Berger " -) +// BuildContext returns goVersion, buildUser and buildDate information. +func BuildContext() string { + return fmt.Sprintf("(go=%s, user=%s, date=%s)", GoVersion, BuildUser, BuildDate) +} From 8a6e8d68ccd05976b65c62396eb1cc3e3629398a Mon Sep 17 00:00:00 2001 From: ricoberger Date: Thu, 4 Jul 2019 21:16:31 +0200 Subject: [PATCH 4/4] Improve documentation --- README.md | 25 +++++-------------------- 1 file changed, 5 insertions(+), 20 deletions(-) diff --git a/README.md b/README.md index 9eedd5a..075017e 100644 --- a/README.md +++ b/README.md @@ -23,27 +23,12 @@ Running: ./bin/script_exporter ``` -Then visit [http://localhost:9469/metrics?script=test&prefix=test](http://localhost:9469/metrics?script=test&prefix=test) in the browser of your choice. There you should see the following output: +Then visit [http://localhost:9469](http://localhost:9469) in the browser of your choice. There you have access to the following examples: -``` -# HELP script_success Script exit status (0 = error, 1 = success). -# TYPE script_success gauge -script_success{} 1 -# HELP script_duration_seconds Script execution time, in seconds. -# TYPE script_duration_seconds gauge -script_duration_seconds{} 0.006133 -# HELP test_first_test -# TYPE test_first_test gauge -test_first_test{label="test_1_label_1"} 1 -# HELP test_second_test -# TYPE test_second_test gauge -test_second_test{label="test_2_label_1",label="test_2_label_2"} 2.71828182846 -# HELP test_third_test -# TYPE test_third_test gauge -test_third_test{} 3.14159265359 -``` - -You can also visit the following url for a more complex example. The `ping` example uses the `params` parameter to check if a `target` is reachable: [http://localhost:9469/metrics?script=ping&prefix=test¶ms=target&target=example.com](http://localhost:9469/metrics?script=ping&prefix=test¶ms=target&target=example.com) +- [test](http://localhost:9469/metrics?script=test&prefix=test): Invalid values which are returned by the script are omitted. +- [ping](http://localhost:9469/metrics?script=ping&prefix=test¶ms=target&target=example.com): Pings the specified address in the `target` parameter and returns if it was successful or not. +- [helloworld](http://localhost:9469/metrics?script=helloworld): Returns the specified argument in the `script` as label. +- [curltest](http://localhost:9469/metrics?script=curltest¶ms=target&target=https://example.com): Runs a binary, which performs a get request against the specified `target` and returns the status code. ## Usage and configuration