pvmetrics.go 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228
  1. package metrics
  2. import (
  3. "github.com/opencost/opencost/pkg/clustercache"
  4. "github.com/prometheus/client_golang/prometheus"
  5. dto "github.com/prometheus/client_model/go"
  6. v1 "k8s.io/api/core/v1"
  7. )
  8. //--------------------------------------------------------------------------
  9. // KubePVCollector
  10. //--------------------------------------------------------------------------
  11. // KubePVCollector is a prometheus collector that generates PV metrics
  12. type KubePVCollector 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 (kpvcb KubePVCollector) Describe(ch chan<- *prometheus.Desc) {
  19. disabledMetrics := kpvcb.metricsConfig.GetDisabledMetricsMap()
  20. if _, disabled := disabledMetrics["kube_persistentvolume_capacity_bytes"]; !disabled {
  21. ch <- prometheus.NewDesc("kube_persistentvolume_capacity_bytes", "The pv storage capacity in bytes", []string{}, nil)
  22. }
  23. if _, disabled := disabledMetrics["kube_persistentvolume_status_phase"]; !disabled {
  24. ch <- prometheus.NewDesc("kube_persistentvolume_status_phase", "The phase indicates if a volume is available, bound to a claim, or released by a claim.", []string{}, nil)
  25. }
  26. if _, disabled := disabledMetrics["kubecost_pv_info"]; !disabled {
  27. ch <- prometheus.NewDesc("kubecost_pv_info", "The pv information", []string{}, nil)
  28. }
  29. }
  30. // Collect is called by the Prometheus registry when collecting metrics.
  31. func (kpvcb KubePVCollector) Collect(ch chan<- prometheus.Metric) {
  32. pvs := kpvcb.KubeClusterCache.GetAllPersistentVolumes()
  33. disabledMetrics := kpvcb.metricsConfig.GetDisabledMetricsMap()
  34. for _, pv := range pvs {
  35. if _, disabled := disabledMetrics["kube_persistentvolume_status_phase"]; !disabled {
  36. phase := pv.Status.Phase
  37. if phase != "" {
  38. phases := []struct {
  39. v bool
  40. n string
  41. }{
  42. {phase == v1.VolumePending, string(v1.VolumePending)},
  43. {phase == v1.VolumeAvailable, string(v1.VolumeAvailable)},
  44. {phase == v1.VolumeBound, string(v1.VolumeBound)},
  45. {phase == v1.VolumeReleased, string(v1.VolumeReleased)},
  46. {phase == v1.VolumeFailed, string(v1.VolumeFailed)},
  47. }
  48. for _, p := range phases {
  49. ch <- newKubePVStatusPhaseMetric("kube_persistentvolume_status_phase", pv.Name, p.n, boolFloat64(p.v))
  50. }
  51. }
  52. }
  53. if _, disabled := disabledMetrics["kube_persistentvolume_capacity_bytes"]; !disabled {
  54. storage := pv.Spec.Capacity[v1.ResourceStorage]
  55. m := newKubePVCapacityBytesMetric("kube_persistentvolume_capacity_bytes", pv.Name, float64(storage.Value()))
  56. ch <- m
  57. }
  58. if _, disabled := disabledMetrics["kubecost_pv_info"]; !disabled {
  59. storageClass := pv.Spec.StorageClassName
  60. m := newKubecostPVInfoMetric("kubecost_pv_info", pv.Name, storageClass, float64(1))
  61. ch <- m
  62. }
  63. }
  64. }
  65. //--------------------------------------------------------------------------
  66. // KubePVCapacityBytesMetric
  67. //--------------------------------------------------------------------------
  68. // KubePVCapacityBytesMetric is a prometheus.Metric
  69. type KubePVCapacityBytesMetric struct {
  70. fqName string
  71. help string
  72. pv string
  73. value float64
  74. }
  75. // Creates a new KubePVCapacityBytesMetric, implementation of prometheus.Metric
  76. func newKubePVCapacityBytesMetric(fqname, pv string, value float64) KubePVCapacityBytesMetric {
  77. return KubePVCapacityBytesMetric{
  78. fqName: fqname,
  79. help: "kube_persistentvolume_capacity_bytes pv storage capacity in bytes",
  80. pv: pv,
  81. value: value,
  82. }
  83. }
  84. // Desc returns the descriptor for the Metric. This method idempotently
  85. // returns the same descriptor throughout the lifetime of the Metric.
  86. func (kpcrr KubePVCapacityBytesMetric) Desc() *prometheus.Desc {
  87. l := prometheus.Labels{
  88. "persistentvolume": kpcrr.pv,
  89. }
  90. return prometheus.NewDesc(kpcrr.fqName, kpcrr.help, []string{}, l)
  91. }
  92. // Write encodes the Metric into a "Metric" Protocol Buffer data
  93. // transmission object.
  94. func (kpcrr KubePVCapacityBytesMetric) Write(m *dto.Metric) error {
  95. m.Gauge = &dto.Gauge{
  96. Value: &kpcrr.value,
  97. }
  98. m.Label = []*dto.LabelPair{
  99. {
  100. Name: toStringPtr("persistentvolume"),
  101. Value: &kpcrr.pv,
  102. },
  103. }
  104. return nil
  105. }
  106. //--------------------------------------------------------------------------
  107. // KubePVStatusPhaseMetric
  108. //--------------------------------------------------------------------------
  109. // KubePVStatusPhaseMetric is a prometheus.Metric
  110. type KubePVStatusPhaseMetric struct {
  111. fqName string
  112. help string
  113. pv string
  114. phase string
  115. value float64
  116. }
  117. // Creates a new KubePVCapacityBytesMetric, implementation of prometheus.Metric
  118. func newKubePVStatusPhaseMetric(fqname, pv, phase string, value float64) KubePVStatusPhaseMetric {
  119. return KubePVStatusPhaseMetric{
  120. fqName: fqname,
  121. help: "kube_persistentvolume_status_phase pv status phase",
  122. pv: pv,
  123. phase: phase,
  124. value: value,
  125. }
  126. }
  127. // Desc returns the descriptor for the Metric. This method idempotently
  128. // returns the same descriptor throughout the lifetime of the Metric.
  129. func (kpcrr KubePVStatusPhaseMetric) Desc() *prometheus.Desc {
  130. l := prometheus.Labels{
  131. "persistentvolume": kpcrr.pv,
  132. "phase": kpcrr.phase,
  133. }
  134. return prometheus.NewDesc(kpcrr.fqName, kpcrr.help, []string{}, l)
  135. }
  136. // Write encodes the Metric into a "Metric" Protocol Buffer data
  137. // transmission object.
  138. func (kpcrr KubePVStatusPhaseMetric) Write(m *dto.Metric) error {
  139. m.Gauge = &dto.Gauge{
  140. Value: &kpcrr.value,
  141. }
  142. m.Label = []*dto.LabelPair{
  143. {
  144. Name: toStringPtr("persistentvolume"),
  145. Value: &kpcrr.pv,
  146. },
  147. {
  148. Name: toStringPtr("phase"),
  149. Value: &kpcrr.phase,
  150. },
  151. }
  152. return nil
  153. }
  154. //--------------------------------------------------------------------------
  155. // KubecostPVInfoMetric
  156. //--------------------------------------------------------------------------
  157. // KubecostPVInfoMetric is a prometheus.Metric
  158. type KubecostPVInfoMetric struct {
  159. fqName string
  160. help string
  161. pv string
  162. storageClass string
  163. value float64
  164. }
  165. // Creates a new newKubecostPVInfoMetric, implementation of prometheus.Metric
  166. func newKubecostPVInfoMetric(fqname, pv, storageClass string, value float64) KubecostPVInfoMetric {
  167. return KubecostPVInfoMetric{
  168. fqName: fqname,
  169. help: "kubecost_pv_info pv info",
  170. pv: pv,
  171. storageClass: storageClass,
  172. value: value,
  173. }
  174. }
  175. // Desc returns the descriptor for the Metric. This method idempotently
  176. // returns the same descriptor throughout the lifetime of the Metric.
  177. func (kpvim KubecostPVInfoMetric) Desc() *prometheus.Desc {
  178. l := prometheus.Labels{
  179. "persistentvolume": kpvim.pv,
  180. "storageclass": kpvim.storageClass,
  181. }
  182. return prometheus.NewDesc(kpvim.fqName, kpvim.help, []string{}, l)
  183. }
  184. // Write encodes the Metric into a "Metric" Protocol Buffer data
  185. // transmission object.
  186. func (kpvim KubecostPVInfoMetric) Write(m *dto.Metric) error {
  187. m.Gauge = &dto.Gauge{
  188. Value: &kpvim.value,
  189. }
  190. m.Label = []*dto.LabelPair{
  191. {
  192. Name: toStringPtr("persistentvolume"),
  193. Value: &kpvim.pv,
  194. },
  195. {
  196. Name: toStringPtr("storageclass"),
  197. Value: &kpvim.storageClass,
  198. },
  199. }
  200. return nil
  201. }