metrics.go 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170
  1. package costmodel
  2. import (
  3. "regexp"
  4. "sort"
  5. "github.com/prometheus/client_golang/prometheus"
  6. dto "github.com/prometheus/client_model/go"
  7. metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
  8. "k8s.io/client-go/kubernetes"
  9. )
  10. var (
  11. invalidLabelCharRE = regexp.MustCompile(`[^a-zA-Z0-9_]`)
  12. )
  13. func kubeLabelsToPrometheusLabels(labels map[string]string) ([]string, []string) {
  14. labelKeys := make([]string, 0, len(labels))
  15. for k := range labels {
  16. labelKeys = append(labelKeys, k)
  17. }
  18. sort.Strings(labelKeys)
  19. labelValues := make([]string, 0, len(labels))
  20. for i, k := range labelKeys {
  21. labelKeys[i] = "label_" + sanitizeLabelName(k)
  22. labelValues = append(labelValues, labels[k])
  23. }
  24. return labelKeys, labelValues
  25. }
  26. func sanitizeLabelName(s string) string {
  27. return invalidLabelCharRE.ReplaceAllString(s, "_")
  28. }
  29. type DeploymentCollector struct {
  30. KubeClientSet kubernetes.Interface
  31. }
  32. func (sc DeploymentCollector) Describe(ch chan<- *prometheus.Desc) {
  33. ch <- prometheus.NewInvalidDesc(nil)
  34. }
  35. func newDeploymentMetric(name, namespace, fqname string, labelNames []string, labelvalues []string) DeploymentMetric {
  36. return DeploymentMetric{
  37. fqName: fqname,
  38. labelNames: labelNames,
  39. labelValues: labelvalues,
  40. help: "service_selector_labels Service Selector Labels",
  41. deploymentName: name,
  42. namespace: namespace,
  43. }
  44. }
  45. type DeploymentMetric struct {
  46. fqName string
  47. help string
  48. labelNames []string
  49. labelValues []string
  50. deploymentName string
  51. namespace string
  52. }
  53. func (s DeploymentMetric) Desc() *prometheus.Desc {
  54. l := prometheus.Labels{"deployment": s.deploymentName, "namespace": s.namespace}
  55. return prometheus.NewDesc(s.fqName, s.help, s.labelNames, l)
  56. }
  57. func (s DeploymentMetric) Write(m *dto.Metric) error {
  58. h := float64(1)
  59. m.Gauge = &dto.Gauge{
  60. Value: &h,
  61. }
  62. var labels []*dto.LabelPair
  63. for i := range s.labelNames {
  64. labels = append(labels, &dto.LabelPair{
  65. Name: &s.labelNames[i],
  66. Value: &s.labelValues[i],
  67. })
  68. }
  69. n := "namespace"
  70. labels = append(labels, &dto.LabelPair{
  71. Name: &n,
  72. Value: &s.namespace,
  73. })
  74. r := "deployment"
  75. labels = append(labels, &dto.LabelPair{
  76. Name: &r,
  77. Value: &s.deploymentName,
  78. })
  79. m.Label = labels
  80. return nil
  81. }
  82. func (sc DeploymentCollector) Collect(ch chan<- prometheus.Metric) {
  83. ds, _ := sc.KubeClientSet.AppsV1().Deployments("").List(metav1.ListOptions{})
  84. for _, deployment := range ds.Items {
  85. labels, values := kubeLabelsToPrometheusLabels(deployment.Spec.Selector.MatchLabels)
  86. m := newDeploymentMetric(sanitizeLabelName(deployment.GetName()), sanitizeLabelName(deployment.GetNamespace()), "deployment_match_labels", labels, values)
  87. ch <- m
  88. }
  89. }
  90. type ServiceCollector struct {
  91. KubeClientSet kubernetes.Interface
  92. }
  93. func (sc ServiceCollector) Describe(ch chan<- *prometheus.Desc) {
  94. return
  95. }
  96. func newServiceMetric(name, namespace, fqname string, labelNames []string, labelvalues []string) ServiceMetric {
  97. return ServiceMetric{
  98. fqName: fqname,
  99. labelNames: labelNames,
  100. labelValues: labelvalues,
  101. help: "service_selector_labels Service Selector Labels",
  102. serviceName: name,
  103. namespace: namespace,
  104. }
  105. }
  106. type ServiceMetric struct {
  107. fqName string
  108. help string
  109. labelNames []string
  110. labelValues []string
  111. serviceName string
  112. namespace string
  113. }
  114. func (s ServiceMetric) Desc() *prometheus.Desc {
  115. l := prometheus.Labels{"service": s.serviceName, "namespace": s.namespace}
  116. return prometheus.NewDesc(s.fqName, s.help, s.labelNames, l)
  117. }
  118. func (s ServiceMetric) Write(m *dto.Metric) error {
  119. h := float64(1)
  120. m.Gauge = &dto.Gauge{
  121. Value: &h,
  122. }
  123. var labels []*dto.LabelPair
  124. for i := range s.labelNames {
  125. labels = append(labels, &dto.LabelPair{
  126. Name: &s.labelNames[i],
  127. Value: &s.labelValues[i],
  128. })
  129. }
  130. n := "namespace"
  131. labels = append(labels, &dto.LabelPair{
  132. Name: &n,
  133. Value: &s.namespace,
  134. })
  135. r := "service"
  136. labels = append(labels, &dto.LabelPair{
  137. Name: &r,
  138. Value: &s.serviceName,
  139. })
  140. m.Label = labels
  141. return nil
  142. }
  143. func (sc ServiceCollector) Collect(ch chan<- prometheus.Metric) {
  144. svcs, _ := sc.KubeClientSet.CoreV1().Services("").List(metav1.ListOptions{})
  145. for _, svc := range svcs.Items {
  146. labels, values := kubeLabelsToPrometheusLabels(svc.Spec.Selector)
  147. m := newServiceMetric(sanitizeLabelName(svc.GetName()), sanitizeLabelName(svc.GetNamespace()), "service_selector_labels", labels, values)
  148. ch <- m
  149. }
  150. }