Skip to content

Commit

Permalink
tsplot: Create settable aggregation options. (#12)
Browse files Browse the repository at this point in the history
Expose ability to set all possible alignment and reduction options on
the queries aggregation settings. All Set_* methods are generated using
scripts/codegen.go.
  • Loading branch information
jharshman committed Aug 11, 2021
1 parent d90e5a1 commit 3103d0c
Show file tree
Hide file tree
Showing 8 changed files with 296 additions and 30 deletions.
13 changes: 3 additions & 10 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,6 @@ jobs:
- uses: actions/setup-go@v2
with:
go-version: '^1.16.2'
- run: go test -v ./tsplot/...
tscli:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions/setup-go@v2
with:
go-version: '^1.16.2'
- run: go test -v ./tscli/...

- run: make test
- run: make build
- run: make codegendiff
29 changes: 25 additions & 4 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,15 +1,36 @@
BINDIR ?= ./bin
SCRIPTDIR := ./scripts
SHELL := /bin/bash
GOBIN := $(shell which go 2> /dev/null)
ifeq ($(GOBIN),)
GOBIN := /usr/local/go/bin/go
endif

.PHONY: test
test:
go test -v ./...
$(GOBIN) test -v ./...

.PHONY: build
build:
build: $(BINDIR)/codegen
make -C tscli

$(BINDIR)/codegen: $(SCRIPTDIR)/codegen.go
@mkdir -p $(BINDIR)
GOOS=linux GOARCH=amd64 $(GOBIN) build -o $(BINDIR)/codegen $<

.PHONY: install
install: build
cp ./bin/tscli /usr/local/bin/
cp $(BINDIR)/tscli /usr/local/bin/

.PHONY: clean
clean:
rm -rf ./bin
rm -rf $(BINDIR)

CODEGENFILE="set_aggregation_opts.go"
.PHONY: codegen
codegen:
$(BINDIR)/codegen -output ./tsplot/$(CODEGENFILE)

.PHONY: codegendiff
codegendiff:
diff ./tsplot/$(CODEGENFILE) <($(BINDIR)/codegen -stdout)
67 changes: 67 additions & 0 deletions scripts/codegen.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
package main
/*
codegen.go creates Set_* API methods for Google Cloud Monitoring aggregation alignment and reduction options.
Leverages the exported variables in the Google monitoring/v3 package (common.pb.go) to ensure that all
alignment and reduction options are covered.
*/

import (
"flag"
"log"
"os"
"text/template"

monitoringpb "google.golang.org/genproto/googleapis/monitoring/v3"
)

var rawTpl = `/*
DO NOT EDIT
Generated by codegen.go
https://github.com/googleapis/go-genproto/blob/0135a39c27378c1b903c75204eff61a060be5eb7/googleapis/monitoring/v3/common.pb.go
*/
package tsplot
{{range $name, $value := .Aligners}}
func (mq *MetricQuery) Set_{{$name}}() {
*mq.aggregation = append(*mq.aggregation, withPerSeriesAligner({{$value}}))
}
{{end -}}
{{range $name, $value := .Reducers}}
func (mq *MetricQuery) Set_{{$name}}() {
*mq.aggregation = append(*mq.aggregation, withCrossSeriesReducer({{$value}}))
}
{{end}}
`

func main() {
outFileName := flag.String("output", "./tsplot/set_aggregation_opts.go", "Output path of generated file.")
toStdout := flag.Bool("stdout", false, "Toggle output to STDOUT.")
flag.Parse()

var outFile *os.File
var fileErr error

if *toStdout {
outFile = os.Stdout
} else {
outFile, fileErr = os.OpenFile(*outFileName, os.O_CREATE|os.O_RDWR|os.O_TRUNC, 0644)
if fileErr != nil {
log.Print(fileErr)
}
defer outFile.Close()
}

values := struct {
Aligners map[string]int32
Reducers map[string]int32
}{
Aligners: monitoringpb.Aggregation_Aligner_value,
Reducers: monitoringpb.Aggregation_Reducer_value,
}

t := template.New("codegen")
pt := template.Must(t.Parse(rawTpl))
err := pt.Execute(outFile, values)
if err != nil {
log.Fatal(err)
}
}
7 changes: 6 additions & 1 deletion tscli/Makefile
Original file line number Diff line number Diff line change
@@ -1,8 +1,13 @@
BINDIR ?= ../bin
SHELL := /bin/bash
GOBIN := $(shell which go 2> /dev/null)
ifeq ($(GOBIN),)
GOBIN := /usr/local/go/bin/go
endif

default: build

.PHONY: build
build:
@mkdir -p $(BINDIR)
GOOS=linux GOARCH=amd64 /usr/local/go/bin/go build -o $(BINDIR)/tscli
GOOS=linux GOARCH=amd64 $(GOBIN) build -o $(BINDIR)/tscli
16 changes: 9 additions & 7 deletions tscli/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -114,18 +114,20 @@ func executeQuery(cmd *cobra.Command, args []string) error {
st := parseTime(startTime)
et := parseTime(endTime)

query := tsplot.MetricQuery{
Project: project,
MetricDescriptor: fmt.Sprintf("custom.googleapis.com/opencensus/%s/%s/%s", app, service, metric),
StartTime: &st,
EndTime: &et,
}
query := tsplot.NewMetricQuery(
project,
fmt.Sprintf("custom.googleapis.com/opencensus/%s/%s/%s", app, service, metric),
&st,
&et,
)

if queryOverride != "" {
query.SetQueryFilter(queryOverride)
}

query.SetReduce(reduce)
if !reduce {
query.Set_REDUCE_NONE()
}

tsi, err := query.PerformWithClient(GoogleCloudMonitoringClient)
if err != nil {
Expand Down
31 changes: 30 additions & 1 deletion tsplot/options.go
Original file line number Diff line number Diff line change
@@ -1,9 +1,13 @@
package tsplot

import (
"image/color"
"time"

"gonum.org/v1/plot"
"gonum.org/v1/plot/plotter"
"image/color"
monitoringpb "google.golang.org/genproto/googleapis/monitoring/v3"
"google.golang.org/protobuf/types/known/durationpb"
)

// PlotOption defines the type used to configure the underlying *plot.Plot.
Expand Down Expand Up @@ -91,3 +95,28 @@ func ApplyDefaultHighContrast(p *plot.Plot) {
opt(p)
}
}

// aggregationOption defines the type used to configure the underlying *monitoringpb.Aggregation.
// A function that returns aggregationOption can be used to set options on the *monitoringpb.Aggregation.
type aggregationOption func(agg *monitoringpb.Aggregation)

// withAlignmentPeriod sets the duration of the aggregation's alignment period.
func withAlignmentPeriod(d time.Duration) aggregationOption {
return func(agg *monitoringpb.Aggregation) {
agg.AlignmentPeriod = durationpb.New(d)
}
}

// withPerSeriesAligner sets the alignment method used for the time series.
func withPerSeriesAligner(aligner monitoringpb.Aggregation_Aligner) aggregationOption {
return func(agg *monitoringpb.Aggregation) {
agg.PerSeriesAligner = aligner
}
}

// withCrossSeriesReducer sets the reduction method used for the time series.
func withCrossSeriesReducer(reducer monitoringpb.Aggregation_Reducer) aggregationOption {
return func(agg *monitoringpb.Aggregation) {
agg.CrossSeriesReducer = reducer
}
}
24 changes: 17 additions & 7 deletions tsplot/query.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,18 +29,28 @@ type MetricQuery struct {
EndTime *time.Time

queryFilter string
reduce bool
aggregation *[]aggregationOption
}

// NewMetricQuery creates a new MetricQuery type with the aggregation opts initialized.
func NewMetricQuery(project, metric string, startTime, endTime *time.Time) *MetricQuery {
return &MetricQuery{
Project: project,
MetricDescriptor: metric,
StartTime: startTime,
EndTime: endTime,
aggregation: &[]aggregationOption{},
}
}

// SetQueryFilter provides a hook to modify the metric query filter.
func (mq *MetricQuery) SetQueryFilter(queryFilter string) {
mq.queryFilter = queryFilter
}

// SetReduce sets the boolean reduce value on *MetricQuery structure. This controls whether or not cross series reduction is
// performed on multiple time series.
func (mq *MetricQuery) SetReduce(b bool) {
mq.reduce = b
// SetAlignmentPeriod sets the alignment duration.
func (mq *MetricQuery) SetAlignmentPeriod(d time.Duration) {
*mq.aggregation = append(*mq.aggregation, withAlignmentPeriod(d))
}

// request builds and returns a *monitoringpb.ListTimeSeriesRequest.
Expand Down Expand Up @@ -88,8 +98,8 @@ func (mq *MetricQuery) request() (*monitoringpb.ListTimeSeriesRequest, error) {
View: monitoringpb.ListTimeSeriesRequest_FULL,
}

if !mq.reduce {
tsreq.Aggregation.CrossSeriesReducer = 0
for _, opt := range *mq.aggregation {
opt(tsreq.Aggregation)
}

return &tsreq, nil
Expand Down
139 changes: 139 additions & 0 deletions tsplot/set_aggregation_opts.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,139 @@
/*
DO NOT EDIT
Generated by codegen.go
https://github.com/googleapis/go-genproto/blob/0135a39c27378c1b903c75204eff61a060be5eb7/googleapis/monitoring/v3/common.pb.go
*/
package tsplot

func (mq *MetricQuery) Set_ALIGN_COUNT() {
*mq.aggregation = append(*mq.aggregation, withPerSeriesAligner(13))
}

func (mq *MetricQuery) Set_ALIGN_COUNT_FALSE() {
*mq.aggregation = append(*mq.aggregation, withPerSeriesAligner(24))
}

func (mq *MetricQuery) Set_ALIGN_COUNT_TRUE() {
*mq.aggregation = append(*mq.aggregation, withPerSeriesAligner(16))
}

func (mq *MetricQuery) Set_ALIGN_DELTA() {
*mq.aggregation = append(*mq.aggregation, withPerSeriesAligner(1))
}

func (mq *MetricQuery) Set_ALIGN_FRACTION_TRUE() {
*mq.aggregation = append(*mq.aggregation, withPerSeriesAligner(17))
}

func (mq *MetricQuery) Set_ALIGN_INTERPOLATE() {
*mq.aggregation = append(*mq.aggregation, withPerSeriesAligner(3))
}

func (mq *MetricQuery) Set_ALIGN_MAX() {
*mq.aggregation = append(*mq.aggregation, withPerSeriesAligner(11))
}

func (mq *MetricQuery) Set_ALIGN_MEAN() {
*mq.aggregation = append(*mq.aggregation, withPerSeriesAligner(12))
}

func (mq *MetricQuery) Set_ALIGN_MIN() {
*mq.aggregation = append(*mq.aggregation, withPerSeriesAligner(10))
}

func (mq *MetricQuery) Set_ALIGN_NEXT_OLDER() {
*mq.aggregation = append(*mq.aggregation, withPerSeriesAligner(4))
}

func (mq *MetricQuery) Set_ALIGN_NONE() {
*mq.aggregation = append(*mq.aggregation, withPerSeriesAligner(0))
}

func (mq *MetricQuery) Set_ALIGN_PERCENTILE_05() {
*mq.aggregation = append(*mq.aggregation, withPerSeriesAligner(21))
}

func (mq *MetricQuery) Set_ALIGN_PERCENTILE_50() {
*mq.aggregation = append(*mq.aggregation, withPerSeriesAligner(20))
}

func (mq *MetricQuery) Set_ALIGN_PERCENTILE_95() {
*mq.aggregation = append(*mq.aggregation, withPerSeriesAligner(19))
}

func (mq *MetricQuery) Set_ALIGN_PERCENTILE_99() {
*mq.aggregation = append(*mq.aggregation, withPerSeriesAligner(18))
}

func (mq *MetricQuery) Set_ALIGN_PERCENT_CHANGE() {
*mq.aggregation = append(*mq.aggregation, withPerSeriesAligner(23))
}

func (mq *MetricQuery) Set_ALIGN_RATE() {
*mq.aggregation = append(*mq.aggregation, withPerSeriesAligner(2))
}

func (mq *MetricQuery) Set_ALIGN_STDDEV() {
*mq.aggregation = append(*mq.aggregation, withPerSeriesAligner(15))
}

func (mq *MetricQuery) Set_ALIGN_SUM() {
*mq.aggregation = append(*mq.aggregation, withPerSeriesAligner(14))
}

func (mq *MetricQuery) Set_REDUCE_COUNT() {
*mq.aggregation = append(*mq.aggregation, withCrossSeriesReducer(6))
}

func (mq *MetricQuery) Set_REDUCE_COUNT_FALSE() {
*mq.aggregation = append(*mq.aggregation, withCrossSeriesReducer(15))
}

func (mq *MetricQuery) Set_REDUCE_COUNT_TRUE() {
*mq.aggregation = append(*mq.aggregation, withCrossSeriesReducer(7))
}

func (mq *MetricQuery) Set_REDUCE_FRACTION_TRUE() {
*mq.aggregation = append(*mq.aggregation, withCrossSeriesReducer(8))
}

func (mq *MetricQuery) Set_REDUCE_MAX() {
*mq.aggregation = append(*mq.aggregation, withCrossSeriesReducer(3))
}

func (mq *MetricQuery) Set_REDUCE_MEAN() {
*mq.aggregation = append(*mq.aggregation, withCrossSeriesReducer(1))
}

func (mq *MetricQuery) Set_REDUCE_MIN() {
*mq.aggregation = append(*mq.aggregation, withCrossSeriesReducer(2))
}

func (mq *MetricQuery) Set_REDUCE_NONE() {
*mq.aggregation = append(*mq.aggregation, withCrossSeriesReducer(0))
}

func (mq *MetricQuery) Set_REDUCE_PERCENTILE_05() {
*mq.aggregation = append(*mq.aggregation, withCrossSeriesReducer(12))
}

func (mq *MetricQuery) Set_REDUCE_PERCENTILE_50() {
*mq.aggregation = append(*mq.aggregation, withCrossSeriesReducer(11))
}

func (mq *MetricQuery) Set_REDUCE_PERCENTILE_95() {
*mq.aggregation = append(*mq.aggregation, withCrossSeriesReducer(10))
}

func (mq *MetricQuery) Set_REDUCE_PERCENTILE_99() {
*mq.aggregation = append(*mq.aggregation, withCrossSeriesReducer(9))
}

func (mq *MetricQuery) Set_REDUCE_STDDEV() {
*mq.aggregation = append(*mq.aggregation, withCrossSeriesReducer(5))
}

func (mq *MetricQuery) Set_REDUCE_SUM() {
*mq.aggregation = append(*mq.aggregation, withCrossSeriesReducer(4))
}

0 comments on commit 3103d0c

Please sign in to comment.