Skip to content

Commit 693042c

Browse files
committed
Move the logic for collecting the metrics into a submodule.
So that this logic can be included in other libraries without the main func.
1 parent 5d1e706 commit 693042c

File tree

5 files changed

+178
-173
lines changed

5 files changed

+178
-173
lines changed

main.go

Lines changed: 56 additions & 145 deletions
Original file line numberDiff line numberDiff line change
@@ -1,101 +1,51 @@
1-
package main
1+
package main // import "github.com/jonnenauha/prometheus_varnish_exporter"
22

33
import (
44
"encoding/json"
55
"flag"
66
"fmt"
7-
"log"
87
"net/http"
98
"os"
10-
"sync"
119
"time"
1210

1311
"github.com/prometheus/client_golang/prometheus"
1412
"github.com/prometheus/client_golang/prometheus/promhttp"
13+
14+
"github.com/jonnenauha/prometheus_varnish_exporter/varnishexporter"
1515
)
1616

1717
var (
1818
ApplicationName = "prometheus_varnish_exporter"
1919
Version string
2020
VersionHash string
2121
VersionDate string
22-
23-
PrometheusExporter = NewPrometheusExporter()
24-
VarnishVersion = NewVarnishVersion()
25-
ExitHandler = &exitHandler{}
26-
27-
StartParams = &startParams{
28-
ListenAddress: ":9131", // Reserved and publicly announced at https://github.com/prometheus/prometheus/wiki/Default-port-allocations
29-
Path: "/metrics",
30-
VarnishstatExe: "varnishstat",
31-
Params: &varnishstatParams{},
32-
}
33-
logger *log.Logger
3422
)
3523

36-
type startParams struct {
37-
ListenAddress string
38-
Path string
39-
HealthPath string
40-
VarnishstatExe string
41-
VarnishDockerContainer string
42-
Params *varnishstatParams
43-
44-
Verbose bool
45-
ExitOnErrors bool
46-
Test bool
47-
Raw bool
48-
WithGoMetrics bool
49-
50-
noExit bool // deprecated
51-
}
52-
53-
type varnishstatParams struct {
54-
Instance string
55-
VSM string
56-
}
57-
58-
func (p *varnishstatParams) isEmpty() bool {
59-
return p.Instance == "" && p.VSM == ""
60-
}
61-
62-
func (p *varnishstatParams) make() (params []string) {
63-
// -n
64-
if p.Instance != "" {
65-
params = append(params, "-n", p.Instance)
66-
}
67-
// -N is not supported by 3.x
68-
if p.VSM != "" && VarnishVersion.EqualsOrGreater(4, 0) {
69-
params = append(params, "-N", p.VSM)
70-
}
71-
return params
72-
}
73-
7424
func init() {
7525
// prometheus conventions
76-
flag.StringVar(&StartParams.ListenAddress, "web.listen-address", StartParams.ListenAddress, "Address on which to expose metrics and web interface.")
77-
flag.StringVar(&StartParams.Path, "web.telemetry-path", StartParams.Path, "Path under which to expose metrics.")
78-
flag.StringVar(&StartParams.HealthPath, "web.health-path", StartParams.HealthPath, "Path under which to expose healthcheck. Disabled unless configured.")
26+
flag.StringVar(&varnishexporter.StartParams.ListenAddress, "web.listen-address", varnishexporter.StartParams.ListenAddress, "Address on which to expose metrics and web interface.")
27+
flag.StringVar(&varnishexporter.StartParams.Path, "web.telemetry-path", varnishexporter.StartParams.Path, "Path under which to expose metrics.")
28+
flag.StringVar(&varnishexporter.StartParams.HealthPath, "web.health-path", varnishexporter.StartParams.HealthPath, "Path under which to expose healthcheck. Disabled unless configured.")
7929

8030
// varnish
81-
flag.StringVar(&StartParams.VarnishstatExe, "varnishstat-path", StartParams.VarnishstatExe, "Path to varnishstat.")
82-
flag.StringVar(&StartParams.Params.Instance, "n", StartParams.Params.Instance, "varnishstat -n value.")
83-
flag.StringVar(&StartParams.Params.VSM, "N", StartParams.Params.VSM, "varnishstat -N value.")
31+
flag.StringVar(&varnishexporter.StartParams.VarnishstatExe, "varnishstat-path", varnishexporter.StartParams.VarnishstatExe, "Path to varnishstat.")
32+
flag.StringVar(&varnishexporter.StartParams.Params.Instance, "n", varnishexporter.StartParams.Params.Instance, "varnishstat -n value.")
33+
flag.StringVar(&varnishexporter.StartParams.Params.VSM, "N", varnishexporter.StartParams.Params.VSM, "varnishstat -N value.")
8434

8535
// docker
86-
flag.StringVar(&StartParams.VarnishDockerContainer, "docker-container-name", StartParams.VarnishDockerContainer, "Docker container name to exec varnishstat in.")
36+
flag.StringVar(&varnishexporter.StartParams.VarnishDockerContainer, "docker-container-name", varnishexporter.StartParams.VarnishDockerContainer, "Docker container name to exec varnishstat in.")
8737

8838
// modes
8939
version := false
9040
flag.BoolVar(&version, "version", version, "Print version and exit")
91-
flag.BoolVar(&StartParams.ExitOnErrors, "exit-on-errors", StartParams.ExitOnErrors, "Exit process on scrape errors.")
92-
flag.BoolVar(&StartParams.Verbose, "verbose", StartParams.Verbose, "Verbose logging.")
93-
flag.BoolVar(&StartParams.Test, "test", StartParams.Test, "Test varnishstat availability, prints available metrics and exits.")
94-
flag.BoolVar(&StartParams.Raw, "raw", StartParams.Test, "Raw stdout logging without timestamps.")
95-
flag.BoolVar(&StartParams.WithGoMetrics, "with-go-metrics", StartParams.WithGoMetrics, "Export go runtime and http handler metrics")
41+
flag.BoolVar(&varnishexporter.StartParams.ExitOnErrors, "exit-on-errors", varnishexporter.StartParams.ExitOnErrors, "Exit process on scrape errors.")
42+
flag.BoolVar(&varnishexporter.StartParams.Verbose, "verbose", varnishexporter.StartParams.Verbose, "Verbose varnishexporter.Logging.")
43+
flag.BoolVar(&varnishexporter.StartParams.Test, "test", varnishexporter.StartParams.Test, "Test varnishstat availability, prints available metrics and exits.")
44+
flag.BoolVar(&varnishexporter.StartParams.Raw, "raw", varnishexporter.StartParams.Test, "Raw stdout varnishexporter.Logging without timestamps.")
45+
flag.BoolVar(&varnishexporter.StartParams.WithGoMetrics, "with-go-metrics", varnishexporter.StartParams.WithGoMetrics, "Export go runtime and http handler metrics")
9646

9747
// deprecated
98-
flag.BoolVar(&StartParams.noExit, "no-exit", StartParams.noExit, "Deprecated: see -exit-on-errors")
48+
flag.BoolVar(&varnishexporter.StartParams.NoExit, "no-exit", varnishexporter.StartParams.NoExit, "Deprecated: see -exit-on-errors")
9949

10050
flag.Parse()
10151

@@ -104,42 +54,40 @@ func init() {
10454
os.Exit(0)
10555
}
10656

107-
logger = log.New(os.Stdout, "", log.Ldate|log.Ltime)
108-
109-
if len(StartParams.Path) == 0 || StartParams.Path[0] != '/' {
110-
logFatal("-web.telemetry-path cannot be empty and must start with a slash '/', given %q", StartParams.Path)
57+
if len(varnishexporter.StartParams.Path) == 0 || varnishexporter.StartParams.Path[0] != '/' {
58+
varnishexporter.LogFatal("-web.telemetry-path cannot be empty and must start with a slash '/', given %q", varnishexporter.StartParams.Path)
11159
}
112-
if len(StartParams.HealthPath) != 0 && StartParams.HealthPath[0] != '/' {
113-
logFatal("-web.health-path must start with a slash '/' if configured, given %q", StartParams.HealthPath)
60+
if len(varnishexporter.StartParams.HealthPath) != 0 && varnishexporter.StartParams.HealthPath[0] != '/' {
61+
varnishexporter.LogFatal("-web.health-path must start with a slash '/' if configured, given %q", varnishexporter.StartParams.HealthPath)
11462
}
115-
if StartParams.Path == StartParams.HealthPath {
116-
logFatal("-web.telemetry-path and -web.health-path cannot have same value")
63+
if varnishexporter.StartParams.Path == varnishexporter.StartParams.HealthPath {
64+
varnishexporter.LogFatal("-web.telemetry-path and -web.health-path cannot have same value")
11765
}
11866

119-
// Don't log warning on !noExit as that would spam for the formed default value.
120-
if StartParams.noExit {
121-
logWarn("-no-exit is deprecated. As of v1.5 it is the default behavior not to exit process on scrape errors. You can remove this parameter.")
67+
// Don't varnishexporter.Log warning on !noExit as that would spam for the formed default value.
68+
if varnishexporter.StartParams.NoExit {
69+
varnishexporter.LogWarn("-no-exit is deprecated. As of v1.5 it is the default behavior not to exit process on scrape errors. You can remove this parameter.")
12270
}
12371

12472
// Test run or user explicitly wants to exit on any scrape errors during runtime.
125-
ExitHandler.exitOnError = StartParams.Test == true || StartParams.ExitOnErrors == true
73+
varnishexporter.ExitHandler.ExitOnError = varnishexporter.StartParams.Test == true || varnishexporter.StartParams.ExitOnErrors == true
12674
}
12775

12876
func main() {
129-
if b, err := json.MarshalIndent(StartParams, "", " "); err == nil {
130-
logInfo("%s %s %s", ApplicationName, getVersion(false), b)
77+
if b, err := json.MarshalIndent(varnishexporter.StartParams, "", " "); err == nil {
78+
varnishexporter.LogInfo("%s %s %s", ApplicationName, getVersion(false), b)
13179
} else {
132-
logFatal(err.Error())
80+
varnishexporter.LogFatal(err.Error())
13381
}
13482

13583
// Initialize
136-
if err := VarnishVersion.Initialize(); err != nil {
137-
ExitHandler.Errorf("Varnish version initialize failed: %s", err.Error())
84+
if err := varnishexporter.VarnishVersion.Initialize(); err != nil {
85+
varnishexporter.ExitHandler.Errorf("Varnish version initialize failed: %s", err.Error())
13886
}
139-
if VarnishVersion.Valid() {
140-
logInfo("Found varnishstat %s", VarnishVersion)
141-
if err := PrometheusExporter.Initialize(); err != nil {
142-
logFatal("Prometheus exporter initialize failed: %s", err.Error())
87+
if varnishexporter.VarnishVersion.Valid() {
88+
varnishexporter.LogInfo("Found varnishstat %s", varnishexporter.VarnishVersion)
89+
if err := varnishexporter.PrometheusExporter.Initialize(); err != nil {
90+
varnishexporter.LogFatal("Prometheus exporter initialize failed: %s", err.Error())
14391
}
14492
}
14593

@@ -149,105 +97,68 @@ func main() {
14997
metrics := make(chan prometheus.Metric)
15098
go func() {
15199
for m := range metrics {
152-
if StartParams.Test {
153-
logInfo("%s", m.Desc())
100+
if varnishexporter.StartParams.Test {
101+
varnishexporter.LogInfo("%s", m.Desc())
154102
}
155103
}
156104
done <- true
157105
}()
158106
tStart := time.Now()
159-
buf, err := ScrapeVarnish(metrics)
107+
buf, err := varnishexporter.ScrapeVarnish(metrics)
160108
close(metrics)
161109
<-done
162110

163111
if err == nil {
164-
logInfo("Test scrape done in %s", time.Now().Sub(tStart))
165-
logRaw("")
112+
varnishexporter.LogInfo("Test scrape done in %s", time.Now().Sub(tStart))
113+
varnishexporter.LogRaw("")
166114
} else {
167115
if len(buf) > 0 {
168-
logRaw("\n%s", buf)
116+
varnishexporter.LogRaw("\n%s", buf)
169117
}
170-
ExitHandler.Errorf("Startup test: %s", err.Error())
118+
varnishexporter.ExitHandler.Errorf("Startup test: %s", err.Error())
171119
}
172120
}
173-
if StartParams.Test {
121+
if varnishexporter.StartParams.Test {
174122
return
175123
}
176124

177125
// Start serving
178-
logInfo("Server starting on %s with metrics path %s", StartParams.ListenAddress, StartParams.Path)
126+
varnishexporter.LogInfo("Server starting on %s with metrics path %s", varnishexporter.StartParams.ListenAddress, varnishexporter.StartParams.Path)
179127

180-
if !StartParams.WithGoMetrics {
128+
if !varnishexporter.StartParams.WithGoMetrics {
181129
registry := prometheus.NewRegistry()
182-
if err := registry.Register(PrometheusExporter); err != nil {
183-
logFatal("registry.Register failed: %s", err.Error())
130+
if err := registry.Register(varnishexporter.PrometheusExporter); err != nil {
131+
varnishexporter.LogFatal("registry.Register failed: %s", err.Error())
184132
}
185133
handler := promhttp.HandlerFor(registry, promhttp.HandlerOpts{
186-
ErrorLog: logger,
134+
ErrorLog: varnishexporter.Logger,
187135
})
188-
http.Handle(StartParams.Path, handler)
136+
http.Handle(varnishexporter.StartParams.Path, handler)
189137
} else {
190-
prometheus.MustRegister(PrometheusExporter)
191-
http.Handle(StartParams.Path, promhttp.Handler())
138+
prometheus.MustRegister(varnishexporter.PrometheusExporter)
139+
http.Handle(varnishexporter.StartParams.Path, promhttp.Handler())
192140
}
193141

194-
if StartParams.Path != "/" {
142+
if varnishexporter.StartParams.Path != "/" {
195143
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
196144
w.Write([]byte(`<html>
197145
<head><title>Varnish Exporter</title></head>
198146
<body>
199147
<h1>Varnish Exporter</h1>
200-
<p><a href="` + StartParams.Path + `">Metrics</a></p>
148+
<p><a href="` + varnishexporter.StartParams.Path + `">Metrics</a></p>
201149
</body>
202150
</html>`))
203151
})
204152
}
205-
if StartParams.HealthPath != "" {
206-
http.HandleFunc(StartParams.HealthPath, func(w http.ResponseWriter, r *http.Request) {
153+
if varnishexporter.StartParams.HealthPath != "" {
154+
http.HandleFunc(varnishexporter.StartParams.HealthPath, func(w http.ResponseWriter, r *http.Request) {
207155
// As noted in the "up" metric, needs some way to determine if everything is actually Ok.
208156
// For now, this just lets us check that we're accepting connections
209157
w.WriteHeader(http.StatusOK)
210158
fmt.Fprintln(w, "Ok")
211159
})
212160
}
213-
logFatalError(http.ListenAndServe(StartParams.ListenAddress, nil))
214-
}
215-
216-
type exitHandler struct {
217-
sync.RWMutex
218-
exitOnError bool
219-
err error
220-
}
221-
222-
func (ex *exitHandler) Errorf(format string, a ...interface{}) error {
223-
return ex.Set(fmt.Errorf(format, a...))
224-
}
225-
226-
func (ex *exitHandler) HasError() bool {
227-
ex.RLock()
228-
hasError := ex.err != nil
229-
ex.RUnlock()
230-
return hasError
231-
}
232-
233-
func (ex *exitHandler) Set(err error) error {
234-
ex.Lock()
235-
defer ex.Unlock()
236-
237-
if err == nil {
238-
ex.err = nil
239-
return nil
240-
}
241-
242-
errDiffers := ex.err == nil || ex.err.Error() != err.Error()
243-
ex.err = err
244-
245-
if ex.exitOnError {
246-
logFatal("%s", err.Error())
247-
} else if errDiffers {
248-
logError("%s", err.Error())
249-
}
250-
return err
161+
varnishexporter.LogFatalError(http.ListenAndServe(varnishexporter.StartParams.ListenAddress, nil))
251162
}
252163

253164
func getVersion(date bool) (version string) {

prometheus.go renamed to varnishexporter/prometheus.go

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
package main
1+
package varnishexporter
22

33
import (
44
"regexp"
@@ -13,6 +13,10 @@ const (
1313
exporterNamespace = "varnish"
1414
)
1515

16+
var (
17+
PrometheusExporter = NewPrometheusExporter()
18+
)
19+
1620
// prometheusExporter
1721

1822
type prometheusExporter struct {
@@ -53,7 +57,7 @@ func (pe *prometheusExporter) Describe(ch chan<- *prometheus.Desc) {
5357
}
5458

5559
if StartParams.Verbose {
56-
logInfo("prometheus.Collector.Describe %s", time.Now().Sub(start))
60+
LogInfo("prometheus.Collector.Describe %s", time.Now().Sub(start))
5761
}
5862
}
5963

@@ -84,7 +88,7 @@ func (pe *prometheusExporter) Collect(ch chan<- prometheus.Metric) {
8488

8589
if err == nil {
8690
if hadError {
87-
logInfo("Successful scrape")
91+
LogInfo("Successful scrape")
8892
}
8993
pe.up.Set(1)
9094
} else {
@@ -101,7 +105,7 @@ func (pe *prometheusExporter) Collect(ch chan<- prometheus.Metric) {
101105
if err != nil {
102106
postfix = " (scrape failed)"
103107
}
104-
logInfo("prometheus.Collector.Collect %s%s", time.Now().Sub(start), postfix)
108+
LogInfo("prometheus.Collector.Collect %s%s", time.Now().Sub(start), postfix)
105109
}
106110
}
107111

0 commit comments

Comments
 (0)