mirror of https://github.com/linkerd/linkerd2.git
Verify in Prometheus edges query that data for a specific resource type exists (#2826)
Adds a check to Prometheus `edges` queries to verify that data for the requested resource type exists. Previously, if Prometheus could not find request data for the requested resource type, it would skip that label and still return data for other labels in the `by` clause, leading to an incorrect response.
This commit is contained in:
parent
512dcd336f
commit
bb2921a3d9
|
@ -65,8 +65,12 @@ func (s *grpcServer) getEdges(ctx context.Context, req *pb.EdgesRequest) ([]*pb.
|
|||
labelsOutbound := labels.Merge(promDirectionLabels("outbound"))
|
||||
labelsInbound := labels.Merge(promDirectionLabels("inbound"))
|
||||
|
||||
inboundQuery := fmt.Sprintf(inboundIdentityQuery, labelsInbound, resourceType)
|
||||
outboundQuery := fmt.Sprintf(outboundIdentityQuery, labelsOutbound, resourceType, resourceType)
|
||||
// checking that data for the specified resource type exists
|
||||
labelsOutboundStr := generateLabelStringWithExclusion(labelsOutbound, resourceType)
|
||||
labelsInboundStr := generateLabelStringWithExclusion(labelsInbound, resourceType)
|
||||
|
||||
outboundQuery := fmt.Sprintf(outboundIdentityQuery, labelsOutboundStr, resourceType, resourceType)
|
||||
inboundQuery := fmt.Sprintf(inboundIdentityQuery, labelsInboundStr, resourceType)
|
||||
|
||||
inboundResult, err := s.queryProm(ctx, inboundQuery)
|
||||
if err != nil {
|
||||
|
|
|
@ -4,6 +4,8 @@ import (
|
|||
"context"
|
||||
"fmt"
|
||||
"math"
|
||||
"sort"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
pb "github.com/linkerd/linkerd2/controller/gen/public"
|
||||
|
@ -116,6 +118,20 @@ func promDstQueryLabels(resource *pb.Resource) model.LabelSet {
|
|||
return set
|
||||
}
|
||||
|
||||
// insert a not-nil check into a LabelSet to verify that data for a specified
|
||||
// label name exists. due to the `!=` this must be inserted as a string. the
|
||||
// structure of this code is taken from the Prometheus labelset.go library.
|
||||
func generateLabelStringWithExclusion(l model.LabelSet, labelName string) string {
|
||||
lstrs := make([]string, 0, len(l))
|
||||
for l, v := range l {
|
||||
lstrs = append(lstrs, fmt.Sprintf("%s=%q", l, v))
|
||||
}
|
||||
lstrs = append(lstrs, fmt.Sprintf(`%s!=""`, labelName))
|
||||
|
||||
sort.Strings(lstrs)
|
||||
return fmt.Sprintf("{%s}", strings.Join(lstrs, ", "))
|
||||
}
|
||||
|
||||
// determine if we should add "namespace=<namespace>" to a named query
|
||||
func shouldAddNamespaceLabel(resource *pb.Resource) bool {
|
||||
return resource.Type != k8s.Namespace && resource.Namespace != ""
|
||||
|
|
Loading…
Reference in New Issue