collector.go 7.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151
  1. package metric
  2. import (
  3. "maps"
  4. "time"
  5. "github.com/opencost/opencost/modules/collector-source/pkg/metric/aggregator"
  6. "github.com/opencost/opencost/modules/collector-source/pkg/util"
  7. )
  8. // MetricCollectorID is a unique identifier for a specific metric collector instance. We
  9. // use this identifier to register and unregister metric instances from the metrics metric
  10. // instead of the metric name and aggregation type to allow selectable cardinality (via Labels)
  11. // across multiple instances of the same aggregation type and metric name.
  12. type MetricCollectorID string
  13. const (
  14. PVPricePerGiBHourID MetricCollectorID = "PVPricePerGiBHour"
  15. PVUsedAverageID MetricCollectorID = "PVUsedAverage"
  16. PVUsedMaxID MetricCollectorID = "PVUsedMax"
  17. PVCInfoID MetricCollectorID = "PVCInfo"
  18. PVActiveMinutesID MetricCollectorID = "PVActiveMinutes"
  19. LocalStorageUsedActiveMinutesID MetricCollectorID = "LocalStorageUsedCost"
  20. LocalStorageUsedAverageID MetricCollectorID = "LocalStorageUsedAverage"
  21. LocalStorageUsedMaxID MetricCollectorID = "LocalStorageUsedMax"
  22. LocalStorageBytesID MetricCollectorID = "LocalStorageBytesID"
  23. LocalStorageActiveMinutesID MetricCollectorID = "LocalStorageActiveMinutes"
  24. NodeCPUCoresCapacityID MetricCollectorID = "NodeCPUCoresCapacity"
  25. NodeCPUCoresAllocatableID MetricCollectorID = "NodeCPUCoresAllocatable"
  26. NodeRAMBytesCapacityID MetricCollectorID = "NodeRAMBytesCapacity"
  27. NodeRAMBytesAllocatableID MetricCollectorID = "NodeRAMBytesAllocatable"
  28. NodeGPUCountID MetricCollectorID = "NodeGPUCount"
  29. NodeLabelsID MetricCollectorID = "NodeLabels"
  30. NodeActiveMinutesID MetricCollectorID = "NodeActiveMinutes"
  31. NodeCPUModeTotalID MetricCollectorID = "NodeCPUModeTotal"
  32. NodeRAMSystemUsageAverageID MetricCollectorID = "NodeRAMSystemUsageAverage"
  33. NodeRAMUserUsageAverageID MetricCollectorID = "NodeRAMUserUsageAverage"
  34. LBPricePerHourID MetricCollectorID = "LBPricePerHour"
  35. LBActiveMinutesID MetricCollectorID = "LBActiveMinutes"
  36. ClusterManagementDurationID MetricCollectorID = "ClusterManagementDuration"
  37. ClusterManagementPricePerHourID MetricCollectorID = "ClusterManagementPricePerHour"
  38. PodActiveMinutesID MetricCollectorID = "PodActiveMinutes"
  39. RAMBytesAllocatedID MetricCollectorID = "RAMBytesAllocated"
  40. RAMRequestsID MetricCollectorID = "RAMRequests"
  41. RAMUsageAverageID MetricCollectorID = "RAMUsageAverage"
  42. RAMUsageMaxID MetricCollectorID = "RAMUsageMax"
  43. CPUCoresAllocatedID MetricCollectorID = "CPUCoresAllocated"
  44. CPURequestsID MetricCollectorID = "CPURequestsID"
  45. CPUUsageAverageID MetricCollectorID = "CPUUsageAverage"
  46. CPUUsageMaxID MetricCollectorID = "CPUUsageMax"
  47. GPUsRequestedID MetricCollectorID = "GPUsRequested"
  48. GPUsUsageAverageID MetricCollectorID = "GPUsUsageAverage"
  49. GPUsUsageMaxID MetricCollectorID = "GPUsUsageMax"
  50. GPUsAllocatedID MetricCollectorID = "GPUsAllocated"
  51. IsGPUSharedID MetricCollectorID = "IsGPUShared"
  52. GPUInfoID MetricCollectorID = "GPUInfo"
  53. NodeCPUPricePerHourID MetricCollectorID = "NodeCPUPricePerHour"
  54. NodeRAMPricePerGiBHourID MetricCollectorID = "NodeRAMPricePerGiBHour"
  55. NodeGPUPricePerHourID MetricCollectorID = "NodeGPUPricePerHour"
  56. NodeIsSpotID MetricCollectorID = "NodeIsSpot"
  57. PodPVCAllocationID MetricCollectorID = "PodPVCAllocation"
  58. PVCBytesRequestedID MetricCollectorID = "PVCBytesRequested"
  59. PVBytesID MetricCollectorID = "PVBytesID"
  60. PVInfoID MetricCollectorID = "PVInfo"
  61. NetZoneGiBID MetricCollectorID = "NetZoneGiB"
  62. NetZonePricePerGiBID MetricCollectorID = "NetZonePricePerGiB"
  63. NetRegionGiBID MetricCollectorID = "NetRegionGiB"
  64. NetRegionPricePerGiBID MetricCollectorID = "NetRegionPricePerGiB"
  65. NetInternetGiBID MetricCollectorID = "NetInternetGiB"
  66. NetInternetPricePerGiBID MetricCollectorID = "NetInternetPricePerGiB"
  67. NetInternetServiceGiBID MetricCollectorID = "NetInternetServiceGiB"
  68. NetTransferBytesID MetricCollectorID = "NetTransferBytes"
  69. NetZoneIngressGiBID MetricCollectorID = "NetZoneIngressGiB"
  70. NetRegionIngressGiBID MetricCollectorID = "NetRegionIngressGiB"
  71. NetInternetIngressGiBID MetricCollectorID = "NetInternetIngressGiB"
  72. NetInternetServiceIngressGiBID MetricCollectorID = "NetInternetServiceIngressGiB"
  73. NetReceiveBytesID MetricCollectorID = "NetReceiveBytes"
  74. NamespaceLabelsID MetricCollectorID = "NamespaceLabels"
  75. NamespaceAnnotationsID MetricCollectorID = "NamespaceAnnotations"
  76. PodLabelsID MetricCollectorID = "PodLabels"
  77. PodAnnotationsID MetricCollectorID = "PodAnnotations"
  78. ServiceLabelsID MetricCollectorID = "ServiceLabels"
  79. DeploymentLabelsID MetricCollectorID = "DeploymentLabels"
  80. StatefulSetLabelsID MetricCollectorID = "StatefulSetLabels"
  81. DaemonSetLabelsID MetricCollectorID = "DaemonSetLabels"
  82. JobLabelsID MetricCollectorID = "JobLabels"
  83. PodsWithReplicaSetOwnerID MetricCollectorID = "PodsWithReplicaSetOwner"
  84. ReplicaSetsWithoutOwnersID MetricCollectorID = "ReplicaSetsWithoutOwners"
  85. ReplicaSetsWithRolloutID MetricCollectorID = "ReplicaSetsWithRollout"
  86. )
  87. // MetricCollector is a data structure that represents a specific MetricCollector metric instance that contains its own breakdown
  88. // of stored metrics by a specific label set.
  89. type MetricCollector struct {
  90. id MetricCollectorID // ie: RAMUsageAverage
  91. metricName string // ie: container_memory_working_set_bytes
  92. labels []string
  93. aggregatorFactory aggregator.MetricAggregatorFactory
  94. metrics map[uint64]aggregator.MetricAggregator // map[Hash(labelValues)] = aggregator
  95. filter func(map[string]string) bool
  96. }
  97. // NewMetricCollector creates a new MetricCollector instance with a unique identifier. The metric name is the specific
  98. // name of the collected metric that will be used to query the
  99. func NewMetricCollector(id MetricCollectorID, metricName string, labels []string, aggregatorFactory aggregator.MetricAggregatorFactory, fn func(map[string]string) bool) *MetricCollector {
  100. return &MetricCollector{
  101. id: id,
  102. metricName: metricName,
  103. labels: labels,
  104. aggregatorFactory: aggregatorFactory,
  105. metrics: make(map[uint64]aggregator.MetricAggregator),
  106. filter: fn,
  107. }
  108. }
  109. func (mi *MetricCollector) Update(labels map[string]string, value float64, timestamp time.Time, additionalInfo map[string]string) {
  110. if mi.filter != nil && !mi.filter(labels) {
  111. return
  112. }
  113. labelValues := make([]string, len(mi.labels))
  114. for i, key := range mi.labels {
  115. labelValues[i] = labels[key]
  116. }
  117. key := util.Hash(labelValues)
  118. if mi.metrics[key] == nil {
  119. mi.metrics[key] = mi.aggregatorFactory(labelValues)
  120. }
  121. mi.metrics[key].Update(value, timestamp, additionalInfo)
  122. }
  123. func (mi *MetricCollector) Get() []*aggregator.MetricResult {
  124. results := make([]*aggregator.MetricResult, 0, len(mi.metrics))
  125. for _, metric := range mi.metrics {
  126. labels := util.ToMap(mi.labels, metric.LabelValues())
  127. maps.Copy(labels, metric.AdditionInfo())
  128. mr := &aggregator.MetricResult{
  129. MetricLabels: labels,
  130. Values: metric.Value(),
  131. }
  132. results = append(results, mr)
  133. }
  134. return results
  135. }
  136. func (mi *MetricCollector) Labels() []string {
  137. return mi.labels
  138. }