in adapter/pkg/provider/provider.go [164:275]
func (p *externalMetricsProvider) GetExternalMetric(_ context.Context, namespace string, metricSelector labels.Selector,
info apiprovider.ExternalMetricInfo) (*external_metrics.ExternalMetricValueList, error) {
var md *swctlapi.MetricDefinition
for _, m := range p.metricDefines {
if p.getMetricNameWithNamespace(m.Name) == info.Metric {
md = m
}
}
if md == nil {
klog.Errorf("%s is missing in OAP", info.Metric)
return nil, apierr.NewBadRequest(fmt.Sprintf("%s is defined in OAP", info.Metric))
}
requirement, selector := metricSelector.Requirements()
if !selector {
klog.Errorf("no selector for metric: %s", md.Name)
return nil, apierr.NewBadRequest(fmt.Sprintf("no selector for metric: %s", md.Name))
}
svc := ¶mValue{key: "service"}
label := ¶mValue{key: "label"}
instance := ¶mValue{key: "instance"}
endpoint := ¶mValue{key: "endpoint"}
extractValue(requirement, svc, label, instance, endpoint)
if *svc.val == "" {
klog.Errorf("%s is lack of required label 'service'", md.Name)
return nil, apierr.NewBadRequest(fmt.Sprintf("%s is lack of required label 'service'", md.Name))
}
now := time.Now()
startTime := now.Add(-3 * time.Minute)
endTime := now
step := swctlapi.StepMinute
duration := swctlapi.Duration{
Start: startTime.Format(stepMinute),
End: endTime.Format(stepMinute),
Step: step,
}
normal := true
empty := ""
entity := &swctlapi.Entity{
ServiceName: svc.val,
ServiceInstanceName: instance.val,
EndpointName: endpoint.val,
Normal: &normal,
DestServiceName: &empty,
DestNormal: &normal,
DestServiceInstanceName: &empty,
DestEndpointName: &empty,
}
entity.Scope = parseScope(entity)
condition := swctlapi.MetricsCondition{
Name: md.Name,
Entity: entity,
}
var metricsValues swctlapi.MetricsValues
if md.Type == swctlapi.MetricsTypeRegularValue {
var err error
metricsValues, err = metrics.LinearIntValues(p.ctx, condition, duration)
if err != nil {
return nil, apierr.NewInternalError(fmt.Errorf("unable to fetch metrics: %v", err))
}
klog.V(4).Infof("Linear request{condition:%s, duration:%s} response %s", display(condition), display(duration), display(metricsValues))
} else if md.Type == swctlapi.MetricsTypeLabeledValue {
if *label.val == "" {
klog.Errorf("%s is lack of required label 'label'", md.Name)
return nil, apierr.NewBadRequest(fmt.Sprintf("%s is lack of required label 'label'", md.Name))
}
result, err := metrics.MultipleLinearIntValues(p.ctx, condition, []string{*label.val}, duration)
if err != nil {
return nil, apierr.NewInternalError(fmt.Errorf("unable to fetch metrics: %v", err))
}
klog.V(4).Infof("Labeled request{condition:%s, duration:%s, labels:%s} response %s",
display(condition), display(duration), *label.val, display(result))
for _, r := range result {
if *r.Label == *label.val {
metricsValues = r
}
}
}
if len(metricsValues.Values.Values) < 1 {
return nil, apiprovider.NewMetricNotFoundError(p.selectGroupResource(namespace), info.Metric)
}
var sTime time.Time
var sValue int64
l := len(metricsValues.Values.Values)
if l < 2 {
return nil, apiprovider.NewMetricNotFoundError(p.selectGroupResource(namespace), info.Metric)
}
kv := metricsValues.Values.Values[l-2]
sTime = endTime.Add(time.Minute * time.Duration(-1))
if kv.Value > 0 {
sValue = kv.Value
}
if sValue == 0 {
sTime = endTime
}
klog.V(4).Infof("metric value: %d, timestamp: %s", sValue, sTime.Format(stepMinute))
return &external_metrics.ExternalMetricValueList{
Items: []external_metrics.ExternalMetricValue{
{
MetricName: info.Metric,
Timestamp: metav1.Time{
Time: sTime,
},
Value: *resource.NewQuantity(sValue, resource.DecimalSI),
},
},
}, nil
}