collector.go 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172
  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. ClusterUptimeID MetricCollectorID = "ClusterUptime"
  37. ClusterManagementDurationID MetricCollectorID = "ClusterManagementDuration"
  38. ClusterManagementPricePerHourID MetricCollectorID = "ClusterManagementPricePerHour"
  39. PodActiveMinutesID MetricCollectorID = "PodActiveMinutes"
  40. RAMBytesAllocatedID MetricCollectorID = "RAMBytesAllocated"
  41. RAMRequestsID MetricCollectorID = "RAMRequests"
  42. RAMLimitsID MetricCollectorID = "RAMLimits"
  43. RAMUsageAverageID MetricCollectorID = "RAMUsageAverage"
  44. RAMUsageMaxID MetricCollectorID = "RAMUsageMax"
  45. CPUCoresAllocatedID MetricCollectorID = "CPUCoresAllocated"
  46. CPURequestsID MetricCollectorID = "CPURequestsID"
  47. CPULimitsID MetricCollectorID = "CPULimitsID"
  48. CPUUsageAverageID MetricCollectorID = "CPUUsageAverage"
  49. CPUUsageMaxID MetricCollectorID = "CPUUsageMax"
  50. GPUsRequestedID MetricCollectorID = "GPUsRequested"
  51. GPUsUsageAverageID MetricCollectorID = "GPUsUsageAverage"
  52. GPUsUsageMaxID MetricCollectorID = "GPUsUsageMax"
  53. GPUsAllocatedID MetricCollectorID = "GPUsAllocated"
  54. IsGPUSharedID MetricCollectorID = "IsGPUShared"
  55. GPUInfoID MetricCollectorID = "GPUInfo"
  56. NodeCPUPricePerHourID MetricCollectorID = "NodeCPUPricePerHour"
  57. NodeRAMPricePerGiBHourID MetricCollectorID = "NodeRAMPricePerGiBHour"
  58. NodeGPUPricePerHourID MetricCollectorID = "NodeGPUPricePerHour"
  59. NodeIsSpotID MetricCollectorID = "NodeIsSpot"
  60. PodPVCAllocationID MetricCollectorID = "PodPVCAllocation"
  61. PVCBytesRequestedID MetricCollectorID = "PVCBytesRequested"
  62. PVBytesID MetricCollectorID = "PVBytesID"
  63. PVInfoID MetricCollectorID = "PVInfo"
  64. NetZoneGiBID MetricCollectorID = "NetZoneGiB"
  65. NetZonePricePerGiBID MetricCollectorID = "NetZonePricePerGiB"
  66. NetRegionGiBID MetricCollectorID = "NetRegionGiB"
  67. NetRegionPricePerGiBID MetricCollectorID = "NetRegionPricePerGiB"
  68. NetInternetGiBID MetricCollectorID = "NetInternetGiB"
  69. NetInternetPricePerGiBID MetricCollectorID = "NetInternetPricePerGiB"
  70. NetInternetServiceGiBID MetricCollectorID = "NetInternetServiceGiB"
  71. NetTransferBytesID MetricCollectorID = "NetTransferBytes"
  72. NetZoneIngressGiBID MetricCollectorID = "NetZoneIngressGiB"
  73. NetRegionIngressGiBID MetricCollectorID = "NetRegionIngressGiB"
  74. NetInternetIngressGiBID MetricCollectorID = "NetInternetIngressGiB"
  75. NetInternetServiceIngressGiBID MetricCollectorID = "NetInternetServiceIngressGiB"
  76. NetReceiveBytesID MetricCollectorID = "NetReceiveBytes"
  77. NamespaceUptimeID MetricCollectorID = "NamespaceUptime"
  78. NamespaceLabelsID MetricCollectorID = "NamespaceLabels"
  79. NamespaceAnnotationsID MetricCollectorID = "NamespaceAnnotations"
  80. PodLabelsID MetricCollectorID = "PodLabels"
  81. PodAnnotationsID MetricCollectorID = "PodAnnotations"
  82. ServiceLabelsID MetricCollectorID = "ServiceLabels"
  83. DeploymentLabelsID MetricCollectorID = "DeploymentLabels"
  84. StatefulSetLabelsID MetricCollectorID = "StatefulSetLabels"
  85. DaemonSetLabelsID MetricCollectorID = "DaemonSetLabels"
  86. JobLabelsID MetricCollectorID = "JobLabels"
  87. PodsWithReplicaSetOwnerID MetricCollectorID = "PodsWithReplicaSetOwner"
  88. ReplicaSetsWithoutOwnersID MetricCollectorID = "ReplicaSetsWithoutOwners"
  89. ReplicaSetsWithRolloutID MetricCollectorID = "ReplicaSetsWithRollout"
  90. ResourceQuotaUptimeID MetricCollectorID = "ResourceQuotaUptime"
  91. ResourceQuotaSpecCPURequestAverageID MetricCollectorID = "ResourceQuotaSpecCPURequestAverage"
  92. ResourceQuotaSpecCPURequestMaxID MetricCollectorID = "ResourceQuotaSpecCPURequestMax"
  93. ResourceQuotaSpecRAMRequestAverageID MetricCollectorID = "ResourceQuotaSpecRAMRequestAverage"
  94. ResourceQuotaSpecRAMRequestMaxID MetricCollectorID = "ResourceQuotaSpecRAMRequestMax"
  95. ResourceQuotaSpecCPULimitAverageID MetricCollectorID = "ResourceQuotaSpecCPULimitAverage"
  96. ResourceQuotaSpecCPULimitMaxID MetricCollectorID = "ResourceQuotaSpecCPULimitMax"
  97. ResourceQuotaSpecRAMLimitAverageID MetricCollectorID = "ResourceQuotaSpecRAMLimitAverage"
  98. ResourceQuotaSpecRAMLimitMaxID MetricCollectorID = "ResourceQuotaSpecRAMLimitMax"
  99. ResourceQuotaStatusUsedCPURequestAverageID MetricCollectorID = "ResourceQuotaStatusUsedCPURequestAverage"
  100. ResourceQuotaStatusUsedCPURequestMaxID MetricCollectorID = "ResourceQuotaStatusUsedCPURequestMax"
  101. ResourceQuotaStatusUsedRAMRequestAverageID MetricCollectorID = "ResourceQuotaStatusUsedRAMRequestAverage"
  102. ResourceQuotaStatusUsedRAMRequestMaxID MetricCollectorID = "ResourceQuotaStatusUsedRAMRequestMax"
  103. ResourceQuotaStatusUsedCPULimitAverageID MetricCollectorID = "ResourceQuotaStatusUsedCPULimitAverage"
  104. ResourceQuotaStatusUsedCPULimitMaxID MetricCollectorID = "ResourceQuotaStatusUsedCPULimitMax"
  105. ResourceQuotaStatusUsedRAMLimitAverageID MetricCollectorID = "ResourceQuotaStatusUsedRAMLimitAverage"
  106. ResourceQuotaStatusUsedRAMLimitMaxID MetricCollectorID = "ResourceQuotaStatusUsedRAMLimitMax"
  107. )
  108. // MetricCollector is a data structure that represents a specific MetricCollector metric instance that contains its own breakdown
  109. // of stored metrics by a specific label set.
  110. type MetricCollector struct {
  111. id MetricCollectorID // ie: RAMUsageAverage
  112. metricName string // ie: container_memory_working_set_bytes
  113. labels []string
  114. aggregatorFactory aggregator.MetricAggregatorFactory
  115. metrics map[uint64]aggregator.MetricAggregator // map[Hash(labelValues)] = aggregator
  116. filter func(map[string]string) bool
  117. }
  118. // NewMetricCollector creates a new MetricCollector instance with a unique identifier. The metric name is the specific
  119. // name of the collected metric that will be used to query the
  120. func NewMetricCollector(id MetricCollectorID, metricName string, labels []string, aggregatorFactory aggregator.MetricAggregatorFactory, fn func(map[string]string) bool) *MetricCollector {
  121. return &MetricCollector{
  122. id: id,
  123. metricName: metricName,
  124. labels: labels,
  125. aggregatorFactory: aggregatorFactory,
  126. metrics: make(map[uint64]aggregator.MetricAggregator),
  127. filter: fn,
  128. }
  129. }
  130. func (mi *MetricCollector) Update(labels map[string]string, value float64, timestamp time.Time, additionalInfo map[string]string) {
  131. if mi.filter != nil && !mi.filter(labels) {
  132. return
  133. }
  134. labelValues := make([]string, len(mi.labels))
  135. for i, key := range mi.labels {
  136. labelValues[i] = labels[key]
  137. }
  138. key := util.Hash(labelValues)
  139. if mi.metrics[key] == nil {
  140. mi.metrics[key] = mi.aggregatorFactory(labelValues)
  141. }
  142. mi.metrics[key].Update(value, timestamp, additionalInfo)
  143. }
  144. func (mi *MetricCollector) Get() []*aggregator.MetricResult {
  145. results := make([]*aggregator.MetricResult, 0, len(mi.metrics))
  146. for _, metric := range mi.metrics {
  147. labels := util.ToMap(mi.labels, metric.LabelValues())
  148. maps.Copy(labels, metric.AdditionInfo())
  149. mr := &aggregator.MetricResult{
  150. MetricLabels: labels,
  151. Values: metric.Value(),
  152. }
  153. results = append(results, mr)
  154. }
  155. return results
  156. }
  157. func (mi *MetricCollector) Labels() []string {
  158. return mi.labels
  159. }