Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[query] Implemented the Graphite useSeriesAbove function #2587

Merged
merged 64 commits into from
Oct 9, 2020
Merged
Show file tree
Hide file tree
Changes from 63 commits
Commits
Show all changes
64 commits
Select commit Hold shift + click to select a range
4e901d7
Added the moving movingMin function
teddywahle Aug 27, 2020
f42685a
Merge branch 'master' into twahle-moving-min
teddywahle Aug 27, 2020
f0df4ce
worked on moving min
teddywahle Aug 27, 2020
bef6377
Merge branch 'twahle-moving-min' of https://github.com/teddywahle/m3 …
teddywahle Aug 27, 2020
8ce6dc3
more work on the moving min func
teddywahle Aug 27, 2020
30ef946
Merge branch 'master' into twahle-moving-min
teddywahle Aug 28, 2020
cf9288f
updated movingMedian
teddywahle Aug 28, 2020
50b0ae9
Merge branch 'twahle-moving-min' of https://github.com/teddywahle/m3 …
teddywahle Aug 28, 2020
1ebe629
Apply suggestions from code review
teddywahle Aug 28, 2020
ebaafce
testMovingFunction
teddywahle Aug 28, 2020
2a0643c
wrote test movingSum function
teddywahle Aug 28, 2020
53222b9
Merge branch 'master' into twahle-moving-min
teddywahle Aug 31, 2020
bc163dd
added graphite's useSeriesAbove function
teddywahle Sep 3, 2020
cef4ab6
Merge branch 'master' into graphite-useSeriesAbove
teddywahle Sep 3, 2020
e7f6055
Apply suggestions from code review
teddywahle Sep 3, 2020
bd9b8af
Update src/query/graphite/common/percentiles.go
teddywahle Sep 3, 2020
459159e
Update src/query/graphite/native/builtin_functions.go
teddywahle Sep 3, 2020
ff632b1
Update src/query/graphite/native/builtin_functions.go
teddywahle Sep 3, 2020
6673ef5
Update src/query/graphite/native/builtin_functions_test.go
teddywahle Sep 3, 2020
5f8d944
Update src/query/graphite/native/builtin_functions_test.go
teddywahle Sep 3, 2020
a42856b
Merge branch 'master' into graphite-useSeriesAbove
teddywahle Sep 3, 2020
db93037
got useSeriesAbove working
teddywahle Sep 3, 2020
a0d7730
Merge branch 'graphite-useSeriesAbove' of https://github.com/teddywah…
teddywahle Sep 3, 2020
8f5954b
Update src/query/graphite/native/builtin_functions_test.go
teddywahle Sep 3, 2020
52042de
Merge branch 'master' into graphite-useSeriesAbove
teddywahle Sep 3, 2020
f14955f
Got test passing
teddywahle Sep 4, 2020
435c3bc
Merge branch 'graphite-useSeriesAbove' of https://github.com/teddywah…
teddywahle Sep 4, 2020
7bac9ad
Update src/query/graphite/native/builtin_functions.go
teddywahle Sep 4, 2020
e2999ea
Apply suggestions from code review
teddywahle Sep 4, 2020
0467321
Merge branch 'master' into graphite-useSeriesAbove
teddywahle Sep 4, 2020
490dd3e
added registration check
teddywahle Sep 4, 2020
9b020e1
Merge branch 'master' into graphite-useSeriesAbove
teddywahle Sep 7, 2020
8e677ae
Modified useSeriesAbove to handle errors
teddywahle Sep 8, 2020
44a4734
Merge branch 'master' into graphite-useSeriesAbove
teddywahle Sep 8, 2020
2af3e28
Merge branch 'master' into graphite-useSeriesAbove
teddywahle Sep 10, 2020
4f93312
Merge branch 'master' into graphite-useSeriesAbove
teddywahle Sep 21, 2020
13a3792
Update src/query/graphite/native/builtin_functions.go
teddywahle Sep 21, 2020
1094816
updated after PR review
teddywahle Sep 21, 2020
308e1d2
Merge branch 'master' into graphite-useSeriesAbove
teddywahle Sep 21, 2020
7c4af26
Merge branch 'master' into graphite-useSeriesAbove
teddywahle Sep 21, 2020
48e3cdf
Merge branch 'master' into graphite-useSeriesAbove
teddywahle Sep 23, 2020
e99be8b
Merge branch 'master' into graphite-useSeriesAbove
teddywahle Sep 23, 2020
45275a1
Merge branch 'master' into graphite-useSeriesAbove
teddywahle Sep 28, 2020
a8efcb6
Merge branch 'master' into graphite-useSeriesAbove
teddywahle Sep 28, 2020
f203440
updated useSeriesAbove
teddywahle Sep 28, 2020
74d2364
Update src/query/graphite/native/builtin_functions.go
teddywahle Sep 28, 2020
6776450
made the useSeriesAbove tests much more robust
teddywahle Sep 28, 2020
5f283ec
ran go fmt
teddywahle Sep 29, 2020
eb68215
Merge branch 'master' into graphite-useSeriesAbove
teddywahle Sep 29, 2020
cfb852f
Merge branch 'master' into graphite-useSeriesAbove
teddywahle Sep 30, 2020
1a5b683
Update builtin_functions.go
teddywahle Sep 30, 2020
93cbc6b
Update src/query/graphite/native/aggregation_functions_test.go
teddywahle Sep 30, 2020
34b29b5
Update src/query/graphite/native/aggregation_functions_test.go
teddywahle Sep 30, 2020
f61705d
Merge branch 'master' into graphite-useSeriesAbove
teddywahle Sep 30, 2020
3f92a0f
Update engine.go
teddywahle Sep 30, 2020
b8fa221
Merge branch 'master' into graphite-useSeriesAbove
teddywahle Oct 1, 2020
18d79b2
Merge branch 'master' into graphite-useSeriesAbove
teddywahle Oct 5, 2020
50632cf
Update src/query/graphite/common/engine.go
teddywahle Oct 5, 2020
0313b3f
Apply suggestions from code review
teddywahle Oct 5, 2020
a001260
Apply suggestions from code review
teddywahle Oct 5, 2020
9033078
Merge branch 'master' into graphite-useSeriesAbove
arnikola Oct 6, 2020
16e11a7
Merge branch 'master' into graphite-useSeriesAbove
teddywahle Oct 6, 2020
1c4eb9f
Added proper concurrency
teddywahle Oct 6, 2020
a7160f8
Merge branch 'master' into graphite-useSeriesAbove
arnikola Oct 9, 2020
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
64 changes: 64 additions & 0 deletions src/query/graphite/native/builtin_functions.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,15 +26,18 @@ import (
"math"
"math/rand"
"regexp"
"runtime"
"sort"
"strings"
"sync"
"time"

"github.com/m3db/m3/src/query/graphite/common"
"github.com/m3db/m3/src/query/graphite/errors"
"github.com/m3db/m3/src/query/graphite/graphite"
"github.com/m3db/m3/src/query/graphite/ts"
"github.com/m3db/m3/src/query/util"
xerrors "github.com/m3db/m3/src/x/errors"
)

const (
Expand Down Expand Up @@ -94,6 +97,66 @@ func sortByMaxima(ctx *common.Context, series singlePathSpec) (ts.SeriesList, er
return highestMax(ctx, series, len(series.Values))
}

// useSeriesAbove compares the maximum of each series against the given `value`. If the series
// maximum is greater than `value`, the regular expression search and replace is
// applied against the series name to plot a related metric.
//
// e.g. given useSeriesAbove(ganglia.metric1.reqs,10,'reqs','time'),
// the response time metric will be plotted only when the maximum value of the
// corresponding request/s metric is > 10
// Example: useSeriesAbove(ganglia.metric1.reqs,10,"reqs","time")
func useSeriesAbove(ctx *common.Context, seriesList singlePathSpec, maxAllowedValue float64, search, replace string) (ts.SeriesList, error) {
var (
mu sync.Mutex
wg sync.WaitGroup
multiErr xerrors.MultiError
newNames []string

output = make([]*ts.Series, 0, len(seriesList.Values))
maxConcurrency = runtime.NumCPU() / 2
)

for _, series := range seriesList.Values {
if series.SafeMax() > maxAllowedValue {
seriesName := strings.Replace(series.Name(), search, replace, -1)
newNames = append(newNames, seriesName)
}
}

for _, newNameChunk := range chunkArrayHelper(newNames, maxConcurrency) {
if multiErr.LastError() != nil {
return ts.NewSeriesList(), multiErr.LastError()
}

for _, newTarget := range newNameChunk {
wg.Add(1)
go func() {
defer wg.Done()
resultSeriesList, err := evaluateTarget(ctx, newTarget)

if err != nil {
mu.Lock()
multiErr = multiErr.Add(err)
mu.Unlock()
return
}

mu.Lock()
for _, resultSeries := range resultSeriesList.Values {
resultSeries.Specification = newTarget
output = append(output, resultSeries)
}
mu.Unlock()
}()
}
wg.Wait()
}

r := ts.NewSeriesList()
r.Values = output
return r, nil
}

// sortByMinima sorts timeseries by the minimum value across the time period specified.
func sortByMinima(ctx *common.Context, series singlePathSpec) (ts.SeriesList, error) {
return lowest(ctx, series, len(series.Values), "min")
Expand Down Expand Up @@ -2397,6 +2460,7 @@ func init() {
MustRegisterFunction(transformNull).WithDefaultParams(map[uint8]interface{}{
2: 0.0, // defaultValue
})
MustRegisterFunction(useSeriesAbove)
MustRegisterFunction(weightedAverage)
teddywahle marked this conversation as resolved.
Show resolved Hide resolved

// alias functions - in alpha ordering
Expand Down
68 changes: 68 additions & 0 deletions src/query/graphite/native/builtin_functions_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -302,6 +302,73 @@ func TestScale(t *testing.T) {
}
}

func TestUseSeriesAbove(t *testing.T) {
var (
ctrl = xgomock.NewController(t)
store = storage.NewMockStorage(ctrl)
now = time.Now().Truncate(time.Hour)
engine = NewEngine(store)
startTime = now.Add(-3 * time.Minute)
endTime = now.Add(-time.Minute)
ctx = common.NewContext(common.ContextOptions{Start: startTime, End: endTime, Engine: engine})
stepSize = 60000
)

defer ctrl.Finish()
defer ctx.Close()

store.EXPECT().FetchByQuery(gomock.Any(), "foo.bar.q.zed", gomock.Any()).DoAndReturn(
buildTestSeriesFn(stepSize, "foo.bar.q.zed"))
store.EXPECT().FetchByQuery(gomock.Any(), "foo.bar.g.zed", gomock.Any()).DoAndReturn(
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Mind adding a test where nothing is replaced, and another where multiple values are replaced?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

added

buildTestSeriesFn(stepSize, "foo.bar.g.zed"))
store.EXPECT().FetchByQuery(gomock.Any(), "foo.bar.x.zed", gomock.Any()).DoAndReturn(
buildTestSeriesFn(stepSize, "foo.bar.x.zed")).Times(2)
store.EXPECT().FetchByQuery(gomock.Any(), "foo.bar.g.zed.g", gomock.Any()).Return(
&storage.FetchResult{SeriesList: []*ts.Series{ts.NewSeries(ctx, "foo.bar.g.zed.g", startTime,
common.NewTestSeriesValues(ctx, 60000, []float64{10, 20, 30}))}}, nil)
store.EXPECT().FetchByQuery(gomock.Any(), "foo.bar.q.zed.q", gomock.Any()).Return(
&storage.FetchResult{SeriesList: []*ts.Series{ts.NewSeries(ctx, "foo.bar.q.zed.q", startTime,
common.NewTestSeriesValues(ctx, 60000, []float64{1, 2, 3}))}}, nil)

tests := []struct {
target string
expected common.TestSeries
}{
{
"useSeriesAbove(foo.bar.q.zed, -1, 'q', 'g')",
common.TestSeries{
Name: "foo.bar.g.zed",
Data: []float64{1.0, 1.0},
},
},
// two replacements
{
"useSeriesAbove(foo.bar.g.zed.g, 15, 'g', 'q')",
common.TestSeries{
Name: "foo.bar.q.zed.q",
Data: []float64{1.0, 2.0, 3.0},
},
},
// no replacments
{
"useSeriesAbove(foo.bar.x.zed, 1, 'p', 'g')",
common.TestSeries{
Name: "foo.bar.x.zed",
Data: []float64{2.0, 2.0},
},
},
}

for _, test := range tests {
expr, err := engine.Compile(test.target)
require.NoError(t, err)
res, err := expr.Execute(ctx)
require.NoError(t, err)
common.CompareOutputsAndExpected(t, stepSize, startTime,
[]common.TestSeries{test.expected}, res.Values)
}
}

func TestPercentileOfSeriesErrors(t *testing.T) {
ctx := common.NewTestContext()

Expand Down Expand Up @@ -3419,6 +3486,7 @@ func TestFunctionsRegistered(t *testing.T) {
"timeShift",
"timeSlice",
"transformNull",
"useSeriesAbove",
"weightedAverage",
}

Expand Down