MetricsServiceImpl.java 9.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183
  1. package cn.seecoder.paas.service.impl;
  2. import cn.seecoder.paas.data.dao.EnvironmentDAO;
  3. import cn.seecoder.paas.data.dao.MetricsDAO;
  4. import cn.seecoder.paas.data.entity.Environment;
  5. import cn.seecoder.paas.data.entity.Metrics;
  6. import cn.seecoder.paas.service.MetricsService;
  7. import cn.seecoder.paas.service.facade.k8s.PodApi;
  8. import cn.seecoder.paas.service.facade.k8s.model.K8sObjectRequest;
  9. import cn.seecoder.paas.service.facade.k8s.model.Pod;
  10. import cn.seecoder.paas.service.model.converter.MetricsConverter;
  11. import cn.seecoder.paas.service.model.vo.MetricsVO;
  12. import cn.seecoder.paas.util.ApplicationProperties;
  13. import cn.seecoder.paas.util.DateUtil;
  14. import cn.seecoder.paas.util.enums.MetricsSource;
  15. import cn.seecoder.paas.util.enums.MetricsType;
  16. import cn.seecoder.paas.util.enums.ResourceLabel;
  17. import io.fabric8.kubernetes.api.model.Quantity;
  18. import io.fabric8.kubernetes.api.model.metrics.v1beta1.NodeMetrics;
  19. import io.fabric8.kubernetes.api.model.metrics.v1beta1.NodeMetricsList;
  20. import io.fabric8.kubernetes.api.model.metrics.v1beta1.PodMetrics;
  21. import io.fabric8.kubernetes.client.DefaultKubernetesClient;
  22. import org.springframework.beans.factory.annotation.Autowired;
  23. import java.time.LocalDateTime;
  24. import java.util.*;
  25. import java.util.stream.Collectors;
  26. @org.springframework.stereotype.Service
  27. public class MetricsServiceImpl implements MetricsService {
  28. private final DefaultKubernetesClient fabricK8sClient;
  29. private final ApplicationProperties applicationProperties;
  30. private final EnvironmentDAO environmentDAO;
  31. private final MetricsDAO metricsDAO;
  32. private final PodApi podApi;
  33. @Autowired
  34. public MetricsServiceImpl(DefaultKubernetesClient fabricK8sClient, ApplicationProperties applicationProperties, EnvironmentDAO environmentDAO, PodApi podApi, MetricsDAO metricsDAO) {
  35. this.fabricK8sClient = fabricK8sClient;
  36. this.applicationProperties = applicationProperties;
  37. this.environmentDAO = environmentDAO;
  38. this.podApi = podApi;
  39. this.metricsDAO = metricsDAO;
  40. }
  41. @Override
  42. public List<MetricsVO> getMetricsBySourceAndTypeBetween(MetricsSource metricsSource, String metricsSourceValue, MetricsType metricsType, LocalDateTime startTime, LocalDateTime endTime) {
  43. List<Metrics> metrics = metricsDAO.findByMetricsSourceAndAndMetricsSourceValueAndMetricsTypeAndMetricsTimeBetween(metricsSource, metricsSourceValue, metricsType, startTime, endTime);
  44. return metrics.stream().map(MetricsConverter::convertToVO).collect(Collectors.toList());
  45. }
  46. @Override
  47. public List<MetricsVO> getMetricsSourceCurrentStatus(MetricsSource metricsSource, String metricsSourceValue) {
  48. List<MetricsVO> result = new ArrayList<>();
  49. String deploymentNamespace = applicationProperties.getDeploymentNamespace();
  50. switch (metricsSource) {
  51. case POD:
  52. PodMetrics podMetrics = fabricK8sClient.top().pods().metrics(deploymentNamespace, metricsSourceValue);
  53. return statPodMetrics(Collections.singletonList(podMetrics), metricsSource, metricsSourceValue);
  54. case NODE:
  55. NodeMetrics nodeMetrics = fabricK8sClient.top().nodes().metrics(metricsSourceValue);
  56. return statNodeMetrics(Collections.singletonList(nodeMetrics), metricsSource, metricsSourceValue);
  57. case APPLICATION:
  58. List<Environment> environments = environmentDAO.findAllByAppId(Integer.parseInt(metricsSourceValue));
  59. List<PodMetrics> podMetricsList = new ArrayList<>();
  60. environments.forEach(environment -> {
  61. String labelKey = ResourceLabel.RESOURCE.getCode();
  62. String labelValue = ResourceLabel.RESOURCE.getGenerator().gen("environment", metricsSourceValue, String.valueOf(environment.getId()));
  63. K8sObjectRequest request = K8sObjectRequest.builder().namespace(applicationProperties.getDeploymentNamespace()).labels(Collections.singletonMap(labelKey, labelValue)).build();
  64. List<Pod> pods = podApi.getByCondition(request);
  65. pods.forEach(pod -> {
  66. PodMetrics metrics = fabricK8sClient.top().pods().metrics(deploymentNamespace, pod.getName());
  67. podMetricsList.add(metrics);
  68. });
  69. });
  70. return statPodMetrics(podMetricsList, metricsSource, metricsSourceValue);
  71. case ENVIRONMENT:
  72. Environment environment = environmentDAO.findById(Integer.parseInt(metricsSourceValue)).orElse(null);
  73. if (environment == null) {
  74. return Collections.emptyList();
  75. }
  76. List<PodMetrics> environmentMetricsList = new ArrayList<>();
  77. String labelKey = ResourceLabel.RESOURCE.getCode();
  78. String labelValue = ResourceLabel.RESOURCE.getGenerator().gen("environment", String.valueOf(environment.getAppId()), String.valueOf(environment.getId()));
  79. K8sObjectRequest request = K8sObjectRequest.builder().namespace(applicationProperties.getDeploymentNamespace()).labels(Collections.singletonMap(labelKey, labelValue)).build();
  80. List<Pod> pods = podApi.getByCondition(request);
  81. pods.forEach(pod -> {
  82. PodMetrics metrics = fabricK8sClient.top().pods().metrics(deploymentNamespace, pod.getName());
  83. environmentMetricsList.add(metrics);
  84. });
  85. return statPodMetrics(environmentMetricsList, metricsSource, metricsSourceValue);
  86. case CLUSTER:
  87. NodeMetricsList nodeMetricsList = fabricK8sClient.top().nodes().metrics();
  88. return statNodeMetrics(nodeMetricsList.getItems(), metricsSource, metricsSourceValue);
  89. }
  90. return result;
  91. }
  92. public List<MetricsVO> statPodMetrics(List<PodMetrics> podMetricsList, MetricsSource metricsSource, String metricsSourceValue) {
  93. if (podMetricsList == null || podMetricsList.isEmpty()) {
  94. return Collections.emptyList();
  95. }
  96. List<MetricsVO> result;
  97. Map<String, Long> values = new HashMap<>();
  98. podMetricsList.forEach(podMetrics -> {
  99. podMetrics.getContainers().forEach(containerMetrics -> {
  100. Map<String, Quantity> metricValues = containerMetrics.getUsage();
  101. metricValues.forEach((key, quantity) -> {
  102. if (values.get(key) != null) {
  103. values.put(key, values.get(key) + Long.parseLong(quantity.getAmount()));
  104. } else {
  105. values.put(key, Long.parseLong(quantity.getAmount()));
  106. }
  107. });
  108. });
  109. });
  110. result = values.entrySet().stream().map(entry -> {
  111. MetricsVO vo = new MetricsVO();
  112. vo.setMetricsSource(metricsSource);
  113. vo.setMetricsSourceValue(metricsSourceValue);
  114. vo.setMetricsType(entry.getKey());
  115. vo.setMetricsTypeValue(Long.toString(entry.getValue()));
  116. vo.setMetricsTime(podMetricsList.size() == 1 ? DateUtil.fromUTCTimeString(podMetricsList.get(0).getTimestamp()) : LocalDateTime.now());
  117. return vo;
  118. }).collect(Collectors.toList());
  119. if (podMetricsList.size() == 1) {
  120. // duration
  121. MetricsVO durationVO = new MetricsVO();
  122. durationVO.setMetricsSource(metricsSource);
  123. durationVO.setMetricsSourceValue(metricsSourceValue);
  124. durationVO.setMetricsType(MetricsType.DURATION.getCode());
  125. durationVO.setMetricsTypeValue(podMetricsList.get(0).getWindow().getDuration().toString());
  126. durationVO.setMetricsTime(DateUtil.fromUTCTimeString(podMetricsList.get(0).getTimestamp()));
  127. result.add(durationVO);
  128. }
  129. return result;
  130. }
  131. public List<MetricsVO> statNodeMetrics(List<NodeMetrics> nodeMetricsList, MetricsSource metricsSource, String metricsSourceValue) {
  132. if (nodeMetricsList == null || nodeMetricsList.isEmpty()) {
  133. return Collections.emptyList();
  134. }
  135. List<MetricsVO> result;
  136. Map<String, Long> values = new HashMap<>();
  137. nodeMetricsList.forEach(nodeMetrics -> {
  138. Map<String, Quantity> metricValues = nodeMetrics.getUsage();
  139. metricValues.forEach((key, quantity) -> {
  140. if (values.get(key) != null) {
  141. values.put(key, values.get(key) + Long.parseLong(quantity.getAmount()));
  142. } else {
  143. values.put(key, Long.parseLong(quantity.getAmount()));
  144. }
  145. });
  146. });
  147. result = values.entrySet().stream().map(entry -> {
  148. MetricsVO vo = new MetricsVO();
  149. vo.setMetricsSource(metricsSource);
  150. vo.setMetricsSourceValue(metricsSourceValue);
  151. vo.setMetricsType(entry.getKey());
  152. vo.setMetricsTypeValue(Long.toString(entry.getValue()));
  153. vo.setMetricsTime(nodeMetricsList.size() == 1 ? DateUtil.fromUTCTimeString(nodeMetricsList.get(0).getTimestamp()) : LocalDateTime.now());
  154. return vo;
  155. }).collect(Collectors.toList());
  156. if (nodeMetricsList.size() == 1) {
  157. // duration
  158. MetricsVO durationVO = new MetricsVO();
  159. durationVO.setMetricsSource(metricsSource);
  160. durationVO.setMetricsSourceValue(metricsSourceValue);
  161. durationVO.setMetricsType(MetricsType.DURATION.getCode());
  162. durationVO.setMetricsTypeValue(nodeMetricsList.get(0).getWindow().getDuration().toString());
  163. durationVO.setMetricsTime(DateUtil.fromUTCTimeString(nodeMetricsList.get(0).getTimestamp()));
  164. result.add(durationVO);
  165. }
  166. return result;
  167. }
  168. }