podlabelmetrics.go 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111
  1. package metrics
  2. import (
  3. "maps"
  4. "github.com/opencost/opencost/core/pkg/clustercache"
  5. "github.com/opencost/opencost/core/pkg/util/promutil"
  6. "github.com/prometheus/client_golang/prometheus"
  7. )
  8. //--------------------------------------------------------------------------
  9. // KubePodLabelsCollector
  10. //--------------------------------------------------------------------------
  11. // KubePodLabelsCollector is a prometheus collector that emits pod labels only
  12. type KubePodLabelsCollector struct {
  13. KubeClusterCache clustercache.ClusterCache
  14. metricsConfig MetricsConfig
  15. labelsWhitelist map[string]bool
  16. }
  17. func (kpmc *KubePodLabelsCollector) SetLabelsWhiteList() {
  18. kpmc.labelsWhitelist = make(map[string]bool)
  19. for k, v := range kpmc.metricsConfig.LabelsWhitelist {
  20. kpmc.labelsWhitelist[k] = v
  21. }
  22. }
  23. // Describe sends the super-set of all possible descriptors of pod labels only
  24. // collected by this Collector.
  25. func (kpmc KubePodLabelsCollector) Describe(ch chan<- *prometheus.Desc) {
  26. disabledMetrics := kpmc.metricsConfig.GetDisabledMetricsMap()
  27. if _, disabled := disabledMetrics["kube_pod_labels"]; !disabled {
  28. ch <- prometheus.NewDesc("kube_pod_labels", "All labels for each pod prefixed with label_", []string{}, nil)
  29. }
  30. if _, disabled := disabledMetrics["kube_pod_owner"]; !disabled {
  31. ch <- prometheus.NewDesc("kube_pod_owner", "Information about the Pod's owner", []string{}, nil)
  32. }
  33. }
  34. func (kpmc *KubePodLabelsCollector) UpdateControllerSelectorsCache() {
  35. for _, r := range kpmc.KubeClusterCache.GetAllReplicaSets() {
  36. for k := range r.SpecSelector.MatchLabels {
  37. kpmc.labelsWhitelist[k] = true
  38. }
  39. for _, v := range r.SpecSelector.MatchExpressions {
  40. kpmc.labelsWhitelist[v.Key] = true
  41. }
  42. }
  43. for _, ss := range kpmc.KubeClusterCache.GetAllStatefulSets() {
  44. for k := range ss.SpecSelector.MatchLabels {
  45. kpmc.labelsWhitelist[k] = true
  46. }
  47. for _, v := range ss.SpecSelector.MatchExpressions {
  48. kpmc.labelsWhitelist[v.Key] = true
  49. }
  50. }
  51. }
  52. func (kpmc *KubePodLabelsCollector) UpdateServiceLabels() {
  53. for _, service := range kpmc.KubeClusterCache.GetAllServices() {
  54. // Just unroll the selector and keep all labels whose keys could match a service selector
  55. for k := range service.SpecSelector {
  56. kpmc.labelsWhitelist[k] = true
  57. }
  58. }
  59. }
  60. func (kpmc *KubePodLabelsCollector) UpdateWhitelist() {
  61. kpmc.SetLabelsWhiteList()
  62. kpmc.UpdateControllerSelectorsCache()
  63. kpmc.UpdateServiceLabels()
  64. }
  65. // Collect is called by the Prometheus registry when collecting metrics.
  66. func (kpmc KubePodLabelsCollector) Collect(ch chan<- prometheus.Metric) {
  67. pods := kpmc.KubeClusterCache.GetAllPods()
  68. disabledMetrics := kpmc.metricsConfig.GetDisabledMetricsMap()
  69. for _, pod := range pods {
  70. podName := pod.Name
  71. podNS := pod.Namespace
  72. podUID := string(pod.UID)
  73. // Pod Labels
  74. if _, disabled := disabledMetrics["kube_pod_labels"]; !disabled {
  75. podLabels := pod.Labels
  76. if kpmc.metricsConfig.UseLabelsWhitelist {
  77. // only clone the map if we need to remove labels
  78. podLabels = maps.Clone(pod.Labels)
  79. kpmc.UpdateWhitelist()
  80. for lname := range pod.Labels {
  81. if _, ok := kpmc.labelsWhitelist[lname]; !ok {
  82. delete(podLabels, lname)
  83. }
  84. }
  85. }
  86. labelNames, labelValues := promutil.KubePrependQualifierToLabels(promutil.SanitizeLabels(podLabels), "label_")
  87. ch <- newKubePodLabelsMetric("kube_pod_labels", podNS, podName, podUID, labelNames, labelValues)
  88. }
  89. // Owner References
  90. if _, disabled := disabledMetrics["kube_pod_owner"]; !disabled {
  91. for _, owner := range pod.OwnerReferences {
  92. ch <- newKubePodOwnerMetric("kube_pod_owner", podNS, podName, podUID, owner.Name, owner.Kind, owner.Controller != nil)
  93. }
  94. }
  95. }
  96. }