diff --git a/go.mod b/go.mod index 91608e318be..5aa3a0821ee 100644 --- a/go.mod +++ b/go.mod @@ -22,7 +22,7 @@ require ( github.com/golang/snappy v0.0.4 github.com/google/gopacket v1.1.19 github.com/gorilla/mux v1.8.1 - github.com/grafana/dskit v0.0.0-20241216174023-0450f2ba7c3d + github.com/grafana/dskit v0.0.0-20250103192458-b54518d1a463 github.com/grafana/e2e v0.1.2-0.20240118170847-db90b84177fc github.com/hashicorp/golang-lru v1.0.2 // indirect github.com/json-iterator/go v1.1.12 diff --git a/go.sum b/go.sum index dc6f43653fb..546dcaacb69 100644 --- a/go.sum +++ b/go.sum @@ -1271,8 +1271,8 @@ github.com/grafana-tools/sdk v0.0.0-20220919052116-6562121319fc h1:PXZQA2WCxe85T github.com/grafana-tools/sdk v0.0.0-20220919052116-6562121319fc/go.mod h1:AHHlOEv1+GGQ3ktHMlhuTUwo3zljV3QJbC0+8o2kn+4= github.com/grafana/alerting v0.0.0-20241211182001-0f317eb6b2f7 h1:VGLUQ2mwzlF1NGwTxpSfv1RnuOsDlNh/NT5KRvhZ0sQ= github.com/grafana/alerting v0.0.0-20241211182001-0f317eb6b2f7/go.mod h1:QsnoKX/iYZxA4Cv+H+wC7uxutBD8qi8ZW5UJvD2TYmU= -github.com/grafana/dskit v0.0.0-20241216174023-0450f2ba7c3d h1:Fp40FtD0sR4z6Nb7tqoY0YOPmeNWNfH4UBpIGEMANjs= -github.com/grafana/dskit v0.0.0-20241216174023-0450f2ba7c3d/go.mod h1:SPLNCARd4xdjCkue0O6hvuoveuS1dGJjDnfxYe405YQ= +github.com/grafana/dskit v0.0.0-20250103192458-b54518d1a463 h1:H6DzXDDyoqnLIH5CPSxx3zDd9FY8D8SyeVbzlRfCipI= +github.com/grafana/dskit v0.0.0-20250103192458-b54518d1a463/go.mod h1:SPLNCARd4xdjCkue0O6hvuoveuS1dGJjDnfxYe405YQ= github.com/grafana/e2e v0.1.2-0.20240118170847-db90b84177fc h1:BW+LjKJDz0So5LI8UZfW5neWeKpSkWqhmGjQFzcFfLM= github.com/grafana/e2e v0.1.2-0.20240118170847-db90b84177fc/go.mod h1:JVmqPBe8A/pZWwRoJW5ZjyALeY5OXMzPl7LrVXOdZAI= github.com/grafana/franz-go v0.0.0-20241009100846-782ba1442937 h1:fwwnG/NcygoS6XbAaEyK2QzMXI/BZIEJvQ3CD+7XZm8= diff --git a/vendor/github.com/grafana/dskit/ring/basic_lifecycler.go b/vendor/github.com/grafana/dskit/ring/basic_lifecycler.go index 1675cafac92..c0860d682b6 100644 --- a/vendor/github.com/grafana/dskit/ring/basic_lifecycler.go +++ b/vendor/github.com/grafana/dskit/ring/basic_lifecycler.go @@ -294,7 +294,7 @@ func (l *BasicLifecycler) registerInstance(ctx context.Context) error { var exists bool instanceDesc, exists = ringDesc.Ingesters[l.cfg.ID] if exists { - level.Info(l.logger).Log("msg", "instance found in the ring", "instance", l.cfg.ID, "ring", l.ringName, "state", instanceDesc.GetState(), "tokens", len(instanceDesc.GetTokens()), "registered_at", instanceDesc.GetRegisteredAt().String()) + level.Info(l.logger).Log("msg", "instance found in the ring", "instance", l.cfg.ID, "ring", l.ringName, "state", instanceDesc.GetState(), "tokens", len(instanceDesc.GetTokens()), "registered_at", instanceDesc.GetRegisteredAt().String(), "last_heartbeat_at", instanceDesc.GetLastHeartbeatAt().String()) } else { level.Info(l.logger).Log("msg", "instance not found in the ring", "instance", l.cfg.ID, "ring", l.ringName) } diff --git a/vendor/github.com/grafana/dskit/ring/model.go b/vendor/github.com/grafana/dskit/ring/model.go index c4ba6446693..32529b6bab5 100644 --- a/vendor/github.com/grafana/dskit/ring/model.go +++ b/vendor/github.com/grafana/dskit/ring/model.go @@ -146,6 +146,16 @@ func (i *InstanceDesc) GetRegisteredAt() time.Time { return time.Unix(i.RegisteredTimestamp, 0) } +// GetLastHeartbeatAt returns the timestamp of the last heartbeat sent by the instance +// or a zero value if unknown. +func (i *InstanceDesc) GetLastHeartbeatAt() time.Time { + if i == nil || i.Timestamp == 0 { + return time.Time{} + } + + return time.Unix(i.Timestamp, 0) +} + // GetReadOnlyState returns the read-only state and timestamp of last read-only state update. func (i *InstanceDesc) GetReadOnlyState() (bool, time.Time) { if i == nil { diff --git a/vendor/github.com/grafana/dskit/ring/partition_ring_http.go b/vendor/github.com/grafana/dskit/ring/partition_ring_http.go index 8fe3778eb38..698f33b0f77 100644 --- a/vendor/github.com/grafana/dskit/ring/partition_ring_http.go +++ b/vendor/github.com/grafana/dskit/ring/partition_ring_http.go @@ -5,6 +5,7 @@ import ( _ "embed" "fmt" "html/template" + "math" "net/http" "slices" "sort" @@ -18,6 +19,9 @@ var partitionRingPageTemplate = template.Must(template.New("webpage").Funcs(temp "mod": func(i, j int32) bool { return i%j == 0 }, + "humanFloat": func(f float64) string { + return fmt.Sprintf("%.3g", f) + }, "formatTimestamp": func(ts time.Time) string { return ts.Format("2006-01-02 15:04:05 MST") }, @@ -55,6 +59,7 @@ func (h *PartitionRingPageHandler) handleGetRequest(w http.ResponseWriter, req * ring = h.reader.PartitionRing() ringDesc = ring.desc ) + ownedTokens := ringDesc.countTokens() // Prepare the data to render partitions in the page. partitionsByID := make(map[int32]partitionPageData, len(ringDesc.Partitions)) @@ -68,6 +73,9 @@ func (h *PartitionRingPageHandler) handleGetRequest(w http.ResponseWriter, req * State: partition.State, StateTimestamp: partition.GetStateTime(), OwnerIDs: owners, + Tokens: partition.Tokens, + NumTokens: len(partition.Tokens), + Ownership: distancePercentage(ownedTokens[id]), } } @@ -83,6 +91,9 @@ func (h *PartitionRingPageHandler) handleGetRequest(w http.ResponseWriter, req * State: PartitionUnknown, StateTimestamp: time.Time{}, OwnerIDs: []string{ownerID}, + Tokens: partition.Tokens, + NumTokens: len(partition.Tokens), + Ownership: distancePercentage(ownedTokens[owner.OwnedPartition]), } partitionsByID[owner.OwnedPartition] = partition @@ -105,6 +116,8 @@ func (h *PartitionRingPageHandler) handleGetRequest(w http.ResponseWriter, req * return partitions[i].ID < partitions[j].ID }) + tokensParam := req.URL.Query().Get("tokens") + renderHTTPResponse(w, partitionRingPageData{ Partitions: partitions, PartitionStateChanges: map[PartitionState]PartitionState{ @@ -112,6 +125,7 @@ func (h *PartitionRingPageHandler) handleGetRequest(w http.ResponseWriter, req * PartitionActive: PartitionInactive, PartitionInactive: PartitionActive, }, + ShowTokens: tokensParam == "true", }, partitionRingPageTemplate, req) } @@ -146,6 +160,7 @@ type partitionRingPageData struct { // PartitionStateChanges maps the allowed state changes through the UI. PartitionStateChanges map[PartitionState]PartitionState `json:"-"` + ShowTokens bool `json:"-"` } type partitionPageData struct { @@ -154,4 +169,12 @@ type partitionPageData struct { State PartitionState `json:"state"` StateTimestamp time.Time `json:"state_timestamp"` OwnerIDs []string `json:"owner_ids"` + Tokens []uint32 `json:"tokens"` + NumTokens int `json:"-"` + Ownership float64 `json:"-"` +} + +// distancePercentage renders a given token distance as the percentage of all possible token values covered by that distance. +func distancePercentage(distance int64) float64 { + return (float64(distance) / float64(math.MaxUint32)) * 100 } diff --git a/vendor/github.com/grafana/dskit/ring/partition_ring_model.go b/vendor/github.com/grafana/dskit/ring/partition_ring_model.go index f957fe6b831..cecda6b8989 100644 --- a/vendor/github.com/grafana/dskit/ring/partition_ring_model.go +++ b/vendor/github.com/grafana/dskit/ring/partition_ring_model.go @@ -94,6 +94,34 @@ func (m *PartitionRingDesc) partitionByToken() map[Token]int32 { return out } +// CountTokens returns the summed token distance of all tokens in each partition. +func (m *PartitionRingDesc) countTokens() map[int32]int64 { + owned := make(map[int32]int64, len(m.Partitions)) + sortedTokens := m.tokens() + tokensToPartitions := m.partitionByToken() + + for i, token := range sortedTokens { + partition := tokensToPartitions[Token(token)] + + var prevToken uint32 + if i == 0 { + prevToken = sortedTokens[len(sortedTokens)-1] + } else { + prevToken = sortedTokens[i-1] + } + diff := tokenDistance(prevToken, token) + owned[partition] = owned[partition] + diff + } + + // Partitions with 0 tokens should still exist in the result. + for id := range m.Partitions { + if _, ok := owned[id]; !ok { + owned[id] = 0 + } + } + return owned +} + // ownersByPartition returns a map where the key is the partition ID and the value is a list of owner IDs. func (m *PartitionRingDesc) ownersByPartition() map[int32][]string { out := make(map[int32][]string, len(m.Partitions)) diff --git a/vendor/github.com/grafana/dskit/ring/partition_ring_status.gohtml b/vendor/github.com/grafana/dskit/ring/partition_ring_status.gohtml index f4f9afe87d8..1f0a2eaf020 100644 --- a/vendor/github.com/grafana/dskit/ring/partition_ring_status.gohtml +++ b/vendor/github.com/grafana/dskit/ring/partition_ring_status.gohtml @@ -15,6 +15,8 @@
+ Tokens:
+ {{ range $token := .Tokens }}
+ {{ $token }}
+ {{ end }}
+