Skip to content

Commit

Permalink
rule/metrics: optimize default metric labels for events and calls
Browse files Browse the repository at this point in the history
  • Loading branch information
James DeFelice committed Jun 14, 2017
1 parent 90fe8a5 commit 48ac237
Show file tree
Hide file tree
Showing 14 changed files with 165 additions and 36 deletions.
4 changes: 2 additions & 2 deletions api/v1/cmd/example-scheduler/app/app.go
Original file line number Diff line number Diff line change
Expand Up @@ -287,7 +287,7 @@ func eventMetrics(metricsAPI *metricsAPI, clock func() time.Time, timingMetrics
timed = nil
}
harness := xmetrics.NewHarness(metricsAPI.eventReceivedCount, metricsAPI.eventErrorCount, timed, clock)
return eventrules.Metrics(harness)
return eventrules.Metrics(harness, nil)
}

// callMetrics logs metrics for every outgoing Mesos call
Expand All @@ -297,7 +297,7 @@ func callMetrics(metricsAPI *metricsAPI, clock func() time.Time, timingMetrics b
timed = nil
}
harness := xmetrics.NewHarness(metricsAPI.callCount, metricsAPI.callErrorCount, timed, clock)
return callrules.Metrics(harness)
return callrules.Metrics(harness, nil)
}

// logCalls logs a specific message string when a particular call-type is observed
Expand Down
2 changes: 1 addition & 1 deletion api/v1/lib/extras/executor/callrules/gen.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,4 @@ package callrules

//go:generate go run ../../gen/rule_callers.go ../../gen/gen.go -import github.com/mesos/mesos-go/api/v1/lib/executor -import github.com/mesos/mesos-go/api/v1/lib/executor/calls -type E:*executor.Call -type C:calls.Caller -type CF:calls.CallerFunc -output callers_generated.go

//go:generate go run ../../gen/rule_metrics.go ../../gen/gen.go -import github.com/mesos/mesos-go/api/v1/lib -import github.com/mesos/mesos-go/api/v1/lib/executor -type E:*executor.Call:&executor.Call{} -type Z:mesos.Response:&mesos.ResponseWrapper{} -output metrics_generated.go
//go:generate go run ../../gen/rule_metrics.go ../../gen/gen.go -import github.com/mesos/mesos-go/api/v1/lib -import github.com/mesos/mesos-go/api/v1/lib/executor -type E:*executor.Call:&executor.Call{} -type ET:executor.Call_Type -type Z:mesos.Response:&mesos.ResponseWrapper{} -output metrics_generated.go
32 changes: 28 additions & 4 deletions api/v1/lib/extras/executor/callrules/metrics_generated.go
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
package callrules

// go generate -import github.com/mesos/mesos-go/api/v1/lib -import github.com/mesos/mesos-go/api/v1/lib/executor -type E:*executor.Call:&executor.Call{} -type Z:mesos.Response:&mesos.ResponseWrapper{} -output metrics_generated.go
// go generate -import github.com/mesos/mesos-go/api/v1/lib -import github.com/mesos/mesos-go/api/v1/lib/executor -type E:*executor.Call:&executor.Call{} -type ET:executor.Call_Type -type Z:mesos.Response:&mesos.ResponseWrapper{} -output metrics_generated.go
// GENERATED CODE FOLLOWS; DO NOT EDIT.

import (
"context"

"strings"

"github.com/mesos/mesos-go/api/v1/lib/extras/metrics"
Expand All @@ -13,13 +14,36 @@ import (
"github.com/mesos/mesos-go/api/v1/lib/executor"
)

func Metrics(harness metrics.Harness) Rule {
// Labeler generates a set of strings that should be associated with metrics that are generated for the given event.
type Labeler func(ctx context.Context, e *executor.Call) []string

var defaultLabels = func() map[executor.Call_Type][]string {
m := make(map[executor.Call_Type][]string)
for k, v := range executor.Call_Type_name {
m[executor.Call_Type(k)] = []string{strings.ToLower(v)}
}
return m
}()

func defaultLabeler(ctx context.Context, e *executor.Call) []string {
return defaultLabels[e.GetType()]
}

// Metrics generates a Rule that invokes the given harness for each event, using the labels generated by the Labeler.
// Panics if harness or labeler is nil.
func Metrics(harness metrics.Harness, labeler Labeler) Rule {
if harness == nil {
panic("harness is a required parameter")
}
if labeler == nil {
labeler = defaultLabeler
}
return func(ctx context.Context, e *executor.Call, z mesos.Response, err error, ch Chain) (context.Context, *executor.Call, mesos.Response, error) {
typename := strings.ToLower(e.GetType().String())
labels := labeler(ctx, e)
harness(func() error {
ctx, e, z, err = ch(ctx, e, z, err)
return err
}, typename)
}, labels...)
return ctx, e, z, err
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package callrules

// go generate -import github.com/mesos/mesos-go/api/v1/lib -import github.com/mesos/mesos-go/api/v1/lib/executor -type E:*executor.Call:&executor.Call{} -type Z:mesos.Response:&mesos.ResponseWrapper{} -output metrics_generated.go
// go generate -import github.com/mesos/mesos-go/api/v1/lib -import github.com/mesos/mesos-go/api/v1/lib/executor -type E:*executor.Call:&executor.Call{} -type ET:executor.Call_Type -type Z:mesos.Response:&mesos.ResponseWrapper{} -output metrics_generated.go
// GENERATED CODE FOLLOWS; DO NOT EDIT.

import (
Expand All @@ -23,7 +23,7 @@ func TestMetrics(t *testing.T) {
i++
return f()
}
r = Metrics(h)
r = Metrics(h, func(_ context.Context, _ *executor.Call) []string { return nil })
)
var zp = &mesos.ResponseWrapper{}
for ti, tc := range []struct {
Expand Down
2 changes: 1 addition & 1 deletion api/v1/lib/extras/executor/eventrules/gen.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,4 @@ package eventrules

//go:generate go run ../../gen/rule_handlers.go ../../gen/gen.go -import github.com/mesos/mesos-go/api/v1/lib/executor -import github.com/mesos/mesos-go/api/v1/lib/executor/events -type E:*executor.Event -type H:events.Handler -type HF:events.HandlerFunc -output handlers_generated.go

//go:generate go run ../../gen/rule_metrics.go ../../gen/gen.go -import github.com/mesos/mesos-go/api/v1/lib/executor -type E:*executor.Event:&executor.Event{} -output metrics_generated.go
//go:generate go run ../../gen/rule_metrics.go ../../gen/gen.go -import github.com/mesos/mesos-go/api/v1/lib/executor -type E:*executor.Event:&executor.Event{} -type ET:executor.Event_Type -output metrics_generated.go
32 changes: 28 additions & 4 deletions api/v1/lib/extras/executor/eventrules/metrics_generated.go
Original file line number Diff line number Diff line change
@@ -1,24 +1,48 @@
package eventrules

// go generate -import github.com/mesos/mesos-go/api/v1/lib/executor -type E:*executor.Event:&executor.Event{} -output metrics_generated.go
// go generate -import github.com/mesos/mesos-go/api/v1/lib/executor -type E:*executor.Event:&executor.Event{} -type ET:executor.Event_Type -output metrics_generated.go
// GENERATED CODE FOLLOWS; DO NOT EDIT.

import (
"context"

"strings"

"github.com/mesos/mesos-go/api/v1/lib/extras/metrics"

"github.com/mesos/mesos-go/api/v1/lib/executor"
)

func Metrics(harness metrics.Harness) Rule {
// Labeler generates a set of strings that should be associated with metrics that are generated for the given event.
type Labeler func(ctx context.Context, e *executor.Event) []string

var defaultLabels = func() map[executor.Event_Type][]string {
m := make(map[executor.Event_Type][]string)
for k, v := range executor.Event_Type_name {
m[executor.Event_Type(k)] = []string{strings.ToLower(v)}
}
return m
}()

func defaultLabeler(ctx context.Context, e *executor.Event) []string {
return defaultLabels[e.GetType()]
}

// Metrics generates a Rule that invokes the given harness for each event, using the labels generated by the Labeler.
// Panics if harness or labeler is nil.
func Metrics(harness metrics.Harness, labeler Labeler) Rule {
if harness == nil {
panic("harness is a required parameter")
}
if labeler == nil {
labeler = defaultLabeler
}
return func(ctx context.Context, e *executor.Event, err error, ch Chain) (context.Context, *executor.Event, error) {
typename := strings.ToLower(e.GetType().String())
labels := labeler(ctx, e)
harness(func() error {
ctx, e, err = ch(ctx, e, err)
return err
}, typename)
}, labels...)
return ctx, e, err
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package eventrules

// go generate -import github.com/mesos/mesos-go/api/v1/lib/executor -type E:*executor.Event:&executor.Event{} -output metrics_generated.go
// go generate -import github.com/mesos/mesos-go/api/v1/lib/executor -type E:*executor.Event:&executor.Event{} -type ET:executor.Event_Type -output metrics_generated.go
// GENERATED CODE FOLLOWS; DO NOT EDIT.

import (
Expand All @@ -22,7 +22,7 @@ func TestMetrics(t *testing.T) {
i++
return f()
}
r = Metrics(h)
r = Metrics(h, func(_ context.Context, _ *executor.Event) []string { return nil })
)
for ti, tc := range []struct {
ctx context.Context
Expand Down
45 changes: 39 additions & 6 deletions api/v1/lib/extras/gen/rule_metrics.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,22 +18,55 @@ var metricsTemplate = template.Must(template.New("").Parse(`package {{.Package}}
import (
"context"
{{if .Type "ET"}}
"strings"
{{end}}
"github.com/mesos/mesos-go/api/v1/lib/extras/metrics"
{{range .Imports}}
{{ printf "%q" . -}}
{{end}}
)
{{.RequireType "E" -}}{{/* type E should have a GetType() func that returns an object w/ a String() func */ -}}
func Metrics(harness metrics.Harness) Rule {
{{.RequireType "E" -}}
// Labeler generates a set of strings that should be associated with metrics that are generated for the given event.
type Labeler func(ctx context.Context, e {{.Type "E"}}) []string
{{if .Type "ET" -}}
var defaultLabels = func() map[{{.Type "ET"}}][]string {
m := make(map[{{.Type "ET"}}][]string)
for k, v := range {{.Type "ET"}}_name {
m[{{.Type "ET"}}(k)] = []string{strings.ToLower(v)}
}
return m
}()
func defaultLabeler(ctx context.Context, e {{.Type "E"}}) []string {
return defaultLabels[e.GetType()]
}
{{end -}}
// Metrics generates a Rule that invokes the given harness for each event, using the labels generated by the Labeler.
// Panics if harness {{if .Type "ET"}}or labeler {{end}}is nil.
func Metrics(harness metrics.Harness, labeler Labeler) Rule {
if harness == nil {
panic("harness is a required parameter")
}
{{if .Type "ET" -}}
if labeler == nil {
labeler = defaultLabeler
}
{{else -}}
if labeler == nil {
panic("labeler is a required parameter")
}
{{end -}}
return func(ctx context.Context, e {{.Type "E"}}, {{.Arg "Z" "z," -}} err error, ch Chain) (context.Context, {{.Type "E"}}, {{.Arg "Z" "," -}} error) {
typename := strings.ToLower(e.GetType().String())
labels := labeler(ctx, e)
harness(func() error {
ctx, e, {{.Ref "Z" "z," -}} err = ch(ctx, e, {{.Ref "Z" "z," -}} err)
return err
}, typename)
}, labels...)
return ctx, e, {{.Ref "Z" "z," -}} err
}
}
Expand Down Expand Up @@ -67,7 +100,7 @@ func TestMetrics(t *testing.T) {
i++
return f()
}
r = Metrics(h)
r = Metrics(h, func(_ context.Context, _ {{.Type "E"}}) []string { return nil })
)
{{if .Type "Z" -}}
var zp = {{.Prototype "Z"}}
Expand Down
2 changes: 1 addition & 1 deletion api/v1/lib/extras/scheduler/callrules/gen.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,4 @@ package callrules

//go:generate go run ../../gen/rule_callers.go ../../gen/gen.go -import github.com/mesos/mesos-go/api/v1/lib/scheduler -import github.com/mesos/mesos-go/api/v1/lib/scheduler/calls -type E:*scheduler.Call -type C:calls.Caller -type CF:calls.CallerFunc -output callers_generated.go

//go:generate go run ../../gen/rule_metrics.go ../../gen/gen.go -import github.com/mesos/mesos-go/api/v1/lib -import github.com/mesos/mesos-go/api/v1/lib/scheduler -type E:*scheduler.Call:&scheduler.Call{} -type Z:mesos.Response:&mesos.ResponseWrapper{} -output metrics_generated.go
//go:generate go run ../../gen/rule_metrics.go ../../gen/gen.go -import github.com/mesos/mesos-go/api/v1/lib -import github.com/mesos/mesos-go/api/v1/lib/scheduler -type E:*scheduler.Call:&scheduler.Call{} -type ET:scheduler.Call_Type -type Z:mesos.Response:&mesos.ResponseWrapper{} -output metrics_generated.go
32 changes: 28 additions & 4 deletions api/v1/lib/extras/scheduler/callrules/metrics_generated.go
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
package callrules

// go generate -import github.com/mesos/mesos-go/api/v1/lib -import github.com/mesos/mesos-go/api/v1/lib/scheduler -type E:*scheduler.Call:&scheduler.Call{} -type Z:mesos.Response:&mesos.ResponseWrapper{} -output metrics_generated.go
// go generate -import github.com/mesos/mesos-go/api/v1/lib -import github.com/mesos/mesos-go/api/v1/lib/scheduler -type E:*scheduler.Call:&scheduler.Call{} -type ET:scheduler.Call_Type -type Z:mesos.Response:&mesos.ResponseWrapper{} -output metrics_generated.go
// GENERATED CODE FOLLOWS; DO NOT EDIT.

import (
"context"

"strings"

"github.com/mesos/mesos-go/api/v1/lib/extras/metrics"
Expand All @@ -13,13 +14,36 @@ import (
"github.com/mesos/mesos-go/api/v1/lib/scheduler"
)

func Metrics(harness metrics.Harness) Rule {
// Labeler generates a set of strings that should be associated with metrics that are generated for the given event.
type Labeler func(ctx context.Context, e *scheduler.Call) []string

var defaultLabels = func() map[scheduler.Call_Type][]string {
m := make(map[scheduler.Call_Type][]string)
for k, v := range scheduler.Call_Type_name {
m[scheduler.Call_Type(k)] = []string{strings.ToLower(v)}
}
return m
}()

func defaultLabeler(ctx context.Context, e *scheduler.Call) []string {
return defaultLabels[e.GetType()]
}

// Metrics generates a Rule that invokes the given harness for each event, using the labels generated by the Labeler.
// Panics if harness or labeler is nil.
func Metrics(harness metrics.Harness, labeler Labeler) Rule {
if harness == nil {
panic("harness is a required parameter")
}
if labeler == nil {
labeler = defaultLabeler
}
return func(ctx context.Context, e *scheduler.Call, z mesos.Response, err error, ch Chain) (context.Context, *scheduler.Call, mesos.Response, error) {
typename := strings.ToLower(e.GetType().String())
labels := labeler(ctx, e)
harness(func() error {
ctx, e, z, err = ch(ctx, e, z, err)
return err
}, typename)
}, labels...)
return ctx, e, z, err
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package callrules

// go generate -import github.com/mesos/mesos-go/api/v1/lib -import github.com/mesos/mesos-go/api/v1/lib/scheduler -type E:*scheduler.Call:&scheduler.Call{} -type Z:mesos.Response:&mesos.ResponseWrapper{} -output metrics_generated.go
// go generate -import github.com/mesos/mesos-go/api/v1/lib -import github.com/mesos/mesos-go/api/v1/lib/scheduler -type E:*scheduler.Call:&scheduler.Call{} -type ET:scheduler.Call_Type -type Z:mesos.Response:&mesos.ResponseWrapper{} -output metrics_generated.go
// GENERATED CODE FOLLOWS; DO NOT EDIT.

import (
Expand All @@ -23,7 +23,7 @@ func TestMetrics(t *testing.T) {
i++
return f()
}
r = Metrics(h)
r = Metrics(h, func(_ context.Context, _ *scheduler.Call) []string { return nil })
)
var zp = &mesos.ResponseWrapper{}
for ti, tc := range []struct {
Expand Down
2 changes: 1 addition & 1 deletion api/v1/lib/extras/scheduler/eventrules/gen.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,4 @@ package eventrules

//go:generate go run ../../gen/rule_handlers.go ../../gen/gen.go -import github.com/mesos/mesos-go/api/v1/lib/scheduler -import github.com/mesos/mesos-go/api/v1/lib/scheduler/events -type E:*scheduler.Event -type H:events.Handler -type HF:events.HandlerFunc -output handlers_generated.go

//go:generate go run ../../gen/rule_metrics.go ../../gen/gen.go -import github.com/mesos/mesos-go/api/v1/lib/scheduler -type E:*scheduler.Event:&scheduler.Event{} -output metrics_generated.go
//go:generate go run ../../gen/rule_metrics.go ../../gen/gen.go -import github.com/mesos/mesos-go/api/v1/lib/scheduler -type E:*scheduler.Event:&scheduler.Event{} -type ET:scheduler.Event_Type -output metrics_generated.go
32 changes: 28 additions & 4 deletions api/v1/lib/extras/scheduler/eventrules/metrics_generated.go
Original file line number Diff line number Diff line change
@@ -1,24 +1,48 @@
package eventrules

// go generate -import github.com/mesos/mesos-go/api/v1/lib/scheduler -type E:*scheduler.Event:&scheduler.Event{} -output metrics_generated.go
// go generate -import github.com/mesos/mesos-go/api/v1/lib/scheduler -type E:*scheduler.Event:&scheduler.Event{} -type ET:scheduler.Event_Type -output metrics_generated.go
// GENERATED CODE FOLLOWS; DO NOT EDIT.

import (
"context"

"strings"

"github.com/mesos/mesos-go/api/v1/lib/extras/metrics"

"github.com/mesos/mesos-go/api/v1/lib/scheduler"
)

func Metrics(harness metrics.Harness) Rule {
// Labeler generates a set of strings that should be associated with metrics that are generated for the given event.
type Labeler func(ctx context.Context, e *scheduler.Event) []string

var defaultLabels = func() map[scheduler.Event_Type][]string {
m := make(map[scheduler.Event_Type][]string)
for k, v := range scheduler.Event_Type_name {
m[scheduler.Event_Type(k)] = []string{strings.ToLower(v)}
}
return m
}()

func defaultLabeler(ctx context.Context, e *scheduler.Event) []string {
return defaultLabels[e.GetType()]
}

// Metrics generates a Rule that invokes the given harness for each event, using the labels generated by the Labeler.
// Panics if harness or labeler is nil.
func Metrics(harness metrics.Harness, labeler Labeler) Rule {
if harness == nil {
panic("harness is a required parameter")
}
if labeler == nil {
labeler = defaultLabeler
}
return func(ctx context.Context, e *scheduler.Event, err error, ch Chain) (context.Context, *scheduler.Event, error) {
typename := strings.ToLower(e.GetType().String())
labels := labeler(ctx, e)
harness(func() error {
ctx, e, err = ch(ctx, e, err)
return err
}, typename)
}, labels...)
return ctx, e, err
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package eventrules

// go generate -import github.com/mesos/mesos-go/api/v1/lib/scheduler -type E:*scheduler.Event:&scheduler.Event{} -output metrics_generated.go
// go generate -import github.com/mesos/mesos-go/api/v1/lib/scheduler -type E:*scheduler.Event:&scheduler.Event{} -type ET:scheduler.Event_Type -output metrics_generated.go
// GENERATED CODE FOLLOWS; DO NOT EDIT.

import (
Expand All @@ -22,7 +22,7 @@ func TestMetrics(t *testing.T) {
i++
return f()
}
r = Metrics(h)
r = Metrics(h, func(_ context.Context, _ *scheduler.Event) []string { return nil })
)
for ti, tc := range []struct {
ctx context.Context
Expand Down

0 comments on commit 48ac237

Please sign in to comment.