diff --git a/message/controller.proto b/message/controller.proto index 18446752475..7746f8c7f77 100644 --- a/message/controller.proto +++ b/message/controller.proto @@ -214,6 +214,11 @@ message PrometheusMetricLabelRequest { repeated PrometheusLabelRequest labels = 2; } +message PrometheusMetricLabel { + optional uint32 metric_name_id = 1; + repeated uint32 label_ids = 2; +} + message PrometheusMetricAPPLabelLayout { required string metric_name = 1; required string app_label_name = 2; @@ -282,6 +287,7 @@ message SyncPrometheusResponse { repeated PrometheusLabel labels = 6; repeated PrometheusMetricTarget metric_targets = 7; repeated PrometheusTarget targets = 8; + repeated PrometheusMetricLabel metric_labels = 9; } service PrometheusDebug { diff --git a/server/controller/prometheus/cache/cache.go b/server/controller/prometheus/cache/cache.go index d8dd5226668..4810369a38b 100644 --- a/server/controller/prometheus/cache/cache.go +++ b/server/controller/prometheus/cache/cache.go @@ -67,7 +67,7 @@ func GetSingleton() *Cache { MetricAndAPPLabelLayout: new(metricAndAPPLabelLayout), Target: t, Label: l, - MetricLabel: newMetricLabel(l), + MetricLabel: newMetricLabel(mn, l), MetricTarget: newMetricTarget(mn, t), } }) @@ -223,9 +223,9 @@ func GetDebugCache(t controller.PrometheusCacheType) []byte { temp["id_to_key"].(map[int]string)[key.(int)] = marshal(value) return true }) - for item := range tempCache.Label.keys.Iterator().C { - temp["keys"].(map[string]interface{})[marshal(item)] = struct{}{} - } + // for item := range tempCache.Label.keys.Iterator().C { // TODO + // temp["keys"].(map[string]interface{})[marshal(item)] = struct{}{} + // } if len(temp["keys"].(map[string]interface{})) > 0 || len(temp["id_to_key"].(map[int]string)) > 0 { content["label"] = temp @@ -240,19 +240,19 @@ func GetDebugCache(t controller.PrometheusCacheType) []byte { "metric_name_to_label_ids": make(map[string][]int), "metric_label_detail_keys": make(map[string]interface{}), } - for item := range tempCache.MetricLabel.labelCache.keys.Iterator().C { - temp["label_cache"].(map[string]interface{})["keys"].(map[string]interface{})[marshal(item)] = struct{}{} - } + // for item := range tempCache.MetricLabel.labelCache.keys.Iterator().C { // TODO + // temp["label_cache"].(map[string]interface{})["keys"].(map[string]interface{})[marshal(item)] = struct{}{} + // } tempCache.MetricLabel.labelCache.idToKey.Range(func(key, value any) bool { temp["label_cache"].(map[string]interface{})["id_to_key"].(map[int]string)[key.(int)] = marshal(value) return true }) - for k, v := range tempCache.MetricLabel.metricNameToLabelIDs { - temp["metric_name_to_label_ids"].(map[string][]int)[k] = v - } - for item := range tempCache.MetricLabel.metricLabelDetailKeys.Iterator().C { - temp["metric_label_detail_keys"].(map[string]interface{})[marshal(item)] = struct{}{} - } + // for k, v := range tempCache.MetricLabel.metricNameToLabelIDs { // TODO + // temp["metric_name_to_label_ids"].(map[string][]int)[k] = v + // } + // for item := range tempCache.MetricLabel.metricLabelDetailKeys.Iterator().C { // TODO + // temp["metric_label_detail_keys"].(map[string]interface{})[marshal(item)] = struct{}{} + // } if len(temp["label_cache"].(map[string]interface{})["keys"].(map[string]interface{})) > 0 || len(temp["label_cache"].(map[string]interface{})["id_to_key"].(map[int]string)) > 0 || len(temp["metric_name_to_label_ids"].(map[string][]int)) > 0 || diff --git a/server/controller/prometheus/cache/label.go b/server/controller/prometheus/cache/label.go index fd846401acc..c86ffb382ef 100644 --- a/server/controller/prometheus/cache/label.go +++ b/server/controller/prometheus/cache/label.go @@ -19,8 +19,6 @@ package cache import ( "sync" - mapset "github.com/deckarep/golang-set/v2" - "github.com/deepflowio/deepflow/message/controller" "github.com/deepflowio/deepflow/server/controller/db/mysql" ) @@ -38,18 +36,26 @@ func NewLabelKey(name, value string) LabelKey { } type label struct { - keys mapset.Set[LabelKey] + // keys mapset.Set[LabelKey] idToKey sync.Map + keyToID sync.Map } func newLabel() *label { return &label{ - keys: mapset.NewSet[LabelKey](), + // keys: mapset.NewSet[LabelKey](), } } -func (l *label) IfKeyExists(key LabelKey) bool { - return l.keys.Contains(key) +// func (l *label) IfKeyExists(key LabelKey) bool { +// return l.keys.Contains(key) +// } + +func (l *label) GetIDByKey(key LabelKey) (int, bool) { + if item, ok := l.keyToID.Load(key); ok { + return item.(int), true + } + return 0, false } func (l *label) GetKeyByID(id int) (LabelKey, bool) { @@ -61,8 +67,10 @@ func (l *label) GetKeyByID(id int) (LabelKey, bool) { func (l *label) Add(batch []*controller.PrometheusLabel) { for _, item := range batch { - l.keys.Add(NewLabelKey(item.GetName(), item.GetValue())) - l.idToKey.Store(int(item.GetId()), NewLabelKey(item.GetName(), item.GetValue())) + k := NewLabelKey(item.GetName(), item.GetValue()) + l.keyToID.Store(k, item.GetId()) + l.idToKey.Store(int(item.GetId()), k) + // l.keys.Add(NewLabelKey(item.GetName(), item.GetValue())) } } @@ -72,8 +80,10 @@ func (l *label) refresh(args ...interface{}) error { return err } for _, item := range ls { - l.keys.Add(NewLabelKey(item.Name, item.Value)) - l.idToKey.Store(item.ID, NewLabelKey(item.Name, item.Value)) + // l.keys.Add(NewLabelKey(item.Name, item.Value)) + k := NewLabelKey(item.Name, item.Value) + l.keyToID.Store(k, item.ID) + l.idToKey.Store(item.ID, k) } return nil } diff --git a/server/controller/prometheus/cache/metric_label.go b/server/controller/prometheus/cache/metric_label.go index 37a2400aca3..72e4cd0883f 100644 --- a/server/controller/prometheus/cache/metric_label.go +++ b/server/controller/prometheus/cache/metric_label.go @@ -17,85 +17,126 @@ package cache import ( + "github.com/cornelk/hashmap" mapset "github.com/deckarep/golang-set/v2" + "github.com/deepflowio/deepflow/message/controller" "github.com/deepflowio/deepflow/server/controller/db/mysql" ) -type MetricLabelDetailKey struct { - MetricName string - LabelName string - LabelValue string -} +// type MetricLabelKey struct { +// MetricNameID int +// LabelID int +// } -func NewMetricLabelDetailKey(metricName, labelName, labelValue string) MetricLabelDetailKey { - return MetricLabelDetailKey{ - MetricName: metricName, - LabelName: labelName, - LabelValue: labelValue, - } -} +// func NewMetricLabelKey(metricNameID, labelID int) MetricLabelKey { +// return MetricLabelKey{ +// MetricNameID: metricNameID, +// LabelID: labelID, +// } +// } + +// type MetricLabelDetailKey struct { +// MetricName string +// LabelName string +// LabelValue string +// } + +// func NewMetricLabelDetailKey(metricName, labelName, labelValue string) MetricLabelDetailKey { +// return MetricLabelDetailKey{ +// MetricName: metricName, +// LabelName: labelName, +// LabelValue: labelValue, +// } +// } type metricLabel struct { - labelCache *label - metricLabelDetailKeys mapset.Set[MetricLabelDetailKey] // for metric_label check - metricNameToLabelIDs map[string][]int // only for fully assembled + metricNameCache *metricName + labelCache *label + // metricLabelDetailKeys mapset.Set[MetricLabelDetailKey] // for metric_label check + // metricLabelKeys mapset.Set[MetricLabelKey] // for metric_label check + // metricNameToLabelIDs map[string][]int // only for fully assembled + metricNameIDToLabelIDs *hashmap.Map[int, mapset.Set[int]] } -func newMetricLabel(l *label) *metricLabel { +func newMetricLabel(mn *metricName, l *label) *metricLabel { return &metricLabel{ - labelCache: l, - metricLabelDetailKeys: mapset.NewSet[MetricLabelDetailKey](), - metricNameToLabelIDs: make(map[string][]int), + metricNameCache: mn, + labelCache: l, + // metricLabelDetailKeys: mapset.NewSet[MetricLabelDetailKey](), + // metricLabelKeys: mapset.NewSet[MetricLabelKey](), + // metricNameToLabelIDs: make(map[string][]int), + metricNameIDToLabelIDs: hashmap.New[int, mapset.Set[int]](), } } -func (ml *metricLabel) IfKeyExists(k MetricLabelDetailKey) bool { - return ml.metricLabelDetailKeys.Contains(k) +// func (ml *metricLabel) IfKeyExists(k MetricLabelDetailKey) bool { +// return ml.metricLabelDetailKeys.Contains(k) +// } + +func (ml *metricLabel) IfLinked(metricID, labelID int) bool { + if labelIDs, ok := ml.metricNameIDToLabelIDs.Get(metricID); ok { + return labelIDs.(mapset.Set[int]).Contains(labelID) + } + return false } -func (ml *metricLabel) GetLabelsByMetricName(metricName string) []LabelKey { - var ret []LabelKey - if labelIDs, ok := ml.metricNameToLabelIDs[metricName]; ok { - for _, labelID := range labelIDs { - if labelKey, ok := ml.labelCache.GetKeyByID(labelID); ok { - ret = append(ret, labelKey) - } - } +func (ml *metricLabel) GetLabelsByMetricName(metricName string) []int { + mni, ok := ml.metricNameCache.GetIDByName(metricName) + if !ok { + return nil } - return ret + labelIDs, ok := ml.metricNameIDToLabelIDs.Get(mni) + return labelIDs.ToSlice() +} + +func (mi *metricLabel) GetMetricNameIDToLabelIDs() *hashmap.Map[int, mapset.Set[int]] { + return mi.metricNameIDToLabelIDs } -func (ml *metricLabel) Add(batch []MetricLabelDetailKey) { +func (ml *metricLabel) Add(batch []*controller.PrometheusMetricLabel) { for _, item := range batch { - ml.metricLabelDetailKeys.Add(item) + for _, li := range item.GetLabelIds() { + // ml.metricLabelKeys.Add(NewMetricLabelKey(int(item.GetMetricNameId()), int(li))) + ml.metricNameIDToLabelIDs.GetOrInsert(int(item.GetMetricNameId()), mapset.NewSet(int(li))) + } } } -func (ml *metricLabel) GetMetricLabelDetailKeys() mapset.Set[MetricLabelDetailKey] { - return ml.metricLabelDetailKeys -} +// func (ml *metricLabel) Add(batch []MetricLabelDetailKey) { +// for _, item := range batch { +// ml.metricLabelDetailKeys.Add(item) +// } +// } + +// func (ml *metricLabel) GetMetricLabelDetailKeys() mapset.Set[MetricLabelDetailKey] { +// return ml.metricLabelDetailKeys +// } func (ml *metricLabel) refresh(args ...interface{}) error { metricLabels, err := ml.load() if err != nil { return err } - metricNameToLabelIDs := make(map[string][]int) + // metricNameToLabelIDs := make(map[string][]int) for _, item := range metricLabels { - if lk, ok := ml.labelCache.GetKeyByID(item.LabelID); ok { - ml.metricLabelDetailKeys.Add(NewMetricLabelDetailKey(item.MetricName, lk.Name, lk.Value)) - } - if _, ok := ml.labelCache.GetKeyByID(item.LabelID); ok { - metricNameToLabelIDs[item.MetricName] = append(metricNameToLabelIDs[item.MetricName], item.LabelID) + // if lk, ok := ml.labelCache.GetKeyByID(item.LabelID); ok { + // ml.metricLabelDetailKeys.Add(NewMetricLabelDetailKey(item.MetricName, lk.Name, lk.Value)) + // } + if mni, ok := ml.metricNameCache.GetIDByName(item.MetricName); ok { + // ml.metricLabelKeys.Add(NewMetricLabelKey(mni, item.LabelID)) + ml.metricNameIDToLabelIDs.GetOrInsert(mni, mapset.NewSet(item.LabelID)) } + // if _, ok := ml.labelCache.GetKeyByID(item.LabelID); ok { + // metricNameToLabelIDs[item.MetricName] = append(metricNameToLabelIDs[item.MetricName], item.LabelID) + // } } - ml.metricNameToLabelIDs = metricNameToLabelIDs + // ml.metricNameToLabelIDs = metricNameToLabelIDs return nil } func (ml *metricLabel) load() ([]*mysql.PrometheusMetricLabel, error) { var metricLabels []*mysql.PrometheusMetricLabel - err := mysql.Db.Find(&metricLabels).Error + err := mysql.Db.Select("metric_name", "label_id").Find(&metricLabels).Error return metricLabels, err } diff --git a/server/controller/prometheus/cache/metric_name.go b/server/controller/prometheus/cache/metric_name.go index c7239d5e4e1..6f0e883983f 100644 --- a/server/controller/prometheus/cache/metric_name.go +++ b/server/controller/prometheus/cache/metric_name.go @@ -25,6 +25,7 @@ import ( type metricName struct { nameToID sync.Map + idToName sync.Map } func (mn *metricName) Get() *sync.Map { @@ -38,9 +39,17 @@ func (mn *metricName) GetIDByName(n string) (int, bool) { return 0, false } +func (mn *metricName) GetNameByID(id int) (string, bool) { + if name, ok := mn.idToName.Load(id); ok { + return name.(string), true + } + return "", false +} + func (mn *metricName) Add(batch []*controller.PrometheusMetricName) { for _, item := range batch { mn.nameToID.Store(item.GetName(), int(item.GetId())) + mn.idToName.Store(int(item.GetId()), item.GetName()) } } @@ -51,6 +60,7 @@ func (mn *metricName) refresh(args ...interface{}) error { } for _, item := range metricNames { mn.nameToID.Store(item.Name, item.ID) + mn.idToName.Store(item.ID, item.Name) } return nil } diff --git a/server/controller/prometheus/encoder/encoder.go b/server/controller/prometheus/encoder/encoder.go index 71af88163bb..1091d55e7a8 100644 --- a/server/controller/prometheus/encoder/encoder.go +++ b/server/controller/prometheus/encoder/encoder.go @@ -71,7 +71,7 @@ func (e *Encoder) Init(ctx context.Context, cfg *prometheuscfg.Config) { e.labelValue = newLabelValue(cfg.ResourceMaxID1) e.label = newLabel() e.LabelLayout = newLabelLayout(cfg) - e.metricLabel = newMetricLabel(e.label) + e.metricLabel = newMetricLabel(e.metricName, e.label) e.target = newTarget(cfg.ResourceMaxID1) e.metricTarget = newMetricTarget(e.target) e.refreshInterval = time.Duration(cfg.EncoderCacheRefreshInterval) * time.Second @@ -205,11 +205,13 @@ func (e *Encoder) encodeLabel(args ...interface{}) error { } func (e *Encoder) encodeMetricLabel(args ...interface{}) error { - mls := args[0].([]*controller.PrometheusMetricLabelRequest) - err := e.metricLabel.encode(mls) + resp := args[0].(*controller.SyncPrometheusResponse) + metricLabels := args[1].([]*controller.PrometheusMetricLabelRequest) + mls, err := e.metricLabel.encode(metricLabels) if err != nil { return err } + resp.MetricLabels = mls return nil } diff --git a/server/controller/prometheus/encoder/metric_label.go b/server/controller/prometheus/encoder/metric_label.go index 898e7ff2ebc..496ec17741f 100644 --- a/server/controller/prometheus/encoder/metric_label.go +++ b/server/controller/prometheus/encoder/metric_label.go @@ -20,30 +20,52 @@ import ( "sync" mapset "github.com/deckarep/golang-set/v2" + "github.com/golang/protobuf/proto" "github.com/deepflowio/deepflow/message/controller" "github.com/deepflowio/deepflow/server/controller/db/mysql" "github.com/deepflowio/deepflow/server/controller/prometheus/cache" ) +type metricLabelKey struct { + MetricNameID int + LabelID int +} + +func newMetricLabelKey(metricNameID, labelID int) metricLabelKey { + return metricLabelKey{ + MetricNameID: metricNameID, + LabelID: labelID, + } +} + type metricLabel struct { - lock sync.Mutex - resourceType string - labelEncoder *label - metricLabelDetailKeys mapset.Set[cache.MetricLabelDetailKey] + lock sync.Mutex + resourceType string + + metricNameEncoder *metricName + labelEncoder *label + + // metricLabelDetailKeys mapset.Set[cache.MetricLabelDetailKey] + metricLabelKeys mapset.Set[metricLabelKey] } -func newMetricLabel(l *label) *metricLabel { +func newMetricLabel(mn *metricName, l *label) *metricLabel { return &metricLabel{ - resourceType: "metric_label", - labelEncoder: l, - metricLabelDetailKeys: mapset.NewSet[cache.MetricLabelDetailKey](), + resourceType: "metric_label", + metricNameEncoder: mn, + labelEncoder: l, + // metricLabelDetailKeys: mapset.NewSet[cache.MetricLabelDetailKey](), + metricLabelKeys: mapset.NewSet[metricLabelKey](), } } func (ml *metricLabel) store(item *mysql.PrometheusMetricLabel) { - if labelKey, ok := ml.labelEncoder.getKey(item.LabelID); ok { - ml.metricLabelDetailKeys.Add(cache.NewMetricLabelDetailKey(item.MetricName, labelKey.Name, labelKey.Value)) + // if labelKey, ok := ml.labelEncoder.getKey(item.LabelID); ok { + // ml.metricLabelDetailKeys.Add(cache.NewMetricLabelDetailKey(item.MetricName, labelKey.Name, labelKey.Value)) + // } + if mni, ok := ml.metricNameEncoder.getID(item.MetricName); ok { + ml.metricLabelKeys.Add(newMetricLabelKey(mni, item.LabelID)) } } @@ -59,36 +81,60 @@ func (ml *metricLabel) refresh(args ...interface{}) error { return nil } -func (ml *metricLabel) encode(rMLs []*controller.PrometheusMetricLabelRequest) error { +func (ml *metricLabel) encode(rMLs []*controller.PrometheusMetricLabelRequest) ([]*controller.PrometheusMetricLabel, error) { ml.lock.Lock() defer ml.lock.Unlock() + resp := make([]*controller.PrometheusMetricLabel, 0) var dbToAdd []*mysql.PrometheusMetricLabel + respToAdd := make([]*controller.PrometheusMetricLabel, 0) for _, rML := range rMLs { mn := rML.GetMetricName() + mni, ok := ml.metricNameEncoder.getID(mn) + if !ok { + log.Warningf("%s metric_name: %s id not found", ml.resourceType, mn) + continue + } + lis := make([]uint32, 0) + lisToAdd := make([]uint32, 0) for _, l := range rML.GetLabels() { ln := l.GetName() lv := l.GetValue() - if ok := ml.metricLabelDetailKeys.Contains(cache.NewMetricLabelDetailKey(mn, ln, lv)); ok { + li, ok := ml.labelEncoder.getID(cache.NewLabelKey(ln, lv)) + if !ok { + log.Warningf("%s label (name: %s, value: %s) id not found", ml.resourceType, ln, lv) continue } - if li, ok := ml.labelEncoder.getID(cache.NewLabelKey(ln, lv)); ok { - dbToAdd = append(dbToAdd, &mysql.PrometheusMetricLabel{ - MetricName: mn, - LabelID: li, - }) + if ok := ml.metricLabelKeys.Contains(newMetricLabelKey(mni, li)); ok { + lis = append(lis, uint32(li)) continue } - log.Warningf("%s label_id (name: %s, value: %s) not found", ml.resourceType, ln, lv) + dbToAdd = append(dbToAdd, &mysql.PrometheusMetricLabel{ + MetricName: mn, + LabelID: li, + }) + lisToAdd = append(lisToAdd, uint32(li)) + } + if len(lis) != 0 { + resp = append(resp, &controller.PrometheusMetricLabel{ + MetricNameId: proto.Uint32(uint32(mni)), + LabelIds: lis, + }) + } + if len(lisToAdd) != 0 { + respToAdd = append(respToAdd, &controller.PrometheusMetricLabel{ + MetricNameId: proto.Uint32(uint32(mni)), + LabelIds: lisToAdd, + }) } } err := addBatch(dbToAdd, ml.resourceType) if err != nil { log.Errorf("add %s error: %s", ml.resourceType, err.Error()) - return err + return resp, err } for _, item := range dbToAdd { ml.store(item) } - return nil + return append(resp, respToAdd...), nil } diff --git a/server/controller/prometheus/encoder/metric_name.go b/server/controller/prometheus/encoder/metric_name.go index 121c6446279..12fa376bfec 100644 --- a/server/controller/prometheus/encoder/metric_name.go +++ b/server/controller/prometheus/encoder/metric_name.go @@ -19,6 +19,7 @@ package encoder import ( "sync" + "github.com/cornelk/hashmap" mapset "github.com/deckarep/golang-set/v2" "github.com/golang/protobuf/proto" @@ -30,20 +31,24 @@ import ( type metricName struct { lock sync.Mutex resourceType string - strToID map[string]int + strToID *hashmap.Map[string, int] ascIDAllocator } func newMetricName(max int) *metricName { mn := &metricName{ resourceType: "metric_name", - strToID: make(map[string]int), + strToID: hashmap.New[string, int](), } mn.ascIDAllocator = newAscIDAllocator(mn.resourceType, 1, max) mn.rawDataProvider = mn return mn } +func (mn *metricName) getID(str string) (int, bool) { + return mn.strToID.Get(str) +} + func (mn *metricName) refresh(args ...interface{}) error { mn.lock.Lock() defer mn.lock.Unlock() @@ -59,7 +64,7 @@ func (mn *metricName) encode(strs []string) ([]*controller.PrometheusMetricName, dbToAdd := make([]*mysql.PrometheusMetricName, 0) for i := range strs { str := strs[i] - if id, ok := mn.strToID[str]; ok { + if id, ok := mn.strToID.Get(str); ok { resp = append(resp, &controller.PrometheusMetricName{Name: &str, Id: proto.Uint32(uint32(id))}) continue } @@ -83,7 +88,7 @@ func (mn *metricName) encode(strs []string) ([]*controller.PrometheusMetricName, for i := range dbToAdd { id := dbToAdd[i].ID str := dbToAdd[i].Name - mn.strToID[str] = id + mn.strToID.Set(str, id) resp = append(resp, &controller.PrometheusMetricName{Name: &str, Id: proto.Uint32(uint32(id))}) } return resp, nil @@ -99,7 +104,7 @@ func (mn *metricName) load() (ids mapset.Set[int], err error) { inUseIDsSet := mapset.NewSet[int]() for _, item := range items { inUseIDsSet.Add(item.ID) - mn.strToID[item.Name] = item.ID + mn.strToID.Set(item.Name, item.ID) } return inUseIDsSet, nil } diff --git a/server/controller/prometheus/label.go b/server/controller/prometheus/label.go index 124503586e0..86f3adf4e0e 100644 --- a/server/controller/prometheus/label.go +++ b/server/controller/prometheus/label.go @@ -100,7 +100,7 @@ func (s *LabelSynchronizer) prepare(req *trident.PrometheusLabelRequest) error { AppendErrGroup(eg, s.addLabelValueCache, syncResp.GetLabelValues()) AppendErrGroup(eg, s.addMetricAPPLabelLayoutCache, syncResp.GetMetricAppLabelLayouts()) AppendErrGroup(eg, s.addLabelCache, syncResp.GetLabels()) - AppendErrGroup(eg, s.addMetricLabelCache, toEncode.metricToMetricLabels) + AppendErrGroup(eg, s.addMetricLabelCache, syncResp.GetMetricLabels()) AppendErrGroup(eg, s.addMetricTargetCache, syncResp.GetMetricTargets()) AppendErrGroup(eg, s.addTargetCache, syncResp.GetTargets()) return eg.Wait() @@ -170,7 +170,7 @@ func (s *LabelSynchronizer) generateSyncRequest(toEncode *dataToEncode) *control return res }(toEncode.labels.ToSlice()), - MetricLabels: func(m map[string]mapset.Set[cache.MetricLabelDetailKey]) []*controller.PrometheusMetricLabelRequest { + MetricLabels: func(m map[string]mapset.Set[cache.LabelKey]) []*controller.PrometheusMetricLabelRequest { res := make([]*controller.PrometheusMetricLabelRequest, 0, len(m)) for mn, lks := range m { rmn := mn @@ -178,8 +178,8 @@ func (s *LabelSynchronizer) generateSyncRequest(toEncode *dataToEncode) *control lkl := lks.ToSlice() for i := range lkl { ls = append(ls, &controller.PrometheusLabelRequest{ - Name: &lkl[i].LabelName, - Value: &lkl[i].LabelValue, + Name: &lkl[i].Name, + Value: &lkl[i].Value, }) } res = append(res, &controller.PrometheusMetricLabelRequest{ @@ -188,7 +188,7 @@ func (s *LabelSynchronizer) generateSyncRequest(toEncode *dataToEncode) *control }) } return res - }(toEncode.metricToMetricLabels), + }(toEncode.metricNameToLabelKeys), MetricTargets: func(ks []cache.MetricTargetKey, iks map[string]mapset.Set[cache.TargetKey]) []*controller.PrometheusMetricTargetRequest { res := make([]*controller.PrometheusMetricTargetRequest, 0, len(ks)) @@ -408,10 +408,8 @@ func (s *LabelSynchronizer) addLabelCache(arg ...interface{}) error { } func (s *LabelSynchronizer) addMetricLabelCache(arg ...interface{}) error { - m := arg[0].(map[string]mapset.Set[cache.MetricLabelDetailKey]) - for _, ks := range m { - s.cache.MetricLabel.Add(ks.ToSlice()) - } + mls := arg[0].([]*controller.PrometheusMetricLabel) + s.cache.MetricLabel.Add(mls) return nil } @@ -435,7 +433,8 @@ type dataToEncode struct { labelValues mapset.Set[string] metricAPPLabelLayouts mapset.Set[cache.LayoutKey] labels mapset.Set[cache.LabelKey] - metricToMetricLabels map[string]mapset.Set[cache.MetricLabelDetailKey] + // metricToMetricLabels map[string]mapset.Set[cache.MetricLabelDetailKey] + metricNameToLabelKeys map[string]mapset.Set[cache.LabelKey] metricTargets mapset.Set[cache.MetricTargetKey] metricToTargets map[string]mapset.Set[cache.TargetKey] targets mapset.Set[cache.TargetKey] @@ -450,7 +449,8 @@ func newDataToEncode() *dataToEncode { labelValues: mapset.NewSet[string](), metricAPPLabelLayouts: mapset.NewSet[cache.LayoutKey](), labels: mapset.NewSet[cache.LabelKey](), - metricToMetricLabels: make(map[string]mapset.Set[cache.MetricLabelDetailKey], 0), + // metricToMetricLabels: make(map[string]mapset.Set[cache.MetricLabelDetailKey], 0), + metricNameToLabelKeys: make(map[string]mapset.Set[cache.LabelKey], 0), metricTargets: mapset.NewSet[cache.MetricTargetKey](), metricToTargets: make(map[string]mapset.Set[cache.TargetKey], 0), targets: mapset.NewSet[cache.TargetKey](), @@ -459,7 +459,7 @@ func newDataToEncode() *dataToEncode { func (d *dataToEncode) cardinality() int { return d.metricNames.Cardinality() + d.labelNames.Cardinality() + d.labelValues.Cardinality() + - d.metricAPPLabelLayouts.Cardinality() + d.labels.Cardinality() + len(d.metricToMetricLabels) + + d.metricAPPLabelLayouts.Cardinality() + d.labels.Cardinality() + len(d.metricNameToLabelKeys) + d.metricTargets.Cardinality() + len(d.metricToTargets) + d.targets.Cardinality() } @@ -496,19 +496,31 @@ func (d *dataToEncode) appendMetricAPPLabelLayout(metricName, labelName string) } func (d *dataToEncode) tryAppendLabel(name, value string) { - if ok := d.cache.Label.IfKeyExists(cache.NewLabelKey(name, value)); !ok { + if _, ok := d.cache.Label.GetIDByKey(cache.NewLabelKey(name, value)); !ok { d.labels.Add(cache.NewLabelKey(name, value)) } } func (d *dataToEncode) tryAppendMetricLabel(metricName, labelName, labelValue string) { - mlk := cache.NewMetricLabelDetailKey(metricName, labelName, labelValue) - if ok := d.cache.MetricLabel.IfKeyExists(mlk); !ok { - if _, ok := d.metricToMetricLabels[metricName]; !ok { - d.metricToMetricLabels[metricName] = mapset.NewSet[cache.MetricLabelDetailKey]() + if mi, ok := d.cache.MetricName.GetIDByName(metricName); ok { + if li, ok := d.cache.Label.GetIDByKey(cache.NewLabelKey(labelName, labelValue)); ok { + if ok := d.cache.MetricLabel.IfLinked(mi, li); ok { + return + } } - d.metricToMetricLabels[metricName].Add(mlk) } + if _, ok := d.metricNameToLabelKeys[metricName]; !ok { + d.metricNameToLabelKeys[metricName] = mapset.NewSet[cache.LabelKey]() + } + d.metricNameToLabelKeys[metricName].Add(cache.NewLabelKey(labelName, labelValue)) + + // mlk := cache.NewMetricLabelDetailKey(metricName, labelName, labelValue) + // if ok := d.cache.MetricLabel.IfKeyExists(mlk); !ok { + // if _, ok := d.metricToMetricLabels[metricName]; !ok { + // d.metricToMetricLabels[metricName] = mapset.NewSet[cache.MetricLabelDetailKey]() + // } + // d.metricToMetricLabels[metricName].Add(mlk) + // } } func (d *dataToEncode) tryAppendMetricTarget(metricName string, targetID int) { diff --git a/server/controller/prometheus/synchronizer.go b/server/controller/prometheus/synchronizer.go index 0c3c71f8df6..ec7f08ffe7c 100644 --- a/server/controller/prometheus/synchronizer.go +++ b/server/controller/prometheus/synchronizer.go @@ -52,14 +52,20 @@ func (s *Synchronizer) assembleMetricLabelFully() ([]*trident.MetricLabelRespons var err error nonLabelNames := mapset.NewSet[string]() nonLabelValues := mapset.NewSet[string]() + nonLabelIDs := mapset.NewSet[int]() mLabels := make([]*trident.MetricLabelResponse, 0) s.cache.MetricName.Get().Range(func(k, v interface{}) bool { var labels []*trident.LabelResponse metricName := k.(string) metricID := v.(int) - labelKeys := s.cache.MetricLabel.GetLabelsByMetricName(metricName) - for i := range labelKeys { - lk := labelKeys[i] + labelIDs := s.cache.MetricLabel.GetLabelsByMetricName(metricName) + for i := range labelIDs { + li := labelIDs[i] + lk, ok := s.cache.Label.GetKeyByID(li) + if !ok { + nonLabelIDs.Add(li) + continue + } if slices.Contains([]string{TargetLabelInstance, TargetLabelJob}, lk.Name) { continue } @@ -98,6 +104,9 @@ func (s *Synchronizer) assembleMetricLabelFully() ([]*trident.MetricLabelRespons if nonLabelValues.Cardinality() > 0 { log.Warningf("label value id not found, values: %v", nonLabelValues.ToSlice()) } + if nonLabelIDs.Cardinality() > 0 { + log.Warningf("label id not found, ids: %v", nonLabelIDs.ToSlice()) + } return mLabels, err } diff --git a/server/controller/prometheus/updater.go b/server/controller/prometheus/updater.go index db24addd97b..7eb813411e4 100644 --- a/server/controller/prometheus/updater.go +++ b/server/controller/prometheus/updater.go @@ -174,12 +174,18 @@ func (td *toolData) load() error { td.layoutKeyToIndex[cache.NewLayoutKey(item.MetricName, item.APPLabelName)] = item.APPLabelColumnIndex } - metricLabelKeys := td.cache.MetricLabel.GetMetricLabelDetailKeys().ToSlice() - for _, item := range metricLabelKeys { - if _, ok := td.metricNameToLabelNames[item.MetricName]; !ok { - td.metricNameToLabelNames[item.MetricName] = mapset.NewSet[string]() + td.cache.MetricLabel.GetMetricNameIDToLabelIDs().Range(func(mni int, lis mapset.Set[int]) bool { + if mn, ok := td.cache.MetricName.GetNameByID(mni); ok { + for _, li := range lis.ToSlice() { + if lk, ok := td.cache.Label.GetKeyByID(li); ok { + if _, ok := td.metricNameToLabelNames[mn]; !ok { + td.metricNameToLabelNames[mn] = mapset.NewSet[string]() + } + td.metricNameToLabelNames[mn].Add(lk.Name) + } + } } - td.metricNameToLabelNames[item.MetricName].Add(item.LabelName) - } + return true + }) return nil }