Skip to content

Commit 88e80ea

Browse files
authored
Merge pull request #4 from hnlq715/const-metrics
Const metrics
2 parents 0b16f2b + d22111f commit 88e80ea

File tree

5 files changed

+212
-112
lines changed

5 files changed

+212
-112
lines changed

.promu.yml

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
repository:
2+
path: github.com/hnlq715/nginx-vts-exporter
3+
build:
4+
flags: -a -tags netgo
5+
ldflags: |
6+
-X {{repoPath}}/vendor/github.com/prometheus/common/version.Version={{.Version}}
7+
-X {{repoPath}}/vendor/github.com/prometheus/common/version.Revision={{.Revision}}
8+
-X {{repoPath}}/vendor/github.com/prometheus/common/version.Branch={{.Branch}}
9+
-X {{repoPath}}/vendor/github.com/prometheus/common/version.BuildUser={{user}}@{{host}}
10+
-X {{repoPath}}/vendor/github.com/prometheus/common/version.BuildDate={{date "20060102-15:04:05"}}
11+
tarball:
12+
files:
13+
- LICENSE
14+
15+
crossbuild:
16+
platforms:
17+
- linux/amd64
18+
- linux/386
19+
- darwin/amd64
20+
- darwin/386
21+
- windows/amd64
22+
- windows/386

VERSION

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
0.1

nginx_vts_exporter.go

Lines changed: 94 additions & 112 deletions
Original file line numberDiff line numberDiff line change
@@ -10,11 +10,11 @@ import (
1010
"net/http"
1111
"os"
1212
"strconv"
13-
"sync"
1413
"time"
1514

1615
"github.com/prometheus/client_golang/prometheus"
1716
"github.com/prometheus/client_golang/prometheus/promhttp"
17+
"github.com/prometheus/common/version"
1818
)
1919

2020
type NginxVts struct {
@@ -142,61 +142,48 @@ func FloatToString(input_num float64) string {
142142
}
143143

144144
type Exporter struct {
145-
URI string
146-
mutex sync.RWMutex
145+
URI string
147146

148-
serverMetrics, upstreamMetrics, cacheMetrics map[string]*prometheus.GaugeVec
147+
serverMetrics, upstreamMetrics, cacheMetrics map[string]*prometheus.Desc
149148
}
150149

151-
func newServerMetric(metricName string, docString string, labels []string) *prometheus.GaugeVec {
152-
return prometheus.NewGaugeVec(
153-
prometheus.GaugeOpts{
154-
Namespace: *metricsNamespace,
155-
Name: "server_" + metricName,
156-
Help: docString,
157-
},
158-
labels,
150+
func newServerMetric(metricName string, docString string, labels []string) *prometheus.Desc {
151+
return prometheus.NewDesc(
152+
prometheus.BuildFQName(*metricsNamespace, "server", metricName),
153+
docString, labels, nil,
159154
)
160155
}
161156

162-
func newUpstreamMetric(metricName string, docString string, labels []string) *prometheus.GaugeVec {
163-
return prometheus.NewGaugeVec(
164-
prometheus.GaugeOpts{
165-
Namespace: *metricsNamespace,
166-
Name: "upstream_" + metricName,
167-
Help: docString,
168-
},
169-
labels,
157+
func newUpstreamMetric(metricName string, docString string, labels []string) *prometheus.Desc {
158+
return prometheus.NewDesc(
159+
prometheus.BuildFQName(*metricsNamespace, "upstream", metricName),
160+
docString, labels, nil,
170161
)
171162
}
172163

173-
func newCacheMetric(metricName string, docString string, labels []string) *prometheus.GaugeVec {
174-
return prometheus.NewGaugeVec(
175-
prometheus.GaugeOpts{
176-
Namespace: *metricsNamespace,
177-
Name: "cache_" + metricName,
178-
Help: docString,
179-
},
180-
labels,
164+
func newCacheMetric(metricName string, docString string, labels []string) *prometheus.Desc {
165+
return prometheus.NewDesc(
166+
prometheus.BuildFQName(*metricsNamespace, "cache", metricName),
167+
docString, labels, nil,
181168
)
182169
}
183170

184171
func NewExporter(uri string) *Exporter {
185172

186173
return &Exporter{
187174
URI: uri,
188-
serverMetrics: map[string]*prometheus.GaugeVec{
175+
serverMetrics: map[string]*prometheus.Desc{
189176
"connections": newServerMetric("connections", "nginx connections", []string{"status"}),
190177
"requests": newServerMetric("requests", "requests counter", []string{"host", "code"}),
191178
"bytes": newServerMetric("bytes", "request/response bytes", []string{"host", "direction"}),
192179
"cache": newServerMetric("cache", "cache counter", []string{"host", "status"}),
193180
},
194-
upstreamMetrics: map[string]*prometheus.GaugeVec{
181+
upstreamMetrics: map[string]*prometheus.Desc{
195182
"requests": newUpstreamMetric("requests", "requests counter", []string{"upstream", "code"}),
196183
"bytes": newUpstreamMetric("bytes", "request/response bytes", []string{"upstream", "direction"}),
197184
"response": newUpstreamMetric("response", "request response time", []string{"upstream", "backend"}),
198185
},
199-
cacheMetrics: map[string]*prometheus.GaugeVec{
186+
cacheMetrics: map[string]*prometheus.Desc{
200187
"requests": newCacheMetric("requests", "cache requests counter", []string{"zone", "status"}),
201188
"bytes": newCacheMetric("bytes", "cache request/response bytes", []string{"zone", "direction"}),
202189
},
@@ -205,51 +192,18 @@ func NewExporter(uri string) *Exporter {
205192

206193
func (e *Exporter) Describe(ch chan<- *prometheus.Desc) {
207194
for _, m := range e.serverMetrics {
208-
m.Describe(ch)
195+
ch <- m
209196
}
210197
for _, m := range e.upstreamMetrics {
211-
m.Describe(ch)
198+
ch <- m
212199
}
213200
for _, m := range e.cacheMetrics {
214-
m.Describe(ch)
201+
ch <- m
215202
}
216203
}
217204

218205
func (e *Exporter) Collect(ch chan<- prometheus.Metric) {
219-
e.mutex.Lock()
220-
defer e.mutex.Unlock()
221-
222-
e.resetMetrics()
223-
e.scrape()
224206

225-
e.collectMetrics(ch)
226-
}
227-
228-
func (e *Exporter) resetMetrics() {
229-
for _, m := range e.serverMetrics {
230-
m.Reset()
231-
}
232-
for _, m := range e.upstreamMetrics {
233-
m.Reset()
234-
}
235-
for _, m := range e.cacheMetrics {
236-
m.Reset()
237-
}
238-
}
239-
240-
func (e *Exporter) collectMetrics(metrics chan<- prometheus.Metric) {
241-
for _, m := range e.serverMetrics {
242-
m.Collect(metrics)
243-
}
244-
for _, m := range e.upstreamMetrics {
245-
m.Collect(metrics)
246-
}
247-
for _, m := range e.cacheMetrics {
248-
m.Collect(metrics)
249-
}
250-
}
251-
252-
func (e *Exporter) scrape() {
253207
body, err := fetchHTTP(e.URI, 2*time.Second)()
254208
if err != nil {
255209
log.Println("fetchHTTP failed", err)
@@ -270,63 +224,78 @@ func (e *Exporter) scrape() {
270224
return
271225
}
272226

273-
e.serverMetrics["connections"].WithLabelValues("active").Set(float64(nginxVtx.Connections.Active))
274-
e.serverMetrics["connections"].WithLabelValues("reading").Set(float64(nginxVtx.Connections.Reading))
275-
e.serverMetrics["connections"].WithLabelValues("waiting").Set(float64(nginxVtx.Connections.Waiting))
276-
e.serverMetrics["connections"].WithLabelValues("writing").Set(float64(nginxVtx.Connections.Writing))
277-
e.serverMetrics["connections"].WithLabelValues("accepted").Set(float64(nginxVtx.Connections.Accepted))
278-
e.serverMetrics["connections"].WithLabelValues("handled").Set(float64(nginxVtx.Connections.Handled))
279-
e.serverMetrics["connections"].WithLabelValues("requests").Set(float64(nginxVtx.Connections.Requests))
227+
// connections
228+
ch <- prometheus.MustNewConstMetric(e.serverMetrics["connections"], prometheus.GaugeValue, float64(nginxVtx.Connections.Active), "active")
229+
ch <- prometheus.MustNewConstMetric(e.serverMetrics["connections"], prometheus.GaugeValue, float64(nginxVtx.Connections.Reading), "reading")
230+
ch <- prometheus.MustNewConstMetric(e.serverMetrics["connections"], prometheus.GaugeValue, float64(nginxVtx.Connections.Waiting), "waiting")
231+
ch <- prometheus.MustNewConstMetric(e.serverMetrics["connections"], prometheus.GaugeValue, float64(nginxVtx.Connections.Writing), "writing")
232+
ch <- prometheus.MustNewConstMetric(e.serverMetrics["connections"], prometheus.GaugeValue, float64(nginxVtx.Connections.Accepted), "accepted")
233+
ch <- prometheus.MustNewConstMetric(e.serverMetrics["connections"], prometheus.GaugeValue, float64(nginxVtx.Connections.Handled), "handled")
234+
ch <- prometheus.MustNewConstMetric(e.serverMetrics["connections"], prometheus.GaugeValue, float64(nginxVtx.Connections.Requests), "requests")
280235

236+
// ServerZones
281237
for host, s := range nginxVtx.ServerZones {
282-
e.serverMetrics["requests"].WithLabelValues(host, "total").Set(float64(s.RequestCounter))
283-
e.serverMetrics["requests"].WithLabelValues(host, "1xx").Set(float64(s.Responses.OneXx))
284-
e.serverMetrics["requests"].WithLabelValues(host, "2xx").Set(float64(s.Responses.TwoXx))
285-
e.serverMetrics["requests"].WithLabelValues(host, "3xx").Set(float64(s.Responses.ThreeXx))
286-
e.serverMetrics["requests"].WithLabelValues(host, "4xx").Set(float64(s.Responses.FourXx))
287-
e.serverMetrics["requests"].WithLabelValues(host, "5xx").Set(float64(s.Responses.FiveXx))
288-
289-
e.serverMetrics["cache"].WithLabelValues(host, "bypass").Set(float64(s.Responses.Bypass))
290-
e.serverMetrics["cache"].WithLabelValues(host, "expired").Set(float64(s.Responses.Expired))
291-
e.serverMetrics["cache"].WithLabelValues(host, "hit").Set(float64(s.Responses.Hit))
292-
e.serverMetrics["cache"].WithLabelValues(host, "miss").Set(float64(s.Responses.Miss))
293-
e.serverMetrics["cache"].WithLabelValues(host, "revalidated").Set(float64(s.Responses.Revalidated))
294-
e.serverMetrics["cache"].WithLabelValues(host, "scarce").Set(float64(s.Responses.Scarce))
295-
e.serverMetrics["cache"].WithLabelValues(host, "stale").Set(float64(s.Responses.Stale))
296-
e.serverMetrics["cache"].WithLabelValues(host, "updating").Set(float64(s.Responses.Updating))
297-
298-
e.serverMetrics["bytes"].WithLabelValues(host, "in").Set(float64(s.InBytes))
299-
e.serverMetrics["bytes"].WithLabelValues(host, "out").Set(float64(s.OutBytes))
238+
ch <- prometheus.MustNewConstMetric(e.serverMetrics["requests"], prometheus.CounterValue, float64(s.RequestCounter), host, "total")
239+
ch <- prometheus.MustNewConstMetric(e.serverMetrics["requests"], prometheus.CounterValue, float64(s.Responses.OneXx), host, "1xx")
240+
ch <- prometheus.MustNewConstMetric(e.serverMetrics["requests"], prometheus.CounterValue, float64(s.Responses.TwoXx), host, "2xx")
241+
ch <- prometheus.MustNewConstMetric(e.serverMetrics["requests"], prometheus.CounterValue, float64(s.Responses.ThreeXx), host, "3xx")
242+
ch <- prometheus.MustNewConstMetric(e.serverMetrics["requests"], prometheus.CounterValue, float64(s.Responses.FourXx), host, "4xx")
243+
ch <- prometheus.MustNewConstMetric(e.serverMetrics["requests"], prometheus.CounterValue, float64(s.Responses.FiveXx), host, "5xx")
244+
245+
ch <- prometheus.MustNewConstMetric(e.serverMetrics["cache"], prometheus.CounterValue, float64(s.Responses.Bypass), host, "bypass")
246+
ch <- prometheus.MustNewConstMetric(e.serverMetrics["cache"], prometheus.CounterValue, float64(s.Responses.Expired), host, "expired")
247+
ch <- prometheus.MustNewConstMetric(e.serverMetrics["cache"], prometheus.CounterValue, float64(s.Responses.Hit), host, "hit")
248+
ch <- prometheus.MustNewConstMetric(e.serverMetrics["cache"], prometheus.CounterValue, float64(s.Responses.Miss), host, "miss")
249+
ch <- prometheus.MustNewConstMetric(e.serverMetrics["cache"], prometheus.CounterValue, float64(s.Responses.Revalidated), host, "revalidated")
250+
ch <- prometheus.MustNewConstMetric(e.serverMetrics["cache"], prometheus.CounterValue, float64(s.Responses.Scarce), host, "scarce")
251+
ch <- prometheus.MustNewConstMetric(e.serverMetrics["cache"], prometheus.CounterValue, float64(s.Responses.Stale), host, "stale")
252+
ch <- prometheus.MustNewConstMetric(e.serverMetrics["cache"], prometheus.CounterValue, float64(s.Responses.Updating), host, "updating")
253+
254+
ch <- prometheus.MustNewConstMetric(e.serverMetrics["bytes"], prometheus.CounterValue, float64(s.InBytes), host, "in")
255+
ch <- prometheus.MustNewConstMetric(e.serverMetrics["bytes"], prometheus.CounterValue, float64(s.OutBytes), host, "out")
300256
}
301257

258+
// UpstreamZones
302259
for name, upstreamList := range nginxVtx.UpstreamZones {
260+
var total, one, two, three, four, five, inbytes, outbytes float64
303261
for _, s := range upstreamList {
304-
e.upstreamMetrics["requests"].WithLabelValues(name, "total").Add(float64(s.RequestCounter))
305-
e.upstreamMetrics["requests"].WithLabelValues(name, "1xx").Add(float64(s.Responses.OneXx))
306-
e.upstreamMetrics["requests"].WithLabelValues(name, "2xx").Add(float64(s.Responses.TwoXx))
307-
e.upstreamMetrics["requests"].WithLabelValues(name, "3xx").Add(float64(s.Responses.ThreeXx))
308-
e.upstreamMetrics["requests"].WithLabelValues(name, "4xx").Add(float64(s.Responses.FourXx))
309-
e.upstreamMetrics["requests"].WithLabelValues(name, "5xx").Add(float64(s.Responses.FiveXx))
262+
total += float64(s.RequestCounter)
263+
one += float64(s.Responses.OneXx)
264+
two += float64(s.Responses.TwoXx)
265+
three += float64(s.Responses.ThreeXx)
266+
four += float64(s.Responses.FourXx)
267+
five += float64(s.Responses.FiveXx)
310268

311-
e.upstreamMetrics["bytes"].WithLabelValues(name, "in").Add(float64(s.InBytes))
312-
e.upstreamMetrics["bytes"].WithLabelValues(name, "out").Add(float64(s.OutBytes))
269+
inbytes += float64(s.InBytes)
270+
outbytes += float64(s.OutBytes)
313271

314-
e.upstreamMetrics["response"].WithLabelValues(name, s.Server).Add(float64(s.ResponseMsec))
272+
ch <- prometheus.MustNewConstMetric(e.upstreamMetrics["response"], prometheus.GaugeValue, float64(s.ResponseMsec), name, s.Server)
315273
}
274+
275+
ch <- prometheus.MustNewConstMetric(e.upstreamMetrics["requests"], prometheus.CounterValue, total, name, "total")
276+
ch <- prometheus.MustNewConstMetric(e.upstreamMetrics["requests"], prometheus.CounterValue, one, name, "1xx")
277+
ch <- prometheus.MustNewConstMetric(e.upstreamMetrics["requests"], prometheus.CounterValue, two, name, "2xx")
278+
ch <- prometheus.MustNewConstMetric(e.upstreamMetrics["requests"], prometheus.CounterValue, three, name, "3xx")
279+
ch <- prometheus.MustNewConstMetric(e.upstreamMetrics["requests"], prometheus.CounterValue, four, name, "4xx")
280+
ch <- prometheus.MustNewConstMetric(e.upstreamMetrics["requests"], prometheus.CounterValue, five, name, "5xx")
281+
282+
ch <- prometheus.MustNewConstMetric(e.upstreamMetrics["bytes"], prometheus.CounterValue, inbytes, name, "in")
283+
ch <- prometheus.MustNewConstMetric(e.upstreamMetrics["bytes"], prometheus.CounterValue, outbytes, name, "out")
316284
}
317285

286+
// CacheZones
318287
for zone, s := range nginxVtx.CacheZones {
319-
e.cacheMetrics["requests"].WithLabelValues(zone, "bypass").Set(float64(s.Responses.Bypass))
320-
e.cacheMetrics["requests"].WithLabelValues(zone, "expired").Set(float64(s.Responses.Expired))
321-
e.cacheMetrics["requests"].WithLabelValues(zone, "hit").Set(float64(s.Responses.Hit))
322-
e.cacheMetrics["requests"].WithLabelValues(zone, "miss").Set(float64(s.Responses.Miss))
323-
e.cacheMetrics["requests"].WithLabelValues(zone, "revalidated").Set(float64(s.Responses.Revalidated))
324-
e.cacheMetrics["requests"].WithLabelValues(zone, "scarce").Set(float64(s.Responses.Scarce))
325-
e.cacheMetrics["requests"].WithLabelValues(zone, "stale").Set(float64(s.Responses.Stale))
326-
e.cacheMetrics["requests"].WithLabelValues(zone, "updating").Set(float64(s.Responses.Updating))
327-
328-
e.cacheMetrics["bytes"].WithLabelValues(zone, "in").Set(float64(s.InBytes))
329-
e.cacheMetrics["bytes"].WithLabelValues(zone, "out").Set(float64(s.OutBytes))
288+
ch <- prometheus.MustNewConstMetric(e.cacheMetrics["requests"], prometheus.CounterValue, float64(s.Responses.Bypass), zone, "bypass")
289+
ch <- prometheus.MustNewConstMetric(e.cacheMetrics["requests"], prometheus.CounterValue, float64(s.Responses.Expired), zone, "expired")
290+
ch <- prometheus.MustNewConstMetric(e.cacheMetrics["requests"], prometheus.CounterValue, float64(s.Responses.Hit), zone, "hit")
291+
ch <- prometheus.MustNewConstMetric(e.cacheMetrics["requests"], prometheus.CounterValue, float64(s.Responses.Miss), zone, "miss")
292+
ch <- prometheus.MustNewConstMetric(e.cacheMetrics["requests"], prometheus.CounterValue, float64(s.Responses.Revalidated), zone, "revalidated")
293+
ch <- prometheus.MustNewConstMetric(e.cacheMetrics["requests"], prometheus.CounterValue, float64(s.Responses.Scarce), zone, "scarce")
294+
ch <- prometheus.MustNewConstMetric(e.cacheMetrics["requests"], prometheus.CounterValue, float64(s.Responses.Stale), zone, "stale")
295+
ch <- prometheus.MustNewConstMetric(e.cacheMetrics["requests"], prometheus.CounterValue, float64(s.Responses.Updating), zone, "updating")
296+
297+
ch <- prometheus.MustNewConstMetric(e.cacheMetrics["bytes"], prometheus.CounterValue, float64(s.InBytes), zone, "in")
298+
ch <- prometheus.MustNewConstMetric(e.cacheMetrics["bytes"], prometheus.CounterValue, float64(s.OutBytes), zone, "out")
330299
}
331300
}
332301

@@ -347,16 +316,29 @@ func fetchHTTP(uri string, timeout time.Duration) func() (io.ReadCloser, error)
347316
}
348317

349318
var (
319+
showVersion = flag.Bool("version", false, "Print version information.")
350320
listenAddress = flag.String("telemetry.address", ":9913", "Address on which to expose metrics.")
351321
metricsEndpoint = flag.String("telemetry.endpoint", "/metrics", "Path under which to expose metrics.")
352322
metricsNamespace = flag.String("metrics.namespace", "nginx", "Prometheus metrics namespace.")
353323
nginxScrapeURI = flag.String("nginx.scrape_uri", "http://localhost/status", "URI to nginx stub status page")
354324
insecure = flag.Bool("insecure", true, "Ignore server certificate if using https")
355325
)
356326

327+
func init() {
328+
prometheus.MustRegister(version.NewCollector("nginx_vts_exporter"))
329+
}
330+
357331
func main() {
358332
flag.Parse()
359333

334+
if *showVersion {
335+
fmt.Fprintln(os.Stdout, version.Print("nginx_vts_exporter"))
336+
os.Exit(0)
337+
}
338+
339+
log.Printf("Starting nginx_vts_exporter %s", version.Info())
340+
log.Printf("Build context %s", version.BuildContext())
341+
360342
exporter := NewExporter(*nginxScrapeURI)
361343
prometheus.MustRegister(exporter)
362344
prometheus.Unregister(prometheus.NewProcessCollector(os.Getpid(), ""))

0 commit comments

Comments
 (0)