operate.go 2.6 KB
Newer Older
O
ob-robot 已提交
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129
package attr

import (
	"github.com/oceanbase/obagent/monitor/message"

	log "github.com/sirupsen/logrus"
)

type Oper string

const (
	addTagsOper      Oper = "addTags"
	copyTagsOper     Oper = "copyTags"
	renameTagsOper   Oper = "renameTags"
	removeTagsOper   Oper = "removeTags"
	removeFieldsOper Oper = "removeFields"
	removeMetricOper Oper = "removeMetric"
)

type Operation struct {
	Oper        Oper              `yaml:"oper"`
	Condition   Condition         `yaml:"condition"`
	Tags        map[string]string `yaml:"tags"`
	RemoveItems []string          `yaml:"removeItems"`
}

type Condition struct {
	Metric string
	Fields map[string]float64
	Tags   map[string]string
}

func (c *Condition) isMatched(metric *message.Message) bool {
	metricMatched := metric.GetName() == c.Metric || c.Metric == ""
	if !metricMatched {
		return false
	}
	fieldsMatched := true
	for name, value := range c.Fields {
		fieldVal, ex := metric.GetField(name)
		if !ex || fieldVal != value {
			fieldsMatched = false
			break
		}
	}
	if !fieldsMatched {
		return false
	}
	tagsMatched := true
	for name, value := range c.Tags {
		tagVal, ex := metric.GetTag(name)
		if !ex || tagVal != value {
			tagsMatched = false
			break
		}
	}
	if !tagsMatched {
		return false
	}

	return true
}

func switchOper(metric *message.Message, oper Operation) {
	if !oper.Condition.isMatched(metric) {
		return
	}
	switch oper.Oper {
	case addTagsOper:
		addTags(metric, oper.Tags)
		break
	case copyTagsOper:
		copyTags(metric, oper.Tags)
		break
	case renameTagsOper:
		renameTags(metric, oper.Tags)
		break
	case removeTagsOper:
		removeTags(metric, oper.RemoveItems)
		break
	case removeFieldsOper:
		removeFields(metric, oper.RemoveItems)
		break
	case removeMetricOper:
		metric.RemoveAllFields()
		break
	default:
		log.Errorf("oper %s is not supported.", oper.Oper)
	}
}

func addTags(metric *message.Message, tags map[string]string) {
	for k, v := range tags {
		metric.AddTag(k, v)
	}
}

func copyTags(metric *message.Message, tags map[string]string) {
	for oldKey, newKey := range tags {
		val, ex := metric.GetTag(oldKey)
		if !ex {
			continue
		}
		metric.AddTag(newKey, val)
	}
}

func renameTags(metric *message.Message, tags map[string]string) {
	for oldKey, newKey := range tags {
		val, ex := metric.GetTag(oldKey)
		if !ex {
			continue
		}
		metric.AddTag(newKey, val)
		metric.RemoveTag(oldKey)
	}
}

func removeTags(metric *message.Message, tags []string) {
	for _, tag := range tags {
		metric.RemoveTag(tag)
	}
}

func removeFields(metric *message.Message, fields []string) {
	for _, field := range fields {
		metric.RemoveField(field)
	}
}