Skip to content

Commit

Permalink
Reestructure measurement code
Browse files Browse the repository at this point in the history
Signed-off-by: Raul Sevilla <rsevilla@redhat.com>
  • Loading branch information
rsevilla87 committed Aug 8, 2021
1 parent 81d2b02 commit cb2e3d9
Show file tree
Hide file tree
Showing 9 changed files with 145 additions and 77 deletions.
3 changes: 3 additions & 0 deletions .github/workflows/go.yml
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,9 @@ jobs:
- name: Check out code into the Go module directory
uses: actions/checkout@v2

- name: branch
run: echo ${GITHUB_REF}

- uses: actions/cache@v2
with:
path: ~/go/pkg/mod
Expand Down
16 changes: 3 additions & 13 deletions pkg/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,9 @@ import (
"strings"
"time"

"github.com/cloud-bulldozer/kube-burner/log"
mtypes "github.com/cloud-bulldozer/kube-burner/pkg/measurements/types"
"github.com/cloud-bulldozer/kube-burner/pkg/util"

"gopkg.in/yaml.v3"
"k8s.io/apimachinery/pkg/util/validation"
"k8s.io/client-go/kubernetes"
Expand All @@ -38,7 +39,7 @@ var ConfigSpec Spec = Spec{
MetricsDirectory: "collected-metrics",
RequestTimeout: 15 * time.Second,
WriteToFile: true,
Measurements: []Measurement{},
Measurements: []mtypes.Measurement{},
IndexerConfig: IndexerConfig{
Enabled: false,
InsecureSkipVerify: false,
Expand Down Expand Up @@ -112,17 +113,6 @@ func Parse(c string, jobsRequired bool) error {
if err := validateDNS1123(); err != nil {
return err
}
for _, m := range ConfigSpec.GlobalConfig.Measurements {
switch m.Name {
case string(podLatency):
err = validatePodLatencyCfg(m)
case string(pprof):
err = validatePprofCfg(m)
}
if err != nil {
log.Fatalf("Config validataion error: %s", err)
}
}
}
return nil
}
Expand Down
3 changes: 2 additions & 1 deletion pkg/config/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ package config
import (
"time"

mtypes "github.com/cloud-bulldozer/kube-burner/pkg/measurements/types"
v1 "k8s.io/api/core/v1"
)

Expand Down Expand Up @@ -118,7 +119,7 @@ type GlobalConfig struct {
MetricsDirectory string `yaml:"metricsDirectory"`
// Measurements describes a list of measurements kube-burner
// will take along with job
Measurements []Measurement `yaml:"measurements"`
Measurements []mtypes.Measurement `yaml:"measurements"`
// RequestTimeout of restclient
RequestTimeout time.Duration `yaml:"requestTimeout"`
}
Expand Down
47 changes: 0 additions & 47 deletions pkg/config/validations.go

This file was deleted.

24 changes: 16 additions & 8 deletions pkg/measurements/factory.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,12 @@
package measurements

import (
"fmt"

"github.com/cloud-bulldozer/kube-burner/log"
"github.com/cloud-bulldozer/kube-burner/pkg/config"
"github.com/cloud-bulldozer/kube-burner/pkg/indexers"
"github.com/cloud-bulldozer/kube-burner/pkg/measurements/types"
"k8s.io/client-go/kubernetes"
"k8s.io/client-go/rest"
)
Expand All @@ -34,7 +37,7 @@ type measurementFactory struct {
type measurement interface {
start()
stop() (int, error)
setConfig(config.Measurement)
setConfig(types.Measurement) error
}

var factory measurementFactory
Expand All @@ -54,21 +57,26 @@ func NewMeasurementFactory(restConfig *rest.Config, uuid string, indexer *indexe
}
for _, measurement := range kubeburnerCfg.Measurements {
if measurementFunc, exists := measurementMap[measurement.Name]; exists {
factory.register(measurement, measurementFunc)
if err := factory.register(measurement, measurementFunc); err != nil {
log.Fatal(err.Error())
}
} else {
log.Warnf("Measurement not found: %s", measurement.Name)
}
}
}

func (mf *measurementFactory) register(measure config.Measurement, measurementFunc measurement) {
if _, exists := mf.createFuncs[measure.Name]; exists {
log.Warnf("Measurement already registered: %s", measure.Name)
func (mf *measurementFactory) register(measurement types.Measurement, measurementFunc measurement) error {
if _, exists := mf.createFuncs[measurement.Name]; exists {
log.Warnf("Measurement already registered: %s", measurement.Name)
} else {
measurementFunc.setConfig(measure)
mf.createFuncs[measure.Name] = measurementFunc
log.Infof("Registered measurement: %s", measure.Name)
if err := measurementFunc.setConfig(measurement); err != nil {
return fmt.Errorf("Config validataion error: %s", err)
}
mf.createFuncs[measurement.Name] = measurementFunc
log.Infof("Registered measurement: %s", measurement.Name)
}
return nil
}

func SetJobConfig(jobConfig *config.Job) {
Expand Down
31 changes: 28 additions & 3 deletions pkg/measurements/pod_latency.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ import (
"time"

"github.com/cloud-bulldozer/kube-burner/log"
"github.com/cloud-bulldozer/kube-burner/pkg/config"
"github.com/cloud-bulldozer/kube-burner/pkg/measurements/types"
v1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/client-go/tools/cache"
Expand Down Expand Up @@ -75,7 +75,7 @@ const (
type podLatency struct {
informer cache.SharedInformer
stopChannel chan struct{}
config config.Measurement
config types.Measurement
}

func init() {
Expand Down Expand Up @@ -126,8 +126,12 @@ func (p *podLatency) updatePod(obj interface{}) {
}
}

func (p *podLatency) setConfig(cfg config.Measurement) {
func (p *podLatency) setConfig(cfg types.Measurement) error {
p.config = cfg
if err := p.validateConfig(); err != nil {
return err
}
return nil
}

// Start starts podLatency measurement
Expand Down Expand Up @@ -302,3 +306,24 @@ func (p *podLatency) checkThreshold() int {
}
return rc
}

func (p *podLatency) validateConfig() error {
var metricFound bool
var latencyMetrics []string = []string{"P99", "P95", "P50", "Avg", "Max"}
for _, th := range p.config.LatencyThresholds {
if th.ConditionType == v1.ContainersReady || th.ConditionType == v1.PodInitialized || th.ConditionType == v1.PodReady || th.ConditionType == v1.PodScheduled {
for _, lm := range latencyMetrics {
if th.Metric == lm {
metricFound = true
break
}
}
if !metricFound {
return fmt.Errorf("Unsupported metric %s in podLatency measurement, supported are: %s", th.Metric, strings.Join(latencyMetrics, ", "))
}
} else {
return fmt.Errorf("Unsupported pod condition type in podLatency measurement: %s", th.ConditionType)
}
}
return nil
}
18 changes: 13 additions & 5 deletions pkg/measurements/pprof.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ import (
"time"

"github.com/cloud-bulldozer/kube-burner/log"
"github.com/cloud-bulldozer/kube-burner/pkg/config"
"github.com/cloud-bulldozer/kube-burner/pkg/measurements/types"
corev1 "k8s.io/api/core/v1"
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/client-go/tools/remotecommand"
Expand All @@ -36,20 +36,24 @@ import (

type pprof struct {
directory string
config config.Measurement
config types.Measurement
stopChannel chan bool
}

func init() {
measurementMap["pprof"] = &pprof{}
}

func (p *pprof) setConfig(cfg config.Measurement) {
func (p *pprof) setConfig(cfg types.Measurement) error {
p.directory = "pprof"
if cfg.PProfDirectory != "" {
p.directory = cfg.PProfDirectory
}
p.config = cfg
if err := p.validateConfig(); err != nil {
return err
}
return nil
}

func (p *pprof) start() {
Expand Down Expand Up @@ -79,7 +83,7 @@ func (p *pprof) start() {
}()
}

func getPods(target config.PProftarget) []corev1.Pod {
func getPods(target types.PProftarget) []corev1.Pod {
labelSelector := labels.Set(target.LabelSelector).String()
podList, err := factory.clientSet.CoreV1().Pods(target.Namespace).List(context.TODO(), v1.ListOptions{LabelSelector: labelSelector})
if err != nil {
Expand All @@ -99,7 +103,7 @@ func (p *pprof) getPProf(wg *sync.WaitGroup, copyCerts bool) {
podList := getPods(target)
for _, pod := range podList {
wg.Add(1)
go func(target config.PProftarget, pod corev1.Pod) {
go func(target types.PProftarget, pod corev1.Pod) {
defer wg.Done()
pprofFile := fmt.Sprintf("%s-%s-%d.pprof", target.Name, pod.Name, time.Now().Unix())
f, err := os.Create(path.Join(p.directory, pprofFile))
Expand Down Expand Up @@ -223,3 +227,7 @@ func copyCertsToPod(pod corev1.Pod, cert, privKey io.Reader) error {
log.Infof("Certificate and private key copied into %s %s", pod.Name, pod.Spec.Containers[0].Name)
return nil
}

func (p *pprof) validateConfig() error {
return nil
}
66 changes: 66 additions & 0 deletions pkg/measurements/types/types.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
// Copyright 2021 The Kube-burner Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package types

import (
"time"

v1 "k8s.io/api/core/v1"
)

// Measurement holds the measurement configuration
type Measurement struct {
// Name is the name the measurement
Name string `yaml:"name"`
// ESIndex contains the ElasticSearch index used to
// index the metrics
ESIndex string `yaml:"esIndex"`
// LatencyThresholds config
LatencyThresholds []LatencyThreshold `yaml:"thresholds"`
// PPRofTargets targets config
PProfTargets []PProftarget `yaml:"pprofTargets"`
// PPRofInterval pprof collect interval
PProfInterval time.Duration `yaml:"pprofInterval"`
// PProfDirectory output directory
PProfDirectory string `yaml:"pprofDirectory"`
}

// LatencyThreshold holds the thresholds configuration
type LatencyThreshold struct {
// ConditionType
ConditionType v1.PodConditionType `yaml:"conditionType"`
// Metric type
Metric string `yaml:"metric"`
// Threshold accepted
Threshold time.Duration `yaml:"threshold"`
}

// PProftarget pprof targets to collect
type PProftarget struct {
// Name pprof target name
Name string `yaml:"name"`
// Namespace pod namespace
Namespace string `yaml:"namespace"`
// LabelSelector get pprof from pods with these labels
LabelSelector map[string]string `yaml:"labelSelector"`
// BearerToken bearer token
BearerToken string `yaml:"bearerToken"`
// URL target URL
URL string `yaml:"url"`
// Cert Client certificate file
Cert string `yaml:"cert"`
// Key Private key file
Key string `yaml:"key"`
}
14 changes: 14 additions & 0 deletions pkg/prometheus/types.go
Original file line number Diff line number Diff line change
@@ -1,3 +1,17 @@
// Copyright 2021 The Kube-burner Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package prometheus

import (
Expand Down

0 comments on commit cb2e3d9

Please sign in to comment.