diff --git a/pkg/exporter/probe/event.go b/pkg/exporter/probe/event.go index f2020199..a30153f2 100644 --- a/pkg/exporter/probe/event.go +++ b/pkg/exporter/probe/event.go @@ -9,47 +9,39 @@ import ( ) var ( - availableEventProbe = make(map[string]*EventProbeCreator) + availableEventProbe = make(map[string]*eventProbeCreator) ) -// type EventProbeCreator func(sink chan<- *Event, args map[string]interface{}) (EventProbe, error) -type EventProbeCreator struct { +type eventProbeCreator struct { f reflect.Value s *reflect.Type } -func NewEventProbeCreator(creator interface{}) (*EventProbeCreator, error) { +func newEventProbeCreator(creator interface{}) (*eventProbeCreator, error) { t := reflect.TypeOf(creator) - if t.Kind() != reflect.Func { - return nil, fmt.Errorf("metric probe creator %#v is not a func", creator) - } - - err := validateProbeCreatorReturnValue[EventProbe](reflect.TypeOf(creator)) + err := validateProbeCreatorReturnValue[EventProbe](t) if err != nil { return nil, err } if t.NumIn() != 1 && t.NumIn() != 2 { - return nil, fmt.Errorf("input parameter count of creator should be either 2 or 3") + return nil, fmt.Errorf("input parameter count of creator should be either 1 or 2") } ct := t.In(0) et := reflect.TypeOf((*Event)(nil)) if ct.Kind() != reflect.Chan || ct.ChanDir() != reflect.SendDir || ct.Elem() != et { - return nil, fmt.Errorf("first input parameter should be a send channel of *Event") + return nil, fmt.Errorf("first input parameter type should be chan<- *Event") } - ret := &EventProbeCreator{ + ret := &eventProbeCreator{ f: reflect.ValueOf(creator), } if t.NumIn() == 2 { st := t.In(1) - if st.Kind() != reflect.Struct && st.Kind() != reflect.Map { - return nil, fmt.Errorf("input parameter should be struct, but %s", st.Kind()) - } - if st.Kind() == reflect.Map && st.Key().Kind() != reflect.String { - return nil, fmt.Errorf("map key type of input parameter should be string") + if err := validateParamTypeMapOrStruct(st); err != nil { + return nil, err } ret.s = &st } @@ -57,7 +49,7 @@ func NewEventProbeCreator(creator interface{}) (*EventProbeCreator, error) { return ret, nil } -func (e *EventProbeCreator) Call(sink chan<- *Event, args map[string]interface{}) (EventProbe, error) { +func (e *eventProbeCreator) Call(sink chan<- *Event, args map[string]interface{}) (EventProbe, error) { in := []reflect.Value{ reflect.ValueOf(sink), } @@ -70,7 +62,7 @@ func (e *EventProbeCreator) Call(sink chan<- *Event, args map[string]interface{} } result := e.f.Call(in) - // return parameter count and type has been checked in NewEventProbeCreator + // return parameter count and type has been checked in newEventProbeCreator ret := result[0].Interface().(EventProbe) err := result[1].Interface() if err == nil { @@ -118,7 +110,7 @@ func MustRegisterEventProbe(name string, creator interface{}) { panic(fmt.Errorf("duplicated event probe %s", name)) } - c, err := NewEventProbeCreator(creator) + c, err := newEventProbeCreator(creator) if err != nil { panic(fmt.Errorf("error register event probe %s: %s", name, err)) } diff --git a/pkg/exporter/probe/metrics.go b/pkg/exporter/probe/metrics.go index 374a9933..71a39f7a 100644 --- a/pkg/exporter/probe/metrics.go +++ b/pkg/exporter/probe/metrics.go @@ -15,23 +15,18 @@ const LegacyMetricsNamespace = "inspector" const MetricsNamespace = "kubeskoop" var ( - availableMetricsProbes = make(map[string]*MetricsProbeCreator) + availableMetricsProbes = make(map[string]*metricsProbeCreator) ErrUndeclaredMetrics = errors.New("undeclared metrics") ) -// type MetricsProbeCreator func(args map[string]interface{}) (MetricsProbe, error) -type MetricsProbeCreator struct { +type metricsProbeCreator struct { f reflect.Value s *reflect.Type } -func NewMetricProbeCreator(creator interface{}) (*MetricsProbeCreator, error) { +func newMetricProbeCreator(creator interface{}) (*metricsProbeCreator, error) { t := reflect.TypeOf(creator) - if t.Kind() != reflect.Func { - return nil, fmt.Errorf("metric probe creator %#v is not a func", creator) - } - - err := validateProbeCreatorReturnValue[MetricsProbe](reflect.TypeOf(creator)) + err := validateProbeCreatorReturnValue[MetricsProbe](t) if err != nil { return nil, err } @@ -40,17 +35,14 @@ func NewMetricProbeCreator(creator interface{}) (*MetricsProbeCreator, error) { return nil, fmt.Errorf("input parameter count of creator should be either 0 or 1") } - ret := &MetricsProbeCreator{ + ret := &metricsProbeCreator{ f: reflect.ValueOf(creator), } if t.NumIn() == 1 { st := t.In(0) - if st.Kind() != reflect.Struct && st.Kind() != reflect.Map { - return nil, fmt.Errorf("input parameter should be struct, but %s", st.Kind()) - } - if st.Kind() == reflect.Map && st.Key().Kind() != reflect.String { - return nil, fmt.Errorf("map key type of input parameter should be string") + if err := validateParamTypeMapOrStruct(st); err != nil { + return nil, err } ret.s = &st } @@ -58,7 +50,7 @@ func NewMetricProbeCreator(creator interface{}) (*MetricsProbeCreator, error) { return ret, nil } -func (m *MetricsProbeCreator) Call(args map[string]interface{}) (MetricsProbe, error) { +func (m *metricsProbeCreator) Call(args map[string]interface{}) (MetricsProbe, error) { var in []reflect.Value if m.s != nil { s, err := createStructFromTypeWithArgs(*m.s, args) @@ -69,7 +61,7 @@ func (m *MetricsProbeCreator) Call(args map[string]interface{}) (MetricsProbe, e } result := m.f.Call(in) - // return parameter count and type has been checked in NewMetricProbeCreator + // return parameter count and type has been checked in newMetricProbeCreator ret := result[0].Interface().(MetricsProbe) err := result[1].Interface() if err == nil { @@ -116,7 +108,7 @@ func MustRegisterMetricsProbe(name string, creator interface{}) { panic(fmt.Errorf("duplicated metric probe %s", name)) } - c, err := NewMetricProbeCreator(creator) + c, err := newMetricProbeCreator(creator) if err != nil { panic(fmt.Errorf("error register metric probe %s: %s", name, err)) } diff --git a/pkg/exporter/probe/util.go b/pkg/exporter/probe/util.go index 8cc324c2..7fa4587f 100644 --- a/pkg/exporter/probe/util.go +++ b/pkg/exporter/probe/util.go @@ -9,7 +9,7 @@ import ( func validateProbeCreatorReturnValue[T interface{}](t reflect.Type) error { if t.Kind() != reflect.Func { - return fmt.Errorf("%s is not Func type", t) + return fmt.Errorf("creator %#v is not a func", t) } if t.NumOut() != 2 { @@ -28,6 +28,20 @@ func validateProbeCreatorReturnValue[T interface{}](t reflect.Type) error { return nil } +func validateParamTypeMapOrStruct(t reflect.Type) error { + switch t.Kind() { + case reflect.Struct: + // no need to check + case reflect.Map: + if t.Key().Kind() != reflect.String { + return fmt.Errorf("map key type of input parameter should be string") + } + default: + return fmt.Errorf("input parameter type should be struct, but %s", t.Kind()) + } + return nil +} + func createStructFromTypeWithArgs(st reflect.Type, args map[string]interface{}) (reflect.Value, error) { v := reflect.New(st) err := mapstructure.Decode(args, v.Interface())