Skip to content

Commit 1214c03

Browse files
committed
Final touch changes
1 parent 8ebca0c commit 1214c03

File tree

2 files changed

+71
-74
lines changed

2 files changed

+71
-74
lines changed

pkg/autoscaler/metricsclient/k8s.go

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -67,18 +67,6 @@ func NewCustomMetricsClient(
6767
}, nil
6868
}
6969

70-
// getMetricNames extracts unique metric names from resources
71-
func (cmw *K8sCustomMetricsClient) getMetricNames(resources []scalertypes.Resource) []string {
72-
var metricNames []string
73-
for _, resource := range resources {
74-
for _, scaleResource := range resource.ScaleResources {
75-
metricNames = append(metricNames, scaleResource.GetKubernetesMetricName())
76-
}
77-
}
78-
metricNames = common.UniquifyStringSlice(metricNames)
79-
return metricNames
80-
}
81-
8270
func (cmw *K8sCustomMetricsClient) GetResourceMetrics(resources []scalertypes.Resource) (map[string]map[string]int, error) {
8371
metricNames := cmw.getMetricNames(resources)
8472
resourcesMetricsMap := make(map[string]map[string]int)
@@ -121,3 +109,15 @@ func (cmw *K8sCustomMetricsClient) GetResourceMetrics(resources []scalertypes.Re
121109
}
122110
return resourcesMetricsMap, nil
123111
}
112+
113+
// getMetricNames extracts unique metric names from resources
114+
func (cmw *K8sCustomMetricsClient) getMetricNames(resources []scalertypes.Resource) []string {
115+
var metricNames []string
116+
for _, resource := range resources {
117+
for _, scaleResource := range resource.ScaleResources {
118+
metricNames = append(metricNames, scaleResource.GetKubernetesMetricName())
119+
}
120+
}
121+
metricNames = common.UniquifyStringSlice(metricNames)
122+
return metricNames
123+
}

pkg/autoscaler/metricsclient/prometheus.go

Lines changed: 59 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -85,60 +85,6 @@ func NewPrometheusClient(parentLogger logger.Logger, prometheusURL, namespace st
8585
}, nil
8686
}
8787

88-
// renderQuery renders the Prometheus query template
89-
func (pc *PrometheusClient) renderQuery(queryTemplate *template.Template, windowSize, resourceNameRegex string) (string, error) {
90-
templateData := make(map[string]string)
91-
templateData["Namespace"] = pc.namespace
92-
templateData["WindowSize"] = windowSize
93-
templateData["Resources"] = resourceNameRegex
94-
95-
var queryBuffer bytes.Buffer
96-
if err := queryTemplate.Execute(&queryBuffer, templateData); err != nil {
97-
return "", fmt.Errorf("error executing template: %w", err)
98-
}
99-
100-
return queryBuffer.String(), nil
101-
}
102-
103-
// extractWindowSizesForMetric extracts unique window sizes from resources' ScaleResources for a specific metric name.
104-
func (pc *PrometheusClient) extractWindowSizesForMetric(resources []scalertypes.Resource, metricName string) map[string]bool {
105-
windowSizes := make(map[string]bool)
106-
for _, resource := range resources {
107-
for _, scaleResource := range resource.ScaleResources {
108-
if scaleResource.MetricName == metricName {
109-
windowSizeStr := scalertypes.ShortDurationString(scaleResource.WindowSize)
110-
windowSizes[windowSizeStr] = true
111-
}
112-
}
113-
}
114-
return windowSizes
115-
}
116-
117-
// buildResourceNameRegex creates a pipe-separated regex pattern from resource names for Prometheus query filtering (e.g., "func1|func2|func3")
118-
func (pc *PrometheusClient) buildResourceNameRegex(resources []scalertypes.Resource) string {
119-
resourceNames := make([]string, len(resources))
120-
for i, resource := range resources {
121-
resourceNames[i] = resource.Name
122-
}
123-
return strings.Join(resourceNames, "|")
124-
}
125-
126-
// resolveFullMetricName finds the matching ScaleResource for a given metric name and window size,
127-
// and returns the full metric name (e.g., "metric_name_per_1m").
128-
func (pc *PrometheusClient) resolveFullMetricName(resources []scalertypes.Resource, metricName, windowSize string) (string, error) {
129-
for _, resource := range resources {
130-
for _, scaleResource := range resource.ScaleResources {
131-
if scaleResource.MetricName == metricName {
132-
scaleResourceWindowSize := scalertypes.ShortDurationString(scaleResource.WindowSize)
133-
if scaleResourceWindowSize == windowSize {
134-
return scaleResource.GetKubernetesMetricName(), nil
135-
}
136-
}
137-
}
138-
}
139-
return "", errors.Errorf("Failed to find ScaleResource matching metric name and window size: metricName=%s, windowSize=%s", metricName, windowSize)
140-
}
141-
14288
// GetResourceMetrics retrieves metrics for multiple resources
14389
func (pc *PrometheusClient) GetResourceMetrics(resources []scalertypes.Resource) (map[string]map[string]int, error) {
14490
metricsByResource := make(map[string]map[string]int)
@@ -197,23 +143,23 @@ func (pc *PrometheusClient) GetResourceMetrics(resources []scalertypes.Resource)
197143
for _, metricSample := range metricSamples {
198144
resourceName, err := pc.extractResourceName(metricSample.Metric)
199145
if err != nil {
200-
pc.logger.WarnWith("Failed to extract resource name from Prometheus metricSample labels",
146+
pc.logger.WarnWith("Failed to extract resource name from the Prometheus metric's labels",
201147
"metricName", metricName,
202148
"windowSize", windowSize,
203149
"labels", metricSample.Metric.String(),
204150
"error", err)
205151
continue
206152
}
207153

208-
// Use Ceil to ensure any fractional value > 0 becomes at least 1
154+
// Round up values to ensure any fractional value > 0 becomes at least 1
209155
// This prevents incorrect scale-to-zero decisions for resources with low activity
210156
metricValue := int(math.Ceil(float64(metricSample.Value)))
211157

212158
if _, found := metricsByResource[resourceName]; !found {
213159
metricsByResource[resourceName] = make(map[string]int)
214160
}
215161

216-
pc.logger.DebugWith("Retrieved metricSample sample",
162+
pc.logger.DebugWith("Retrieved metric",
217163
"resourceName", resourceName,
218164
"metricName", fullMetricName,
219165
"windowSize", windowSize,
@@ -222,29 +168,80 @@ func (pc *PrometheusClient) GetResourceMetrics(resources []scalertypes.Resource)
222168
if _, found := metricsByResource[resourceName][fullMetricName]; found {
223169
return nil, errors.Errorf("Cannot have more than one metricSample value per resource: resource=%s, metricSample=%s", resourceName, fullMetricName)
224170
}
225-
226171
metricsByResource[resourceName][fullMetricName] = metricValue
227172
}
228173
}
229174
}
230-
231175
return metricsByResource, nil
232176
}
233177

178+
// renderQuery renders the Prometheus query template
179+
func (pc *PrometheusClient) renderQuery(queryTemplate *template.Template, windowSize, resourceNameRegex string) (string, error) {
180+
templateData := make(map[string]string)
181+
templateData["Namespace"] = pc.namespace
182+
templateData["WindowSize"] = windowSize
183+
templateData["Resources"] = resourceNameRegex
184+
185+
var queryBuffer bytes.Buffer
186+
if err := queryTemplate.Execute(&queryBuffer, templateData); err != nil {
187+
return "", fmt.Errorf("error executing template: %w", err)
188+
}
189+
190+
return queryBuffer.String(), nil
191+
}
192+
193+
// extractWindowSizesForMetric extracts unique window sizes from resources' ScaleResources for a specific metric name.
194+
func (pc *PrometheusClient) extractWindowSizesForMetric(resources []scalertypes.Resource, metricName string) map[string]bool {
195+
windowSizes := make(map[string]bool)
196+
for _, resource := range resources {
197+
for _, scaleResource := range resource.ScaleResources {
198+
if scaleResource.MetricName == metricName {
199+
windowSizeStr := scalertypes.ShortDurationString(scaleResource.WindowSize)
200+
windowSizes[windowSizeStr] = true
201+
}
202+
}
203+
}
204+
return windowSizes
205+
}
206+
207+
// buildResourceNameRegex creates a Prometheus regex pattern for query filtering
208+
func (pc *PrometheusClient) buildResourceNameRegex(resources []scalertypes.Resource) string {
209+
resourceNames := make([]string, len(resources))
210+
for i, resource := range resources {
211+
resourceNames[i] = resource.Name
212+
}
213+
// creates a pipe-separated regex pattern from resource names for Prometheus query filtering (e.g., "resource1|resource2")
214+
return strings.Join(resourceNames, "|")
215+
}
216+
217+
// resolveFullMetricName resolves the full metric name because the same resource can have multiple
218+
// metrics with the same base name but different window sizes (e.g., "metric_name_per_1m" vs "metric_name_per_5m"),
219+
// and we need unique keys in our internal metrics map to store them separately.
220+
func (pc *PrometheusClient) resolveFullMetricName(resources []scalertypes.Resource, metricName, windowSize string) (string, error) {
221+
for _, resource := range resources {
222+
for _, scaleResource := range resource.ScaleResources {
223+
if scaleResource.MetricName == metricName {
224+
scaleResourceWindowSize := scalertypes.ShortDurationString(scaleResource.WindowSize)
225+
if scaleResourceWindowSize == windowSize {
226+
return scaleResource.GetKubernetesMetricName(), nil
227+
}
228+
}
229+
}
230+
}
231+
return "", errors.Errorf("Failed to find ScaleResource matching metric name and window size: metricName=%s, windowSize=%s", metricName, windowSize)
232+
}
233+
234234
// extractResourceName extracts the resource name from Prometheus metric labels.
235235
func (pc *PrometheusClient) extractResourceName(labels model.Metric) (string, error) {
236236
labelNames := []model.LabelName{
237237
"function", // For nuclio functions (nuclio_processor_handled_events_total) - maps to nucliofunction resource
238238
"service_name", // For deployments (num_of_requests, jupyter_kernel_busyness) - maps to deployment resource
239239
"pod", // For pod-based metrics (DCGM_FI_DEV_GPU_UTIL) - maps to pod resource
240240
}
241-
242241
for _, labelName := range labelNames {
243242
if value, ok := labels[labelName]; ok {
244243
return string(value), nil
245244
}
246245
}
247-
248-
// If no common label found, return error
249246
return "", errors.Errorf("Could not extract resource name from labels: %v", labels)
250247
}

0 commit comments

Comments
 (0)