Skip to content

Commit eba1751

Browse files
committed
feat: Add step param to Patterns Query API
1 parent 8c18463 commit eba1751

File tree

8 files changed

+186
-85
lines changed

8 files changed

+186
-85
lines changed

pkg/logproto/compat.go

-2
Original file line numberDiff line numberDiff line change
@@ -448,8 +448,6 @@ func (m *ShardsRequest) LogToSpan(sp opentracing.Span) {
448448

449449
func (m *QueryPatternsRequest) GetCachingOptions() (res definitions.CachingOptions) { return }
450450

451-
func (m *QueryPatternsRequest) GetStep() int64 { return 0 }
452-
453451
func (m *QueryPatternsRequest) WithStartEnd(start, end time.Time) definitions.Request {
454452
clone := *m
455453
clone.Start = start

pkg/logproto/pattern.pb.go

+73-32
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

pkg/logproto/pattern.proto

+1
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ message QueryPatternsRequest {
2424
(gogoproto.stdtime) = true,
2525
(gogoproto.nullable) = false
2626
];
27+
int64 step = 4;
2728
}
2829

2930
message QueryPatternsResponse {

pkg/pattern/drain/chunk.go

+31-8
Original file line numberDiff line numberDiff line change
@@ -43,9 +43,9 @@ func (c Chunk) spaceFor(ts model.Time) bool {
4343
}
4444

4545
// ForRange returns samples with only the values
46-
// in the given range [start:end).
47-
// start and end are in milliseconds since epoch.
48-
func (c Chunk) ForRange(start, end model.Time) []logproto.PatternSample {
46+
// in the given range [start:end) and aggregates them by step duration.
47+
// start and end are in milliseconds since epoch. step is a duration in milliseconds.
48+
func (c Chunk) ForRange(start, end, step model.Time) []logproto.PatternSample {
4949
if len(c.Samples) == 0 {
5050
return nil
5151
}
@@ -66,11 +66,34 @@ func (c Chunk) ForRange(start, end model.Time) []logproto.PatternSample {
6666
return c.Samples[i].Timestamp >= end
6767
})
6868
}
69-
return c.Samples[lo:hi]
69+
70+
// Re-scale samples into step-sized buckets
71+
currentStep := truncateTimestamp(c.Samples[lo].Timestamp, step)
72+
outputSamples := []logproto.PatternSample{
73+
{
74+
Timestamp: currentStep,
75+
Value: 0,
76+
},
77+
}
78+
for _, sample := range c.Samples[lo:hi] {
79+
if sample.Timestamp >= currentStep+step {
80+
stepForSample := truncateTimestamp(sample.Timestamp, step)
81+
for i := currentStep + step; i <= stepForSample; i += step {
82+
outputSamples = append(outputSamples, logproto.PatternSample{
83+
Timestamp: i,
84+
Value: 0,
85+
})
86+
}
87+
currentStep = stepForSample
88+
}
89+
outputSamples[len(outputSamples)-1].Value += sample.Value
90+
}
91+
92+
return outputSamples
7093
}
7194

7295
func (c *Chunks) Add(ts model.Time) {
73-
t := truncateTimestamp(ts)
96+
t := truncateTimestamp(ts, timeResolution)
7497

7598
if len(*c) == 0 {
7699
*c = append(*c, newChunk(t))
@@ -91,10 +114,10 @@ func (c *Chunks) Add(ts model.Time) {
91114
})
92115
}
93116

94-
func (c Chunks) Iterator(pattern string, from, through model.Time) iter.Iterator {
117+
func (c Chunks) Iterator(pattern string, from, through, step model.Time) iter.Iterator {
95118
iters := make([]iter.Iterator, 0, len(c))
96119
for _, chunk := range c {
97-
samples := chunk.ForRange(from, through)
120+
samples := chunk.ForRange(from, through, step)
98121
if len(samples) == 0 {
99122
continue
100123
}
@@ -173,4 +196,4 @@ func (c *Chunks) size() int {
173196
return size
174197
}
175198

176-
func truncateTimestamp(ts model.Time) model.Time { return ts - ts%timeResolution }
199+
func truncateTimestamp(ts, step model.Time) model.Time { return ts - ts%step }

0 commit comments

Comments
 (0)