-
Notifications
You must be signed in to change notification settings - Fork 7
/
Copy pathpromrus_test.go
130 lines (107 loc) · 3.98 KB
/
promrus_test.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
package promrus_test
import (
"fmt"
"io/ioutil"
"net/http"
"strconv"
"strings"
"testing"
"github.com/prometheus/client_golang/prometheus/promhttp"
log "github.com/sirupsen/logrus"
"github.com/stretchr/testify/assert"
"github.com/weaveworks/promrus"
)
const (
addr string = ":8080"
endpoint string = "/metrics"
)
func TestRegisteringHookMultipleTimesShouldBeSafe(t *testing.T) {
log.AddHook(promrus.MustNewPrometheusHook())
log.AddHook(promrus.MustNewPrometheusHook()) // Initialising twice in a row should NOT raise any error.
server := httpServePrometheusMetrics(t)
lines := httpGetMetrics(t)
assert.Equal(t, 0, countFor(t, log.InfoLevel, lines))
log.Info("this is at info level!")
lines = httpGetMetrics(t)
assert.Equal(t, 1, countFor(t, log.InfoLevel, lines))
log.AddHook(promrus.MustNewPrometheusHook()) // Initialising again here should NOT raise any error, but will reset counters.
lines = httpGetMetrics(t)
assert.Equal(t, 0, countFor(t, log.InfoLevel, lines))
server.Close()
}
func TestExposeAndQueryLogrusCounters(t *testing.T) {
// Create Prometheus hook and configure logrus to use it:
hook := promrus.MustNewPrometheusHook()
log.AddHook(hook)
log.SetLevel(log.DebugLevel)
server := httpServePrometheusMetrics(t)
lines := httpGetMetrics(t)
assert.Equal(t, 0, countFor(t, log.DebugLevel, lines))
assert.Equal(t, 0, countFor(t, log.InfoLevel, lines))
assert.Equal(t, 0, countFor(t, log.WarnLevel, lines))
assert.Equal(t, 0, countFor(t, log.ErrorLevel, lines))
log.Debug("this is at debug level!")
lines = httpGetMetrics(t)
assert.Equal(t, 1, countFor(t, log.DebugLevel, lines))
assert.Equal(t, 0, countFor(t, log.InfoLevel, lines))
assert.Equal(t, 0, countFor(t, log.WarnLevel, lines))
assert.Equal(t, 0, countFor(t, log.ErrorLevel, lines))
log.Info("this is at info level!")
lines = httpGetMetrics(t)
assert.Equal(t, 1, countFor(t, log.DebugLevel, lines))
assert.Equal(t, 1, countFor(t, log.InfoLevel, lines))
assert.Equal(t, 0, countFor(t, log.WarnLevel, lines))
assert.Equal(t, 0, countFor(t, log.ErrorLevel, lines))
log.Warn("this is at warning level!")
lines = httpGetMetrics(t)
assert.Equal(t, 1, countFor(t, log.DebugLevel, lines))
assert.Equal(t, 1, countFor(t, log.InfoLevel, lines))
assert.Equal(t, 1, countFor(t, log.WarnLevel, lines))
assert.Equal(t, 0, countFor(t, log.ErrorLevel, lines))
log.Error("this is at error level!")
lines = httpGetMetrics(t)
assert.Equal(t, 1, countFor(t, log.DebugLevel, lines))
assert.Equal(t, 1, countFor(t, log.InfoLevel, lines))
assert.Equal(t, 1, countFor(t, log.WarnLevel, lines))
assert.Equal(t, 1, countFor(t, log.ErrorLevel, lines))
server.Close()
}
// httpServePrometheusMetrics exposes the Prometheus metrics over HTTP, in a different go routine.
func httpServePrometheusMetrics(t *testing.T) *http.Server {
server := &http.Server{
Addr: addr,
Handler: promhttp.Handler(),
}
go server.ListenAndServe()
return server
}
// httpGetMetrics queries the local HTTP server for the exposed metrics and parses the response.
func httpGetMetrics(t *testing.T) []string {
resp, err := http.Get(fmt.Sprintf("http://localhost%v%v", addr, endpoint))
assert.Nil(t, err)
body, err := ioutil.ReadAll(resp.Body)
assert.Nil(t, err)
lines := strings.Split(string(body), "\n")
assert.True(t, len(lines) > 0)
return lines
}
// countFor is a helper function to get the counter's value for the provided level.
func countFor(t *testing.T, level log.Level, lines []string) int {
// Metrics are exposed as per the below example:
// # HELP test_debug Number of log statements at debug level.
// # TYPE test_debug counter
// test_debug 0
metric := fmt.Sprintf("log_messages_total{level=\"%v\"}", level)
for _, line := range lines {
items := strings.Split(line, " ")
if len(items) != 2 { // e.g. {"test_debug", "0"}
continue
}
if items[0] == metric {
count, err := strconv.ParseInt(items[1], 10, 32)
assert.Nil(t, err)
return int(count)
}
}
panic(fmt.Sprintf("Could not find %v in %v", metric, lines))
}