deploymentmetrics.go 8.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255
  1. package metrics
  2. import (
  3. "github.com/kubecost/cost-model/pkg/clustercache"
  4. "github.com/kubecost/cost-model/pkg/prom"
  5. "github.com/prometheus/client_golang/prometheus"
  6. dto "github.com/prometheus/client_model/go"
  7. )
  8. //--------------------------------------------------------------------------
  9. // KubecostDeploymentCollector
  10. //--------------------------------------------------------------------------
  11. // KubecostDeploymentCollector is a prometheus collector that generates kubecost
  12. // specific deployment metrics.
  13. type KubecostDeploymentCollector struct {
  14. KubeClusterCache clustercache.ClusterCache
  15. }
  16. // Describe sends the super-set of all possible descriptors of metrics
  17. // collected by this Collector.
  18. func (kdc KubecostDeploymentCollector) Describe(ch chan<- *prometheus.Desc) {
  19. ch <- prometheus.NewDesc("deployment_match_labels", "deployment match labels", []string{}, nil)
  20. }
  21. // Collect is called by the Prometheus registry when collecting metrics.
  22. func (kdc KubecostDeploymentCollector) Collect(ch chan<- prometheus.Metric) {
  23. ds := kdc.KubeClusterCache.GetAllDeployments()
  24. for _, deployment := range ds {
  25. deploymentName := deployment.GetName()
  26. deploymentNS := deployment.GetNamespace()
  27. labels, values := prom.KubeLabelsToLabels(deployment.Spec.Selector.MatchLabels)
  28. if len(labels) > 0 {
  29. m := newDeploymentMatchLabelsMetric(deploymentName, deploymentNS, "deployment_match_labels", labels, values)
  30. ch <- m
  31. }
  32. }
  33. }
  34. //--------------------------------------------------------------------------
  35. // DeploymentMatchLabelsMetric
  36. //--------------------------------------------------------------------------
  37. // DeploymentMatchLabelsMetric is a prometheus.Metric used to encode deployment match labels
  38. type DeploymentMatchLabelsMetric struct {
  39. fqName string
  40. help string
  41. labelNames []string
  42. labelValues []string
  43. deploymentName string
  44. namespace string
  45. }
  46. // Creates a new DeploymentMatchLabelsMetric, implementation of prometheus.Metric
  47. func newDeploymentMatchLabelsMetric(name, namespace, fqname string, labelNames, labelvalues []string) DeploymentMatchLabelsMetric {
  48. return DeploymentMatchLabelsMetric{
  49. fqName: fqname,
  50. labelNames: labelNames,
  51. labelValues: labelvalues,
  52. help: "deployment_match_labels Deployment Match Labels",
  53. deploymentName: name,
  54. namespace: namespace,
  55. }
  56. }
  57. // Desc returns the descriptor for the Metric. This method idempotently
  58. // returns the same descriptor throughout the lifetime of the Metric.
  59. func (dmlm DeploymentMatchLabelsMetric) Desc() *prometheus.Desc {
  60. l := prometheus.Labels{
  61. "deployment": dmlm.deploymentName,
  62. "namespace": dmlm.namespace,
  63. }
  64. return prometheus.NewDesc(dmlm.fqName, dmlm.help, dmlm.labelNames, l)
  65. }
  66. // Write encodes the Metric into a "Metric" Protocol Buffer data
  67. // transmission object.
  68. func (dmlm DeploymentMatchLabelsMetric) Write(m *dto.Metric) error {
  69. h := float64(1)
  70. m.Gauge = &dto.Gauge{
  71. Value: &h,
  72. }
  73. var labels []*dto.LabelPair
  74. for i := range dmlm.labelNames {
  75. labels = append(labels, &dto.LabelPair{
  76. Name: &dmlm.labelNames[i],
  77. Value: &dmlm.labelValues[i],
  78. })
  79. }
  80. labels = append(labels, &dto.LabelPair{
  81. Name: toStringPtr("namespace"),
  82. Value: &dmlm.namespace,
  83. })
  84. labels = append(labels, &dto.LabelPair{
  85. Name: toStringPtr("deployment"),
  86. Value: &dmlm.deploymentName,
  87. })
  88. m.Label = labels
  89. return nil
  90. }
  91. //--------------------------------------------------------------------------
  92. // KubeDeploymentCollector
  93. //--------------------------------------------------------------------------
  94. // KubeDeploymentCollector is a prometheus collector that generates
  95. type KubeDeploymentCollector struct {
  96. KubeClusterCache clustercache.ClusterCache
  97. }
  98. // Describe sends the super-set of all possible descriptors of metrics
  99. // collected by this Collector.
  100. func (kdc KubeDeploymentCollector) Describe(ch chan<- *prometheus.Desc) {
  101. ch <- prometheus.NewDesc("kube_deployment_spec_replicas", "Number of desired pods for a deployment.", []string{}, nil)
  102. ch <- prometheus.NewDesc("kube_deployment_status_replicas_available", "The number of available replicas per deployment.", []string{}, nil)
  103. }
  104. // Collect is called by the Prometheus registry when collecting metrics.
  105. func (kdc KubeDeploymentCollector) Collect(ch chan<- prometheus.Metric) {
  106. deployments := kdc.KubeClusterCache.GetAllDeployments()
  107. for _, deployment := range deployments {
  108. deploymentName := deployment.GetName()
  109. deploymentNS := deployment.GetNamespace()
  110. // Replicas Defined
  111. var replicas int32
  112. if deployment.Spec.Replicas == nil {
  113. replicas = 1 // defaults to 1, documented on the 'Replicas' field
  114. } else {
  115. replicas = *deployment.Spec.Replicas
  116. }
  117. ch <- newKubeDeploymentReplicasMetric("kube_deployment_spec_replicas", deploymentName, deploymentNS, replicas)
  118. // Replicas Available
  119. ch <- newKubeDeploymentStatusAvailableReplicasMetric(
  120. "kube_deployment_status_replicas_available",
  121. deploymentName,
  122. deploymentNS,
  123. deployment.Status.AvailableReplicas)
  124. }
  125. }
  126. //--------------------------------------------------------------------------
  127. // KubeDeploymentReplicasMetric
  128. //--------------------------------------------------------------------------
  129. // KubeDeploymentReplicasMetric is a prometheus.Metric used to encode deployment match labels
  130. type KubeDeploymentReplicasMetric struct {
  131. fqName string
  132. help string
  133. deployment string
  134. namespace string
  135. replicas float64
  136. }
  137. // Creates a new DeploymentMatchLabelsMetric, implementation of prometheus.Metric
  138. func newKubeDeploymentReplicasMetric(fqname, deployment, namespace string, replicas int32) KubeDeploymentReplicasMetric {
  139. return KubeDeploymentReplicasMetric{
  140. fqName: fqname,
  141. help: "kube_deployment_spec_replicas Number of desired pods for a deployment.",
  142. deployment: deployment,
  143. namespace: namespace,
  144. replicas: float64(replicas),
  145. }
  146. }
  147. // Desc returns the descriptor for the Metric. This method idempotently
  148. // returns the same descriptor throughout the lifetime of the Metric.
  149. func (kdr KubeDeploymentReplicasMetric) Desc() *prometheus.Desc {
  150. l := prometheus.Labels{
  151. "deployment": kdr.deployment,
  152. "namespace": kdr.namespace,
  153. }
  154. return prometheus.NewDesc(kdr.fqName, kdr.help, []string{}, l)
  155. }
  156. // Write encodes the Metric into a "Metric" Protocol Buffer data
  157. // transmission object.
  158. func (kdr KubeDeploymentReplicasMetric) Write(m *dto.Metric) error {
  159. m.Gauge = &dto.Gauge{
  160. Value: &kdr.replicas,
  161. }
  162. m.Label = []*dto.LabelPair{
  163. {
  164. Name: toStringPtr("namespace"),
  165. Value: &kdr.namespace,
  166. },
  167. {
  168. Name: toStringPtr("deployment"),
  169. Value: &kdr.deployment,
  170. },
  171. }
  172. return nil
  173. }
  174. //--------------------------------------------------------------------------
  175. // KubeDeploymentStatusAvailableReplicasMetric
  176. //--------------------------------------------------------------------------
  177. // KubeDeploymentStatusAvailableReplicasMetric is a prometheus.Metric used to encode deployment match labels
  178. type KubeDeploymentStatusAvailableReplicasMetric struct {
  179. fqName string
  180. help string
  181. deployment string
  182. namespace string
  183. replicasAvailable float64
  184. }
  185. // Creates a new DeploymentMatchLabelsMetric, implementation of prometheus.Metric
  186. func newKubeDeploymentStatusAvailableReplicasMetric(fqname, deployment, namespace string, replicasAvailable int32) KubeDeploymentStatusAvailableReplicasMetric {
  187. return KubeDeploymentStatusAvailableReplicasMetric{
  188. fqName: fqname,
  189. help: "kube_deployment_status_replicas_available The number of available replicas per deployment.",
  190. deployment: deployment,
  191. namespace: namespace,
  192. replicasAvailable: float64(replicasAvailable),
  193. }
  194. }
  195. // Desc returns the descriptor for the Metric. This method idempotently
  196. // returns the same descriptor throughout the lifetime of the Metric.
  197. func (kdr KubeDeploymentStatusAvailableReplicasMetric) Desc() *prometheus.Desc {
  198. l := prometheus.Labels{
  199. "deployment": kdr.deployment,
  200. "namespace": kdr.namespace,
  201. }
  202. return prometheus.NewDesc(kdr.fqName, kdr.help, []string{}, l)
  203. }
  204. // Write encodes the Metric into a "Metric" Protocol Buffer data
  205. // transmission object.
  206. func (kdr KubeDeploymentStatusAvailableReplicasMetric) Write(m *dto.Metric) error {
  207. m.Gauge = &dto.Gauge{
  208. Value: &kdr.replicasAvailable,
  209. }
  210. m.Label = []*dto.LabelPair{
  211. {
  212. Name: toStringPtr("namespace"),
  213. Value: &kdr.namespace,
  214. },
  215. {
  216. Name: toStringPtr("deployment"),
  217. Value: &kdr.deployment,
  218. },
  219. }
  220. return nil
  221. }