pvmetrics.go 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154
  1. package metrics
  2. import (
  3. "github.com/kubecost/cost-model/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. }
  15. // Describe sends the super-set of all possible descriptors of metrics
  16. // collected by this Collector.
  17. func (kpvcb KubePVCollector) Describe(ch chan<- *prometheus.Desc) {
  18. ch <- prometheus.NewDesc("kube_persistentvolume_capacity_bytes", "The pv storage capacity in bytes", []string{}, nil)
  19. 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)
  20. }
  21. // Collect is called by the Prometheus registry when collecting metrics.
  22. func (kpvcb KubePVCollector) Collect(ch chan<- prometheus.Metric) {
  23. pvs := kpvcb.KubeClusterCache.GetAllPersistentVolumes()
  24. for _, pv := range pvs {
  25. phase := pv.Status.Phase
  26. if phase != "" {
  27. phases := []struct {
  28. v bool
  29. n string
  30. }{
  31. {phase == v1.VolumePending, string(v1.VolumePending)},
  32. {phase == v1.VolumeAvailable, string(v1.VolumeAvailable)},
  33. {phase == v1.VolumeBound, string(v1.VolumeBound)},
  34. {phase == v1.VolumeReleased, string(v1.VolumeReleased)},
  35. {phase == v1.VolumeFailed, string(v1.VolumeFailed)},
  36. }
  37. for _, p := range phases {
  38. ch <- newKubePVStatusPhaseMetric("kube_persistentvolume_status_phase", pv.Name, p.n, boolFloat64(p.v))
  39. }
  40. }
  41. storage := pv.Spec.Capacity[v1.ResourceStorage]
  42. m := newKubePVCapacityBytesMetric("kube_persistentvolume_capacity_bytes", pv.Name, float64(storage.Value()))
  43. ch <- m
  44. }
  45. }
  46. //--------------------------------------------------------------------------
  47. // KubePVCapacityBytesMetric
  48. //--------------------------------------------------------------------------
  49. // KubePVCapacityBytesMetric is a prometheus.Metric
  50. type KubePVCapacityBytesMetric struct {
  51. fqName string
  52. help string
  53. pv string
  54. value float64
  55. }
  56. // Creates a new KubePVCapacityBytesMetric, implementation of prometheus.Metric
  57. func newKubePVCapacityBytesMetric(fqname, pv string, value float64) KubePVCapacityBytesMetric {
  58. return KubePVCapacityBytesMetric{
  59. fqName: fqname,
  60. help: "kube_persistentvolume_capacity_bytes pv storage capacity in bytes",
  61. pv: pv,
  62. value: value,
  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 (kpcrr KubePVCapacityBytesMetric) Desc() *prometheus.Desc {
  68. l := prometheus.Labels{
  69. "persistentvolume": kpcrr.pv,
  70. }
  71. return prometheus.NewDesc(kpcrr.fqName, kpcrr.help, []string{}, l)
  72. }
  73. // Write encodes the Metric into a "Metric" Protocol Buffer data
  74. // transmission object.
  75. func (kpcrr KubePVCapacityBytesMetric) Write(m *dto.Metric) error {
  76. m.Gauge = &dto.Gauge{
  77. Value: &kpcrr.value,
  78. }
  79. m.Label = []*dto.LabelPair{
  80. {
  81. Name: toStringPtr("persistentvolume"),
  82. Value: &kpcrr.pv,
  83. },
  84. }
  85. return nil
  86. }
  87. //--------------------------------------------------------------------------
  88. // KubePVStatusPhaseMetric
  89. //--------------------------------------------------------------------------
  90. // KubePVStatusPhaseMetric is a prometheus.Metric
  91. type KubePVStatusPhaseMetric struct {
  92. fqName string
  93. help string
  94. pv string
  95. phase string
  96. value float64
  97. }
  98. // Creates a new KubePVCapacityBytesMetric, implementation of prometheus.Metric
  99. func newKubePVStatusPhaseMetric(fqname, pv, phase string, value float64) KubePVStatusPhaseMetric {
  100. return KubePVStatusPhaseMetric{
  101. fqName: fqname,
  102. help: "kube_persistentvolume_status_phase pv status phase",
  103. pv: pv,
  104. phase: phase,
  105. value: value,
  106. }
  107. }
  108. // Desc returns the descriptor for the Metric. This method idempotently
  109. // returns the same descriptor throughout the lifetime of the Metric.
  110. func (kpcrr KubePVStatusPhaseMetric) Desc() *prometheus.Desc {
  111. l := prometheus.Labels{
  112. "persistentvolume": kpcrr.pv,
  113. "phase": kpcrr.phase,
  114. }
  115. return prometheus.NewDesc(kpcrr.fqName, kpcrr.help, []string{}, l)
  116. }
  117. // Write encodes the Metric into a "Metric" Protocol Buffer data
  118. // transmission object.
  119. func (kpcrr KubePVStatusPhaseMetric) Write(m *dto.Metric) error {
  120. m.Gauge = &dto.Gauge{
  121. Value: &kpcrr.value,
  122. }
  123. m.Label = []*dto.LabelPair{
  124. {
  125. Name: toStringPtr("persistentvolume"),
  126. Value: &kpcrr.pv,
  127. },
  128. {
  129. Name: toStringPtr("phase"),
  130. Value: &kpcrr.phase,
  131. },
  132. }
  133. return nil
  134. }