From 30530394fc65d812a9d7472849cf2264be0f12a7 Mon Sep 17 00:00:00 2001 From: bayuzhen Date: Tue, 28 May 2024 15:09:42 +0800 Subject: [PATCH] =?UTF-8?q?=E8=BF=81=E7=A7=BBcloudTower=E7=9B=91=E6=8E=A7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pom.xml | 12 + .../com/bocloud/ims/enums/CloudProvider.java | 2 +- .../cloudtower/CloudTowerCollector.java | 112 +++++++++ .../cloudtower/CloudTowerHostCollector.java | 213 ++++++++++++++++++ .../CloudTowerHostNetCollector.java | 122 ++++++++++ .../cloudtower/CloudTowerVmCollector.java | 202 +++++++++++++++++ .../cloudtower/CloudTowerVmNetCollector.java | 122 ++++++++++ .../com/bocloud/mcs/common/Constants.java | 6 + .../internal/CmpCloudVendorService.java | 17 ++ 9 files changed, 807 insertions(+), 1 deletion(-) create mode 100644 src/main/java/com/bocloud/mcs/collector/cloudtower/CloudTowerCollector.java create mode 100644 src/main/java/com/bocloud/mcs/collector/cloudtower/CloudTowerHostCollector.java create mode 100644 src/main/java/com/bocloud/mcs/collector/cloudtower/CloudTowerHostNetCollector.java create mode 100644 src/main/java/com/bocloud/mcs/collector/cloudtower/CloudTowerVmCollector.java create mode 100644 src/main/java/com/bocloud/mcs/collector/cloudtower/CloudTowerVmNetCollector.java diff --git a/pom.xml b/pom.xml index 604f8a5..6230470 100644 --- a/pom.xml +++ b/pom.xml @@ -129,6 +129,18 @@ tea 1.1.15 + + com.bocloud + bocloud.public.provider + 5.6.0-HBCL-RELEASE + compile + + + com.bocloud + bocloud.cloudtowner.provider + 5.6.0-HBCL-RELEASE + compile + diff --git a/src/main/java/com/bocloud/ims/enums/CloudProvider.java b/src/main/java/com/bocloud/ims/enums/CloudProvider.java index 3eedd74..567d7e8 100644 --- a/src/main/java/com/bocloud/ims/enums/CloudProvider.java +++ b/src/main/java/com/bocloud/ims/enums/CloudProvider.java @@ -12,6 +12,6 @@ public enum CloudProvider { OPENSTACK, VMWARE, ALIYUN, JDCLOUD, UNKNOWN, CEPH, SCP, H3C, HMC, FUSIONCLOUD, TENCENT, F5, HUAWEI, XEN, POWERVC, CLOUDOS, SMIS_FABRIC, SMIS_STORAGE, AZURE, KINGCLOUD, KUBERNETES, AWS, QCLOUD, TCE, PQCLOUD, XSKY, MANAGEONE, - JUMPSERVER, HORIZON, TIANYI, HILLSTONE, CISCO, AGILE, NSX,SMARTX; + JUMPSERVER, HORIZON, TIANYI, HILLSTONE, CISCO, AGILE, NSX,SMARTX, CLOUDTOWER; } diff --git a/src/main/java/com/bocloud/mcs/collector/cloudtower/CloudTowerCollector.java b/src/main/java/com/bocloud/mcs/collector/cloudtower/CloudTowerCollector.java new file mode 100644 index 0000000..c639a83 --- /dev/null +++ b/src/main/java/com/bocloud/mcs/collector/cloudtower/CloudTowerCollector.java @@ -0,0 +1,112 @@ +package com.bocloud.mcs.collector.cloudtower; + +import com.alibaba.fastjson.JSONObject; +import com.bocloud.cmp.model.Butler; +import com.bocloud.cmp.provider.CloudTowerProvider; +import com.bocloud.common.encrypt.DESEncrptor; +import com.bocloud.common.model.BocloudResult; +import com.bocloud.common.utils.Common; +import com.bocloud.ims.entity.CloudVendor; +import com.bocloud.ims.enums.CloudProvider; +import com.bocloud.mcs.collector.BocloudCollector; +import com.bocloud.service.core.CurrentService; +import com.smartx.tower.api.MetricsApi; +import lombok.extern.slf4j.Slf4j; +import org.apache.http.ssl.SSLContextBuilder; +import org.openstack4j.core.transport.Config; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.scheduling.annotation.Async; +import org.springframework.scheduling.annotation.Scheduled; + +import java.security.KeyManagementException; +import java.security.KeyStoreException; +import java.security.NoSuchAlgorithmException; +import java.util.*; + +@Slf4j +public abstract class CloudTowerCollector extends BocloudCollector { + + protected static Config config; + static { + // 全部信任 不做身份鉴定 + try { + SSLContextBuilder contextBuilder = SSLContextBuilder.create().loadTrustMaterial(null, + (x509Certificates, authType) -> true); + config = Config.newConfig().withSSLVerificationDisabled().withSSLContext(contextBuilder.build()) + .withReadTimeout(20 * 1000 * 1000).withConnectionTimeout(20 * 1000 * 1000); + } catch (NoSuchAlgorithmException e) { + log.error("NoSuchAlgorithmException", e); + } catch (KeyStoreException e) { + log.error("KeyStoreException", e); + } catch (KeyManagementException e) { + log.error("KeyManagementException", e); + } + } + + /** + * 缓存过期时间,30分钟 + * + * @return + */ + @Override + public int getExpire() { + return 1800000; + } + + Map cache = new HashMap<>(); + + @Autowired + private CurrentService currentService; + + + @Scheduled(initialDelay = 5000L, fixedRate = 300000L) + @Async + @Override + public void scheduledCollect() { + if (!currentService.isLeader()) { + log.info(this.getClass().getName() + "当前节点是否是主节点:" + currentService.isLeader()); + return; + } + Date now = new Date(); + log.info(this.getClass().getName() + " metrics start..."); + BocloudResult bocloudResult = cmpCloudVendorService.list(CloudProvider.CLOUDTOWER); + if (bocloudResult.isFailed()) { + log.error("get cloud vendor list failed , error:{}", bocloudResult.getMessage()); + return; + } + JSONObject data = (JSONObject) bocloudResult.getData(); + List listCloudVendor = data.getJSONArray(Common.ROWS).toJavaList(CloudVendor.class); + + List mfs = new ArrayList<>(); + for (CloudVendor cloudVendor : listCloudVendor) { + try { + String address = JSONObject.parseObject(cloudVendor.getAuthentication()).getString("address"); + String username = JSONObject.parseObject(cloudVendor.getAuthentication()).getString("account"); + String passwordJson = JSONObject.parseObject(cloudVendor.getAuthentication()).getString("password"); + String password = new DESEncrptor().decrypt(passwordJson.trim(), "BocloudCMP"); + Butler butler = new Butler(); + butler.setUrl(address); + butler.setUsername(username); + butler.setPassword(password); + CloudTowerProvider cloudTowerProvider = new CloudTowerProvider(butler); + boolean accessable = cloudTowerProvider.accessable(); + if (accessable) { + MetricsApi metricsApi = new MetricsApi(cloudTowerProvider.getApiClient()); + collectMfs(mfs, metricsApi, cloudVendor); + } + } catch (Exception e) { + log.error("同步监控指标报错", e); + } + } + cache.put(TIME, new Date()); + cache.put(DATA, mfs); + log.info(this.getClass().getName() + " metrics end! use " + (System.currentTimeMillis() - now.getTime()) / 1000 + "s"); + } + + protected abstract void collectMfs(List mfs, MetricsApi metricsApi, CloudVendor cloudVendor) throws Exception; + + @Override + public Map getCache() { + return this.cache; + } +} diff --git a/src/main/java/com/bocloud/mcs/collector/cloudtower/CloudTowerHostCollector.java b/src/main/java/com/bocloud/mcs/collector/cloudtower/CloudTowerHostCollector.java new file mode 100644 index 0000000..5cba0b8 --- /dev/null +++ b/src/main/java/com/bocloud/mcs/collector/cloudtower/CloudTowerHostCollector.java @@ -0,0 +1,213 @@ +package com.bocloud.mcs.collector.cloudtower; + +import com.alibaba.fastjson.JSONArray; +import com.alibaba.fastjson.JSONObject; +import com.bocloud.common.model.BocloudResult; +import com.bocloud.ims.entity.CloudVendor; +import com.bocloud.mcs.common.Constants; +import com.google.common.util.concurrent.ThreadFactoryBuilder; +import com.smartx.tower.api.MetricsApi; +import com.smartx.tower.model.GetHostMetricInput; +import com.smartx.tower.model.HostWhereInput; +import com.smartx.tower.model.Metric; +import com.smartx.tower.model.WithTaskMetric; +import io.prometheus.client.GaugeMetricFamily; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Component; + +import java.util.*; +import java.util.concurrent.*; + +@Slf4j +@Component +public class CloudTowerHostCollector extends CloudTowerCollector { + ThreadFactory nameThreadFactory = new ThreadFactoryBuilder().setNameFormat("cloudTower-host-%d").build(); + private ExecutorService executorService = new ThreadPoolExecutor(Runtime.getRuntime().availableProcessors() + 1, Runtime.getRuntime().availableProcessors() + 1, + 0L, TimeUnit.MILLISECONDS, + new LinkedBlockingQueue<>(), nameThreadFactory); + @Override + protected void collectMfs(List mfs, MetricsApi metricsApi, CloudVendor cloudVendor) { + Date now = new Date(); + List labels = Arrays.asList("vendorId", "id", "name", "instanceId"); + GaugeMetricFamily collectTimeUse = new GaugeMetricFamily(Constants.CLOUDTOWERHOSTPREFIX + "collect_time_use", "help", + Arrays.asList("type")); + try { + BocloudResult bocloudResult = cmpCloudVendorService.hostList(cloudVendor); + JSONObject data = (JSONObject) bocloudResult.getData(); + if (data == null) { + log.info("查询cloudTower宿主机为null"); + return; + } + JSONArray objects = JSONObject.parseArray(data.get("rows").toString()); + List instanceIds = new ArrayList<>(); + for (Object object : objects) { + JSONObject server = JSONObject.parseObject(object.toString()); + instanceIds.add(server.getString("uuid")); + } + String [] metrics = { + "host_cpu_overall_usage_percent", + "elf_host_vcpus_provisioned", + "host_hp_memory_usage_percent", + "elf_host_memory_provisioned_bytes", + // TODO + "zbs_chunk_data_capacity_bytes", + "zbs_chunk_used_data_space_bytes", + "zbs_chunk_read_iops", + "zbs_chunk_write_iops", + "zbs_chunk_avg_read_latency_ns", + "zbs_chunk_avg_write_latency_ns" + }; + log.info("get {} cloudTowerHOST ", objects.size()); + List>> futures = new ArrayList<>(); + for (Object object : objects) { + Future> future = executorService.submit(() -> { + List mfsOne = new ArrayList<>(); + // cpu使用率 + GaugeMetricFamily cpusUsed = new GaugeMetricFamily(Constants.CLOUDTOWERHOSTPREFIX + "host_cpu_overall_usage_percent", "help", + labels); + // cpu已使用量 + GaugeMetricFamily cpusUsedTotal = new GaugeMetricFamily(Constants.CLOUDTOWERHOSTPREFIX + "elf_host_vcpus_provisioned", "help", + labels); + // 内存使用率 + GaugeMetricFamily memUsed = new GaugeMetricFamily(Constants.CLOUDTOWERHOSTPREFIX + "host_memory_usage_percent", "help", + labels); + // 内存已使用量 + GaugeMetricFamily memUsedTotal = new GaugeMetricFamily(Constants.CLOUDTOWERHOSTPREFIX + "elf_host_memory_provisioned_bytes", "help", + labels); + + // 存储使用率 + GaugeMetricFamily storageUsed = new GaugeMetricFamily(Constants.CLOUDTOWERHOSTPREFIX + "host_storage_usage_percent", "help", + labels); + // 存储已使用量 + GaugeMetricFamily storageUsedTotal = new GaugeMetricFamily(Constants.CLOUDTOWERHOSTPREFIX + "zbs_chunk_used_data_space_bytes", "help", + labels); + + GaugeMetricFamily storeIOPSRead = new GaugeMetricFamily(Constants.CLOUDTOWERHOSTPREFIX + "zbs_chunk_read_iops", "help", + labels); + // 存储吞吐量(读) + GaugeMetricFamily storeIngestionRead = new GaugeMetricFamily(Constants.CLOUDTOWERHOSTPREFIX + "zbs_chunk_write_iops", "help", + labels); + // 主机I/O平均读延时 + GaugeMetricFamily storeAwaitRead = new GaugeMetricFamily(Constants.CLOUDTOWERHOSTPREFIX + "zbs_chunk_avg_read_latency_ns", "help", + labels); + // 主机I/O平均写延时 + GaugeMetricFamily storeIOPSWrite = new GaugeMetricFamily(Constants.CLOUDTOWERHOSTPREFIX + "zbs_chunk_avg_write_latency_ns", "help", + labels); + JSONObject server = JSONObject.parseObject(object.toString()); + if (server.getString("uuid") == null) { + log.info("当前主机信息不完善{}" ,server.getString("name")); + } else { + GetHostMetricInput getHostMetricInput = new GetHostMetricInput(); + getHostMetricInput.setMetrics(Arrays.asList(metrics)); + getHostMetricInput.setRange("2h"); + GetHostMetricInput monitors = getHostMetricInput.hosts(new HostWhereInput().id(server.getString("uuid"))); + List hostMetrics = metricsApi.getHostMetrics(monitors); + double storeTotal = 0; + for (WithTaskMetric monitor : hostMetrics) { + if (monitor.getData() == null){ + continue; + } + Metric metric = monitor.getData(); + if (metric.getSampleStreams().get(0).getPoints() == null) { + continue; + } + // cpu使用率 + if ("host_cpu_overall_usage_percent".equals(metric.getSampleStreams().get(0).getLabels().getMetricName())) { + // 取时间最大值 + double value = getV(metric); + cpusUsed.addMetric(Arrays.asList(String.valueOf(cloudVendor.getId()), server.get("id").toString(), + server.get("name").toString(), server.get("uuid").toString()), value); + } + // cpu使用量 + if ("elf_host_vcpus_provisioned".equals(metric.getSampleStreams().get(0).getLabels().getMetricName())) { + // 取时间最大值 + double value = getV(metric); + cpusUsedTotal.addMetric(Arrays.asList(String.valueOf(cloudVendor.getId()), server.get("id").toString(), + server.get("name").toString(), server.get("uuid").toString()), value); + } + // 内存使用率 + if ("host_hp_memory_usage_percent".equals(metric.getSampleStreams().get(0).getLabels().getMetricName())) { + // 取时间最大值 + double value = getV(metric); + memUsed.addMetric(Arrays.asList(String.valueOf(cloudVendor.getId()), server.get("id").toString(), + server.get("name").toString(), server.get("uuid").toString()), value); + } + // 存储使用量 + if ("zbs_chunk_used_data_space_bytes".equals(metric.getSampleStreams().get(0).getLabels().getMetricName())) { + // 取时间最大值 + double storeUsedTotalValue = getV(metric); + // 存储使用率 + storageUsed.addMetric(Arrays.asList(String.valueOf(cloudVendor.getId()), server.get("id").toString(), + server.get("name").toString(), server.get("uuid").toString()), (storeUsedTotalValue/storeTotal)*100); + // 存储使用量 + storageUsedTotal.addMetric(Arrays.asList(String.valueOf(cloudVendor.getId()), server.get("id").toString(), + server.get("name").toString(), server.get("uuid").toString()), storeUsedTotalValue); + } + if ("elf_host_memory_provisioned_bytes".equals(metric.getSampleStreams().get(0).getLabels().getMetricName())) { + // 取时间最大值 + double value = getV(metric); + memUsedTotal.addMetric(Arrays.asList(String.valueOf(cloudVendor.getId()), server.get("id").toString(), + server.get("name").toString(), server.get("uuid").toString()), value); + } + if ("zbs_chunk_read_iops".equals(metric.getSampleStreams().get(0).getLabels().getMetricName())) { + // 取时间最大值 + double value = getV(metric); + storeIOPSRead.addMetric(Arrays.asList(String.valueOf(cloudVendor.getId()), server.get("id").toString(), + server.get("name").toString(), server.get("uuid").toString()), value); + } + if ("zbs_chunk_write_iops".equals(metric.getSampleStreams().get(0).getLabels().getMetricName())) { + // 取时间最大值 + double value = getV(metric); + storeIngestionRead.addMetric(Arrays.asList(String.valueOf(cloudVendor.getId()), server.get("id").toString(), + server.get("name").toString(), server.get("uuid").toString()), value); + } + if ("zbs_chunk_avg_read_latency_ns".equals(metric.getSampleStreams().get(0).getLabels().getMetricName())) { + // 取时间最大值 + double value = getV(metric); + storeAwaitRead.addMetric(Arrays.asList(String.valueOf(cloudVendor.getId()), server.get("id").toString(), + server.get("name").toString(), server.get("uuid").toString()), value); + } + if ("zbs_chunk_avg_write_latency_ns".equals(metric.getSampleStreams().get(0).getLabels().getMetricName())) { + // 取时间最大值 + double value = getV(metric); + storeIOPSWrite.addMetric(Arrays.asList(String.valueOf(cloudVendor.getId()), server.get("id").toString(), + server.get("name").toString(), server.get("uuid").toString()), value); + } + } + mfsOne.add(cpusUsed); + mfsOne.add(cpusUsedTotal); + mfsOne.add(memUsed); + mfsOne.add(memUsedTotal); + mfsOne.add(storageUsed); + mfsOne.add(storageUsedTotal); + mfsOne.add(storeIOPSRead); + mfsOne.add(storeIngestionRead); + mfsOne.add(storeAwaitRead); + mfsOne.add(storeIOPSWrite); + } + return mfsOne; + }); + futures.add(future); + } + Optional.ofNullable(futures).orElse(new ArrayList<>()).forEach(stringFuture -> { + try { + mfs.addAll(stringFuture.get()); + } catch (Exception e) { + log.error("collect cloudTower host partition metrics error!" + e.getMessage(), e); + } + }); + collectTimeUse.addMetric(Arrays.asList("cloudTower_host"), (System.currentTimeMillis() - now.getTime())); + mfs.add(collectTimeUse); + } catch (Exception e) { + log.error(e.getMessage()); + } + log.info("collect cloudTower host partition metrics end! use " + (System.currentTimeMillis() - now.getTime()) / 1000 + "s"); + } + + private static Double getV(Metric metric) { + return metric.getSampleStreams().get(metric.getSampleStreams().size() - 1) + .getPoints() + .get(metric.getSampleStreams().get(0).getPoints().size() - 1) + .getV(); + } +} diff --git a/src/main/java/com/bocloud/mcs/collector/cloudtower/CloudTowerHostNetCollector.java b/src/main/java/com/bocloud/mcs/collector/cloudtower/CloudTowerHostNetCollector.java new file mode 100644 index 0000000..0ed5963 --- /dev/null +++ b/src/main/java/com/bocloud/mcs/collector/cloudtower/CloudTowerHostNetCollector.java @@ -0,0 +1,122 @@ +package com.bocloud.mcs.collector.cloudtower; + +import com.alibaba.fastjson.JSONArray; +import com.alibaba.fastjson.JSONObject; +import com.bocloud.common.model.BocloudResult; +import com.bocloud.ims.entity.CloudVendor; +import com.bocloud.mcs.common.Constants; +import com.google.common.util.concurrent.ThreadFactoryBuilder; +import com.smartx.tower.api.MetricsApi; +import com.smartx.tower.model.*; +import io.prometheus.client.GaugeMetricFamily; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Component; + +import java.util.*; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.*; + +@Slf4j +@Component +public class CloudTowerHostNetCollector extends CloudTowerCollector { + ThreadFactory nameThreadFactory = new ThreadFactoryBuilder().setNameFormat("cloudTower-hostNet-%d").build(); + private ExecutorService executorService = new ThreadPoolExecutor(Runtime.getRuntime().availableProcessors() + 1, Runtime.getRuntime().availableProcessors() + 1, + 0L, TimeUnit.MILLISECONDS, + new LinkedBlockingQueue<>(), nameThreadFactory); + @Override + protected void collectMfs(List mfs, MetricsApi metricsApi, CloudVendor cloudVendor) { + Date now = new Date(); + List labels = Arrays.asList("vendorId", "id", "name", "instanceId"); + // 网口数据接收速度 + GaugeMetricFamily networkReceive = new GaugeMetricFamily(Constants.CLOUDTOWERHOSTPREFIX + "host_network_receive_speed_bitps", "help",labels); + // 网口数据发送速度 + GaugeMetricFamily networkTransmit = new GaugeMetricFamily(Constants.CLOUDTOWERHOSTPREFIX + "host_network_transmit_speed_bitps", "help",labels); + + GaugeMetricFamily collectTimeUse = new GaugeMetricFamily(Constants.CLOUDTOWERHOSTPREFIX + "collect_time_use", "help", + Arrays.asList("type")); + try { + BocloudResult bocloudResult = cmpCloudVendorService.hostList(cloudVendor); + JSONObject data = (JSONObject) bocloudResult.getData(); + if (data == null) { + log.info("查询cloudTower宿主机为null"); + return; + } + JSONArray objects = JSONObject.parseArray(data.get("rows").toString()); + List instanceIds = new ArrayList<>(); + for (Object object : objects) { + JSONObject server = JSONObject.parseObject(object.toString()); + instanceIds.add(server.getString("uuid")); + } + String [] netMetrics = { + // 网口数据接收速度 + "host_network_receive_speed_bitps", + // 网口数据发送速度 + "host_network_transmit_speed_bitps" + }; + log.info("get {} cloudTowerHOST ", objects.size()); + List>> futures = new ArrayList<>(); + for (Object object : objects) { + Future> future = executorService.submit(() -> { + List mfsOne = new ArrayList<>(); + JSONObject server = JSONObject.parseObject(object.toString()); + if (server.getString("uuid") == null) { + log.info("当前主机信息不完善{}" ,server.getString("name")); + } else { + GetHostNetworkMetricInput getHostNetworkMetricInput = new GetHostNetworkMetricInput() + .hosts(new HostWhereInput().id(server.getString("uuid"))) + .range("2h") + .metrics(Arrays.asList(netMetrics)) + .nics(new NicWhereInput().id(server.getString("nicUuid"))); + List networkMetrics = metricsApi.getHostNetworkMetrics(getHostNetworkMetricInput); + for (WithTaskMetric monitor : networkMetrics) { + if (monitor.getData() == null){ + continue; + } + Metric metric = monitor.getData(); + if (metric.getSampleStreams().get(0).getPoints() == null) { + continue; + } + // 网口数据接收速度 + if ("host_network_receive_speed_bitps".equals(metric.getSampleStreams().get(0).getLabels().getMetricName())) { + // 取时间最大值 + double value = getV(metric); + networkReceive.addMetric(Arrays.asList(String.valueOf(cloudVendor.getId()), server.get("id").toString(), + server.get("name").toString(), server.get("uuid").toString()), value); + } + // 网口数据发送速度 + if ("host_network_transmit_speed_bitps".equals(metric.getSampleStreams().get(0).getLabels().getMetricName())) { + // 取时间最大值 + double value = getV(metric); + networkTransmit.addMetric(Arrays.asList(String.valueOf(cloudVendor.getId()), server.get("id").toString(), + server.get("name").toString(), server.get("uuid").toString()), value); + } + } + mfsOne.add(networkReceive); + mfsOne.add(networkTransmit); + } + return mfsOne; + }); + futures.add(future); + } + Optional.ofNullable(futures).orElse(new ArrayList<>()).forEach(stringFuture -> { + try { + mfs.addAll(stringFuture.get()); + } catch (Exception e) { + log.error("collect cloudTower hostNet partition metrics error!" + e.getMessage(), e); + } + }); + collectTimeUse.addMetric(Arrays.asList("cloudTower_host"), (System.currentTimeMillis() - now.getTime())); + mfs.add(collectTimeUse); + } catch (Exception e) { + log.error(e.getMessage()); + } + log.info("collect cloudTower hostNet partition metrics end! use " + (System.currentTimeMillis() - now.getTime()) / 1000 + "s"); + } + + private static Double getV(Metric metric) { + return metric.getSampleStreams().get(metric.getSampleStreams().size() - 1) + .getPoints() + .get(metric.getSampleStreams().get(0).getPoints().size() - 1) + .getV(); + } +} diff --git a/src/main/java/com/bocloud/mcs/collector/cloudtower/CloudTowerVmCollector.java b/src/main/java/com/bocloud/mcs/collector/cloudtower/CloudTowerVmCollector.java new file mode 100644 index 0000000..3a2a37c --- /dev/null +++ b/src/main/java/com/bocloud/mcs/collector/cloudtower/CloudTowerVmCollector.java @@ -0,0 +1,202 @@ +package com.bocloud.mcs.collector.cloudtower; + +import com.alibaba.fastjson.JSONArray; +import com.alibaba.fastjson.JSONObject; +import com.bocloud.common.model.BocloudResult; +import com.bocloud.ims.entity.CloudVendor; +import com.bocloud.mcs.common.Constants; +import com.google.common.util.concurrent.ThreadFactoryBuilder; +import com.smartx.tower.api.MetricsApi; +import com.smartx.tower.model.GetVmMetricInput; +import com.smartx.tower.model.Metric; +import com.smartx.tower.model.VmWhereInput; +import com.smartx.tower.model.WithTaskMetric; +import io.prometheus.client.GaugeMetricFamily; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Component; + +import java.util.*; +import java.util.concurrent.*; + +/** + * archeros虚拟机监控采集器 + * @author byz + * @version 1.0 + * @date 2023-06-30 + * @version 5.6.0-SNAPSHOT + */ +@Slf4j +@Component +public class CloudTowerVmCollector extends CloudTowerCollector { + ThreadFactory nameThreadFactory = new ThreadFactoryBuilder().setNameFormat("cloudTower-vm-%d").build(); + private ExecutorService executorService = new ThreadPoolExecutor(Runtime.getRuntime().availableProcessors() + 1, Runtime.getRuntime().availableProcessors() + 1, + 0L, TimeUnit.MILLISECONDS, + new LinkedBlockingQueue<>(), nameThreadFactory); + @Override + protected void collectMfs(List mfs, MetricsApi metricsApi, CloudVendor cloudVendor) throws Exception { + Date now = new Date(); + List labels = Arrays.asList("vendorId", "id", "name", "instanceId"); + GaugeMetricFamily collectTimeUse = new GaugeMetricFamily(Constants.CLOUDTOWERVMPREFIX + "collect_time_use", "help", + Arrays.asList("type")); + try { + BocloudResult bocloudResult = cmpCloudVendorService.vmtList(cloudVendor); + JSONObject data = (JSONObject) bocloudResult.getData(); + if ( data == null) { + log.info("查询cloudTower虚拟机为null"); + return; + } + JSONArray objects = JSONObject.parseArray(data.get("rows").toString()); + log.info("get {} cloudTowerVM ", objects.size()); + List hostNames = new ArrayList<>(); + JSONObject jsonObject = new JSONObject(); + jsonObject.put("range","0"); + + List instanceIds = new ArrayList<>(); + List>> futures = new ArrayList<>(); + for (Object object : objects) { + JSONObject server = JSONObject.parseObject(object.toString()); + if (server.get("instanceId") == null) { + log.info("当前云主机信息不完善{}" ,server.getString("name")); + continue; + } + instanceIds.add(server.getString("instanceId")); + } + + String [] metrics = { + "elf_vm_cpu_overall_usage_percent", + "elf_vm_cpu_overall_used_hz", + "elf_vm_memory_usage_percent", + "elf_vm_memory_used_bytes", + "elf_vm_network_receive_packets", + "elf_vm_network_transmit_packets", + "elf_vm_disk_overall_read_iops", + "elf_vm_disk_overall_write_iops", + }; + for (Object object : objects) { + Future> future = executorService.submit(() -> { + List mfsOne = new ArrayList<>(); + // cpu使用率 + GaugeMetricFamily cpuUsed = new GaugeMetricFamily(Constants.CLOUDTOWERVMPREFIX + "elf_vm_cpu_overall_usage_percent", "help", + labels); + // 虚拟机CPU使用频率 + GaugeMetricFamily cpuUsedTotal = new GaugeMetricFamily(Constants.CLOUDTOWERVMPREFIX + "elf_vm_cpu_overall_used_hz", "help", + labels); + // 内存使用率 + GaugeMetricFamily memUsed = new GaugeMetricFamily(Constants.CLOUDTOWERVMPREFIX + "elf_vm_memory_usage_percent", "help", + labels); + // 虚拟机内存使用量 + GaugeMetricFamily memUsedTotal = new GaugeMetricFamily(Constants.CLOUDTOWERVMPREFIX + "elf_vm_memory_used_bytes", "help", + labels); + // 网络吞吐量(流入) + GaugeMetricFamily netIngestionIn = new GaugeMetricFamily(Constants.CLOUDTOWERVMPREFIX + "elf_vm_network_receive_packets", "help", + labels); + // 网络吞吐量(流出) + GaugeMetricFamily netIngestionOut = new GaugeMetricFamily(Constants.CLOUDTOWERVMPREFIX + "elf_vm_network_transmit_packets", "help", + labels); + // 磁盘吞吐量(读) + GaugeMetricFamily diskIngestionRead = new GaugeMetricFamily(Constants.CLOUDTOWERVMPREFIX + "elf_vm_disk_overall_read_iops", "help", + labels); + // 磁盘吞吐量(写) + GaugeMetricFamily diskIngestionWrite = new GaugeMetricFamily(Constants.CLOUDTOWERVMPREFIX + "elf_vm_disk_overall_write_iops", "help", + labels); + JSONObject cloudServer = JSONObject.parseObject(object.toString()); + if (cloudServer.get("instanceId") == null) { + log.info("当前云主机信息不完善{}" ,cloudServer.getString("name")); + } else { + GetVmMetricInput getVmMetricInput = new GetVmMetricInput(); + getVmMetricInput.setMetrics(Arrays.asList(metrics)); + getVmMetricInput.setRange("2h"); + GetVmMetricInput monitors = getVmMetricInput.vms(new VmWhereInput().id(cloudServer.getString("instanceId"))); + List vmMetrics = metricsApi.getVmMetrics(monitors); + for (WithTaskMetric monitor : vmMetrics) { + if (monitor.getData() == null){ + continue; + } + Metric metric = monitor.getData(); + if (metric.getSampleStreams().get(0).getPoints() == null) { + continue; + } + // cpu使用率 + if ("elf_vm_cpu_overall_usage_percent".equals(metric.getSampleStreams().get(0).getLabels().getMetricName())) { + // 取时间最大值 + double value = getV(metric); + cpuUsed.addMetric(Arrays.asList(String.valueOf(cloudVendor.getId()), cloudServer.get("id").toString(), + cloudServer.get("name").toString(), cloudServer.get("instanceId").toString()), value); + } + if ("elf_vm_cpu_overall_used_hz".equals(metric.getSampleStreams().get(0).getLabels().getMetricName())) { + // 取时间最大值 + double value = getV(metric); + cpuUsedTotal.addMetric(Arrays.asList(String.valueOf(cloudVendor.getId()), cloudServer.get("id").toString(), + cloudServer.get("name").toString(), cloudServer.get("instanceId").toString()), value); + } + if ("elf_vm_memory_usage_percent".equals(metric.getSampleStreams().get(0).getLabels().getMetricName())) { + // 取时间最大值 + double value = getV(metric); + memUsed.addMetric(Arrays.asList(String.valueOf(cloudVendor.getId()), cloudServer.get("id").toString(), + cloudServer.get("name").toString(), cloudServer.get("instanceId").toString()), value); + } + if ("elf_vm_memory_used_bytes".equals(metric.getSampleStreams().get(0).getLabels().getMetricName())) { + // 取时间最大值 + double value = getV(metric); + memUsedTotal.addMetric(Arrays.asList(String.valueOf(cloudVendor.getId()), cloudServer.get("id").toString(), + cloudServer.get("name").toString(), cloudServer.get("instanceId").toString()), value); + } + if ("elf_vm_network_receive_packets".equals(metric.getSampleStreams().get(0).getLabels().getMetricName())) { + // 取时间最大值 + double value = getV(metric); + netIngestionIn.addMetric(Arrays.asList(String.valueOf(cloudVendor.getId()), cloudServer.get("id").toString(), + cloudServer.get("name").toString(), cloudServer.get("instanceId").toString()), value); + } + if ("elf_vm_network_transmit_packets".equals(metric.getSampleStreams().get(0).getLabels().getMetricName())) { + // 取时间最大值 + double value = getV(metric); + netIngestionOut.addMetric(Arrays.asList(String.valueOf(cloudVendor.getId()), cloudServer.get("id").toString(), + cloudServer.get("name").toString(), cloudServer.get("instanceId").toString()), value); + } + if ("elf_vm_disk_overall_read_iops".equals(metric.getSampleStreams().get(0).getLabels().getMetricName())) { + // 取时间最大值 + double value = getV(metric); + diskIngestionRead.addMetric(Arrays.asList(String.valueOf(cloudVendor.getId()), cloudServer.get("id").toString(), + cloudServer.get("name").toString(), cloudServer.get("instanceId").toString()), value); + } + if ("elf_vm_disk_overall_write_iops".equals(metric.getSampleStreams().get(0).getLabels().getMetricName())) { + // 取时间最大值 + double value = getV(metric); + diskIngestionWrite.addMetric(Arrays.asList(String.valueOf(cloudVendor.getId()), cloudServer.get("id").toString(), + cloudServer.get("name").toString(), cloudServer.get("instanceId").toString()), value); + } + } + mfsOne.add(cpuUsed); + mfsOne.add(cpuUsedTotal); + mfsOne.add(memUsed); + mfsOne.add(memUsedTotal); + mfsOne.add(diskIngestionRead); + mfsOne.add(diskIngestionWrite); + mfsOne.add(netIngestionIn); + mfsOne.add(netIngestionOut); + } + return mfsOne; + }); + futures.add(future); + } + Optional.ofNullable(futures).orElse(new ArrayList<>()).forEach(stringFuture -> { + try { + mfs.addAll(stringFuture.get()); + } catch (Exception e) { + } + }); + collectTimeUse.addMetric(Arrays.asList("cloudTower_vm"), (System.currentTimeMillis() - now.getTime())); + mfs.add(collectTimeUse); + } catch (Exception e) { + log.error(e.getMessage()); + } + log.info("collect cloudTower vm partition metrics end! use " + (System.currentTimeMillis() - now.getTime()) / 1000 + "s"); + } + private static Double getV(Metric metric) { + return metric.getSampleStreams().get(metric.getSampleStreams().size() - 1) + .getPoints() + .get(metric.getSampleStreams().get(0).getPoints().size() - 1) + .getV(); + } +} + diff --git a/src/main/java/com/bocloud/mcs/collector/cloudtower/CloudTowerVmNetCollector.java b/src/main/java/com/bocloud/mcs/collector/cloudtower/CloudTowerVmNetCollector.java new file mode 100644 index 0000000..1bd1d34 --- /dev/null +++ b/src/main/java/com/bocloud/mcs/collector/cloudtower/CloudTowerVmNetCollector.java @@ -0,0 +1,122 @@ +package com.bocloud.mcs.collector.cloudtower; + +import com.alibaba.fastjson.JSONArray; +import com.alibaba.fastjson.JSONObject; +import com.bocloud.common.model.BocloudResult; +import com.bocloud.ims.entity.CloudVendor; +import com.bocloud.mcs.common.Constants; +import com.google.common.util.concurrent.ThreadFactoryBuilder; +import com.smartx.tower.api.MetricsApi; +import com.smartx.tower.model.*; +import io.prometheus.client.GaugeMetricFamily; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Component; + +import java.util.*; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.*; + +@Slf4j +@Component +public class CloudTowerVmNetCollector extends CloudTowerCollector { + ThreadFactory nameThreadFactory = new ThreadFactoryBuilder().setNameFormat("cloudTower-vmNet-%d").build(); + private ExecutorService executorService = new ThreadPoolExecutor(Runtime.getRuntime().availableProcessors() + 1, Runtime.getRuntime().availableProcessors() + 1, + 0L, TimeUnit.MILLISECONDS, + new LinkedBlockingQueue<>(), nameThreadFactory); + @Override + protected void collectMfs(List mfs, MetricsApi metricsApi, CloudVendor cloudVendor) throws Exception { + Date now = new Date(); + List labels = Arrays.asList("vendorId", "id", "name", "instanceId"); + GaugeMetricFamily collectTimeUse = new GaugeMetricFamily(Constants.CLOUDTOWERVMPREFIX + "collect_time_use", "help", + Arrays.asList("type")); + try { + BocloudResult bocloudResult = cmpCloudVendorService.vmtList(cloudVendor); + JSONObject data = (JSONObject) bocloudResult.getData(); + if ( data == null) { + log.info("查询cloudTower虚拟机为null"); + return; + } + JSONArray objects = JSONObject.parseArray(data.get("rows").toString()); + log.info("get {} cloudTowerVM ", objects.size()); + List hostNames = new ArrayList<>(); + JSONObject jsonObject = new JSONObject(); + jsonObject.put("range","0"); + + List instanceIds = new ArrayList<>(); + String [] netMetrics = { + // 接收 + "elf_vm_network_receive_speed_bps", + // 发送 + "elf_vm_network_transmit_speed_bps" + }; + List>> futures = new ArrayList<>(); + for (Object object : objects) { + Future> future = executorService.submit(() -> { + List mfsOne = new ArrayList<>(); + // 网口数据接收速度 + GaugeMetricFamily vmNetReceived = new GaugeMetricFamily(Constants.CLOUDTOWERVMPREFIX + "elf_vm_network_receive_speed_bps", "help", + labels); + // 网口数据发送速度 + GaugeMetricFamily vmNetTransmitted = new GaugeMetricFamily(Constants.CLOUDTOWERVMPREFIX + "elf_vm_network_transmit_speed_bps", "help", + labels); + JSONObject cloudServer = JSONObject.parseObject(object.toString()); + if (cloudServer.get("instanceId") == null) { + log.info("当前云主机信息不完善{}" ,cloudServer.getString("name")); + } else { + GetVmNetWorkMetricInput getVmNetWorkMetricInput = new GetVmNetWorkMetricInput() + .range("2h") + .metrics(Arrays.asList(netMetrics)) + .vms(new VmWhereInput().id(cloudServer.getString("instanceId"))) + .nics(new VmNicWhereInput().id(Optional.ofNullable(cloudServer.getString("nicUuid")).orElse(""))); + List vmNetMetrics = metricsApi.getVmNetWorkMetrics(getVmNetWorkMetricInput); + for (WithTaskMetric vmNetMetric : vmNetMetrics) { + if (vmNetMetric.getData() == null){ + continue; + } + Metric metric = vmNetMetric.getData(); + if (metric.getSampleStreams().get(0).getPoints() == null) { + continue; + } + // 网口数据接收速度 + if ("elf_vm_network_receive_speed_bps".equals(metric.getSampleStreams().get(0).getLabels().getMetricName())) { + // 取时间最大值 + double value = getV(metric); + vmNetReceived.addMetric(Arrays.asList(String.valueOf(cloudVendor.getId()), cloudServer.get("id").toString(), + cloudServer.get("name").toString(), cloudServer.get("instanceId").toString()), value); + } + // 网口数据发送速度 + if ("elf_vm_network_transmit_speed_bps".equals(metric.getSampleStreams().get(0).getLabels().getMetricName())) { + // 取时间最大值 + double value = getV(metric); + vmNetTransmitted.addMetric(Arrays.asList(String.valueOf(cloudVendor.getId()), cloudServer.get("id").toString(), + cloudServer.get("name").toString(), cloudServer.get("instanceId").toString()), value); + } + } + mfsOne.add(vmNetReceived); + mfsOne.add(vmNetTransmitted); + } + return mfsOne; + }); + futures.add(future); + } + Optional.ofNullable(futures).orElse(new ArrayList<>()).forEach(stringFuture -> { + try { + mfs.addAll(stringFuture.get()); + } catch (Exception e) { + } + }); + collectTimeUse.addMetric(Arrays.asList("cloudTower_vm"), (System.currentTimeMillis() - now.getTime())); + mfs.add(collectTimeUse); + } catch (Exception e) { + log.error(e.getMessage()); + } + log.info("collect cloudTower vmNet partition metrics end! use " + (System.currentTimeMillis() - now.getTime()) / 1000 + "s"); + + } + private static Double getV(Metric metric) { + return metric.getSampleStreams().get(metric.getSampleStreams().size() - 1) + .getPoints() + .get(metric.getSampleStreams().get(0).getPoints().size() - 1) + .getV(); + } +} diff --git a/src/main/java/com/bocloud/mcs/common/Constants.java b/src/main/java/com/bocloud/mcs/common/Constants.java index 895a0d9..88a5a14 100644 --- a/src/main/java/com/bocloud/mcs/common/Constants.java +++ b/src/main/java/com/bocloud/mcs/common/Constants.java @@ -15,4 +15,10 @@ public class Constants { public static final String BOCLOUD_SMIS = "bocloud_smis_"; + public static final String CLOUDTOWERVMPREFIX = "bocloud_cloudtower_vm_"; + + public static final String CLOUDTOWERHOSTPREFIX = "bocloud_cloudtower_host_"; + + + } diff --git a/src/main/java/com/bocloud/mcs/service/internal/CmpCloudVendorService.java b/src/main/java/com/bocloud/mcs/service/internal/CmpCloudVendorService.java index bad6dba..3148198 100644 --- a/src/main/java/com/bocloud/mcs/service/internal/CmpCloudVendorService.java +++ b/src/main/java/com/bocloud/mcs/service/internal/CmpCloudVendorService.java @@ -5,6 +5,7 @@ import com.bocloud.common.enums.BoCloudMethod; import com.bocloud.common.enums.BoCloudService; import com.bocloud.common.model.*; import com.bocloud.common.utils.MapTools; +import com.bocloud.ims.entity.CloudVendor; import com.bocloud.ims.enums.CloudProvider; import com.bocloud.service.core.CurrentService; import com.bocloud.service.core.Service; @@ -53,6 +54,22 @@ public class CmpCloudVendorService implements InitializingBean { return remoteService.invoke(); } + public BocloudResult vmtList(CloudVendor cloudVendor) { + List paramList = new ArrayList<>(); + paramList.add(new Param(MapTools.simpleMap("vendor_id", cloudVendor.getId()), Sign.EQ)); + RemoteService remoteService = serviceFactory.build(service, "/v1/vms", BoCloudMethod.GET, headers, + new Pager(1, Integer.MAX_VALUE, paramList, null).toMap(false)); + return remoteService.invoke(); + } + + public BocloudResult hostList(CloudVendor cloudVendor) { + List paramList = new ArrayList<>(); + paramList.add(new Param(MapTools.simpleMap("vendor_id", cloudVendor.getId()), Sign.EQ)); + RemoteService remoteService = serviceFactory.build(service, "/v1/hosts", BoCloudMethod.GET, headers, + new Pager(1, Integer.MAX_VALUE, paramList, null).toMap(false)); + return remoteService.invoke(); + } + @Override public void afterPropertiesSet() throws Exception { this.headers.put(BocloudToken.INTERNAL_TOKEN, currentService.getToken());