Like Prometheus, but for logs.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 
loki/pkg/util/ring.go

49 lines
1.5 KiB

package util
import (
"hash/fnv"
"github.com/go-kit/log/level"
"github.com/grafana/dskit/ring"
util_log "github.com/grafana/loki/pkg/util/log"
)
// TokenFor generates a token used for finding ingesters from ring
func TokenFor(userID, labels string) uint32 {
h := fnv.New32()
_, _ = h.Write([]byte(userID))
_, _ = h.Write([]byte(labels))
return h.Sum32()
}
// IsInReplicationSet will query the provided ring for the provided key
// and see if the provided address is in the resulting ReplicationSet
func IsInReplicationSet(r ring.ReadRing, ringKey uint32, address string) (bool, error) {
bufDescs, bufHosts, bufZones := ring.MakeBuffersForGet()
rs, err := r.Get(ringKey, ring.Write, bufDescs, bufHosts, bufZones)
if err != nil {
return false, err
}
addrs := rs.GetAddresses()
for _, a := range addrs {
if a == address {
return true, nil
}
}
return false, nil
}
// IsAssignedKey replies wether the given instance address is in the ReplicationSet responsible for the given key or not, based on the tokens.
//
// The result will be defined based on the tokens assigned to each ring component, queried through the ring client.
func IsAssignedKey(ringClient ring.ReadRing, instanceAddress string, key string) bool {
token := TokenFor(key, "" /* labels */)
inSet, err := IsInReplicationSet(ringClient, token, instanceAddress)
if err != nil {
level.Error(util_log.Logger).Log("msg", "error checking if key is in replicationset", "error", err, "key", key)
return false
}
return inSet
}