-
Notifications
You must be signed in to change notification settings - Fork 1.4k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Feat/7076_1 | Added Inspect metrics API #7197
base: main
Are you sure you want to change the base?
Changes from all commits
05c0d87
cd6ec76
809edda
f9d07e9
74dd32c
ef2400b
7d4cb88
a53e6f6
56da1e7
31aa380
fb9b47e
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Large diffs are not rendered by default.
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -5,6 +5,7 @@ import ( | |
"encoding/json" | ||
"errors" | ||
"sort" | ||
"strings" | ||
"time" | ||
|
||
"go.uber.org/zap" | ||
|
@@ -142,7 +143,7 @@ func (receiver *SummaryService) GetMetricsSummary(ctx context.Context, metricNam | |
}) | ||
|
||
g.Go(func() error { | ||
attributes, err := receiver.reader.GetAttributesForMetricName(ctx, metricName) | ||
attributes, err := receiver.reader.GetAttributesForMetricName(ctx, metricName, nil, nil) | ||
if err != nil { | ||
return err | ||
} | ||
|
@@ -166,13 +167,15 @@ func (receiver *SummaryService) GetMetricsSummary(ctx context.Context, metricNam | |
return &model.ApiError{Typ: "MarshallingErr", Err: err} | ||
} | ||
|
||
var dashboards []metrics_explorer.Dashboard | ||
var dashboards map[string][]metrics_explorer.Dashboard | ||
err = json.Unmarshal(jsonData, &dashboards) | ||
if err != nil { | ||
zap.L().Error("Error unmarshalling data:", zap.Error(err)) | ||
return &model.ApiError{Typ: "UnMarshallingErr", Err: err} | ||
} | ||
metricDetailsDTO.Dashboards = dashboards | ||
if _, ok := dashboards[metricName]; ok { | ||
metricDetailsDTO.Dashboards = dashboards[metricName] | ||
} | ||
} | ||
return nil | ||
}) | ||
|
@@ -447,3 +450,85 @@ func getQueryRangeForRelateMetricsList(metricName string, scores metrics_explore | |
|
||
return &query | ||
} | ||
|
||
func (receiver *SummaryService) GetInspectMetrics(ctx context.Context, params *metrics_explorer.InspectMetricsRequest) (*metrics_explorer.InspectMetricsResponse, *model.ApiError) { | ||
// Capture the original context. | ||
parentCtx := ctx | ||
|
||
// Create an errgroup using the original context. | ||
g, egCtx := errgroup.WithContext(ctx) | ||
|
||
var attributes []metrics_explorer.Attribute | ||
var resourceAttrs map[string]uint64 | ||
|
||
// Run the two queries concurrently using the derived context. | ||
g.Go(func() error { | ||
attrs, apiErr := receiver.reader.GetAttributesForMetricName(egCtx, params.MetricName, ¶ms.Start, ¶ms.End) | ||
if apiErr != nil { | ||
return apiErr | ||
} | ||
if attrs != nil { | ||
attributes = *attrs | ||
} | ||
return nil | ||
}) | ||
|
||
g.Go(func() error { | ||
resAttrs, apiErr := receiver.reader.GetMetricsAllResourceAttributes(egCtx, params.Start, params.End) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Since the metadata table has the 6 hours rounded precision, directly passing start and end won't give data in many cases. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. resolved |
||
if apiErr != nil { | ||
return apiErr | ||
} | ||
if resAttrs != nil { | ||
resourceAttrs = resAttrs | ||
} | ||
return nil | ||
}) | ||
|
||
// Wait for the concurrent operations to complete. | ||
if err := g.Wait(); err != nil { | ||
return nil, &model.ApiError{Typ: "InternalError", Err: err} | ||
} | ||
|
||
// Use the parentCtx (or create a new context from it) for the rest of the calls. | ||
if parentCtx.Err() != nil { | ||
return nil, &model.ApiError{Typ: "ContextCanceled", Err: parentCtx.Err()} | ||
} | ||
|
||
// Build a set of attribute keys for O(1) lookup. | ||
attributeKeys := make(map[string]struct{}) | ||
for _, attr := range attributes { | ||
attributeKeys[attr.Key] = struct{}{} | ||
} | ||
|
||
// Filter resource attributes that are present in attributes. | ||
var validAttrs []string | ||
for attrName := range resourceAttrs { | ||
normalizedAttrName := strings.ReplaceAll(attrName, ".", "_") | ||
if _, ok := attributeKeys[normalizedAttrName]; ok { | ||
validAttrs = append(validAttrs, normalizedAttrName) | ||
} | ||
} | ||
|
||
// Get top 3 resource attributes (or use top attributes by valueCount if none match). | ||
if len(validAttrs) > 3 { | ||
validAttrs = validAttrs[:3] | ||
} else if len(validAttrs) == 0 { | ||
sort.Slice(attributes, func(i, j int) bool { | ||
return attributes[i].ValueCount > attributes[j].ValueCount | ||
}) | ||
for i := 0; i < len(attributes) && i < 3; i++ { | ||
validAttrs = append(validAttrs, attributes[i].Key) | ||
} | ||
} | ||
fingerprints, apiError := receiver.reader.GetInspectMetricsFingerprints(parentCtx, validAttrs, params) | ||
if apiError != nil { | ||
return nil, apiError | ||
} | ||
|
||
baseResponse, apiErr := receiver.reader.GetInspectMetrics(parentCtx, params, fingerprints) | ||
if apiErr != nil { | ||
return nil, apiErr | ||
} | ||
|
||
return baseResponse, nil | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -149,3 +149,14 @@ type RelatedMetrics struct { | |
Dashboards []Dashboard `json:"dashboards"` | ||
Alerts []Alert `json:"alerts"` | ||
} | ||
|
||
type InspectMetricsRequest struct { | ||
MetricName string `json:"metricName"` | ||
Filters v3.FilterSet `json:"filters"` | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is not used? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. adding filters wont be possible for cases like not in etc, as we are manually getting resource attributes for the user. so filters wont be applicable for the users |
||
Start int64 `json:"start"` | ||
End int64 `json:"end"` | ||
} | ||
|
||
type InspectMetricsResponse struct { | ||
Series *[]v3.Series `json:"series,omitempty"` | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Extract magic number 1800000 into a named constant for clarity.