diff --git a/cmd/loki-canary/main.go b/cmd/loki-canary/main.go index 002ce4322418..4315714c6504 100644 --- a/cmd/loki-canary/main.go +++ b/cmd/loki-canary/main.go @@ -30,6 +30,7 @@ func main() { interval := flag.Duration("interval", 1000*time.Millisecond, "Duration between log entries") size := flag.Int("size", 100, "Size in bytes of each log line") wait := flag.Duration("wait", 60*time.Second, "Duration to wait for log entries before reporting them lost") + buckets := flag.Int("buckets", 10, "Number of buckets in the response_latency histogram") flag.Parse() if *addr == "" { @@ -51,7 +52,7 @@ func main() { _, _ = fmt.Fprintf(os.Stderr, "Connecting to loki at %v, querying for label '%v' with value '%v'\n", u.String(), *lName, *lVal) - c := comparator.NewComparator(os.Stderr, *wait, 1*time.Second) + c := comparator.NewComparator(os.Stderr, *wait, 1*time.Second, *buckets) w := writer.NewWriter(os.Stdout, c, *interval, *size) r := reader.NewReader(os.Stderr, c, u, *user, *pass) diff --git a/pkg/comparator/comparator.go b/pkg/comparator/comparator.go index 79a7568d39f7..2e1c34b30bbc 100644 --- a/pkg/comparator/comparator.go +++ b/pkg/comparator/comparator.go @@ -36,12 +36,7 @@ var ( Name: "unexpected_entries", Help: "counts a log entry received which was not expected (e.g. duplicate, received after reported missing)", }) - responseLatency = promauto.NewHistogram(prometheus.HistogramOpts{ - Namespace: "loki_canary", - Name: "response_latency", - Help: "is how long it takes for log lines to be returned from Loki in seconds.", - Buckets: []float64{1, 5, 10, 30, 60, 90, 120, 300}, - }) + responseLatency prometheus.Histogram ) type Comparator struct { @@ -54,7 +49,7 @@ type Comparator struct { done chan struct{} } -func NewComparator(writer io.Writer, maxWait time.Duration, pruneInterval time.Duration) *Comparator { +func NewComparator(writer io.Writer, maxWait time.Duration, pruneInterval time.Duration, buckets int) *Comparator { c := &Comparator{ w: writer, entries: []*time.Time{}, @@ -64,6 +59,13 @@ func NewComparator(writer io.Writer, maxWait time.Duration, pruneInterval time.D done: make(chan struct{}), } + responseLatency = promauto.NewHistogram(prometheus.HistogramOpts{ + Namespace: "loki_canary", + Name: "response_latency", + Help: "is how long it takes for log lines to be returned from Loki in seconds.", + Buckets: prometheus.ExponentialBuckets(0.5, 2, buckets), + }) + go c.run() return c diff --git a/pkg/comparator/comparator_test.go b/pkg/comparator/comparator_test.go index 6e8cc5faad50..f7d7a24cdd12 100644 --- a/pkg/comparator/comparator_test.go +++ b/pkg/comparator/comparator_test.go @@ -18,7 +18,7 @@ func TestComparatorEntryReceivedOutOfOrder(t *testing.T) { unexpectedEntries = &mockCounter{} actual := &bytes.Buffer{} - c := NewComparator(actual, 1*time.Hour, 1*time.Hour) + c := NewComparator(actual, 1*time.Hour, 1*time.Hour, 1) t1 := time.Now() t2 := t1.Add(1 * time.Second) @@ -44,6 +44,11 @@ func TestComparatorEntryReceivedOutOfOrder(t *testing.T) { assert.Equal(t, 1, outOfOrderEntries.(*mockCounter).count) assert.Equal(t, 0, unexpectedEntries.(*mockCounter).count) assert.Equal(t, 0, missingEntries.(*mockCounter).count) + + // This avoids a panic on subsequent test execution, + // seems ugly but was easy, and multiple instantiations + // of the comparator should be an error + prometheus.Unregister(responseLatency) } func TestComparatorEntryReceivedNotExpected(t *testing.T) { @@ -52,7 +57,7 @@ func TestComparatorEntryReceivedNotExpected(t *testing.T) { unexpectedEntries = &mockCounter{} actual := &bytes.Buffer{} - c := NewComparator(actual, 1*time.Hour, 1*time.Hour) + c := NewComparator(actual, 1*time.Hour, 1*time.Hour, 1) t1 := time.Now() t2 := t1.Add(1 * time.Second) @@ -78,6 +83,11 @@ func TestComparatorEntryReceivedNotExpected(t *testing.T) { assert.Equal(t, 0, outOfOrderEntries.(*mockCounter).count) assert.Equal(t, 1, unexpectedEntries.(*mockCounter).count) assert.Equal(t, 0, missingEntries.(*mockCounter).count) + + // This avoids a panic on subsequent test execution, + // seems ugly but was easy, and multiple instantiations + // of the comparator should be an error + prometheus.Unregister(responseLatency) } func TestEntryNeverReceived(t *testing.T) { @@ -86,7 +96,7 @@ func TestEntryNeverReceived(t *testing.T) { unexpectedEntries = &mockCounter{} actual := &bytes.Buffer{} - c := NewComparator(actual, 5*time.Millisecond, 2*time.Millisecond) + c := NewComparator(actual, 5*time.Millisecond, 2*time.Millisecond, 1) t1 := time.Now() t2 := t1.Add(1 * time.Millisecond) @@ -117,6 +127,11 @@ func TestEntryNeverReceived(t *testing.T) { assert.Equal(t, 0, unexpectedEntries.(*mockCounter).count) assert.Equal(t, 1, missingEntries.(*mockCounter).count) + // This avoids a panic on subsequent test execution, + // seems ugly but was easy, and multiple instantiations + // of the comparator should be an error + prometheus.Unregister(responseLatency) + } type mockCounter struct {