mirror of
https://github.com/ClusterCockpit/cc-backend
synced 2026-08-08 06:17:15 +02:00
modify(metricstore): more verbose logging to DataNonAlignedIssue
This commit is contained in:
+23
-10
@@ -381,7 +381,10 @@ func (l *Level) findLevel(selector []string) *Level {
|
|||||||
// Parameters:
|
// Parameters:
|
||||||
// - selector: Pattern to match (consumed recursively)
|
// - selector: Pattern to match (consumed recursively)
|
||||||
// - offset: Metric index in metrics slice (from MetricConfig.offset)
|
// - offset: Metric index in metrics slice (from MetricConfig.offset)
|
||||||
// - f: Callback invoked on each matching buffer
|
// - f: Callback invoked on each matching buffer; path holds the matched
|
||||||
|
// level keys (e.g. ["cluster","node001","cpu0"]) so callers can
|
||||||
|
// identify which node/component the buffer belongs to
|
||||||
|
// - path: Accumulated level keys from the root; pass nil at the top level
|
||||||
//
|
//
|
||||||
// Returns:
|
// Returns:
|
||||||
// - error: First error returned by callback, or nil if all succeeded
|
// - error: First error returned by callback, or nil if all succeeded
|
||||||
@@ -389,19 +392,19 @@ func (l *Level) findLevel(selector []string) *Level {
|
|||||||
// Example:
|
// Example:
|
||||||
//
|
//
|
||||||
// // Find all cpu0 buffers across all hosts:
|
// // Find all cpu0 buffers across all hosts:
|
||||||
// findBuffers([]Selector{{Any: true}, {String: "cpu0"}}, metricOffset, callback)
|
// findBuffers([]Selector{{Any: true}, {String: "cpu0"}}, metricOffset, callback, nil)
|
||||||
func (l *Level) findBuffers(selector util.Selector, offset int, f func(b *buffer) error) error {
|
func (l *Level) findBuffers(selector util.Selector, offset int, f func(b *buffer, path []string) error, path []string) error {
|
||||||
l.lock.RLock()
|
l.lock.RLock()
|
||||||
defer l.lock.RUnlock()
|
defer l.lock.RUnlock()
|
||||||
|
|
||||||
if len(selector) == 0 {
|
if len(selector) == 0 {
|
||||||
b := l.metrics[offset]
|
b := l.metrics[offset]
|
||||||
if b != nil {
|
if b != nil {
|
||||||
return f(b)
|
return f(b, path)
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, lvl := range l.children {
|
for key, lvl := range l.children {
|
||||||
err := lvl.findBuffers(nil, offset, f)
|
err := lvl.findBuffers(nil, offset, f, appendPath(path, key))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@@ -413,7 +416,7 @@ func (l *Level) findBuffers(selector util.Selector, offset int, f func(b *buffer
|
|||||||
if len(sel.String) != 0 && l.children != nil {
|
if len(sel.String) != 0 && l.children != nil {
|
||||||
lvl, ok := l.children[sel.String]
|
lvl, ok := l.children[sel.String]
|
||||||
if ok {
|
if ok {
|
||||||
err := lvl.findBuffers(selector[1:], offset, f)
|
err := lvl.findBuffers(selector[1:], offset, f, appendPath(path, sel.String))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@@ -425,7 +428,7 @@ func (l *Level) findBuffers(selector util.Selector, offset int, f func(b *buffer
|
|||||||
for _, key := range sel.Group {
|
for _, key := range sel.Group {
|
||||||
lvl, ok := l.children[key]
|
lvl, ok := l.children[key]
|
||||||
if ok {
|
if ok {
|
||||||
err := lvl.findBuffers(selector[1:], offset, f)
|
err := lvl.findBuffers(selector[1:], offset, f, appendPath(path, key))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@@ -435,8 +438,8 @@ func (l *Level) findBuffers(selector util.Selector, offset int, f func(b *buffer
|
|||||||
}
|
}
|
||||||
|
|
||||||
if sel.Any && l.children != nil {
|
if sel.Any && l.children != nil {
|
||||||
for _, lvl := range l.children {
|
for key, lvl := range l.children {
|
||||||
if err := lvl.findBuffers(selector[1:], offset, f); err != nil {
|
if err := lvl.findBuffers(selector[1:], offset, f, appendPath(path, key)); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -445,3 +448,13 @@ func (l *Level) findBuffers(selector util.Selector, offset int, f func(b *buffer
|
|||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// appendPath returns a new slice holding path followed by key. It copies rather
|
||||||
|
// than appending in place so sibling recursions never share/overwrite backing
|
||||||
|
// storage while the tree is walked concurrently.
|
||||||
|
func appendPath(path []string, key string) []string {
|
||||||
|
np := make([]string, len(path)+1)
|
||||||
|
copy(np, path)
|
||||||
|
np[len(path)] = key
|
||||||
|
return np
|
||||||
|
}
|
||||||
|
|||||||
@@ -28,6 +28,7 @@ import (
|
|||||||
"runtime"
|
"runtime"
|
||||||
"runtime/debug"
|
"runtime/debug"
|
||||||
"slices"
|
"slices"
|
||||||
|
"strings"
|
||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
@@ -631,7 +632,7 @@ func (m *MemoryStore) Read(selector util.Selector, metric string, from, to, reso
|
|||||||
n, data := 0, make([]schema.Float, (to-from)/minfo.Frequency+1)
|
n, data := 0, make([]schema.Float, (to-from)/minfo.Frequency+1)
|
||||||
var dataFrom, dataTo int64
|
var dataFrom, dataTo int64
|
||||||
|
|
||||||
err := m.root.findBuffers(selector, minfo.offset, func(b *buffer) error {
|
err := m.root.findBuffers(selector, minfo.offset, func(b *buffer, path []string) error {
|
||||||
cdata, cfrom, cto, err := b.read(from, to, data, false)
|
cdata, cfrom, cto, err := b.read(from, to, data, false)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
@@ -640,24 +641,27 @@ func (m *MemoryStore) Read(selector util.Selector, metric string, from, to, reso
|
|||||||
if n == 0 {
|
if n == 0 {
|
||||||
dataFrom, dataTo = cfrom, cto
|
dataFrom, dataTo = cfrom, cto
|
||||||
} else if cfrom != dataFrom || cto != dataTo {
|
} else if cfrom != dataFrom || cto != dataTo {
|
||||||
|
node := strings.Join(path, "/")
|
||||||
missingfront, missingback := int((dataFrom-cfrom)/minfo.Frequency), int((dataTo-cto)/minfo.Frequency)
|
missingfront, missingback := int((dataFrom-cfrom)/minfo.Frequency), int((dataTo-cto)/minfo.Frequency)
|
||||||
switch {
|
switch {
|
||||||
case missingfront != 0:
|
case missingfront != 0:
|
||||||
cclog.Warnf("%s", fmt.Errorf("%w: metric=%s buf#%d freq=%d ref[%d,%d] this[%d,%d] missingfront=%d pts",
|
cclog.Warnf("%s", fmt.Errorf("%w: metric=%s node=%s buf#%d freq=%d expected[%d,%d] actual[%d,%d] missingfront=%d pts",
|
||||||
ErrDataDoesNotAlignMissingFront, metric, n, minfo.Frequency, dataFrom, dataTo, cfrom, cto, missingfront))
|
ErrDataDoesNotAlignMissingFront, metric, node, n, minfo.Frequency, dataFrom, dataTo, cfrom, cto, missingfront))
|
||||||
case missingback != 0:
|
case missingback != 0:
|
||||||
cclog.Warnf("%s", fmt.Errorf("%w: metric=%s buf#%d freq=%d ref[%d,%d] this[%d,%d] missingback=%d pts",
|
cclog.Warnf("%s", fmt.Errorf("%w: metric=%s node=%s buf#%d freq=%d expected[%d,%d] actual[%d,%d] missingback=%d pts",
|
||||||
ErrDataDoesNotAlignMissingBack, metric, n, minfo.Frequency, dataFrom, dataTo, cfrom, cto, missingback))
|
ErrDataDoesNotAlignMissingBack, metric, node, n, minfo.Frequency, dataFrom, dataTo, cfrom, cto, missingback))
|
||||||
default:
|
default:
|
||||||
cclog.Warnf("%s", fmt.Errorf("%w: metric=%s buf#%d ref[%d,%d] this[%d,%d]",
|
cclog.Warnf("%s", fmt.Errorf("%w: metric=%s node=%s buf#%d expected[%d,%d] actual[%d,%d]",
|
||||||
ErrDataDoesNotAlignDataLenMismatch, metric, n, dataFrom, dataTo, cfrom, cto))
|
ErrDataDoesNotAlignDataLenMismatch, metric, node, n, dataFrom, dataTo, cfrom, cto))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fmt.Printf("Gather data - cto: %d, cfrom: %d, dto: %d, dfrom: %d\n", cto, cfrom, dataTo, dataFrom)
|
||||||
|
|
||||||
data = cdata
|
data = cdata
|
||||||
n += 1
|
n += 1
|
||||||
return nil
|
return nil
|
||||||
})
|
}, nil)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, 0, 0, 0, err
|
return nil, 0, 0, 0, err
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ import (
|
|||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"math"
|
"math"
|
||||||
|
"strings"
|
||||||
|
|
||||||
"github.com/ClusterCockpit/cc-lib/v2/schema"
|
"github.com/ClusterCockpit/cc-lib/v2/schema"
|
||||||
"github.com/ClusterCockpit/cc-lib/v2/util"
|
"github.com/ClusterCockpit/cc-lib/v2/util"
|
||||||
@@ -134,7 +135,7 @@ func (m *MemoryStore) Stats(selector util.Selector, metric string, from, to int6
|
|||||||
|
|
||||||
n, samples := 0, 0
|
n, samples := 0, 0
|
||||||
avg, min, max := schema.Float(0), math.MaxFloat32, -math.MaxFloat32
|
avg, min, max := schema.Float(0), math.MaxFloat32, -math.MaxFloat32
|
||||||
err := m.root.findBuffers(selector, minfo.offset, func(b *buffer) error {
|
err := m.root.findBuffers(selector, minfo.offset, func(b *buffer, path []string) error {
|
||||||
stats, cfrom, cto, err := b.stats(from, to)
|
stats, cfrom, cto, err := b.stats(from, to)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
@@ -143,11 +144,11 @@ func (m *MemoryStore) Stats(selector util.Selector, metric string, from, to int6
|
|||||||
if n == 0 {
|
if n == 0 {
|
||||||
from, to = cfrom, cto
|
from, to = cfrom, cto
|
||||||
} else if from != cfrom {
|
} else if from != cfrom {
|
||||||
return fmt.Errorf("%w: metric=%s buf#%d want[%d,%d] got[%d,%d]",
|
return fmt.Errorf("%w: metric=%s node=%s buf#%d expected[%d,%d] actual[%d,%d]",
|
||||||
ErrDataDoesNotAlignMissingFront, metric, n, from, to, cfrom, cto)
|
ErrDataDoesNotAlignMissingFront, metric, strings.Join(path, "/"), n, from, to, cfrom, cto)
|
||||||
} else if to != cto {
|
} else if to != cto {
|
||||||
return fmt.Errorf("%w: metric=%s buf#%d want[%d,%d] got[%d,%d]",
|
return fmt.Errorf("%w: metric=%s node=%s buf#%d expected[%d,%d] actual[%d,%d]",
|
||||||
ErrDataDoesNotAlignMissingBack, metric, n, from, to, cfrom, cto)
|
ErrDataDoesNotAlignMissingBack, metric, strings.Join(path, "/"), n, from, to, cfrom, cto)
|
||||||
}
|
}
|
||||||
|
|
||||||
samples += stats.Samples
|
samples += stats.Samples
|
||||||
@@ -156,7 +157,7 @@ func (m *MemoryStore) Stats(selector util.Selector, metric string, from, to int6
|
|||||||
max = math.Max(max, float64(stats.Max))
|
max = math.Max(max, float64(stats.Max))
|
||||||
n += 1
|
n += 1
|
||||||
return nil
|
return nil
|
||||||
})
|
}, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, 0, 0, err
|
return nil, 0, 0, err
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user