Initial commit all

develop
Hoshi 2024-08-20 17:57:29 +08:00
parent a16d527fe4
commit f8bb30669b
63 changed files with 5211 additions and 0 deletions

1
README.md Normal file
View File

@ -0,0 +1 @@
Metrics Collection Service

400
pom.xml Normal file
View File

@ -0,0 +1,400 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<groupId>com.freedom</groupId>
<artifactId>megatron</artifactId>
<version>3.0.0</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>com.bocloud</groupId>
<artifactId>bocloud.mcs.booter</artifactId>
<version>${bocloud.booter.version}</version>
<name>bocloud.mcs</name>
<description>BoCloud Exporter</description>
<properties>
<java.version>21</java.version>
<bocloud.boot.common.version>6.5.0-LTS</bocloud.boot.common.version>
<commons-dbutils.version>1.7</commons-dbutils.version>
<prometheus.version>0.6.0</prometheus.version>
<openstack4j.version>3.2.0</openstack4j.version>
<oracle.version>11.2.0.3</oracle.version>
<huawei.version>3.0.30-rc</huawei.version>
<vijava.version>6.5.1</vijava.version>
<log4j.version>1.2.17</log4j.version>
<snmp4j.version>2.5.11</snmp4j.version>
<dom4j.version>2.1.1</dom4j.version>
<aliyun.cms20190101.version>1.0.1</aliyun.cms20190101.version>
<aliyun.tea.version>1.2.0</aliyun.tea.version>
<baidubce.version>0.10.192</baidubce.version>
<awssdk.version>2.15.35</awssdk.version>
<okhttp-version>4.9.2</okhttp-version>
</properties>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>com.ksyun</groupId>
<artifactId>ksc-sdk-java-bom</artifactId>
<version>0.3.31</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<!--for spring boot 3-->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>2.0.7</version>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents.client5</groupId>
<artifactId>httpclient5</artifactId>
</dependency>
<dependency>
<groupId>jdk.tools</groupId>
<artifactId>jdk.tools</artifactId>
<version>1.6</version>
</dependency>
<!-- zstack 依赖-->
<dependency>
<groupId>com.zstack</groupId>
<artifactId>zstack.sdk</artifactId>
<version>4.4.0</version>
</dependency>
<dependency>
<groupId>com.smartx.tower</groupId>
<artifactId>cloudtower-java-sdk</artifactId>
<version>2.8.0</version>
</dependency>
<dependency>
<groupId>org.threeten</groupId>
<artifactId>threetenbp</artifactId>
<version>1.5.0</version>
</dependency>
<dependency>
<groupId>io.gsonfire</groupId>
<artifactId>gson-fire</artifactId>
<version>1.8.3</version>
</dependency>
<dependency>
<groupId>com.squareup.okhttp3</groupId>
<artifactId>okhttp</artifactId>
<version>${okhttp-version}</version>
</dependency>
<dependency>
<groupId>com.squareup.okhttp3</groupId>
<artifactId>logging-interceptor</artifactId>
<version>${okhttp-version}</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.libvirt/libvirt -->
<dependency>
<groupId>org.libvirt</groupId>
<artifactId>libvirt</artifactId>
<version>0.5.3.bocloud</version>
</dependency>
<!-- https://mvnrepository.com/artifact/net.java.dev.jna/jna -->
<dependency>
<groupId>org.jsoup</groupId>
<artifactId>jsoup</artifactId>
<version>1.13.1</version>
</dependency>
<dependency>
<groupId>com.freedom</groupId>
<artifactId>megatron.microservice</artifactId>
<version>3.0.0</version>
</dependency>
<dependency>
<groupId>com.freedom</groupId>
<artifactId>megatron.framework</artifactId>
</dependency>
<dependency>
<groupId>com.freedom</groupId>
<artifactId>megatron.common</artifactId>
</dependency>
<dependency>
<groupId>com.bocloud</groupId>
<artifactId>bocloud.boot.common</artifactId>
<version>${bocloud.boot.common.version}</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>${jackson.version}</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.dataformat</groupId>
<artifactId>jackson-dataformat-yaml</artifactId>
<version>${jackson.version}</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>io.prometheus</groupId>
<artifactId>simpleclient</artifactId>
<version>${prometheus.version}</version>
</dependency>
<dependency>
<groupId>io.prometheus</groupId>
<artifactId>simpleclient_common</artifactId>
<version>${prometheus.version}</version>
</dependency>
<dependency>
<groupId>org.pacesys</groupId>
<artifactId>openstack4j</artifactId>
<version>${openstack4j.version}</version>
</dependency>
<dependency>
<groupId>com.oracle</groupId>
<artifactId>ojdbc6</artifactId>
<version>${oracle.version}</version>
</dependency>
<dependency>
<groupId>commons-dbutils</groupId>
<artifactId>commons-dbutils</artifactId>
<version>${commons-dbutils.version}</version>
</dependency>
<dependency>
<groupId>com.bocloud</groupId>
<artifactId>bocloud.vijava</artifactId>
<version>${vijava.version}</version>
</dependency>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>${log4j.version}</version>
</dependency>
<dependency>
<groupId>org.dom4j</groupId>
<artifactId>dom4j</artifactId>
<version>${dom4j.version}</version>
</dependency>
<dependency>
<groupId>org.snmp4j</groupId>
<artifactId>snmp4j</artifactId>
<version>${snmp4j.version}</version>
</dependency>
<dependency>
<groupId>com.huaweicloud.sdk</groupId>
<artifactId>huaweicloud-sdk-ecs</artifactId>
<version>${huawei.version}</version>
</dependency>
<dependency>
<groupId>com.huaweicloud.sdk</groupId>
<artifactId>huaweicloud-sdk-iam</artifactId>
<version>${huawei.version}</version>
</dependency>
<dependency>
<groupId>com.aliyun</groupId>
<artifactId>cms20190101</artifactId>
<version>${aliyun.cms20190101.version}</version>
</dependency>
<dependency>
<groupId>com.aliyun</groupId>
<artifactId>tea</artifactId>
<version>${aliyun.tea.version}</version>
</dependency>
<!-- baidu -->
<dependency>
<groupId>com.baidubce</groupId>
<artifactId>bce-java-sdk</artifactId>
<version>${baidubce.version}</version>
</dependency>
<!-- aws -->
<dependency>
<groupId>software.amazon.awssdk</groupId>
<artifactId>cloudwatch-metric-publisher</artifactId>
<version>${awssdk.version}</version>
</dependency>
<dependency>
<groupId>software.amazon.awssdk</groupId>
<artifactId>ec2</artifactId>
<version>${awssdk.version}</version>
</dependency>
<dependency>
<groupId>com.huaweicloud.sdk</groupId>
<artifactId>huaweicloud-sdk-ecs</artifactId>
<version>${huawei.version}</version>
</dependency>
<!-- 华为云 -->
<dependency>
<groupId>com.huaweicloud.sdk</groupId>
<artifactId>huaweicloud-sdk-ces</artifactId>
<version>${huawei.version}</version>
</dependency>
<dependency>
<groupId>com.huaweicloud.sdk</groupId>
<artifactId>huaweicloud-sdk-iam</artifactId>
<version>${huawei.version}</version>
</dependency>
<dependency>
<groupId>com.huaweicloud.sdk</groupId>
<artifactId>huaweicloud-sdk-rds</artifactId>
<version>${huawei.version}</version>
</dependency>
<dependency>
<groupId>com.huaweicloud.sdk</groupId>
<artifactId>huaweicloud-sdk-as</artifactId>
<version>${huawei.version}</version>
</dependency>
<dependency>
<groupId>com.huaweicloud.sdk</groupId>
<artifactId>huaweicloud-sdk-eip</artifactId>
<version>${huawei.version}</version>
</dependency>
<dependency>
<groupId>com.huaweicloud.sdk</groupId>
<artifactId>huaweicloud-sdk-evs</artifactId>
<version>${huawei.version}</version>
</dependency>
<dependency>
<groupId>com.huaweicloud.sdk</groupId>
<artifactId>huaweicloud-sdk-nat</artifactId>
<version>${huawei.version}</version>
</dependency>
<dependency>
<groupId>com.huaweicloud.sdk</groupId>
<artifactId>huaweicloud-sdk-elb</artifactId>
<version>${huawei.version}</version>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
</dependency>
<dependency>
<groupId>com.moandjiezana.toml</groupId>
<artifactId>toml4j</artifactId>
<version>0.7.2</version>
</dependency>
<dependency>
<groupId>com.aliyun</groupId>
<artifactId>asapi</artifactId>
<version>1.0.6.7-RELEASE</version>
<classifier>RELEASE</classifier>
</dependency>
<dependency>
<groupId>com.aliyun</groupId>
<artifactId>gmsse</artifactId>
<version>1.1.0</version>
</dependency>
<dependency>
<groupId>com.ksyun</groupId>
<artifactId>ksyun-java-sdk</artifactId>
<version>1.0.6</version>
</dependency>
<dependency>
<groupId>com.qingcloud</groupId>
<artifactId>qingcloud-sdk-java</artifactId>
<version>1.2.2</version>
</dependency>
<dependency>
<groupId>com.ksyun</groupId>
<artifactId>ksc-sdk-java-kec</artifactId>
</dependency>
<dependency>
<groupId>com.ksyun</groupId>
<artifactId>ksc-sdk-java-monitor</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.11.0</version>
<configuration>
<parameters>true</parameters>
<source>21</source>
<target>21</target>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>3.3.0</version>
<configuration>
<archive>
<manifest>
<mainClass>com.bocloud.mcs.Application</mainClass>
<addClasspath>true</addClasspath>
<useUniqueVersions>false</useUniqueVersions>
<classpathPrefix>libs/</classpathPrefix>
</manifest>
</archive>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<version>3.6.1</version>
<executions>
<execution>
<goals>
<goal>copy-dependencies</goal>
</goals>
<configuration>
<type>jar</type>
<includeTypes>jar</includeTypes>
<includeScope>runtime</includeScope>
<outputDirectory>${project.build.directory}/libs</outputDirectory>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
<profiles>
<profile>
<id>bocloud.booter.tomcat</id>
<properties>
<bocloud.booter.version>6.5.0-LTS-SZ</bocloud.booter.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<exclusions>
<exclusion>
<groupId>org.hibernate.validator</groupId>
<artifactId>hibernate-validator</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencies>
</profile>
<profile>
<id>bocloud.booter.tongweb</id>
<properties>
<bocloud.booter.version>6.5.0-LTS-SZ-TONGWEB</bocloud.booter.version>
</properties>
<dependencies>
<dependency>
<groupId>com.tongweb</groupId>
<artifactId>tongweb-embed</artifactId>
<version>7.0.E.2</version>
</dependency>
<dependency>
<groupId>com.tongweb.springboot</groupId>
<artifactId>tongweb-spring-boot-starter</artifactId>
<version>2.x.0.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<exclusions>
<exclusion>
<groupId>org.hibernate.validator</groupId>
<artifactId>hibernate-validator</artifactId>
</exclusion>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencies>
</profile>
</profiles>
</project>

View File

@ -0,0 +1,23 @@
package com.bocloud.cms.entity;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor;
/**
*
* Created by liuyuanyuan on 2019/10/23 17:46
*/
@Data
@NoArgsConstructor
@AllArgsConstructor
@EqualsAndHashCode
public class MonitorAuth {
private Long id; // ID
private String address;
private String username;
private String password;
private Long vendorId;
}

View File

@ -0,0 +1,207 @@
package com.bocloud.ims.entity;
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.megatron.common.utils.DateDeserializer;
import com.megatron.common.utils.DateSerializer;
import lombok.Data;
import lombok.EqualsAndHashCode;
import org.springframework.format.annotation.DateTimeFormat;
import java.math.BigDecimal;
import java.util.Date;
/**
*
*
* @author wangyu
*/
@Data
@EqualsAndHashCode
public class CloudVendor {
@JsonSerialize(using = DateSerializer.class)
@JsonDeserialize(using = DateDeserializer.class)
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private Date gmtCreate;
@JsonSerialize(using = DateSerializer.class)
@JsonDeserialize(using = DateDeserializer.class)
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private Date gmtModify;
private Long creatorId;
private Long ownerId;
private Long menderId;
private String name;
private String status;
private Boolean deleted;
private String props;
private String remark;
private Long id; // ID
private String type; // 平台类型
private Long envId;// 所在环境
private String uuid; // butler uuid
private String guid;// 全局唯一标识
private Boolean isAlarm;// 是否开启告警
private Boolean isPublic;// 是否为公有云
private String syncCron;// 云平台同步任务cron
private Long dcId;// 数据中心id
private String version;// 版本
private String logo;// 平台图标
private String vendorCategory;// 平台分类
private String authentication;// 平台认证信息(address,account,password,tenant,access_key,secret_key,domain_name,project_name,region_id,regions,management_ips,subscription_id,client_id,token)
private String region;// 区域
private String availablitiyZone;// 可用域
private String location; // 站点位置
private String supplier; // 供应商
private String dockerAddress; // 供应商
private String remoteSite; // 远程站点
private String deployUrl; // 部署机url
private String deployUsername; // 部署机用户名
private String deployPassword; // 部署机密码
private Long harborId;
private String harborName;
private String regionsName;
private String envName;
private String dcName;
private Long instance; // 实例数量
private Long online; // 在线
private Long offline; // 离线
private Long hostCount;// 主机数量
private Long dataStoreCount;// 数据存储数量
private Long templateCount;// 模板数量
private Long clusterCount;// 集群数量
private Long imageCount;// 镜像数量
private Long cpuCount;// cpu核数
private Long monCount;// 控制节点数量
private Long osdCount; // osd节点数量
private Long mdsCount;// mds节点数量
private Long cpuTotal; // cpu总赫兹
private Long cpuUsed;
private Long cpuUnused;
private BigDecimal memTotal;// 总内存
private BigDecimal memUsed;
private BigDecimal memUnused;
private BigDecimal diskTotal;
private BigDecimal diskUsed;
private BigDecimal diskUnused;
private Long tenantCount;// 租户数量
private Long networkCount;// 网络数量
private Long vsCount;// virtual server数量
private Long poolCount;// pool数量
private Long nodeCount;// node数量
private Long profileCount;// profile数量
private Long monitorCount;// monitor数量
private Long vpcCount; // vpc数量
private Long lparCount;// 逻辑分区数量
private Long viosCount; // 虚拟IO服务器数量
private Long mdiskCount; // mdisk数量
private Long flashCopyCount;// FlashCopy数量
private Long fabricCount;// 光纤交换机数量
private Long zoneCount; // zone的数量
private Long nsCount; // k8s namespace count
private Long podCount;
private Long serviceCount;
private Long deploymentCount;
private Long aliasCount; // 别名的数量
private Long accessPathCount;
private Long edgeClusterCount;// edge集群
private Long groupCount;// NS组
private Long transportZoneCount;// 传输区域
private Long firewallCount;// 防火墙
private Long routerCount;// 路由器
private Long switchCount;// 交换机
private Long objectUserCount;// 对象用户
private Long objectBucketCount;// 存储桶
private Long objectRouterCount;// 对象路由
private Long fileUserCount; // xsky 文件用户
private Long fileClientCount; // xsky 文件客户端
private Long snapshotCount; // 快照
private Long fileSystemCount; // 文件系统数量
private Long logicPortCount; // 逻辑端口
private Long vasCount; // 逻辑vas
private Long dbCount; // 堡垒机-数据库数量
private Long appCount; // 堡垒机-应用数量
private Long sessionCount; // 堡垒机-会话数量
/********** vmware horizon桌面池统计 **************/
private Long desktopPools;
private Long farms;
private Long sessions;
private Long users;
private Long vcenters;
private Long vendorGroupId;
}

View File

@ -0,0 +1,25 @@
package com.bocloud.ims.entity;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
/**
*
*
* @author YuFengYang
* @version 1.0
* @since 2022/12/30 16:22
*/
@Data
@NoArgsConstructor
@AllArgsConstructor
public class KvmHost {
private String uri;
private Long vendorId;
private Long id;
}

View File

@ -0,0 +1,17 @@
package com.bocloud.ims.enums;
/**
*
*
* @author wangyu
* @version 1.0
* @since 2020131
* @since 202059 modify by aile XSKY
*/
public enum CloudProvider {
OPENSTACK, VMWARE, ALIYUN, JDCLOUD, UNKNOWN, CEPH, SCP, CAS, 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,BAIDU,EASYSTACK,HCSO, APSARASTACK,HWACCESS,KVM,
CNWARE,ZSTACK,CLOUDTOWER,CTSTACK;
}

View File

@ -0,0 +1,21 @@
package com.bocloud.mcs;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.scheduling.annotation.EnableScheduling;
/**
*
*
* @author zhangyf
*/
@SpringBootApplication
@ComponentScan(value = {"com.bocloud", "com.megatron"})
@EnableScheduling
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}

View File

@ -0,0 +1,53 @@
package com.bocloud.mcs.aspect;
import com.megatron.framework.core.CurrentService;
import lombok.RequiredArgsConstructor;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.context.EnvironmentAware;
import org.springframework.core.env.Environment;
import org.springframework.stereotype.Component;
/**
*
*
* @author lym
* @since 2022/07/18
*/
@Aspect
@Component
@RequiredArgsConstructor
@Slf4j
public class AccessAspect implements EnvironmentAware {
private final CurrentService currentService;
private Environment environment;
@Override
public void setEnvironment(Environment environment) {
this.environment = environment;
}
@SneakyThrows
@Around("@annotation(com.bocloud.mcs.aspect.EnableCollector)")
public Object logAround(ProceedingJoinPoint joinPoint) {
String methodName = joinPoint.getSignature().getName();
EnableCollector annotation = joinPoint.getSignature().getDeclaringType().getMethod(methodName).getAnnotation(EnableCollector.class);
String value = environment.resolvePlaceholders(annotation.value());
if (Boolean.FALSE.equals(Boolean.valueOf(value))) {
return false;
}
// 是否支持切片,如果不支持,则只允许主节点执行
if (!annotation.section()) {
if (!currentService.isLeader()) {
log.debug("The current node is not the leader node");
return false;
}
}
return joinPoint.proceed();
}
}

View File

@ -0,0 +1,24 @@
package com.bocloud.mcs.aspect;
import java.lang.annotation.*;
/**
*
*
* @author lym
* @since 2022/07/18
*/
@Documented
@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface EnableCollector {
String value() default "true";
/**
*
*
* @return
*/
boolean section() default false;
}

View File

@ -0,0 +1,87 @@
package com.bocloud.mcs.collector;
import com.bocloud.mcs.service.internal.CmpCloudVendorService;
import com.megatron.framework.core.CurrentService;
import com.megatron.framework.core.Service;
import com.moandjiezana.toml.Toml;
import io.prometheus.client.Collector;
import lombok.Getter;
import org.apache.commons.lang3.time.DateUtils;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.client.discovery.DiscoveryClient;
import java.util.*;
/**
*
*
* @author zhangyf
*/
public abstract class BocloudCollector extends Collector implements Collector.Describable, InitializingBean {
protected static final String TIME = "time";
protected static final String DATA = "data";
@Autowired
protected CmpCloudVendorService cmpCloudVendorService;
@Autowired
protected DiscoveryClient discoveryClient;
@Autowired
protected CurrentService currentService;
@Autowired
protected Service service;
@Autowired
@SuppressWarnings("SpringJavaInjectionPointsAutowiringInspection")
protected Toml collectorConfig;
/**
*
*/
@Getter
private final Map<String, Object> cache = new HashMap<>();
/**
* 10
*/
protected static final int DEFAULT_EXPIRE = 600;
/**
*
*/
@Getter
private int expire = DEFAULT_EXPIRE;
@SuppressWarnings("unchecked")
@Override
public List<MetricFamilySamples> collect() {
if (getCache() != null && getCache().size() > 0) {
Date now = new Date();
Date time = (Date) getCache().get(TIME);
// 数据过期
if (now.getTime() > DateUtils.addSeconds(time, this.getExpire()).getTime()) {
return new ArrayList<>();
} else {
return (List<MetricFamilySamples>) getCache().get(DATA);
}
} else {
return new ArrayList<>();
}
}
/**
*
*/
public abstract void scheduledCollect();
@Override
public List<MetricFamilySamples> describe() {
return new ArrayList<>();
}
@Override
public void afterPropertiesSet() {
register();
}
}

View File

@ -0,0 +1,44 @@
package com.bocloud.mcs.collector.kvm;
import lombok.extern.slf4j.Slf4j;
import org.libvirt.Connect;
import org.libvirt.LibvirtException;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
@Slf4j
public class ConnectHolder {
private static final Map<String, Connect> map = new HashMap<>();
private static Lock lock = new ReentrantLock();
private static boolean validate(String url, Connect connect) {
if (connect == null) return false;
try {
if (!connect.isConnected()) return false;
if (!connect.isAlive()) return false;
connect.getHostName();
return true;
} catch (LibvirtException e) {
log.error("connect {} is not avaliable, message: {}", url, e.getMessage(), e);
return false;
}
}
public static Connect getConnect(String url) throws LibvirtException {
lock.lock();
try {
if (!validate(url, map.get(url))) {
log.info("connect {} is not avaliable, recreate", url);
map.put(url, new Connect(url));
}
log.debug("connect urls: {}", String.join(",", map.keySet()));
return map.get(url);
} finally {
lock.unlock();
}
}
}

View File

@ -0,0 +1,116 @@
package com.bocloud.mcs.collector.kvm;
import com.bocloud.mcs.aspect.EnableCollector;
import com.bocloud.mcs.collector.BocloudCollector;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.ApplicationContext;
import org.springframework.scheduling.annotation.Async;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import java.util.List;
/**
*
*
* @author YuFengYang
* @version 1.0
* @since 2023/1/12 14:57
*/
@Component
@Slf4j
public class KvmHostCollector extends BocloudCollector {
@Autowired
private ApplicationContext applicationContext;
@Value("${collector.kvm.thread.number:20}")
private Integer threadNumber;
@Override
public List<MetricFamilySamples> collect() {
return super.collect();
}
@Async
@Override
@EnableCollector(value = "${collector.kvm.host.enable:true}")
@Scheduled(initialDelay = 1000L, fixedRate = 60000)
public void scheduledCollect() {
// log.info("collect kvm host metrics start...");
// GaugeMetricFamily collectTimeUse = new GaugeMetricFamily("kvm_"_HOST + "collect_time_use", "help",
// Arrays.asList("type"));
// ExecutorService executors = Executors.newFixedThreadPool(threadNumber);
// Date now = new Date();
// List<Collector.MetricFamilySamples> mfs = new ArrayList<>();
// List<Collector.MetricFamilySamples> list = new ArrayList<>();
// List<CloudVendor> vendors = cmpCloudVendorService.list(CloudProvider.KVM);
// List<KvmHost> hosts = new ArrayList<>();
// for (CloudVendor vendor : vendors) {
// List<KvmHost> kvmHosts = cmpCloudVendorService.listKvmHost(vendor.getId());
// hosts.addAll(kvmHosts);
// }
// List<String> labels = Arrays.asList("host_cloud", "host_id");
// for (KvmHost host : hosts) {
// executors.submit(() -> {
// Connect connect = null;
// try {
// connect = new Connect(host.getUri(), true);
//
//// int vir_node_cpu_stats_user = connect.NodeGetCPUStats(8, "VIR_NODE_CPU_STATS_USER", 0, 0);
//// log.info("---------------------------->{}",vir_node_cpu_stats_user);
////
//
// NodeInfo nodeInfo = connect.nodeInfo();
// long freeMemory = connect.getFreeMemory();
// long memoryTotal = connect.nodeInfo().memory * 1024;
// int cpus = nodeInfo.cpus;
// GaugeMetricFamily memoryFreeData = new GaugeMetricFamily("kvm_"_HOST + "memory_free", "help",
// labels);
// GaugeMetricFamily memoryTotalData = new GaugeMetricFamily("kvm_"_HOST + "memory_total", "help",
// labels);
// GaugeMetricFamily cpuNumData = new GaugeMetricFamily("kvm_"_HOST + "info_virtual_cpus", "help",
// labels);
//
//
// memoryFreeData.addMetric(Arrays.asList(host.getVendorId() + "", host.getId() + ""), freeMemory);
// memoryTotalData.addMetric(Arrays.asList(host.getVendorId() + "", host.getId() + ""), memoryTotal);
// cpuNumData.addMetric(Arrays.asList(host.getVendorId() + "", host.getId() + ""), cpus);
//
// list.add(memoryFreeData);
// list.add(memoryTotalData);
// list.add(cpuNumData);
// } catch (Exception e) {
// log.error("collect node metrics error!" + e.getMessage(), e);
// } finally {
// if (connect != null) {
// try {
// connect.close();
// } catch (LibvirtException e) {
// log.error("连接关闭异常 {}", e);
// }
// }
// }
// });
// }
// executors.shutdown();
// try {
// executors.awaitTermination(5, TimeUnit.MINUTES);
// } catch (InterruptedException e) {
// log.error("kvm not complete within its interval", e);
// Thread.currentThread().interrupt();
// }
// mfs.addAll(list);
// collectTimeUse.addMetric(Arrays.asList("instance"), (System.currentTimeMillis() - now.getTime()));
// mfs.add(collectTimeUse);
// super.getCache().put(TIME, new Date());
// super.getCache().put(DATA, mfs);
// log.info("collect kvm vm metrics end! use " + (System.currentTimeMillis() - now.getTime()) / 1000 + "s");
}
}

View File

@ -0,0 +1,112 @@
package com.bocloud.mcs.collector.kvm;
import com.bocloud.ims.entity.CloudVendor;
import com.bocloud.ims.entity.KvmHost;
import com.bocloud.ims.enums.CloudProvider;
import com.bocloud.mcs.aspect.EnableCollector;
import com.bocloud.mcs.collector.BocloudCollector;
import com.bocloud.mcs.collector.kvm.vm.KvmVmAdapter;
import io.prometheus.client.GaugeMetricFamily;
import lombok.extern.slf4j.Slf4j;
import org.libvirt.Connect;
import org.libvirt.Domain;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.ApplicationContext;
import org.springframework.scheduling.annotation.Async;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import java.util.*;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
/**
* @author wpj
* @since 2022/6/9
*/
@Component
@Slf4j
public class KvmVmCollector extends BocloudCollector {
@Autowired
private ApplicationContext applicationContext;
@Value("${collector.kvm.thread.number:20}")
private Integer threadNumber;
@Override
public List<MetricFamilySamples> collect() {
return super.collect();
}
@Async
@Override
@EnableCollector(value = "${collector.kvm.vm.enable:true}")
@Scheduled(initialDelay = 1000L, fixedRate = 60000)
public void scheduledCollect() {
log.info("collect kvm metrics start...");
GaugeMetricFamily collectTimeUse = new GaugeMetricFamily("kvm_" + "collect_time_use", "help",
Arrays.asList("type"));
ExecutorService executors = Executors.newFixedThreadPool(threadNumber);
Date now = new Date();
List<MetricFamilySamples> mfs = new ArrayList<>();
List<MetricFamilySamples> list = new ArrayList<>();
List<CloudVendor> vendors = cmpCloudVendorService.list(CloudProvider.KVM);
List<KvmHost> hosts = new ArrayList<>();
for (CloudVendor vendor : vendors) {
List<KvmHost> kvmHosts = cmpCloudVendorService.listKvmHost(vendor.getId());
hosts.addAll(kvmHosts);
}
for (KvmHost host : hosts) {
executors.submit(() -> {
Connect connect;
try {
// connect = new Connect(host.getUri(), true);
connect = ConnectHolder.getConnect(host.getUri());
int[] idsOfDomain = connect.listDomains();
for (int id : idsOfDomain) {
Domain domain = connect.domainLookupByID(id);
if (domain.isActive() != 1) {
log.warn("domain 不处于激活状态 continue");
continue;
}
Map<String, KvmVmAdapter> adapters = applicationContext.getBeansOfType(KvmVmAdapter.class);
for (Map.Entry<String, KvmVmAdapter> kvmVmAdapterEntry : adapters.entrySet()) {
kvmVmAdapterEntry.getValue().getGaugeMetricFamilyData(domain, host.getVendorId(), list);
}
}
} catch (Exception e) {
log.error("collect node metrics error!" + e.getMessage(), e);
}
// finally {
// if (connect != null) {
// try {
// connect.close();
// } catch (LibvirtException e) {
// log.error("连接关闭异常 {}", e);
// }
// }
// }
});
}
executors.shutdown();
try {
executors.awaitTermination(5, TimeUnit.MINUTES);
} catch (InterruptedException e) {
log.error("kvm not complete within its interval", e);
Thread.currentThread().interrupt();
}
mfs.addAll(list);
collectTimeUse.addMetric(Arrays.asList("instance"), (System.currentTimeMillis() - now.getTime()));
mfs.add(collectTimeUse);
super.getCache().put(TIME, new Date());
super.getCache().put(DATA, mfs);
log.info("collect kvm vm metrics end! use " + (System.currentTimeMillis() - now.getTime()) / 1000 + "s");
}
}

View File

@ -0,0 +1,17 @@
package com.bocloud.mcs.collector.kvm.vm;
import io.prometheus.client.Collector;
import io.prometheus.client.GaugeMetricFamily;
import org.libvirt.Domain;
import org.libvirt.LibvirtException;
import java.util.List;
public interface KvmVmAdapter {
List<Collector.MetricFamilySamples> list = null;
List<GaugeMetricFamily> getGaugeMetricFamilyData(Domain domain, Long vendorId, List<Collector.MetricFamilySamples> result) throws LibvirtException, InterruptedException, NoSuchFieldException, IllegalAccessException;
}

View File

@ -0,0 +1,44 @@
package com.bocloud.mcs.collector.kvm.vm;
import io.prometheus.client.Collector;
import io.prometheus.client.GaugeMetricFamily;
import lombok.extern.slf4j.Slf4j;
import org.libvirt.Domain;
import org.libvirt.LibvirtException;
import org.springframework.stereotype.Component;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
@Slf4j
@Component
public class KvmVmCpuMetricData implements KvmVmAdapter {
@Override
public List<GaugeMetricFamily> getGaugeMetricFamilyData(Domain domain, Long vendorId, List<Collector.MetricFamilySamples> result) throws LibvirtException, InterruptedException {
List<GaugeMetricFamily> list = new ArrayList<>();
List<String> labels = Arrays.asList("vmCloud", "vm_uuid", "vmname");
Double time = domain.getInfo().cpuTime / Math.pow(10, 9);
long c1 = time.longValue();
int vCpus = domain.getInfo().nrVirtCpu;
log.info("monitoring data vmName=>{}, vmTime=>{},timeLongValue=>{},cpus=>{},systemNow=>{}"
, domain.getName(), time, c1, vCpus, System.currentTimeMillis());
GaugeMetricFamily cpuTimeData = new GaugeMetricFamily("kvm_" + "domain_info_cpu_time_seconds_total", "help",
labels);
cpuTimeData.addMetric(Arrays.asList(vendorId + "", domain.getUUIDString(), domain.getName()), c1);
list.add(cpuTimeData);
GaugeMetricFamily cpuMaxData = new GaugeMetricFamily("kvm_" + "domain_info_virtual_cpus", "help",
labels);
cpuMaxData.addMetric(Arrays.asList(vendorId + "", domain.getUUIDString(), domain.getName()), vCpus);
GaugeMetricFamily cpuSystem = new GaugeMetricFamily("kvm_" + "domain_info_cpu_system_time", "help",
labels);
cpuSystem.addMetric(Arrays.asList(vendorId + "", domain.getUUIDString(), domain.getName()), System.currentTimeMillis() / Math.pow(10, 3));
list.add(cpuMaxData);
list.add(cpuSystem);
result.addAll(list);
return list;
}
}

View File

@ -0,0 +1,65 @@
package com.bocloud.mcs.collector.kvm.vm;
import com.alibaba.fastjson.JSONObject;
import io.prometheus.client.Collector;
import io.prometheus.client.GaugeMetricFamily;
import lombok.extern.slf4j.Slf4j;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;
import org.libvirt.Domain;
import org.libvirt.DomainBlockStats;
import org.libvirt.LibvirtException;
import org.springframework.stereotype.Component;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
@Slf4j
@Component
public class KvmVmDiskMetricData implements KvmVmAdapter {
private String type = "disk";
private static HashMap<String, String> typeMap = new HashMap();
static {
typeMap.put("rd_req", "读取请求总数");
typeMap.put("rd_bytes", "读取的数据大小");
typeMap.put("wr_req", "写入请求总数");
typeMap.put("wr_bytes", "写入的数据大小");
typeMap.put("errs", "失败次数");
}
@Override
public List<GaugeMetricFamily> getGaugeMetricFamilyData(Domain domain, Long vendorId, List<Collector.MetricFamilySamples> result) throws LibvirtException, NoSuchFieldException, IllegalAccessException {
List<GaugeMetricFamily> list = new ArrayList<>();
List<String> labels = Arrays.asList("vmCloud", "vm_uuid", "vmname");
String xmlDesc = domain.getXMLDesc(0);
Document document = Jsoup.parse(xmlDesc);
// 磁盘
Elements disks = document.getElementsByTag("devices").get(0).getElementsByTag("disk");
for (Element disk : disks) {
String dev = disk.getElementsByTag("target").get(0).attr("dev");
DomainBlockStats domainBlockStats = domain.blockStats(dev);
log.debug("kvm disk {} stats {}", dev, JSONObject.toJSONString(domainBlockStats));
Class<? extends DomainBlockStats> aClass = domainBlockStats.getClass();
for (String str : typeMap.keySet()) {
Field rxBytes = aClass.getField(str);
long val = (long) rxBytes.get(domainBlockStats);
GaugeMetricFamily nodeData = new GaugeMetricFamily("kvm_" + type + "_" + str, "help",
labels);
nodeData.addMetric(Arrays.asList(vendorId + "", domain.getUUIDString(), domain.getName()), val);
list.add(nodeData);
}
}
result.addAll(list);
return list;
}
}

View File

@ -0,0 +1,70 @@
package com.bocloud.mcs.collector.kvm.vm;
import com.alibaba.fastjson.JSONObject;
import io.prometheus.client.Collector;
import io.prometheus.client.GaugeMetricFamily;
import lombok.extern.slf4j.Slf4j;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;
import org.libvirt.Domain;
import org.libvirt.DomainInterfaceStats;
import org.libvirt.LibvirtException;
import org.springframework.stereotype.Component;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
@Component
@Slf4j
public class KvmVmInterfacesMetricData implements KvmVmAdapter {
private String type = "interfaces";
private static HashMap<String, String> typeMap = new HashMap();
static {
typeMap.put("rx_bytes", "接收数据包大小");
typeMap.put("rx_packets", "接收数据包数量");
typeMap.put("rx_errs", "接收错误数据包数量");
typeMap.put("rx_drop", "接收丢弃数据包数量");
typeMap.put("tx_bytes", "发送数据包大小");
typeMap.put("tx_packets", "发送数据包数量");
typeMap.put("tx_errs", "发送错误数据包数量");
typeMap.put("tx_drop", "发送丢弃数据包数量");
}
@Override
public List<GaugeMetricFamily> getGaugeMetricFamilyData(Domain domain, Long vendorId, List<Collector.MetricFamilySamples> result) throws LibvirtException, NoSuchFieldException, IllegalAccessException {
List<GaugeMetricFamily> list = new ArrayList<>();
List<String> labels = Arrays.asList("vmCloud", "vm_uuid");
String xmlDesc = domain.getXMLDesc(0);
Document document = Jsoup.parse(xmlDesc);
// 网卡
Elements interfaces = document.getElementsByTag("devices").get(0).getElementsByTag("interface");
for (Element inter : interfaces) {
String interName = inter.getElementsByTag("target").get(0).attr("dev");
DomainInterfaceStats domainInterfaceStats = domain.interfaceStats(interName);
log.debug("kvm interfaces {} stats {}", interName, JSONObject.toJSONString(domainInterfaceStats));
Class<? extends DomainInterfaceStats> aClass = domainInterfaceStats.getClass();
for (String str : typeMap.keySet()) {
Field rxBytes = aClass.getField(str);
long val = (long) rxBytes.get(domainInterfaceStats);
GaugeMetricFamily nodeData = new GaugeMetricFamily("kvm_" + type + "_" + str, "help",
labels);
nodeData.addMetric(Arrays.asList(vendorId + "", domain.getUUIDString()), val);
list.add(nodeData);
}
}
result.addAll(list);
return list;
}
}

View File

@ -0,0 +1,51 @@
package com.bocloud.mcs.collector.kvm.vm;
import com.alibaba.fastjson.JSONObject;
import io.prometheus.client.Collector;
import io.prometheus.client.GaugeMetricFamily;
import lombok.extern.slf4j.Slf4j;
import org.libvirt.Domain;
import org.libvirt.LibvirtException;
import org.libvirt.MemoryStatistic;
import org.springframework.stereotype.Component;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Optional;
@Component
@Slf4j
public class KvmVmMemoryMetricData implements KvmVmAdapter {
private String type = "memory_usage";
@Override
public List<GaugeMetricFamily> getGaugeMetricFamilyData(Domain domain, Long vendorId, List<Collector.MetricFamilySamples> result) throws LibvirtException {
List<GaugeMetricFamily> list = new ArrayList<>();
List<String> labels = Arrays.asList("vmCloud", "vm_uuid", "vmname");
MemoryStatistic[] memoryStatistics = domain.memoryStats(10);
Optional<MemoryStatistic> first = Arrays.stream(memoryStatistics).filter(x -> x.getTag() == 4).findFirst();
double memoryUsage = 0;
try {
MemoryStatistic memoryStatistic = first.get();
long unusedMemory = memoryStatistic.getValue();
long maxMemory = domain.getMaxMemory();
memoryUsage = (maxMemory - unusedMemory) * 100.0 / maxMemory;
log.debug("虚拟机[{}]内存使用率为: {} ", domain.getName(), memoryUsage);
} catch (Exception e) {
log.error("first {}", JSONObject.toJSONString(first));
log.error("获取内存异常{}", e);
}
GaugeMetricFamily nodeData = new GaugeMetricFamily("kvm_" + type, "help",
labels);
nodeData.addMetric(Arrays.asList(vendorId + "", domain.getUUIDString(), domain.getName()), (double) Math.round(memoryUsage * 100) / 100);
list.add(nodeData);
result.addAll(list);
return list;
}
}

View File

@ -0,0 +1,105 @@
package com.bocloud.mcs.collector.manageone;
import com.alibaba.fastjson.JSONObject;
import com.bocloud.cms.entity.MonitorAuth;
import com.bocloud.ims.entity.CloudVendor;
import com.bocloud.ims.enums.CloudProvider;
import com.bocloud.mcs.aspect.EnableCollector;
import com.bocloud.mcs.collector.BocloudCollector;
import com.bocloud.mcs.collector.manageone.core.ManageOneClient;
import com.bocloud.mcs.service.internal.CmsCloudVendorService;
import com.megatron.common.encrypt.AESEncryptor;
import com.megatron.common.model.GeneralResult;
import com.megatron.common.utils.ListTool;
import io.prometheus.client.GaugeMetricFamily;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.scheduling.annotation.Async;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import org.springframework.util.Assert;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
/**
* manageone collector
*
* @author zhangyf
* @since 2019-10-12
*/
@Component
@Slf4j
public class ManageOneEvsDiskCollector extends BocloudCollector implements InitializingBean {
private final CmsCloudVendorService cmsCloudVendorService;
List<Long> indicatorIds;
JSONObject indicators;
private String prefix = "bocloud_fusioncloud_evs_disk_";
@Value("${collector.manageone.rate.enable:false}")
boolean rateEnable;
@Value("${collector.manageone.rate.value:10}")
double rateValue;
@Autowired
public ManageOneEvsDiskCollector(CmsCloudVendorService cmsCloudVendorService) {
this.cmsCloudVendorService = cmsCloudVendorService;
}
@Async
@Override
@EnableCollector(value = "${collector.manageone.evs.disk.enable:false}")
@Scheduled(initialDelay = 3000L, fixedRate = 60000)
public void scheduledCollect() {
Date now = new Date();
log.info("collect manageone evs disk metrics start...");
GaugeMetricFamily collectTimeUse = new GaugeMetricFamily(prefix + "collect_time_use", "help",
Collections.singletonList("type"));
List<CloudVendor> vendors = cmpCloudVendorService.list(CloudProvider.MANAGEONE);
Map<String, GaugeMetricFamily> map = new ConcurrentHashMap<>();
for (CloudVendor vendor : vendors) {
try {
ManageOneClient client = new ManageOneClient(rateEnable, rateValue);
try {
// 获取fusioncloud运维侧地址及认证信息
GeneralResult authResult = cmsCloudVendorService.detailVendorAuth(vendor.getId());
Assert.isTrue(authResult.isSuccess(), "get vendor operations auth failed , error:" + authResult.getMessage());
MonitorAuth monitorAuth = JSONObject.parseObject(JSONObject.toJSONString(authResult.getData()), MonitorAuth.class);
Assert.notNull(monitorAuth, "vendor [" + vendor.getName() + "] not found auth config info");
String password = new AESEncryptor().decrypt(monitorAuth.getPassword(), null);
client.auth(monitorAuth.getAddress(), monitorAuth.getUsername(), password);
} catch (Exception e) {
log.error("auth error ", e);
continue;
}
List<JSONObject> objects = client.listCloudVolumes();//云硬盘集合
if (ListTool.isEmpty(indicatorIds)) {
indicatorIds = client.listIndicatorIds(client.getEvsDiskObjTypeId()); // 支持的监控指标集合IndicatorIds
}
if (indicators == null || indicators.size() == 0) {
indicators = client.listIndicators(indicatorIds); // 指标的数字和描述信息
}
client.collectMetrics(vendor, objects, indicatorIds, indicators, client.getEvsDiskObjTypeId(), map, prefix);
} catch (RuntimeException e) {
log.error("invoke manageone evs disk get metrics error,", e);
}
}
List<MetricFamilySamples> mfs = new ArrayList<>(map.values());
collectTimeUse.addMetric(Collections.singletonList("manageone_evs_disk"), (System.currentTimeMillis() - now.getTime()));
mfs.add(collectTimeUse);
super.getCache().put(TIME, new Date());
super.getCache().put(DATA, mfs);
log.info("collect manageone evs disk metrics end! use " + (System.currentTimeMillis() - now.getTime()) / 1000 + "s");
}
@Override
public void afterPropertiesSet() {
register();
}
}

View File

@ -0,0 +1,110 @@
package com.bocloud.mcs.collector.manageone;
import com.alibaba.fastjson.JSONObject;
import com.bocloud.cms.entity.MonitorAuth;
import com.bocloud.ims.entity.CloudVendor;
import com.bocloud.ims.enums.CloudProvider;
import com.bocloud.mcs.aspect.EnableCollector;
import com.bocloud.mcs.collector.BocloudCollector;
import com.bocloud.mcs.collector.manageone.core.ManageOneClient;
import com.bocloud.mcs.service.internal.CmsCloudVendorService;
import com.megatron.common.encrypt.AESEncryptor;
import com.megatron.common.model.GeneralResult;
import com.megatron.common.utils.ListTool;
import io.prometheus.client.GaugeMetricFamily;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.scheduling.annotation.Async;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import org.springframework.util.Assert;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
/**
* manageone collector
*
* @author zhangyf
* @since 2019-10-12
*/
@Component
@Slf4j
public class ManageOneHostCollector extends BocloudCollector implements InitializingBean {
private final CmsCloudVendorService cmsCloudVendorService;
List<Long> indicatorIds;
JSONObject indicators;
private String prefix = "bocloud_fusioncloud_host_";
@Value("${collector.manageone.rate.enable:false}")
boolean rateEnable;
@Value("${collector.manageone.rate.value:10}")
double rateValue;
@Autowired
public ManageOneHostCollector(CmsCloudVendorService cmsCloudVendorService) {
this.cmsCloudVendorService = cmsCloudVendorService;
}
@Async
@Override
@EnableCollector(value = "${collector.manageone.host.enable:true}")
@Scheduled(initialDelay = 1000L, fixedRate = 60000)
public void scheduledCollect() {
Date now = new Date();
log.info("collect manageone host metrics start...");
GaugeMetricFamily collectTimeUse = new GaugeMetricFamily(prefix + "collect_time_use", "help",
Collections.singletonList("type"));
List<CloudVendor> vendors = cmpCloudVendorService.list(CloudProvider.MANAGEONE);
Map<String, GaugeMetricFamily> map = new ConcurrentHashMap<>();
for (CloudVendor vendor : vendors) {
try {
Boolean isSyncServer = JSONObject.parseObject(vendor.getAuthentication()).getBoolean("isSyncServer");
if (isSyncServer == null || !isSyncServer) {
continue;
}
ManageOneClient client = new ManageOneClient(rateEnable, rateValue);
try {
// 获取fusioncloud运维侧地址及认证信息
GeneralResult authResult = cmsCloudVendorService.detailVendorAuth(vendor.getId());
Assert.isTrue(authResult.isSuccess(), "get vendor operations auth failed , error:" + authResult.getMessage());
MonitorAuth monitorAuth = JSONObject.parseObject(JSONObject.toJSONString(authResult.getData()), MonitorAuth.class);
Assert.notNull(monitorAuth, "vendor [" + vendor.getName() + "] not found auth config info");
String password = new AESEncryptor().decrypt(monitorAuth.getPassword(), null);
client.auth(monitorAuth.getAddress(), monitorAuth.getUsername(), password);
} catch (Exception e) {
log.error("auth error ", e);
continue;
}
List<JSONObject> objects = client.listPhysicalHosts();//宿主机集合
if (ListTool.isEmpty(indicatorIds)) {
indicatorIds = client.listIndicatorIds(client.getHostObjTypeId()); // 支持的监控指标集合IndicatorIds
}
if (indicators == null || indicators.size() == 0) {
indicators = client.listIndicators(indicatorIds); // 指标的数字和描述信息
log.debug(indicators.toJSONString());
}
client.collectMetrics(vendor, objects, indicatorIds, indicators, client.getHostObjTypeId(), map, prefix);
} catch (RuntimeException e) {
log.error("invoke manageone host get metrics error,", e);
}
}
List<MetricFamilySamples> mfs = new ArrayList<>(map.values());
collectTimeUse.addMetric(Collections.singletonList("manageone_host"), (System.currentTimeMillis() - now.getTime()));
mfs.add(collectTimeUse);
super.getCache().put(TIME, new Date());
super.getCache().put(DATA, mfs);
log.info("collect manageone host metrics end! use " + (System.currentTimeMillis() - now.getTime()) / 1000 + "s");
}
@Override
public void afterPropertiesSet() {
register();
}
}

View File

@ -0,0 +1,110 @@
package com.bocloud.mcs.collector.manageone;
import com.alibaba.fastjson.JSONObject;
import com.bocloud.cms.entity.MonitorAuth;
import com.bocloud.ims.entity.CloudVendor;
import com.bocloud.ims.enums.CloudProvider;
import com.bocloud.mcs.aspect.EnableCollector;
import com.bocloud.mcs.collector.BocloudCollector;
import com.bocloud.mcs.collector.manageone.core.ManageOneClient;
import com.bocloud.mcs.service.internal.CmsCloudVendorService;
import com.megatron.common.encrypt.AESEncryptor;
import com.megatron.common.model.GeneralResult;
import com.megatron.common.utils.ListTool;
import io.prometheus.client.GaugeMetricFamily;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.scheduling.annotation.Async;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import org.springframework.util.Assert;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.stream.Collectors;
/**
* manageone collector
*
* @author zhangyf
* @since 2019-10-12
*/
@Component
@Slf4j
public class ManageOneVmCollector extends BocloudCollector implements InitializingBean {
private final CmsCloudVendorService cmsCloudVendorService;
List<Long> indicatorIds;
JSONObject indicators;
private String prefix = "bocloud_fusioncloud_vm_";
@Value("${collector.manageone.rate.enable:false}")
boolean rateEnable;
@Value("${collector.manageone.rate.value:10}")
double rateValue;
@Autowired
public ManageOneVmCollector(CmsCloudVendorService cmsCloudVendorService) {
this.cmsCloudVendorService = cmsCloudVendorService;
}
@Async
@Override
@EnableCollector(value = "${collector.manageone.vm.enable:true}")
@Scheduled(initialDelay = 2000L, fixedRate = 60000)
public void scheduledCollect() {
Date now = new Date();
log.info("collect manageone vm metrics start...");
GaugeMetricFamily collectTimeUse = new GaugeMetricFamily(prefix + "collect_time_use", "help",
Collections.singletonList("type"));
List<CloudVendor> vendors = cmpCloudVendorService.list(CloudProvider.MANAGEONE);
Map<String, GaugeMetricFamily> map = new ConcurrentHashMap<>();
for (CloudVendor vendor : vendors) {
try {
String projectId = JSONObject.parseObject(vendor.getAuthentication()).getString("projectId");
ManageOneClient client = new ManageOneClient(rateEnable, rateValue);
try {
// 获取fusioncloud运维侧地址及认证信息
GeneralResult authResult = cmsCloudVendorService.detailVendorAuth(vendor.getId());
Assert.isTrue(authResult.isSuccess(), "get vendor operations auth failed , error:" + authResult.getMessage());
MonitorAuth monitorAuth = JSONObject.parseObject(JSONObject.toJSONString(authResult.getData()), MonitorAuth.class);
Assert.notNull(monitorAuth, "vendor [" + vendor.getName() + "] not found auth config info");
String password = new AESEncryptor().decrypt(monitorAuth.getPassword(), null);
client.auth(monitorAuth.getAddress(), monitorAuth.getUsername(), password);
} catch (Exception e) {
log.error("auth error ", e);
continue;
}
if (ListTool.isEmpty(indicatorIds)) {
indicatorIds = client.listIndicatorIds(client.getVmObjTypeId()); // 支持的监控指标集合IndicatorIds
}
if (indicators == null || indicators.size() == 0) {
indicators = client.listIndicators(indicatorIds); // 指标的数字和描述信息
log.debug(indicators.toJSONString());
}
List<JSONObject> objects = client.listCloudVms(); //虚拟机集合
objects = objects.stream().filter(object -> object.getString("projectId").equals(projectId)).collect(Collectors.toList());
client.collectMetrics(vendor, objects, indicatorIds, indicators, client.getVmObjTypeId(), map, prefix);
} catch (RuntimeException e) {
log.error("invoke manageone vm get metrics error,", e);
}
}
List<MetricFamilySamples> mfs = new ArrayList<>(map.values());
collectTimeUse.addMetric(Collections.singletonList("fusioncloud_vm"), (System.currentTimeMillis() - now.getTime()));
mfs.add(collectTimeUse);
super.getCache().put(TIME, new Date());
super.getCache().put(DATA, mfs);
log.info("collect manageone vm metrics end! use " + (System.currentTimeMillis() - now.getTime()) / 1000 + "s");
}
@Override
public void afterPropertiesSet() {
register();
}
}

View File

@ -0,0 +1,138 @@
package com.bocloud.mcs.collector.manageone.bms;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.bocloud.cms.entity.MonitorAuth;
import com.bocloud.ims.entity.CloudVendor;
import com.bocloud.ims.enums.CloudProvider;
import com.bocloud.mcs.aspect.EnableCollector;
import com.bocloud.mcs.collector.BocloudCollector;
import com.bocloud.mcs.collector.manageone.bms.common.ManageOneBmsClient;
import com.bocloud.mcs.service.internal.CmsCloudVendorService;
import com.megatron.common.encrypt.AESEncryptor;
import com.megatron.common.model.GeneralResult;
import io.prometheus.client.GaugeMetricFamily;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import org.springframework.util.Assert;
import java.util.*;
import java.util.stream.Collectors;
@Component
@Slf4j
public class BmsCollector extends BocloudCollector implements InitializingBean {
private static final String PREFIX = "managerOne_bms_";
@Autowired
private CmsCloudVendorService cmsCloudVendorService;
private Integer limit = 5;
private static final Map<String,String> METRIC_MAP = new HashMap<>();
static {
METRIC_MAP.put("562992903094273","cpu_usage_user"); // 用户空间CPU使用率
METRIC_MAP.put("562992903094285","mem_usedPercent"); // 内存使用率
METRIC_MAP.put("562992903094292","disk_usedPercent"); // 磁盘使用率
METRIC_MAP.put("562992903094296","disk_agt_read_bytes_rate"); // 磁盘读速率
METRIC_MAP.put("562992903094297","disk_agt_read_requests_rate"); // 磁盘读操作速率
METRIC_MAP.put("562992903094298","disk_agt_write_bytes_rate"); // 磁盘写速率
METRIC_MAP.put("562992903094299","disk_agt_write_requests_rate"); // 磁盘写操作速率
METRIC_MAP.put("562992903094301","disk_writeTime"); // 写操作平均耗时
METRIC_MAP.put("562992903094302","disk_readTime"); // 读操作平均耗时
METRIC_MAP.put("562992903094303","net_bitSent"); // 出网带宽
METRIC_MAP.put("562992903094304","net_bitRecv"); // 入网带宽
METRIC_MAP.put("562992903094305","net_packetSent"); // 网卡包发送速率
METRIC_MAP.put("562992903094306","net_packetRecv"); // 网卡包接收速率
METRIC_MAP.put("562992903094309","net_dropin"); // 接收丢包率
METRIC_MAP.put("562992903094310","net_dropout"); // 发送丢包率
}
/**
* 30
*
* @return
*/
@Override
public int getExpire() {
return 1800000;
}
@Async
@Override
@EnableCollector(value = "${collector.managerOne.bms.enable:true}")
@Scheduled(initialDelay = 1000L, fixedRate = 120000L)
public void scheduledCollect() {
log.info("BMS => collect managerOne metrics start...");
Date now = new Date();
List<MetricFamilySamples> mfs = new ArrayList<>();
GaugeMetricFamily collectTimeUse = new GaugeMetricFamily(PREFIX + "collect_time_use", "help",
Collections.singletonList("type"));
List<CloudVendor> vendors = cmpCloudVendorService.list(CloudProvider.MANAGEONE);
for (CloudVendor vendor : vendors) {
JSONObject auth = JSONObject.parseObject(vendor.getAuthentication());
String projectId = auth.getString("projectId");
ManageOneBmsClient manageOneBmsClient = new ManageOneBmsClient();
GeneralResult authResult = cmsCloudVendorService.detailVendorAuth(vendor.getId());
Assert.isTrue(authResult.isSuccess(), "get vendor operations auth failed , error:" + authResult.getMessage());
MonitorAuth monitorAuth = JSONObject.parseObject(JSONObject.toJSONString(authResult.getData()), MonitorAuth.class);
Assert.notNull(monitorAuth, "vendor [" + vendor.getName() + "] not found auth config info");
String password = new AESEncryptor().decrypt(monitorAuth.getPassword(), null);
manageOneBmsClient.setAddr(monitorAuth.getAddress());
manageOneBmsClient.setUserName(monitorAuth.getUsername());
manageOneBmsClient.setPassword(password);
manageOneBmsClient.setProjectId(projectId);
Integer offset = 0;
JSONArray jsonArray = manageOneBmsClient.getVms(limit, offset);
while (null != jsonArray && jsonArray.size() != 0){
// 每五台机器循环获取一次监控数据
offset += limit;
List<JSONObject> vmJson = jsonArray.toJavaList(JSONObject.class);
List<String> vmResId = vmJson.stream().map(jsonObject -> jsonObject.getString("resId")).collect(Collectors.toList());
JSONObject monitor = manageOneBmsClient.getMonitor(vmResId, METRIC_MAP);
if (null != monitor){
JSONObject data = monitor.getJSONObject("data");
if (null != data){
for (String vmMonitorStr : data.keySet()) {
// 单个云主机监控数据key为监控指标的key vmMonitorStr为objId
JSONObject vmMonitor = data.getJSONObject(vmMonitorStr);
for (String monitorKey : vmMonitor.keySet()) {
if (METRIC_MAP.containsKey(monitorKey)){
JSONObject monitorJSONObject = vmMonitor.getJSONObject("monitorKey");
GaugeMetricFamily cpuMaxData = new GaugeMetricFamily(PREFIX + METRIC_MAP.get(monitorKey), "help",
Arrays.asList("vendorId", "instanceId"));
cpuMaxData.addMetric(Arrays.asList(vendor.getId() + "", vmMonitorStr), monitorJSONObject.getFloatValue("last_collect_data"));
mfs.add(cpuMaxData);
}
}
}
}else {
log.info("本次获取到监控数据为null");
}
}
jsonArray = manageOneBmsClient.getVms(limit, offset);
}
}
collectTimeUse.addMetric(Collections.singletonList("manager_bms"), (System.currentTimeMillis() - now.getTime()));
mfs.add(collectTimeUse);
super.getCache().put(TIME, new Date());
super.getCache().put(DATA, mfs);
log.info("collect manager bms metrics end! use " + (System.currentTimeMillis() - now.getTime()) / 1000 + "s");
}
}

View File

@ -0,0 +1,70 @@
package com.bocloud.mcs.collector.manageone.bms.common;
import com.alibaba.fastjson.JSONObject;
import com.megatron.common.enums.PostDataFormat;
import com.megatron.common.http.HttpClient;
import com.megatron.common.model.Result;
import java.util.Map;
/**
* @author fanzx
* @create 2021/10/12 11:53
*/
public class ManageCommon {
private HttpClient client;
private static final Integer TIMEOUT = 20 * 60 * 1000;
/**
* post token
* @param url url
* @param header
* @param params body -> username and password
* @return
*/
public JSONObject post(String url, Map<String, Object> header, Map<String, Object> params) {
this.client = new HttpClient(TIMEOUT, PostDataFormat.RAW);
try {
client.setDataFormat(PostDataFormat.RAW);
Result result = this.client.post(header, params, url);
client.close();
String message = result.getMessage();
return JSONObject.parseObject(message);
} finally {
this.client.close();
}
}
/**
*
* @param url
* @param header
* @param params
* @return
*/
public JSONObject get(String url, Map<String, Object> header, Map<String, Object> params) {
client = new HttpClient(TIMEOUT, PostDataFormat.RAW);
try {
client.setDataFormat(null);
Result result = client.get(header, params, url);
client.close();
return JSONObject.parseObject(result.getMessage());
} finally {
client.close();
}
}
public JSONObject put(String url, Map<String, Object> header, Map<String, Object> params) {
client = new HttpClient(TIMEOUT, PostDataFormat.RAW);
try {
Result result = client.put(header, params, url);
client.close();
return JSONObject.parseObject(result.getMessage());
} finally {
client.close();
}
}
}

View File

@ -0,0 +1,104 @@
package com.bocloud.mcs.collector.manageone.bms.common;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.megatron.common.enums.PostDataFormat;
import com.megatron.common.http.HttpClient;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@Data
@AllArgsConstructor
@NoArgsConstructor
@Slf4j
public class ManageOneBmsClient {
private static final String BATCH_GET_METRIC_DATA_URL = "/rest/performance/v1/data-svc/latest-data/action/query";
private static final String BMS_OBJ_TYPE_ID = "562992903094272";
private static final String VM_LIST_URL = "/rest/tenant-resource/v1/tenant/resources/CLOUD_BMS";
private static final String TOKEN_URL = "/rest/plat/smapp/v1/sessions";
private HttpClient client = new HttpClient(PostDataFormat.RAW);
private String userName;
private String password;
private String addr;
private String projectId;
public String getToken(){
ManageCommon manageCommon = new ManageCommon();
Map<String, Object> params = new HashMap<>();
params.put("grantType", "password");
params.put("userName", this.userName);
params.put("value" ,this.password);
log.info("BMS => 获取token接口参数为{}", JSONObject.toJSONString(params));
JSONObject jsonObject = manageCommon.put(this.buildUrl(TOKEN_URL), buildHeader(null), params);
log.info("BMS => 获取token接口返回: {}", jsonObject.toJSONString());
log.info("BMS => token为: {}", jsonObject.getString("accessSession"));
return jsonObject.getString("accessSession");
}
private String buildUrl(String tokenUrl) {
return this.addr + tokenUrl;
}
private Map<String, Object> buildHeader(String token) {
HashMap<String, Object> header = new HashMap<>();
header.put("Content-Type", "application/json;charset=UTF-8");
header.put("Accept", "application/json");
if (null != token){
header.put("x-auth-token", token);
}
return header;
}
public JSONArray getVms(Integer limit, Integer offset) {
Map<String, Object> header = this.buildHeader(this.getToken());
ManageCommon manageCommon = new ManageCommon();
HashMap<String, Object> params = new HashMap<>();
params.put("limit", limit);
params.put("offset", offset);
log.info("BMS => 获取bms列表参数为:{}, url为:{}, 请求头为{}", JSONObject.toJSONString(params), buildUrl(VM_LIST_URL),
JSONObject.toJSONString(header));
try {
JSONObject jsonObject = manageCommon.get(buildUrl(VM_LIST_URL), header, params);
log.info("BMS => 获取到bms列表为{}", jsonObject.toJSONString());
return jsonObject.getJSONArray("objList");
}catch (Exception e){
log.error("获取bms 云主机列表异常", e);
return null;
}
}
public JSONObject getMonitor(List<String> vmIds, Map<String,String> METRIC_MAP) {
Map<String, Object> header = this.buildHeader(this.getToken());
ManageCommon manageCommon = new ManageCommon();
HashMap<String, Object> params = new HashMap<>();
params.put("obj_type_id", BMS_OBJ_TYPE_ID);
params.put("indicator_ids", JSONObject.parseArray(JSONObject.toJSONString(new ArrayList<>(METRIC_MAP.keySet()))));
params.put("obj_ids", JSONObject.parseArray(JSONObject.toJSONString(vmIds)));
log.info("BMS => 获取bms监控参数为{}", JSONObject.toJSONString(params));
try {
JSONObject jsonObject = manageCommon.post(buildUrl(BATCH_GET_METRIC_DATA_URL), header, params);
log.info("BMS => 获取到bms监控数据为 {}", jsonObject.toJSONString());
return jsonObject;
}catch (Exception e){
log.error("BMS => 获取bms 云主机列表异常", e);
return null;
}
}
}

View File

@ -0,0 +1,142 @@
package com.bocloud.mcs.collector.manageone.cce;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.bocloud.cms.entity.MonitorAuth;
import com.bocloud.ims.entity.CloudVendor;
import com.bocloud.ims.enums.CloudProvider;
import com.bocloud.mcs.aspect.EnableCollector;
import com.bocloud.mcs.collector.BocloudCollector;
import com.bocloud.mcs.collector.manageone.cce.common.ContainerCluster;
import com.bocloud.mcs.collector.manageone.cce.common.ManageOneCceClient;
import com.bocloud.mcs.collector.manageone.cce.common.ManagerMonitorEntity;
import com.bocloud.mcs.common.Authentication;
import com.bocloud.mcs.service.internal.CmsCloudVendorService;
import com.bocloud.mcs.service.internal.ImsCloudServerService;
import com.megatron.common.encrypt.AESEncryptor;
import com.megatron.common.model.GeneralResult;
import io.prometheus.client.GaugeMetricFamily;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import org.springframework.util.Assert;
import java.util.*;
import java.util.stream.Collectors;
@Component
@Slf4j
public class CceCollector extends BocloudCollector implements InitializingBean {
private static final String PREFIX = "managerOne_cce_";
@Autowired
private CmsCloudVendorService cmsCloudVendorService;
@Autowired
private ImsCloudServerService imsCloudServerService;
private Integer limit = 5;
private static final Map<String,String> METRIC_MAP = new HashMap<>();
static {
// METRIC_MAP.put("磁盘写入速率","diskWriteRate"); // 用户空间CPU使用率
// METRIC_MAP.put("磁盘读取速率","diskReadRate"); // 内存使用率
// METRIC_MAP.put("CPU使用率","cpuUsage"); // 磁盘使用率
// METRIC_MAP.put("物理内存使用率","memUsage"); // 磁盘读速率
// METRIC_MAP.put("接收Bps","recvBytesRate"); // 磁盘读操作速率
// METRIC_MAP.put("接收Pps","recvPackRate"); // 磁盘写速率
// METRIC_MAP.put("显存使用率","gpuMemUsage"); // 磁盘写操作速率
// METRIC_MAP.put("GPU使用率","gpuUtil"); // 写操作平均耗时
// METRIC_MAP.put("发送Bps","sendBytesRate"); // 写操作平均耗时
// METRIC_MAP.put("发送Pps","sendPackRate"); // 写操作平均耗时
METRIC_MAP.put("CPU使用率","cpuUsage");
METRIC_MAP.put("内存使用率","memUsedRate");
METRIC_MAP.put("磁盘使用率","diskUsedRate");
METRIC_MAP.put("网卡接收速率","recvBytesRate"); // Bytes/Second
METRIC_MAP.put("网卡发送速率","sendBytesRate"); // Bytes/Second
}
/**
* 30
*
* @return
*/
@Override
public int getExpire() {
return 1800000;
}
@Async
@Override
@EnableCollector(value = "${collector.managerOne.cce.enable:true}")
@Scheduled(initialDelay = 1000L, fixedRate = 120000L)
public void scheduledCollect() {
log.info("CCE => collect managerOne metrics start...");
Date now = new Date();
List<MetricFamilySamples> mfs = new ArrayList<>();
GaugeMetricFamily collectTimeUse = new GaugeMetricFamily(PREFIX + "collect_time_use", "help",
Collections.singletonList("type"));
List<CloudVendor> vendors = cmpCloudVendorService.list(CloudProvider.MANAGEONE);
for (CloudVendor vendor : vendors) {
try {
Authentication authentication = JSON.parseObject(vendor.getAuthentication(), Authentication.class);
GeneralResult authResult = cmsCloudVendorService.detailVendorAuth(vendor.getId());
Assert.isTrue(authResult.isSuccess(), "get vendor operations auth failed , error:" + authResult.getMessage());
MonitorAuth monitorAuth = JSONObject.parseObject(JSONObject.toJSONString(authResult.getData()), MonitorAuth.class);
Assert.notNull(monitorAuth, "vendor [" + vendor.getName() + "] not found auth config info");
String addr = monitorAuth.getAddress().replace("oc", "aom");
log.info("aom地址为: {}", addr);
String password = new AESEncryptor().decrypt(authentication.getPassword(), "BocloudCMP");
ManageOneCceClient manageOneCceClient = new ManageOneCceClient(authentication.getAddress(), addr,authentication.getAccount(), password, authentication.getDomainName(), authentication.getProjectId());
List<ContainerCluster> cceContainer = imsCloudServerService.getCceContainer(vendor.getId());
List<String> clusterUuids = cceContainer.stream().map(ContainerCluster::getClusterUuid).collect(Collectors.toList());
log.info("CCE => 获取到cce列表为{}", JSONObject.toJSONString(cceContainer));
for (String value : METRIC_MAP.values()) {
for (String clusterUuid : clusterUuids) {
JSONObject monitorResource = manageOneCceClient.getMonitor(Arrays.asList(clusterUuid), value);
if (monitorResource!= null) {
ManagerMonitorEntity managerMonitorEntity = JSONObject.parseObject(monitorResource.toJSONString(), ManagerMonitorEntity.class);
for (ManagerMonitorEntity.Metrics metric : managerMonitorEntity.getMetrics()) {
List<ManagerMonitorEntity.Dimensions> dimensions = metric.getMetric().getDimensions();
List<ManagerMonitorEntity.DataPoints> dataPoints = metric.getDataPoints();
if (dimensions!= null && dimensions.size() > 0) {
for (int i = 0; i < dimensions.size(); i++) {
if (clusterUuid.contains(dimensions.get(i).getValue())){
String cceUuid = dimensions.get(i).getValue();
String val = dataPoints.get(i).getStatistics().get(0).getValue();
GaugeMetricFamily cpuMaxData = new GaugeMetricFamily(PREFIX + metric.getMetric().getMetricName(), "help",
Arrays.asList("vendorId", "instanceId"));
cpuMaxData.addMetric(Arrays.asList(vendor.getId() + "", cceUuid), Double.parseDouble(val));
mfs.add(cpuMaxData);
}
}
}
}
}
}
}
}catch (Exception e) {
log.error("collect managerOne metrics error", e);
}
}
collectTimeUse.addMetric(Collections.singletonList("manager_cce"), (System.currentTimeMillis() - now.getTime()));
mfs.add(collectTimeUse);
super.getCache().put(TIME, new Date());
super.getCache().put(DATA, mfs);
log.info("collect manager bms metrics end! use " + (System.currentTimeMillis() - now.getTime()) / 1000 + "s");
}
}

View File

@ -0,0 +1,160 @@
package com.bocloud.mcs.collector.manageone.cce.common;
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.megatron.common.encrypt.AESEncryptor;
import com.megatron.common.encrypt.Encryptor;
import com.megatron.common.model.RequestContext;
import com.megatron.common.utils.DateDeserializer;
import com.megatron.common.utils.DateSerializer;
import com.megatron.common.utils.DaySerializer;
import lombok.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.format.annotation.DateTimeFormat;
import java.util.Date;
/**
* @ClassName: ContainerCluster
* @Description: Kubernetes
* @Author lxy
* @Date 2022/7/14 17:54
*/
@Slf4j
@Data
@NoArgsConstructor
@AllArgsConstructor
public class ContainerCluster {
private Long id;// ID
private String regionId;// 所属域
private Long vendorId;// 所属云平台
private String clusterUuid;// 集群ID
private String clusterType;// 集群类型
// 集群创建时间
private Date created;
// 集群版本
private String version;
// 集群Docker版本。
private String dockerVersion;
// 集群API Server访问地址包含内网访问地址以及公网访问地址。
private String masterUrl;
// 集群安全组ID。
private String securityGroupUuid;
/**
* initial failed running updating updating_failed scaling
* stopped deleting deleted delete_failed
*/
// @Column("status")
// private String status;
/**
* Pod
* <p>
* 10.0.0.0/8 172.16-31.0.0/12-16 192.168.0.0/16 VPCVPCKubernetes使
*/
private String subnetCidr;
// 集群专有网络ID创建集群时必传。
private String vpcUuid;
private String vpcName;
// 虚拟交换机ID创建集群时可选择1~3个虚拟交换机。为保证集群高可用建议选择不同可用区的虚拟交换机。
private String vswitchUuid;
// 集群所属可用区ID。
private String zoneId;
// 托管版集群类型,面向托管集群: ack.pro.small专业托管集群。 ack.standard标准托管集群。
private String clusterSpec;
// 集群删除保护
private Boolean deletionProtection;
private String eipUuid;
private String loadBalancerUuid;
private String resourceGroupUuid;// 资源组id
// SSH登录密码。密码规则为8~30 个字符且至少同时包含三项大小写字母、数字和特殊符号和key_pair二选一。
public String loginPassword;
// 密钥对名称和login_password二选一。
public String keyPair;
// 网络插件
private String capabilitiesNetwork;
// kube-proxy代理模式
private String capabilitiesProxyModel;
// HSC START
// 子网uuid
private String subnetUuid;
private String subnetName;
// 容器网段
private String containerCidr;
// 服务网段
private String serviceCidr;
// HCS END
// 自服务 start
private Long tenantId;// 租户ID
private String tenantName; // 租户名称
private Long projectId;// 项目ID
private String projectName; // 项目名称
private String uuid;// uuid对应子订单号
@JsonSerialize(using = DaySerializer.class)
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private Date expiredTime;// 过期时间
// 所属申请类别
private RequestContext.Catalog catalog;
// 所属业务id
private Long businessId;
// 所属业务名称
private String businessName;
private Boolean isRecycle = false;
@JsonSerialize(using = DaySerializer.class)
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private Date recycleTime;// 回收时间
// 自服务 end
private String regionName;
private String vpcSafetyType;//安全类型
private String vpcFunctionType;
private String applicationName; //应用系统
private String resourceSetName; //资源集
private String imageId;//自定义镜像
@Getter(AccessLevel.NONE)
@Setter(AccessLevel.NONE)
private Encryptor encryptor = new AESEncryptor();
@JsonSerialize(
using = DateSerializer.class
)
@JsonDeserialize(
using = DateDeserializer.class
)
@DateTimeFormat(
pattern = "yyyy-MM-dd HH:mm:ss"
)
private Date gmtCreate;
@JsonSerialize(
using = DateSerializer.class
)
@JsonDeserialize(
using = DateDeserializer.class
)
@DateTimeFormat(
pattern = "yyyy-MM-dd HH:mm:ss"
)
private Date gmtModify;
private Long creatorId;
private Long ownerId;
private Long menderId;
private String name;
private String status;
private Boolean deleted;
private String props;
private String remark;
}

View File

@ -0,0 +1,63 @@
package com.bocloud.mcs.collector.manageone.cce.common;
/**
* manage one
*
* @author wangyu
* @version 1.0
* @since 2018916
*
*/
public class ManageOneAuth {
private ManageOneIdentity identity;
private ManageOneScope scope;
/**
*
*/
public ManageOneAuth() {
super();
}
/**
* @param identity
* @param scope
*/
public ManageOneAuth(ManageOneIdentity identity, ManageOneScope scope) {
super();
this.identity = identity;
this.scope = scope;
}
/**
* @return the identity
*/
public ManageOneIdentity getIdentity() {
return identity;
}
/**
* @param identity
* the identity to set
*/
public void setIdentity(ManageOneIdentity identity) {
this.identity = identity;
}
/**
* @return the scope
*/
public ManageOneScope getScope() {
return scope;
}
/**
* @param scope
* the scope to set
*/
public void setScope(ManageOneScope scope) {
this.scope = scope;
}
}

View File

@ -0,0 +1,91 @@
package com.bocloud.mcs.collector.manageone.cce.common;
import java.util.List;
public class ManageOneCatalog {
private String id;
private String name;
private String type;
private List<ManageOneEndpoint> endpoints;
/**
*
*/
public ManageOneCatalog() {
super();
}
/**
* @param name
* @param type
* @param endpoints
*/
public ManageOneCatalog(String name, String type, List<ManageOneEndpoint> endpoints) {
super();
this.name = name;
this.type = type;
this.endpoints = endpoints;
}
/**
* @return the id
*/
public String getId() {
return id;
}
/**
* @param id
* the id to set
*/
public void setId(String id) {
this.id = id;
}
/**
* @return the name
*/
public String getName() {
return name;
}
/**
* @param name
* the name to set
*/
public void setName(String name) {
this.name = name;
}
/**
* @return the type
*/
public String getType() {
return type;
}
/**
* @param type
* the type to set
*/
public void setType(String type) {
this.type = type;
}
/**
* @return the endpoints
*/
public List<ManageOneEndpoint> getEndpoints() {
return endpoints;
}
/**
* @param endpoints
* the endpoints to set
*/
public void setEndpoints(List<ManageOneEndpoint> endpoints) {
this.endpoints = endpoints;
}
}

View File

@ -0,0 +1,187 @@
package com.bocloud.mcs.collector.manageone.cce.common;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.megatron.common.enums.PostDataFormat;
import com.megatron.common.http.CommonResultBuilder;
import com.megatron.common.http.HttpClient;
import com.megatron.common.model.Result;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.http.Header;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import java.util.*;
/**
* @ Description @ Author @ Date Created in 17:07 2018/11/14 @ Modified
* By
*/
@Data
@Slf4j
@NoArgsConstructor
public class ManageOneCceClient {
private static final String GET_METRIC_DATA_URL = "/v1/{project_id}/ams/metricdata";
private String username;// 管理员账号
private String password;// 管理员密码
private String domain;// 所属域
private String project;// 项目ID
private boolean accessable;
private ManageOneToken token;// token信息
private String error; // 错误信息
private HttpClient client = new HttpClient(60 * 1000, PostDataFormat.RAW);
private String monitorUrl;
private String monitorUserName;
private String monitorPwd;
private String monitorToken;
private String monitorRoaRand;
private String tokenUrl;
public ManageOneCceClient(String tokenUrl,String monitorUrl, String userName, String pwd, String domainName, String projectId) {
this.tokenUrl = tokenUrl;
this.monitorUrl = monitorUrl;
this.username = userName;
this.password = pwd;
this.domain = domainName;
this.project = projectId;
initToken();
}
private void initToken() {
init();
}
/**
*
*/
private void init() {
String url = this.tokenUrl + "/v3/auth/tokens";
ManageOneDomain domain = new ManageOneDomain(this.domain);
ManageOneUser user = new ManageOneUser(this.username, this.password, domain);
ManageOnePassword password = new ManageOnePassword(user);
List<String> methods = new ArrayList<String>();
methods.add("password");
ManageOneIdentity identity = new ManageOneIdentity(password, methods);
ManageOneProject project = new ManageOneProject(this.project);
ManageOneScope scope = new ManageOneScope(project);
ManageOneAuth auth = new ManageOneAuth(identity, scope);
Map<String, Object> params = new HashMap<String, Object>();
params.put("auth", auth);
HttpPost httpPost = new HttpPost(url);
httpPost.addHeader("accept", "application/json");
httpPost.addHeader("content-type", "application/json");
log.info("CCE => 参数{}", JSONObject.toJSONString(params));
StringEntity httpEntity = new StringEntity(JSONObject.toJSON(params).toString(), "UTF-8");
httpPost.setEntity(httpEntity);
try {
CloseableHttpResponse httpResponse = client.getHttpClient().execute(httpPost);
log.info("CCE => 获取token地址{},参数{}, 返回{}", url, httpEntity, JSONObject.toJSONString(httpResponse));
Result result = new CommonResultBuilder().build(httpResponse.getStatusLine().getStatusCode());
if (result.isFailed()) {
this.accessable = false;
log.error("CCE => Driver init error : {}", result.getMessage());
this.error = result.getMessage();
return;
}
JSONObject content = JSONObject
.parseObject(IOUtils.toString(httpResponse.getEntity().getContent(), "utf-8"));
this.token = JSONObject.parseObject(content.getString("token"), ManageOneToken.class);
if (null == this.token) {
this.accessable = false;
log.error("CCE => Driver init error : {}", "Token is empty !");
this.error = "Token is empty !";
return;
}
String authToken = findToken(httpResponse);
if (StringUtils.isEmpty(authToken)) {
this.accessable = false;
log.error("CCE => Driver init error : {}", "Token is empty !");
this.error = "CCE => Token is empty !";
return;
}
token.setToken(authToken);
this.accessable = true;
log.info("CCE => Driver init token : {}", JSON.toJSONString(token));
} catch (Exception e) {
log.error("CCE => Get error message", e);
this.accessable = false;
}
}
/**
* X-Subject-Token
*
* @param httpResponse
* @return
*/
private String findToken(CloseableHttpResponse httpResponse) {
String token = "";
Header[] headers = httpResponse.getHeaders("X-Subject-Token");
if (null == headers || headers.length == 0) {
return token;
}
for (Header header : headers) {
if ("X-Subject-Token".equalsIgnoreCase(header.getName())) {
token = header.getValue();
break;
}
}
return token;
}
private Map<String, Object> buildHeader() {
Map<String, Object> header = new HashMap<String, Object>();
header.put("accept", "application/json");
header.put("content-type", "application/json");
header.put("X-Auth-Token", this.token.getToken());
return header;
}
public JSONObject getMonitor(List<String> instanceIds, String metricName) {
ManageOneCommon manageOneCommon = new ManageOneCommon();
String dimensionName = "clusterId";// 维度名称。长度最短为1最大为32。
String timerange = "-1.-1.5"; // 表示查询近5分钟数据
long period = 60; //周期
JSONObject metricObj = new JSONObject();
metricObj.put("namespace", "PAAS.AGGR");
metricObj.put("metricName", metricName);
ArrayList<Object> dimensions = new ArrayList<>();
instanceIds.forEach(instanceid -> {
JSONObject dimension = new JSONObject();
dimension.put("name", dimensionName);
dimension.put("value", instanceid);
dimensions.add(dimension);
});
metricObj.put("dimensions", dimensions);
Map<String, Object> params = new HashMap<>();
params.put("metrics", Arrays.asList(metricObj));
params.put("period", period);
params.put("timerange", timerange);
params.put("statistics", Collections.singletonList("average"));
String url = buildUrl(GET_METRIC_DATA_URL, this.project);
log.info("CCE => 获取cce监控参数为{}, 路径为: {}, 参数为{}", JSONObject.toJSONString(params), url, JSONObject.toJSONString(params));
Map<String, Object> header = this.buildHeader();
JSONObject jsonObject = manageOneCommon.post(url, header, params);
log.info("CCE => 获取到cce监控数据为 {}", jsonObject.toJSONString());
return jsonObject;
}
private String buildUrl(String url, String projectId) {
return (this.monitorUrl + url).replace("{project_id}", projectId);
}
}

View File

@ -0,0 +1,70 @@
package com.bocloud.mcs.collector.manageone.cce.common;
import com.alibaba.fastjson.JSONObject;
import com.megatron.common.enums.PostDataFormat;
import com.megatron.common.http.HttpClient;
import com.megatron.common.model.Result;
import java.util.Map;
/**
* @author fanzx
* @create 2021/10/12 11:53
*/
public class ManageOneCommon {
private HttpClient client;
private static final Integer TIMEOUT = 20 * 60 * 1000;
/**
* post token
* @param url url
* @param header
* @param params body -> username and password
* @return
*/
public JSONObject post(String url, Map<String, Object> header, Map<String, Object> params) {
this.client = new HttpClient(TIMEOUT, PostDataFormat.RAW);
try {
client.setDataFormat(PostDataFormat.RAW);
Result result = this.client.post(header, params, url);
client.close();
String message = result.getMessage();
return JSONObject.parseObject(message);
} finally {
this.client.close();
}
}
/**
*
* @param url
* @param header
* @param params
* @return
*/
public JSONObject get(String url, Map<String, Object> header, Map<String, Object> params) {
client = new HttpClient(TIMEOUT, PostDataFormat.RAW);
try {
client.setDataFormat(null);
Result result = client.get(header, params, url);
client.close();
return JSONObject.parseObject(result.getMessage());
} finally {
client.close();
}
}
public JSONObject put(String url, Map<String, Object> header, Map<String, Object> params) {
client = new HttpClient(TIMEOUT, PostDataFormat.RAW);
try {
Result result = client.put(header, params, url);
client.close();
return JSONObject.parseObject(result.getMessage());
} finally {
client.close();
}
}
}

View File

@ -0,0 +1,62 @@
package com.bocloud.mcs.collector.manageone.cce.common;
public class ManageOneDomain {
private String id;
private String name;
/**
*
*/
public ManageOneDomain() {
super();
}
/**
* @param id
* @param name
*/
public ManageOneDomain(String id, String name) {
super();
this.id = id;
this.name = name;
}
/**
* @param name
*/
public ManageOneDomain(String name) {
super();
this.name = name;
}
/**
* @return the id
*/
public String getId() {
return id;
}
/**
* @param id
* the id to set
*/
public void setId(String id) {
this.id = id;
}
/**
* @return the name
*/
public String getName() {
return name;
}
/**
* @param name
* the name to set
*/
public void setName(String name) {
this.name = name;
}
}

View File

@ -0,0 +1,89 @@
package com.bocloud.mcs.collector.manageone.cce.common;
public class ManageOneEndpoint {
private String id;
private String regionId;
private String region;
private String url;
/**
*
*/
public ManageOneEndpoint() {
super();
}
/**
* @param regionId
* @param region
* @param url
*/
public ManageOneEndpoint(String regionId, String region, String url) {
super();
this.regionId = regionId;
this.region = region;
this.url = url;
}
/**
* @return the id
*/
public String getId() {
return id;
}
/**
* @param id
* the id to set
*/
public void setId(String id) {
this.id = id;
}
/**
* @return the regionId
*/
public String getRegionId() {
return regionId;
}
/**
* @param regionId
* the regionId to set
*/
public void setRegionId(String regionId) {
this.regionId = regionId;
}
/**
* @return the region
*/
public String getRegion() {
return region;
}
/**
* @param region
* the region to set
*/
public void setRegion(String region) {
this.region = region;
}
/**
* @return the url
*/
public String getUrl() {
return url;
}
/**
* @param url
* the url to set
*/
public void setUrl(String url) {
this.url = url;
}
}

View File

@ -0,0 +1,57 @@
package com.bocloud.mcs.collector.manageone.cce.common;
import java.util.List;
public class ManageOneIdentity {
private ManageOnePassword password;
private List<String> methods;
/**
*
*/
public ManageOneIdentity() {
super();
}
/**
* @param password
* @param methods
*/
public ManageOneIdentity(ManageOnePassword password, List<String> methods) {
super();
this.password = password;
this.methods = methods;
}
/**
* @return the password
*/
public ManageOnePassword getPassword() {
return password;
}
/**
* @param password
* the password to set
*/
public void setPassword(ManageOnePassword password) {
this.password = password;
}
/**
* @return the methods
*/
public List<String> getMethods() {
return methods;
}
/**
* @param methods
* the methods to set
*/
public void setMethods(List<String> methods) {
this.methods = methods;
}
}

View File

@ -0,0 +1,37 @@
package com.bocloud.mcs.collector.manageone.cce.common;
public class ManageOnePassword {
private ManageOneUser user;
/**
*
*/
public ManageOnePassword() {
super();
}
/**
* @param user
*/
public ManageOnePassword(ManageOneUser user) {
super();
this.user = user;
}
/**
* @return the user
*/
public ManageOneUser getUser() {
return user;
}
/**
* @param user
* the user to set
*/
public void setUser(ManageOneUser user) {
this.user = user;
}
}

View File

@ -0,0 +1,87 @@
package com.bocloud.mcs.collector.manageone.cce.common;
public class ManageOneProject {
private String id;
private String name;
private ManageOneDomain domain;
/**
*
*/
public ManageOneProject() {
super();
}
/**
* @param id
*/
public ManageOneProject(String id) {
super();
this.id = id;
}
/**
* @param domain
*/
public ManageOneProject(ManageOneDomain domain) {
super();
this.domain = domain;
}
/**
* @param name
* @param domain
*/
public ManageOneProject(String name, ManageOneDomain domain) {
super();
this.name = name;
this.domain = domain;
}
/**
* @return the id
*/
public String getId() {
return id;
}
/**
* @param id
* the id to set
*/
public void setId(String id) {
this.id = id;
}
/**
* @return the name
*/
public String getName() {
return name;
}
/**
* @param name
* the name to set
*/
public void setName(String name) {
this.name = name;
}
/**
* @return the domain
*/
public ManageOneDomain getDomain() {
return domain;
}
/**
* @param domain
* the domain to set
*/
public void setDomain(ManageOneDomain domain) {
this.domain = domain;
}
}

View File

@ -0,0 +1,21 @@
package com.bocloud.mcs.collector.manageone.cce.common;
import com.alibaba.fastjson.annotation.JSONField;
import lombok.Data;
@Data
public class ManageOneResponse {
@JSONField(name = "job_id")
public String jobId;
private ErrorInfo error;
@Data
public static class ErrorInfo{
public String message;
private String code;
}
}

View File

@ -0,0 +1,53 @@
package com.bocloud.mcs.collector.manageone.cce.common;
public class ManageOneRole {
private String id;
private String name;
/**
*
*/
public ManageOneRole() {
super();
}
/**
* @param name
*/
public ManageOneRole(String name) {
super();
this.name = name;
}
/**
* @return the id
*/
public String getId() {
return id;
}
/**
* @param id
* the id to set
*/
public void setId(String id) {
this.id = id;
}
/**
* @return the name
*/
public String getName() {
return name;
}
/**
* @param name
* the name to set
*/
public void setName(String name) {
this.name = name;
}
}

View File

@ -0,0 +1,37 @@
package com.bocloud.mcs.collector.manageone.cce.common;
public class ManageOneScope {
private ManageOneProject project;
/**
*
*/
public ManageOneScope() {
super();
}
/**
* @param project
*/
public ManageOneScope(ManageOneProject project) {
super();
this.project = project;
}
/**
* @return the project
*/
public ManageOneProject getProject() {
return project;
}
/**
* @param project
* the project to set
*/
public void setProject(ManageOneProject project) {
this.project = project;
}
}

View File

@ -0,0 +1,181 @@
package com.bocloud.mcs.collector.manageone.cce.common;
import com.alibaba.fastjson.annotation.JSONField;
import java.util.Date;
import java.util.List;
/**
* manage oneToken
*
* @author wangyu
* @version 1.0
* @since 2018916
*
*/
public class ManageOneToken {
private String token;
@JSONField(format = "yyyy-MM-dd'T'HH:mm:ss.SSS")
private Date expiresAt;
private List<String> methods;
private List<ManageOneCatalog> catalog;
private List<ManageOneRole> roles;
private ManageOneProject project;
@JSONField(format = "yyyy-MM-dd'T'HH:mm:ss.SSS")
private Date issuedAt;
private ManageOneUser user;
/**
*
*/
public ManageOneToken() {
super();
}
/**
* @param token
* @param expiresAt
* @param methods
* @param catalog
* @param roles
* @param project
* @param issuedAt
* @param user
*/
public ManageOneToken(String token, Date expiresAt, List<String> methods, List<ManageOneCatalog> catalog,
List<ManageOneRole> roles, ManageOneProject project, Date issuedAt, ManageOneUser user) {
super();
this.token = token;
this.expiresAt = expiresAt;
this.methods = methods;
this.catalog = catalog;
this.roles = roles;
this.project = project;
this.issuedAt = issuedAt;
this.user = user;
}
/**
* @return the token
*/
public String getToken() {
return token;
}
/**
* @param token
* the token to set
*/
public void setToken(String token) {
this.token = token;
}
/**
* @return the expiresAt
*/
@JSONField(format = "yyyy-MM-dd HH:mm:ss")
public Date getExpiresAt() {
return expiresAt;
}
/**
* @param expiresAt
* the expiresAt to set
*/
public void setExpiresAt(Date expiresAt) {
this.expiresAt = expiresAt;
}
/**
* @return the methods
*/
public List<String> getMethods() {
return methods;
}
/**
* @param methods
* the methods to set
*/
public void setMethods(List<String> methods) {
this.methods = methods;
}
/**
* @return the catalog
*/
public List<ManageOneCatalog> getCatalog() {
return catalog;
}
/**
* @param catalog
* the catalog to set
*/
public void setCatalog(List<ManageOneCatalog> catalog) {
this.catalog = catalog;
}
/**
* @return the roles
*/
public List<ManageOneRole> getRoles() {
return roles;
}
/**
* @param roles
* the roles to set
*/
public void setRoles(List<ManageOneRole> roles) {
this.roles = roles;
}
/**
* @return the project
*/
public ManageOneProject getProject() {
return project;
}
/**
* @param project
* the project to set
*/
public void setProject(ManageOneProject project) {
this.project = project;
}
/**
* @return the issuedAt
*/
@JSONField(format = "yyyy-MM-dd HH:mm:ss")
public Date getIssuedAt() {
return issuedAt;
}
/**
* @param issuedAt
* the issuedAt to set
*/
public void setIssuedAt(Date issuedAt) {
this.issuedAt = issuedAt;
}
/**
* @return the user
*/
public ManageOneUser getUser() {
return user;
}
/**
* @param user
* the user to set
*/
public void setUser(ManageOneUser user) {
this.user = user;
}
}

View File

@ -0,0 +1,89 @@
package com.bocloud.mcs.collector.manageone.cce.common;
public class ManageOneUser {
private String id;
private String name;
private String password;
private ManageOneDomain domain;
/**
*
*/
public ManageOneUser() {
super();
}
/**
* @param name
* @param password
* @param domain
*/
public ManageOneUser(String name, String password, ManageOneDomain domain) {
super();
this.name = name;
this.password = password;
this.domain = domain;
}
/**
* @return the id
*/
public String getId() {
return id;
}
/**
* @param id
* the id to set
*/
public void setId(String id) {
this.id = id;
}
/**
* @return the name
*/
public String getName() {
return name;
}
/**
* @param name
* the name to set
*/
public void setName(String name) {
this.name = name;
}
/**
* @return the password
*/
public String getPassword() {
return password;
}
/**
* @param password
* the password to set
*/
public void setPassword(String password) {
this.password = password;
}
/**
* @return the domain
*/
public ManageOneDomain getDomain() {
return domain;
}
/**
* @param domain
* the domain to set
*/
public void setDomain(ManageOneDomain domain) {
this.domain = domain;
}
}

View File

@ -0,0 +1,89 @@
package com.bocloud.mcs.collector.manageone.cce.common;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.util.List;
@Data
@AllArgsConstructor
@NoArgsConstructor
public class ManagerMonitorEntity {
/**
* {
* "errorCode":"SVCSTG_AMS_2000000",
* "errorMessage":"success",
* "metrics":[
* {
* "metric":{
* "namespace":"abc",
* "metricName":"def",
* "dimensions":[
* {
* "name":"ghi",
* "value":"lmn"
* }
* ]
* },
* "dataPoints":[
* {
* "timestamp":"1467892800000",
* "unit":"Percent",
* "statistics":[
* {
* "statistic":"maximum",
* "value":"23"
* }
* ]
* }
* ]
* }
* ]
* }
*/
private String errorCode;
private String errorMessage;
private List<Metrics> metrics;
@Data
@AllArgsConstructor
@NoArgsConstructor
public static class Metrics{
private Metric metric;
private List<DataPoints> dataPoints;
}
@Data
@AllArgsConstructor
@NoArgsConstructor
public static class Metric{
private String namespace;
private String metricName;
private List<Dimensions> dimensions;
}
@Data
@AllArgsConstructor
@NoArgsConstructor
public static class Dimensions{
private String name;
private String value;
}
@Data
@AllArgsConstructor
@NoArgsConstructor
public static class DataPoints{
private String timestamp;
private String unit;
private List<Statistics> statistics;
}
@Data
@AllArgsConstructor
@NoArgsConstructor
public static class Statistics{
private String statistic;
private String value;
}
}

View File

@ -0,0 +1,294 @@
package com.bocloud.mcs.collector.manageone.core;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.bocloud.ims.entity.CloudVendor;
import com.google.common.util.concurrent.RateLimiter;
import com.megatron.common.enums.PostDataFormat;
import com.megatron.common.http.HttpClient;
import com.megatron.common.model.Result;
import io.prometheus.client.GaugeMetricFamily;
import lombok.extern.slf4j.Slf4j;
import org.springframework.util.Assert;
import java.text.DecimalFormat;
import java.time.LocalDateTime;
import java.time.ZoneOffset;
import java.util.*;
import java.util.stream.Collectors;
/**
* ManageOne
*
* @author zhangyf
* @since 2019-10-17
*/
@Slf4j
public class ManageOneClient {
private final boolean rateEnable;
public static RateLimiter rateLimiter;
private final HttpClient client = new HttpClient(PostDataFormat.RAW);
private String endpoint;
private String token;
/**
* roaRand
*/
private String roaRand;
public ManageOneClient(boolean rateEnable, double rateValue) {
this.rateEnable = rateEnable;
if (rateLimiter == null) {
rateLimiter = RateLimiter.create(rateValue);
}
}
/**
*
*
* @param endpoint
* @param user
* @param password
*/
public void auth(String endpoint, String user, String password) {
this.endpoint = endpoint;
String url = endpoint + "/rest/plat/smapp/v1/oauth/token";
Map<String, Object> params = new HashMap<>(4);
params.put("grantType", "password");
params.put("userName", user);
params.put("value", password);
Map<String, Object> header = new HashMap<>(3);
header.put("accept", "application/json");
header.put("content-type", "application/json");
Result result = client.put(header, params, url);
Assert.isTrue(result.isSuccess(), result.getMessage());
JSONObject content = JSONObject.parseObject(result.getMessage());
this.token = content.getString("accessSession");
this.roaRand = content.getString("roaRand");
}
public void collectMetrics(CloudVendor vendor, List<JSONObject> objects, List<Long> indicatorIds, JSONObject indicators,
Long objTypeId, Map<String, GaugeMetricFamily> map, String prefix) {
List<String> objIds = Optional.ofNullable(objects).orElse(new ArrayList<>()).stream().map(vm -> vm.getString("resId")).collect(Collectors.toList());
Map<String, JSONObject> objIdNativeIdMap = new HashMap<>(); //resIdnativeId(openstack里资源的id)
Optional.ofNullable(objects).orElse(new ArrayList<>()).forEach(object -> objIdNativeIdMap.put(object.getString("resId"), object));
JSONObject metrics = this.metrics(objIds, objTypeId, indicatorIds);
objIds.forEach(objId -> {
JSONObject metric = metrics.getJSONObject(objId);
Optional.ofNullable(metric).orElse(new JSONObject()).forEach((key, value) -> {
JSONObject indicator = indicators.getJSONObject(key);
if (!Optional.ofNullable(map.get(key)).isPresent()) {
GaugeMetricFamily gaugeMetricFamily = new GaugeMetricFamily(prefix + indicator.getString("indicator_name"),
indicator.getString("zh_cn"), Arrays.asList("vendorId", "id", "name", "instanceUuid"));
map.put(key, gaugeMetricFamily);
}
GaugeMetricFamily gaugeMetricFamily = map.get(key);
assert metric != null;
double datapointValue = 0D;
JSONArray series = metric.getJSONObject(key).getJSONArray("series");
if (series != null && !series.isEmpty()) {
series.sort(Comparator.comparingInt(o -> JSON.parseObject(o.toString()).size()));
List<Object> list = series.stream().filter(o -> !JSON.parseObject(o.toString()).isEmpty()).collect(Collectors.toList());
if (!list.isEmpty()) {
List<Object> values = new ArrayList<>(JSON.parseObject(String.valueOf(list.get(list.size() - 1))).values());
if (!values.isEmpty() && values.get(0) != null) {
DecimalFormat df = new DecimalFormat("#.00");
datapointValue = Double.parseDouble(df.format(Double.parseDouble(String.valueOf(values.get(0)))));
}
}
}
gaugeMetricFamily.addMetric(Arrays.asList(String.valueOf(vendor.getId()), objIdNativeIdMap.get(objId).getString("nativeId"),
objIdNativeIdMap.get(objId).getString("name"), objIdNativeIdMap.get(objId).getString("nativeId")), datapointValue);
});
});
}
/**
* 宿
*
* @return 宿
*/
public List<JSONObject> listPhysicalHosts() {
int pageNo = 1;
int pageSize = 1000;
List<JSONObject> list = null;
while (true) {
String url = this.endpoint + "/rest/cmdb/v1/instances/SYS_PhysicalHost";
Map<String, Object> params = new HashMap<>();
params.put("pageSize", pageSize);
params.put("pageNo", pageNo++);
params.put("contentSelector", JSONObject.toJSONString(Arrays.asList("resId", "nativeId", "name")));
Result result = client.get(defaultHeader(), params, url);
JSONObject content = JSONObject.parseObject(result.getMessage());
Assert.isTrue(result.isSuccess(), result.getMessage());
if (list == null) {
list = new ArrayList<>(content.getIntValue("totalNum"));
}
list.addAll(JSONObject.parseArray(content.getString("objList"), JSONObject.class));
if (content.getIntValue("totalPageNo") == content.getIntValue("currentPage")) {
break;
}
}
return list;
}
/**
*
*
* @return
*/
public List<JSONObject> listCloudVms() {
return listTenantResource("CLOUD_VM");
}
/**
*
*
* @return
*/
public List<JSONObject> listCloudVolumes() {
return listTenantResource("CLOUD_VOLUME");
}
/**
*
*
* @param className
* @return
*/
private List<JSONObject> listTenantResource(String className) {
int limit = 1000;
int offset = 0;
List<JSONObject> list = null;
while (true) {
String url = this.endpoint + "/rest/tenant-resource/v1/tenant/resources/" + className;
JSONObject params = new JSONObject();
params.put("limit", limit);
params.put("offset", offset);
Result result = client.get(defaultHeader(), params, url);
JSONObject content = JSONObject.parseObject(result.getMessage());
Assert.isTrue(result.isSuccess(), result.getMessage());
if (list == null) {
list = new ArrayList<>(content.getIntValue("totalNum"));
}
list.addAll(JSONObject.parseArray(content.getString("objList"), JSONObject.class));
offset = limit * content.getIntValue("currentPage");
if (content.getIntValue("totalPageNo") == content.getIntValue("currentPage")) {
break;
}
}
return list;
}
/**
*
*
* @param objIds resId
* @param objTypeId Id
* @param indicatorIds IndicatorIds
* @return
*/
public JSONObject metrics(List<String> objIds, Long objTypeId, List<Long> indicatorIds) {
JSONObject jsonObject = new JSONObject();
String url = this.endpoint + "/rest/performance/v1/data-svc/history-data/action/query";
int size = objIds.size();
long step = 100 / indicatorIds.size();
int i = 0;
LocalDateTime now = LocalDateTime.now();
long endTime = now.toInstant(ZoneOffset.of("+8")).toEpochMilli();
long beginTime = now.minusMinutes(10).toInstant(ZoneOffset.of("+8")).toEpochMilli();
while (size > 0) {
size -= step;
List<String> filterObjIds = objIds.stream().skip(step * i).limit(step).collect(Collectors.toList());
i++;
JSONObject params = new JSONObject();
params.put("obj_type_id", objTypeId);
params.put("indicator_ids", indicatorIds);
params.put("obj_ids", filterObjIds);
params.put("interval", "ORIGINAL");
params.put("range", "BEGIN_END_TIME");
params.put("begin_time", beginTime);
params.put("end_time", endTime);
if (rateEnable) {
ManageOneClient.rateLimiter.acquire(1);
}
Result result = client.post(defaultHeader(), params, url);
Assert.isTrue(result.isSuccess(), result.getMessage());
jsonObject.putAll(JSONObject.parseObject(result.getMessage()).getJSONObject("data"));
}
return jsonObject;
}
/**
*
*
* @return
*/
public JSONObject listIndicators(List<Long> indicatorIds) {
String url = this.endpoint + "/rest/performance/v1/mgr-svc/indicators";
Result result = client.post(defaultHeader(), indicatorIds, url);
Assert.isTrue(result.isSuccess(), result.getMessage());
return JSONObject.parseObject(result.getMessage()).getJSONObject("data");
}
/**
* objTypeIndicatorIds
*
* @param objTypeId objTypeId
* @return indicatorIds
*/
public List<Long> listIndicatorIds(Long objTypeId) {
String url = this.endpoint + "/rest/performance/v1/mgr-svc/obj-types/" + objTypeId + "/indicators";
Result result = client.get(defaultHeader(), null, url);
Assert.isTrue(result.isSuccess(), result.getMessage());
return JSONObject.parseObject(result.getMessage()).getJSONObject("data").getJSONArray("indicator_ids").toJavaList(Long.class);
}
/**
* header
*
* @return header
*/
private Map<String, Object> defaultHeader() {
Map<String, Object> header = new HashMap<>();
header.put("Accept", "application/json");
header.put("Content-Type", "application/json;charset=UTF-8");
header.put("X-Auth-Token", this.token);
header.put("roaRand", this.roaRand);
return header;
}
/**
* id(objTypeId)
*
* @return id
*/
public Long getVmObjTypeId() {
return 562958543355904L;
}
/**
* 宿id(objTypeId)
*
* @return 宿id
*/
public Long getHostObjTypeId() {
return 1407379178520576L;
}
/**
* id(objTypeId)
*
* @return id
*/
public Long getEvsDiskObjTypeId() {
return 562967133290496L;
}
}

View File

@ -0,0 +1,113 @@
package com.bocloud.mcs.collector.tianyicloud;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.bocloud.ims.entity.CloudVendor;
import com.bocloud.ims.enums.CloudProvider;
import com.bocloud.mcs.aspect.EnableCollector;
import com.bocloud.mcs.collector.BocloudCollector;
import com.bocloud.mcs.collector.tianyicloud.core.TianyiProvider;
import com.bocloud.mcs.common.Authentication;
import com.megatron.common.encrypt.DESEncryptor;
import io.prometheus.client.GaugeMetricFamily;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.scheduling.annotation.Async;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import java.util.*;
@Component
@Slf4j
public class TianyiCloudCollector extends BocloudCollector implements InitializingBean {
private static final String PREFIX = "tianyi_vm_";
@Value("${metrics.tianyi.batchSize:100}")
private Integer batchSize = 100;
/**
* 30
*
* @return
*/
@Override
public int getExpire() {
return 1800000;
}
@Async
@Override
@EnableCollector(value = "${collector.tianyi.enable:true}")
@Scheduled(initialDelay = 1000L, fixedRate = 120000L)
public void scheduledCollect() {
Date now = new Date();
log.info("collect tianyi vm metrics start...");
GaugeMetricFamily collectTimeUse = new GaugeMetricFamily(PREFIX + "collect_time_use", "help",
Collections.singletonList("type"));
List<MetricFamilySamples> mfs = new ArrayList<>();
List<String> labels = Arrays.asList("vendor_id", "instanceId", "region", "instanceUuid");
List<CloudVendor> vendors = cmpCloudVendorService.list(CloudProvider.CTSTACK);
for (CloudVendor vendor : vendors) {
if (StringUtils.isBlank(vendor.getAuthentication())) {
continue;
}
Authentication authentication = JSONArray.parseObject(vendor.getAuthentication(), Authentication.class);
String accessKey = new DESEncryptor().decrypt(authentication.getAccessKey().trim(), "BocloudCMP").trim();
String secretKey = new DESEncryptor().decrypt(authentication.getSecretKey().trim(), "BocloudCMP").trim();
String projectId = authentication.getProjectId();
for (String region : authentication.getRegions()) {
try {
TianyiProvider tianyiProvider = new TianyiProvider(accessKey, secretKey, projectId, region, authentication.getUrl());
List<String> instanceIds = tianyiProvider.instanceList();
if (instanceIds == null || instanceIds.isEmpty()) {
log.warn("获取到云主机列表为null, 云平台名称: {}, 可用区:{}", vendor.getName(), region);
continue;
}
// 分割instanceIds控制每批获取监控的云主机数量
for (List<String> instanceIdsBatch : splitList(instanceIds, batchSize)) {
List<JSONObject> metric = tianyiProvider.getMetric(instanceIdsBatch);
for (JSONObject jsonObject : metric) { // 每个metric为一个vm的监控数据
List<JSONObject> itemList = JSONObject.parseArray(jsonObject.getJSONArray("itemList").toJSONString(), JSONObject.class);
for (JSONObject metricItem : itemList) {
//windows机器磁盘监控数据返回值会包括.C: ,暂定把点后面的删除
String name = (PREFIX + metricItem.getString("itemName"));
if (name.contains(".")) {
name = name.substring(0, name.indexOf("."));
}
GaugeMetricFamily gmf = new GaugeMetricFamily(name.replace("./", ""), "help", labels);
gmf.addMetric(Arrays.asList(vendor.getId() + "", jsonObject.getString("deviceUUID"), jsonObject.getString("regionID"), jsonObject.getString("deviceUUID")),
Double.parseDouble(metricItem.getString("value")));
mfs.add(gmf);
}
}
}
} catch (Exception e) {
log.error("获取云主机监控信息失败, 云平台名称: {}, 可用区:{}, 异常原因", vendor.getName(), region, e);
}
}
}
collectTimeUse.addMetric(Arrays.asList("tianyi"), (System.currentTimeMillis() - now.getTime()));
mfs.add(collectTimeUse);
super.getCache().put(TIME, new Date());
super.getCache().put(DATA, mfs);
log.info("collect tianyi metrics end! use " + (System.currentTimeMillis() - now.getTime()) / 1000 + "s");
}
public static List<List<String>> splitList(List<String> originalList, int batchSize) {
List<List<String>> batches = new ArrayList<>();
for (int i = 0; i < originalList.size(); i += batchSize) {
int end = Math.min(i + batchSize, originalList.size());
List<String> batch = new ArrayList<>(originalList.subList(i, end));
batches.add(batch);
}
return batches;
}
}

View File

@ -0,0 +1,147 @@
package com.bocloud.mcs.collector.tianyicloud.core;
import lombok.extern.slf4j.Slf4j;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
/**
*
*
* <pre>
*
* MD2 The MD2 message digest algorithm as defined in RFC 1319.
* MD5 The MD5 message digest algorithm as defined in RFC 1321.
* SHA-1 Hash algorithms defined in the FIPS PUB 180-2.
* SHA-256 SHA-256 is a 256-bit hash function intended to provide 128 bits of security against collision attacks,
* SHA-384 while SHA-512 is a 512-bit hash function intended to provide 256 bits of security. A 384-bit hash may
* SHA-512 be obtained by truncating the SHA-512 output.
* </pre>
*
* @author Shawpin Shi
* @since 2016-9-1
*/
@Slf4j
public class MessageDigestUtils {
private final static char[] HEX_ARRAY = "0123456789abcdef".toCharArray();
/**
* MD5(128bit,16byte,32hex)<br>
* Message Digest Algorithm MD5
*/
public static final String MD5 = "MD5";
/**
* SHA-1(160bit,20byte,40hex)<br>
* Secure Hash Algorithm<br>
* SHASHA-1SHA-224SHA-256SHA-384SHA-512 NSA<br>
* NIST SHA-2<br>
* JavaSHA-224
*/
public static final String SHA_1 = "SHA-1";
/**
* SHA-256(256bit,64hex)
*/
public static final String SHA_256 = "SHA-256";
/**
* SHA-384(384bit,96hex)
*/
public static final String SHA_384 = "SHA-384";
/**
* SHA-512(512bit,64byte,128hex)
*/
public static final String SHA_512 = "SHA-512";
/**
*
*
* @author Shawpin Shi
* @since 2016-9-1
*/
public static String encrypt(String source, String algorithmName) {
return encrypt(source, algorithmName, StandardCharsets.UTF_8);
}
/**
* ()
*
* @author Shawpin Shi
* @since 2020-12-03
*/
public static String encrypt(String source, String algorithmName, Charset charset) {
String ciphertext = null;
MessageDigest md;
try {
md = MessageDigest.getInstance(algorithmName);
byte[] digest = md.digest(source.getBytes(charset));
ciphertext = byteToHexString(digest);
} catch (NoSuchAlgorithmException e) {
log.error(e.getMessage(), e);
}
return ciphertext;
}
/**
*
*
* @author Shawpin Shi
* @since 2016-9-1
*/
public static String encryptWithSalt(String source, String salt, String algorithmName) {
String newSource = source + "@" + salt;
return encrypt(newSource, algorithmName);
}
/**
* 16
*
* @author Shawpin Shi
* @since 2016-9-1
* @since 2017-9-29
*/
private static String byteToHexString(byte[] bytes) {
int len = bytes.length;
if (len > Integer.MAX_VALUE >> 1) {
throw new RuntimeException("字节数组的长度不能超过" + (Integer.MAX_VALUE >> 1));
}
int newLen = len << 1;// len * 2
char[] hexChars = new char[newLen];
int v, index;
for (int i = 0; i < len; i++) {
v = bytes[i] & 0xFF; // 保留低8位高24位置0
index = i << 1;// i * 2
hexChars[index] = HEX_ARRAY[v >>> 4];
hexChars[index + 1] = HEX_ARRAY[v & 0x0F];
}
return new String(hexChars);
}
/**
* Test
*/
public static void main(String[] args) {
String source = "0aece0ff48aafb9c481826d13ef5e3c8b74e44b4584b28a0fe499aee108227e8db8470f4b9f9ac5d2ab508a9ff84312da9f1646a8b5ed6570fd2f27790460e47";
System.out.println("Source String:" + source);
System.out.println("Encrypted String:");
System.out.println("Use MD5: " + MessageDigestUtils.encrypt(source, MessageDigestUtils.MD5));
System.out.println("Use SHA-1: " + MessageDigestUtils.encrypt(source, MessageDigestUtils.SHA_1));
System.out.println("Use SHA-256: " + MessageDigestUtils.encrypt(source, MessageDigestUtils.SHA_256));
System.out.println("Use SHA-384: " + MessageDigestUtils.encrypt(source, MessageDigestUtils.SHA_384));
System.out.println("Use SHA-512: " + MessageDigestUtils.encrypt(source, MessageDigestUtils.SHA_512));
System.out.println("MD5 Salt: " + MessageDigestUtils.encryptWithSalt(source, "sxp", MessageDigestUtils.MD5));
}
}

View File

@ -0,0 +1,126 @@
package com.bocloud.mcs.collector.tianyicloud.core;
import com.alibaba.fastjson.JSONObject;
import com.megatron.common.enums.HttpRequestMethod;
import com.megatron.common.utils.MapTools;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.codec.binary.Base64;
import org.apache.commons.lang3.time.DateFormatUtils;
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.util.*;
import java.util.stream.Collectors;
@Slf4j
public class TianyiHeaderUtils {
public static Map<String, Object> createHeaders(HttpRequestMethod method, Map<String, Object> headers, Map<String, Object> params,
String accessKey, String secretKey, String ctUserId) {
Map<String, Object> newHeaders = new HashMap<>();
Map<String, Object> headersOfAuth = new HashMap<>();
try {
if (!MapTools.isEmpty(headers)) {
newHeaders.putAll(headers);
}
String hybridDate = DateFormatUtils.format(new Date(), "yyyyMMdd'T'HHmmss'Z'");
headersOfAuth.put("hybrid-date", hybridDate);
String requestId = UUID.randomUUID().toString().replace("-", "");
headersOfAuth.put("ctyun-hybrid-request-id", requestId);
String forSignature = forSignature(method, headersOfAuth, params);
byte[] kdate = kdate(hybridDate, accessKey, secretKey);
byte[] signatureBytes = hmacSHA256(forSignature.getBytes(StandardCharsets.UTF_8), kdate);
String signature = new String(Base64.encodeBase64(signatureBytes), StandardCharsets.UTF_8);
List<String> keyList = new ArrayList<>(headersOfAuth.keySet());
keyList = keyList.stream().sorted(Comparator.comparing(String::toString)).collect(Collectors.toList());
String headersValue = String.join(";", keyList);
String authorization = accessKey + " Header=" + headersValue + " Signature=" + signature;
newHeaders.put("Content-Type", "application/json");
newHeaders.put("hybrid-date", hybridDate);
newHeaders.put("ctyun-hybrid-request-id", requestId);
newHeaders.put("Hybrid-Authorization", authorization);
newHeaders.put("ctUserId", ctUserId);
} catch (Exception e) {
log.error("构造请求头出现异常", e);
}
return newHeaders;
}
private static String forSignature(HttpRequestMethod method, Map<String, Object> headersOfAuth, Map<String, Object> params) {
List<String> keyList = new ArrayList<>(headersOfAuth.keySet());
keyList = keyList.stream().sorted(Comparator.comparing(String::toString)).collect(Collectors.toList());
StringBuilder headerBuffer = new StringBuilder();
for (int i = 0; i < keyList.size(); i++) {
String key = keyList.get(i);
headerBuffer.append(key).append(':').append(headersOfAuth.get(key));
if (i != keyList.size() - 1) {
headerBuffer.append('\n');
}
}
String campmocalHeader = headerBuffer.toString();
String query = null;
String body = null;
String encodedValue;
Object value;
if (method == HttpRequestMethod.GET) {
if (params != null && !params.isEmpty()) {
keyList = new ArrayList<>(params.keySet());
keyList = keyList.stream().sorted(Comparator.comparing(String::toString)).collect(Collectors.toList());
// aa=1&bb=2
StringBuilder queryBuffer = new StringBuilder();
for (String key : keyList) {
if (!queryBuffer.isEmpty()) {
queryBuffer.append('&');
}
value = params.get(key);
if (value == null) {
value = "";
}
encodedValue = URLEncoder.encode(String.valueOf(value), StandardCharsets.UTF_8);
queryBuffer.append(key).append('=').append(encodedValue);
}
query = queryBuffer.toString();
}
} else if (method == HttpRequestMethod.POST) {
if (params != null && !params.isEmpty()) {
body = JSONObject.toJSONString(params);
body = MessageDigestUtils.encrypt(body, MessageDigestUtils.SHA_256);
}
}
String forSignature = campmocalHeader;
if (null != query) {
forSignature = forSignature + "\n" + query;
}
if (null != body) {
forSignature = forSignature + "\n" + body;
}
return forSignature;
}
private static byte[] kdate(String hybridDate, String accessKey, String secretKey) throws Exception {
byte[] ktime = hmacSHA256(hybridDate.getBytes(StandardCharsets.UTF_8), secretKey.getBytes(StandardCharsets.UTF_8));
byte[] kAk = hmacSHA256(accessKey.getBytes(StandardCharsets.UTF_8), ktime);
byte[] kdate = hmacSHA256(hybridDate.substring(0, 8).getBytes(StandardCharsets.UTF_8), kAk);
return kdate;
}
/**
* HmacSHA256,32
*
* @param contentBytes
* @param secretBytes
* @return
*/
private static byte[] hmacSHA256(byte[] contentBytes, byte[] secretBytes) throws Exception {
Mac hmacSha256 = Mac.getInstance("HmacSHA256");
hmacSha256.init(new SecretKeySpec(secretBytes, "HmacSHA256"));
return hmacSha256.doFinal(contentBytes);
}
}

View File

@ -0,0 +1,206 @@
package com.bocloud.mcs.collector.tianyicloud.core;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.megatron.common.enums.HttpRequestMethod;
import com.megatron.common.enums.PostDataFormat;
import com.megatron.common.http.CommonResultBuilder;
import com.megatron.common.http.HttpClient;
import com.megatron.common.http.ResultBuilder;
import com.megatron.common.model.Result;
import com.megatron.common.utils.ListTool;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.springframework.util.Assert;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.util.*;
import java.util.stream.Collectors;
@Slf4j
@Data
public class TianyiProvider {
private String accessKey;
private String secretKey;
private String projectId;
private String ctUserId;
private String regionId;
public static final Integer SUCCESS_STATUS_CODE = 800;
public String PROTOCOL;
public Integer PAGE_SIZE = 50;
private final HttpClient client = new HttpClient(60 * 1000, PostDataFormat.RAW);
protected ResultBuilder resultBuilder = new CommonResultBuilder();
public TianyiProvider(String ak, String sk, String projectId, String reginId, String url) {
this.accessKey = ak;
this.secretKey = sk;
this.ctUserId = projectId;
this.regionId = reginId;
this.PROTOCOL = url;
}
private Map<String, Object> buildHeader(HttpRequestMethod method, Map<String, Object> headers, Map<String, Object> params) {
return TianyiHeaderUtils.createHeaders(method, headers, params, this.accessKey, this.secretKey, this.ctUserId);
}
public String buildUrl(String apiUrl) {
return PROTOCOL + apiUrl;
}
public Result doGet(String url, Map<String, Object> headers) {
HttpClient httpClient = new HttpClient(20 * 1000, PostDataFormat.RAW);
httpClient.setDataFormat(null);
return httpClient.get(buildHeader(HttpRequestMethod.GET, headers, null), null, buildUrl(url));
}
public Result doGet(String url, Map<String, Object> headers, Map<String, Object> params) {
HttpClient httpClient = new HttpClient(60 * 1000, PostDataFormat.RAW);
httpClient.setDataFormat(null);
String uri = buildUrl(url);
Map<String, Object> header = buildHeader(HttpRequestMethod.GET, headers, params);
printCurl(HttpRequestMethod.GET, uri, header, params);
return httpClient.get(header, params, uri);
}
public Result doPost(String url, Map<String, Object> params) {
HttpClient httpClient = new HttpClient(60 * 1000, PostDataFormat.RAW);
Map<String, Object> header = buildHeader(HttpRequestMethod.POST, null, params);
printCurl(HttpRequestMethod.POST, buildUrl(url), header, params);
return httpClient.post(header, params, buildUrl(url));
}
/**
* check
*
* @param result
* @param title
*/
public JSONObject checkResult(Result result, String title) {
Assert.isTrue(result.isSuccess(), "调用" + title + "API失败" + result.getMessage());
JSONObject object = JSONObject.parseObject(result.getMessage());
Assert.notNull(object, "调用" + title + "API" + "返回的object为null");
log.debug("API返回的数据:{}", object.toJSONString());
Assert.isTrue(object.getInteger("statusCode").equals(SUCCESS_STATUS_CODE), "调用-" + title + "-API-返回的statusCode为" + object.getInteger("statusCode") + "-message:" + object.getString("message") + "-description:" + object.getString("description"));
JSONObject returnObj = object.getJSONObject("returnObj");
log.debug("returnObj返回的数据:{}", returnObj == null ? null : returnObj.toJSONString());
return returnObj;
}
public void printCurl(HttpRequestMethod method, String uri, Map<String, Object> header, Map<String, Object> params) {
StringBuilder builder = new StringBuilder();
builder.append("curl --location --request");
if (Objects.requireNonNull(method) == HttpRequestMethod.GET) {
builder.append(" GET ").append("'").append(uri);
if (params == null || params.isEmpty()) {
builder.append("'");
} else {
List<String> keyList = new ArrayList<>(params.keySet());
keyList = keyList.stream().sorted(Comparator.comparing(String::toString)).toList();
// aa=1&bb=2
StringBuilder queryBuffer = new StringBuilder();
for (String key : keyList) {
if (!queryBuffer.isEmpty()) {
queryBuffer.append('&');
}
Object value = params.get(key);
if (value == null) {
value = "";
}
String encodedValue = URLEncoder.encode(String.valueOf(value), StandardCharsets.UTF_8);
queryBuffer.append(key).append('=').append(encodedValue);
}
String query = queryBuffer.toString();
builder.append("?").append(query).append("'");
}
} else {
builder.append(" POST ").append("'").append(uri);
if (params == null || params.isEmpty()) {
builder.append("'");
} else {
builder.append("'");
builder.append(" --data-raw ").append("'{");
List<String> keyList = new ArrayList<>(params.keySet());
StringBuilder queryBuffer = new StringBuilder();
for (String key : keyList) {
if (!queryBuffer.isEmpty()) {
queryBuffer.append(',');
}
Object value = params.get(key);
if (value == null) {
value = "";
}
String encodedValue = String.valueOf(value);
queryBuffer.append("\"").append(key).append("\"").append(':').append("\"").append(encodedValue).append("\"");
}
builder.append(queryBuffer);
builder.append("}'");
}
}
for (Map.Entry<String, Object> entry : header.entrySet()) {
builder.append(" --header ").append("'").append(entry.getKey()).append(":").append(entry.getValue()).append("'");
}
uri = builder.toString();
log.debug("uri:{}", uri);
}
public List<JSONObject> getMetric(List<String> instanceList) {
String url = "/v4.1/monitor/query-vm-latestmetricdata";
JSONObject body = new JSONObject();
body.put("regionID", this.regionId);
body.put("deviceUUIDList", instanceList);
HttpClient httpClient = new HttpClient(60 * 1000, PostDataFormat.RAW);
String uri = buildUrl(url);
Map<String, Object> header = buildHeader(HttpRequestMethod.POST, null, body);
printCurl(HttpRequestMethod.POST, uri, header, body);
Result result = httpClient.post(header, body, uri);
if (JSONObject.parseObject(result.getMessage()).getInteger("statusCode").equals(800)) {
return JSONObject.parseArray(JSONObject.parseObject(result.getMessage()).getJSONObject("returnObj").getJSONArray("result").toJSONString(), JSONObject.class);
} else {
throw new RuntimeException("获取监控数据失败,接口返回 " + JSONObject.toJSONString(result));
}
}
public List<String> instanceList() {
int pageNo = 1;
try {
String apiUrl = "/v4/ecs/instance-list";
JSONObject body = new JSONObject();
body.put("regionID", this.getRegionId());
body.put("pageNo", pageNo);
body.put("pageSize", this.PAGE_SIZE);
HttpClient httpClient = new HttpClient(60 * 1000, PostDataFormat.RAW);
Map<String, Object> header = buildHeader(HttpRequestMethod.POST, null, body);
printCurl(HttpRequestMethod.POST, buildUrl(apiUrl), header, body);
Result result = httpClient.post(header, body, buildUrl(apiUrl));
JSONObject returnObj = checkResult(result, "查询虚拟机列表");
List<JSONObject> results = JSONArray.parseArray(returnObj.getString("results"), JSONObject.class);
if (ListTool.isEmpty(results)) {
return null;
}
while (returnObj.getInteger("totalCount") > results.size()) {
++pageNo;
body.put("pageNo", pageNo);
result = doPost(apiUrl, body);
returnObj = checkResult(result, "查询虚拟机列表");
results.addAll(JSONArray.parseArray(returnObj.getString("results"), JSONObject.class));
}
return results.stream().map(o -> o.getString("iD")).collect(Collectors.toList());
} catch (Exception e) {
log.error("查询云主机列表失败 " + e);
}
return new ArrayList<>();
}
}

View File

@ -0,0 +1,62 @@
package com.bocloud.mcs.common;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.ToString;
import java.util.List;
/**
* ()
*
* @author fanzhenxi
*/
@Data
@AllArgsConstructor
@NoArgsConstructor
@ToString
public class Authentication {
/**
*
*/
private List<String> regions;
private String regionId;
/**
* AK
*/
private String secretKey;
/**
* SK
*/
private String accessKey;
/**
*
*/
private String version;
/**
*
*/
private String address;
private String url;
/**
*
*/
private String userId;
private String account;
private String password;
private String projectId;
private String domainName;
}

View File

@ -0,0 +1,35 @@
package com.bocloud.mcs.config;
import com.moandjiezana.toml.Toml;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import java.io.File;
import java.io.InputStream;
/**
* @author zhangyf
*/
@Slf4j
@Configuration
public class CollectorConfiguration {
@Value("${collector.config:}")
private String collectorConfigPath;
@Bean
public Toml collectorConfig() {
if (StringUtils.isBlank(collectorConfigPath)) {
try (InputStream inputStream = this.getClass().getResourceAsStream("/collector.conf")) {
return new Toml().read(inputStream);
} catch (Exception e) {
log.error("load collector.conf failed!", e);
return null;
}
}
return new Toml().read(new File(collectorConfigPath));
}
}

View File

@ -0,0 +1,24 @@
package com.bocloud.mcs.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.SchedulingConfigurer;
import org.springframework.scheduling.config.ScheduledTaskRegistrar;
import java.util.concurrent.Executor;
import java.util.concurrent.ScheduledThreadPoolExecutor;
@Configuration
public class ScheduledConfig implements SchedulingConfigurer {
@Override
public void configureTasks(ScheduledTaskRegistrar taskRegistrar) {
taskRegistrar.setScheduler(setTaskExecutors());
}
@Bean(destroyMethod = "shutdown")
public Executor setTaskExecutors() {
return new ScheduledThreadPoolExecutor(8);
}
}

View File

@ -0,0 +1,29 @@
package com.bocloud.mcs.config;
import com.megatron.framework.core.InterceptorBridge;
import com.megatron.framework.core.config.InterceptorConfiguration;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import java.util.ArrayList;
/**
*
*
* @author wangyu
* @version 1.0
* @since 2018330
*/
@Slf4j
@Component
public class WebInterceptorConfiguration implements InterceptorConfiguration {
@Override
public InterceptorBridge buildBridge() {
InterceptorBridge bridge = new InterceptorBridge();
bridge.setInterceptors(new ArrayList<>());
bridge.setMessageConverters(new ArrayList<>());
bridge.setResolvers(new ArrayList<>());
return bridge;
}
}

View File

@ -0,0 +1,45 @@
package com.bocloud.mcs.controller;
import io.prometheus.client.CollectorRegistry;
import io.prometheus.client.exporter.common.TextFormat;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.apache.commons.io.FileUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import java.io.File;
import java.io.IOException;
import java.util.Collections;
@RestController
public class MetricController {
private final CollectorRegistry collectorRegistry = CollectorRegistry.defaultRegistry;
@Value("${metrics.sample.path:/home/cmp/prometheus/metrics}")
private String path;
@GetMapping("/metrics")
public void writeRegistry(HttpServletRequest request, HttpServletResponse response) {
try {
response.setContentType("text/plain;charset=UTF-8");
TextFormat.write004(response.getWriter(), collectorRegistry.filteredMetricFamilySamples(Collections.<String>emptySet()));
} catch (IOException e) {
// This actually never happens since StringWriter::write() doesn't
// throw any IOException
throw new RuntimeException("Writing metrics failed", e);
}
}
@GetMapping("/sample/metrics")
public void writeRegistry2(HttpServletRequest request, HttpServletResponse response) {
try {
response.setContentType("text/plain;charset=UTF-8");
response.getWriter().write(FileUtils.readFileToString(new File(path), "utf-8"));
} catch (IOException e) {
throw new RuntimeException("Writing metrics failed", e);
}
}
}

View File

@ -0,0 +1,50 @@
package com.bocloud.mcs.controller;
import com.bocloud.mcs.entity.PrometheusHttpConfigBean;
import com.megatron.common.utils.ListTool;
import com.megatron.framework.core.RegistryService;
import com.megatron.framework.core.Service;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.*;
/**
* Prometheus http
*
* @author fanzhenxi
* @version 5.6.0-SNAPSHOT
* @date 2022/2/23 18:23
*/
@RestController
@Slf4j
public class PrometheusController {
@Autowired
private Service service;
@Autowired
private RegistryService registry;
@GetMapping("/targets")
public List<PrometheusHttpConfigBean> targets() {
try {
List<PrometheusHttpConfigBean> prometheusHttpConfigBeans = new ArrayList<>();
List<String> serviceInstances = registry.getServices(service);
List<String> servers = ListTool.isEmpty(serviceInstances) ? new ArrayList<>() : serviceInstances;
Set<String> targets = new HashSet<>();
Optional.ofNullable(servers).orElse(new ArrayList<>()).forEach(server -> {
server = server.replaceAll("http://", "").replaceAll("https://", "");
targets.add(server);
});
PrometheusHttpConfigBean prometheusHttpConfigBean = new PrometheusHttpConfigBean(targets);
prometheusHttpConfigBeans.add(prometheusHttpConfigBean);
return prometheusHttpConfigBeans;
} catch (Exception e) {
log.error("获取zookeeper列表中节点失败");
return null;
}
}
}

View File

@ -0,0 +1,27 @@
package com.bocloud.mcs.entity;
import com.alibaba.fastjson.annotation.JSONField;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.ToString;
import java.util.Set;
/**
* Prometheus http
*
* @author fanzhenxi
* @version 5.6.0-SNAPSHOT
* @date 2022/2/23 17:23
*/
@Data
@ToString
@AllArgsConstructor
@NoArgsConstructor
public class PrometheusHttpConfigBean {
@JSONField(name = "targets")
Set<String> targets;
}

View File

@ -0,0 +1,78 @@
package com.bocloud.mcs.service.internal;
import com.alibaba.fastjson.JSONObject;
import com.bocloud.cmp.boot.model.BoCloudService;
import com.bocloud.cmp.boot.model.BocloudToken;
import com.bocloud.ims.entity.CloudVendor;
import com.bocloud.ims.entity.KvmHost;
import com.bocloud.ims.enums.CloudProvider;
import com.megatron.common.model.GeneralResult;
import com.megatron.common.model.Pager;
import com.megatron.common.model.Param;
import com.megatron.common.model.Sign;
import com.megatron.common.utils.Common;
import com.megatron.common.utils.MapTools;
import com.megatron.framework.core.CurrentService;
import com.megatron.framework.core.Service;
import com.megatron.framework.http.core.HttpMethod;
import com.megatron.framework.http.core.ServiceFactory;
import com.megatron.framework.http.model.RemoteService;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Component;
import org.springframework.util.Assert;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* @author zhangyf
*/
@RequiredArgsConstructor
@Component
public class CmpCloudVendorService {
private final ServiceFactory serviceFactory;
private final CurrentService currentService;
/**
*
*
* @return
*/
public List<CloudVendor> list(CloudProvider cloudProvider) {
Map<String, Object> headers = new HashMap<>(4);
headers.put(BocloudToken.INTERNAL_TOKEN, currentService.getToken());
List<Param> paramList = new ArrayList<>();
paramList.add(new Param(MapTools.simpleMap("is_alarm", 1), Sign.EQ));
paramList.add(new Param(MapTools.simpleMap("type", cloudProvider.name()), Sign.EQ));
RemoteService remoteService = serviceFactory.build(Service.create(String.valueOf(BoCloudService.CMP.getName())),
"/v1/vendors", HttpMethod.GET, headers, new Pager(1, Integer.MAX_VALUE, paramList, null).toMap(false));
GeneralResult<?> result = remoteService.invoke();
Assert.isTrue(result.isSuccess(), "list cloud vendor failed, error:" + result.getMessage());
JSONObject data = (JSONObject) result.getData();
return data.getJSONArray(Common.ROWS).toJavaList(CloudVendor.class);
}
/**
* 宿
*
* @return
*/
public List<KvmHost> listKvmHost(Long vendorId) {
Map<String, Object> headers = new HashMap<>(4);
headers.put(BocloudToken.INTERNAL_TOKEN, currentService.getToken());
List<Param> paramList = new ArrayList<>();
paramList.add(new Param(MapTools.simpleMap("vendorId", vendorId), Sign.EQ));
RemoteService remoteService = serviceFactory.build(Service.create(String.valueOf(BoCloudService.CMP.getName())), "/plugins/kvm/v1/hosts", HttpMethod.GET, headers,
new Pager(1, Integer.MAX_VALUE, paramList, null).toMap(false));
GeneralResult result = remoteService.invoke();
Assert.isTrue(result.isSuccess(), "get kvm host list failed , error:" + result.getMessage());
JSONObject data = (JSONObject) result.getData();
return data.getJSONArray(Common.ROWS).toJavaList(KvmHost.class);
}
}

View File

@ -0,0 +1,54 @@
package com.bocloud.mcs.service.internal;
import com.bocloud.cmp.boot.model.BoCloudService;
import com.bocloud.cmp.boot.model.BocloudToken;
import com.megatron.common.model.GeneralResult;
import com.megatron.framework.core.CurrentService;
import com.megatron.framework.core.Service;
import com.megatron.framework.http.core.HttpMethod;
import com.megatron.framework.http.core.ServiceFactory;
import com.megatron.framework.http.model.RemoteService;
import org.springframework.stereotype.Component;
import java.util.HashMap;
import java.util.Map;
@Component
public class CmsCloudVendorService {
private final ServiceFactory serviceFactory;
private final CurrentService currentService;
public CmsCloudVendorService(ServiceFactory serviceFactory, CurrentService currentService) {
this.serviceFactory = serviceFactory;
this.currentService = currentService;
}
/**
* FusionCloud
*
* @return
*/
public GeneralResult detailVendorAuth(Long vendorId) {
Map<String, Object> headers = new HashMap<>(4);
headers.put(BocloudToken.INTERNAL_TOKEN, currentService.getToken());
String url = "/v1/vendors/" + vendorId + "/authentications";
RemoteService remoteService = serviceFactory.build(Service.create(String.valueOf(BoCloudService.CMS.getName())), url, HttpMethod.GET, headers, null);
return remoteService.invoke();
}
/**
* FC
* @return
*/
public GeneralResult listFC() {
Map<String, Object> headers = new HashMap<>(4);
headers.put(BocloudToken.INTERNAL_TOKEN, currentService.getToken());
RemoteService remoteService = serviceFactory.build(Service.create(String.valueOf(BoCloudService.CMS.getName())), "/v1/vendors/authentications", HttpMethod.GET, headers,
new HashMap<>());
return remoteService.invoke();
}
}

View File

@ -0,0 +1,68 @@
package com.bocloud.mcs.service.internal;
import com.alibaba.fastjson.JSONObject;
import com.bocloud.cmp.boot.model.BoCloudService;
import com.bocloud.cmp.boot.model.BocloudToken;
import com.bocloud.mcs.collector.manageone.cce.common.ContainerCluster;
import com.megatron.common.model.GeneralResult;
import com.megatron.common.model.Pager;
import com.megatron.common.model.Param;
import com.megatron.common.utils.Common;
import com.megatron.common.utils.MapTools;
import com.megatron.framework.core.CurrentService;
import com.megatron.framework.core.Service;
import com.megatron.framework.http.core.ServiceFactory;
import com.megatron.framework.http.model.RemoteService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.util.Assert;
import com.megatron.framework.http.core.HttpMethod;
import com.megatron.common.model.Sign;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@Component
public class ImsCloudServerService {
@Autowired
private ServiceFactory serviceFactory;
@Autowired
private CurrentService currentService;
/**
*
*
* @param pager
* @param token null使internal_token
* @return
*/
public GeneralResult list(Pager pager, String token) {
Map<String, Object> headers = new HashMap<>(4);
if (token == null) {
headers.put(BocloudToken.INTERNAL_TOKEN, currentService.getToken());
} else {
headers.put(Common.TOKEN, token);
}
RemoteService remoteService = serviceFactory.build(Service.create(String.valueOf(BoCloudService.CMP.getName())), "/v1/vms", HttpMethod.GET, headers, pager.toMap(false));
return remoteService.invoke();
}
public List<ContainerCluster> getCceContainer(Long vendorId) {
Map<String, Object> headers = new HashMap<>(4);
headers.put(BocloudToken.INTERNAL_TOKEN, currentService.getToken());
List<Param> paramList = new ArrayList<>();
paramList.add(new Param(MapTools.simpleMap("vendorId", vendorId), Sign.EQ));
RemoteService remoteService = serviceFactory.build(Service.create(String.valueOf(BoCloudService.CMP.getName())),
"/plugins/manageone/v1/containers/clusters", HttpMethod.GET, headers, new Pager(1, Integer.MAX_VALUE, paramList, null).toMap(false));
GeneralResult<?> result = remoteService.invoke();
Assert.isTrue(result.isSuccess(), "list manager bms failed, error:" + result.getMessage());
JSONObject data = (JSONObject) result.getData();
return data.getJSONArray(Common.ROWS).toJavaList(ContainerCluster.class);
}
}

View File

@ -0,0 +1,15 @@
package com.bocloud.mcs.syslog;
import ch.qos.logback.classic.net.SyslogAppender;
import ch.qos.logback.core.net.SyslogOutputStream;
import java.net.SocketException;
import java.net.UnknownHostException;
public class SysLogAppenderTcpAndUdp extends SyslogAppender {
@Override
public SyslogOutputStream createOutputStream() throws SocketException, UnknownHostException {
return new SyslogOutputStreamTcpAndUdp(getSyslogHost(), getPort());
}
}

View File

@ -0,0 +1,22 @@
package com.bocloud.mcs.syslog;
import ch.qos.logback.classic.spi.ILoggingEvent;
import ch.qos.logback.core.pattern.CompositeConverter;
import java.util.HashMap;
import java.util.Map;
public class SysLogLevelConvertor extends CompositeConverter<ILoggingEvent> {
private static final Map<String, String> MAP = new HashMap<>() {{
this.put("DEBUG", "7");
this.put("INFO", "6");
this.put("WARN", "4");
this.put("ERROR", "3");
}};
@Override
protected String transform(ILoggingEvent iLoggingEvent, String s) {
return MAP.getOrDefault(iLoggingEvent.getLevel().toString(), iLoggingEvent.getLevel().toString());
}
}

View File

@ -0,0 +1,70 @@
package com.bocloud.mcs.syslog;
import ch.qos.logback.core.net.SyslogOutputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.net.InetAddress;
import java.net.Socket;
import java.net.SocketException;
import java.net.UnknownHostException;
public class SyslogOutputStreamTcpAndUdp extends SyslogOutputStream {
private static final int MAX_LEN_TCP = 1024;
private InetAddress addressTcp;
private Socket socketTcp;
private ByteArrayOutputStream baosTcp = new ByteArrayOutputStream();
final private int portTcp;
public SyslogOutputStreamTcpAndUdp(String syslogHost, int port) throws SocketException, UnknownHostException {
super(syslogHost, port);
this.addressTcp = InetAddress.getByName(syslogHost);
this.portTcp = port;
try {
this.socketTcp = new Socket(addressTcp, portTcp);
} catch (IOException e) {
throw new SocketException(e);
}
}
@Override
public void write(byte[] byteArray, int offset, int len) throws IOException {
super.write(byteArray, offset, len);
baosTcp.write(byteArray, offset, len);
}
@Override
public void flush() throws IOException {
super.flush();
byte[] bytes = baosTcp.toByteArray();
// clean up for next round
if (baosTcp.size() > MAX_LEN_TCP) {
baosTcp = new ByteArrayOutputStream();
} else {
baosTcp.reset();
}
// after a failure, it can happen that bytes.length is zero
// in that case, there is no point in sending out an empty message/
if (bytes.length == 0) {
return;
}
if (this.socketTcp != null) {
socketTcp.getOutputStream().write(bytes);
}
}
@Override
public void close() {
super.close();
addressTcp = null;
try {
socketTcp.close();
} catch (IOException ignored) {
}
}
}

View File

@ -0,0 +1,111 @@
server:
port: '18080'
spring:
application:
name: mcs
thread:
core:
pool:
size: 1000
max:
pool:
size: 1000
queue:
capacity: 2000
upload:
path: /home/cmp
cloud:
zookeeper:
connect-string: 10.20.12.88:2181
home: /bocloud/cmp/product
auth:
username: bocloud
password: AES@CoU6oY/zuAoBbu6cdgOKlA==
config:
enabled: false
discovery:
register: true
enable: true
instance-host: 10.40.51.188
instance-port: ${server.port}
root: ${spring.cloud.zookeeper.home}/services
conn:
timeout: '50000'
session:
timeout: '50000'
datasource:
druid:
dialect: mysql
url: jdbc:mysql://10.20.12.88:3306/cmp?characterEncoding=utf8&useSSL=false
username: cmp
password: Gy2VghUgWHszx8gLFT4etT9ZVOukJi73KoG1q3Oz/DAz5h2mFVVunjcyaaKT9tMPsBgoWBFRmrYbhgqJqT/Q8A==
initialSize: '2'
maxActive: '30'
minIdle: '2'
maxWait: '60000'
poolPreparedStatements: 'true'
maxOpenPreparedStatements: '20'
maxPoolPreparedStatementPerConnectionSize: '20'
validationQuery: select 1
validationQueryTimeout: '1'
testOnBorrow: 'true'
testOnReturn: 'true'
testWhileIdle: 'true'
remove-abandoned: 'true'
remove-abandoned-timeout: '60'
log-abandoned: 'true'
timeBetweenEvictionRunsMillis: '10000'
minEvictableIdleTimeMillis: '30001'
asyncCloseConnectionEnable: 'true'
filters: config,stat,wall,log4j
publicKey: MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBAJfVJOpXYGy8aBCk3zEoKKQDTVCCvJwhhithfY/I5PUvzFBAYygunmuCtUhzPUZ+1RJQds0Q4fu07m5mr5kv5ocCAwEAAQ==
connectionProperties: config.decrypt=true;config.decrypt.key=MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBAJfVJOpXYGy8aBCk3zEoKKQDTVCCvJwhhithfY/I5PUvzFBAYygunmuCtUhzPUZ+1RJQds0Q4fu07m5mr5kv5ocCAwEAAQ==;druid.stat.mergeSql=true;druid.stat.slowSqlMillis=5000
use-global-data-source-stat: 'true'
rabbitmq:
host: 10.20.12.88
port: 5672
username: admin
password: AES@CoU6oY/zuAoBbu6cdgOKlA==
virtual-host: cmp
dynamic: 'true'
banner:
charset: UTF-8
freemarker:
checkTemplateLocation: 'false'
data:
redis:
# standalone
host: 10.20.12.88
port: 6379
timeout: 60000ms
password: AES@CoU6oY/zuAoBbu6cdgOKlA==
lettuce:
pool:
max-active: '1024'
max-idle: '16'
min-idle: '4'
max-wait: -1ms
servlet:
multipart:
max-file-size: 2MB
max-request-size: 20MB
main:
allow-circular-references: true
logging:
config: classpath:logback-spring.xml
dir: /log/services
level:
root: info
com:
bocloud: info
file:
max-size: 100MB
max-history: '30'
total-size-cap: 2GB
syslog:
#host: mai-miao.cn
#port: 8340
host: 10.20.12.88
port: 50000
facility: LOCAL3
level: info

View File

@ -0,0 +1,11 @@
$$$$$$$\ $$\ $$$$$$\ $$\ $$\ $$$$$$$\ $$\ $$\ $$$$$$\ $$$$$$\
$$ __$$\ $$ |$$ __$$\ $$$\ $$$ |$$ __$$\ $$$\ $$$ |$$ __$$\ $$ __$$\
$$ | $$ | $$$$$$\ $$\ $$\ $$$$$$\ $$$$$$$\ $$$$$$$ |$$ / \__|$$$$\ $$$$ |$$ | $$ | $$$$\ $$$$ |$$ / \__|$$ / \__|
$$$$$$$\ |$$ __$$\ $$ | $$ |$$ __$$\ $$ __$$\ $$ __$$ |$$ | $$\$$\$$ $$ |$$$$$$$ | $$\$$\$$ $$ |$$ | \$$$$$$\
$$ __$$\ $$$$$$$$ |$$ | $$ |$$ / $$ |$$ | $$ |$$ / $$ |$$ | $$ \$$$ $$ |$$ ____/ $$ \$$$ $$ |$$ | \____$$\
$$ | $$ |$$ ____|$$ | $$ |$$ | $$ |$$ | $$ |$$ | $$ |$$ | $$\ $$ |\$ /$$ |$$ | $$ |\$ /$$ |$$ | $$\ $$\ $$ |
$$$$$$$ |\$$$$$$$\ \$$$$$$$ |\$$$$$$ |$$ | $$ |\$$$$$$$ |\$$$$$$ |$$ | \_/ $$ |$$ | $$ | \_/ $$ |\$$$$$$ |\$$$$$$ |
\_______/ \_______| \____$$ | \______/ \__| \__| \_______| \______/ \__| \__|\__| \__| \__| \______/ \______/
$$\ $$ |
\$$$$$$ |
\______/

View File

@ -0,0 +1,20 @@
[aliyun]
[aliyun.ecs]
metric_include = ["cpu_total_average","memory_usedutilization_average","load_1m_average","load_5m_average","load_15m_average","diskusage_utilization_average",
"disk_writebytes_average","disk_readbytes_average","disk_writeiops_average","disk_readiops_average","fs_inodeutilization_average","net_tcpconnection_average",
"CPUUtilization_average","IntranetInRate_average","InternetInRate_average","InternetOutRate_average","IntranetOutRate_average","DiskReadBPS_average","DiskWriteBPS_average",
"DiskReadIOPS_average","DiskWriteIOPS_average"]
[aliyun.rds]
[aliyun.redis]
[aliyun.mongodb]
[aliyun.oceanbase]
[aliyun.kafka]
[aliyun.rocketmq]
[apsarastack.ecs]
metric_include = ["cpu_total_average","memory_usedutilization_average","load_1m_average","load_5m_average","load_15m_average","diskusage_utilization_average",
"disk_writebytes_average","disk_readbytes_average","disk_writeiops_average","disk_readiops_average","fs_inodeutilization_average","net_tcpconnection_average",
"CPUUtilization_average","IntranetInRate_average","InternetInRate_average","InternetOutRate_average","IntranetOutRate_average","DiskReadBPS_average","DiskWriteBPS_average",
"DiskReadIOPS_average","DiskWriteIOPS_average"]
[apsarastack.rds]
metric_include = ["DiskUsage_average","IOPSUsage_average","ConnectionUsage_average","CpuUsage_average","MemoryUsage_average","MySQL_NetworkInNew_average",
"MySQL_NetworkOutNew_average","MySQL_QPS_average","DockerCpuUsage_average"]

View File

@ -0,0 +1,75 @@
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<!-- 读取application.properties中的配置 -->
<springProperty scope="context" name="service.name" source="spring.application.name"/>
<springProperty scope="context" name="logging.dir" source="logging.dir"/>
<springProperty scope="context" name="logging.file.total-size-cap" source="logging.file.total-size-cap"/>
<springProperty scope="context" name="logging.file.max-size" source="logging.file.max-size"/>
<springProperty scope="context" name="logging.file.max-history" source="logging.file.max-history"/>
<springProperty scope="context" name="logging.level.com.bocloud" source="logging.level.com.bocloud"/>
<springProperty scope="context" name="logging.level.root" source="logging.level.root"/>
<springProperty scope="context" name="logging.syslog.host" source="logging.syslog.host"/>
<springProperty scope="context" name="logging.syslog.port" source="logging.syslog.port"/>
<springProperty scope="context" name="logging.syslog.facility" source="logging.syslog.facility"/>
<springProperty scope="context" name="logging.syslog.level" source="logging.syslog.level"/>
<conversionRule conversionWord="ilevel" converterClass="com.bocloud.mcs.syslog.SysLogLevelConvertor"/>
<property name="local_log_pattern" value="%d{yyyy-MM-dd HH:mm:ss.SSS} %highlight(%-5level) [%thread] [%X{REQUEST_ID}] %cyan(%logger{32}):%L - %msg%n"/>
<property name="sys_log_pattern" value="{&quot;level&quot;:&quot;%ilevel{%level}&quot;,&quot;log_level&quot;:&quot;%level&quot;,&quot;time&quot;:&quot;%d{yyyy-MM-dd HH:mm:ss.SSS}&quot;,&quot;thread&quot;:&quot;%thread&quot;,&quot;class&quot;:&quot;%logger{36}.%M:%line&quot;,&quot;message&quot;:&quot;%msg&quot;}%n"/>
<include resource="org/springframework/boot/logging/logback/defaults.xml" />
<!-- 默认的控制台日志输出,一般生产环境都是后台启动,这个没太大作用 -->
<appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
<layout class="ch.qos.logback.classic.PatternLayout">
<pattern>${local_log_pattern}</pattern>
</layout>
</appender>
<!-- 配置文件轮转 -->
<appender name="LOG_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<File>${logging.dir}/${service.name}.log</File>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<FileNamePattern>${logging.dir}/history/${service.name}.%d{yyyy-MM-dd}.%i.log.gz
</FileNamePattern>
<timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
<maxFileSize>${logging.file.max-size}</maxFileSize>
</timeBasedFileNamingAndTriggeringPolicy>
<MaxHistory>${logging.file.max-history}</MaxHistory>
<totalSizeCap>${logging.file.total-size-cap}</totalSizeCap>
</rollingPolicy>
<layout class="ch.qos.logback.classic.PatternLayout">
<pattern>${local_log_pattern}</pattern>
</layout>
</appender>
<!--syslog -->
<appender name="SYSLOG" class="com.bocloud.mcs.syslog.SysLogAppenderTcpAndUdp">
<syslogHost>${logging.syslog.host}</syslogHost> <!-- Syslog 服务器的地址 -->
<port>${logging.syslog.port}</port> <!-- Syslog 服务器的端口号 -->
<facility>${logging.syslog.facility}</facility> <!-- Syslog 设备标识 -->
<suffixPattern>${sys_log_pattern}</suffixPattern>
<filter class="ch.qos.logback.classic.filter.ThresholdFilter">
<level>${logging.syslog.level}</level>
</filter>
</appender>
<root level="${logging.level.root}">
<appender-ref ref="CONSOLE"/>
<appender-ref ref="LOG_FILE"/>
<appender-ref ref="SYSLOG"/>
</root>
<logger name="com.bocloud" level="${logging.level.com.bocloud}" additivity="false">
<appender-ref ref="CONSOLE"/>
<appender-ref ref="LOG_FILE"/>
<appender-ref ref="SYSLOG"/>
</logger>
<logger name="com.alibaba.druid.pool.DruidAbstractDataSource" level="error" additivity="false">
<appender-ref ref="CONSOLE"/>
<appender-ref ref="LOG_FILE"/>
<appender-ref ref="SYSLOG"/>
</logger>
</configuration>