Skip to content

Commit a56a065

Browse files
committed
Added syncer for steal time metric and started implementing feature extractor for it
1 parent 180b56d commit a56a065

File tree

7 files changed

+104
-0
lines changed

7 files changed

+104
-0
lines changed

helm/bundles/cortex-nova/values.yaml

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,9 @@ cortex-core:
113113
(sum by (node) (node_memory_MemTotal_bytes) / count by (node) (node_memory_MemTotal_bytes))
114114
)) * 100
115115
type: node_exporter_metric
116+
- alias: kvm_libvirt_domain_steal_time
117+
query: rate(kvm_libvirt_domain_steal_time[1m])
118+
type: kvm_cpu_steal_time_metric
116119

117120
openstack:
118121
nova:
@@ -195,6 +198,16 @@ cortex-core:
195198
- alias: vrops_hostsystem_cpu_contention_short_term_percentage
196199

197200
# KVM-specific extractors.
201+
- name: libvirt_domain_cpu_steal_time_extractor
202+
dependencies:
203+
sync:
204+
prometheus:
205+
metrics:
206+
- alias: kvm_libvirt_domain_steal_time
207+
openstack:
208+
nova:
209+
types:
210+
- servers
198211
- name: node_exporter_host_cpu_usage_extractor
199212
dependencies:
200213
sync:

helm/library/cortex-core/templates/alerts.yaml

Whitespace-only changes.

internal/extractor/pipeline.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ var SupportedExtractors = []plugins.FeatureExtractor{
3131
// KVM-specific extractors
3232
&kvm.NodeExporterHostCPUUsageExtractor{},
3333
&kvm.NodeExporterHostMemoryActiveExtractor{},
34+
&kvm.LibvirtDomainCPUStealTimeExtractor{},
3435
// NetApp-specific extractors
3536
&netapp.StoragePoolCPUUsageExtractor{},
3637
// Shared extractors
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
// Copyright 2025 SAP SE
2+
// SPDX-License-Identifier: Apache-2.0
3+
4+
package kvm
5+
6+
import (
7+
_ "embed"
8+
9+
"github.com/cobaltcore-dev/cortex/internal/db"
10+
"github.com/cobaltcore-dev/cortex/internal/extractor/plugins"
11+
"github.com/cobaltcore-dev/cortex/internal/sync/prometheus"
12+
)
13+
14+
// Feature that maps CPU steal time of kvm hosts.
15+
type LibvirtDomainCPUStealTime struct {
16+
Instance string
17+
}
18+
19+
// Table under which the feature is stored.
20+
func (LibvirtDomainCPUStealTime) TableName() string {
21+
return "feature_libvirt_domain_cpu_steal_time"
22+
}
23+
24+
// Indexes for the feature.
25+
func (LibvirtDomainCPUStealTime) Indexes() []db.Index {
26+
return nil
27+
}
28+
29+
// Extractor that extracts CPU steal time
30+
type LibvirtDomainCPUStealTimeExtractor struct {
31+
// Common base for all extractors that provides standard functionality.
32+
plugins.BaseExtractor[
33+
struct{}, // No options passed through yaml config
34+
LibvirtDomainCPUStealTime, // Feature model
35+
]
36+
}
37+
38+
// Name of this feature extractor that is used in the yaml config, for logging etc.
39+
func (*LibvirtDomainCPUStealTimeExtractor) GetName() string {
40+
return "libvirt_domain_cpu_steal_time_extractor"
41+
}
42+
43+
// Get message topics that trigger a re-execution of this extractor.
44+
func (LibvirtDomainCPUStealTimeExtractor) Triggers() []string {
45+
return []string{
46+
prometheus.TriggerMetricAliasSynced("kvm_libvirt_domain_steal_time"),
47+
}
48+
}
49+
50+
//go:embed cpu_steal_time.sql
51+
var cpuStealTimeSQL string
52+
53+
// Extract CPU steal time of kvm hosts.
54+
func (e *LibvirtDomainCPUStealTimeExtractor) Extract() ([]plugins.Feature, error) {
55+
return e.ExtractSQL(cpuStealTimeSQL)
56+
}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
SELECT * FROM (
2+
SELECT *,
3+
ROW_NUMBER() OVER (PARTITION BY os.id ORDER BY kvm.timestamp DESC) as rn
4+
FROM kvm_cpu_steal_time_metrics kvm
5+
LEFT JOIN openstack_servers os ON os.os_ext_srv_attr_instance_name = kvm.domain
6+
) ranked
7+
WHERE rn = 1 AND os.id IS NOT NULL;

internal/sync/prometheus/sync.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ var SupportedSyncers = map[string]syncerFunc{
3333
"netapp_aggregate_labels_metric": newSyncerOfType[NetAppAggregateLabelsMetric],
3434
"netapp_node_metric": newSyncerOfType[NetAppNodeMetric],
3535
"netapp_volume_aggregate_labels_metric": newSyncerOfType[NetAppVolumeAggrLabelsMetric],
36+
"kvm_cpu_steal_time_metric": newSyncerOfType[KVMCPUStealTimeMetric],
3637
}
3738

3839
// Syncer that syncs all configured metrics.

internal/sync/prometheus/types.go

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -266,3 +266,29 @@ func (m NetAppVolumeAggrLabelsMetric) With(n string, t time.Time, v float64) Pro
266266
m.Value = v
267267
return m
268268
}
269+
270+
type KVMCPUStealTimeMetric struct {
271+
// The name of the metric.
272+
Name string `db:"name"`
273+
Instance string `json:"instance" db:"instance"`
274+
Domain string `json:"domain" db:"domain"`
275+
Node string `json:"node" db:"node"`
276+
// Timestamp of the metric value.
277+
Timestamp time.Time `json:"timestamp" db:"timestamp"`
278+
// The value of the metric (usually 1 for label metrics).
279+
Value float64 `json:"value" db:"value"`
280+
}
281+
282+
func (m KVMCPUStealTimeMetric) TableName() string {
283+
return "kvm_cpu_steal_time_metrics"
284+
}
285+
func (m KVMCPUStealTimeMetric) Indexes() []db.Index { return nil }
286+
func (m KVMCPUStealTimeMetric) GetName() string { return m.Name }
287+
func (m KVMCPUStealTimeMetric) GetTimestamp() time.Time { return m.Timestamp }
288+
func (m KVMCPUStealTimeMetric) GetValue() float64 { return m.Value }
289+
func (m KVMCPUStealTimeMetric) With(n string, t time.Time, v float64) PrometheusMetric {
290+
m.Name = n
291+
m.Timestamp = t
292+
m.Value = v
293+
return m
294+
}

0 commit comments

Comments
 (0)