youtubebeat/vendor/github.com/elastic/beats/libbeat/conditions/range.go

151 lines
3.3 KiB
Go
Raw Normal View History

2018-11-18 11:08:38 +01:00
// Licensed to Elasticsearch B.V. under one or more contributor
// license agreements. See the NOTICE file distributed with
// this work for additional information regarding copyright
// ownership. Elasticsearch B.V. licenses this file to you 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 conditions
import (
"fmt"
"reflect"
"strings"
"github.com/elastic/beats/libbeat/common"
"github.com/elastic/beats/libbeat/logp"
)
type rangeValue struct {
gte *float64
gt *float64
lte *float64
lt *float64
}
// Range is a Condition type for checking against ranges.
type Range map[string]rangeValue
// NewRangeCondition builds a new Range from a map of ranges.
func NewRangeCondition(config map[string]interface{}) (c Range, err error) {
c = Range{}
updateRangeValue := func(key string, op string, value float64) error {
field := strings.TrimSuffix(key, "."+op)
_, exists := c[field]
if !exists {
c[field] = rangeValue{}
}
rv := c[field]
switch op {
case "gte":
rv.gte = &value
case "gt":
rv.gt = &value
case "lt":
rv.lt = &value
case "lte":
rv.lte = &value
default:
return fmt.Errorf("unexpected field %s", op)
}
c[field] = rv
return nil
}
for key, value := range config {
floatValue, err := ExtractFloat(value)
if err != nil {
return c, err
}
list := strings.Split(key, ".")
err = updateRangeValue(key, list[len(list)-1], floatValue)
if err != nil {
return c, err
}
}
return c, nil
}
// Check determines whether the given event matches this condition.
func (c Range) Check(event ValuesMap) bool {
checkValue := func(value float64, rangeValue rangeValue) bool {
if rangeValue.gte != nil {
if value < *rangeValue.gte {
return false
}
}
if rangeValue.gt != nil {
if value <= *rangeValue.gt {
return false
}
}
if rangeValue.lte != nil {
if value > *rangeValue.lte {
return false
}
}
if rangeValue.lt != nil {
if value >= *rangeValue.lt {
return false
}
}
return true
}
for field, rangeValue := range c {
value, err := event.GetValue(field)
if err != nil {
return false
}
switch value.(type) {
case int, int8, int16, int32, int64:
intValue := reflect.ValueOf(value).Int()
if !checkValue(float64(intValue), rangeValue) {
return false
}
case uint, uint8, uint16, uint32, uint64:
uintValue := reflect.ValueOf(value).Uint()
if !checkValue(float64(uintValue), rangeValue) {
return false
}
case float64, float32, common.Float:
floatValue := reflect.ValueOf(value).Float()
if !checkValue(floatValue, rangeValue) {
return false
}
default:
logp.Warn("unexpected type %T in range condition. ", value)
return false
}
}
return true
}
func (c Range) String() string {
return fmt.Sprintf("range: %v", map[string]rangeValue(c))
}