metrics.go 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238
  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 StatefulsetCollector struct {
  30. KubeClientSet kubernetes.Interface
  31. }
  32. func (sc StatefulsetCollector) Describe(ch chan<- *prometheus.Desc) {
  33. ch <- prometheus.NewDesc("statefulSet_match_labels", "statfulSet match labels", []string{}, nil)
  34. }
  35. type DeploymentCollector struct {
  36. KubeClientSet kubernetes.Interface
  37. }
  38. func (sc DeploymentCollector) Describe(ch chan<- *prometheus.Desc) {
  39. ch <- prometheus.NewInvalidDesc(nil)
  40. }
  41. func newStatefulsetMetric(name, namespace, fqname string, labelNames []string, labelvalues []string) StatefulsetMetric {
  42. return StatefulsetMetric{
  43. fqName: fqname,
  44. labelNames: labelNames,
  45. labelValues: labelvalues,
  46. help: "statefulSet_match_labels StatefulSet Match Labels",
  47. statefulsetName: name,
  48. namespace: namespace,
  49. }
  50. }
  51. type StatefulsetMetric struct {
  52. fqName string
  53. help string
  54. labelNames []string
  55. labelValues []string
  56. statefulsetName string
  57. namespace string
  58. }
  59. func (s StatefulsetMetric) Desc() *prometheus.Desc {
  60. l := prometheus.Labels{"statefulSet": s.statefulsetName, "namespace": s.namespace}
  61. return prometheus.NewDesc(s.fqName, s.help, s.labelNames, l)
  62. }
  63. func (s StatefulsetMetric) Write(m *dto.Metric) error {
  64. h := float64(1)
  65. m.Gauge = &dto.Gauge{
  66. Value: &h,
  67. }
  68. var labels []*dto.LabelPair
  69. for i := range s.labelNames {
  70. labels = append(labels, &dto.LabelPair{
  71. Name: &s.labelNames[i],
  72. Value: &s.labelValues[i],
  73. })
  74. }
  75. n := "namespace"
  76. labels = append(labels, &dto.LabelPair{
  77. Name: &n,
  78. Value: &s.namespace,
  79. })
  80. r := "statefulSet"
  81. labels = append(labels, &dto.LabelPair{
  82. Name: &r,
  83. Value: &s.statefulsetName,
  84. })
  85. m.Label = labels
  86. return nil
  87. }
  88. func (sc StatefulsetCollector) Collect(ch chan<- prometheus.Metric) {
  89. ds, _ := sc.KubeClientSet.AppsV1().StatefulSets("").List(metav1.ListOptions{})
  90. for _, statefulset := range ds.Items {
  91. labels, values := kubeLabelsToPrometheusLabels(statefulset.Spec.Selector.MatchLabels)
  92. m := newStatefulsetMetric(statefulset.GetName(), statefulset.GetNamespace(), "statefulSet_match_labels", labels, values)
  93. ch <- m
  94. }
  95. }
  96. func newDeploymentMetric(name, namespace, fqname string, labelNames []string, labelvalues []string) DeploymentMetric {
  97. return DeploymentMetric{
  98. fqName: fqname,
  99. labelNames: labelNames,
  100. labelValues: labelvalues,
  101. help: "deployment_match_labels Deployment Match Labels",
  102. deploymentName: name,
  103. namespace: namespace,
  104. }
  105. }
  106. type DeploymentMetric struct {
  107. fqName string
  108. help string
  109. labelNames []string
  110. labelValues []string
  111. deploymentName string
  112. namespace string
  113. }
  114. func (s DeploymentMetric) Desc() *prometheus.Desc {
  115. l := prometheus.Labels{"deployment": s.deploymentName, "namespace": s.namespace}
  116. return prometheus.NewDesc(s.fqName, s.help, s.labelNames, l)
  117. }
  118. func (s DeploymentMetric) 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 := "deployment"
  136. labels = append(labels, &dto.LabelPair{
  137. Name: &r,
  138. Value: &s.deploymentName,
  139. })
  140. m.Label = labels
  141. return nil
  142. }
  143. func (sc DeploymentCollector) Collect(ch chan<- prometheus.Metric) {
  144. ds, _ := sc.KubeClientSet.AppsV1().Deployments("").List(metav1.ListOptions{})
  145. for _, deployment := range ds.Items {
  146. labels, values := kubeLabelsToPrometheusLabels(deployment.Spec.Selector.MatchLabels)
  147. m := newDeploymentMetric(deployment.GetName(), deployment.GetNamespace(), "deployment_match_labels", labels, values)
  148. ch <- m
  149. }
  150. }
  151. type ServiceCollector struct {
  152. KubeClientSet kubernetes.Interface
  153. }
  154. func (sc ServiceCollector) Describe(ch chan<- *prometheus.Desc) {
  155. return
  156. }
  157. func newServiceMetric(name, namespace, fqname string, labelNames []string, labelvalues []string) ServiceMetric {
  158. return ServiceMetric{
  159. fqName: fqname,
  160. labelNames: labelNames,
  161. labelValues: labelvalues,
  162. help: "service_selector_labels Service Selector Labels",
  163. serviceName: name,
  164. namespace: namespace,
  165. }
  166. }
  167. type ServiceMetric struct {
  168. fqName string
  169. help string
  170. labelNames []string
  171. labelValues []string
  172. serviceName string
  173. namespace string
  174. }
  175. func (s ServiceMetric) Desc() *prometheus.Desc {
  176. l := prometheus.Labels{"service": s.serviceName, "namespace": s.namespace}
  177. return prometheus.NewDesc(s.fqName, s.help, s.labelNames, l)
  178. }
  179. func (s ServiceMetric) Write(m *dto.Metric) error {
  180. h := float64(1)
  181. m.Gauge = &dto.Gauge{
  182. Value: &h,
  183. }
  184. var labels []*dto.LabelPair
  185. for i := range s.labelNames {
  186. labels = append(labels, &dto.LabelPair{
  187. Name: &s.labelNames[i],
  188. Value: &s.labelValues[i],
  189. })
  190. }
  191. n := "namespace"
  192. labels = append(labels, &dto.LabelPair{
  193. Name: &n,
  194. Value: &s.namespace,
  195. })
  196. r := "service"
  197. labels = append(labels, &dto.LabelPair{
  198. Name: &r,
  199. Value: &s.serviceName,
  200. })
  201. m.Label = labels
  202. return nil
  203. }
  204. func (sc ServiceCollector) Collect(ch chan<- prometheus.Metric) {
  205. svcs, _ := sc.KubeClientSet.CoreV1().Services("").List(metav1.ListOptions{})
  206. for _, svc := range svcs.Items {
  207. labels, values := kubeLabelsToPrometheusLabels(svc.Spec.Selector)
  208. m := newServiceMetric(svc.GetName(), svc.GetNamespace(), "service_selector_labels", labels, values)
  209. ch <- m
  210. }
  211. }