namespacemetrics.go 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221
  1. package metrics
  2. import (
  3. "github.com/opencost/opencost/core/pkg/clustercache"
  4. "github.com/opencost/opencost/core/pkg/util/promutil"
  5. "github.com/prometheus/client_golang/prometheus"
  6. dto "github.com/prometheus/client_model/go"
  7. )
  8. //--------------------------------------------------------------------------
  9. // KubecostNamespaceCollector
  10. //--------------------------------------------------------------------------
  11. // KubecostNamespaceCollector is a prometheus collector that generates namespace sourced metrics
  12. type KubecostNamespaceCollector struct {
  13. KubeClusterCache clustercache.ClusterCache
  14. metricsConfig MetricsConfig
  15. }
  16. // Describe sends the super-set of all possible descriptors of metrics
  17. // collected by this Collector.
  18. func (nsac KubecostNamespaceCollector) Describe(ch chan<- *prometheus.Desc) {
  19. disabledMetrics := nsac.metricsConfig.GetDisabledMetricsMap()
  20. if _, disabled := disabledMetrics["kube_namespace_annotations"]; disabled {
  21. return
  22. }
  23. ch <- prometheus.NewDesc("kube_namespace_annotations", "namespace annotations", []string{}, nil)
  24. }
  25. // Collect is called by the Prometheus registry when collecting metrics.
  26. func (nsac KubecostNamespaceCollector) Collect(ch chan<- prometheus.Metric) {
  27. disabledMetrics := nsac.metricsConfig.GetDisabledMetricsMap()
  28. if _, disabled := disabledMetrics["kube_namespace_annotations"]; disabled {
  29. return
  30. }
  31. namespaces := nsac.KubeClusterCache.GetAllNamespaces()
  32. for _, namespace := range namespaces {
  33. nsName := namespace.Name
  34. nsUID := string(namespace.UID)
  35. labels, values := promutil.KubeAnnotationsToLabels(namespace.Annotations)
  36. if len(labels) > 0 {
  37. m := newNamespaceAnnotationsMetric("kube_namespace_annotations", nsName, nsUID, labels, values)
  38. ch <- m
  39. }
  40. }
  41. }
  42. //--------------------------------------------------------------------------
  43. // NamespaceAnnotationsMetric
  44. //--------------------------------------------------------------------------
  45. // NamespaceAnnotationsMetric is a prometheus.Metric used to encode namespace annotations
  46. type NamespaceAnnotationsMetric struct {
  47. fqName string
  48. help string
  49. namespace string
  50. uid string
  51. labelNames []string
  52. labelValues []string
  53. }
  54. // Creates a new NamespaceAnnotationsMetric, implementation of prometheus.Metric
  55. func newNamespaceAnnotationsMetric(fqname, namespace string, uid string, labelNames []string, labelValues []string) NamespaceAnnotationsMetric {
  56. return NamespaceAnnotationsMetric{
  57. fqName: fqname,
  58. help: "kube_namespace_annotations Namespace Annotations",
  59. namespace: namespace,
  60. uid: uid,
  61. labelNames: labelNames,
  62. labelValues: labelValues,
  63. }
  64. }
  65. // Desc returns the descriptor for the Metric. This method idempotently
  66. // returns the same descriptor throughout the lifetime of the Metric.
  67. func (nam NamespaceAnnotationsMetric) Desc() *prometheus.Desc {
  68. l := prometheus.Labels{
  69. "namespace": nam.namespace,
  70. "uid": nam.uid,
  71. }
  72. return prometheus.NewDesc(nam.fqName, nam.help, []string{}, l)
  73. }
  74. // Write encodes the Metric into a "Metric" Protocol Buffer data
  75. // transmission object.
  76. func (nam NamespaceAnnotationsMetric) Write(m *dto.Metric) error {
  77. h := float64(1)
  78. m.Gauge = &dto.Gauge{
  79. Value: &h,
  80. }
  81. var labels []*dto.LabelPair
  82. for i := range nam.labelNames {
  83. labels = append(labels, &dto.LabelPair{
  84. Name: &nam.labelNames[i],
  85. Value: &nam.labelValues[i],
  86. })
  87. }
  88. labels = append(labels,
  89. &dto.LabelPair{
  90. Name: toStringPtr("namespace"),
  91. Value: &nam.namespace,
  92. },
  93. &dto.LabelPair{
  94. Name: toStringPtr("uid"),
  95. Value: &nam.uid,
  96. })
  97. m.Label = labels
  98. return nil
  99. }
  100. //--------------------------------------------------------------------------
  101. // KubeNamespaceCollector
  102. //--------------------------------------------------------------------------
  103. // KubeNamespaceCollector is a prometheus collector that generates namespace sourced metrics
  104. type KubeNamespaceCollector struct {
  105. KubeClusterCache clustercache.ClusterCache
  106. metricsConfig MetricsConfig
  107. }
  108. // Describe sends the super-set of all possible descriptors of metrics
  109. // collected by this Collector.
  110. func (nsac KubeNamespaceCollector) Describe(ch chan<- *prometheus.Desc) {
  111. disabledMetrics := nsac.metricsConfig.GetDisabledMetricsMap()
  112. if _, disabled := disabledMetrics["kube_namespace_labels"]; disabled {
  113. return
  114. }
  115. ch <- prometheus.NewDesc("kube_namespace_labels", "namespace labels", []string{}, nil)
  116. }
  117. // Collect is called by the Prometheus registry when collecting metrics.
  118. func (nsac KubeNamespaceCollector) Collect(ch chan<- prometheus.Metric) {
  119. disabledMetrics := nsac.metricsConfig.GetDisabledMetricsMap()
  120. if _, disabled := disabledMetrics["kube_namespace_labels"]; disabled {
  121. return
  122. }
  123. namespaces := nsac.KubeClusterCache.GetAllNamespaces()
  124. for _, namespace := range namespaces {
  125. nsName := namespace.Name
  126. nsUID := string(namespace.UID)
  127. labels, values := promutil.KubeLabelsToLabels(promutil.SanitizeLabels(namespace.Labels))
  128. if len(labels) > 0 {
  129. m := newKubeNamespaceLabelsMetric("kube_namespace_labels", nsName, nsUID, labels, values)
  130. ch <- m
  131. }
  132. }
  133. }
  134. //--------------------------------------------------------------------------
  135. // NamespaceAnnotationsMetric
  136. //--------------------------------------------------------------------------
  137. // NamespaceAnnotationsMetric is a prometheus.Metric used to encode namespace annotations
  138. type KubeNamespaceLabelsMetric struct {
  139. fqName string
  140. help string
  141. namespace string
  142. uid string
  143. labelNames []string
  144. labelValues []string
  145. }
  146. // Creates a new KubeNamespaceLabelsMetric, implementation of prometheus.Metric
  147. func newKubeNamespaceLabelsMetric(fqname, namespace string, uid string, labelNames []string, labelValues []string) KubeNamespaceLabelsMetric {
  148. return KubeNamespaceLabelsMetric{
  149. namespace: namespace,
  150. uid: uid,
  151. fqName: fqname,
  152. labelNames: labelNames,
  153. labelValues: labelValues,
  154. help: "kube_namespace_labels Namespace Labels",
  155. }
  156. }
  157. // Desc returns the descriptor for the Metric. This method idempotently
  158. // returns the same descriptor throughout the lifetime of the Metric.
  159. func (nam KubeNamespaceLabelsMetric) Desc() *prometheus.Desc {
  160. l := prometheus.Labels{
  161. "namespace": nam.namespace,
  162. }
  163. return prometheus.NewDesc(nam.fqName, nam.help, []string{}, l)
  164. }
  165. // Write encodes the Metric into a "Metric" Protocol Buffer data transmission object.
  166. func (nam KubeNamespaceLabelsMetric) Write(m *dto.Metric) error {
  167. h := float64(1)
  168. m.Gauge = &dto.Gauge{
  169. Value: &h,
  170. }
  171. var labels []*dto.LabelPair
  172. for i := range nam.labelNames {
  173. labels = append(labels, &dto.LabelPair{
  174. Name: &nam.labelNames[i],
  175. Value: &nam.labelValues[i],
  176. })
  177. }
  178. labels = append(labels,
  179. &dto.LabelPair{
  180. Name: toStringPtr("namespace"),
  181. Value: &nam.namespace,
  182. },
  183. &dto.LabelPair{
  184. Name: toStringPtr("uid"),
  185. Value: &nam.uid,
  186. })
  187. m.Label = labels
  188. return nil
  189. }