mirror of
https://github.com/yunionio/cloudpods.git
synced 2026-08-31 01:35:56 +08:00
refactor(cloudmon): metric collect
This commit is contained in:
@@ -1,158 +0,0 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"os"
|
||||
"path"
|
||||
"time"
|
||||
|
||||
"yunion.io/x/log"
|
||||
"yunion.io/x/pkg/errors"
|
||||
"yunion.io/x/pkg/util/version"
|
||||
|
||||
_ "yunion.io/x/onecloud/pkg/cloudmon/collectors"
|
||||
"yunion.io/x/onecloud/pkg/cloudmon/options"
|
||||
"yunion.io/x/onecloud/pkg/mcclient"
|
||||
)
|
||||
|
||||
func showErrorAndExit(e error) {
|
||||
fmt.Fprintf(os.Stderr, "%s", e)
|
||||
fmt.Fprintln(os.Stderr)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
func newClientSession(options *options.CloudMonOptions) (*mcclient.ClientSession, error) {
|
||||
if len(options.AuthURL) == 0 {
|
||||
return nil, errors.Error("empty auth_url")
|
||||
}
|
||||
if len(options.AdminUser) == 0 {
|
||||
return nil, errors.Error("empty admin_user")
|
||||
}
|
||||
if len(options.AdminPassword) == 0 {
|
||||
return nil, errors.Error("empty admin_password")
|
||||
}
|
||||
if len(options.AdminProject) == 0 {
|
||||
return nil, errors.Error("empty admin_project")
|
||||
}
|
||||
|
||||
client := mcclient.NewClient(
|
||||
options.AuthURL,
|
||||
options.ReqTimeout,
|
||||
options.Debug,
|
||||
options.Insecure,
|
||||
options.CertFile,
|
||||
options.KeyFile,
|
||||
)
|
||||
|
||||
token, err := client.AuthenticateWithSource(
|
||||
options.AdminUser,
|
||||
options.AdminPassword,
|
||||
options.AdminDomain,
|
||||
options.AdminProject,
|
||||
options.AdminProjectDomain,
|
||||
mcclient.AuthSourceAPI)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
session := client.NewSession(
|
||||
context.Background(),
|
||||
options.Region,
|
||||
"",
|
||||
options.EndpointType,
|
||||
token,
|
||||
)
|
||||
|
||||
return session, nil
|
||||
}
|
||||
|
||||
func TestCron() {
|
||||
parser, err := options.GetArgumentParser()
|
||||
if err != nil {
|
||||
showErrorAndExit(err)
|
||||
}
|
||||
|
||||
err = parser.ParseArgs2(os.Args[1:], false, false)
|
||||
|
||||
opts := parser.Options().(*options.SubCloudMonOptions)
|
||||
|
||||
if opts.Help {
|
||||
fmt.Println(parser.HelpString())
|
||||
os.Exit(0)
|
||||
}
|
||||
|
||||
if opts.Version {
|
||||
fmt.Println(version.GetJsonString())
|
||||
os.Exit(0)
|
||||
}
|
||||
|
||||
if len(opts.Config) == 0 {
|
||||
for _, p := range []string{"./etc", "/etc/yunion"} {
|
||||
confTmp := path.Join(p, "cloudmon.conf")
|
||||
if _, err := os.Stat(confTmp); err == nil {
|
||||
opts.Config = confTmp
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if len(opts.Config) > 0 {
|
||||
err := parser.ParseFile(opts.Config)
|
||||
if err != nil {
|
||||
showErrorAndExit(err)
|
||||
}
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
showErrorAndExit(err)
|
||||
}
|
||||
|
||||
parser.SetDefault()
|
||||
|
||||
subcmd := parser.GetSubcommand()
|
||||
subparser := subcmd.GetSubParser()
|
||||
if err != nil {
|
||||
if subparser != nil {
|
||||
fmt.Print(subparser.Usage())
|
||||
} else {
|
||||
fmt.Print(parser.Usage())
|
||||
}
|
||||
showErrorAndExit(err)
|
||||
}
|
||||
|
||||
suboptions := subparser.Options()
|
||||
if opts.Subcommand == "help" {
|
||||
err = subcmd.Invoke(suboptions)
|
||||
} else {
|
||||
timout := suboptions.(*options.ReportOptions).Timeout
|
||||
endChan := make(chan int, 1)
|
||||
go func() {
|
||||
ticker := time.NewTicker(time.Duration(timout) * time.Second)
|
||||
for {
|
||||
select {
|
||||
case <-ticker.C:
|
||||
log.Errorf("cmd: %s,provider: %v,end due to timeout: %d s", opts.Subcommand,
|
||||
suboptions.(*options.ReportOptions).Provider, suboptions.(*options.ReportOptions).Timeout)
|
||||
os.Exit(3)
|
||||
case <-endChan:
|
||||
}
|
||||
}
|
||||
}()
|
||||
|
||||
var session *mcclient.ClientSession
|
||||
session, err = newClientSession(&opts.CloudMonOptions)
|
||||
if err != nil {
|
||||
showErrorAndExit(err)
|
||||
}
|
||||
err = subcmd.Invoke(session, suboptions)
|
||||
endChan <- 1
|
||||
}
|
||||
if err != nil {
|
||||
showErrorAndExit(err)
|
||||
}
|
||||
}
|
||||
|
||||
//func main() {
|
||||
// TestCron()
|
||||
//}
|
||||
+15
-10
@@ -35,7 +35,7 @@ import (
|
||||
type Options struct {
|
||||
Debug bool `help:"Show debug" default:"false"`
|
||||
AccessKey string `help:"Access key" default:"$JDCLOUD_ACCESS_KEY"`
|
||||
AccessSecret string `help:"Secret" default:"$JDCLOUD_ACCESS_SECRET"`
|
||||
AccessSecret string `help:"Secret" default:"$JDCLOUD_SECRET"`
|
||||
RegionId string `help:"RegionId" default:"$JDCLOUD_REGION"`
|
||||
SUBCOMMAND string `help:"jdcloudcli subcommand" subcommand:"true"`
|
||||
}
|
||||
@@ -69,7 +69,7 @@ func showErrorAndExit(e error) {
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
func newClient(options *Options) (*jdcloud.SRegion, error) {
|
||||
func newClient(options *Options) (*jdcloud.SJDCloudClient, error) {
|
||||
if len(options.AccessKey) == 0 {
|
||||
return nil, fmt.Errorf("Missing access key")
|
||||
}
|
||||
@@ -91,15 +91,16 @@ func newClient(options *Options) (*jdcloud.SRegion, error) {
|
||||
return cfgProxyFunc(req.URL)
|
||||
}
|
||||
|
||||
cfcg := &cloudprovider.ProviderConfig{
|
||||
cfcg := cloudprovider.ProviderConfig{
|
||||
ProxyFunc: proxyFunc,
|
||||
}
|
||||
|
||||
region := jdcloud.NewRegion(regionId, options.AccessKey, options.AccessSecret, cfcg, options.Debug)
|
||||
if region == nil {
|
||||
return nil, fmt.Errorf("no such region %s", regionId)
|
||||
}
|
||||
return region, nil
|
||||
return jdcloud.NewJDCloudClient(
|
||||
jdcloud.NewJDCloudClientConfig(
|
||||
options.AccessKey,
|
||||
options.AccessSecret,
|
||||
).CloudproviderConfig(cfcg).Debug(options.Debug),
|
||||
)
|
||||
}
|
||||
|
||||
func main() {
|
||||
@@ -134,11 +135,15 @@ func main() {
|
||||
fmt.Print(subparser.HelpString())
|
||||
return
|
||||
}
|
||||
var region *jdcloud.SRegion
|
||||
region, err = newClient(options)
|
||||
client, err := newClient(options)
|
||||
if err != nil {
|
||||
showErrorAndExit(err)
|
||||
}
|
||||
region := client.GetRegion(options.RegionId)
|
||||
if region == nil {
|
||||
fmt.Printf("not found region: %s", options.RegionId)
|
||||
return
|
||||
}
|
||||
err = subcmd.Invoke(region, suboptions)
|
||||
if err != nil {
|
||||
showErrorAndExit(err)
|
||||
|
||||
@@ -16,6 +16,7 @@ package compute
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"strings"
|
||||
|
||||
"yunion.io/x/pkg/errors"
|
||||
"yunion.io/x/pkg/util/regutils"
|
||||
@@ -63,6 +64,33 @@ type BucketDetails struct {
|
||||
AccessUrls []cloudprovider.SBucketAccessUrl `json:"access_urls"`
|
||||
}
|
||||
|
||||
func (self BucketDetails) GetMetricTags() map[string]string {
|
||||
ret := map[string]string{
|
||||
"brand": self.Brand,
|
||||
"cloudregion": self.Cloudregion,
|
||||
"cloudregion_id": self.CloudregionId,
|
||||
"domain_id": self.DomainId,
|
||||
"oss_id": self.Id,
|
||||
"oss_name": self.Name,
|
||||
"project_domain": self.ProjectDomain,
|
||||
"region_ext_id": self.RegionExtId,
|
||||
"status": self.Status,
|
||||
"tenant": self.Tenant,
|
||||
"tenant_id": self.TenantId,
|
||||
}
|
||||
for k, v := range self.Metadata {
|
||||
if strings.HasPrefix(k, apis.USER_TAG_PREFIX) {
|
||||
ret[k] = v
|
||||
}
|
||||
}
|
||||
return ret
|
||||
}
|
||||
|
||||
func (self BucketDetails) GetMetricPairs() map[string]string {
|
||||
ret := map[string]string{}
|
||||
return ret
|
||||
}
|
||||
|
||||
type BucketObjectsActionInput struct {
|
||||
Key []string
|
||||
}
|
||||
|
||||
@@ -15,7 +15,9 @@
|
||||
package compute
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"reflect"
|
||||
"strings"
|
||||
|
||||
"yunion.io/x/jsonutils"
|
||||
"yunion.io/x/pkg/gotypes"
|
||||
@@ -317,6 +319,29 @@ type CloudaccountDetail struct {
|
||||
ProjectMappingResourceInfo
|
||||
}
|
||||
|
||||
func (self CloudaccountDetail) GetMetricTags() map[string]string {
|
||||
ret := map[string]string{
|
||||
"cloudaccount_id": self.Id,
|
||||
"cloudaccount_name": self.Name,
|
||||
"brand": self.Brand,
|
||||
"domain_id": self.DomainId,
|
||||
"project_domain": self.ProjectDomain,
|
||||
}
|
||||
for k, v := range self.Metadata {
|
||||
if strings.HasPrefix(k, apis.USER_TAG_PREFIX) {
|
||||
ret[k] = v
|
||||
}
|
||||
}
|
||||
return ret
|
||||
}
|
||||
|
||||
func (self CloudaccountDetail) GetMetricPairs() map[string]string {
|
||||
ret := map[string]string{
|
||||
"balance": fmt.Sprintf("%.2f", self.Balance),
|
||||
}
|
||||
return ret
|
||||
}
|
||||
|
||||
type CloudaccountUpdateInput struct {
|
||||
apis.EnabledStatusInfrasResourceBaseUpdateInput
|
||||
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
package compute
|
||||
|
||||
import (
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"yunion.io/x/onecloud/pkg/apis"
|
||||
@@ -317,6 +318,42 @@ type DBInstanceDetails struct {
|
||||
Zone2Name string `json:"zone2_name"`
|
||||
// Zone3名称
|
||||
Zone3Name string `json:"zone3_name"`
|
||||
|
||||
Databases []apis.IdNameDetails `json:"databases"`
|
||||
}
|
||||
|
||||
func (self DBInstanceDetails) GetMetricTags() map[string]string {
|
||||
ret := map[string]string{
|
||||
"rds_id": self.Id,
|
||||
"rds_name": self.Name,
|
||||
"zone": self.Zone1Name,
|
||||
"zone_id": self.Zone1,
|
||||
"status": self.Status,
|
||||
"engine": self.Engine,
|
||||
"server_type": strings.ToLower(self.Engine),
|
||||
"cloudregion": self.Cloudregion,
|
||||
"cloudregion_id": self.CloudregionId,
|
||||
"region_ext_id": self.RegionExtId,
|
||||
"tenant": self.Project,
|
||||
"tenant_id": self.ProjectId,
|
||||
"brand": self.Brand,
|
||||
"domain_id": self.DomainId,
|
||||
"project_domain": self.ProjectDomain,
|
||||
}
|
||||
if len(self.IpAddrs) > 0 {
|
||||
ret["rds_ip"] = strings.ReplaceAll(self.IpAddrs, ",", "|")
|
||||
}
|
||||
for k, v := range self.Metadata {
|
||||
if strings.HasPrefix(k, apis.USER_TAG_PREFIX) {
|
||||
ret[k] = v
|
||||
}
|
||||
}
|
||||
return ret
|
||||
}
|
||||
|
||||
func (self DBInstanceDetails) GetMetricPairs() map[string]string {
|
||||
ret := map[string]string{}
|
||||
return ret
|
||||
}
|
||||
|
||||
type DBInstanceResourceInfoBase struct {
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
package compute
|
||||
|
||||
import (
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"yunion.io/x/onecloud/pkg/apis"
|
||||
@@ -37,6 +38,37 @@ type ElasticcacheDetails struct {
|
||||
SlaveZoneInfos []apis.StandaloneShortDesc `json:"slave_zone_infos"`
|
||||
}
|
||||
|
||||
func (self ElasticcacheDetails) GetMetricTags() map[string]string {
|
||||
ret := map[string]string{
|
||||
"redis_id": self.Id,
|
||||
"redis_ip": self.PrivateIpAddr,
|
||||
"redis_name": self.Name,
|
||||
"zone": self.Zone,
|
||||
"zone_id": self.ZoneId,
|
||||
"zone_ext_id": self.ZoneExtId,
|
||||
"status": self.Status,
|
||||
"cloudregion": self.Cloudregion,
|
||||
"cloudregion_id": self.CloudregionId,
|
||||
"region_ext_id": self.RegionExtId,
|
||||
"tenant": self.Tenant,
|
||||
"tenant_id": self.TenantId,
|
||||
"brand": self.Brand,
|
||||
"domain_id": self.DomainId,
|
||||
"project_domain": self.ProjectDomain,
|
||||
}
|
||||
for k, v := range self.Metadata {
|
||||
if strings.HasPrefix(k, apis.USER_TAG_PREFIX) {
|
||||
ret[k] = v
|
||||
}
|
||||
}
|
||||
return ret
|
||||
}
|
||||
|
||||
func (self ElasticcacheDetails) GetMetricPairs() map[string]string {
|
||||
ret := map[string]string{}
|
||||
return ret
|
||||
}
|
||||
|
||||
type ElasticcacheResourceInfo struct {
|
||||
// 弹性缓存实例名称
|
||||
Elasticcache string `json:"elasticcache"`
|
||||
|
||||
@@ -16,6 +16,7 @@ package compute
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"yunion.io/x/jsonutils"
|
||||
@@ -245,6 +246,49 @@ type ServerDetails struct {
|
||||
ScalingGroupId string `json:"scaling_group_id"`
|
||||
}
|
||||
|
||||
func (self ServerDetails) GetMetricTags() map[string]string {
|
||||
ret := map[string]string{
|
||||
"res_type": "guest",
|
||||
"is_vm": "true",
|
||||
"paltform": self.Hypervisor,
|
||||
"host": self.Host,
|
||||
"host_id": self.HostId,
|
||||
"vm_id": self.Id,
|
||||
"vm_name": self.Name,
|
||||
"zone": self.Zone,
|
||||
"zone_id": self.ZoneId,
|
||||
"zone_ext_id": self.ZoneExtId,
|
||||
"os_type": self.OsType,
|
||||
"status": self.Status,
|
||||
"cloudregion": self.Cloudregion,
|
||||
"cloudregion_id": self.CloudregionId,
|
||||
"region_ext_id": self.RegionExtId,
|
||||
"tenant": self.Tenant,
|
||||
"tenant_id": self.TenantId,
|
||||
"brand": self.Brand,
|
||||
"vm_scaling_group_id": self.ScalingGroupId,
|
||||
"domain_id": self.DomainId,
|
||||
"project_domain": self.TenantId,
|
||||
"account": self.Account,
|
||||
"account_id": self.AccountId,
|
||||
}
|
||||
for k, v := range self.Metadata {
|
||||
if strings.HasPrefix(k, apis.USER_TAG_PREFIX) {
|
||||
ret[k] = v
|
||||
}
|
||||
}
|
||||
return ret
|
||||
}
|
||||
|
||||
func (self ServerDetails) GetMetricPairs() map[string]string {
|
||||
ret := map[string]string{
|
||||
"vcpu_count": fmt.Sprintf("%d", self.VcpuCount),
|
||||
"vmem_size": fmt.Sprintf("%d", self.VmemSize),
|
||||
"disk": fmt.Sprintf("%d", self.DiskSizeMb),
|
||||
}
|
||||
return ret
|
||||
}
|
||||
|
||||
// GuestDiskInfo describe the information of disk on the guest.
|
||||
type GuestDiskInfo struct {
|
||||
Id string `json:"id"`
|
||||
|
||||
@@ -15,6 +15,8 @@
|
||||
package compute
|
||||
|
||||
import (
|
||||
"strings"
|
||||
|
||||
"yunion.io/x/jsonutils"
|
||||
|
||||
"yunion.io/x/onecloud/pkg/apis"
|
||||
@@ -228,6 +230,38 @@ type HostDetails struct {
|
||||
SysError string `json:"sys_error"`
|
||||
}
|
||||
|
||||
func (self HostDetails) GetMetricTags() map[string]string {
|
||||
ret := map[string]string{
|
||||
"host_id": self.Id,
|
||||
"host_ip": self.AccessIp,
|
||||
"host": self.Name,
|
||||
"zone": self.Zone,
|
||||
"zone_id": self.ZoneId,
|
||||
"zone_ext_id": self.ZoneExtId,
|
||||
"status": self.Status,
|
||||
"cloudregion": self.Cloudregion,
|
||||
"cloudregion_id": self.CloudregionId,
|
||||
"region_ext_id": self.RegionExtId,
|
||||
"brand": self.Brand,
|
||||
"domain_id": self.DomainId,
|
||||
"project_domain": self.ProjectDomain,
|
||||
"account": self.Account,
|
||||
"res_type": "host",
|
||||
"account_id": self.AccountId,
|
||||
}
|
||||
for k, v := range self.Metadata {
|
||||
if strings.HasPrefix(k, apis.USER_TAG_PREFIX) {
|
||||
ret[k] = v
|
||||
}
|
||||
}
|
||||
return ret
|
||||
}
|
||||
|
||||
func (self HostDetails) GetMetricPairs() map[string]string {
|
||||
ret := map[string]string{}
|
||||
return ret
|
||||
}
|
||||
|
||||
type HostResourceInfo struct {
|
||||
// 归属云订阅ID
|
||||
ManagerId string `json:"manager_id"`
|
||||
|
||||
@@ -45,10 +45,17 @@ type KubeClusterCreateInput struct {
|
||||
|
||||
type KubeClusterDetails struct {
|
||||
apis.EnabledStatusInfrasResourceBaseDetails
|
||||
|
||||
SKubeCluster
|
||||
ManagedResourceInfo
|
||||
CloudregionResourceInfo
|
||||
}
|
||||
|
||||
func (self KubeClusterDetails) GetMetricTags() map[string]string {
|
||||
ret := map[string]string{}
|
||||
return ret
|
||||
}
|
||||
|
||||
type KubeClusterUpdateInput struct {
|
||||
apis.EnabledStatusInfrasResourceBaseUpdateInput
|
||||
}
|
||||
|
||||
@@ -15,6 +15,9 @@
|
||||
package compute
|
||||
|
||||
import (
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"yunion.io/x/jsonutils"
|
||||
|
||||
"yunion.io/x/onecloud/pkg/apis"
|
||||
@@ -147,6 +150,34 @@ type StorageDetails struct {
|
||||
CommitBound float32 `json:"commit_bound"`
|
||||
}
|
||||
|
||||
func (self StorageDetails) GetMetricTags() map[string]string {
|
||||
ret := map[string]string{
|
||||
"storage_id": self.Id,
|
||||
"storage_name": self.Name,
|
||||
"brand": self.Brand,
|
||||
"domain_id": self.DomainId,
|
||||
"project_domain": self.ProjectDomain,
|
||||
}
|
||||
for k, v := range self.Metadata {
|
||||
if strings.HasPrefix(k, apis.USER_TAG_PREFIX) {
|
||||
ret[k] = v
|
||||
}
|
||||
}
|
||||
return ret
|
||||
}
|
||||
|
||||
func (self StorageDetails) GetMetricPairs() map[string]string {
|
||||
usageActive := "0"
|
||||
if self.Capacity > 0 {
|
||||
usageActive = strconv.FormatFloat(float64(self.ActualCapacityUsed/self.Capacity*100.0), 'f', -1, 64)
|
||||
}
|
||||
ret := map[string]string{
|
||||
"free": strconv.FormatFloat(float64(self.Capacity-self.ActualCapacityUsed), 'f', 2, 64),
|
||||
"usage_active": usageActive,
|
||||
}
|
||||
return ret
|
||||
}
|
||||
|
||||
type StorageResourceInfo struct {
|
||||
// 归属云订阅ID
|
||||
ManagerId string `json:"manager_id"`
|
||||
|
||||
@@ -33,6 +33,7 @@ const (
|
||||
SERVICE_TYPE_MONITOR = "monitor"
|
||||
SERVICE_TYPE_LOG = "log"
|
||||
SERVICE_TYPE_REGION = "compute"
|
||||
SERVICE_TYPE_CLOUDMON = "cloudmon"
|
||||
|
||||
SERVICE_TYPE_ETCD = "etcd"
|
||||
SERVICE_TYPE_INFLUXDB = "influxdb"
|
||||
|
||||
@@ -377,3 +377,8 @@ type OpsLogListInput struct {
|
||||
|
||||
Until time.Time `json:"until"`
|
||||
}
|
||||
|
||||
type IdNameDetails struct {
|
||||
Id string `json:"id"`
|
||||
Name string `json:"name"`
|
||||
}
|
||||
|
||||
@@ -159,6 +159,8 @@ type AlertListInput struct {
|
||||
}
|
||||
|
||||
type AlertDetails struct {
|
||||
SAlert
|
||||
|
||||
apis.StatusStandaloneResourceDetails
|
||||
apis.ScopedResourceBaseInfo
|
||||
}
|
||||
|
||||
@@ -42,6 +42,8 @@ type AlertRecordListInput struct {
|
||||
}
|
||||
|
||||
type AlertRecordDetails struct {
|
||||
SAlertRecord
|
||||
|
||||
apis.StatusStandaloneResourceDetails
|
||||
apis.ScopedResourceBaseInfo
|
||||
|
||||
@@ -50,6 +52,19 @@ type AlertRecordDetails struct {
|
||||
TriggerTime time.Time
|
||||
}
|
||||
|
||||
func (self AlertRecordDetails) GetMetricTags() map[string]string {
|
||||
ret := map[string]string{
|
||||
"alert_id": self.AlertId,
|
||||
"alert_name": self.AlertName,
|
||||
"domain_id": self.DomainId,
|
||||
"project_domain": self.ProjectDomain,
|
||||
"res_type": "agent",
|
||||
"tenant": self.Tenant,
|
||||
"tenant_id": self.TenantId,
|
||||
}
|
||||
return ret
|
||||
}
|
||||
|
||||
type AlertRecordCreateInput struct {
|
||||
apis.StandaloneResourceCreateInput
|
||||
|
||||
|
||||
@@ -38,6 +38,7 @@ var (
|
||||
)
|
||||
|
||||
type TCronJobFunction func(ctx context.Context, userCred mcclient.TokenCredential, isStart bool)
|
||||
type TCronJobFunctionWithStartTime func(ctx context.Context, userCred mcclient.TokenCredential, start time.Time, isStart bool)
|
||||
|
||||
var manager *SCronJobManager
|
||||
|
||||
@@ -72,11 +73,13 @@ func (t *TimerHour) Next(now time.Time) time.Time {
|
||||
}
|
||||
|
||||
type SCronJob struct {
|
||||
Name string
|
||||
job TCronJobFunction
|
||||
Timer ICronTimer
|
||||
Next time.Time
|
||||
StartRun bool
|
||||
Name string
|
||||
job TCronJobFunction
|
||||
jobWithStartTime TCronJobFunctionWithStartTime
|
||||
Timer ICronTimer
|
||||
Next time.Time
|
||||
StartRun bool
|
||||
times []time.Time
|
||||
}
|
||||
|
||||
type CronJobTimerHeap []*SCronJob
|
||||
@@ -161,6 +164,38 @@ func (self *SCronJobManager) AddJobAtIntervals(name string, interval time.Durati
|
||||
return self.AddJobAtIntervalsWithStartRun(name, interval, jobFunc, false)
|
||||
}
|
||||
|
||||
func (self *SCronJobManager) AddJobAtIntervalsWithStarTime(name string, interval time.Duration, jobFunc TCronJobFunctionWithStartTime) error {
|
||||
return self.AddJobAtIntervalsWithStarTimeStartRun(name, interval, jobFunc, false)
|
||||
}
|
||||
|
||||
func (self *SCronJobManager) AddJobAtIntervalsWithStarTimeStartRun(name string, interval time.Duration, jobFunc TCronJobFunctionWithStartTime, startRun bool) error {
|
||||
if interval <= 0 {
|
||||
return errors.Error("AddJobAtIntervals: interval must > 0")
|
||||
}
|
||||
self.dataLock.Lock()
|
||||
defer self.dataLock.Unlock()
|
||||
|
||||
if !self.IsNameUnique(name) {
|
||||
return ErrCronJobNameConflict
|
||||
}
|
||||
|
||||
t := Timer1{
|
||||
dur: interval,
|
||||
}
|
||||
job := SCronJob{
|
||||
Name: name,
|
||||
jobWithStartTime: jobFunc,
|
||||
Timer: &t,
|
||||
StartRun: startRun,
|
||||
}
|
||||
if !self.running {
|
||||
self.jobs = append(self.jobs, &job)
|
||||
} else {
|
||||
self.addJob(&job)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (self *SCronJobManager) AddJobAtIntervalsWithStartRun(name string, interval time.Duration, jobFunc TCronJobFunction, startRun bool) error {
|
||||
if interval <= 0 {
|
||||
return errors.Error("AddJobAtIntervals: interval must > 0")
|
||||
@@ -268,7 +303,7 @@ func (self *SCronJobManager) addJob(newJob *SCronJob) {
|
||||
now := time.Now()
|
||||
newJob.Next = newJob.Timer.Next(now)
|
||||
if newJob.StartRun {
|
||||
newJob.runJob(true)
|
||||
newJob.runJob(true, now)
|
||||
}
|
||||
heap.Push(&self.jobs, newJob)
|
||||
go func() { self.add <- struct{}{} }()
|
||||
@@ -335,7 +370,7 @@ func (self *SCronJobManager) init() {
|
||||
for i := 0; i < len(self.jobs); i += 1 {
|
||||
if self.jobs[i].StartRun {
|
||||
self.jobs[i].StartRun = false
|
||||
self.jobs[i].runJob(true)
|
||||
self.jobs[i].runJob(true, now)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -369,7 +404,7 @@ func (self *SCronJobManager) runJobs(now time.Time) {
|
||||
defer self.dataLock.Unlock()
|
||||
for i := 0; i < len(self.jobs); i++ {
|
||||
if !(self.jobs[i].Next.After(now) || self.jobs[i].Next.IsZero()) {
|
||||
self.jobs[i].runJob(false)
|
||||
self.jobs[i].runJob(false, now)
|
||||
self.jobs[i].Next = self.jobs[i].Timer.Next(now)
|
||||
heap.Fix(&self.jobs, i)
|
||||
}
|
||||
@@ -377,19 +412,25 @@ func (self *SCronJobManager) runJobs(now time.Time) {
|
||||
}
|
||||
|
||||
func (job *SCronJob) Run() {
|
||||
job.runJobInWorker(job.StartRun)
|
||||
startTime := time.Now()
|
||||
if len(job.times) > 0 {
|
||||
startTime = job.times[0]
|
||||
job.times = job.times[1:]
|
||||
}
|
||||
job.runJobInWorker(job.StartRun, startTime)
|
||||
}
|
||||
|
||||
func (job *SCronJob) Dump() string {
|
||||
return ""
|
||||
}
|
||||
|
||||
func (job *SCronJob) runJob(isStart bool) {
|
||||
func (job *SCronJob) runJob(isStart bool, now time.Time) {
|
||||
job.StartRun = isStart
|
||||
job.times = append(job.times, now)
|
||||
manager.workers.Run(job, nil, nil)
|
||||
}
|
||||
|
||||
func (job *SCronJob) runJobInWorker(isStart bool) {
|
||||
func (job *SCronJob) runJobInWorker(isStart bool, startTime time.Time) {
|
||||
defer func() {
|
||||
if r := recover(); r != nil {
|
||||
log.Errorf("CronJob task %s run error: %s", job.Name, r)
|
||||
@@ -397,10 +438,14 @@ func (job *SCronJob) runJobInWorker(isStart bool) {
|
||||
}
|
||||
}()
|
||||
|
||||
log.Debugf("Cron job: %s started", job.Name)
|
||||
log.Debugf("Cron job: %s started, startTime: %s", job.Name, startTime)
|
||||
ctx := context.Background()
|
||||
ctx = context.WithValue(ctx, appctx.APP_CONTEXT_KEY_APPNAME, "Cron-Service")
|
||||
ctx = context.WithValue(ctx, appctx.APP_CONTEXT_KEY_TASKNAME, fmt.Sprintf("%s-%d", job.Name, time.Now().Unix()))
|
||||
userCred := DefaultAdminSessionGenerator()
|
||||
job.job(ctx, userCred, isStart)
|
||||
if job.job != nil {
|
||||
job.job(ctx, userCred, isStart)
|
||||
} else if job.jobWithStartTime != nil {
|
||||
job.jobWithStartTime(ctx, userCred, startTime, isStart)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,142 +0,0 @@
|
||||
// Copyright 2019 Yunion
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package alertrecordhistorymon
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"strconv"
|
||||
"time"
|
||||
|
||||
"golang.org/x/sync/errgroup"
|
||||
|
||||
"yunion.io/x/jsonutils"
|
||||
"yunion.io/x/pkg/errors"
|
||||
"yunion.io/x/pkg/util/timeutils"
|
||||
|
||||
"yunion.io/x/onecloud/pkg/cloudmon/collectors/common"
|
||||
"yunion.io/x/onecloud/pkg/cloudmon/options"
|
||||
"yunion.io/x/onecloud/pkg/mcclient"
|
||||
modules "yunion.io/x/onecloud/pkg/mcclient/modules/monitor"
|
||||
)
|
||||
|
||||
func init() {
|
||||
factory := SAlertRecordHistoryFactory{}
|
||||
common.RegisterFactory(&factory)
|
||||
}
|
||||
|
||||
type SAlertRecordHistoryFactory struct {
|
||||
}
|
||||
|
||||
func (self *SAlertRecordHistoryFactory) MyRoutineInteval(monOptions options.CloudMonOptions) time.Duration {
|
||||
return time.Duration(monOptions.AlertRecordHistoryInterval)
|
||||
}
|
||||
|
||||
func (self *SAlertRecordHistoryFactory) MyRoutineFunc() common.RoutineFunc {
|
||||
return common.MakePullMetricRoutineAtZeroPoint
|
||||
}
|
||||
|
||||
func (self *SAlertRecordHistoryFactory) NewCloudReport(provider *common.SProvider, session *mcclient.ClientSession,
|
||||
args *options.ReportOptions,
|
||||
operatorType string) common.ICloudReport {
|
||||
return &SAlertRecordHistoryReport{
|
||||
common.CloudReportBase{
|
||||
SProvider: nil,
|
||||
Session: session,
|
||||
Args: args,
|
||||
Operator: string(common.ALERT_RECORD),
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func (S *SAlertRecordHistoryFactory) GetId() string {
|
||||
return string(common.ALERT_RECORD)
|
||||
}
|
||||
|
||||
type SAlertRecordHistoryReport struct {
|
||||
common.CloudReportBase
|
||||
}
|
||||
|
||||
func (self *SAlertRecordHistoryReport) Report() error {
|
||||
alerts, err := self.getMonitorCommonAlert()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
errs := make([]error, 0)
|
||||
recordGroup, _ := errgroup.WithContext(context.Background())
|
||||
count := 0
|
||||
for i, _ := range alerts {
|
||||
tmp := alerts[i]
|
||||
count++
|
||||
recordGroup.Go(func() error {
|
||||
alert_id, _ := tmp.GetString("id")
|
||||
alertRecords, err := self.getAlertRecordsByAlertId(alert_id)
|
||||
if err != nil {
|
||||
return errors.Wrapf(err, "getAlertRecordsByAlertId:%s error", alert_id)
|
||||
}
|
||||
return self.collectMetric(alertRecords)
|
||||
})
|
||||
if count == 4 {
|
||||
err := recordGroup.Wait()
|
||||
if err != nil {
|
||||
errs = append(errs, errors.Wrap(err, "alertRecordHistoryReport collectMetric error"))
|
||||
}
|
||||
count = 0
|
||||
}
|
||||
}
|
||||
err = recordGroup.Wait()
|
||||
if err != nil {
|
||||
errs = append(errs, errors.Wrap(err, "alertRecordHistoryReport collectMetric error"))
|
||||
}
|
||||
return errors.NewAggregate(errs)
|
||||
}
|
||||
|
||||
func (self *SAlertRecordHistoryReport) getMonitorCommonAlert() ([]jsonutils.JSONObject, error) {
|
||||
alerts := make([]jsonutils.JSONObject, 0)
|
||||
query := jsonutils.NewDict()
|
||||
query.Add(jsonutils.NewString("0"), common.KEY_LIMIT)
|
||||
//query.Add(jsonutils.NewBool(true), common.DETAILS)
|
||||
query.Add(jsonutils.NewString("system"), "scope")
|
||||
|
||||
alerts, err := self.ListAllResource(modules.CommonAlertManager, query)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "getMonitorCommonAlert error")
|
||||
}
|
||||
return alerts, nil
|
||||
}
|
||||
|
||||
func (self *SAlertRecordHistoryReport) getAlertRecordsByAlertId(id string) ([]jsonutils.JSONObject, error) {
|
||||
now := time.Now().UTC()
|
||||
period64, err := strconv.ParseInt(self.Args.Interval, 10, 8)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
query := jsonutils.NewDict()
|
||||
query.Add(jsonutils.NewString("0"), common.KEY_LIMIT)
|
||||
query.Add(jsonutils.NewBool(true), common.DETAILS)
|
||||
query.Add(jsonutils.NewString("system"), "scope")
|
||||
query.Add(jsonutils.NewString(id), "alert_id")
|
||||
query.Add(jsonutils.NewString("alerting"), "state")
|
||||
query.Add(jsonutils.NewString(fmt.Sprintf(`created_at.between("%s","%s")`,
|
||||
now.Add(-time.Hour*24*time.Duration(period64)).Format(timeutils.MysqlTimeFormat),
|
||||
now.Format(timeutils.MysqlTimeFormat))),
|
||||
"filter")
|
||||
|
||||
alertRecords, err := self.ListAllResource(modules.AlertRecordManager, query)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return alertRecords, nil
|
||||
}
|
||||
@@ -1,54 +0,0 @@
|
||||
// Copyright 2019 Yunion
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package alertrecordhistorymon
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
"yunion.io/x/jsonutils"
|
||||
|
||||
"yunion.io/x/onecloud/pkg/cloudmon/collectors/common"
|
||||
"yunion.io/x/onecloud/pkg/util/influxdb"
|
||||
)
|
||||
|
||||
func (self *SAlertRecordHistoryReport) collectMetric(alertRecords []jsonutils.JSONObject) error {
|
||||
dataList := make([]influxdb.SMetricData, 0)
|
||||
matchRecord := self.getMaxEvalMatchOfAlertRecord(alertRecords)
|
||||
if matchRecord == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
metric, err := self.NewMetricFromJson(matchRecord)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
metric.Timestamp = time.Now()
|
||||
metric.Name = ALERT_RECORD_HISTORY_MEASUREMENT
|
||||
dataList = append(dataList, metric)
|
||||
return common.SendMetrics(self.Session, dataList, self.Args.Debug, ALERT_RECORD_HISTORY_DATABASE)
|
||||
}
|
||||
|
||||
func (self *SAlertRecordHistoryReport) getMaxEvalMatchOfAlertRecord(alertRecords []jsonutils.JSONObject) jsonutils.JSONObject {
|
||||
var matchRecord jsonutils.JSONObject
|
||||
maxCount := int64(0)
|
||||
for _, record := range alertRecords {
|
||||
resNum, _ := record.Int("res_num")
|
||||
if resNum > maxCount {
|
||||
maxCount = resNum
|
||||
matchRecord = record
|
||||
}
|
||||
}
|
||||
return matchRecord
|
||||
}
|
||||
@@ -1,15 +0,0 @@
|
||||
// Copyright 2019 Yunion
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package alertrecordhistorymon // import "yunion.io/x/onecloud/pkg/cloudmon/collectors/alertrecordhistorymon"
|
||||
@@ -1,96 +0,0 @@
|
||||
// Copyright 2019 Yunion
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package alimon
|
||||
|
||||
import "yunion.io/x/onecloud/pkg/cloudmon/collectors/common"
|
||||
|
||||
const (
|
||||
SERVER_METRIC_NAMESPACE = "acs_ecs_dashboard"
|
||||
|
||||
REDIS_METRIC_NAMESPACE = "acs_kvstore"
|
||||
RDS_METRIC_NAMESPACE = "acs_rds_dashboard"
|
||||
OSS_METRIC_NAMESPACE = "acs_oss"
|
||||
ELB_METRIC_NAMESPACE = "acs_slb_dashboard"
|
||||
|
||||
K8S_METRIC_NAMESPACE = "acs_k8s"
|
||||
)
|
||||
|
||||
//multiCloud查询指标列表组装
|
||||
var aliMetricSpecs = map[string][]string{
|
||||
"CPUUtilization": {common.DEFAULT_STATISTICS, common.UNIT_PERCENT, common.INFLUXDB_FIELD_CPU_USAGE},
|
||||
"InternetInRate": {common.DEFAULT_STATISTICS, common.UNIT_BPS, common.INFLUXDB_FIELD_NET_BPS_RX_INTERNET},
|
||||
"IntranetInRate": {common.DEFAULT_STATISTICS, common.UNIT_BPS, common.INFLUXDB_FIELD_NET_BPS_RX_INTRANET},
|
||||
"InternetOutRate": {common.DEFAULT_STATISTICS, common.UNIT_BPS, common.INFLUXDB_FIELD_NET_BPS_TX_INTERNET},
|
||||
"IntranetOutRate": {common.DEFAULT_STATISTICS, common.UNIT_BPS, common.INFLUXDB_FIELD_NET_BPS_TX_INTRANET},
|
||||
"DiskReadBPS": {common.DEFAULT_STATISTICS, common.UNIT_BYTEPS, common.INFLUXDB_FIELD_DISK_READ_BPS},
|
||||
"DiskWriteBPS": {common.DEFAULT_STATISTICS, common.UNIT_BYTEPS, common.INFLUXDB_FIELD_DISK_WRITE_BPS},
|
||||
"DiskReadIOPS": {common.DEFAULT_STATISTICS, common.UNIT_CPS, common.INFLUXDB_FIELD_DISK_READ_IOPS},
|
||||
"DiskWriteIOPS": {common.DEFAULT_STATISTICS, common.UNIT_CPS, common.INFLUXDB_FIELD_DISK_WRITE_IOPS},
|
||||
}
|
||||
var aliRdsMetricSpecs = map[string][]string{
|
||||
"CpuUsage": {common.DEFAULT_STATISTICS, common.UNIT_PERCENT, common.INFLUXDB_FIELD_RDS_CPU_USAGE},
|
||||
"MemoryUsage": {common.DEFAULT_STATISTICS, common.UNIT_PERCENT, common.INFLUXDB_FIELD_RDS_MEM_USAGE},
|
||||
"MySQL_NetworkInNew": {common.DEFAULT_STATISTICS, common.UNIT_BPS, common.INFLUXDB_FIELD_RDS_NET_BPS_RX_MYSQL},
|
||||
"MySQL_NetworkOutNew": {common.DEFAULT_STATISTICS, common.UNIT_BPS, common.INFLUXDB_FIELD_RDS_NET_BPS_TX_MYSQL},
|
||||
"DiskUsage": {common.DEFAULT_STATISTICS, common.UNIT_PERCENT, common.INFLUXDB_FIELD_RDS_DISK_USAGE},
|
||||
"SQLServer_NetworkInNew": {common.DEFAULT_STATISTICS, common.UNIT_BPS, common.INFLUXDB_FIELD_RDS_NET_BPS_RX_SQLSERVER},
|
||||
"SQLServer_NetworkOutNew": {common.DEFAULT_STATISTICS, common.UNIT_BPS, common.INFLUXDB_FIELD_RDS_NET_BPS_TX_SQLSERVER},
|
||||
"ConnectionUsage": {common.DEFAULT_STATISTICS, common.UNIT_PERCENT, common.INFLUXDB_FIELD_RDS_CONN_USAGE},
|
||||
}
|
||||
var aliRedisMetricSpecs = map[string][]string{
|
||||
"CpuUsage": {common.DEFAULT_STATISTICS, common.UNIT_PERCENT, common.INFLUXDB_FIELD_REDIS_CPU_USAGE},
|
||||
"MemoryUsage": {common.DEFAULT_STATISTICS, common.UNIT_PERCENT, common.INFLUXDB_FIELD_REDIS_MEM_USAGE},
|
||||
"IntranetIn": {common.DEFAULT_STATISTICS, common.UNIT_BPS, common.INFLUXDB_FIELD_REDIS_NET_BPS_RX},
|
||||
"IntranetOut": {common.DEFAULT_STATISTICS, common.UNIT_BPS, common.INFLUXDB_FIELD_REDIS_NET_BPS_TX},
|
||||
"UsedConnection": {common.DEFAULT_STATISTICS, common.UNIT_COUNT, common.INFLUXDB_FIFLD_REDIS_CONN_USAGE},
|
||||
"UsedQPS": {common.DEFAULT_STATISTICS, common.UNIT_COUNT, common.INFLUXDB_FIFLD_REDIS_OPT_SES},
|
||||
"Keys": {common.DEFAULT_STATISTICS, common.UNIT_COUNT, common.INFLUXDB_FIFLD_REDIS_CACHE_KEYS},
|
||||
"ExpiredKeys": {common.DEFAULT_STATISTICS, common.UNIT_COUNT, common.INFLUXDB_FIFLD_REDIS_CACHE_EXP_KEYS},
|
||||
"UsedMemory": {common.DEFAULT_STATISTICS, common.UNIT_MEM, common.INFLUXDB_FIFLD_REDIS_DATA_MEM_USAGE},
|
||||
}
|
||||
var aliOSSMetricSpecs = map[string][]string{
|
||||
"InternetSend": {common.DEFAULT_STATISTICS, common.UNIT_MEM, common.INFLUXDB_FIELD_OSS_NET_BPS_TX_INTERNET},
|
||||
"InternetRecv": {common.DEFAULT_STATISTICS, common.UNIT_MEM, common.INFLUXDB_FIELD_OSS_NET_BPS_RX_INTERNET},
|
||||
"IntranetSend": {common.DEFAULT_STATISTICS, common.UNIT_MEM, common.INFLUXDB_FIELD_OSS_NET_BPS_TX_INTRANET},
|
||||
"IntranetRecv": {common.DEFAULT_STATISTICS, common.UNIT_MEM, common.INFLUXDB_FIELD_OSS_NET_BPS_RX_INTRANET},
|
||||
"GetObjectE2eLatency": {common.DEFAULT_STATISTICS, common.UNIT_MSEC, common.INFLUXDB_FIELD_OSS_LATECY_GET},
|
||||
"PostObjectE2eLatency": {common.DEFAULT_STATISTICS, common.UNIT_MSEC, common.INFLUXDB_FIELD_OSS_LATECY_POST},
|
||||
"GetObjectCount": {common.DEFAULT_STATISTICS, common.UNIT_COUNT, common.INFLUXDB_FIELD_OSS_REQ_COUNT_GET},
|
||||
"PostObjectCount": {common.DEFAULT_STATISTICS, common.UNIT_COUNT, common.INFLUXDB_FIELD_OSS_REQ_COUNT_POST},
|
||||
"ServerErrorCount": {common.DEFAULT_STATISTICS, common.UNIT_COUNT, common.INFLUXDB_FIELD_OSS_REQ_COUNT_5XX},
|
||||
}
|
||||
var aliElbMetricSpecs = map[string][]string{
|
||||
"InstanceTrafficRX": {common.DEFAULT_STATISTICS, common.UNIT_BPS, common.INFLUXDB_FIELD_ELB_NET_BPS_RX},
|
||||
"InstanceTrafficTX": {common.DEFAULT_STATISTICS, common.UNIT_BPS, common.INFLUXDB_FIELD_ELB_NET_BPS_TX},
|
||||
"InstanceStatusCode2xx": {common.DEFAULT_STATISTICS, common.UNIT_COUNT_SEC, common.INFLUXDB_FIELD_ELB_HRSP_COUNT_2XX},
|
||||
"InstanceStatusCode3xx": {common.DEFAULT_STATISTICS, common.UNIT_COUNT_SEC, common.INFLUXDB_FIELD_ELB_HRSP_COUNT_3XX},
|
||||
"InstanceStatusCode4xx": {common.DEFAULT_STATISTICS, common.UNIT_COUNT_SEC, common.INFLUXDB_FIELD_ELB_HRSP_COUNT_4XX},
|
||||
"InstanceStatusCode5xx": {common.DEFAULT_STATISTICS, common.UNIT_COUNT_SEC, common.INFLUXDB_FIELD_ELB_HRSP_COUNT_5XX},
|
||||
}
|
||||
|
||||
var aliK8SClusterMetricSpecs = map[string][]string{
|
||||
"cluster.cpu.utilization": {common.DEFAULT_STATISTICS, common.UNIT_PERCENT, common.INFLUXDB_FIELD_K8S_CLUSTER_CPU_USAGE},
|
||||
"cluster.memory.utilization": {common.DEFAULT_STATISTICS, common.UNIT_PERCENT, common.INFLUXDB_FIELD_K8S_CLUSTER_MEM_USAGE},
|
||||
}
|
||||
|
||||
var aliK8SPodMetricSpecs = map[string][]string{
|
||||
"pod.cpu.utilization": {common.DEFAULT_STATISTICS, common.UNIT_PERCENT, common.INFLUXDB_FIELD_K8S_POD_CPU_USAGE},
|
||||
"pod.memory.utilization": {common.DEFAULT_STATISTICS, common.UNIT_PERCENT, common.INFLUXDB_FIELD_K8S_POD_MEM_USAGE},
|
||||
}
|
||||
|
||||
var aliK8SNodeMetricSpecs = map[string][]string{
|
||||
"node.cpu.utilization": {common.DEFAULT_STATISTICS, common.UNIT_PERCENT, common.INFLUXDB_FIELD_K8S_NODE_CPU_USAGE},
|
||||
"node.memory.utilization": {common.DEFAULT_STATISTICS, common.UNIT_PERCENT, common.INFLUXDB_FIELD_K8S_NODE_MEM_USAGE},
|
||||
}
|
||||
@@ -1,143 +0,0 @@
|
||||
// Copyright 2019 Yunion
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package alimon
|
||||
|
||||
import (
|
||||
"yunion.io/x/jsonutils"
|
||||
|
||||
"yunion.io/x/onecloud/pkg/apis/compute"
|
||||
"yunion.io/x/onecloud/pkg/cloudmon/collectors/common"
|
||||
"yunion.io/x/onecloud/pkg/cloudmon/options"
|
||||
"yunion.io/x/onecloud/pkg/mcclient"
|
||||
)
|
||||
|
||||
func init() {
|
||||
factory := SAliCloudReportFactory{}
|
||||
common.RegisterFactory(&factory)
|
||||
cluster := &AliK8sClusterHelper{
|
||||
K8sClusterMetricBaseHelper: &common.K8sClusterMetricBaseHelper{
|
||||
ModuleHelper: map[common.K8sClusterModuleType]common.IK8sClusterModuleHelper{},
|
||||
},
|
||||
}
|
||||
cluster.RegisterModuleHelper(new(AliK8sClusterPodHelper))
|
||||
cluster.RegisterModuleHelper(new(AliK8sClusterNodeHelper))
|
||||
common.RegisterK8sClusterHelper(cluster)
|
||||
}
|
||||
|
||||
type SAliCloudReportFactory struct {
|
||||
common.CommonReportFactory
|
||||
}
|
||||
|
||||
func (self *SAliCloudReportFactory) NewCloudReport(provider *common.SProvider, session *mcclient.ClientSession,
|
||||
args *options.ReportOptions, operatorType string) common.ICloudReport {
|
||||
return &SAliCloudReport{
|
||||
common.CloudReportBase{
|
||||
SProvider: provider,
|
||||
Session: session,
|
||||
Args: args,
|
||||
Operator: operatorType,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func (self *SAliCloudReportFactory) GetId() string {
|
||||
return compute.CLOUD_PROVIDER_ALIYUN
|
||||
}
|
||||
|
||||
type SAliCloudReport struct {
|
||||
common.CloudReportBase
|
||||
}
|
||||
|
||||
func (self *SAliCloudReport) Report() error {
|
||||
var servers []jsonutils.JSONObject
|
||||
var err error
|
||||
|
||||
servers, err = self.GetResourceByOperator()
|
||||
|
||||
providerInstance, err := self.InitProviderInstance()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
regionList, regionServerMap, err := self.GetAllRegionOfServers(servers, providerInstance)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
for _, region := range regionList {
|
||||
servers := regionServerMap[region.GetGlobalId()]
|
||||
switch common.MonType(self.Operator) {
|
||||
case common.REDIS:
|
||||
err = self.collectRegionMetricOfRedis(region, servers)
|
||||
case common.K8S:
|
||||
err = self.collectRegionMetricOfResource(region, servers)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
self.Impl = self
|
||||
err = self.CollectRegionMetricOfK8sModules(region, servers)
|
||||
default:
|
||||
err = self.collectRegionMetricOfResource(region, servers)
|
||||
}
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type AliK8sClusterHelper struct {
|
||||
*common.K8sClusterMetricBaseHelper
|
||||
}
|
||||
|
||||
func (a AliK8sClusterHelper) HelperBrand() string {
|
||||
return compute.CLOUD_PROVIDER_ALIYUN
|
||||
}
|
||||
|
||||
type AliK8sClusterPodHelper struct {
|
||||
common.K8sClusterModuleQueryHelper
|
||||
}
|
||||
|
||||
func (q AliK8sClusterPodHelper) MyModuleType() common.K8sClusterModuleType {
|
||||
return common.K8S_MODULE_POD
|
||||
}
|
||||
|
||||
func (q AliK8sClusterPodHelper) MyResDimensionId() common.DimensionId {
|
||||
return common.DimensionId{
|
||||
LocalId: "name",
|
||||
ExtId: "pod",
|
||||
}
|
||||
}
|
||||
|
||||
func (q AliK8sClusterPodHelper) MyNamespaceAndMetrics() (string, map[string][]string) {
|
||||
return K8S_METRIC_NAMESPACE, aliK8SPodMetricSpecs
|
||||
}
|
||||
|
||||
type AliK8sClusterNodeHelper struct {
|
||||
common.K8sClusterModuleQueryHelper
|
||||
}
|
||||
|
||||
func (a AliK8sClusterNodeHelper) MyModuleType() common.K8sClusterModuleType {
|
||||
return common.K8S_MODULE_NODE
|
||||
}
|
||||
|
||||
func (a AliK8sClusterNodeHelper) MyResDimensionId() common.DimensionId {
|
||||
return common.DimensionId{
|
||||
LocalId: "name",
|
||||
ExtId: "node",
|
||||
}
|
||||
}
|
||||
|
||||
func (a AliK8sClusterNodeHelper) MyNamespaceAndMetrics() (string, map[string][]string) {
|
||||
return K8S_METRIC_NAMESPACE, aliK8SNodeMetricSpecs
|
||||
}
|
||||
@@ -1,315 +0,0 @@
|
||||
// Copyright 2019 Yunion
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package alimon
|
||||
|
||||
import (
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"yunion.io/x/jsonutils"
|
||||
"yunion.io/x/log"
|
||||
|
||||
"yunion.io/x/onecloud/pkg/cloudmon/collectors/common"
|
||||
"yunion.io/x/onecloud/pkg/cloudprovider"
|
||||
"yunion.io/x/onecloud/pkg/multicloud/aliyun"
|
||||
"yunion.io/x/onecloud/pkg/util/influxdb"
|
||||
)
|
||||
|
||||
func (self *SAliCloudReport) collectRegionMetricOfResource(region cloudprovider.ICloudRegion, servers []jsonutils.JSONObject) error {
|
||||
dataList := make([]influxdb.SMetricData, 0)
|
||||
aliReg := region.(*aliyun.SRegion)
|
||||
since, until, err := common.TimeRangeFromArgs(self.Args)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
namespace, metrics := self.getMetricSpecs(servers)
|
||||
dimensionId := self.getDimensionId()
|
||||
dataCnt := 0
|
||||
for metricName, influxDbSpecs := range metrics {
|
||||
rtnArray, _, err := aliReg.DescribeMetricList(metricName, namespace, since, until, "", nil)
|
||||
if err != nil {
|
||||
log.Errorln(err)
|
||||
continue
|
||||
}
|
||||
dataCnt = len(dataList)
|
||||
if len(rtnArray) > 0 {
|
||||
for _, rtnMetric := range rtnArray {
|
||||
for _, server := range servers {
|
||||
external_id, _ := server.GetString(dimensionId.LocalId)
|
||||
if instanceId, _ := rtnMetric.GetString(dimensionId.ExtId); instanceId == external_id {
|
||||
if self.Operator == string(common.SERVER) {
|
||||
metric, err := common.FillVMCapacity(server.(*jsonutils.JSONDict))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
dataList = append(dataList, metric)
|
||||
}
|
||||
serverMetric, err := self.collectMetricFromThisServer(server, rtnMetric, influxDbSpecs, metricName)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
dataList = append(dataList, serverMetric)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
log.Debugf("%s %s %s report %d metric", self.SProvider.Name, self.Operator, metricName, len(dataList)-dataCnt)
|
||||
}
|
||||
return common.SendMetrics(self.Session, dataList, self.Args.Debug, "")
|
||||
}
|
||||
|
||||
func (self *SAliCloudReport) collectRegionMetricOfRedis(region cloudprovider.ICloudRegion,
|
||||
servers []jsonutils.JSONObject) error {
|
||||
dataList := make([]influxdb.SMetricData, 0)
|
||||
aliReg := region.(*aliyun.SRegion)
|
||||
since, until, err := common.TimeRangeFromArgs(self.Args)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
redisDeployType := make(map[string]string)
|
||||
for _, server := range servers {
|
||||
local_category, err := server.GetString("local_category")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
switch local_category {
|
||||
case "single":
|
||||
redisDeployType["single"] = "Standard"
|
||||
case "master":
|
||||
redisDeployType["master"] = "Standard"
|
||||
case "cluster":
|
||||
redisDeployType["cluster"] = "Sharding"
|
||||
case "rwsplit":
|
||||
redisDeployType["rwsplit"] = "Splitrw"
|
||||
}
|
||||
|
||||
}
|
||||
dataCnt := 0
|
||||
for metricName, influxDbSpecs := range aliRedisMetricSpecs {
|
||||
for _, pre := range redisDeployType {
|
||||
rtnArray, _, err := aliReg.DescribeMetricList(pre+metricName, "acs_kvstore", since, until, "", nil)
|
||||
if err != nil {
|
||||
log.Errorln(err)
|
||||
continue
|
||||
}
|
||||
dataCnt = len(dataList)
|
||||
if len(rtnArray) > 0 {
|
||||
for _, rtnMetric := range rtnArray {
|
||||
for _, server := range servers {
|
||||
external_id, _ := server.GetString("external_id")
|
||||
if instanceId, _ := rtnMetric.GetString("instanceId"); instanceId == external_id {
|
||||
serverMetric, err := self.collectMetricFromThisServer(server, rtnMetric, influxDbSpecs, "")
|
||||
node_id, _ := rtnMetric.GetString("nodeId")
|
||||
serverMetric.Tags = append(serverMetric.Tags, influxdb.SKeyValue{Key: "node_id", Value: node_id})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
dataList = append(dataList, serverMetric)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
log.Debugf("%s %s %s report %d metric", self.SProvider.Name, self.Operator, metricName, len(dataList)-dataCnt)
|
||||
}
|
||||
return common.SendMetrics(self.Session, dataList, self.Args.Debug, "")
|
||||
}
|
||||
|
||||
func (self *SAliCloudReport) collectMetricFromThisServer(server jsonutils.JSONObject, rtnMetric jsonutils.JSONObject, influxDbSpecs []string, valueKey string) (influxdb.SMetricData, error) {
|
||||
metric, err := self.NewMetricFromJson(server)
|
||||
//metric, err := common.JsonToMetric(server.(*jsonutils.JSONDict), "", common.ServerTags, make([]string, 0))
|
||||
if err != nil {
|
||||
return influxdb.SMetricData{}, err
|
||||
}
|
||||
timestamp, _ := rtnMetric.Get("timestamp")
|
||||
metric.Timestamp = time.Unix(timestamp.(*jsonutils.JSONInt).Value()/1000, 0)
|
||||
fieldValue, err := self.getDataPointValue(valueKey, influxDbSpecs, rtnMetric)
|
||||
if err != nil {
|
||||
return influxdb.SMetricData{}, err
|
||||
}
|
||||
//根据条件拼装metric的tag和metirc信息
|
||||
influxDbSpec := influxDbSpecs[2]
|
||||
measurement := common.SubstringBefore(influxDbSpec, ".")
|
||||
var pairsKey string
|
||||
if strings.Contains(influxDbSpec, ",") {
|
||||
pairsKey = common.SubstringBetween(influxDbSpec, ".", ",")
|
||||
} else {
|
||||
pairsKey = common.SubstringAfter(influxDbSpec, ".")
|
||||
}
|
||||
if influxDbSpecs[1] == common.UNIT_BYTEPS && strings.Contains(pairsKey, common.UNIT_BPS) {
|
||||
fieldValue = fieldValue * 8
|
||||
}
|
||||
tag := common.SubstringAfter(influxDbSpec, ",")
|
||||
if tag != "" && strings.Contains(influxDbSpec, "=") {
|
||||
metric.Tags = append(metric.Tags, influxdb.SKeyValue{
|
||||
Key: common.SubstringBefore(tag, "="),
|
||||
Value: common.SubstringAfter(tag, "="),
|
||||
})
|
||||
}
|
||||
cpu_cout, err := server.Get("vcpu_count")
|
||||
if err == nil {
|
||||
metric.Metrics = append(metric.Metrics, influxdb.SKeyValue{
|
||||
Key: "cpu_count",
|
||||
Value: strconv.FormatInt(cpu_cout.(*jsonutils.JSONInt).Value(), 10),
|
||||
})
|
||||
}
|
||||
metric.Metrics = append(metric.Metrics, influxdb.SKeyValue{
|
||||
Key: pairsKey,
|
||||
Value: strconv.FormatFloat(fieldValue, 'E', -1, 64),
|
||||
})
|
||||
metric.Name = measurement
|
||||
return metric, nil
|
||||
}
|
||||
|
||||
func (self *SAliCloudReport) getDataPointValue(valueKey string, influxDbSpecs []string, rtnMetric jsonutils.JSONObject) (float64, error) {
|
||||
key := common.UNIT_AVERAGE
|
||||
switch common.MonType(self.Operator) {
|
||||
case common.OSS:
|
||||
key = valueKey
|
||||
case common.K8S:
|
||||
key = "Value"
|
||||
}
|
||||
fieldValue, err := rtnMetric.Float(key)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
return fieldValue, nil
|
||||
}
|
||||
|
||||
func (self *SAliCloudReport) getMetricSpecs(res []jsonutils.JSONObject) (string, map[string][]string) {
|
||||
switch common.MonType(self.Operator) {
|
||||
case common.SERVER:
|
||||
return SERVER_METRIC_NAMESPACE, aliMetricSpecs
|
||||
case common.REDIS:
|
||||
return REDIS_METRIC_NAMESPACE, aliRedisMetricSpecs
|
||||
case common.RDS:
|
||||
return RDS_METRIC_NAMESPACE, aliRdsMetricSpecs
|
||||
case common.OSS:
|
||||
return OSS_METRIC_NAMESPACE, aliOSSMetricSpecs
|
||||
case common.ELB:
|
||||
return ELB_METRIC_NAMESPACE, aliElbMetricSpecs
|
||||
case common.K8S:
|
||||
return K8S_METRIC_NAMESPACE, aliK8SClusterMetricSpecs
|
||||
default:
|
||||
return SERVER_METRIC_NAMESPACE, aliMetricSpecs
|
||||
}
|
||||
}
|
||||
|
||||
func (self *SAliCloudReport) getDimensionId() *common.DimensionId {
|
||||
switch common.MonType(self.Operator) {
|
||||
case common.SERVER:
|
||||
return &common.DimensionId{
|
||||
LocalId: "external_id",
|
||||
ExtId: "instanceId",
|
||||
}
|
||||
case common.REDIS:
|
||||
return &common.DimensionId{
|
||||
LocalId: "external_id",
|
||||
ExtId: "instanceId",
|
||||
}
|
||||
case common.RDS:
|
||||
return &common.DimensionId{
|
||||
LocalId: "external_id",
|
||||
ExtId: "instanceId",
|
||||
}
|
||||
case common.OSS:
|
||||
return &common.DimensionId{
|
||||
LocalId: "name",
|
||||
ExtId: "BucketName",
|
||||
}
|
||||
case common.ELB:
|
||||
return &common.DimensionId{
|
||||
LocalId: "external_id",
|
||||
ExtId: "InstanceId",
|
||||
}
|
||||
case common.K8S:
|
||||
return &common.DimensionId{
|
||||
LocalId: "external_cloud_cluster_id",
|
||||
ExtId: "cluster",
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (self *SAliCloudReport) CollectK8sModuleMetric(region cloudprovider.ICloudRegion, cluster jsonutils.JSONObject,
|
||||
helper common.IK8sClusterModuleHelper) error {
|
||||
aliReg := region.(*aliyun.SRegion)
|
||||
since, until, err := common.TimeRangeFromArgs(self.Args)
|
||||
id, _ := cluster.GetString("id")
|
||||
resources, err := common.ListK8sClusterModuleResources(helper.MyModuleType(), id, self.Session, nil)
|
||||
if err != nil {
|
||||
log.Errorf("ListK8sClusterModuleResources err: %v", err)
|
||||
return err
|
||||
}
|
||||
namespace, metricSpecs := helper.MyNamespaceAndMetrics()
|
||||
metricNames := make([]string, 0)
|
||||
for metricName := range metricSpecs {
|
||||
metricNames = append(metricNames, metricName)
|
||||
}
|
||||
dimensionId := helper.MyResDimensionId()
|
||||
dataList := make([]influxdb.SMetricData, 0)
|
||||
dataCnt := 0
|
||||
for metricName, influxDbSpecs := range metricSpecs {
|
||||
rtnArray, _, err := aliReg.DescribeMetricList(metricName, namespace, since, until, "", nil)
|
||||
if err != nil {
|
||||
log.Errorln(err)
|
||||
continue
|
||||
}
|
||||
dataCnt = len(dataList)
|
||||
if len(rtnArray) > 0 {
|
||||
for _, rtnMetric := range rtnArray {
|
||||
for _, resource := range resources {
|
||||
external_id, _ := resource.GetString(dimensionId.LocalId)
|
||||
if instanceId, _ := rtnMetric.GetString(dimensionId.ExtId); instanceId == external_id {
|
||||
serverMetric, err := self.collectMetricFromThisServer(resource, rtnMetric, influxDbSpecs, metricName)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
dataList = append(dataList, serverMetric)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
log.Debugf("%s %s %s report %d metric", self.SProvider.Name, self.Operator, metricName, len(dataList)-dataCnt)
|
||||
}
|
||||
err = common.SendMetrics(self.Session, dataList, self.Args.Debug, "")
|
||||
if err != nil {
|
||||
log.Errorf("K8s metricName: %s SendMetrics err: %#v", "", err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (self *SAliCloudReport) getK8sModuleDimensions(helper common.IK8sClusterModuleHelper, module jsonutils.JSONObject,
|
||||
clusterId string) []aliyun.SResourceLabel {
|
||||
dimensions := make([]aliyun.SResourceLabel, 0)
|
||||
dimensionId := helper.MyResDimensionId()
|
||||
|
||||
localIds := strings.Split(dimensionId.LocalId, ",")
|
||||
extIds := strings.Split(dimensionId.ExtId, ",")
|
||||
if len(localIds) != len(extIds) {
|
||||
return dimensions
|
||||
}
|
||||
for index, localId := range localIds {
|
||||
localIdKey := strings.Split(localId, ".")
|
||||
val, _ := module.GetString(localIdKey...)
|
||||
dimensions = append(dimensions, aliyun.SResourceLabel{
|
||||
Name: extIds[index],
|
||||
Value: val,
|
||||
})
|
||||
|
||||
}
|
||||
return dimensions
|
||||
}
|
||||
@@ -1,86 +0,0 @@
|
||||
// Copyright 2019 Yunion
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package apsaramon
|
||||
|
||||
import (
|
||||
"yunion.io/x/jsonutils"
|
||||
|
||||
"yunion.io/x/onecloud/pkg/apis/compute"
|
||||
"yunion.io/x/onecloud/pkg/cloudmon/collectors/common"
|
||||
"yunion.io/x/onecloud/pkg/cloudmon/options"
|
||||
"yunion.io/x/onecloud/pkg/mcclient"
|
||||
)
|
||||
|
||||
func init() {
|
||||
factory := SApsaraCloudReportFactory{}
|
||||
common.RegisterFactory(&factory)
|
||||
}
|
||||
|
||||
type SApsaraCloudReportFactory struct {
|
||||
common.CommonReportFactory
|
||||
}
|
||||
|
||||
func (self *SApsaraCloudReportFactory) NewCloudReport(provider *common.SProvider, session *mcclient.ClientSession,
|
||||
args *options.ReportOptions, operatorType string) common.ICloudReport {
|
||||
return &SApsaraCloudReport{
|
||||
common.CloudReportBase{
|
||||
SProvider: provider,
|
||||
Session: session,
|
||||
Args: args,
|
||||
Operator: operatorType,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func (self *SApsaraCloudReportFactory) GetId() string {
|
||||
return compute.CLOUD_PROVIDER_APSARA
|
||||
}
|
||||
|
||||
type SApsaraCloudReport struct {
|
||||
common.CloudReportBase
|
||||
}
|
||||
|
||||
func (self *SApsaraCloudReport) Report() error {
|
||||
var servers []jsonutils.JSONObject
|
||||
var err error
|
||||
servers, err = self.GetResourceByOperator()
|
||||
providerInstance, err := self.InitProviderInstance()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
regionList, regionServerMap, err := self.GetAllRegionOfServers(servers, providerInstance)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
for _, region := range regionList {
|
||||
servers := regionServerMap[region.GetGlobalId()]
|
||||
switch self.Operator {
|
||||
case "server":
|
||||
err = self.collectRegionMetricOfHost(region, servers)
|
||||
case "redis":
|
||||
err = self.collectRegionMetricOfRedis(region, servers)
|
||||
case "rds":
|
||||
err = self.collectRegionMetricOfRds(region, servers)
|
||||
case "oss":
|
||||
err = self.collectRegionMetricOfOss(region, servers)
|
||||
case "elb":
|
||||
err = self.collectRegionMetricOfElb(region, servers)
|
||||
}
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
@@ -1,373 +0,0 @@
|
||||
// Copyright 2019 Yunion
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package apsaramon
|
||||
|
||||
import (
|
||||
"strconv"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"yunion.io/x/jsonutils"
|
||||
"yunion.io/x/log"
|
||||
"yunion.io/x/pkg/errors"
|
||||
|
||||
api "yunion.io/x/onecloud/pkg/apis/compute"
|
||||
"yunion.io/x/onecloud/pkg/cloudmon/collectors/common"
|
||||
"yunion.io/x/onecloud/pkg/cloudprovider"
|
||||
iden_modules "yunion.io/x/onecloud/pkg/mcclient/modules/identity"
|
||||
"yunion.io/x/onecloud/pkg/multicloud/apsara"
|
||||
"yunion.io/x/onecloud/pkg/util/influxdb"
|
||||
)
|
||||
|
||||
type SApsaraMetric struct {
|
||||
Timestamp int64
|
||||
UserId string
|
||||
InstanceId string
|
||||
Maximum float64
|
||||
Minimum float64
|
||||
Average float64
|
||||
NodeId string
|
||||
}
|
||||
|
||||
func (self *SApsaraCloudReport) collectRegionMetricOfHost(region cloudprovider.ICloudRegion, servers []jsonutils.JSONObject) error {
|
||||
dataList := make([]influxdb.SMetricData, 0)
|
||||
aliReg := region.(*apsara.SRegion)
|
||||
since, until, err := common.TimeRangeFromArgs(self.Args)
|
||||
if err != nil {
|
||||
return errors.Wrapf(err, "common.TimeRangeFromArgs")
|
||||
}
|
||||
|
||||
instances := []api.ServerDetails{}
|
||||
instanceMaps := map[string]api.ServerDetails{}
|
||||
jsonutils.Update(&instances, servers)
|
||||
for i := range instances {
|
||||
if len(instances[i].ExternalId) == 0 {
|
||||
continue
|
||||
}
|
||||
instanceMaps[instances[i].ExternalId] = instances[i]
|
||||
metric, err := common.FillVMCapacity(jsonutils.Marshal(instances[i]).(*jsonutils.JSONDict))
|
||||
if err != nil {
|
||||
return errors.Wrapf(err, "common.FillVMCapacity")
|
||||
}
|
||||
dataList = append(dataList, metric)
|
||||
}
|
||||
|
||||
err = common.SendMetrics(self.Session, dataList, self.Args.Debug, "")
|
||||
if err != nil {
|
||||
log.Errorf("send server base metric error: %v", err)
|
||||
}
|
||||
|
||||
var wg sync.WaitGroup
|
||||
wg.Add(len(apsaraMetricSpecs))
|
||||
for _metricName, _influxDbSpecs := range apsaraMetricSpecs {
|
||||
go func(metricName string, influxDbSpecs []string) {
|
||||
defer wg.Done()
|
||||
dataList = []influxdb.SMetricData{}
|
||||
metricArray, err := aliReg.FetchMetricData(metricName, "acs_ecs_dashboard", since, until)
|
||||
if err != nil {
|
||||
log.Errorln(err)
|
||||
return
|
||||
}
|
||||
|
||||
metrics := []SApsaraMetric{}
|
||||
jsonutils.Update(&metrics, metricArray)
|
||||
|
||||
for _, rtnMetric := range metrics {
|
||||
server, ok := instanceMaps[rtnMetric.InstanceId]
|
||||
if ok {
|
||||
serverMetric, err := self.collectMetricFromThisServer(jsonutils.Marshal(server), rtnMetric, influxDbSpecs)
|
||||
if err != nil {
|
||||
log.Errorf("collect %s error: %v", metricName, err)
|
||||
continue
|
||||
}
|
||||
|
||||
project, err := self.GetResourceById(server.ProjectId, &iden_modules.Projects)
|
||||
if err != nil {
|
||||
log.Errorf("server: %s getProject: %s err: %v", server.Name, server.ProjectId, err)
|
||||
continue
|
||||
}
|
||||
metaMap, _ := project.GetMap("metadata")
|
||||
if len(metaMap) > 0 {
|
||||
for key, valObj := range metaMap {
|
||||
if strings.Contains(key, "user:") {
|
||||
val, _ := valObj.GetString()
|
||||
serverMetric.Tags = append(serverMetric.Tags, influxdb.SKeyValue{
|
||||
Key: key,
|
||||
Value: val,
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
dataList = append(dataList, serverMetric)
|
||||
}
|
||||
}
|
||||
log.Infof("SendMetrics %s length: %d", metricName, len(dataList))
|
||||
err = common.SendMetrics(self.Session, dataList, self.Args.Debug, "")
|
||||
if err != nil {
|
||||
log.Errorf("SendMetrics %s length: %d error: %v", metricName, len(dataList), err)
|
||||
}
|
||||
|
||||
}(_metricName, _influxDbSpecs)
|
||||
}
|
||||
wg.Wait()
|
||||
return nil
|
||||
}
|
||||
|
||||
func (self *SApsaraCloudReport) collectRegionMetricOfRedis(region cloudprovider.ICloudRegion,
|
||||
servers []jsonutils.JSONObject) error {
|
||||
dataList := make([]influxdb.SMetricData, 0)
|
||||
aliReg := region.(*apsara.SRegion)
|
||||
since, until, err := common.TimeRangeFromArgs(self.Args)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
redisDeployType := make(map[string]string)
|
||||
for _, server := range servers {
|
||||
local_category, err := server.GetString("local_category")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
switch local_category {
|
||||
case "single":
|
||||
redisDeployType["single"] = "Standard"
|
||||
case "master":
|
||||
redisDeployType["master"] = "Standard"
|
||||
case "cluster":
|
||||
redisDeployType["cluster"] = "Sharding"
|
||||
case "rwsplit":
|
||||
redisDeployType["rwsplit"] = "Splitrw"
|
||||
}
|
||||
|
||||
}
|
||||
for metricName, influxDbSpecs := range aliRedisMetricSpecs {
|
||||
for _, pre := range redisDeployType {
|
||||
rtnArray, err := aliReg.FetchMetricData(pre+metricName, "acs_kvstore", since, until)
|
||||
if err != nil {
|
||||
log.Errorln(err)
|
||||
continue
|
||||
}
|
||||
|
||||
metrics := []SApsaraMetric{}
|
||||
jsonutils.Update(&metrics, rtnArray)
|
||||
|
||||
for _, rtnMetric := range metrics {
|
||||
for _, server := range servers {
|
||||
external_id, _ := server.GetString("external_id")
|
||||
if rtnMetric.InstanceId == external_id {
|
||||
serverMetric, err := self.collectMetricFromThisServer(server, rtnMetric, influxDbSpecs)
|
||||
serverMetric.Tags = append(serverMetric.Tags, influxdb.SKeyValue{Key: "node_id", Value: rtnMetric.NodeId})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
dataList = append(dataList, serverMetric)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return common.SendMetrics(self.Session, dataList, self.Args.Debug, "")
|
||||
}
|
||||
|
||||
func (self *SApsaraCloudReport) collectRegionMetricOfRds(region cloudprovider.ICloudRegion, servers []jsonutils.JSONObject) error {
|
||||
dataList := make([]influxdb.SMetricData, 0)
|
||||
aliReg := region.(*apsara.SRegion)
|
||||
since, until, err := common.TimeRangeFromArgs(self.Args)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
for metricName, influxDbSpecs := range aliRdsMetricSpecs {
|
||||
rtnArray, err := aliReg.FetchMetricData(metricName, "acs_rds_dashboard", since, until)
|
||||
if err != nil {
|
||||
log.Errorln(err)
|
||||
continue
|
||||
}
|
||||
metrics := []SApsaraMetric{}
|
||||
jsonutils.Update(&metrics, rtnArray)
|
||||
|
||||
for _, rtnMetric := range metrics {
|
||||
for _, server := range servers {
|
||||
external_id, _ := server.GetString("external_id")
|
||||
if rtnMetric.InstanceId == external_id {
|
||||
metric, err := common.FillVMCapacity(server.(*jsonutils.JSONDict))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
dataList = append(dataList, metric)
|
||||
serverMetric, err := self.collectMetricFromThisServer(server, rtnMetric, influxDbSpecs)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
dataList = append(dataList, serverMetric)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return common.SendMetrics(self.Session, dataList, self.Args.Debug, "")
|
||||
}
|
||||
|
||||
func (self *SApsaraCloudReport) collectRegionMetricOfOss(region cloudprovider.ICloudRegion, servers []jsonutils.JSONObject) error {
|
||||
dataList := make([]influxdb.SMetricData, 0)
|
||||
aliReg := region.(*apsara.SRegion)
|
||||
since, until, err := common.TimeRangeFromArgs(self.Args)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
for metricName, influxDbSpecs := range aliOSSMetricSpecs {
|
||||
rtnArray, err := aliReg.FetchMetricData(metricName, "acs_oss", since, until)
|
||||
if err != nil {
|
||||
log.Errorln(err)
|
||||
continue
|
||||
}
|
||||
if len(rtnArray) > 0 {
|
||||
for _, rtnMetric := range rtnArray {
|
||||
for _, server := range servers {
|
||||
name, _ := server.GetString("name")
|
||||
if bucketName, _ := rtnMetric.GetString("BucketName"); bucketName == name {
|
||||
serverMetric, err := self.collectOssMetricFromThisServer(server, rtnMetric, metricName,
|
||||
influxDbSpecs)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
dataList = append(dataList, serverMetric)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return common.SendMetrics(self.Session, dataList, self.Args.Debug, "")
|
||||
}
|
||||
|
||||
func (self *SApsaraCloudReport) collectRegionMetricOfElb(region cloudprovider.ICloudRegion, servers []jsonutils.JSONObject) error {
|
||||
dataList := make([]influxdb.SMetricData, 0)
|
||||
aliReg := region.(*apsara.SRegion)
|
||||
since, until, err := common.TimeRangeFromArgs(self.Args)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
for metricName, influxDbSpecs := range aliElbMetricSpecs {
|
||||
rtnArray, err := aliReg.FetchMetricData(metricName, "acs_slb_dashboard", since, until)
|
||||
if err != nil {
|
||||
log.Errorln(err)
|
||||
continue
|
||||
}
|
||||
|
||||
metrics := []SApsaraMetric{}
|
||||
jsonutils.Update(&metrics, rtnArray)
|
||||
|
||||
for _, rtnMetric := range metrics {
|
||||
for _, server := range servers {
|
||||
external_id, _ := server.GetString("external_id")
|
||||
if rtnMetric.InstanceId == external_id {
|
||||
serverMetric, err := self.collectMetricFromThisServer(server, rtnMetric, influxDbSpecs)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
dataList = append(dataList, serverMetric)
|
||||
}
|
||||
}
|
||||
}
|
||||
log.Infof("SendMetrics %s length: %d", metricName, len(dataList))
|
||||
}
|
||||
return common.SendMetrics(self.Session, dataList, self.Args.Debug, "")
|
||||
}
|
||||
|
||||
func (self *SApsaraCloudReport) collectMetricFromThisServer(server jsonutils.JSONObject, rtnMetric SApsaraMetric, influxDbSpecs []string) (influxdb.SMetricData, error) {
|
||||
metric, err := self.NewMetricFromJson(server)
|
||||
if err != nil {
|
||||
return influxdb.SMetricData{}, err
|
||||
}
|
||||
metric.Timestamp = time.Unix(rtnMetric.Timestamp/1000, 0)
|
||||
fieldValue := rtnMetric.Average
|
||||
//根据条件拼装metric的tag和metirc信息
|
||||
influxDbSpec := influxDbSpecs[2]
|
||||
measurement := common.SubstringBefore(influxDbSpec, ".")
|
||||
var pairsKey string
|
||||
if strings.Contains(influxDbSpec, ",") {
|
||||
pairsKey = common.SubstringBetween(influxDbSpec, ".", ",")
|
||||
} else {
|
||||
pairsKey = common.SubstringAfter(influxDbSpec, ".")
|
||||
}
|
||||
if influxDbSpecs[1] == UNIT_BYTEPS && strings.Contains(pairsKey, UNIT_BPS) {
|
||||
fieldValue = fieldValue * 8
|
||||
}
|
||||
tag := common.SubstringAfter(influxDbSpec, ",")
|
||||
if tag != "" && strings.Contains(influxDbSpec, "=") {
|
||||
metric.Tags = append(metric.Tags, influxdb.SKeyValue{
|
||||
Key: common.SubstringBefore(tag, "="),
|
||||
Value: common.SubstringAfter(tag, "="),
|
||||
})
|
||||
}
|
||||
cpu_cout, err := server.Get("vcpu_count")
|
||||
if err == nil {
|
||||
metric.Metrics = append(metric.Metrics, influxdb.SKeyValue{
|
||||
Key: "cpu_count",
|
||||
Value: strconv.FormatInt(cpu_cout.(*jsonutils.JSONInt).Value(), 10),
|
||||
})
|
||||
}
|
||||
metric.Metrics = append(metric.Metrics, influxdb.SKeyValue{
|
||||
Key: pairsKey,
|
||||
Value: strconv.FormatFloat(fieldValue, 'E', -1, 64),
|
||||
})
|
||||
metric.Name = measurement
|
||||
return metric, nil
|
||||
}
|
||||
|
||||
func (self *SApsaraCloudReport) collectOssMetricFromThisServer(server jsonutils.JSONObject, rtnMetric jsonutils.JSONObject,
|
||||
metricName string, influxDbSpecs []string) (influxdb.SMetricData, error) {
|
||||
metric, err := self.NewMetricFromJson(server)
|
||||
//metric, err := common.JsonToMetric(server.(*jsonutils.JSONDict), "", common.ServerTags, make([]string, 0))
|
||||
if err != nil {
|
||||
return influxdb.SMetricData{}, err
|
||||
}
|
||||
timestamp, _ := rtnMetric.Get("timestamp")
|
||||
metric.Timestamp = time.Unix(timestamp.(*jsonutils.JSONInt).Value()/1000, 0)
|
||||
fieldValue, err := rtnMetric.Float(metricName)
|
||||
if err != nil {
|
||||
return influxdb.SMetricData{}, err
|
||||
}
|
||||
//根据条件拼装metric的tag和metirc信息
|
||||
influxDbSpec := influxDbSpecs[2]
|
||||
measurement := common.SubstringBefore(influxDbSpec, ".")
|
||||
var pairsKey string
|
||||
if strings.Contains(influxDbSpec, ",") {
|
||||
pairsKey = common.SubstringBetween(influxDbSpec, ".", ",")
|
||||
} else {
|
||||
pairsKey = common.SubstringAfter(influxDbSpec, ".")
|
||||
}
|
||||
if influxDbSpecs[1] == UNIT_BYTEPS && strings.Contains(pairsKey, UNIT_BPS) {
|
||||
fieldValue = fieldValue * 8
|
||||
}
|
||||
tag := common.SubstringAfter(influxDbSpec, ",")
|
||||
if tag != "" && strings.Contains(influxDbSpec, "=") {
|
||||
metric.Tags = append(metric.Tags, influxdb.SKeyValue{
|
||||
Key: common.SubstringBefore(tag, "="),
|
||||
Value: common.SubstringAfter(tag, "="),
|
||||
})
|
||||
}
|
||||
cpu_cout, err := server.Get("vcpu_count")
|
||||
if err == nil {
|
||||
metric.Metrics = append(metric.Metrics, influxdb.SKeyValue{
|
||||
Key: "cpu_count",
|
||||
Value: strconv.FormatInt(cpu_cout.(*jsonutils.JSONInt).Value(), 10),
|
||||
})
|
||||
}
|
||||
metric.Metrics = append(metric.Metrics, influxdb.SKeyValue{
|
||||
Key: pairsKey,
|
||||
Value: strconv.FormatFloat(fieldValue, 'E', -1, 64),
|
||||
})
|
||||
metric.Name = measurement
|
||||
return metric, nil
|
||||
}
|
||||
@@ -1,190 +0,0 @@
|
||||
// Copyright 2019 Yunion
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package apsaramon
|
||||
|
||||
import "yunion.io/x/onecloud/pkg/cloudmon/collectors/common"
|
||||
|
||||
const (
|
||||
PERIOD = 60
|
||||
UNIT_AVERAGE = "Average"
|
||||
DEFAULT_STATISTICS = "Average,Minimum,Maximum"
|
||||
UNIT_PERCENT = "Percent"
|
||||
UNIT_BPS = "bps"
|
||||
UNIT_MBPS = "Mbps"
|
||||
UNIT_BYTEPS = "Bps"
|
||||
UNIT_CPS = "cps"
|
||||
UNIT_COUNT = "count"
|
||||
UNIT_MEM = "byte"
|
||||
UNIT_MSEC = "ms"
|
||||
UNIT_COUNT_SEC = "count/s"
|
||||
|
||||
//ESC监控指标
|
||||
INFLUXDB_FIELD_CPU_USAGE = "vm_cpu.usage_active"
|
||||
INFLUXDB_FIELD_MEM_USAGE = "vm_mem.used_percent"
|
||||
INFLUXDB_FIELD_DISK_READ_BPS = "vm_diskio.read_bps"
|
||||
INFLUXDB_FIELD_DISK_WRITE_BPS = "vm_diskio.write_bps"
|
||||
INFLUXDB_FIELD_DISK_READ_IOPS = "vm_diskio.read_iops"
|
||||
INFLUXDB_FIELD_DISK_WRITE_IOPS = "vm_diskio.write_iops"
|
||||
INFLUXDB_FIELD_NET_BPS_RX = "vm_netio.bps_recv"
|
||||
INFLUXDB_FIELD_NET_BPS_RX_INTERNET = INFLUXDB_FIELD_NET_BPS_RX + ",net_type=internet"
|
||||
INFLUXDB_FIELD_NET_BPS_RX_INTRANET = INFLUXDB_FIELD_NET_BPS_RX + ",net_type=intranet"
|
||||
INFLUXDB_FIELD_NET_BPS_TX = "vm_netio.bps_sent"
|
||||
INFLUXDB_FIELD_NET_BPS_TX_INTERNET = INFLUXDB_FIELD_NET_BPS_TX + ",net_type=internet"
|
||||
INFLUXDB_FIELD_NET_BPS_TX_INTRANET = INFLUXDB_FIELD_NET_BPS_TX + ",net_type=intranet"
|
||||
INFLUXDB_FIELD_WANOUTTRAFFIC = "vm_eipio.bps_out"
|
||||
INFLUXDB_FIELD_WANINTRAFFIC = "vm_eipio.bps_in"
|
||||
INFLUXDB_FIELD_WANOUTPKG = "vm_eipio.pps_out"
|
||||
INFLUXDB_FIELD_WANINPKG = "vm_eipio.pps_in"
|
||||
|
||||
//RDS监控指标
|
||||
INFLUXDB_FIELD_RDS_CPU_USAGE = "rds_cpu.usage_active"
|
||||
INFLUXDB_FIELD_RDS_MEM_USAGE = "rds_mem.used_percent"
|
||||
INFLUXDB_FIELD_RDS_NET_BPS_RX = "rds_netio.bps_recv"
|
||||
INFLUXDB_FIELD_RDS_NET_BPS_RX_MYSQL = INFLUXDB_FIELD_RDS_NET_BPS_RX + ",server_type=mysql"
|
||||
INFLUXDB_FIELD_RDS_NET_BPS_RX_SQLSERVER = INFLUXDB_FIELD_RDS_NET_BPS_RX + ",server_type=sqlserver"
|
||||
INFLUXDB_FIELD_RDS_NET_BPS_TX = "rds_netio.bps_sent"
|
||||
INFLUXDB_FIELD_RDS_NET_BPS_TX_MYSQL = INFLUXDB_FIELD_RDS_NET_BPS_TX + ",server_type=mysql"
|
||||
INFLUXDB_FIELD_RDS_NET_BPS_TX_SQLSERVER = INFLUXDB_FIELD_RDS_NET_BPS_TX + ",server_type=sqlserver"
|
||||
INFLUXDB_FIELD_RDS_DISK_USAGE = "rds_disk.used_percent"
|
||||
INFLUXDB_FIELD_RDS_DISK_READ_BPS = "rds_diskio.read_bps"
|
||||
INFLUXDB_FIELD_RDS_DISK_WRITE_BPS = "rds_diskio.write_bps"
|
||||
INFLUXDB_FIELD_RDS_CONN_COUNT = "rds_conn.used_count"
|
||||
INFLUXDB_FIELD_RDS_CONN_USAGE = "rds_conn.used_percent"
|
||||
|
||||
INFLUXDB_FIELD_RDS_QPS = "rds_qps.query_qps"
|
||||
INFLUXDB_FIELD_RDS_TPS = "rds_tps.trans_qps"
|
||||
INFLUXDB_FIELD_RDS_INNODB_REDA_BPS = "rds_innodb.read_bps"
|
||||
INFLUXDB_FIELD_RDS_INNODB_WRITE_BPS = "rds_innodb.write_bps"
|
||||
|
||||
//REDIS监控指标
|
||||
INFLUXDB_FIELD_REDIS_CPU_USAGE = "dcs_cpu.usage_percent"
|
||||
INFLUXDB_FIELD_REDIS_MEM_USAGE = "dcs_mem.used_percent"
|
||||
INFLUXDB_FIELD_REDIS_NET_BPS_RX = "dcs_netio.bps_recv"
|
||||
INFLUXDB_FIELD_REDIS_NET_BPS_TX = "dcs_netio.bps_sent"
|
||||
INFLUXDB_FIFLD_REDIS_CONN_USAGE = "dcs_conn.used_conn"
|
||||
INFLUXDB_FIFLD_REDIS_OPT_SES = "dcs_instantopt.opt_sec"
|
||||
INFLUXDB_FIFLD_REDIS_CACHE_KEYS = "dcs_cachekeys.key_count"
|
||||
INFLUXDB_FIFLD_REDIS_CACHE_EXP_KEYS = INFLUXDB_FIFLD_REDIS_CACHE_KEYS + ",exp=expire"
|
||||
INFLUXDB_FIFLD_REDIS_DATA_MEM_USAGE = "dcs_datamem.used_byte"
|
||||
|
||||
//对象存储OSS监控指标
|
||||
INFLUXDB_FIELD_OSS_NET_BPS_RX = "oss_netio.bps_recv"
|
||||
INFLUXDB_FIELD_OSS_NET_BPS_RX_INTERNET = INFLUXDB_FIELD_OSS_NET_BPS_RX + ",net_type=internet"
|
||||
INFLUXDB_FIELD_OSS_NET_BPS_RX_INTRANET = INFLUXDB_FIELD_OSS_NET_BPS_RX + ",net_type=intranet"
|
||||
INFLUXDB_FIELD_OSS_NET_BPS_TX = "oss_netio.bps_sent"
|
||||
INFLUXDB_FIELD_OSS_NET_BPS_TX_INTERNET = INFLUXDB_FIELD_OSS_NET_BPS_TX + ",net_type=internet"
|
||||
INFLUXDB_FIELD_OSS_NET_BPS_TX_INTRANET = INFLUXDB_FIELD_OSS_NET_BPS_TX + ",net_type=intranet"
|
||||
INFLUXDB_FIELD_OSS_LATECY = "oss_latency.req_late"
|
||||
INFLUXDB_FIELD_OSS_LATECY_GET = INFLUXDB_FIELD_OSS_LATECY + ",request=get"
|
||||
INFLUXDB_FIELD_OSS_LATECY_POST = INFLUXDB_FIELD_OSS_LATECY + ",request=post"
|
||||
INFLUXDB_FIELD_OSS_REQ_COUNT = "oss_req.req_count"
|
||||
INFLUXDB_FIELD_OSS_REQ_COUNT_GET = INFLUXDB_FIELD_OSS_REQ_COUNT + ",request=get"
|
||||
INFLUXDB_FIELD_OSS_REQ_COUNT_POST = INFLUXDB_FIELD_OSS_REQ_COUNT + ",request=post"
|
||||
INFLUXDB_FIELD_OSS_REQ_COUNT_5XX = INFLUXDB_FIELD_OSS_REQ_COUNT + ",request=5xx"
|
||||
INFLUXDB_FIELD_OSS_REQ_COUNT_4XX = INFLUXDB_FIELD_OSS_REQ_COUNT + ",request=4xx"
|
||||
|
||||
//负载均衡监控指标
|
||||
INFLUXDB_FIELD_ELB_NET_BPS_RX = "haproxy.bin"
|
||||
INFLUXDB_FIELD_ELB_NET_BPS_TX = "haproxy.bout"
|
||||
INFLUXDB_FIELD_ELB_REQ_RATE = "haproxy.req_rate,request=http"
|
||||
INFLUXDB_FIELD_ELB_CONN_RATE = "haproxy.conn_rate,request=tcp"
|
||||
INFLUXDB_FIELD_ELB_DREQ_COUNT = "haproxy.dreq,request=http"
|
||||
INFLUXDB_FIELD_ELB_DCONN_COUNT = "haproxy.dcon,request=tcp"
|
||||
INFLUXDB_FIELD_ELB_HRSP_COUNT = "haproxy.hrsp_Nxx"
|
||||
INFLUXDB_FIELD_ELB_HRSP_COUNT_2XX = INFLUXDB_FIELD_ELB_HRSP_COUNT + ",request=2xx"
|
||||
INFLUXDB_FIELD_ELB_HRSP_COUNT_3XX = INFLUXDB_FIELD_ELB_HRSP_COUNT + ",request=3xx"
|
||||
INFLUXDB_FIELD_ELB_HRSP_COUNT_4XX = INFLUXDB_FIELD_ELB_HRSP_COUNT + ",request=4xx"
|
||||
INFLUXDB_FIELD_ELB_HRSP_COUNT_5XX = INFLUXDB_FIELD_ELB_HRSP_COUNT + ",request=5xx"
|
||||
INFLUXDB_FIELD_ELB_CHC_STATUS = "haproxy.check_status"
|
||||
INFLUXDB_FIELD_ELB_CHC_CODE = "haproxy.check_code"
|
||||
INFLUXDB_FIELD_ELB_LAST_CHC = "haproxy.last_chk"
|
||||
|
||||
KEY_VMS = "vms"
|
||||
KEY_CPUS = "cpus"
|
||||
KEY_MEMS = "mems"
|
||||
KEY_DISKS = "disks"
|
||||
|
||||
KEY_LIMIT = "limit"
|
||||
KEY_ADMIN = "admin"
|
||||
KEY_USABLE = "usable"
|
||||
)
|
||||
|
||||
//multiCloud查询指标列表组装
|
||||
var aliMetricSpecs = map[string][]string{
|
||||
"CPUUtilization": {DEFAULT_STATISTICS, UNIT_PERCENT, INFLUXDB_FIELD_CPU_USAGE},
|
||||
"InternetInRate": {DEFAULT_STATISTICS, UNIT_BPS, INFLUXDB_FIELD_NET_BPS_RX_INTERNET},
|
||||
"IntranetInRate": {DEFAULT_STATISTICS, UNIT_BPS, INFLUXDB_FIELD_NET_BPS_RX_INTRANET},
|
||||
"InternetOutRate": {DEFAULT_STATISTICS, UNIT_BPS, INFLUXDB_FIELD_NET_BPS_TX_INTERNET},
|
||||
"IntranetOutRate": {DEFAULT_STATISTICS, UNIT_BPS, INFLUXDB_FIELD_NET_BPS_TX_INTRANET},
|
||||
"DiskReadBPS": {DEFAULT_STATISTICS, UNIT_BYTEPS, INFLUXDB_FIELD_DISK_READ_BPS},
|
||||
"DiskWriteBPS": {DEFAULT_STATISTICS, UNIT_BYTEPS, INFLUXDB_FIELD_DISK_WRITE_BPS},
|
||||
"DiskReadIOPS": {DEFAULT_STATISTICS, UNIT_CPS, INFLUXDB_FIELD_DISK_READ_IOPS},
|
||||
"DiskWriteIOPS": {DEFAULT_STATISTICS, UNIT_CPS, INFLUXDB_FIELD_DISK_WRITE_IOPS},
|
||||
}
|
||||
var apsaraMetricSpecs = map[string][]string{
|
||||
"vm.MemoryUtilization": {DEFAULT_STATISTICS, UNIT_PERCENT, INFLUXDB_FIELD_MEM_USAGE},
|
||||
"vm.CPUUtilization": {DEFAULT_STATISTICS, UNIT_PERCENT, INFLUXDB_FIELD_CPU_USAGE},
|
||||
"diskusage_utilization": {DEFAULT_STATISTICS, UNIT_PERCENT, common.INFLUXDB_FIELD_DISK_USAGE},
|
||||
"InternetInRate": {DEFAULT_STATISTICS, UNIT_BPS, INFLUXDB_FIELD_NET_BPS_RX_INTERNET},
|
||||
"IntranetInRate": {DEFAULT_STATISTICS, UNIT_BPS, INFLUXDB_FIELD_NET_BPS_RX_INTRANET},
|
||||
"InternetOutRate": {DEFAULT_STATISTICS, UNIT_BPS, INFLUXDB_FIELD_NET_BPS_TX_INTERNET},
|
||||
"IntranetOutRate": {DEFAULT_STATISTICS, UNIT_BPS, INFLUXDB_FIELD_NET_BPS_TX_INTRANET},
|
||||
"DiskReadBPS": {DEFAULT_STATISTICS, UNIT_BYTEPS, INFLUXDB_FIELD_DISK_READ_BPS},
|
||||
"DiskWriteBPS": {DEFAULT_STATISTICS, UNIT_BYTEPS, INFLUXDB_FIELD_DISK_WRITE_BPS},
|
||||
"DiskReadIOPS": {DEFAULT_STATISTICS, UNIT_CPS, INFLUXDB_FIELD_DISK_READ_IOPS},
|
||||
"DiskWriteIOPS": {DEFAULT_STATISTICS, UNIT_CPS, INFLUXDB_FIELD_DISK_WRITE_IOPS},
|
||||
}
|
||||
var aliRdsMetricSpecs = map[string][]string{
|
||||
"CpuUsage": {DEFAULT_STATISTICS, UNIT_PERCENT, INFLUXDB_FIELD_RDS_CPU_USAGE},
|
||||
"MemoryUsage": {DEFAULT_STATISTICS, UNIT_PERCENT, INFLUXDB_FIELD_RDS_MEM_USAGE},
|
||||
"MySQL_NetworkInNew": {DEFAULT_STATISTICS, UNIT_BPS, INFLUXDB_FIELD_RDS_NET_BPS_RX_MYSQL},
|
||||
"MySQL_NetworkOutNew": {DEFAULT_STATISTICS, UNIT_BPS, INFLUXDB_FIELD_RDS_NET_BPS_TX_MYSQL},
|
||||
"DiskUsage": {DEFAULT_STATISTICS, UNIT_PERCENT, INFLUXDB_FIELD_RDS_DISK_USAGE},
|
||||
"SQLServer_NetworkInNew": {DEFAULT_STATISTICS, UNIT_BPS, INFLUXDB_FIELD_RDS_NET_BPS_RX_SQLSERVER},
|
||||
"SQLServer_NetworkOutNew": {DEFAULT_STATISTICS, UNIT_BPS, INFLUXDB_FIELD_RDS_NET_BPS_TX_SQLSERVER},
|
||||
"ConnectionUsage": {DEFAULT_STATISTICS, UNIT_PERCENT, INFLUXDB_FIELD_RDS_CONN_USAGE},
|
||||
}
|
||||
var aliRedisMetricSpecs = map[string][]string{
|
||||
"CpuUsage": {DEFAULT_STATISTICS, UNIT_PERCENT, INFLUXDB_FIELD_REDIS_CPU_USAGE},
|
||||
"MemoryUsage": {DEFAULT_STATISTICS, UNIT_PERCENT, INFLUXDB_FIELD_REDIS_MEM_USAGE},
|
||||
"IntranetIn": {DEFAULT_STATISTICS, UNIT_BPS, INFLUXDB_FIELD_REDIS_NET_BPS_RX},
|
||||
"IntranetOut": {DEFAULT_STATISTICS, UNIT_BPS, INFLUXDB_FIELD_REDIS_NET_BPS_TX},
|
||||
"UsedConnection": {DEFAULT_STATISTICS, UNIT_COUNT, INFLUXDB_FIFLD_REDIS_CONN_USAGE},
|
||||
"UsedQPS": {DEFAULT_STATISTICS, UNIT_COUNT, INFLUXDB_FIFLD_REDIS_OPT_SES},
|
||||
"Keys": {DEFAULT_STATISTICS, UNIT_COUNT, INFLUXDB_FIFLD_REDIS_CACHE_KEYS},
|
||||
"ExpiredKeys": {DEFAULT_STATISTICS, UNIT_COUNT, INFLUXDB_FIFLD_REDIS_CACHE_EXP_KEYS},
|
||||
"UsedMemory": {DEFAULT_STATISTICS, UNIT_MEM, INFLUXDB_FIFLD_REDIS_DATA_MEM_USAGE},
|
||||
}
|
||||
var aliOSSMetricSpecs = map[string][]string{
|
||||
"InternetSend": {DEFAULT_STATISTICS, UNIT_MEM, INFLUXDB_FIELD_OSS_NET_BPS_TX_INTERNET},
|
||||
"InternetRecv": {DEFAULT_STATISTICS, UNIT_MEM, INFLUXDB_FIELD_OSS_NET_BPS_RX_INTERNET},
|
||||
"IntranetSend": {DEFAULT_STATISTICS, UNIT_MEM, INFLUXDB_FIELD_OSS_NET_BPS_TX_INTRANET},
|
||||
"IntranetRecv": {DEFAULT_STATISTICS, UNIT_MEM, INFLUXDB_FIELD_OSS_NET_BPS_RX_INTRANET},
|
||||
"GetObjectE2eLatency": {DEFAULT_STATISTICS, UNIT_MSEC, INFLUXDB_FIELD_OSS_LATECY_GET},
|
||||
"PostObjectE2eLatency": {DEFAULT_STATISTICS, UNIT_MSEC, INFLUXDB_FIELD_OSS_LATECY_POST},
|
||||
"GetObjectCount": {DEFAULT_STATISTICS, UNIT_COUNT, INFLUXDB_FIELD_OSS_REQ_COUNT_GET},
|
||||
"PostObjectCount": {DEFAULT_STATISTICS, UNIT_COUNT, INFLUXDB_FIELD_OSS_REQ_COUNT_POST},
|
||||
"ServerErrorCount": {DEFAULT_STATISTICS, UNIT_COUNT, INFLUXDB_FIELD_OSS_REQ_COUNT_5XX},
|
||||
}
|
||||
var aliElbMetricSpecs = map[string][]string{
|
||||
"InstanceTrafficRX": {DEFAULT_STATISTICS, UNIT_BPS, INFLUXDB_FIELD_ELB_NET_BPS_RX},
|
||||
"TrafficRXNew": {DEFAULT_STATISTICS, UNIT_BPS, INFLUXDB_FIELD_ELB_NET_BPS_RX},
|
||||
"InstanceTrafficTX": {DEFAULT_STATISTICS, UNIT_BPS, INFLUXDB_FIELD_ELB_NET_BPS_TX},
|
||||
"TrafficTXNew": {DEFAULT_STATISTICS, UNIT_BPS, INFLUXDB_FIELD_ELB_NET_BPS_TX},
|
||||
"InstanceStatusCode2xx": {DEFAULT_STATISTICS, UNIT_COUNT_SEC, INFLUXDB_FIELD_ELB_HRSP_COUNT_2XX},
|
||||
"InstanceStatusCode3xx": {DEFAULT_STATISTICS, UNIT_COUNT_SEC, INFLUXDB_FIELD_ELB_HRSP_COUNT_3XX},
|
||||
"InstanceStatusCode4xx": {DEFAULT_STATISTICS, UNIT_COUNT_SEC, INFLUXDB_FIELD_ELB_HRSP_COUNT_4XX},
|
||||
"InstanceStatusCode5xx": {DEFAULT_STATISTICS, UNIT_COUNT_SEC, INFLUXDB_FIELD_ELB_HRSP_COUNT_5XX},
|
||||
}
|
||||
@@ -1,15 +0,0 @@
|
||||
// Copyright 2019 Yunion
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package apsaramon // import "yunion.io/x/onecloud/pkg/cloudmon/collectors/apsaramon"
|
||||
@@ -1,87 +0,0 @@
|
||||
// Copyright 2019 Yunion
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package awsmon
|
||||
|
||||
import (
|
||||
"yunion.io/x/onecloud/pkg/apis/compute"
|
||||
"yunion.io/x/onecloud/pkg/cloudmon/collectors/common"
|
||||
"yunion.io/x/onecloud/pkg/cloudmon/options"
|
||||
"yunion.io/x/onecloud/pkg/mcclient"
|
||||
)
|
||||
|
||||
func init() {
|
||||
factory := SAwsCloudReportFactory{}
|
||||
common.RegisterFactory(&factory)
|
||||
}
|
||||
|
||||
type SAwsCloudReportFactory struct {
|
||||
common.CommonReportFactory
|
||||
}
|
||||
|
||||
func (self *SAwsCloudReportFactory) NewCloudReport(provider *common.SProvider, session *mcclient.ClientSession,
|
||||
args *options.ReportOptions, operatorType string) common.ICloudReport {
|
||||
return &SAwsCloudReport{
|
||||
common.CloudReportBase{
|
||||
SProvider: provider,
|
||||
Session: session,
|
||||
Args: args,
|
||||
Operator: operatorType,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func (self *SAwsCloudReportFactory) GetId() string {
|
||||
return compute.CLOUD_PROVIDER_AWS
|
||||
}
|
||||
|
||||
type SAwsCloudReport struct {
|
||||
common.CloudReportBase
|
||||
}
|
||||
|
||||
func (self *SAwsCloudReport) Report() error {
|
||||
servers, err := self.GetResourceByOperator()
|
||||
//servers, err := self.GetAllserverOfThisProvider(&modules.Servers)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
providerInstance, err := self.InitProviderInstance()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
regionList, regionServerMap, err := self.GetAllRegionOfServers(servers, providerInstance)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
for _, region := range regionList {
|
||||
servers := regionServerMap[region.GetGlobalId()]
|
||||
switch self.Operator {
|
||||
default:
|
||||
err = common.CollectRegionMetricAsync(self.Args.Batch, region, servers, self)
|
||||
//err = self.collectRegionMetricOfHost(region, servers)
|
||||
//case "redis":
|
||||
// err = self.collectRegionMetricOfRedis(region, servers)
|
||||
//case "rds":
|
||||
// err = self.collectRegionMetricOfRds(region, servers)
|
||||
//case "oss":
|
||||
// err = self.collectRegionMetricOfOss(region, servers)
|
||||
//case "elb":
|
||||
// err = self.collectRegionMetricOfElb(region, servers)
|
||||
}
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
@@ -1,160 +0,0 @@
|
||||
// Copyright 2019 Yunion
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package awsmon
|
||||
|
||||
import (
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
aws_sdk "github.com/aws/aws-sdk-go/aws"
|
||||
"github.com/aws/aws-sdk-go/service/cloudwatch"
|
||||
|
||||
"yunion.io/x/jsonutils"
|
||||
"yunion.io/x/log"
|
||||
|
||||
"yunion.io/x/onecloud/pkg/cloudmon/collectors/common"
|
||||
"yunion.io/x/onecloud/pkg/cloudprovider"
|
||||
"yunion.io/x/onecloud/pkg/multicloud/aws"
|
||||
"yunion.io/x/onecloud/pkg/util/influxdb"
|
||||
)
|
||||
|
||||
func (self *SAwsCloudReport) CollectRegionMetric(region cloudprovider.ICloudRegion,
|
||||
servers []jsonutils.JSONObject) error {
|
||||
var err error
|
||||
switch self.Operator {
|
||||
default:
|
||||
|
||||
err = self.collectRegionMetricOfHost(region, servers)
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
func (self *SAwsCloudReport) collectRegionMetricOfHost(region cloudprovider.ICloudRegion,
|
||||
servers []jsonutils.JSONObject) error {
|
||||
dataList := make([]influxdb.SMetricData, 0)
|
||||
awsRegion := region.(*aws.SRegion)
|
||||
since, until, err := common.TimeRangeFromArgs(self.Args)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
namespace, specs := self.getMetricSpecs(nil)
|
||||
for metricName, influxDbSpecs := range specs {
|
||||
for i, server := range servers {
|
||||
//external_id, _ := servers[i].GetString("external_id")
|
||||
name, val := self.getDimensionNameAndVal(servers[i])
|
||||
rtnArray, err := awsRegion.GetMonitorDataByDimensionName(metricName, namespace, name, val,
|
||||
since, until)
|
||||
if err != nil {
|
||||
log.Errorln(err)
|
||||
continue
|
||||
}
|
||||
if len(rtnArray.Datapoints) > 0 {
|
||||
for _, dataPoint := range rtnArray.Datapoints {
|
||||
metric, err := common.FillVMCapacity(server.(*jsonutils.JSONDict))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
dataList = append(dataList, metric)
|
||||
serverMetric, err := self.collectMetricFromThisServerForAws(server, dataPoint, influxDbSpecs)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
dataList = append(dataList, serverMetric)
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
err = common.SendMetrics(self.Session, dataList, self.Args.Debug, "")
|
||||
if err != nil {
|
||||
log.Errorln(err)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (self *SAwsCloudReport) getMetricSpecs(res jsonutils.JSONObject) (string, map[string][]string) {
|
||||
switch common.MonType(self.Operator) {
|
||||
case common.SERVER:
|
||||
return SERVER_METRIC_NAMESPACE, awsMetricSpecs
|
||||
case common.REDIS:
|
||||
return REDIS_METRIC_NAMESPACE, awsRedisMetricsSpec
|
||||
case common.RDS:
|
||||
return RDS_METRIC_NAMESPACE, awsRdsMetricSpecs
|
||||
default:
|
||||
return SERVER_METRIC_NAMESPACE, awsMetricSpecs
|
||||
}
|
||||
}
|
||||
|
||||
func (self *SAwsCloudReport) getDimensionNameAndVal(res jsonutils.JSONObject) (string, string) {
|
||||
external_id, _ := res.GetString("external_id")
|
||||
switch common.MonType(self.Operator) {
|
||||
case common.SERVER:
|
||||
return "InstanceId", external_id
|
||||
case common.REDIS:
|
||||
external_id, _ = res.GetString("name")
|
||||
return "CacheClusterId", external_id
|
||||
case common.RDS:
|
||||
external_id, _ = res.GetString("name")
|
||||
return "DBInstanceIdentifier", external_id
|
||||
default:
|
||||
return "InstanceId", external_id
|
||||
}
|
||||
}
|
||||
|
||||
func (self *SAwsCloudReport) collectMetricFromThisServerForAws(server jsonutils.JSONObject, datapoint *cloudwatch.Datapoint,
|
||||
influxDbSpecs []string) (metric influxdb.SMetricData, err error) {
|
||||
metric, err = self.NewMetricFromJson(server)
|
||||
if err != nil {
|
||||
return metric, err
|
||||
}
|
||||
metric.Timestamp = aws_sdk.TimeValue(datapoint.Timestamp)
|
||||
fieldValue := aws_sdk.Float64Value(datapoint.Average)
|
||||
//根据条件拼装metric的tag和metirc信息
|
||||
influxDbSpec := influxDbSpecs[2]
|
||||
measurement := common.SubstringBefore(influxDbSpec, ".")
|
||||
var pairsKey string
|
||||
if strings.Contains(influxDbSpec, ",") {
|
||||
pairsKey = common.SubstringBetween(influxDbSpec, ".", ",")
|
||||
} else {
|
||||
pairsKey = common.SubstringAfter(influxDbSpec, ".")
|
||||
}
|
||||
// 300:AWS metric collection period is 5m
|
||||
if influxDbSpecs[1] == UNIT_COUNT {
|
||||
fieldValue = (fieldValue / float64(300))
|
||||
}
|
||||
if influxDbSpecs[1] == UNIT_MEM {
|
||||
fieldValue = (fieldValue / float64(300) * 8)
|
||||
}
|
||||
if influxDbSpecs[1] == UNIT_BYTEPS {
|
||||
fieldValue = (fieldValue * 8)
|
||||
}
|
||||
tag := common.SubstringAfter(influxDbSpec, ",")
|
||||
if tag != "" && strings.Contains(influxDbSpec, "=") {
|
||||
metric.Tags = append(metric.Tags, influxdb.SKeyValue{Key: common.SubstringBefore(tag, "="),
|
||||
Value: common.SubstringAfter(tag, "=")})
|
||||
}
|
||||
cpu_cout, err := server.Get("vcpu_count")
|
||||
if err != nil {
|
||||
metric.Metrics = append(metric.Metrics, influxdb.SKeyValue{Key: pairsKey,
|
||||
Value: strconv.FormatFloat(fieldValue, 'E', -1, 64)})
|
||||
} else {
|
||||
metric.Metrics = append(metric.Metrics, influxdb.SKeyValue{Key: "cpu_count",
|
||||
Value: strconv.FormatInt(cpu_cout.(*jsonutils.JSONInt).Value(), 10)},
|
||||
influxdb.SKeyValue{Key: pairsKey,
|
||||
Value: strconv.FormatFloat(fieldValue, 'E', -1, 64)})
|
||||
}
|
||||
metric.Name = measurement
|
||||
return metric, nil
|
||||
}
|
||||
@@ -1,158 +0,0 @@
|
||||
// Copyright 2019 Yunion
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package awsmon
|
||||
|
||||
const (
|
||||
PERIOD = 60
|
||||
UNIT_AVERAGE = "Average"
|
||||
DEFAULT_STATISTICS = "Average,Minimum,Maximum"
|
||||
UNIT_PERCENT = "Percent"
|
||||
UNIT_BPS = "bps"
|
||||
UNIT_MBPS = "Mbps"
|
||||
UNIT_BYTEPS = "Bps"
|
||||
UNIT_CPS = "cps"
|
||||
UNIT_COUNT = "count"
|
||||
UNIT_MEM = "byte"
|
||||
UNIT_MSEC = "ms"
|
||||
UNIT_COUNT_SEC = "count/s"
|
||||
|
||||
SERVER_METRIC_NAMESPACE = "AWS/EC2"
|
||||
REDIS_METRIC_NAMESPACE = "AWS/ElastiCache"
|
||||
RDS_METRIC_NAMESPACE = "AWS/RDS"
|
||||
|
||||
//ESC监控指标
|
||||
INFLUXDB_FIELD_CPU_USAGE = "vm_cpu.usage_active"
|
||||
INFLUXDB_FIELD_MEM_USAGE = "vm_mem.used_percent"
|
||||
INFLUXDB_FIELD_DISK_READ_BPS = "vm_diskio.read_bps"
|
||||
INFLUXDB_FIELD_DISK_WRITE_BPS = "vm_diskio.write_bps"
|
||||
INFLUXDB_FIELD_DISK_READ_BPS_EBS = INFLUXDB_FIELD_DISK_READ_BPS + ",disk_type=ebs"
|
||||
INFLUXDB_FIELD_DISK_WRITE_BPS_EBS = INFLUXDB_FIELD_DISK_WRITE_BPS + ",disk_type=ebs"
|
||||
INFLUXDB_FIELD_DISK_READ_IOPS = "vm_diskio.read_iops"
|
||||
INFLUXDB_FIELD_DISK_WRITE_IOPS = "vm_diskio.write_iops"
|
||||
INFLUXDB_FIELD_DISK_READ_IOPS_EBS = INFLUXDB_FIELD_DISK_READ_IOPS + ",disk_type=ebs"
|
||||
INFLUXDB_FIELD_DISK_WRITE_IOPS_EBS = INFLUXDB_FIELD_DISK_WRITE_IOPS + ",disk_type=ebs"
|
||||
INFLUXDB_FIELD_NET_BPS_RX = "vm_netio.bps_recv"
|
||||
INFLUXDB_FIELD_NET_BPS_RX_INTERNET = INFLUXDB_FIELD_NET_BPS_RX + ",net_type=internet"
|
||||
INFLUXDB_FIELD_NET_BPS_RX_INTRANET = INFLUXDB_FIELD_NET_BPS_RX + ",net_type=intranet"
|
||||
INFLUXDB_FIELD_NET_BPS_TX = "vm_netio.bps_sent"
|
||||
INFLUXDB_FIELD_NET_BPS_TX_INTERNET = INFLUXDB_FIELD_NET_BPS_TX + ",net_type=internet"
|
||||
INFLUXDB_FIELD_NET_BPS_TX_INTRANET = INFLUXDB_FIELD_NET_BPS_TX + ",net_type=intranet"
|
||||
INFLUXDB_FIELD_WANOUTTRAFFIC = "vm_eipio.bps_out"
|
||||
INFLUXDB_FIELD_WANINTRAFFIC = "vm_eipio.bps_in"
|
||||
INFLUXDB_FIELD_WANOUTPKG = "vm_eipio.pps_out"
|
||||
INFLUXDB_FIELD_WANINPKG = "vm_eipio.pps_in"
|
||||
|
||||
//RDS监控指标
|
||||
INFLUXDB_FIELD_RDS_CPU_USAGE = "rds_cpu.usage_active"
|
||||
INFLUXDB_FIELD_RDS_MEM_USAGE = "rds_mem.used_percent"
|
||||
INFLUXDB_FIELD_RDS_NET_BPS_RX = "rds_netio.bps_recv"
|
||||
INFLUXDB_FIELD_RDS_NET_BPS_RX_MYSQL = INFLUXDB_FIELD_RDS_NET_BPS_RX + ",server_type=mysql"
|
||||
INFLUXDB_FIELD_RDS_NET_BPS_RX_SQLSERVER = INFLUXDB_FIELD_RDS_NET_BPS_RX + ",server_type=sqlserver"
|
||||
INFLUXDB_FIELD_RDS_NET_BPS_TX = "rds_netio.bps_send"
|
||||
INFLUXDB_FIELD_RDS_NET_BPS_TX_MYSQL = INFLUXDB_FIELD_RDS_NET_BPS_TX + ",server_type=mysql"
|
||||
INFLUXDB_FIELD_RDS_NET_BPS_TX_SQLSERVER = INFLUXDB_FIELD_RDS_NET_BPS_TX + ",server_type=sqlserver"
|
||||
INFLUXDB_FIELD_RDS_DISK_USAGE = "rds_disk.used_percent"
|
||||
INFLUXDB_FIELD_RDS_DISK_READ_BPS = "rds_diskio.read_bps"
|
||||
INFLUXDB_FIELD_RDS_DISK_WRITE_BPS = "rds_diskio.write_bps"
|
||||
INFLUXDB_FIELD_RDS_CONN_COUNT = "rds_conn.used_count"
|
||||
INFLUXDB_FIELD_RDS_CONN_USAGE = "rds_conn.used_percent"
|
||||
|
||||
INFLUXDB_FIELD_RDS_QPS = "rds_qps.query_qps"
|
||||
INFLUXDB_FIELD_RDS_TPS = "rds_tps.trans_qps"
|
||||
INFLUXDB_FIELD_RDS_INNODB_REDA_BPS = "rds_innodb.read_bps"
|
||||
INFLUXDB_FIELD_RDS_INNODB_WRITE_BPS = "rds_innodb.write_bps"
|
||||
|
||||
//REDIS监控指标
|
||||
INFLUXDB_FIELD_REDIS_CPU_USAGE = "dcs_cpu.usage_percent"
|
||||
INFLUXDB_FIELD_REDIS_MEM_USAGE = "dcs_mem.used_percent"
|
||||
INFLUXDB_FIELD_REDIS_NET_BPS_RX = "dcs_netio.bps_recv"
|
||||
INFLUXDB_FIELD_REDIS_NET_BPS_TX = "dcs_netio.bps_sent"
|
||||
INFLUXDB_FIFLD_REDIS_CONN_USAGE = "dcs_conn.used_conn"
|
||||
INFLUXDB_FIFLD_REDIS_OPT_SES = "dcs_instantopt.opt_sec"
|
||||
INFLUXDB_FIFLD_REDIS_CACHE_KEYS = "dcs_cachekeys.key_count"
|
||||
INFLUXDB_FIFLD_REDIS_CACHE_KEYS_PERCENT = "dcs_cachekeys.used_percent"
|
||||
INFLUXDB_FIFLD_REDIS_CACHE_EXP_KEYS = INFLUXDB_FIFLD_REDIS_CACHE_KEYS + ",exp=expire"
|
||||
INFLUXDB_FIFLD_REDIS_DATA_MEM_USAGE = "dcs_datamem.used_byte"
|
||||
|
||||
//对象存储OSS监控指标
|
||||
INFLUXDB_FIELD_OSS_NET_BPS_RX = "oss_netio.bps_recv"
|
||||
INFLUXDB_FIELD_OSS_NET_BPS_RX_INTERNET = INFLUXDB_FIELD_OSS_NET_BPS_RX + ",net_type=internet"
|
||||
INFLUXDB_FIELD_OSS_NET_BPS_RX_INTRANET = INFLUXDB_FIELD_OSS_NET_BPS_RX + ",net_type=intranet"
|
||||
INFLUXDB_FIELD_OSS_NET_BPS_TX = "oss_netio.bps_sent"
|
||||
INFLUXDB_FIELD_OSS_NET_BPS_TX_INTERNET = INFLUXDB_FIELD_OSS_NET_BPS_TX + ",net_type=internet"
|
||||
INFLUXDB_FIELD_OSS_NET_BPS_TX_INTRANET = INFLUXDB_FIELD_OSS_NET_BPS_TX + ",net_type=intranet"
|
||||
INFLUXDB_FIELD_OSS_LATECY = "oss_latency.req_late"
|
||||
INFLUXDB_FIELD_OSS_LATECY_GET = INFLUXDB_FIELD_OSS_LATECY + ",request=get"
|
||||
INFLUXDB_FIELD_OSS_LATECY_POST = INFLUXDB_FIELD_OSS_LATECY + ",request=post"
|
||||
INFLUXDB_FIELD_OSS_REQ_COUNT = "oss_req.req_count"
|
||||
INFLUXDB_FIELD_OSS_REQ_COUNT_GET = INFLUXDB_FIELD_OSS_REQ_COUNT + ",request=get"
|
||||
INFLUXDB_FIELD_OSS_REQ_COUNT_POST = INFLUXDB_FIELD_OSS_REQ_COUNT + ",request=post"
|
||||
INFLUXDB_FIELD_OSS_REQ_COUNT_5XX = INFLUXDB_FIELD_OSS_REQ_COUNT + ",request=5xx"
|
||||
INFLUXDB_FIELD_OSS_REQ_COUNT_4XX = INFLUXDB_FIELD_OSS_REQ_COUNT + ",request=4xx"
|
||||
|
||||
//负载均衡监控指标
|
||||
INFLUXDB_FIELD_ELB_NET_BPS_RX = "haproxy.bin"
|
||||
INFLUXDB_FIELD_ELB_NET_BPS_TX = "haproxy.bout"
|
||||
INFLUXDB_FIELD_ELB_REQ_RATE = "haproxy.req_rate,request=http"
|
||||
INFLUXDB_FIELD_ELB_CONN_RATE = "haproxy.conn_rate,request=tcp"
|
||||
INFLUXDB_FIELD_ELB_DREQ_COUNT = "haproxy.dreq,request=http"
|
||||
INFLUXDB_FIELD_ELB_DCONN_COUNT = "haproxy.dcon,request=tcp"
|
||||
INFLUXDB_FIELD_ELB_HRSP_COUNT = "haproxy.hrsp_Nxx"
|
||||
INFLUXDB_FIELD_ELB_HRSP_COUNT_2XX = INFLUXDB_FIELD_ELB_HRSP_COUNT + ",request=2xx"
|
||||
INFLUXDB_FIELD_ELB_HRSP_COUNT_3XX = INFLUXDB_FIELD_ELB_HRSP_COUNT + ",request=3xx"
|
||||
INFLUXDB_FIELD_ELB_HRSP_COUNT_4XX = INFLUXDB_FIELD_ELB_HRSP_COUNT + ",request=4xx"
|
||||
INFLUXDB_FIELD_ELB_HRSP_COUNT_5XX = INFLUXDB_FIELD_ELB_HRSP_COUNT + ",request=5xx"
|
||||
INFLUXDB_FIELD_ELB_CHC_STATUS = "haproxy.check_status"
|
||||
INFLUXDB_FIELD_ELB_CHC_CODE = "haproxy.check_code"
|
||||
INFLUXDB_FIELD_ELB_LAST_CHC = "haproxy.last_chk"
|
||||
|
||||
KEY_VMS = "vms"
|
||||
KEY_CPUS = "cpus"
|
||||
KEY_MEMS = "mems"
|
||||
KEY_DISKS = "disks"
|
||||
|
||||
KEY_LIMIT = "limit"
|
||||
KEY_ADMIN = "admin"
|
||||
KEY_USABLE = "usable"
|
||||
)
|
||||
|
||||
//multiCloud查询指标列表组装
|
||||
var awsMetricSpecs = map[string][]string{
|
||||
"CPUUtilization": {DEFAULT_STATISTICS, UNIT_PERCENT, INFLUXDB_FIELD_CPU_USAGE},
|
||||
"DiskReadOps": {DEFAULT_STATISTICS, UNIT_COUNT, INFLUXDB_FIELD_DISK_READ_IOPS},
|
||||
"EBSReadOps": {DEFAULT_STATISTICS, UNIT_COUNT, INFLUXDB_FIELD_DISK_READ_IOPS_EBS},
|
||||
"DiskWriteOps": {DEFAULT_STATISTICS, UNIT_COUNT, INFLUXDB_FIELD_DISK_WRITE_IOPS},
|
||||
"EBSWriteOps": {DEFAULT_STATISTICS, UNIT_COUNT, INFLUXDB_FIELD_DISK_WRITE_IOPS_EBS},
|
||||
"DiskReadBytes": {DEFAULT_STATISTICS, UNIT_MEM, INFLUXDB_FIELD_DISK_READ_BPS},
|
||||
"EBSReadBytes": {DEFAULT_STATISTICS, UNIT_MEM, INFLUXDB_FIELD_DISK_READ_BPS_EBS},
|
||||
"DiskWriteBytes": {DEFAULT_STATISTICS, UNIT_MEM, INFLUXDB_FIELD_DISK_WRITE_BPS},
|
||||
"EBSWriteBytes": {DEFAULT_STATISTICS, UNIT_MEM, INFLUXDB_FIELD_DISK_WRITE_BPS_EBS},
|
||||
"NetworkIn": {DEFAULT_STATISTICS, UNIT_MEM, INFLUXDB_FIELD_NET_BPS_RX},
|
||||
"NetworkOut": {DEFAULT_STATISTICS, UNIT_MEM, INFLUXDB_FIELD_NET_BPS_TX},
|
||||
}
|
||||
|
||||
var awsRdsMetricSpecs = map[string][]string{
|
||||
"CPUUtilization": {DEFAULT_STATISTICS, UNIT_PERCENT, INFLUXDB_FIELD_RDS_CPU_USAGE},
|
||||
"NetworkReceiveThroughput": {DEFAULT_STATISTICS, UNIT_BYTEPS, INFLUXDB_FIELD_RDS_NET_BPS_RX},
|
||||
"NetworkTransmitThroughput": {DEFAULT_STATISTICS, UNIT_BYTEPS, INFLUXDB_FIELD_RDS_NET_BPS_TX},
|
||||
"DatabaseConnections": {DEFAULT_STATISTICS, UNIT_COUNT, INFLUXDB_FIELD_RDS_CONN_COUNT},
|
||||
}
|
||||
|
||||
var awsRedisMetricsSpec = map[string][]string{
|
||||
"CPUUtilization": {DEFAULT_STATISTICS, UNIT_PERCENT, INFLUXDB_FIELD_REDIS_CPU_USAGE},
|
||||
"CurrConnections": {DEFAULT_STATISTICS, UNIT_COUNT, INFLUXDB_FIFLD_REDIS_CONN_USAGE},
|
||||
"Reclaimed": {DEFAULT_STATISTICS, UNIT_COUNT, INFLUXDB_FIFLD_REDIS_CACHE_EXP_KEYS},
|
||||
"CacheHitRate": {DEFAULT_STATISTICS, UNIT_PERCENT, INFLUXDB_FIFLD_REDIS_CACHE_KEYS_PERCENT},
|
||||
}
|
||||
@@ -1,15 +0,0 @@
|
||||
// Copyright 2019 Yunion
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package awsmon // import "yunion.io/x/onecloud/pkg/cloudmon/collectors/awsmon"
|
||||
@@ -1,165 +0,0 @@
|
||||
// Copyright 2019 Yunion
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package azuremon
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"yunion.io/x/jsonutils"
|
||||
|
||||
"yunion.io/x/onecloud/pkg/apis/compute"
|
||||
"yunion.io/x/onecloud/pkg/cloudmon/collectors/common"
|
||||
"yunion.io/x/onecloud/pkg/cloudmon/options"
|
||||
"yunion.io/x/onecloud/pkg/mcclient"
|
||||
)
|
||||
|
||||
func init() {
|
||||
factory := SAzureCloudReportFactory{}
|
||||
common.RegisterFactory(&factory)
|
||||
|
||||
cluster := &AzureK8sClusterHelper{
|
||||
K8sClusterMetricBaseHelper: &common.K8sClusterMetricBaseHelper{
|
||||
ModuleHelper: map[common.K8sClusterModuleType]common.IK8sClusterModuleHelper{},
|
||||
},
|
||||
}
|
||||
cluster.RegisterModuleHelper(new(AzureK8sClusterPodHelper))
|
||||
cluster.RegisterModuleHelper(new(AzureK8sClusterNodeHelper))
|
||||
common.RegisterK8sClusterHelper(cluster)
|
||||
}
|
||||
|
||||
type SAzureCloudReportFactory struct {
|
||||
common.CommonReportFactory
|
||||
}
|
||||
|
||||
func (self *SAzureCloudReportFactory) NewCloudReport(provider *common.SProvider, session *mcclient.ClientSession,
|
||||
args *options.ReportOptions, operatorType string) common.ICloudReport {
|
||||
return &SAzureCloudReport{
|
||||
common.CloudReportBase{
|
||||
SProvider: provider,
|
||||
Session: session,
|
||||
Args: args,
|
||||
Operator: operatorType,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func (self *SAzureCloudReportFactory) GetId() string {
|
||||
return compute.CLOUD_PROVIDER_AZURE
|
||||
}
|
||||
|
||||
type SAzureCloudReport struct {
|
||||
common.CloudReportBase
|
||||
}
|
||||
|
||||
func (self *SAzureCloudReport) Report() error {
|
||||
servers, err := self.GetResourceByOperator()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
providerInstance, err := self.InitProviderInstance()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
regionList, regionServerMap, err := self.GetAllRegionOfServers(servers, providerInstance)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
for _, region := range regionList {
|
||||
servers := regionServerMap[region.GetGlobalId()]
|
||||
switch common.MonType(self.Operator) {
|
||||
case common.K8S:
|
||||
self.Impl = self
|
||||
err = self.CollectRegionMetricOfK8sModules(region, servers)
|
||||
default:
|
||||
err = common.CollectRegionMetricAsync(self.Args.Batch, region, servers, self)
|
||||
|
||||
}
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type AzureK8sClusterHelper struct {
|
||||
*common.K8sClusterMetricBaseHelper
|
||||
}
|
||||
|
||||
func (a AzureK8sClusterHelper) HelperBrand() string {
|
||||
return compute.CLOUD_PROVIDER_AZURE
|
||||
}
|
||||
|
||||
type ik8sModuleFilterHelper interface {
|
||||
filter(object jsonutils.JSONObject) string
|
||||
}
|
||||
|
||||
type AzureK8sClusterPodHelper struct {
|
||||
common.K8sClusterModuleQueryHelper
|
||||
}
|
||||
|
||||
func (a AzureK8sClusterPodHelper) filter(resource jsonutils.JSONObject) string {
|
||||
parentName, _ := resource.GetString("name")
|
||||
return fmt.Sprintf(`controllerName eq '%s'`, parentName)
|
||||
}
|
||||
|
||||
func (a AzureK8sClusterPodHelper) MyModuleType() common.K8sClusterModuleType {
|
||||
return common.K8S_MODULE_POD
|
||||
}
|
||||
|
||||
func (a AzureK8sClusterPodHelper) MyResDimensionId() common.DimensionId {
|
||||
return common.DimensionId{
|
||||
LocalId: "",
|
||||
ExtId: "",
|
||||
}
|
||||
}
|
||||
|
||||
func (a AzureK8sClusterPodHelper) MyNamespaceAndMetrics() (string, map[string][]string) {
|
||||
return K8S_POD_METRIC_NAMESPACE, azureK8SPodMetricSpecs
|
||||
}
|
||||
|
||||
func (q AzureK8sClusterPodHelper) MyResourceFilterQuery(resource jsonutils.JSONObject) jsonutils.JSONObject {
|
||||
query := jsonutils.NewDict()
|
||||
parentName, _ := resource.GetString("name")
|
||||
kind, _ := resource.GetString("kind")
|
||||
namespace, _ := resource.GetString("namespace")
|
||||
query.Set("owner_name", jsonutils.NewString(parentName))
|
||||
query.Set("owner_kind", jsonutils.NewString(kind))
|
||||
query.Set("namespace", jsonutils.NewString(namespace))
|
||||
return query
|
||||
}
|
||||
|
||||
type AzureK8sClusterNodeHelper struct {
|
||||
common.K8sClusterModuleQueryHelper
|
||||
}
|
||||
|
||||
func (a AzureK8sClusterNodeHelper) filter(resource jsonutils.JSONObject) string {
|
||||
parentName, _ := resource.GetString("name")
|
||||
return fmt.Sprintf(`node eq '%s'`, parentName)
|
||||
}
|
||||
|
||||
func (a AzureK8sClusterNodeHelper) MyModuleType() common.K8sClusterModuleType {
|
||||
return common.K8S_MODULE_NODE
|
||||
}
|
||||
|
||||
func (a AzureK8sClusterNodeHelper) MyResDimensionId() common.DimensionId {
|
||||
return common.DimensionId{
|
||||
LocalId: "",
|
||||
ExtId: "",
|
||||
}
|
||||
}
|
||||
|
||||
func (a AzureK8sClusterNodeHelper) MyNamespaceAndMetrics() (string, map[string][]string) {
|
||||
return K8S_NODE_METRIC_NAMESPACE, azureK8SNodeMetricSpecs
|
||||
}
|
||||
@@ -1,279 +0,0 @@
|
||||
// Copyright 2019 Yunion
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package azuremon
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"yunion.io/x/jsonutils"
|
||||
"yunion.io/x/log"
|
||||
"yunion.io/x/pkg/errors"
|
||||
|
||||
com_api "yunion.io/x/onecloud/pkg/apis/compute"
|
||||
"yunion.io/x/onecloud/pkg/cloudmon/collectors/common"
|
||||
"yunion.io/x/onecloud/pkg/cloudprovider"
|
||||
"yunion.io/x/onecloud/pkg/mcclient"
|
||||
"yunion.io/x/onecloud/pkg/multicloud/azure"
|
||||
"yunion.io/x/onecloud/pkg/util/influxdb"
|
||||
)
|
||||
|
||||
func (self *SAzureCloudReport) CollectRegionMetric(region cloudprovider.ICloudRegion,
|
||||
servers []jsonutils.JSONObject) error {
|
||||
return self.collectRegionMetricOfHost(region, servers)
|
||||
}
|
||||
|
||||
func (self *SAzureCloudReport) collectRegionMetricOfHost(region cloudprovider.ICloudRegion,
|
||||
servers []jsonutils.JSONObject) error {
|
||||
azureReg := region.(*azure.SRegion)
|
||||
since, until, err := common.TimeRangeFromArgs(self.Args)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
for _, server := range servers {
|
||||
dataList := make([]influxdb.SMetricData, 0)
|
||||
srvId, _ := server.GetString("id")
|
||||
srvName, _ := server.GetString("name")
|
||||
srvPrefix := srvId + "/" + "srvName"
|
||||
externalId, err := server.GetString("external_id")
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
classicKey := "microsoft.classiccompute/virtualmachines"
|
||||
ns, metricSpecs := self.getMetricSpecs(server)
|
||||
if strings.Contains(strings.ToLower(externalId), classicKey) {
|
||||
ns = classicKey
|
||||
metricSpecs = azureClassicMetricsSpec
|
||||
}
|
||||
// SQLServer with databases/master
|
||||
if strings.Contains(strings.ToLower(externalId), "microsoft.sql/servers") {
|
||||
externalId = fmt.Sprintf("%s/databases/master", externalId)
|
||||
}
|
||||
|
||||
err = func() error {
|
||||
metricNameArr := make([]string, 0)
|
||||
for metricName := range metricSpecs {
|
||||
metricNameArr = append(metricNameArr, metricName)
|
||||
}
|
||||
metricNames := strings.Join(metricNameArr, ",")
|
||||
rtnMetrics, err := azureReg.GetMonitorData(metricNames, ns, externalId, since, until, self.Args.MetricInterval, "")
|
||||
if err != nil {
|
||||
return errors.Wrapf(err, "GetMonitorData")
|
||||
}
|
||||
if rtnMetrics == nil || rtnMetrics.Value == nil {
|
||||
return fmt.Errorf("server %s metic is nil", srvPrefix)
|
||||
}
|
||||
|
||||
for metricName, influxDbSpecs := range metricSpecs {
|
||||
for _, value := range rtnMetrics.Value {
|
||||
if metricName == value.Name.LocalizedValue || (value.Name.Value == metricName) {
|
||||
if self.Operator == string(common.SERVER) {
|
||||
metric, err := common.FillVMCapacity(server.(*jsonutils.JSONDict))
|
||||
if err != nil {
|
||||
return errors.Wrapf(err, "fill vm %q capacity", srvPrefix)
|
||||
}
|
||||
dataList = append(dataList, metric)
|
||||
}
|
||||
if value.Timeseries != nil {
|
||||
for _, timeserie := range value.Timeseries {
|
||||
serverMetric, err := self.collectMetricFromThisServer(server, timeserie, influxDbSpecs)
|
||||
if err != nil {
|
||||
return errors.Wrapf(err, "collect metrics from server %q", srvPrefix)
|
||||
}
|
||||
dataList = append(dataList, serverMetric...)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}()
|
||||
if err != nil {
|
||||
log.Errorf("collect azure %s %s %s metric error: %v", externalId, ns, srvName, err)
|
||||
continue
|
||||
}
|
||||
log.Infof("send %s %s %d metrics", ns, externalId, len(dataList))
|
||||
err = common.SendMetrics(self.Session, dataList, self.Args.Debug, "")
|
||||
if err != nil {
|
||||
log.Errorf("send %q metrics error: %v", srvName, err)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (self *SAzureCloudReport) collectMetricFromThisServer(server jsonutils.JSONObject,
|
||||
rtnMetric azure.TimeSeriesElement, influxDbSpecs []string) ([]influxdb.SMetricData, error) {
|
||||
datas := make([]influxdb.SMetricData, 0)
|
||||
for _, data := range rtnMetric.Data {
|
||||
metric, err := self.NewMetricFromJson(server)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
metric.Timestamp = data.TimeStamp
|
||||
//根据条件拼装metric的tag和metirc信息
|
||||
fieldValue := data.Average
|
||||
influxDbSpec := influxDbSpecs[2]
|
||||
measurement := common.SubstringBefore(influxDbSpec, ".")
|
||||
metric.Name = measurement
|
||||
var pairsKey string
|
||||
if strings.Contains(influxDbSpec, ",") {
|
||||
pairsKey = common.SubstringBetween(influxDbSpec, ".", ",")
|
||||
} else {
|
||||
pairsKey = common.SubstringAfter(influxDbSpec, ".")
|
||||
}
|
||||
if influxDbSpecs[1] == common.UNIT_MEM {
|
||||
//fieldValue = fieldValue * 8 / common.PERIOD
|
||||
fieldValue = fieldValue * 8
|
||||
}
|
||||
tag := common.SubstringAfter(influxDbSpec, ",")
|
||||
if tag != "" && strings.Contains(influxDbSpec, "=") {
|
||||
metric.Tags = append(metric.Tags, influxdb.SKeyValue{
|
||||
Key: common.SubstringBefore(tag, "="),
|
||||
Value: common.SubstringAfter(tag, "="),
|
||||
})
|
||||
}
|
||||
cpu_cout, err := server.Get("vcpu_count")
|
||||
if err == nil {
|
||||
metric.Metrics = append(metric.Metrics, influxdb.SKeyValue{
|
||||
Key: "cpu_count",
|
||||
Value: strconv.FormatInt(cpu_cout.(*jsonutils.JSONInt).Value(), 10),
|
||||
})
|
||||
}
|
||||
metric.Metrics = append(metric.Metrics, influxdb.SKeyValue{
|
||||
Key: pairsKey,
|
||||
Value: strconv.FormatFloat(fieldValue, 'E', -1, 64),
|
||||
})
|
||||
datas = append(datas, metric)
|
||||
}
|
||||
|
||||
return datas, nil
|
||||
}
|
||||
|
||||
func (self *SAzureCloudReport) getMetricSpecs(res jsonutils.JSONObject) (string, map[string][]string) {
|
||||
switch common.MonType(self.Operator) {
|
||||
case common.SERVER:
|
||||
return SERVER_METRIC_NAMESPACE, azureMetricSpecs
|
||||
case common.REDIS:
|
||||
return REDIS_METRIC_NAMESPACE, azureRedisMetricsSpec
|
||||
case common.RDS:
|
||||
return self.getRdsMetricSpecsByEngine(res)
|
||||
case common.ELB:
|
||||
return ELB_METRIC_NAMESPACE, azureElbMetricSpecs
|
||||
default:
|
||||
return SERVER_METRIC_NAMESPACE, azureMetricSpecs
|
||||
}
|
||||
}
|
||||
|
||||
func (self *SAzureCloudReport) getRdsMetricSpecsByEngine(res jsonutils.JSONObject) (string, map[string][]string) {
|
||||
engine, _ := res.GetString("engine")
|
||||
externalId, _ := res.GetString("external_id")
|
||||
suffix := "servers"
|
||||
if strings.Contains(externalId, "flexible") {
|
||||
suffix = "flexibleServers"
|
||||
}
|
||||
switch engine {
|
||||
case com_api.DBINSTANCE_TYPE_SQLSERVER:
|
||||
return "Microsoft.Sql/servers/databases", azureRdsMetricsSpecSqlserver
|
||||
case com_api.DBINSTANCE_TYPE_MYSQL:
|
||||
return fmt.Sprintf("Microsoft.DBforMySQL/%s", suffix), azureRdsMetricsSpec
|
||||
case com_api.DBINSTANCE_TYPE_POSTGRESQL:
|
||||
return fmt.Sprintf("Microsoft.DBforPostgreSQL/%s", suffix), azureRdsMetricsSpec
|
||||
case com_api.DBINSTANCE_TYPE_MARIADB:
|
||||
return "Microsoft.DBforMariaDB/servers", azureRdsMetricsSpec
|
||||
default:
|
||||
return fmt.Sprintf("Microsoft.DBforMySQL/%s", suffix), azureRdsMetricsSpec
|
||||
}
|
||||
}
|
||||
|
||||
func (self *SAzureCloudReport) CollectK8sModuleMetric(region cloudprovider.ICloudRegion, cluster jsonutils.JSONObject,
|
||||
helper common.IK8sClusterModuleHelper) error {
|
||||
azureReg := region.(*azure.SRegion)
|
||||
since, until, err := common.TimeRangeFromArgs(self.Args)
|
||||
id, _ := cluster.GetString("id")
|
||||
resources, err := self.getClusterModuleResourceByType(helper.MyModuleType(), id, self.Session, nil)
|
||||
if err != nil {
|
||||
return errors.Wrapf(err, "getClusterModuleResourceByType")
|
||||
}
|
||||
externalId, _ := cluster.GetString("external_cloud_cluster_id")
|
||||
namespace, metricSpecs := helper.MyNamespaceAndMetrics()
|
||||
|
||||
metricNameArr := make([]string, 0)
|
||||
for metricName := range metricSpecs {
|
||||
metricNameArr = append(metricNameArr, metricName)
|
||||
}
|
||||
metricNames := strings.Join(metricNameArr, ",")
|
||||
azureReg.GetClient().Debug(true)
|
||||
for _, resource := range resources {
|
||||
parentName, _ := resource.GetString("name")
|
||||
filter := helper.(ik8sModuleFilterHelper).filter(resource)
|
||||
rtnMetrics, err := azureReg.GetMonitorData(metricNames, namespace, externalId, since, until,
|
||||
self.Args.MetricInterval, filter)
|
||||
if err != nil {
|
||||
log.Errorf("get deploy/daemonset: %s metrics err %v", parentName, err)
|
||||
continue
|
||||
}
|
||||
if rtnMetrics == nil || rtnMetrics.Value == nil {
|
||||
log.Warningf("get deploy/daemonset: %s metrics is nil", parentName)
|
||||
continue
|
||||
}
|
||||
|
||||
dataList := make([]influxdb.SMetricData, 0)
|
||||
for metricName, influxDbSpecs := range metricSpecs {
|
||||
for _, value := range rtnMetrics.Value {
|
||||
if metricName == value.Name.LocalizedValue || (value.Name.Value == metricName) {
|
||||
if value.Timeseries != nil {
|
||||
for _, timeserie := range value.Timeseries {
|
||||
serverMetric, err := self.collectMetricFromThisServer(resource, timeserie, influxDbSpecs)
|
||||
if err != nil {
|
||||
log.Errorf("collect pod: %s metric err: %v", parentName, err)
|
||||
}
|
||||
dataList = append(dataList, serverMetric...)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
err = common.SendMetrics(self.Session, dataList, self.Args.Debug, "")
|
||||
if err != nil {
|
||||
log.Errorf("send resource: %s metrics error: %v", parentName, err)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (self *SAzureCloudReport) getClusterModuleResourceByType(typ common.K8sClusterModuleType, clusterId string,
|
||||
session *mcclient.ClientSession, query *jsonutils.JSONDict) ([]jsonutils.JSONObject, error) {
|
||||
switch typ {
|
||||
case common.K8S_MODULE_POD:
|
||||
return self.getK8sClusterPods(clusterId, session, nil)
|
||||
case common.K8S_MODULE_NODE:
|
||||
return common.ListK8sClusterModuleResources(typ, clusterId, session, nil)
|
||||
default:
|
||||
return nil, errors.Errorf("unsupport the clusterModuleType: %s", string(typ))
|
||||
}
|
||||
}
|
||||
|
||||
func (self *SAzureCloudReport) getK8sClusterPods(clusterId string, session *mcclient.ClientSession, query *jsonutils.JSONDict) ([]jsonutils.JSONObject, error) {
|
||||
deployRes, err := common.ListK8sClusterModuleResources(common.K8S_MODULE_DEPLOY, clusterId, session, query)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "List cluster: %s deploy err", clusterId)
|
||||
}
|
||||
daemonsetRes, err := common.ListK8sClusterModuleResources(common.K8S_MODULE_DAEMONSET, clusterId, session, query)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "List cluster: %s daemonset err", clusterId)
|
||||
}
|
||||
return append(daemonsetRes, deployRes...), nil
|
||||
}
|
||||
@@ -1,115 +0,0 @@
|
||||
// Copyright 2019 Yunion
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package azuremon
|
||||
|
||||
import "yunion.io/x/onecloud/pkg/cloudmon/collectors/common"
|
||||
|
||||
// multiCloud查询指标列表组装
|
||||
const (
|
||||
MetricKeyPercentageCPU = "Percentage CPU"
|
||||
MetricKeyNetworkInTotal = "Network In Total"
|
||||
MetricKeyNetworkOutTotal = "Network Out Total"
|
||||
MetricKeyDiskReadBytes = "Disk Read Bytes"
|
||||
MetricKeyDiskWriteBytes = "Disk Write Bytes"
|
||||
MetricKeyDiskReadOPS = "Disk Read Operations/Sec"
|
||||
MetricKeyDiskWriteOPS = "Disk Write Operations/Sec"
|
||||
|
||||
MetricKeyClassicNetworkIn = "Network In"
|
||||
MetricKeyClassicNetworkOut = "Network Out"
|
||||
MetricKeyClassicDiskReadBPS = "Disk Read Bytes/Sec"
|
||||
MetricKeyClassicDiskWriteBPS = "Disk Write Bytes/Sec"
|
||||
|
||||
SERVER_METRIC_NAMESPACE = "Microsoft.Compute/virtualMachines"
|
||||
REDIS_METRIC_NAMESPACE = "Microsoft.Cache/redis"
|
||||
ELB_METRIC_NAMESPACE = "Microsoft.Network/loadBalancers"
|
||||
K8S_NODE_METRIC_NAMESPACE = "Microsoft.ContainerService/managedClusters"
|
||||
|
||||
// pricing metric
|
||||
K8S_POD_METRIC_NAMESPACE = "insights.container/pods"
|
||||
)
|
||||
|
||||
var azureMetricSpecs = map[string][]string{
|
||||
MetricKeyPercentageCPU: {common.DEFAULT_STATISTICS, common.UNIT_PERCENT, common.INFLUXDB_FIELD_CPU_USAGE},
|
||||
MetricKeyNetworkInTotal: {common.DEFAULT_STATISTICS, common.UNIT_MEM, common.INFLUXDB_FIELD_NET_BPS_RX},
|
||||
MetricKeyNetworkOutTotal: {common.DEFAULT_STATISTICS, common.UNIT_MEM, common.INFLUXDB_FIELD_NET_BPS_TX},
|
||||
MetricKeyDiskReadBytes: {common.DEFAULT_STATISTICS, common.UNIT_MEM, common.INFLUXDB_FIELD_DISK_READ_BPS},
|
||||
MetricKeyDiskWriteBytes: {common.DEFAULT_STATISTICS, common.UNIT_MEM, common.INFLUXDB_FIELD_DISK_WRITE_BPS},
|
||||
MetricKeyDiskReadOPS: {common.DEFAULT_STATISTICS, common.UNIT_COUNT_SEC, common.INFLUXDB_FIELD_DISK_READ_IOPS},
|
||||
MetricKeyDiskWriteOPS: {common.DEFAULT_STATISTICS, common.UNIT_COUNT_SEC, common.INFLUXDB_FIELD_DISK_WRITE_IOPS},
|
||||
}
|
||||
|
||||
var azureClassicMetricsSpec = map[string][]string{
|
||||
MetricKeyPercentageCPU: {common.DEFAULT_STATISTICS, common.UNIT_PERCENT, common.INFLUXDB_FIELD_CPU_USAGE},
|
||||
MetricKeyClassicNetworkIn: {common.DEFAULT_STATISTICS, common.UNIT_MEM, common.INFLUXDB_FIELD_NET_BPS_RX},
|
||||
MetricKeyClassicNetworkOut: {common.DEFAULT_STATISTICS, common.UNIT_MEM, common.INFLUXDB_FIELD_NET_BPS_TX},
|
||||
MetricKeyClassicDiskReadBPS: {common.DEFAULT_STATISTICS, common.UNIT_MEM, common.INFLUXDB_FIELD_DISK_READ_BPS},
|
||||
MetricKeyClassicDiskWriteBPS: {common.DEFAULT_STATISTICS, common.UNIT_MEM, common.INFLUXDB_FIELD_DISK_WRITE_BPS},
|
||||
MetricKeyDiskReadOPS: {common.DEFAULT_STATISTICS, common.UNIT_COUNT_SEC, common.INFLUXDB_FIELD_DISK_READ_IOPS},
|
||||
MetricKeyDiskWriteOPS: {common.DEFAULT_STATISTICS, common.UNIT_COUNT_SEC, common.INFLUXDB_FIELD_DISK_WRITE_IOPS},
|
||||
}
|
||||
|
||||
var azureRedisMetricsSpec = map[string][]string{
|
||||
"percentProcessorTime": {common.DEFAULT_STATISTICS, common.UNIT_PERCENT, common.INFLUXDB_FIELD_REDIS_CPU_USAGE},
|
||||
"usedmemorypercentage": {common.DEFAULT_STATISTICS, common.UNIT_PERCENT, common.INFLUXDB_FIELD_REDIS_MEM_USAGE},
|
||||
"connectedclients": {common.DEFAULT_STATISTICS, common.UNIT_COUNT, common.INFLUXDB_FIFLD_REDIS_CONN_USAGE},
|
||||
"operationsPerSecond": {common.DEFAULT_STATISTICS, common.UNIT_COUNT, common.INFLUXDB_FIFLD_REDIS_OPT_SES},
|
||||
"alltotalkeys": {common.DEFAULT_STATISTICS, common.UNIT_COUNT, common.INFLUXDB_FIFLD_REDIS_CACHE_KEYS},
|
||||
"expiredkeys": {common.DEFAULT_STATISTICS, common.UNIT_COUNT, common.INFLUXDB_FIFLD_REDIS_CACHE_EXP_KEYS},
|
||||
"usedmemory": {common.DEFAULT_STATISTICS, common.UNIT_BYTES, common.INFLUXDB_FIFLD_REDIS_DATA_MEM_USAGE},
|
||||
"serverLoad": {common.DEFAULT_STATISTICS, common.UNIT_PERCENT, common.INFLUXDB_FIFLD_REDIS_SERVER_LOAD},
|
||||
"errors": {common.DEFAULT_STATISTICS, common.UNIT_PERCENT, common.INFLUXDB_FIFLD_REDIS_CONN_ERRORS},
|
||||
}
|
||||
|
||||
//mariadb,mysql,postgresql
|
||||
var azureRdsMetricsSpec = map[string][]string{
|
||||
"cpu_percent": {common.DEFAULT_STATISTICS, common.UNIT_PERCENT, common.INFLUXDB_FIELD_RDS_CPU_USAGE},
|
||||
"memory_percent": {common.DEFAULT_STATISTICS, common.UNIT_PERCENT, common.INFLUXDB_FIELD_RDS_MEM_USAGE},
|
||||
"storage_percent": {common.DEFAULT_STATISTICS, common.UNIT_PERCENT, common.INFLUXDB_FIELD_RDS_DISK_USAGE},
|
||||
"network_bytes_ingress": {common.DEFAULT_STATISTICS, common.UNIT_BYTES, common.INFLUXDB_FIELD_RDS_NET_BPS_RX},
|
||||
"network_bytes_egress": {common.DEFAULT_STATISTICS, common.UNIT_BYTES, common.INFLUXDB_FIELD_RDS_NET_BPS_TX},
|
||||
"io_consumption_percent": {common.DEFAULT_STATISTICS, common.UNIT_PERCENT, common.INFLUXDB_FIELD_RDS_DISK_IO_PERSENT},
|
||||
"connections_failed": {common.DEFAULT_STATISTICS, common.UNIT_COUNT, common.INFLUXDB_FIELD_RDS_CONN_FAILED},
|
||||
"active_connections": {common.DEFAULT_STATISTICS, common.UNIT_COUNT, common.INFLUXDB_FIELD_RDS_CONN_ACTIVE},
|
||||
}
|
||||
|
||||
var azureRdsMetricsSpecSqlserver = map[string][]string{
|
||||
"cpu_percent": {common.DEFAULT_STATISTICS, common.UNIT_PERCENT, common.INFLUXDB_FIELD_RDS_CPU_USAGE},
|
||||
"sqlserver_process_memory_percent": {common.DEFAULT_STATISTICS, common.UNIT_PERCENT, common.INFLUXDB_FIELD_RDS_MEM_USAGE},
|
||||
"storage_percent": {common.DEFAULT_STATISTICS, common.UNIT_PERCENT, common.INFLUXDB_FIELD_RDS_DISK_USAGE},
|
||||
"connection_failed": {common.DEFAULT_STATISTICS, common.UNIT_COUNT, common.INFLUXDB_FIELD_RDS_CONN_FAILED},
|
||||
}
|
||||
|
||||
var azureElbMetricSpecs = map[string][]string{
|
||||
"SnatConnectionCount": {common.DEFAULT_STATISTICS, common.UNIT_COUNT, common.INFLUXDB_FIELD_ELB_SNAT_PORT},
|
||||
"UsedSnatPorts": {common.DEFAULT_STATISTICS, common.UNIT_COUNT, common.INFLUXDB_FIELD_ELB_SNAT_CONN_COUNT},
|
||||
}
|
||||
|
||||
// insights.container/pods
|
||||
var azureK8SPodMetricSpecs = map[string][]string{
|
||||
"oomKilledContainerCount": {common.DEFAULT_STATISTICS, common.UNIT_COUNT, common.INFLUXDB_FIELD_K8S_POD_OOM_CONTAINER_COUNT},
|
||||
"restartingContainerCount": {common.DEFAULT_STATISTICS, common.UNIT_COUNT, common.INFLUXDB_FIELD_K8S_POD_RESTARTING_CONTAINER_COUNT},
|
||||
}
|
||||
|
||||
// Microsoft.ContainerService/managedClusters
|
||||
var azureK8SNodeMetricSpecs = map[string][]string{
|
||||
"node_cpu_usage_percentage": {common.DEFAULT_STATISTICS, common.UNIT_PERCENT, common.INFLUXDB_FIELD_K8S_NODE_CPU_USAGE},
|
||||
"node_memory_rss_percentage": {common.DEFAULT_STATISTICS, common.UNIT_PERCENT, common.INFLUXDB_FIELD_K8S_NODE_MEM_USAGE},
|
||||
//磁盘已用百分比
|
||||
"node_disk_usage_percentage": {common.DEFAULT_STATISTICS, common.UNIT_PERCENT, common.INFLUXDB_FIELD_K8S_NODE_DISK_USAGE},
|
||||
"node_network_in_bytes": {common.DEFAULT_STATISTICS, common.UNIT_BYTEPS, common.INFLUXDB_FIELD_K8S_NODE_NET_BPS_RX},
|
||||
"node_network_out_bytes": {common.DEFAULT_STATISTICS, common.UNIT_BYTEPS, common.INFLUXDB_FIELD_K8S_NODE_NET_BPS_TX},
|
||||
}
|
||||
|
||||
// insights.container/persistentvolumes
|
||||
@@ -1,15 +0,0 @@
|
||||
// Copyright 2019 Yunion
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package azuremon // import "yunion.io/x/onecloud/pkg/cloudmon/collectors/azuremon"
|
||||
@@ -1,34 +0,0 @@
|
||||
// Copyright 2019 Yunion
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package bingomon
|
||||
|
||||
import "yunion.io/x/onecloud/pkg/cloudmon/collectors/common"
|
||||
|
||||
const (
|
||||
SERVER_METRIC_NAMESPACE = "AWS/EC2"
|
||||
HOST_METRIC_NAMESPACE = "AWS/HOST"
|
||||
)
|
||||
|
||||
//multiCloud查询指标列表组装
|
||||
var bingoMetricSpecs = map[string][]string{
|
||||
"CPUUtilization": {common.DEFAULT_STATISTICS, common.UNIT_PERCENT, common.INFLUXDB_FIELD_CPU_USAGE},
|
||||
"MemeryUsage": {common.DEFAULT_STATISTICS, common.UNIT_PERCENT, common.INFLUXDB_FIELD_MEM_USAGE},
|
||||
"NetworkIn": {common.DEFAULT_STATISTICS, common.UNIT_BYTEPS, common.INFLUXDB_FIELD_NET_BPS_RX},
|
||||
"NetworkOut": {common.DEFAULT_STATISTICS, common.UNIT_BYTEPS, common.INFLUXDB_FIELD_NET_BPS_TX},
|
||||
"DiskReadBytes": {common.DEFAULT_STATISTICS, common.UNIT_BYTEPS, common.INFLUXDB_FIELD_DISK_READ_BPS},
|
||||
"DiskWriteBytes": {common.DEFAULT_STATISTICS, common.UNIT_BYTEPS, common.INFLUXDB_FIELD_DISK_WRITE_BPS},
|
||||
"DiskReadOps": {common.DEFAULT_STATISTICS, common.UNIT_CPS, common.INFLUXDB_FIELD_DISK_READ_IOPS},
|
||||
"DiskWriteOps": {common.DEFAULT_STATISTICS, common.UNIT_CPS, common.INFLUXDB_FIELD_DISK_WRITE_IOPS},
|
||||
}
|
||||
@@ -1,82 +0,0 @@
|
||||
// Copyright 2019 Yunion
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package bingomon
|
||||
|
||||
import (
|
||||
"yunion.io/x/jsonutils"
|
||||
|
||||
"yunion.io/x/onecloud/pkg/apis/compute"
|
||||
"yunion.io/x/onecloud/pkg/cloudmon/collectors/common"
|
||||
"yunion.io/x/onecloud/pkg/cloudmon/options"
|
||||
"yunion.io/x/onecloud/pkg/mcclient"
|
||||
)
|
||||
|
||||
func init() {
|
||||
factory := SBingoCloudReportFactory{}
|
||||
common.RegisterFactory(&factory)
|
||||
}
|
||||
|
||||
type SBingoCloudReportFactory struct {
|
||||
common.CommonReportFactory
|
||||
}
|
||||
|
||||
func (self *SBingoCloudReportFactory) NewCloudReport(provider *common.SProvider, session *mcclient.ClientSession,
|
||||
args *options.ReportOptions, operatorType string) common.ICloudReport {
|
||||
return &SBingoCloudReport{
|
||||
common.CloudReportBase{
|
||||
SProvider: provider,
|
||||
Session: session,
|
||||
Args: args,
|
||||
Operator: operatorType,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func (self *SBingoCloudReportFactory) GetId() string {
|
||||
return compute.CLOUD_PROVIDER_BINGO_CLOUD
|
||||
}
|
||||
|
||||
type SBingoCloudReport struct {
|
||||
common.CloudReportBase
|
||||
}
|
||||
|
||||
func (self *SBingoCloudReport) Report() error {
|
||||
var servers []jsonutils.JSONObject
|
||||
var err error
|
||||
|
||||
servers, err = self.GetResourceByOperator()
|
||||
|
||||
providerInstance, err := self.InitProviderInstance()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
regionList, regionServerMap, err := self.GetAllRegionOfServers(servers, providerInstance)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
for _, region := range regionList {
|
||||
servers := regionServerMap[region.GetGlobalId()]
|
||||
switch common.MonType(self.Operator) {
|
||||
case common.SERVER:
|
||||
err = self.collectRegionMetricOfResource(region, servers)
|
||||
case common.HOST:
|
||||
err = self.collectRegionMetricOfResource(region, servers)
|
||||
}
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
@@ -1,171 +0,0 @@
|
||||
// Copyright 2019 Yunion
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package bingomon
|
||||
|
||||
import (
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"yunion.io/x/jsonutils"
|
||||
"yunion.io/x/log"
|
||||
"yunion.io/x/pkg/errors"
|
||||
|
||||
"yunion.io/x/onecloud/pkg/cloudmon/collectors/common"
|
||||
"yunion.io/x/onecloud/pkg/cloudprovider"
|
||||
"yunion.io/x/onecloud/pkg/multicloud/bingocloud"
|
||||
"yunion.io/x/onecloud/pkg/util/influxdb"
|
||||
)
|
||||
|
||||
func (self *SBingoCloudReport) collectRegionMetricOfResource(region cloudprovider.ICloudRegion, servers []jsonutils.JSONObject) error {
|
||||
dataList := make([]influxdb.SMetricData, 0)
|
||||
bingoReg := region.(*bingocloud.SRegion)
|
||||
since, until, err := common.TimeRangeFromArgs(self.Args)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
namespace, metrics := self.getMetricSpecs(servers)
|
||||
dimensionId := self.getDimensionId()
|
||||
if dimensionId == nil {
|
||||
return errors.Errorf("can not get BingoCloudReport getDimensionId")
|
||||
}
|
||||
|
||||
for metricName, influxDbSpecs := range metrics {
|
||||
for _, server := range servers {
|
||||
external_id, _ := server.GetString(dimensionId.LocalId)
|
||||
if len(external_id) == 0 {
|
||||
continue
|
||||
}
|
||||
name, _ := server.GetString("name")
|
||||
dimension := bingocloud.Dimension{
|
||||
Name: dimensionId.ExtId,
|
||||
Value: external_id,
|
||||
}
|
||||
rtnMetric, err := bingoReg.DescribeMetricList(dimension, namespace, metricName, since,
|
||||
until, "")
|
||||
if err != nil {
|
||||
log.Errorln(err)
|
||||
continue
|
||||
}
|
||||
if rtnMetric != nil {
|
||||
serverMetric, err := self.collectMetricFromThisServer(server, *rtnMetric, influxDbSpecs)
|
||||
if err != nil {
|
||||
log.Errorf("provider: %s,metric: %s collectMetricFromThisServer: %s, err: %#v", self.SProvider.Name,
|
||||
metricName, name, err)
|
||||
continue
|
||||
}
|
||||
dataList = append(dataList, serverMetric...)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
return common.SendMetrics(self.Session, dataList, self.Args.Debug, "")
|
||||
}
|
||||
|
||||
func (self *SBingoCloudReport) collectMetricFromThisServer(server jsonutils.JSONObject, rtnMetric bingocloud.GetMetricStatisticsOutput,
|
||||
influxDbSpecs []string) ([]influxdb.SMetricData, error) {
|
||||
datas := make([]influxdb.SMetricData, 0)
|
||||
for _, point := range rtnMetric.Datapoints.Member {
|
||||
metric, err := self.NewMetricFromJson(server)
|
||||
//metric, err := common.JsonToMetric(server.(*jsonutils.JSONDict), "", common.ServerTags, make([]string, 0))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
metric.Timestamp = *point.Timestamp
|
||||
//根据条件拼装metric的tag和metirc信息
|
||||
influxDbSpec := influxDbSpecs[2]
|
||||
var pairsKey string
|
||||
if strings.Contains(influxDbSpec, ",") {
|
||||
pairsKey = common.SubstringBetween(influxDbSpec, ".", ",")
|
||||
} else {
|
||||
pairsKey = common.SubstringAfter(influxDbSpec, ".")
|
||||
}
|
||||
fieldValue := *point.Average
|
||||
if influxDbSpecs[1] == common.UNIT_BYTEPS && strings.Contains(pairsKey, common.UNIT_BPS) {
|
||||
fieldValue = fieldValue * 8
|
||||
}
|
||||
|
||||
measurement := self.getMeasurement(influxDbSpec)
|
||||
tag := common.SubstringAfter(influxDbSpec, ",")
|
||||
if tag != "" && strings.Contains(influxDbSpec, "=") {
|
||||
metric.Tags = append(metric.Tags, influxdb.SKeyValue{
|
||||
Key: common.SubstringBefore(tag, "="),
|
||||
Value: common.SubstringAfter(tag, "="),
|
||||
})
|
||||
}
|
||||
metric.Metrics = append(metric.Metrics, influxdb.SKeyValue{
|
||||
Key: pairsKey,
|
||||
Value: strconv.FormatFloat(fieldValue, 'E', -1, 64),
|
||||
})
|
||||
metric.Name = measurement
|
||||
datas = append(datas, metric)
|
||||
}
|
||||
|
||||
return datas, nil
|
||||
}
|
||||
|
||||
func (self *SBingoCloudReport) getMetricSpecs(res []jsonutils.JSONObject) (string, map[string][]string) {
|
||||
switch common.MonType(self.Operator) {
|
||||
case common.SERVER:
|
||||
return SERVER_METRIC_NAMESPACE, bingoMetricSpecs
|
||||
case common.HOST:
|
||||
return HOST_METRIC_NAMESPACE, bingoMetricSpecs
|
||||
}
|
||||
return "", map[string][]string{}
|
||||
}
|
||||
|
||||
func (self *SBingoCloudReport) getMeasurement(influxDbSpec string) (measurement string) {
|
||||
switch common.MonType(self.Operator) {
|
||||
case common.HOST:
|
||||
measurement = common.SubstringBetween(influxDbSpec, "vm_", ".")
|
||||
if strings.Contains(influxDbSpec, "vm_netio") {
|
||||
measurement = "net"
|
||||
}
|
||||
default:
|
||||
measurement = common.SubstringBefore(influxDbSpec, ".")
|
||||
}
|
||||
return measurement
|
||||
}
|
||||
|
||||
func (self *SBingoCloudReport) getDataPointValue(valueKey string, influxDbSpecs []string, rtnMetric jsonutils.JSONObject) (float64, error) {
|
||||
key := common.UNIT_AVERAGE
|
||||
switch common.MonType(self.Operator) {
|
||||
case common.OSS:
|
||||
key = valueKey
|
||||
case common.K8S:
|
||||
key = "Value"
|
||||
}
|
||||
fieldValue, err := rtnMetric.Float(key)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
return fieldValue, nil
|
||||
}
|
||||
|
||||
func (self *SBingoCloudReport) getDimensionId() *common.DimensionId {
|
||||
switch common.MonType(self.Operator) {
|
||||
case common.SERVER:
|
||||
return &common.DimensionId{
|
||||
LocalId: "external_id",
|
||||
ExtId: "InstanceId",
|
||||
}
|
||||
case common.HOST:
|
||||
return &common.DimensionId{
|
||||
LocalId: "access_ip",
|
||||
ExtId: "HostId",
|
||||
}
|
||||
|
||||
}
|
||||
return nil
|
||||
}
|
||||
@@ -1 +0,0 @@
|
||||
package bingomon // import "yunion.io/x/onecloud/pkg/cloudmon/collectors/bingomon"
|
||||
@@ -1,88 +0,0 @@
|
||||
// Copyright 2019 Yunion
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package collectors
|
||||
|
||||
import (
|
||||
"yunion.io/x/jsonutils"
|
||||
"yunion.io/x/pkg/errors"
|
||||
|
||||
"yunion.io/x/onecloud/pkg/mcclient"
|
||||
modules "yunion.io/x/onecloud/pkg/mcclient/modules/compute"
|
||||
"yunion.io/x/onecloud/pkg/util/influxdb"
|
||||
"yunion.io/x/onecloud/pkg/util/shellutils"
|
||||
)
|
||||
|
||||
type BucketStatsOptions struct {
|
||||
Debug bool `help:"debug"`
|
||||
}
|
||||
|
||||
func bucketStatsCollect(s *mcclient.ClientSession, args *BucketStatsOptions) error {
|
||||
metrics := make([]influxdb.SMetricData, 0)
|
||||
listAll(s, modules.Buckets.List, nil,
|
||||
func(data jsonutils.JSONObject) error {
|
||||
m, err := collectBucket(s, data)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
metrics = append(metrics, m)
|
||||
return nil
|
||||
},
|
||||
)
|
||||
return sendMetrics(s, metrics, args.Debug)
|
||||
}
|
||||
|
||||
func collectBucket(s *mcclient.ClientSession, bucket jsonutils.JSONObject) (influxdb.SMetricData, error) {
|
||||
metric := influxdb.SMetricData{}
|
||||
bucketId, _ := bucket.GetString("id")
|
||||
if len(bucketId) == 0 {
|
||||
return metric, errors.Error("empty bucket id")
|
||||
}
|
||||
params := jsonutils.NewDict()
|
||||
params.Set("stats_only", jsonutils.JSONTrue)
|
||||
result, err := modules.Buckets.PerformAction(s, bucketId, "sync", params)
|
||||
if err != nil {
|
||||
return metric, errors.Wrap(err, "PerformAction")
|
||||
}
|
||||
return jsonToMetric(result.(*jsonutils.JSONDict), "bucket",
|
||||
[]string{
|
||||
"name",
|
||||
"id",
|
||||
"account",
|
||||
"account_id",
|
||||
"manager",
|
||||
"manager_id",
|
||||
"manager_domain",
|
||||
"manager_domain_id",
|
||||
"manager_project",
|
||||
"manager_project_id",
|
||||
"brand",
|
||||
"provider",
|
||||
"region_id",
|
||||
"region_ext_id",
|
||||
"tenant",
|
||||
"tenant_id",
|
||||
"domain_id",
|
||||
"project_domain",
|
||||
},
|
||||
[]string{
|
||||
"object_cnt",
|
||||
"size_bytes",
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
func init() {
|
||||
shellutils.R(&BucketStatsOptions{}, "buckets", "Bucket stats", bucketStatsCollect)
|
||||
}
|
||||
@@ -1,60 +0,0 @@
|
||||
// Copyright 2019 Yunion
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package cloudaccountmon
|
||||
|
||||
import (
|
||||
"yunion.io/x/onecloud/pkg/cloudmon/collectors/common"
|
||||
"yunion.io/x/onecloud/pkg/cloudmon/options"
|
||||
"yunion.io/x/onecloud/pkg/mcclient"
|
||||
modules "yunion.io/x/onecloud/pkg/mcclient/modules/compute"
|
||||
)
|
||||
|
||||
func init() {
|
||||
factory := SCloudAccountFactory{}
|
||||
common.RegisterFactory(&factory)
|
||||
}
|
||||
|
||||
type SCloudAccountFactory struct {
|
||||
common.CommonReportFactory
|
||||
}
|
||||
|
||||
func (self *SCloudAccountFactory) NewCloudReport(provider *common.SProvider, session *mcclient.ClientSession,
|
||||
args *options.ReportOptions,
|
||||
operatorType string) common.ICloudReport {
|
||||
return &SCloudAccountReport{
|
||||
common.CloudReportBase{
|
||||
SProvider: nil,
|
||||
Session: session,
|
||||
Args: args,
|
||||
Operator: ClOUDACCOUNT_ID,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func (S SCloudAccountFactory) GetId() string {
|
||||
return ClOUDACCOUNT_ID
|
||||
}
|
||||
|
||||
type SCloudAccountReport struct {
|
||||
common.CloudReportBase
|
||||
}
|
||||
|
||||
func (self *SCloudAccountReport) Report() error {
|
||||
accounts, err := self.GetAllCloudAccount(&modules.Cloudaccounts)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return self.collectMetric(accounts)
|
||||
}
|
||||
@@ -1,38 +0,0 @@
|
||||
// Copyright 2019 Yunion
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package cloudaccountmon
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
"yunion.io/x/jsonutils"
|
||||
|
||||
"yunion.io/x/onecloud/pkg/cloudmon/collectors/common"
|
||||
"yunion.io/x/onecloud/pkg/util/influxdb"
|
||||
)
|
||||
|
||||
func (self *SCloudAccountReport) collectMetric(accounts []jsonutils.JSONObject) error {
|
||||
dataList := make([]influxdb.SMetricData, 0)
|
||||
for _, account := range accounts {
|
||||
metric, err := self.NewMetricFromJson(account)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
metric.Timestamp = time.Now()
|
||||
metric.Name = CLOUDACCOUNT_MEASUREMENT
|
||||
dataList = append(dataList, metric)
|
||||
}
|
||||
return common.SendMetrics(self.Session, dataList, self.Args.Debug, CLOUDACCOUNT_DATABASE)
|
||||
}
|
||||
@@ -1,15 +0,0 @@
|
||||
// Copyright 2019 Yunion
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package cloudaccountmon // import "yunion.io/x/onecloud/pkg/cloudmon/collectors/cloudaccountmon"
|
||||
@@ -1,45 +0,0 @@
|
||||
// Copyright 2019 Yunion
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package collectors
|
||||
|
||||
import (
|
||||
_ "yunion.io/x/onecloud/pkg/cloudmon/collectors/alertrecordhistorymon"
|
||||
_ "yunion.io/x/onecloud/pkg/cloudmon/collectors/alimon"
|
||||
_ "yunion.io/x/onecloud/pkg/cloudmon/collectors/apsaramon"
|
||||
_ "yunion.io/x/onecloud/pkg/cloudmon/collectors/awsmon"
|
||||
_ "yunion.io/x/onecloud/pkg/cloudmon/collectors/azuremon"
|
||||
_ "yunion.io/x/onecloud/pkg/cloudmon/collectors/bingomon"
|
||||
_ "yunion.io/x/onecloud/pkg/cloudmon/collectors/cloudaccountmon"
|
||||
_ "yunion.io/x/onecloud/pkg/cloudmon/collectors/gcpmon"
|
||||
_ "yunion.io/x/onecloud/pkg/cloudmon/collectors/huaweimon"
|
||||
_ "yunion.io/x/onecloud/pkg/cloudmon/collectors/jdmon"
|
||||
_ "yunion.io/x/onecloud/pkg/cloudmon/collectors/qcmon"
|
||||
_ "yunion.io/x/onecloud/pkg/cloudmon/collectors/storagemon"
|
||||
_ "yunion.io/x/onecloud/pkg/cloudmon/collectors/vmwaremon"
|
||||
_ "yunion.io/x/onecloud/pkg/cloudmon/collectors/zstackmon"
|
||||
_ "yunion.io/x/onecloud/pkg/multicloud/aliyun/provider"
|
||||
_ "yunion.io/x/onecloud/pkg/multicloud/apsara/provider"
|
||||
_ "yunion.io/x/onecloud/pkg/multicloud/aws/provider"
|
||||
_ "yunion.io/x/onecloud/pkg/multicloud/azure/provider"
|
||||
_ "yunion.io/x/onecloud/pkg/multicloud/bingocloud/provider"
|
||||
_ "yunion.io/x/onecloud/pkg/multicloud/esxi/provider"
|
||||
_ "yunion.io/x/onecloud/pkg/multicloud/google/provider"
|
||||
_ "yunion.io/x/onecloud/pkg/multicloud/hcso/provider"
|
||||
_ "yunion.io/x/onecloud/pkg/multicloud/huawei/provider"
|
||||
_ "yunion.io/x/onecloud/pkg/multicloud/jdcloud/provider"
|
||||
_ "yunion.io/x/onecloud/pkg/multicloud/qcloud/provider"
|
||||
_ "yunion.io/x/onecloud/pkg/multicloud/zstack/provider"
|
||||
// pingprobe default init
|
||||
)
|
||||
@@ -1,351 +0,0 @@
|
||||
// Copyright 2019 Yunion
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package common
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"time"
|
||||
|
||||
"golang.org/x/net/http/httpproxy"
|
||||
|
||||
"yunion.io/x/jsonutils"
|
||||
"yunion.io/x/log"
|
||||
"yunion.io/x/pkg/errors"
|
||||
"yunion.io/x/pkg/utils"
|
||||
|
||||
"yunion.io/x/onecloud/pkg/apis/compute"
|
||||
"yunion.io/x/onecloud/pkg/cloudmon/options"
|
||||
"yunion.io/x/onecloud/pkg/cloudprovider"
|
||||
"yunion.io/x/onecloud/pkg/mcclient"
|
||||
"yunion.io/x/onecloud/pkg/mcclient/modulebase"
|
||||
modules "yunion.io/x/onecloud/pkg/mcclient/modules/compute"
|
||||
k8s_modules "yunion.io/x/onecloud/pkg/mcclient/modules/k8s"
|
||||
"yunion.io/x/onecloud/pkg/util/httputils"
|
||||
"yunion.io/x/onecloud/pkg/util/influxdb"
|
||||
)
|
||||
|
||||
type CloudReportBase struct {
|
||||
SProvider *SProvider
|
||||
Session *mcclient.ClientSession
|
||||
Args *options.ReportOptions
|
||||
Operator string
|
||||
Impl ICloudReportK8s
|
||||
}
|
||||
|
||||
func (self *CloudReportBase) Report() error {
|
||||
return fmt.Errorf("No Implment the method")
|
||||
}
|
||||
|
||||
func (self *CloudReportBase) GetResourceByOperator() ([]jsonutils.JSONObject, error) {
|
||||
var servers []jsonutils.JSONObject
|
||||
var err error
|
||||
switch MonType(self.Operator) {
|
||||
case REDIS:
|
||||
servers, err = self.GetAllserverOfThisProvider(&modules.ElasticCache, nil)
|
||||
case RDS:
|
||||
servers, err = self.GetAllserverOfThisProvider(&modules.DBInstance, nil)
|
||||
case OSS:
|
||||
servers, err = self.GetAllserverOfThisProvider(&modules.Buckets, nil)
|
||||
case ELB:
|
||||
query := jsonutils.NewDict()
|
||||
query.Add(jsonutils.NewString("0"), KEY_LIMIT)
|
||||
query.Add(jsonutils.NewString("true"), KEY_ADMIN)
|
||||
query.Add(jsonutils.NewString(self.SProvider.Provider), "provider")
|
||||
query.Add(jsonutils.NewString(self.SProvider.Id), "manager")
|
||||
servers, err = self.GetAllserverOfThisProvider(&modules.Loadbalancers, query)
|
||||
case K8S:
|
||||
query := jsonutils.NewDict()
|
||||
query.Add(jsonutils.NewString("0"), KEY_LIMIT)
|
||||
query.Add(jsonutils.NewString("true"), KEY_ADMIN)
|
||||
query.Add(jsonutils.NewString(self.SProvider.Provider), "provider")
|
||||
query.Add(jsonutils.NewString(self.SProvider.Id), "manager")
|
||||
servers, err = self.GetAllserverOfThisProvider(k8s_modules.KubeClusters, query)
|
||||
case SERVER:
|
||||
servers, err = self.GetAllserverOfThisProvider(&modules.Servers, nil)
|
||||
default:
|
||||
return []jsonutils.JSONObject{}, nil
|
||||
}
|
||||
return servers, err
|
||||
}
|
||||
|
||||
func (self *CloudReportBase) GetAllserverOfThisProvider(manager modulebase.Manager, query *jsonutils.JSONDict) ([]jsonutils.JSONObject, error) {
|
||||
if query == nil {
|
||||
query = jsonutils.NewDict()
|
||||
query.Add(jsonutils.NewStringArray([]string{"running", "ready"}), "status")
|
||||
query.Add(jsonutils.NewString("0"), KEY_LIMIT)
|
||||
query.Add(jsonutils.NewString("true"), KEY_ADMIN)
|
||||
query.Add(jsonutils.NewString(self.SProvider.Provider), "provider")
|
||||
query.Add(jsonutils.NewString(self.SProvider.Id), "manager")
|
||||
}
|
||||
return self.ListAllResources(manager, query)
|
||||
}
|
||||
|
||||
func (self *CloudReportBase) GetAllHostOfThisProvider(manager modulebase.Manager) ([]jsonutils.JSONObject, error) {
|
||||
query := jsonutils.NewDict()
|
||||
query.Add(jsonutils.NewString("running"), "status")
|
||||
query.Add(jsonutils.NewString("0"), KEY_LIMIT)
|
||||
query.Add(jsonutils.NewString("true"), KEY_ADMIN)
|
||||
query.Add(jsonutils.NewString(self.SProvider.Provider), "provider")
|
||||
query.Add(jsonutils.NewString(self.SProvider.Id), "manager")
|
||||
return self.ListAllResources(manager, query)
|
||||
}
|
||||
|
||||
func (self *CloudReportBase) GetAllCloudAccount(manager modulebase.Manager) ([]jsonutils.JSONObject, error) {
|
||||
query := jsonutils.NewDict()
|
||||
query.Add(jsonutils.NewString("0"), KEY_LIMIT)
|
||||
query.Add(jsonutils.NewBool(true), DETAILS)
|
||||
query.Add(jsonutils.NewString("true"), KEY_ADMIN)
|
||||
query.Add(jsonutils.NewString(fmt.Sprintf("brand.in(%s,%s,%s,%s)", compute.CLOUD_PROVIDER_ALIYUN,
|
||||
compute.CLOUD_PROVIDER_QCLOUD, compute.CLOUD_PROVIDER_HUAWEI, compute.CLOUD_PROVIDER_JDCLOUD)), "filter")
|
||||
return self.ListAllResources(manager, query)
|
||||
}
|
||||
|
||||
func (self *CloudReportBase) GetAllStorage(manager modulebase.Manager) ([]jsonutils.JSONObject, error) {
|
||||
query := jsonutils.NewDict()
|
||||
query.Add(jsonutils.NewString("0"), KEY_LIMIT)
|
||||
query.Add(jsonutils.NewBool(true), DETAILS)
|
||||
query.Add(jsonutils.NewString("system"), KEY_SCOPE)
|
||||
return self.ListAllResources(manager, query)
|
||||
}
|
||||
|
||||
func (self *CloudReportBase) ListAllResource(manager modulebase.Manager,
|
||||
query jsonutils.JSONObject) ([]jsonutils.JSONObject, error) {
|
||||
resources := make([]jsonutils.JSONObject, 0)
|
||||
offsetIndex := 0
|
||||
for {
|
||||
query.(*jsonutils.JSONDict).Add(jsonutils.NewInt(int64(offsetIndex)), "offset")
|
||||
resList, err := manager.List(self.Session, query)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
resources = append(resources, resList.Data...)
|
||||
offsetIndex = offsetIndex + len(resList.Data)
|
||||
if offsetIndex >= resList.Total {
|
||||
break
|
||||
}
|
||||
}
|
||||
return resources, nil
|
||||
}
|
||||
|
||||
func (self *CloudReportBase) InitProviderInstance() (cloudprovider.ICloudProvider, error) {
|
||||
//secret进行Descrypt
|
||||
secretDe, _ := utils.DescryptAESBase64(self.SProvider.Id, self.SProvider.Secret)
|
||||
var proxyFunc httputils.TransportProxyFunc
|
||||
{
|
||||
cfg := &httpproxy.Config{
|
||||
HTTPProxy: self.SProvider.ProxySetting.HTTPProxy,
|
||||
HTTPSProxy: self.SProvider.ProxySetting.HTTPSProxy,
|
||||
NoProxy: self.SProvider.ProxySetting.NoProxy,
|
||||
}
|
||||
cfgProxyFunc := cfg.ProxyFunc()
|
||||
proxyFunc = func(req *http.Request) (*url.URL, error) {
|
||||
return cfgProxyFunc(req.URL)
|
||||
}
|
||||
}
|
||||
cloudAccout, err := self.getCloudAccount(&modules.Cloudaccounts)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "getCloudAccount error")
|
||||
}
|
||||
cfg := cloudprovider.ProviderConfig{
|
||||
Id: self.SProvider.Id,
|
||||
Name: self.SProvider.Name,
|
||||
URL: self.SProvider.AccessUrl,
|
||||
Account: self.SProvider.Account,
|
||||
Secret: secretDe,
|
||||
Vendor: self.SProvider.Provider,
|
||||
ProxyFunc: proxyFunc,
|
||||
}
|
||||
if options, _ := cloudAccout.Get("options"); options != nil {
|
||||
cfg.Options = options.(*jsonutils.JSONDict)
|
||||
defaultRegion, _ := options.GetString("default_region")
|
||||
cfg.DefaultRegion = defaultRegion
|
||||
}
|
||||
return cloudprovider.GetProvider(cfg)
|
||||
}
|
||||
|
||||
func (self *CloudReportBase) getCloudAccount(manager modulebase.Manager) (jsonutils.JSONObject, error) {
|
||||
return self.GetResourceById(self.SProvider.CloudaccountId, manager)
|
||||
}
|
||||
|
||||
func (self *CloudReportBase) GetResourceById(id string, manager modulebase.Manager) (jsonutils.JSONObject, error) {
|
||||
return manager.Get(self.Session, id, jsonutils.NewDict())
|
||||
}
|
||||
|
||||
func (self *CloudReportBase) GetAllRegionOfServers(servers []jsonutils.JSONObject,
|
||||
providerInstance cloudprovider.ICloudProvider) ([]cloudprovider.
|
||||
ICloudRegion, map[string][]jsonutils.JSONObject, error) {
|
||||
extranleIdMap := make(map[string]string)
|
||||
regionServerList := make([]cloudprovider.ICloudRegion, 0)
|
||||
regionServerMap := make(map[string][]jsonutils.JSONObject)
|
||||
for i, server := range servers {
|
||||
region_external_id, err := server.GetString("region_external_id")
|
||||
if err != nil {
|
||||
cloudregionExternalId := self.getCloudregionExternalId(server)
|
||||
if cloudregionExternalId == nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
region_external_id = *cloudregionExternalId
|
||||
}
|
||||
if _, ok := extranleIdMap[region_external_id]; !ok {
|
||||
extranleIdMap[region_external_id] = ""
|
||||
region, err := providerInstance.GetIRegionById(region_external_id)
|
||||
if err != nil {
|
||||
name, _ := server.GetString("name")
|
||||
log.Errorf("name:%s,region_external_id:%s,err:%v", name, region_external_id, err)
|
||||
continue
|
||||
}
|
||||
regionServerList = append(regionServerList, region)
|
||||
regionServers := make([]jsonutils.JSONObject, 0)
|
||||
regionServers = append(regionServers, servers[i])
|
||||
regionServerMap[region_external_id] = regionServers
|
||||
} else {
|
||||
regionservers := regionServerMap[region_external_id]
|
||||
regionservers = append(regionservers, server)
|
||||
regionServerMap[region_external_id] = regionservers
|
||||
}
|
||||
}
|
||||
return regionServerList, regionServerMap, nil
|
||||
}
|
||||
|
||||
func (self *CloudReportBase) getCloudregionExternalId(res jsonutils.JSONObject) *string {
|
||||
cloudregionId, _ := res.GetString("cloudregion_id")
|
||||
cloudregion, err := self.GetResourceById(cloudregionId, &modules.Cloudregions)
|
||||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
external_id, _ := cloudregion.GetString("external_id")
|
||||
return &external_id
|
||||
}
|
||||
|
||||
func (self *CloudReportBase) AddMetricTag(metric *influxdb.SMetricData, tags map[string]string) {
|
||||
for key, value := range tags {
|
||||
metric.Tags = append(metric.Tags, influxdb.SKeyValue{
|
||||
Key: key,
|
||||
Value: value,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func (self *CloudReportBase) NewMetricFromJson(server jsonutils.JSONObject) (influxdb.SMetricData, error) {
|
||||
switch MonType(self.Operator) {
|
||||
case SERVER:
|
||||
metric, err := JsonToMetric(server.(*jsonutils.JSONDict), "", ServerTags, make([]string, 0))
|
||||
if err != nil {
|
||||
return metric, err
|
||||
}
|
||||
self.AddMetricTag(&metric, OtherVmTags)
|
||||
return metric, nil
|
||||
case HOST:
|
||||
return JsonToMetric(server.(*jsonutils.JSONDict), "", HostTags, make([]string, 0))
|
||||
case REDIS:
|
||||
return JsonToMetric(server.(*jsonutils.JSONDict), "", RedisTags, make([]string, 0))
|
||||
case RDS:
|
||||
return JsonToMetric(server.(*jsonutils.JSONDict), "", RdsTags, make([]string, 0))
|
||||
case OSS:
|
||||
return JsonToMetric(server.(*jsonutils.JSONDict), "", OssTags, make([]string, 0))
|
||||
case ELB:
|
||||
return JsonToMetric(server.(*jsonutils.JSONDict), "", ElbTags, make([]string, 0))
|
||||
case CLOUDACCOUNT:
|
||||
return JsonToMetric(server.(*jsonutils.JSONDict), "", CloudAccountTags, CloudAccountFields)
|
||||
case STORAGE:
|
||||
return JsonToMetric(server.(*jsonutils.JSONDict), "", StorageTags, make([]string, 0))
|
||||
case ALERT_RECORD:
|
||||
return JsonToMetric(server.(*jsonutils.JSONDict), "", AlertRecordHistoryTags, AlertRecordHistoryFields)
|
||||
case K8S:
|
||||
return JsonToMetric(server.(*jsonutils.JSONDict), "", K8sTags, make([]string, 0))
|
||||
}
|
||||
return influxdb.SMetricData{}, fmt.Errorf("no found report operator")
|
||||
}
|
||||
|
||||
func (self *CloudReportBase) CollectRegionMetric(region cloudprovider.ICloudRegion,
|
||||
servers []jsonutils.JSONObject) error {
|
||||
panic("NO implement CollectRegionMetricOfServer")
|
||||
}
|
||||
|
||||
func (self *CloudReportBase) ListAllResources(manager modulebase.Manager,
|
||||
query *jsonutils.JSONDict) ([]jsonutils.JSONObject, error) {
|
||||
|
||||
return ListAllResources(manager, self.Session, query)
|
||||
}
|
||||
|
||||
func ListAllResources(manager modulebase.Manager, session *mcclient.ClientSession,
|
||||
query *jsonutils.JSONDict) ([]jsonutils.JSONObject, error) {
|
||||
offsetIndex := 0
|
||||
resources := make([]jsonutils.JSONObject, 0)
|
||||
tryTimes := 5
|
||||
i := 0
|
||||
for {
|
||||
i++
|
||||
query.Add(jsonutils.NewInt(int64(offsetIndex)), "offset")
|
||||
resList, err := manager.List(session, query)
|
||||
if err != nil {
|
||||
if i <= tryTimes {
|
||||
time.Sleep(3 * time.Second)
|
||||
continue
|
||||
}
|
||||
return nil, err
|
||||
}
|
||||
resources = append(resources, resList.Data...)
|
||||
offsetIndex = offsetIndex + len(resList.Data)
|
||||
if offsetIndex >= resList.Total {
|
||||
break
|
||||
}
|
||||
}
|
||||
return resources, nil
|
||||
}
|
||||
|
||||
func ListK8sClusterModuleResources(typ K8sClusterModuleType, clusterId string, session *mcclient.ClientSession, query *jsonutils.JSONDict) ([]jsonutils.JSONObject, error) {
|
||||
var manager modulebase.Manager
|
||||
switch typ {
|
||||
case K8S_MODULE_POD:
|
||||
manager = k8s_modules.Pods
|
||||
case K8S_MODULE_DEPLOY:
|
||||
manager = k8s_modules.Deployments
|
||||
case K8S_MODULE_NODE:
|
||||
manager = k8s_modules.K8sNodes
|
||||
case K8S_MODULE_DAEMONSET:
|
||||
manager = k8s_modules.DaemonSets
|
||||
default:
|
||||
return nil, fmt.Errorf("K8sClusterModuleType: %s is not support", string(typ))
|
||||
}
|
||||
if query == nil {
|
||||
query = jsonutils.NewDict()
|
||||
}
|
||||
query.Set("cluster", jsonutils.NewString(clusterId))
|
||||
query.Set("scope", jsonutils.NewString("system"))
|
||||
return ListAllResources(manager, session, query)
|
||||
}
|
||||
|
||||
func (self *CloudReportBase) CollectRegionMetricOfK8sModules(region cloudprovider.ICloudRegion,
|
||||
clusters []jsonutils.JSONObject) error {
|
||||
errs := make([]error, 0)
|
||||
for _, cluster := range clusters {
|
||||
helper, err := GetK8sClusterHelper(self.SProvider.Provider)
|
||||
if err != nil {
|
||||
log.Errorf("GetK8sClusterHelper err: %v", err)
|
||||
return err
|
||||
}
|
||||
moduleHelpers := helper.MyModuleHelper()
|
||||
for _, moduleHelper := range moduleHelpers {
|
||||
err := self.Impl.CollectK8sModuleMetric(region, cluster, moduleHelper)
|
||||
if err != nil {
|
||||
errs = append(errs, errors.Errorf("k8s moduleType: %s collectK8sModuleMetric err: %v", moduleHelper.MyModuleType(), err))
|
||||
}
|
||||
}
|
||||
}
|
||||
return errors.NewAggregate(errs)
|
||||
}
|
||||
@@ -1,194 +0,0 @@
|
||||
// Copyright 2019 Yunion
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package common
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strconv"
|
||||
"time"
|
||||
|
||||
"github.com/aws/aws-sdk-go/aws/request"
|
||||
|
||||
"yunion.io/x/jsonutils"
|
||||
"yunion.io/x/log"
|
||||
|
||||
"yunion.io/x/onecloud/pkg/apis/compute"
|
||||
"yunion.io/x/onecloud/pkg/cloudmon/options"
|
||||
"yunion.io/x/onecloud/pkg/cloudprovider"
|
||||
"yunion.io/x/onecloud/pkg/mcclient"
|
||||
"yunion.io/x/onecloud/pkg/mcclient/modulebase"
|
||||
)
|
||||
|
||||
type K8sClusterModuleType string
|
||||
|
||||
const (
|
||||
K8S_MODULE_DEPLOY = K8sClusterModuleType("deploy")
|
||||
K8S_MODULE_POD = K8sClusterModuleType("pod")
|
||||
K8S_MODULE_CONTAINER = K8sClusterModuleType("container")
|
||||
K8S_MODULE_NS = K8sClusterModuleType("ns")
|
||||
K8S_MODULE_NODE = K8sClusterModuleType("node")
|
||||
K8S_MODULE_DAEMONSET = K8sClusterModuleType("daemonset")
|
||||
)
|
||||
|
||||
var (
|
||||
cloudReportTable map[string]ICloudReportFactory
|
||||
k8sClusterHelperTable map[string]IK8sClusterMetricHelper
|
||||
)
|
||||
|
||||
func init() {
|
||||
cloudReportTable = make(map[string]ICloudReportFactory)
|
||||
|
||||
k8sClusterHelperTable = make(map[string]IK8sClusterMetricHelper)
|
||||
}
|
||||
|
||||
type IRoutineFactory interface {
|
||||
MyRoutineFunc() RoutineFunc
|
||||
}
|
||||
|
||||
type ICloudReportFactory interface {
|
||||
NewCloudReport(provider *SProvider, session *mcclient.ClientSession, args *options.ReportOptions,
|
||||
operatorType string) ICloudReport
|
||||
GetId() string
|
||||
MyRoutineInteval(monOptions options.CloudMonOptions) time.Duration
|
||||
}
|
||||
|
||||
type IK8sClusterMetricHelper interface {
|
||||
HelperBrand() string
|
||||
MyModuleHelper() map[K8sClusterModuleType]IK8sClusterModuleHelper
|
||||
RegisterModuleHelper(helper IK8sClusterModuleHelper)
|
||||
}
|
||||
|
||||
type K8sClusterMetricBaseHelper struct {
|
||||
ModuleHelper map[K8sClusterModuleType]IK8sClusterModuleHelper
|
||||
}
|
||||
|
||||
func (h *K8sClusterMetricBaseHelper) MyModuleHelper() map[K8sClusterModuleType]IK8sClusterModuleHelper {
|
||||
return h.ModuleHelper
|
||||
}
|
||||
|
||||
func (h *K8sClusterMetricBaseHelper) RegisterModuleHelper(helper IK8sClusterModuleHelper) {
|
||||
h.ModuleHelper[helper.MyModuleType()] = helper
|
||||
}
|
||||
|
||||
type IK8sClusterModuleHelper interface {
|
||||
MyModuleType() K8sClusterModuleType
|
||||
/**
|
||||
DimensionId.LocalId 由「,」分割表示多个组装后Dimension
|
||||
LocalId和ExtId 「,」分割长度需一致
|
||||
*/
|
||||
MyResDimensionId() DimensionId
|
||||
MyNamespaceAndMetrics() (string, map[string][]string)
|
||||
MyResourceFilterQuery(res jsonutils.JSONObject) jsonutils.JSONObject
|
||||
}
|
||||
|
||||
type K8sClusterModuleQueryHelper struct {
|
||||
}
|
||||
|
||||
func (q K8sClusterModuleQueryHelper) MyResourceFilterQuery(jsonutils.JSONObject) jsonutils.JSONObject {
|
||||
return nil
|
||||
}
|
||||
|
||||
type DimensionId struct {
|
||||
LocalId string
|
||||
ExtId string
|
||||
}
|
||||
|
||||
type CommonReportFactory struct {
|
||||
}
|
||||
|
||||
func (co *CommonReportFactory) MyRoutineInteval(monOptions options.CloudMonOptions) time.Duration {
|
||||
interval64, _ := strconv.ParseInt(monOptions.Interval, 10, 32)
|
||||
duration := time.Duration(interval64) * time.Minute
|
||||
return duration
|
||||
}
|
||||
|
||||
type ICloudReport interface {
|
||||
Report() error
|
||||
GetAllserverOfThisProvider(manager modulebase.Manager, query *jsonutils.JSONDict) ([]jsonutils.JSONObject, error)
|
||||
InitProviderInstance() (cloudprovider.ICloudProvider, error)
|
||||
GetAllRegionOfServers(servers []jsonutils.JSONObject, providerInstance cloudprovider.ICloudProvider) (
|
||||
[]cloudprovider.ICloudRegion, map[string][]jsonutils.JSONObject, error)
|
||||
CollectRegionMetric(region cloudprovider.ICloudRegion,
|
||||
servers []jsonutils.JSONObject) error
|
||||
}
|
||||
|
||||
type ICloudReportK8s interface {
|
||||
CollectRegionMetricOfK8sModules(region cloudprovider.ICloudRegion,
|
||||
clusters []jsonutils.JSONObject) error
|
||||
CollectK8sModuleMetric(region cloudprovider.ICloudRegion, cluster jsonutils.JSONObject,
|
||||
helper IK8sClusterModuleHelper) error
|
||||
}
|
||||
|
||||
type SProvider struct {
|
||||
compute.CloudproviderDetails
|
||||
//Id string `json:"id"
|
||||
//Name string `json:"name"`
|
||||
//Provider string `json:"provider"`
|
||||
//Account string `json:"account"`
|
||||
//Secret string `json:"secret"`
|
||||
//AccessUrl string `json:"access_url"`
|
||||
}
|
||||
|
||||
func RegisterFactory(factory ICloudReportFactory) {
|
||||
cloudReportTable[factory.GetId()] = factory
|
||||
}
|
||||
|
||||
func GetCloudReportFactory(provider string) (ICloudReportFactory, error) {
|
||||
factory, ok := cloudReportTable[provider]
|
||||
if ok {
|
||||
return factory, nil
|
||||
}
|
||||
log.Errorf("Provider %s not registerd", provider)
|
||||
return nil, fmt.Errorf("No such cloudReport %s", provider)
|
||||
}
|
||||
|
||||
func (s *SProvider) Validate() error {
|
||||
invalidParams := request.ErrInvalidParams{Context: "SProvider"}
|
||||
if s.Id == "" {
|
||||
invalidParams.Add(request.NewErrParamRequired("Id"))
|
||||
}
|
||||
if s.Name == "" {
|
||||
invalidParams.Add(request.NewErrParamRequired("Name"))
|
||||
}
|
||||
if s.Account == "" {
|
||||
invalidParams.Add(request.NewErrParamRequired("Account"))
|
||||
}
|
||||
//if s.AccessUrl == "" {
|
||||
// invalidParams.Add(request.NewErrParamRequired("AccountUrl"))
|
||||
//}
|
||||
if s.Provider == "" {
|
||||
invalidParams.Add(request.NewErrParamRequired("Provider"))
|
||||
}
|
||||
if s.Secret == "" {
|
||||
invalidParams.Add(request.NewErrParamRequired("Secret"))
|
||||
}
|
||||
if invalidParams.Len() > 0 {
|
||||
return invalidParams
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func RegisterK8sClusterHelper(helper IK8sClusterMetricHelper) {
|
||||
k8sClusterHelperTable[helper.HelperBrand()] = helper
|
||||
}
|
||||
|
||||
func GetK8sClusterHelper(brand string) (IK8sClusterMetricHelper, error) {
|
||||
helper, ok := k8sClusterHelperTable[brand]
|
||||
if ok {
|
||||
return helper, nil
|
||||
}
|
||||
log.Errorf("brand %s not registerd", brand)
|
||||
return nil, fmt.Errorf("No such K8sClusterMetricHelper %s", brand)
|
||||
}
|
||||
@@ -1,155 +0,0 @@
|
||||
package common
|
||||
|
||||
const (
|
||||
PERIOD = 60
|
||||
UNIT_AVERAGE = "Average"
|
||||
DEFAULT_STATISTICS = "Average,Minimum,Maximum"
|
||||
UNIT_PERCENT = "Percent"
|
||||
UNIT_BPS = "bps"
|
||||
UNIT_MBPS = "Mbps"
|
||||
UNIT_BYTEPS = "Bps"
|
||||
UNIT_CPS = "cps"
|
||||
UNIT_COUNT = "count"
|
||||
UNIT_MEM = "byte"
|
||||
UNIT_MSEC = "ms"
|
||||
UNIT_COUNT_SEC = "count/s"
|
||||
UNIT_BYTES = "byte"
|
||||
|
||||
SERVER_METRIC_NAMESPACE = "QCE/CVM"
|
||||
REDIS_METRIC_NAMESPACE = "QCE/REDIS"
|
||||
RDS_METRIC_NAMESPACE = "QCE/CDB"
|
||||
|
||||
//ESC监控指标
|
||||
INFLUXDB_FIELD_CPU_USAGE = "vm_cpu.usage_active"
|
||||
INFLUXDB_FIELD_MEM_USAGE = "vm_mem.used_percent"
|
||||
INFLUXDB_FIELD_DISK_USAGE = "vm_disk.used_percent"
|
||||
INFLUXDB_FIELD_DISK_READ_BPS = "vm_diskio.read_bps"
|
||||
INFLUXDB_FIELD_DISK_WRITE_BPS = "vm_diskio.write_bps"
|
||||
INFLUXDB_FIELD_DISK_READ_IOPS = "vm_diskio.read_iops"
|
||||
INFLUXDB_FIELD_DISK_WRITE_IOPS = "vm_diskio.write_iops"
|
||||
INFLUXDB_FIELD_NET_BPS_RX = "vm_netio.bps_recv"
|
||||
INFLUXDB_FIELD_NET_BPS_RX_INTERNET = INFLUXDB_FIELD_NET_BPS_RX + ",net_type=internet"
|
||||
INFLUXDB_FIELD_NET_BPS_RX_INTRANET = INFLUXDB_FIELD_NET_BPS_RX + ",net_type=intranet"
|
||||
INFLUXDB_FIELD_NET_BPS_TX = "vm_netio.bps_sent"
|
||||
INFLUXDB_FIELD_NET_BPS_TX_INTERNET = INFLUXDB_FIELD_NET_BPS_TX + ",net_type=internet"
|
||||
INFLUXDB_FIELD_NET_BPS_TX_INTRANET = INFLUXDB_FIELD_NET_BPS_TX + ",net_type=intranet"
|
||||
INFLUXDB_FIELD_WANOUTTRAFFIC = "vm_eipio.bps_out"
|
||||
INFLUXDB_FIELD_WANINTRAFFIC = "vm_eipio.bps_in"
|
||||
INFLUXDB_FIELD_WANOUTPKG = "vm_eipio.pps_out"
|
||||
INFLUXDB_FIELD_WANINPKG = "vm_eipio.pps_in"
|
||||
|
||||
//RDS监控指标
|
||||
INFLUXDB_FIELD_RDS_CPU_USAGE = "rds_cpu.usage_active"
|
||||
INFLUXDB_FIELD_RDS_MEM_USAGE = "rds_mem.used_percent"
|
||||
INFLUXDB_FIELD_RDS_NET_BPS_RX = "rds_netio.bps_recv"
|
||||
INFLUXDB_FIELD_RDS_NET_BPS_RX_INTRANET = INFLUXDB_FIELD_RDS_NET_BPS_RX + ",net_type=intranet"
|
||||
INFLUXDB_FIELD_RDS_NET_BPS_RX_MYSQL = INFLUXDB_FIELD_RDS_NET_BPS_RX + ",server_type=mysql"
|
||||
INFLUXDB_FIELD_RDS_NET_BPS_RX_SQLSERVER = INFLUXDB_FIELD_RDS_NET_BPS_RX + ",server_type=sqlserver"
|
||||
INFLUXDB_FIELD_RDS_NET_BPS_TX = "rds_netio.bps_sent"
|
||||
INFLUXDB_FIELD_RDS_NET_BPS_TX_INTRANET = INFLUXDB_FIELD_RDS_NET_BPS_TX + ",net_type=intranet"
|
||||
INFLUXDB_FIELD_RDS_NET_BPS_TX_MYSQL = INFLUXDB_FIELD_RDS_NET_BPS_TX + ",server_type=mysql"
|
||||
INFLUXDB_FIELD_RDS_NET_BPS_TX_SQLSERVER = INFLUXDB_FIELD_RDS_NET_BPS_TX + ",server_type=sqlserver"
|
||||
INFLUXDB_FIELD_RDS_DISK_USAGE = "rds_disk.used_percent"
|
||||
INFLUXDB_FIELD_RDS_DISK_READ_BPS = "rds_diskio.read_bps"
|
||||
INFLUXDB_FIELD_RDS_DISK_WRITE_BPS = "rds_diskio.write_bps"
|
||||
INFLUXDB_FIELD_RDS_DISK_IO_PERSENT = "rds_diskio.used_percent"
|
||||
INFLUXDB_FIELD_RDS_CONN_COUNT = "rds_conn.used_count"
|
||||
INFLUXDB_FIELD_RDS_CONN_ACTIVE = "rds_conn.active_count"
|
||||
INFLUXDB_FIELD_RDS_CONN_USAGE = "rds_conn.used_percent"
|
||||
INFLUXDB_FIELD_RDS_CONN_FAILED = "rds_conn.failed_count"
|
||||
|
||||
INFLUXDB_FIELD_RDS_QPS = "rds_qps.query_qps"
|
||||
INFLUXDB_FIELD_RDS_TPS = "rds_tps.trans_qps"
|
||||
INFLUXDB_FIELD_RDS_INNODB_REDA_BPS = "rds_innodb.read_bps"
|
||||
INFLUXDB_FIELD_RDS_INNODB_WRITE_BPS = "rds_innodb.write_bps"
|
||||
|
||||
//REDIS监控指标
|
||||
INFLUXDB_FIELD_REDIS_CPU_USAGE = "dcs_cpu.usage_active"
|
||||
INFLUXDB_FIELD_REDIS_MEM_USAGE = "dcs_mem.used_percent"
|
||||
INFLUXDB_FIELD_REDIS_NET_BPS_RX = "dcs_netio.bps_recv"
|
||||
INFLUXDB_FIELD_REDIS_NET_BPS_TX = "dcs_netio.bps_sent"
|
||||
INFLUXDB_FIFLD_REDIS_CONN_USAGE = "dcs_conn.used_percent"
|
||||
INFLUXDB_FIFLD_REDIS_OPT_SES = "dcs_instantopt.opt_sec"
|
||||
INFLUXDB_FIFLD_REDIS_CACHE_KEYS = "dcs_cachekeys.key_count"
|
||||
INFLUXDB_FIFLD_REDIS_CACHE_EXP_KEYS = INFLUXDB_FIFLD_REDIS_CACHE_KEYS + ",exp=expire"
|
||||
INFLUXDB_FIFLD_REDIS_DATA_MEM_USAGE = "dcs_datamem.used_byte"
|
||||
INFLUXDB_FIFLD_REDIS_SERVER_LOAD = "dcs_cpu.server_load"
|
||||
INFLUXDB_FIFLD_REDIS_CONN_ERRORS = "dcs_conn.errors"
|
||||
|
||||
//对象存储OSS监控指标
|
||||
INFLUXDB_FIELD_OSS_NET_BPS_RX = "oss_netio.bps_recv"
|
||||
INFLUXDB_FIELD_OSS_NET_BPS_RX_INTERNET = INFLUXDB_FIELD_OSS_NET_BPS_RX + ",net_type=internet"
|
||||
INFLUXDB_FIELD_OSS_NET_BPS_RX_INTRANET = INFLUXDB_FIELD_OSS_NET_BPS_RX + ",net_type=intranet"
|
||||
INFLUXDB_FIELD_OSS_NET_BPS_TX = "oss_netio.bps_sent"
|
||||
INFLUXDB_FIELD_OSS_NET_BPS_TX_INTERNET = INFLUXDB_FIELD_OSS_NET_BPS_TX + ",net_type=internet"
|
||||
INFLUXDB_FIELD_OSS_NET_BPS_TX_INTRANET = INFLUXDB_FIELD_OSS_NET_BPS_TX + ",net_type=intranet"
|
||||
INFLUXDB_FIELD_OSS_LATECY = "oss_latency.req_late"
|
||||
INFLUXDB_FIELD_OSS_LATECY_GET = INFLUXDB_FIELD_OSS_LATECY + ",request=get"
|
||||
INFLUXDB_FIELD_OSS_LATECY_POST = INFLUXDB_FIELD_OSS_LATECY + ",request=post"
|
||||
INFLUXDB_FIELD_OSS_REQ_COUNT = "oss_req.req_count"
|
||||
INFLUXDB_FIELD_OSS_REQ_COUNT_GET = INFLUXDB_FIELD_OSS_REQ_COUNT + ",request=get"
|
||||
INFLUXDB_FIELD_OSS_REQ_COUNT_POST = INFLUXDB_FIELD_OSS_REQ_COUNT + ",request=post"
|
||||
INFLUXDB_FIELD_OSS_REQ_COUNT_5XX = INFLUXDB_FIELD_OSS_REQ_COUNT + ",request=5xx"
|
||||
INFLUXDB_FIELD_OSS_REQ_COUNT_4XX = INFLUXDB_FIELD_OSS_REQ_COUNT + ",request=4xx"
|
||||
|
||||
//负载均衡监控指标
|
||||
INFLUXDB_FIELD_ELB_NET_BPS_RX = "haproxy.bin"
|
||||
INFLUXDB_FIELD_ELB_NET_BPS_TX = "haproxy.bout"
|
||||
INFLUXDB_FIELD_ELB_REQ_RATE = "haproxy.req_rate,request=http"
|
||||
INFLUXDB_FIELD_ELB_CONN_RATE = "haproxy.conn_rate,request=tcp"
|
||||
INFLUXDB_FIELD_ELB_DREQ_COUNT = "haproxy.dreq,request=http"
|
||||
INFLUXDB_FIELD_ELB_DCONN_COUNT = "haproxy.dcon,request=tcp"
|
||||
INFLUXDB_FIELD_ELB_HRSP_COUNT = "haproxy.hrsp_Nxx"
|
||||
INFLUXDB_FIELD_ELB_HRSP_COUNT_2XX = INFLUXDB_FIELD_ELB_HRSP_COUNT + ",request=2xx"
|
||||
INFLUXDB_FIELD_ELB_HRSP_COUNT_3XX = INFLUXDB_FIELD_ELB_HRSP_COUNT + ",request=3xx"
|
||||
INFLUXDB_FIELD_ELB_HRSP_COUNT_4XX = INFLUXDB_FIELD_ELB_HRSP_COUNT + ",request=4xx"
|
||||
INFLUXDB_FIELD_ELB_HRSP_COUNT_5XX = INFLUXDB_FIELD_ELB_HRSP_COUNT + ",request=5xx"
|
||||
INFLUXDB_FIELD_ELB_CHC_STATUS = "haproxy.check_status"
|
||||
INFLUXDB_FIELD_ELB_CHC_CODE = "haproxy.check_code"
|
||||
INFLUXDB_FIELD_ELB_LAST_CHC = "haproxy.last_chk"
|
||||
INFLUXDB_FIELD_ELB_SNAT_PORT = "haproxy.used_snat_port"
|
||||
INFLUXDB_FIELD_ELB_SNAT_CONN_COUNT = "haproxy.snat_conn_count"
|
||||
|
||||
INFLUXDB_FIELD_K8S_CLUSTER_CPU_USAGE = "k8s_cluster.cpu_used_percent"
|
||||
INFLUXDB_FIELD_K8S_CLUSTER_MEM_USAGE = "k8s_cluster.mem_used_percent"
|
||||
INFLUXDB_FIELD_K8S_CLUSTER_ALLOCATABLE_POD = "k8s_cluster.allocatable_pod"
|
||||
INFLUXDB_FIELD_K8S_CLUSTER_TOTAL_CPUCORE = "k8s_cluster.total_cpu"
|
||||
INFLUXDB_FIELD_K8S_CLUSTER_CPU_ALLOCATED = "k8s_cluster.cpu_allocated_percent"
|
||||
|
||||
INFLUXDB_FIELD_K8S_DEPLOY_CPU_USAGE = "k8s_deploy.cpu_used_percent"
|
||||
INFLUXDB_FIELD_K8S_DEPLOY_MEM_USAGE = "k8s_deploy.mem_used_percent"
|
||||
INFLUXDB_FIELD_K8S_DEPLOY_RESTART_TOTAL = "k8s_deploy.restart_total"
|
||||
INFLUXDB_FIELD_K8S_DEPLOY_NET_BPS_RX = "k8s_deploy.bps_recv"
|
||||
INFLUXDB_FIELD_K8S_DEPLOY_NET_BPS_RX_INTERNET = INFLUXDB_FIELD_NET_BPS_RX + ",net_type=internet"
|
||||
INFLUXDB_FIELD_K8S_DEPLOY_NET_BPS_RX_INTRANET = INFLUXDB_FIELD_NET_BPS_RX + ",net_type=intranet"
|
||||
INFLUXDB_FIELD_K8S_DEPLOY_NET_BPS_TX = "k8s_deploy.bps_sent"
|
||||
INFLUXDB_FIELD_K8S_DEPLOY_NET_BPS_TX_INTERNET = INFLUXDB_FIELD_NET_BPS_TX + ",net_type=internet"
|
||||
INFLUXDB_FIELD_K8S_DEPLOY_NET_BPS_TX_INTRANET = INFLUXDB_FIELD_NET_BPS_TX + ",net_type=intranet"
|
||||
INFLUXDB_FIELD_K8S_POD_OOM_CONTAINER_COUNT = "k8s_deploy.pod_oom_total"
|
||||
INFLUXDB_FIELD_K8S_POD_RESTARTING_CONTAINER_COUNT = "k8s_deploy.pod_restarting_total"
|
||||
|
||||
INFLUXDB_FIELD_K8S_POD_CPU_USAGE = "k8s_pod.cpu_used_percent"
|
||||
INFLUXDB_FIELD_K8S_POD_MEM_USAGE = "k8s_pod.mem_used_percent"
|
||||
INFLUXDB_FIELD_K8S_POD_RESTART_TOTAL = "k8s_pod.restart_total"
|
||||
|
||||
INFLUXDB_FIELD_K8S_CONTAINER_CPU_USAGE = "k8s_container.cpu_used_percent"
|
||||
INFLUXDB_FIELD_K8S_CONTAINER_MEM_USAGE = "k8s_container.mem_used_percent"
|
||||
INFLUXDB_FIELD_K8S_CONTAINER_NET_BPS_RX = "k8s_container.net_bps_recv"
|
||||
INFLUXDB_FIELD_K8S_CONTAINER_NET_BPS_TX = "k8s_container.net_bps_sent"
|
||||
|
||||
INFLUXDB_FIELD_K8S_NODE_CPU_USAGE = "k8s_node.cpu_used_percent"
|
||||
INFLUXDB_FIELD_K8S_NODE_MEM_USAGE = "k8s_node.mem_used_percent"
|
||||
INFLUXDB_FIELD_K8S_NODE_DISK_USAGE = "k8s_node.disk_used_percent"
|
||||
INFLUXDB_FIELD_K8S_NODE_NET_BPS_RX = "k8s_node.bps_recv"
|
||||
INFLUXDB_FIELD_K8S_NODE_NET_BPS_RX_INTERNET = INFLUXDB_FIELD_NET_BPS_RX + ",net_type=internet"
|
||||
INFLUXDB_FIELD_K8S_NODE_NET_BPS_RX_INTRANET = INFLUXDB_FIELD_NET_BPS_RX + ",net_type=intranet"
|
||||
INFLUXDB_FIELD_K8S_NODE_NET_BPS_TX = "k8s_node.bps_sent"
|
||||
INFLUXDB_FIELD_K8S_NODE_NET_BPS_TX_INTERNET = INFLUXDB_FIELD_NET_BPS_TX + ",net_type=internet"
|
||||
INFLUXDB_FIELD_K8S_NODE_NET_BPS_TX_INTRANET = INFLUXDB_FIELD_NET_BPS_TX + ",net_type=intranet"
|
||||
INFLUXDB_FIELD_K8S_NODE_POD_RESTART_TOTAL = "k8s_node.pod_restart_total"
|
||||
|
||||
KEY_VMS = "vms"
|
||||
KEY_CPUS = "cpus"
|
||||
KEY_MEMS = "mems"
|
||||
KEY_DISKS = "disks"
|
||||
)
|
||||
@@ -1,15 +0,0 @@
|
||||
// Copyright 2019 Yunion
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package common // import "yunion.io/x/onecloud/pkg/cloudmon/collectors/common"
|
||||
@@ -1,666 +0,0 @@
|
||||
// Copyright 2019 Yunion
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package common
|
||||
|
||||
import (
|
||||
"context"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"golang.org/x/sync/errgroup"
|
||||
|
||||
"yunion.io/x/jsonutils"
|
||||
"yunion.io/x/log"
|
||||
"yunion.io/x/pkg/errors"
|
||||
"yunion.io/x/pkg/util/timeutils"
|
||||
"yunion.io/x/pkg/utils"
|
||||
|
||||
"yunion.io/x/onecloud/pkg/apis/compute"
|
||||
o "yunion.io/x/onecloud/pkg/cloudmon/options"
|
||||
"yunion.io/x/onecloud/pkg/cloudprovider"
|
||||
"yunion.io/x/onecloud/pkg/mcclient"
|
||||
"yunion.io/x/onecloud/pkg/mcclient/auth"
|
||||
modules "yunion.io/x/onecloud/pkg/mcclient/modules/compute"
|
||||
"yunion.io/x/onecloud/pkg/util/influxdb"
|
||||
)
|
||||
|
||||
type MonType string
|
||||
|
||||
const (
|
||||
SERVER MonType = "server"
|
||||
HOST MonType = "host"
|
||||
REDIS MonType = "redis"
|
||||
RDS MonType = "rds"
|
||||
OSS MonType = "oss"
|
||||
ELB MonType = "elb"
|
||||
CLOUDACCOUNT MonType = "cloudaccount"
|
||||
STORAGE MonType = "storage"
|
||||
ALERT_RECORD MonType = "alertRecord"
|
||||
|
||||
PING_PROBE MonType = "ping_probe"
|
||||
USAGE MonType = "usage"
|
||||
|
||||
K8S MonType = "k8s"
|
||||
K8S_DEPLOY = MonType(K8S_MODULE_DEPLOY)
|
||||
K8S_POD = MonType(K8S_MODULE_POD)
|
||||
K8S_NODE = MonType(K8S_MODULE_NODE)
|
||||
|
||||
ALL_RESOURCE MonType = "all"
|
||||
)
|
||||
|
||||
const (
|
||||
KEY_LIMIT = "limit"
|
||||
KEY_ADMIN = "admin"
|
||||
KEY_USABLE = "usable"
|
||||
DETAILS = "details"
|
||||
KEY_SCOPE = "scope"
|
||||
)
|
||||
|
||||
const (
|
||||
TYPE_VIRTUALMACHINE = "VirtualMachine"
|
||||
TYPE_HOSTSYSTEM = "HostSystem"
|
||||
)
|
||||
|
||||
var (
|
||||
SupportMetricBrands = []string{compute.CLOUD_PROVIDER_ALIYUN, compute.CLOUD_PROVIDER_VMWARE, compute.CLOUD_PROVIDER_APSARA,
|
||||
compute.CLOUD_PROVIDER_QCLOUD, compute.CLOUD_PROVIDER_AZURE, compute.CLOUD_PROVIDER_AWS,
|
||||
compute.CLOUD_PROVIDER_HUAWEI, compute.CLOUD_PROVIDER_HCSO, compute.CLOUD_PROVIDER_ZSTACK,
|
||||
compute.CLOUD_PROVIDER_GOOGLE, compute.CLOUD_PROVIDER_ECLOUD, compute.CLOUD_PROVIDER_JDCLOUD, compute.CLOUD_PROVIDER_BINGO_CLOUD}
|
||||
|
||||
ResMonTypeList = []string{string(SERVER), string(HOST), string(REDIS), string(RDS), string(OSS),
|
||||
string(ELB), string(K8S)}
|
||||
CustomizeMonTypeList = []string{string(CLOUDACCOUNT), string(STORAGE), string(ALERT_RECORD), string(PING_PROBE),
|
||||
string(USAGE)}
|
||||
)
|
||||
|
||||
var OtherVmTags = map[string]string{
|
||||
"source": "cloudmon",
|
||||
"res_type": "guest",
|
||||
"is_vm": "true",
|
||||
}
|
||||
var OtherTags = map[string]string{
|
||||
"source": "cloudmon",
|
||||
}
|
||||
|
||||
var OtherHostTag = map[string]string{
|
||||
"source": "cloudmon",
|
||||
"res_type": "host",
|
||||
"is_vm": "false",
|
||||
}
|
||||
|
||||
var InstanceProviders = "Aliyun,Azure,Aws,Qcloud,VMWare,Huawei,Openstack,Ucloud,ZStack"
|
||||
|
||||
//server的key-value对应保存时的Tags和Pairs
|
||||
//var ServerTags = []string{"host", "host_id", "vm_id", "vm_ip", "vm_name", "zone", "zone_id", "zone_ext_id",
|
||||
// "hypervisor", "os_type", "status", "region", "region_id", "region_ext_id", "tenant", "tenant_id", "brand", "name"}
|
||||
var ServerTags = map[string]string{
|
||||
"host": "host",
|
||||
"host_id": "host_id",
|
||||
"id": "vm_id",
|
||||
"ips": "vm_ip",
|
||||
"name": "vm_name",
|
||||
"zone": "zone",
|
||||
"zone_id": "zone_id",
|
||||
"zone_ext_id": "zone_ext_id",
|
||||
"os_type": "os_type",
|
||||
"status": "status",
|
||||
"cloudregion": "cloudregion",
|
||||
"cloudregion_id": "cloudregion_id",
|
||||
"region_ext_id": "region_ext_id",
|
||||
"tenant": "tenant",
|
||||
"tenant_id": "tenant_id",
|
||||
"brand": "brand",
|
||||
"scaling_group_id": "vm_scaling_group_id",
|
||||
"domain_id": "domain_id",
|
||||
"project_domain": "project_domain",
|
||||
"account": "account",
|
||||
"account_id": "account_id",
|
||||
}
|
||||
var HostTags = map[string]string{
|
||||
"id": "host_id",
|
||||
"ips": "host_ip",
|
||||
"name": "host",
|
||||
"zone": "zone",
|
||||
"zone_id": "zone_id",
|
||||
"zone_ext_id": "zone_ext_id",
|
||||
"os_type": "os_type",
|
||||
"status": "status",
|
||||
"cloudregion": "cloudregion",
|
||||
"cloudregion_id": "cloudregion_id",
|
||||
"region_ext_id": "region_ext_id",
|
||||
"tenant": "tenant",
|
||||
"tenant_id": "tenant_id",
|
||||
"brand": "brand",
|
||||
"domain_id": "domain_id",
|
||||
"project_domain": "project_domain",
|
||||
"account": "account",
|
||||
"account_id": "account_id",
|
||||
}
|
||||
var RdsTags = map[string]string{
|
||||
"host": "host",
|
||||
"host_id": "host_id",
|
||||
"id": "rds_id",
|
||||
"ips": "rds_ip",
|
||||
"name": "rds_name",
|
||||
"zone": "zone",
|
||||
"zone_id": "zone_id",
|
||||
"zone_ext_id": "zone_ext_id",
|
||||
"os_type": "os_type",
|
||||
"status": "status",
|
||||
"cloudregion": "cloudregion",
|
||||
"cloudregion_id": "cloudregion_id",
|
||||
"region_ext_id": "region_ext_id",
|
||||
"tenant": "tenant",
|
||||
"tenant_id": "tenant_id",
|
||||
"brand": "brand",
|
||||
"domain_id": "domain_id",
|
||||
"project_domain": "project_domain",
|
||||
}
|
||||
var RedisTags = map[string]string{
|
||||
"host": "host",
|
||||
"host_id": "host_id",
|
||||
"id": "redis_id",
|
||||
"ips": "redis_ip",
|
||||
"name": "redis_name",
|
||||
"zone": "zone",
|
||||
"zone_id": "zone_id",
|
||||
"zone_ext_id": "zone_ext_id",
|
||||
"os_type": "os_type",
|
||||
"status": "status",
|
||||
"cloudregion": "cloudregion",
|
||||
"cloudregion_id": "cloudregion_id",
|
||||
"region_ext_id": "region_ext_id",
|
||||
"tenant": "tenant",
|
||||
"tenant_id": "tenant_id",
|
||||
"brand": "brand",
|
||||
"domain_id": "domain_id",
|
||||
"project_domain": "project_domain",
|
||||
}
|
||||
var OssTags = map[string]string{
|
||||
"host": "host",
|
||||
"host_id": "host_id",
|
||||
"id": "oss_id",
|
||||
"ips": "oss_ip",
|
||||
"name": "oss_name",
|
||||
"zone": "zone",
|
||||
"zone_id": "zone_id",
|
||||
"zone_ext_id": "zone_ext_id",
|
||||
"os_type": "os_type",
|
||||
"status": "status",
|
||||
"cloudregion": "cloudregion",
|
||||
"cloudregion_id": "cloudregion_id",
|
||||
"region_ext_id": "region_ext_id",
|
||||
"tenant": "tenant",
|
||||
"tenant_id": "tenant_id",
|
||||
"brand": "brand",
|
||||
"domain_id": "domain_id",
|
||||
"project_domain": "project_domain",
|
||||
}
|
||||
var ElbTags = map[string]string{
|
||||
"host": "host",
|
||||
"host_id": "host_id",
|
||||
"id": "elb_id",
|
||||
"ips": "elb_ip",
|
||||
"name": "elb_name",
|
||||
"zone": "zone",
|
||||
"zone_id": "zone_id",
|
||||
"zone_ext_id": "zone_ext_id",
|
||||
"os_type": "os_type",
|
||||
"status": "status",
|
||||
"region": "region",
|
||||
"cloudregion": "cloudregion",
|
||||
"cloudregion_id": "cloudregion_id",
|
||||
"tenant": "tenant",
|
||||
"tenant_id": "tenant_id",
|
||||
"brand": "brand",
|
||||
"domain_id": "domain_id",
|
||||
"project_domain": "project_domain",
|
||||
}
|
||||
|
||||
var CloudAccountTags = map[string]string{
|
||||
"id": "cloudaccount_id",
|
||||
"name": "cloudaccount_name",
|
||||
"brand": "brand",
|
||||
"domain_id": "domain_id",
|
||||
"project_domain": "project_domain",
|
||||
}
|
||||
|
||||
var StorageTags = map[string]string{
|
||||
"id": "storage_id",
|
||||
"name": "storage_name",
|
||||
"zone": "zone",
|
||||
"zone_id": "zone_id",
|
||||
"zone_ext_id": "zone_ext_id",
|
||||
"status": "status",
|
||||
"cloudregion": "cloudregion",
|
||||
"cloudregion_id": "cloudregion_id",
|
||||
"region_ext_id": "region_ext_id",
|
||||
"brand": "brand",
|
||||
"domain_id": "domain_id",
|
||||
"project_domain": "project_domain",
|
||||
}
|
||||
|
||||
var K8sTags = map[string]string{
|
||||
"id": "id",
|
||||
"name": "name",
|
||||
"zone": "zone",
|
||||
"zone_id": "zone_id",
|
||||
"zone_ext_id": "zone_ext_id",
|
||||
"status": "status",
|
||||
"cloudregion": "cloudregion",
|
||||
"cloudregion_id": "cloudregion_id",
|
||||
"region_ext_id": "region_ext_id",
|
||||
"tenant": "tenant",
|
||||
"tenant_id": "tenant_id",
|
||||
"brand": "brand",
|
||||
"provider": "provider",
|
||||
"domain_id": "domain_id",
|
||||
"project_domain": "project_domain",
|
||||
}
|
||||
|
||||
var AlertRecordHistoryTags = map[string]string{
|
||||
"alert_name": "alert_name",
|
||||
"alert_id": "alert_id",
|
||||
"domain_id": "domain_id",
|
||||
"project_domain": "project_domain",
|
||||
"tenant_id": "tenant_id",
|
||||
"tenant": "tenant",
|
||||
"res_type": "res_type",
|
||||
}
|
||||
|
||||
var CloudAccountFields = []string{"balance"}
|
||||
|
||||
var AlertRecordHistoryFields = []string{"res_num"}
|
||||
|
||||
var ServerPairs = []string{"vcpu_count", "vmem_size", "disk"}
|
||||
|
||||
var AddTags = map[string]string{
|
||||
"source": "cloudmon",
|
||||
}
|
||||
|
||||
//get substring from str before separator
|
||||
func SubstringBefore(str, separator string) string {
|
||||
if str != "" {
|
||||
if separator == "" {
|
||||
return ""
|
||||
} else {
|
||||
if pos := strings.Index(str, separator); pos == -1 {
|
||||
return str
|
||||
} else {
|
||||
return str[0:pos]
|
||||
}
|
||||
}
|
||||
} else {
|
||||
return str
|
||||
}
|
||||
}
|
||||
|
||||
//get substring from str after separator
|
||||
func SubstringAfter(str, separator string) string {
|
||||
if str != "" {
|
||||
if separator == "" {
|
||||
return ""
|
||||
} else {
|
||||
if pos := strings.Index(str, separator); pos == -1 {
|
||||
return ""
|
||||
} else {
|
||||
return str[pos+len(separator):]
|
||||
}
|
||||
}
|
||||
} else {
|
||||
return str
|
||||
}
|
||||
}
|
||||
|
||||
//get a substring from str between[open,close)
|
||||
func SubstringBetween(str, open, close string) string {
|
||||
if str != "" && open != "" && close != "" {
|
||||
if start := strings.Index(str, open); start != -1 {
|
||||
if end := strings.Index(str[start+len(open):], close); end != -1 {
|
||||
return str[start+len(open) : start+len(open)+end]
|
||||
}
|
||||
}
|
||||
return ""
|
||||
} else {
|
||||
return ""
|
||||
}
|
||||
}
|
||||
|
||||
func ParseTimeStr(startTime, endTime string) (since, util time.Time, err error) {
|
||||
since, err = timeutils.ParseTimeStr(startTime)
|
||||
if err != nil {
|
||||
return since, util, err
|
||||
}
|
||||
util, err = timeutils.ParseTimeStr(endTime)
|
||||
if err != nil {
|
||||
return since, util, err
|
||||
}
|
||||
return since, util, nil
|
||||
}
|
||||
|
||||
func TimeRangeFromArgs(args *o.ReportOptions) (since, until time.Time, err error) {
|
||||
if args.SinceTime != "" && args.EndTime != "" {
|
||||
since, until, err = ParseTimeStr(args.SinceTime, args.EndTime)
|
||||
if err != nil {
|
||||
return since, until, err
|
||||
}
|
||||
} else {
|
||||
period64, err := strconv.ParseInt(args.Interval, 10, 32)
|
||||
if err != nil {
|
||||
return since, until, err
|
||||
}
|
||||
since = time.Now().Add(-time.Minute * time.Duration(period64))
|
||||
until = time.Now()
|
||||
}
|
||||
return since, until, nil
|
||||
}
|
||||
|
||||
//组装server相关capability
|
||||
func FillVMCapacity(server *jsonutils.JSONDict) (influxdb.SMetricData, error) {
|
||||
metric, err := JsonToMetric(server, "vm_capacity", ServerTags, ServerPairs)
|
||||
if err != nil {
|
||||
return influxdb.SMetricData{}, err
|
||||
}
|
||||
hypevisor, _ := server.GetString("hypervisor")
|
||||
metric.Timestamp = time.Now()
|
||||
metric.Tags = append(metric.Tags, influxdb.SKeyValue{
|
||||
Key: "res_type",
|
||||
Value: "guest",
|
||||
}, influxdb.SKeyValue{
|
||||
Key: "is_vm",
|
||||
Value: "true",
|
||||
}, influxdb.SKeyValue{
|
||||
Key: "platform",
|
||||
Value: hypevisor,
|
||||
})
|
||||
return metric, nil
|
||||
}
|
||||
|
||||
func GetMeasurement(action string, influxDbSpec string) (measurement string) {
|
||||
// VirtualMachine -> VMware类型的虚拟机
|
||||
if action == TYPE_VIRTUALMACHINE {
|
||||
measurement = SubstringBefore(influxDbSpec, ".")
|
||||
}
|
||||
if action == TYPE_HOSTSYSTEM {
|
||||
measurement = SubstringBetween(influxDbSpec, "vm_", ".")
|
||||
if strings.Contains(influxDbSpec, "vm_netio") {
|
||||
measurement = "net"
|
||||
}
|
||||
}
|
||||
return measurement
|
||||
}
|
||||
|
||||
func JsonToMetric(obj *jsonutils.JSONDict, name string, tags map[string]string, metrics []string) (influxdb.SMetricData, error) {
|
||||
metric := influxdb.SMetricData{Name: name}
|
||||
objMap, err := obj.GetMap()
|
||||
if err != nil {
|
||||
return metric, errors.Wrap(err, "obj.GetMap")
|
||||
}
|
||||
tagPairs := make([]influxdb.SKeyValue, 0)
|
||||
metricPairs := make([]influxdb.SKeyValue, 0)
|
||||
for k, v := range objMap {
|
||||
val, _ := v.GetString()
|
||||
if strings.Contains(k, "ip") {
|
||||
if strings.Contains(val, ",") {
|
||||
val = strings.ReplaceAll(val, ",", "|")
|
||||
}
|
||||
}
|
||||
if tag, ok := tags[k]; ok {
|
||||
tagPairs = append(tagPairs, influxdb.SKeyValue{
|
||||
Key: tag,
|
||||
Value: val,
|
||||
})
|
||||
} else if utils.IsInStringArray(k, metrics) {
|
||||
metricPairs = append(metricPairs, influxdb.SKeyValue{
|
||||
Key: k, Value: val,
|
||||
})
|
||||
}
|
||||
//if k == "metadata" {
|
||||
// mValMap, err := v.GetMap()
|
||||
// if err != nil {
|
||||
// log.Errorf("get metadata value err: %v", err)
|
||||
// continue
|
||||
// }
|
||||
// for mKey, mValObj := range mValMap {
|
||||
// if strings.Contains(mKey, "sys") {
|
||||
// mVal, _ := mValObj.GetString()
|
||||
// tagPairs = append(tagPairs, influxdb.SKeyValue{
|
||||
// Key: mKey,
|
||||
// Value: mVal,
|
||||
// })
|
||||
// }
|
||||
// }
|
||||
//}
|
||||
}
|
||||
metric.Tags = tagPairs
|
||||
metric.Metrics = metricPairs
|
||||
return metric, nil
|
||||
}
|
||||
|
||||
func SendMetrics(s *mcclient.ClientSession, metrics []influxdb.SMetricData, debug bool, database string) error {
|
||||
urls, err := s.GetServiceURLs("influxdb", o.Options.SessionEndpointType, "")
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "GetServiceURLs")
|
||||
}
|
||||
if len(database) == 0 {
|
||||
database = o.Options.InfluxDatabase
|
||||
}
|
||||
return influxdb.SendMetrics(urls, database, metrics, debug)
|
||||
}
|
||||
|
||||
func ReportCloudMetricOfoperatorType(operatorType string, session *mcclient.ClientSession,
|
||||
args *o.ReportOptions) error {
|
||||
query := jsonutils.NewDict()
|
||||
query.Add(jsonutils.NewString("10"), KEY_LIMIT)
|
||||
query.Add(jsonutils.NewString("true"), KEY_ADMIN)
|
||||
//query.Add(jsonutils.NewString("true"), KEY_USABLE)
|
||||
if len(args.Provider) > 0 {
|
||||
for _, val := range args.Provider {
|
||||
query.Add(jsonutils.NewString(val), "provider")
|
||||
}
|
||||
}
|
||||
cloudProviderList, err := ListAllResources(&modules.Cloudproviders, session, query)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "cloudProviders get list error")
|
||||
}
|
||||
providerGroup, _ := errgroup.WithContext(context.Background())
|
||||
tmpCount := 0
|
||||
if args.Count == 0 {
|
||||
args.Count = 1
|
||||
}
|
||||
for i := 0; i < len(cloudProviderList); i++ {
|
||||
provider := cloudProviderList[i]
|
||||
status, err := provider.GetString("status")
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "provider get status error")
|
||||
}
|
||||
if status == "connected" {
|
||||
providerStruct := SProvider{}
|
||||
err := provider.Unmarshal(&providerStruct)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "provider.Unmarshal")
|
||||
}
|
||||
err = (&providerStruct).Validate()
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "provider Invalidate")
|
||||
}
|
||||
providerStr := providerStruct.Provider
|
||||
cloudReportFactory, err := GetCloudReportFactory(providerStr)
|
||||
if err != nil {
|
||||
log.Errorln(errors.Wrap(err, "GetCloudReportFactory"))
|
||||
continue
|
||||
}
|
||||
tmpCount++
|
||||
providerGroup.Go(func() error {
|
||||
err = cloudReportFactory.NewCloudReport(&providerStruct, session, args, operatorType).Report()
|
||||
if err != nil {
|
||||
log.Errorln(errors.Wrap(err, "cloudReport Report method"))
|
||||
}
|
||||
return nil
|
||||
})
|
||||
if tmpCount == args.Count {
|
||||
err := providerGroup.Wait()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
tmpCount = 0
|
||||
}
|
||||
}
|
||||
}
|
||||
return providerGroup.Wait()
|
||||
}
|
||||
|
||||
func ReportCustomizeCloudMetric(operatorType string, session *mcclient.ClientSession, args *o.ReportOptions) error {
|
||||
cloudReportFactory, err := GetCloudReportFactory(operatorType)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "GetCloudReportFactory")
|
||||
}
|
||||
err = cloudReportFactory.NewCloudReport(nil, session, args, operatorType).Report()
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "cloudReport Report method")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func CollectRegionMetricAsync(asynCount int, region cloudprovider.ICloudRegion,
|
||||
servers []jsonutils.JSONObject, report ICloudReport) error {
|
||||
metricGroup, _ := errgroup.WithContext(context.Background())
|
||||
count := 0
|
||||
if asynCount == 0 {
|
||||
asynCount = 10
|
||||
}
|
||||
for i, _ := range servers {
|
||||
server := servers[i]
|
||||
metricGroup.Go(func() error {
|
||||
return report.CollectRegionMetric(region, []jsonutils.JSONObject{server})
|
||||
})
|
||||
count++
|
||||
if count == asynCount {
|
||||
err := metricGroup.Wait()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
count = 0
|
||||
}
|
||||
}
|
||||
return metricGroup.Wait()
|
||||
}
|
||||
|
||||
func ReportConnectCloudproviderMetric(ctx context.Context, provider jsonutils.JSONObject,
|
||||
closeChan chan struct{}) error {
|
||||
status, err := provider.GetString("status")
|
||||
if err != nil {
|
||||
return errors.Errorf("provider get status error: %v", err)
|
||||
}
|
||||
if status != "connected" {
|
||||
return errors.Errorf("provider status: %s expect: connected", status)
|
||||
}
|
||||
providerStruct := SProvider{}
|
||||
err = provider.Unmarshal(&providerStruct)
|
||||
if err != nil {
|
||||
return errors.Errorf("provider.Unmarshal err: %v", provider)
|
||||
}
|
||||
err = (&providerStruct).Validate()
|
||||
if err != nil {
|
||||
return errors.Errorf("provider validate err: %v", err)
|
||||
}
|
||||
providerStr := providerStruct.Provider
|
||||
cloudReportFactory, err := GetCloudReportFactory(providerStr)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "GetCloudReportFactory")
|
||||
}
|
||||
|
||||
MakePullMetricRoutineWithDur(ctx, cloudReportFactory, &providerStruct, closeChan,
|
||||
cloudReportFactory.MyRoutineInteval(o.Options),
|
||||
cloudproviderRunfunc)
|
||||
return nil
|
||||
}
|
||||
|
||||
type RoutineFunc func(ctx context.Context, factory ICloudReportFactory, provider *SProvider, closeChan chan struct{},
|
||||
interval time.Duration, run runFunc)
|
||||
|
||||
func MakePullMetricRoutineWithDur(ctx context.Context, factory ICloudReportFactory, provider *SProvider, closeChan chan struct{}, interval time.Duration, run runFunc) {
|
||||
go func() {
|
||||
timer := time.NewTimer(0)
|
||||
for {
|
||||
session := auth.GetAdminSession(ctx, "")
|
||||
select {
|
||||
case <-closeChan:
|
||||
log.Warningf("closed provider: %s,name: %s. pull metric", provider.Name, provider.Name)
|
||||
return
|
||||
case <-timer.C:
|
||||
run(ctx, factory, provider, session)
|
||||
}
|
||||
timer.Reset(interval)
|
||||
}
|
||||
}()
|
||||
}
|
||||
|
||||
func MakePullMetricRoutineAtZeroPoint(ctx context.Context, factory ICloudReportFactory, provider *SProvider,
|
||||
closeChan chan struct{}, interval time.Duration, run runFunc) {
|
||||
go func() {
|
||||
timer := time.NewTimer(interval)
|
||||
for {
|
||||
now := time.Now()
|
||||
next := now.Add(time.Hour * 24 * interval)
|
||||
date := time.Date(next.Year(), next.Month(), next.Day(), 0, 0, 0, 0, next.Location())
|
||||
timer.Reset(date.Sub(now))
|
||||
session := auth.GetAdminSession(ctx, "")
|
||||
select {
|
||||
case <-closeChan:
|
||||
log.Warningf("closed provider: %s,brand: %s. pull metric", provider.Name, provider.Brand)
|
||||
return
|
||||
case <-timer.C:
|
||||
run(ctx, factory, provider, session)
|
||||
}
|
||||
}
|
||||
}()
|
||||
}
|
||||
|
||||
type runFunc func(ctx context.Context, factory ICloudReportFactory, provider *SProvider, session *mcclient.ClientSession)
|
||||
|
||||
func cloudproviderRunfunc(ctx context.Context, factory ICloudReportFactory, provider *SProvider,
|
||||
session *mcclient.ClientSession) {
|
||||
opt := o.Options
|
||||
group, _ := errgroup.WithContext(ctx)
|
||||
for i := range ResMonTypeList {
|
||||
resType := ResMonTypeList[i]
|
||||
group.Go(func() error {
|
||||
log.Infof("cloudprovider: %s,operator: %s start report().", provider.Name, resType)
|
||||
|
||||
err := factory.NewCloudReport(provider, session, &opt.ReportOptions, resType).Report()
|
||||
if err != nil {
|
||||
log.Errorf("provider: %s report metric err: %v", provider.Name, err)
|
||||
return nil
|
||||
}
|
||||
log.Infof("cloudprovider: %s,operator: %s report() end.", provider.Name, resType)
|
||||
return nil
|
||||
})
|
||||
}
|
||||
group.Wait()
|
||||
}
|
||||
|
||||
func CustomizeRunFunc(ctx context.Context, factory ICloudReportFactory, provider *SProvider,
|
||||
session *mcclient.ClientSession) {
|
||||
opt := o.Options
|
||||
err := factory.NewCloudReport(provider, session, &opt.ReportOptions, "").Report()
|
||||
if err != nil {
|
||||
// provider maybe nil
|
||||
log.Errorf("provider: %v report metric err: %v", provider, err)
|
||||
return
|
||||
}
|
||||
log.Errorf("operator: %s report() end.", factory.GetId())
|
||||
}
|
||||
@@ -1,15 +0,0 @@
|
||||
// Copyright 2019 Yunion
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package ecloudmon // import "yunion.io/x/onecloud/pkg/cloudmon/collectors/ecloudmon"
|
||||
@@ -1,77 +0,0 @@
|
||||
// Copyright 2019 Yunion
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package ecloudmon
|
||||
|
||||
import (
|
||||
"yunion.io/x/onecloud/pkg/apis/compute"
|
||||
"yunion.io/x/onecloud/pkg/cloudmon/collectors/common"
|
||||
"yunion.io/x/onecloud/pkg/cloudmon/options"
|
||||
"yunion.io/x/onecloud/pkg/mcclient"
|
||||
)
|
||||
|
||||
func init() {
|
||||
factory := SECloudReportFactory{}
|
||||
common.RegisterFactory(&factory)
|
||||
}
|
||||
|
||||
type SECloudReportFactory struct {
|
||||
common.CommonReportFactory
|
||||
}
|
||||
|
||||
func (self *SECloudReportFactory) NewCloudReport(provider *common.SProvider, session *mcclient.ClientSession,
|
||||
args *options.ReportOptions, operatorType string) common.ICloudReport {
|
||||
return &SECloudReport{
|
||||
common.CloudReportBase{
|
||||
SProvider: provider,
|
||||
Session: session,
|
||||
Args: args,
|
||||
Operator: operatorType,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func (self *SECloudReportFactory) GetId() string {
|
||||
return compute.CLOUD_PROVIDER_ECLOUD
|
||||
}
|
||||
|
||||
type SECloudReport struct {
|
||||
common.CloudReportBase
|
||||
}
|
||||
|
||||
func (self *SECloudReport) Report() error {
|
||||
servers, err := self.GetResourceByOperator()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
providerInstance, err := self.InitProviderInstance()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
regionList, regionServerMap, err := self.GetAllRegionOfServers(servers, providerInstance)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
for _, region := range regionList {
|
||||
servers := regionServerMap[region.GetGlobalId()]
|
||||
switch self.Operator {
|
||||
case "server":
|
||||
err = self.collectRegionMetricOfHost(region, servers)
|
||||
}
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
@@ -1,127 +0,0 @@
|
||||
// Copyright 2019 Yunion
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package ecloudmon
|
||||
|
||||
import (
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"yunion.io/x/jsonutils"
|
||||
"yunion.io/x/log"
|
||||
"yunion.io/x/pkg/errors"
|
||||
|
||||
"yunion.io/x/onecloud/pkg/cloudmon/collectors/common"
|
||||
"yunion.io/x/onecloud/pkg/cloudprovider"
|
||||
"yunion.io/x/onecloud/pkg/multicloud/ecloud"
|
||||
"yunion.io/x/onecloud/pkg/util/influxdb"
|
||||
)
|
||||
|
||||
const (
|
||||
SERVER_PRODUCT_TYPE = "vm"
|
||||
)
|
||||
|
||||
func (self *SECloudReport) collectRegionMetricOfHost(region cloudprovider.ICloudRegion,
|
||||
servers []jsonutils.JSONObject) error {
|
||||
dataList := make([]influxdb.SMetricData, 0)
|
||||
ecloudReg := region.(*ecloud.SRegion)
|
||||
since, until, err := common.TimeRangeFromArgs(self.Args)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
for _, server := range servers {
|
||||
external_id, err := server.GetString("external_id")
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
name, _ := server.GetString("name")
|
||||
external_id = strings.Split(external_id, "/")[1]
|
||||
metrics := make([]ecloud.Metric, 0)
|
||||
for metricName, _ := range ecloudMetricSpecs {
|
||||
metrics = append(metrics, ecloud.Metric{Name: metricName})
|
||||
}
|
||||
data, err := ecloudReg.DescribeMetricList(SERVER_PRODUCT_TYPE, metrics, external_id, since, until)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "region DescribeMetricList err:")
|
||||
}
|
||||
for _, entity := range data.Entitys {
|
||||
if influxDbSpecs, ok := ecloudMetricSpecs[entity.MetricName]; ok {
|
||||
metricData, err := self.collectMetricFromThisServer(server, entity, influxDbSpecs)
|
||||
if err != nil {
|
||||
log.Errorf("server:%s collectMetric:%s err", name, entity.MetricName)
|
||||
continue
|
||||
}
|
||||
dataList = append(dataList, metricData...)
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
return common.SendMetrics(self.Session, dataList, self.Args.Debug, "")
|
||||
}
|
||||
|
||||
func (self *SECloudReport) collectMetricFromThisServer(server jsonutils.JSONObject,
|
||||
entity ecloud.Entity, influxDbSpecs []string) ([]influxdb.SMetricData, error) {
|
||||
datas := make([]influxdb.SMetricData, 0)
|
||||
for _, point := range entity.Datapoints {
|
||||
metric, err := common.JsonToMetric(server.(*jsonutils.JSONDict), "", common.ServerTags, make([]string, 0))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if len(point) != 2 {
|
||||
log.Errorf("invalid point:%v", point)
|
||||
continue
|
||||
}
|
||||
influxDbSpec := influxDbSpecs[2]
|
||||
|
||||
measurement := common.SubstringBefore(influxDbSpec, ".")
|
||||
metric.Name = measurement
|
||||
pointTime, err := strconv.ParseInt(point[1], 10, 64)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "point parseInt err")
|
||||
}
|
||||
metric.Timestamp = time.Unix(pointTime, 0)
|
||||
pointVal, err := strconv.ParseFloat(point[0], 64)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "point parseInt err")
|
||||
}
|
||||
if influxDbSpecs[1] == UNIT_BYTEPS {
|
||||
pointVal = pointVal * 8
|
||||
}
|
||||
if influxDbSpecs[1] == UNIT_KBYTEPS {
|
||||
pointVal = pointVal * 8 * 1024
|
||||
}
|
||||
var pairsKey string
|
||||
if strings.Contains(influxDbSpec, ",") {
|
||||
pairsKey = common.SubstringBetween(influxDbSpec, ".", ",")
|
||||
} else {
|
||||
pairsKey = common.SubstringAfter(influxDbSpec, ".")
|
||||
}
|
||||
|
||||
tag := common.SubstringAfter(influxDbSpec, ",")
|
||||
if tag != "" && strings.Contains(influxDbSpec, "=") {
|
||||
metric.Tags = append(metric.Tags, influxdb.SKeyValue{
|
||||
Key: common.SubstringBefore(tag, "="),
|
||||
Value: common.SubstringAfter(tag, "="),
|
||||
})
|
||||
}
|
||||
metric.Metrics = append(metric.Metrics, influxdb.SKeyValue{
|
||||
Key: pairsKey,
|
||||
Value: strconv.FormatFloat(pointVal, 'f', -1, 64),
|
||||
})
|
||||
self.AddMetricTag(&metric, common.AddTags)
|
||||
datas = append(datas, metric)
|
||||
}
|
||||
return datas, nil
|
||||
}
|
||||
@@ -1,56 +0,0 @@
|
||||
// Copyright 2019 Yunion
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package ecloudmon
|
||||
|
||||
const (
|
||||
PERIOD = 60
|
||||
UNIT_AVERAGE = "Average"
|
||||
DEFAULT_STATISTICS = "Average,Minimum,Maximum"
|
||||
UNIT_PERCENT = "Percent"
|
||||
UNIT_BPS = "bps"
|
||||
UNIT_CPS = "cps"
|
||||
UNIT_MBPS = "Mbps"
|
||||
UNIT_BYTEPS = "Bps"
|
||||
UNIT_KBYTEPS = "KBps"
|
||||
UNIT_COUNT = "count"
|
||||
UNIT_MEM = "byte"
|
||||
|
||||
//ESC监控指标
|
||||
INFLUXDB_FIELD_CPU_USAGE = "vm_cpu.usage_active"
|
||||
INFLUXDB_FIELD_MEM_USAGE = "vm_mem.used_percent"
|
||||
INFLUXDB_FIELD_DISK_READ_BPS = "vm_diskio.read_bps"
|
||||
INFLUXDB_FIELD_DISK_WRITE_BPS = "vm_diskio.write_bps"
|
||||
INFLUXDB_FIELD_DISK_READ_IOPS = "vm_diskio.read_iops"
|
||||
INFLUXDB_FIELD_DISK_WRITE_IOPS = "vm_diskio.write_iops"
|
||||
INFLUXDB_FIELD_NET_BPS_RX = "vm_netio.bps_recv"
|
||||
INFLUXDB_FIELD_NET_BPS_TX = "vm_netio.bps_sent"
|
||||
|
||||
KEY_LIMIT = "limit"
|
||||
KEY_ADMIN = "admin"
|
||||
)
|
||||
|
||||
var ecloudProTypeMetric = map[string]string{}
|
||||
|
||||
//multiCloud查询指标列表组装
|
||||
var ecloudMetricSpecs = map[string][]string{
|
||||
"cpu_util": {DEFAULT_STATISTICS, UNIT_PERCENT, INFLUXDB_FIELD_CPU_USAGE},
|
||||
"memory.util": {DEFAULT_STATISTICS, UNIT_PERCENT, INFLUXDB_FIELD_MEM_USAGE},
|
||||
"disk.device.read.bytes.rate": {DEFAULT_STATISTICS, UNIT_KBYTEPS, INFLUXDB_FIELD_DISK_READ_BPS},
|
||||
"disk.device.write.bytes.rate": {DEFAULT_STATISTICS, UNIT_KBYTEPS, INFLUXDB_FIELD_DISK_WRITE_BPS},
|
||||
"disk.device.read.requests.rate": {DEFAULT_STATISTICS, UNIT_CPS, INFLUXDB_FIELD_DISK_READ_IOPS},
|
||||
"disk.device.write.requests.rate": {DEFAULT_STATISTICS, UNIT_CPS, INFLUXDB_FIELD_DISK_WRITE_IOPS},
|
||||
"network.incoming.bytes": {DEFAULT_STATISTICS, UNIT_BYTEPS, INFLUXDB_FIELD_NET_BPS_RX},
|
||||
"network.outgoing.bytes": {DEFAULT_STATISTICS, UNIT_BYTEPS, INFLUXDB_FIELD_NET_BPS_TX},
|
||||
}
|
||||
@@ -1,15 +0,0 @@
|
||||
// Copyright 2019 Yunion
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package gcpmon // import "yunion.io/x/onecloud/pkg/cloudmon/collectors/gcpmon"
|
||||
@@ -1,85 +0,0 @@
|
||||
// Copyright 2019 Yunion
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package gcpmon
|
||||
|
||||
import (
|
||||
"yunion.io/x/onecloud/pkg/apis/compute"
|
||||
"yunion.io/x/onecloud/pkg/cloudmon/collectors/common"
|
||||
"yunion.io/x/onecloud/pkg/cloudmon/options"
|
||||
"yunion.io/x/onecloud/pkg/mcclient"
|
||||
)
|
||||
|
||||
func init() {
|
||||
factory := SGoogleCloudReportFactory{}
|
||||
common.RegisterFactory(&factory)
|
||||
}
|
||||
|
||||
type SGoogleCloudReportFactory struct {
|
||||
common.CommonReportFactory
|
||||
}
|
||||
|
||||
func (self *SGoogleCloudReportFactory) NewCloudReport(provider *common.SProvider, session *mcclient.ClientSession,
|
||||
args *options.ReportOptions, operatorType string) common.ICloudReport {
|
||||
return &SGoogleCloudReport{
|
||||
common.CloudReportBase{
|
||||
SProvider: provider,
|
||||
Session: session,
|
||||
Args: args,
|
||||
Operator: operatorType,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func (self *SGoogleCloudReportFactory) GetId() string {
|
||||
return compute.CLOUD_PROVIDER_GOOGLE
|
||||
}
|
||||
|
||||
type SGoogleCloudReport struct {
|
||||
common.CloudReportBase
|
||||
}
|
||||
|
||||
func (self *SGoogleCloudReport) Report() error {
|
||||
servers, err := self.GetResourceByOperator()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
providerInstance, err := self.InitProviderInstance()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
regionList, regionServerMap, err := self.GetAllRegionOfServers(servers, providerInstance)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
for _, region := range regionList {
|
||||
servers := regionServerMap[region.GetGlobalId()]
|
||||
switch self.Operator {
|
||||
case "server":
|
||||
err = self.collectRegionMetricOfHost(region, servers)
|
||||
//case "redis":
|
||||
// err = self.collectRegionMetricOfRedis(region, servers)
|
||||
//case "rds":
|
||||
// err = self.collectRegionMetricOfRds(region, servers)
|
||||
//case "oss":
|
||||
// err = self.collectRegionMetricOfOss(region, servers)
|
||||
//case "elb":
|
||||
// err = self.collectRegionMetricOfElb(region, servers)
|
||||
}
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
@@ -1,159 +0,0 @@
|
||||
// Copyright 2019 Yunion
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package gcpmon
|
||||
|
||||
import (
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"yunion.io/x/jsonutils"
|
||||
"yunion.io/x/log"
|
||||
"yunion.io/x/pkg/util/timeutils"
|
||||
|
||||
"yunion.io/x/onecloud/pkg/cloudmon/collectors/common"
|
||||
"yunion.io/x/onecloud/pkg/cloudprovider"
|
||||
"yunion.io/x/onecloud/pkg/multicloud/google"
|
||||
"yunion.io/x/onecloud/pkg/util/influxdb"
|
||||
)
|
||||
|
||||
func (self *SGoogleCloudReport) collectRegionMetricOfHost(region cloudprovider.ICloudRegion,
|
||||
servers []jsonutils.JSONObject) error {
|
||||
dataList := make([]influxdb.SMetricData, 0)
|
||||
googleReg := region.(*google.SRegion)
|
||||
since, until, err := common.TimeRangeFromArgs(self.Args)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
for _, server := range servers {
|
||||
external_id, err := server.GetString("external_id")
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
serverName, _ := server.GetString("name")
|
||||
if strings.Contains(external_id, "/") {
|
||||
external_id = strings.Split(external_id, "/")[1]
|
||||
}
|
||||
for metricName, influxDbSpecs := range gcpMetricSpecs {
|
||||
rtn, err := googleReg.GetMonitorData(external_id, serverName, metricName, since, until)
|
||||
if err != nil {
|
||||
log.Errorln(err)
|
||||
continue
|
||||
}
|
||||
metric, err := common.FillVMCapacity(server.(*jsonutils.JSONDict))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
dataList = append(dataList, metric)
|
||||
for _, resp := range rtn.Value() {
|
||||
if !resp.(*jsonutils.JSONDict).Contains("points") {
|
||||
continue
|
||||
}
|
||||
serverMetric, err := self.collectMetricFromThisServer(server, resp, influxDbSpecs)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
dataList = append(dataList, serverMetric...)
|
||||
}
|
||||
}
|
||||
}
|
||||
return common.SendMetrics(self.Session, dataList, self.Args.Debug, "")
|
||||
}
|
||||
|
||||
func (self *SGoogleCloudReport) collectMetricFromThisServer(server jsonutils.JSONObject,
|
||||
rtnMetric jsonutils.JSONObject, influxDbSpecs []string) ([]influxdb.SMetricData, error) {
|
||||
datas := make([]influxdb.SMetricData, 0)
|
||||
points_, _ := rtnMetric.Get("points")
|
||||
for _, point := range points_.(*jsonutils.JSONArray).Value() {
|
||||
metric, err := common.JsonToMetric(server.(*jsonutils.JSONDict), "", common.ServerTags, make([]string, 0))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if time, err := point.Get("interval", "startTime"); err == nil {
|
||||
influxDbSpec := influxDbSpecs[2]
|
||||
|
||||
measurement := common.SubstringBefore(influxDbSpec, ".")
|
||||
metric.Name = measurement
|
||||
|
||||
timestamp, err := timeutils.ParseTimeStr(time.(*jsonutils.JSONString).Value())
|
||||
if err != nil {
|
||||
log.Errorln(err)
|
||||
continue
|
||||
}
|
||||
metric.Timestamp = timestamp
|
||||
|
||||
var pairsKey string
|
||||
if strings.Contains(influxDbSpec, ",") {
|
||||
pairsKey = common.SubstringBetween(influxDbSpec, ".", ",")
|
||||
} else {
|
||||
pairsKey = common.SubstringAfter(influxDbSpec, ".")
|
||||
}
|
||||
|
||||
tag := common.SubstringAfter(influxDbSpec, ",")
|
||||
if tag != "" && strings.Contains(influxDbSpec, "=") {
|
||||
metric.Tags = append(metric.Tags, influxdb.SKeyValue{
|
||||
Key: common.SubstringBefore(tag, "="),
|
||||
Value: common.SubstringAfter(tag, "="),
|
||||
})
|
||||
}
|
||||
|
||||
cpu_cout, err := server.Get("vcpu_count")
|
||||
if err == nil {
|
||||
metric.Metrics = append(metric.Metrics, influxdb.SKeyValue{
|
||||
Key: "cpu_count",
|
||||
Value: strconv.FormatInt(cpu_cout.(*jsonutils.JSONInt).Value(), 10),
|
||||
})
|
||||
}
|
||||
|
||||
valueTypeObj, _ := rtnMetric.Get("valueType")
|
||||
valueType := strings.ToLower(valueTypeObj.(*jsonutils.JSONString).Value())
|
||||
value := getMetricValue(point, valueType, influxDbSpecs[1])
|
||||
metric.Metrics = append(metric.Metrics, influxdb.SKeyValue{
|
||||
Key: pairsKey,
|
||||
Value: value,
|
||||
})
|
||||
self.AddMetricTag(&metric, common.AddTags)
|
||||
datas = append(datas, metric)
|
||||
}
|
||||
}
|
||||
return datas, nil
|
||||
}
|
||||
|
||||
func getMetricValue(point jsonutils.JSONObject, valueType string,
|
||||
influxDbSpec string) string {
|
||||
value, _ := point.Get("value", valueType+"Value")
|
||||
|
||||
switch valueType {
|
||||
case "int64":
|
||||
if val, ok := value.(*jsonutils.JSONString); ok {
|
||||
fieldValue, _ := strconv.ParseInt(val.Value(), 10, 64)
|
||||
if influxDbSpec == UNIT_MEM {
|
||||
fieldValue = fieldValue * 8 / PERIOD
|
||||
}
|
||||
return strconv.FormatInt(fieldValue, 10)
|
||||
}
|
||||
fieldValue := value.(*jsonutils.JSONInt).Value()
|
||||
if influxDbSpec == UNIT_MEM {
|
||||
fieldValue = fieldValue * 8 / PERIOD
|
||||
}
|
||||
return strconv.FormatInt(fieldValue, 10)
|
||||
case "double":
|
||||
fieldValue := value.(*jsonutils.JSONFloat).Value()
|
||||
if influxDbSpec == UNIT_MEM {
|
||||
fieldValue = fieldValue * 8 / PERIOD
|
||||
}
|
||||
return strconv.FormatFloat(fieldValue, 'f', 3, 64)
|
||||
}
|
||||
return ""
|
||||
}
|
||||
@@ -1,131 +0,0 @@
|
||||
// Copyright 2019 Yunion
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package gcpmon
|
||||
|
||||
const (
|
||||
PERIOD = 60
|
||||
UNIT_AVERAGE = "Average"
|
||||
DEFAULT_STATISTICS = "Average,Minimum,Maximum"
|
||||
UNIT_PERCENT = "Percent"
|
||||
UNIT_BPS = "bps"
|
||||
UNIT_MBPS = "Mbps"
|
||||
UNIT_BYTEPS = "Bps"
|
||||
UNIT_CPS = "cps"
|
||||
UNIT_COUNT = "count"
|
||||
UNIT_MEM = "byte"
|
||||
UNIT_MSEC = "ms"
|
||||
UNIT_COUNT_SEC = "count/s"
|
||||
|
||||
//ESC监控指标
|
||||
INFLUXDB_FIELD_CPU_USAGE = "vm_cpu.usage_active"
|
||||
INFLUXDB_FIELD_MEM_USAGE = "vm_mem.used_percent"
|
||||
INFLUXDB_FIELD_DISK_READ_BPS = "vm_diskio.read_bps"
|
||||
INFLUXDB_FIELD_DISK_WRITE_BPS = "vm_diskio.write_bps"
|
||||
INFLUXDB_FIELD_DISK_READ_IOPS = "vm_diskio.read_iops"
|
||||
INFLUXDB_FIELD_DISK_WRITE_IOPS = "vm_diskio.write_iops"
|
||||
INFLUXDB_FIELD_NET_BPS_RX = "vm_netio.bps_recv"
|
||||
INFLUXDB_FIELD_NET_BPS_RX_INTERNET = INFLUXDB_FIELD_NET_BPS_RX + ",net_type=internet"
|
||||
INFLUXDB_FIELD_NET_BPS_RX_INTRANET = INFLUXDB_FIELD_NET_BPS_RX + ",net_type=intranet"
|
||||
INFLUXDB_FIELD_NET_BPS_TX = "vm_netio.bps_sent"
|
||||
INFLUXDB_FIELD_NET_BPS_TX_INTERNET = INFLUXDB_FIELD_NET_BPS_TX + ",net_type=internet"
|
||||
INFLUXDB_FIELD_NET_BPS_TX_INTRANET = INFLUXDB_FIELD_NET_BPS_TX + ",net_type=intranet"
|
||||
INFLUXDB_FIELD_WANOUTTRAFFIC = "vm_eipio.bps_out"
|
||||
INFLUXDB_FIELD_WANINTRAFFIC = "vm_eipio.bps_in"
|
||||
INFLUXDB_FIELD_WANOUTPKG = "vm_eipio.pps_out"
|
||||
INFLUXDB_FIELD_WANINPKG = "vm_eipio.pps_in"
|
||||
|
||||
//RDS监控指标
|
||||
INFLUXDB_FIELD_RDS_CPU_USAGE = "rds_cpu.usage_active"
|
||||
INFLUXDB_FIELD_RDS_MEM_USAGE = "rds_mem.used_percent"
|
||||
INFLUXDB_FIELD_RDS_NET_BPS_RX = "rds_netio.bps_recv"
|
||||
INFLUXDB_FIELD_RDS_NET_BPS_RX_MYSQL = INFLUXDB_FIELD_RDS_NET_BPS_RX + ",server_type=mysql"
|
||||
INFLUXDB_FIELD_RDS_NET_BPS_RX_SQLSERVER = INFLUXDB_FIELD_RDS_NET_BPS_RX + ",server_type=sqlserver"
|
||||
INFLUXDB_FIELD_RDS_NET_BPS_TX = "rds_netio.bps_send"
|
||||
INFLUXDB_FIELD_RDS_NET_BPS_TX_MYSQL = INFLUXDB_FIELD_RDS_NET_BPS_TX + ",server_type=mysql"
|
||||
INFLUXDB_FIELD_RDS_NET_BPS_TX_SQLSERVER = INFLUXDB_FIELD_RDS_NET_BPS_TX + ",server_type=sqlserver"
|
||||
INFLUXDB_FIELD_RDS_DISK_USAGE = "rds_disk.used_percent"
|
||||
INFLUXDB_FIELD_RDS_DISK_READ_BPS = "rds_diskio.read_bps"
|
||||
INFLUXDB_FIELD_RDS_DISK_WRITE_BPS = "rds_diskio.write_bps"
|
||||
INFLUXDB_FIELD_RDS_CONN_COUNT = "rds_conn.used_count"
|
||||
INFLUXDB_FIELD_RDS_CONN_USAGE = "rds_conn.used_percent"
|
||||
|
||||
INFLUXDB_FIELD_RDS_QPS = "rds_qps.query_qps"
|
||||
INFLUXDB_FIELD_RDS_TPS = "rds_tps.trans_qps"
|
||||
INFLUXDB_FIELD_RDS_INNODB_REDA_BPS = "rds_innodb.read_bps"
|
||||
INFLUXDB_FIELD_RDS_INNODB_WRITE_BPS = "rds_innodb.write_bps"
|
||||
|
||||
//REDIS监控指标
|
||||
INFLUXDB_FIELD_REDIS_CPU_USAGE = "dcs_cpu.usage_percent"
|
||||
INFLUXDB_FIELD_REDIS_MEM_USAGE = "dcs_mem.used_percent"
|
||||
INFLUXDB_FIELD_REDIS_NET_BPS_RX = "dcs_netio.bps_recv"
|
||||
INFLUXDB_FIELD_REDIS_NET_BPS_TX = "dcs_netio.bps_sent"
|
||||
INFLUXDB_FIFLD_REDIS_CONN_USAGE = "dcs_conn.used_conn"
|
||||
INFLUXDB_FIFLD_REDIS_OPT_SES = "dcs_instantopt.opt_sec"
|
||||
INFLUXDB_FIFLD_REDIS_CACHE_KEYS = "dcs_cachekeys.key_count"
|
||||
INFLUXDB_FIFLD_REDIS_CACHE_EXP_KEYS = INFLUXDB_FIFLD_REDIS_CACHE_KEYS + ",exp=expire"
|
||||
INFLUXDB_FIFLD_REDIS_DATA_MEM_USAGE = "dcs_datamem.used_byte"
|
||||
|
||||
//对象存储OSS监控指标
|
||||
INFLUXDB_FIELD_OSS_NET_BPS_RX = "oss_netio.bps_recv"
|
||||
INFLUXDB_FIELD_OSS_NET_BPS_RX_INTERNET = INFLUXDB_FIELD_OSS_NET_BPS_RX + ",net_type=internet"
|
||||
INFLUXDB_FIELD_OSS_NET_BPS_RX_INTRANET = INFLUXDB_FIELD_OSS_NET_BPS_RX + ",net_type=intranet"
|
||||
INFLUXDB_FIELD_OSS_NET_BPS_TX = "oss_netio.bps_sent"
|
||||
INFLUXDB_FIELD_OSS_NET_BPS_TX_INTERNET = INFLUXDB_FIELD_OSS_NET_BPS_TX + ",net_type=internet"
|
||||
INFLUXDB_FIELD_OSS_NET_BPS_TX_INTRANET = INFLUXDB_FIELD_OSS_NET_BPS_TX + ",net_type=intranet"
|
||||
INFLUXDB_FIELD_OSS_LATECY = "oss_latency.req_late"
|
||||
INFLUXDB_FIELD_OSS_LATECY_GET = INFLUXDB_FIELD_OSS_LATECY + ",request=get"
|
||||
INFLUXDB_FIELD_OSS_LATECY_POST = INFLUXDB_FIELD_OSS_LATECY + ",request=post"
|
||||
INFLUXDB_FIELD_OSS_REQ_COUNT = "oss_req.req_count"
|
||||
INFLUXDB_FIELD_OSS_REQ_COUNT_GET = INFLUXDB_FIELD_OSS_REQ_COUNT + ",request=get"
|
||||
INFLUXDB_FIELD_OSS_REQ_COUNT_POST = INFLUXDB_FIELD_OSS_REQ_COUNT + ",request=post"
|
||||
INFLUXDB_FIELD_OSS_REQ_COUNT_5XX = INFLUXDB_FIELD_OSS_REQ_COUNT + ",request=5xx"
|
||||
INFLUXDB_FIELD_OSS_REQ_COUNT_4XX = INFLUXDB_FIELD_OSS_REQ_COUNT + ",request=4xx"
|
||||
|
||||
//负载均衡监控指标
|
||||
INFLUXDB_FIELD_ELB_NET_BPS_RX = "haproxy.bin"
|
||||
INFLUXDB_FIELD_ELB_NET_BPS_TX = "haproxy.bout"
|
||||
INFLUXDB_FIELD_ELB_REQ_RATE = "haproxy.req_rate,request=http"
|
||||
INFLUXDB_FIELD_ELB_CONN_RATE = "haproxy.conn_rate,request=tcp"
|
||||
INFLUXDB_FIELD_ELB_DREQ_COUNT = "haproxy.dreq,request=http"
|
||||
INFLUXDB_FIELD_ELB_DCONN_COUNT = "haproxy.dcon,request=tcp"
|
||||
INFLUXDB_FIELD_ELB_HRSP_COUNT = "haproxy.hrsp_Nxx"
|
||||
INFLUXDB_FIELD_ELB_HRSP_COUNT_2XX = INFLUXDB_FIELD_ELB_HRSP_COUNT + ",request=2xx"
|
||||
INFLUXDB_FIELD_ELB_HRSP_COUNT_3XX = INFLUXDB_FIELD_ELB_HRSP_COUNT + ",request=3xx"
|
||||
INFLUXDB_FIELD_ELB_HRSP_COUNT_4XX = INFLUXDB_FIELD_ELB_HRSP_COUNT + ",request=4xx"
|
||||
INFLUXDB_FIELD_ELB_HRSP_COUNT_5XX = INFLUXDB_FIELD_ELB_HRSP_COUNT + ",request=5xx"
|
||||
INFLUXDB_FIELD_ELB_CHC_STATUS = "haproxy.check_status"
|
||||
INFLUXDB_FIELD_ELB_CHC_CODE = "haproxy.check_code"
|
||||
INFLUXDB_FIELD_ELB_LAST_CHC = "haproxy.last_chk"
|
||||
|
||||
KEY_VMS = "vms"
|
||||
KEY_CPUS = "cpus"
|
||||
KEY_MEMS = "mems"
|
||||
KEY_DISKS = "disks"
|
||||
|
||||
KEY_LIMIT = "limit"
|
||||
KEY_ADMIN = "admin"
|
||||
KEY_USABLE = "usable"
|
||||
)
|
||||
|
||||
//multiCloud查询指标列表组装
|
||||
var gcpMetricSpecs = map[string][]string{
|
||||
"compute.googleapis.com/instance/cpu/utilization": {DEFAULT_STATISTICS, UNIT_PERCENT, INFLUXDB_FIELD_CPU_USAGE},
|
||||
"compute.googleapis.com/instance/network/received_bytes_count": {DEFAULT_STATISTICS, UNIT_MEM, INFLUXDB_FIELD_NET_BPS_RX},
|
||||
"compute.googleapis.com/instance/network/sent_bytes_count": {DEFAULT_STATISTICS, UNIT_MEM, INFLUXDB_FIELD_NET_BPS_TX},
|
||||
"compute.googleapis.com/instance/disk/read_bytes_count": {DEFAULT_STATISTICS, UNIT_MEM, INFLUXDB_FIELD_DISK_READ_BPS},
|
||||
"compute.googleapis.com/instance/disk/write_bytes_count": {DEFAULT_STATISTICS, UNIT_MEM, INFLUXDB_FIELD_DISK_WRITE_BPS},
|
||||
"compute.googleapis.com/instance/disk/read_ops_count": {DEFAULT_STATISTICS, UNIT_MEM, INFLUXDB_FIELD_DISK_READ_IOPS},
|
||||
"compute.googleapis.com/instance/disk/write_ops_count": {DEFAULT_STATISTICS, UNIT_MEM, INFLUXDB_FIELD_DISK_WRITE_IOPS},
|
||||
}
|
||||
@@ -1,15 +0,0 @@
|
||||
// Copyright 2019 Yunion
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package huaweimon // import "yunion.io/x/onecloud/pkg/cloudmon/collectors/huaweimon"
|
||||
@@ -1,102 +0,0 @@
|
||||
// Copyright 2019 Yunion
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package huaweimon
|
||||
|
||||
import (
|
||||
"yunion.io/x/jsonutils"
|
||||
|
||||
"yunion.io/x/onecloud/pkg/apis/compute"
|
||||
"yunion.io/x/onecloud/pkg/cloudmon/collectors/common"
|
||||
"yunion.io/x/onecloud/pkg/cloudmon/options"
|
||||
"yunion.io/x/onecloud/pkg/mcclient"
|
||||
)
|
||||
|
||||
func init() {
|
||||
factory := SHwCloudReportFactory{}
|
||||
common.RegisterFactory(&factory)
|
||||
|
||||
stackFactory := SHwStackCloudReportFactory{
|
||||
&SHwCloudReportFactory{},
|
||||
}
|
||||
common.RegisterFactory(&stackFactory)
|
||||
}
|
||||
|
||||
type SHwCloudReportFactory struct {
|
||||
common.CommonReportFactory
|
||||
}
|
||||
|
||||
func (self *SHwCloudReportFactory) NewCloudReport(provider *common.SProvider, session *mcclient.ClientSession,
|
||||
args *options.ReportOptions, operatorType string) common.ICloudReport {
|
||||
return &SHwCloudReport{
|
||||
common.CloudReportBase{
|
||||
SProvider: provider,
|
||||
Session: session,
|
||||
Args: args,
|
||||
Operator: operatorType,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func (self *SHwCloudReportFactory) GetId() string {
|
||||
return compute.CLOUD_PROVIDER_HUAWEI
|
||||
}
|
||||
|
||||
type SHwCloudReport struct {
|
||||
common.CloudReportBase
|
||||
}
|
||||
|
||||
func (self *SHwCloudReport) Report() error {
|
||||
var servers []jsonutils.JSONObject
|
||||
var err error
|
||||
servers, err = self.GetResourceByOperator()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
providerInstance, err := self.InitProviderInstance()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
regionList, regionServerMap, err := self.GetAllRegionOfServers(servers, providerInstance)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
for _, region := range regionList {
|
||||
servers := regionServerMap[region.GetGlobalId()]
|
||||
switch self.Operator {
|
||||
case "server":
|
||||
err = self.collectRegionMetricOfHost(region, servers)
|
||||
case "redis":
|
||||
err = self.collectRegionMetricOfRedis(region, servers)
|
||||
case "rds":
|
||||
err = self.collectRegionMetricOfRds(region, servers)
|
||||
case "oss":
|
||||
err = self.collectRegionMetricOfOss(region, servers)
|
||||
case "elb":
|
||||
err = self.collectRegionMetricOfElb(region, servers)
|
||||
}
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type SHwStackCloudReportFactory struct {
|
||||
*SHwCloudReportFactory
|
||||
}
|
||||
|
||||
func (self *SHwStackCloudReportFactory) GetId() string {
|
||||
return compute.CLOUD_PROVIDER_HCSO
|
||||
}
|
||||
@@ -1,353 +0,0 @@
|
||||
// Copyright 2019 Yunion
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package huaweimon
|
||||
|
||||
import (
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"yunion.io/x/jsonutils"
|
||||
"yunion.io/x/log"
|
||||
|
||||
"yunion.io/x/onecloud/pkg/apis/compute"
|
||||
"yunion.io/x/onecloud/pkg/cloudmon/collectors/common"
|
||||
"yunion.io/x/onecloud/pkg/cloudprovider"
|
||||
"yunion.io/x/onecloud/pkg/multicloud/hcso"
|
||||
"yunion.io/x/onecloud/pkg/multicloud/huawei"
|
||||
hw_moudules "yunion.io/x/onecloud/pkg/multicloud/huawei/client/modules"
|
||||
"yunion.io/x/onecloud/pkg/util/influxdb"
|
||||
)
|
||||
|
||||
func (self *SHwCloudReport) collectRegionMetricOfHost(region cloudprovider.ICloudRegion, servers []jsonutils.JSONObject) error {
|
||||
dataList := make([]influxdb.SMetricData, 0)
|
||||
since, until, err := common.TimeRangeFromArgs(self.Args)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
for _, server := range servers {
|
||||
instanceId, _ := server.GetString("external_id")
|
||||
metric, err := common.FillVMCapacity(server.(*jsonutils.JSONDict))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
dataList = append(dataList, metric)
|
||||
metas := make([]hw_moudules.SMetricMeta, 0)
|
||||
for metricName := range huaweiMetricSpecs {
|
||||
hwMeta := hw_moudules.SMetricMeta{}
|
||||
hwMeta.MetricName = metricName
|
||||
hwMeta.Namespace = "SYS.ECS"
|
||||
hwMeta.Dimensions = make([]hw_moudules.SMetricDimension, 0)
|
||||
hwMeta.Dimensions = append(hwMeta.Dimensions, hw_moudules.SMetricDimension{Name: "instance_id", Value: instanceId})
|
||||
metas = append(metas, hwMeta)
|
||||
}
|
||||
metricDatas, err := self.GetMetricData(region, metas, since, until)
|
||||
if err != nil {
|
||||
log.Errorln(err)
|
||||
continue
|
||||
}
|
||||
if len(metricDatas) > 0 {
|
||||
for _, metricData := range metricDatas {
|
||||
for metricName, influxDbSpecs := range huaweiMetricSpecs {
|
||||
if metricData.MetricName == metricName {
|
||||
if len(metricData.Datapoints) > 0 {
|
||||
for _, datapoint := range metricData.Datapoints {
|
||||
serverMetric, err := self.collectMetricFromThisServer(server, datapoint,
|
||||
influxDbSpecs)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
dataList = append(dataList, serverMetric)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
return common.SendMetrics(self.Session, dataList, self.Args.Debug, "")
|
||||
}
|
||||
|
||||
func (self *SHwCloudReport) collectRegionMetricOfRedis(region cloudprovider.ICloudRegion, servers []jsonutils.JSONObject) error {
|
||||
dataList := make([]influxdb.SMetricData, 0)
|
||||
|
||||
hwReg := region.(*huawei.SRegion)
|
||||
since, until, err := common.TimeRangeFromArgs(self.Args)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
for _, server := range servers {
|
||||
instanceId, _ := server.GetString("external_id")
|
||||
metas := make([]hw_moudules.SMetricMeta, 0)
|
||||
for metricName := range huaweiRedisMetricSpecs {
|
||||
hwMeta := hw_moudules.SMetricMeta{}
|
||||
hwMeta.MetricName = metricName
|
||||
hwMeta.Namespace = "SYS.DCS"
|
||||
hwMeta.Dimensions = make([]hw_moudules.SMetricDimension, 0)
|
||||
hwMeta.Dimensions = append(hwMeta.Dimensions, hw_moudules.SMetricDimension{Name: "dcs_instance_id", Value: instanceId})
|
||||
metas = append(metas, hwMeta)
|
||||
}
|
||||
|
||||
metricDatas, err := hwReg.GetMetricsData(metas, since, until)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if len(metricDatas) > 0 {
|
||||
for _, metricData := range metricDatas {
|
||||
for metricName, influxDbSpecs := range huaweiRedisMetricSpecs {
|
||||
if metricData.MetricName == metricName {
|
||||
if len(metricData.Datapoints) > 0 {
|
||||
for _, datapoint := range metricData.Datapoints {
|
||||
serverMetric, err := self.collectMetricFromThisServer(server, datapoint,
|
||||
influxDbSpecs)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
dataList = append(dataList, serverMetric)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
return common.SendMetrics(self.Session, dataList, self.Args.Debug, "")
|
||||
}
|
||||
|
||||
func (self *SHwCloudReport) collectRegionMetricOfRds(region cloudprovider.ICloudRegion,
|
||||
servers []jsonutils.JSONObject) error {
|
||||
dataList := make([]influxdb.SMetricData, 0)
|
||||
|
||||
since, until, err := common.TimeRangeFromArgs(self.Args)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
for _, server := range servers {
|
||||
instanceId, _ := server.GetString("external_id")
|
||||
engine, _ := server.GetString("engine")
|
||||
metric, err := common.FillVMCapacity(server.(*jsonutils.JSONDict))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
dataList = append(dataList, metric)
|
||||
metas := make([]hw_moudules.SMetricMeta, 0)
|
||||
for metricName := range huaweiRdsMetricSpecs {
|
||||
hwMeta := hw_moudules.SMetricMeta{}
|
||||
hwMeta.MetricName = metricName
|
||||
hwMeta.Namespace = "SYS.RDS"
|
||||
hwMeta.Dimensions = make([]hw_moudules.SMetricDimension, 0)
|
||||
switch engine {
|
||||
case "MySQL":
|
||||
hwMeta.Dimensions = append(hwMeta.Dimensions, hw_moudules.SMetricDimension{Name: "rds_cluster_id", Value: instanceId})
|
||||
case "PostgreSQL":
|
||||
hwMeta.Dimensions = append(hwMeta.Dimensions, hw_moudules.SMetricDimension{Name: "postgresql_cluster_id", Value: instanceId})
|
||||
case "SQLServer":
|
||||
hwMeta.Dimensions = append(hwMeta.Dimensions, hw_moudules.SMetricDimension{Name: "rds_cluster_sqlserver_id", Value: instanceId})
|
||||
}
|
||||
metas = append(metas, hwMeta)
|
||||
}
|
||||
index := 0
|
||||
tmp := 0
|
||||
for {
|
||||
if index > len(metas) {
|
||||
break
|
||||
}
|
||||
tmp = index + 10
|
||||
if tmp > len(metas) {
|
||||
tmp = len(metas)
|
||||
}
|
||||
metricDatas, err := self.GetMetricData(region, metas[index:tmp], since, until)
|
||||
if err != nil {
|
||||
log.Errorln(err)
|
||||
continue
|
||||
}
|
||||
if len(metricDatas) > 0 {
|
||||
for _, metricData := range metricDatas {
|
||||
for metricName, influxDbSpecs := range huaweiRdsMetricSpecs {
|
||||
if metricData.MetricName == metricName {
|
||||
if len(metricData.Datapoints) > 0 {
|
||||
for _, datapoint := range metricData.Datapoints {
|
||||
serverMetric, err := self.collectMetricFromThisServer(server, datapoint, influxDbSpecs)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
dataList = append(dataList, serverMetric)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
index += 10
|
||||
}
|
||||
}
|
||||
return common.SendMetrics(self.Session, dataList, self.Args.Debug, "")
|
||||
}
|
||||
|
||||
func (self *SHwCloudReport) collectRegionMetricOfOss(region cloudprovider.ICloudRegion,
|
||||
servers []jsonutils.JSONObject) error {
|
||||
dataList := make([]influxdb.SMetricData, 0)
|
||||
hwReg := region.(*huawei.SRegion)
|
||||
since, until, err := common.TimeRangeFromArgs(self.Args)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
for _, server := range servers {
|
||||
name, _ := server.GetString("name")
|
||||
metas := make([]hw_moudules.SMetricMeta, 0)
|
||||
for metricName := range huaweiOSSMetricSpecs {
|
||||
hwMeta := hw_moudules.SMetricMeta{}
|
||||
hwMeta.MetricName = metricName
|
||||
hwMeta.Namespace = "SYS.OBS"
|
||||
hwMeta.Dimensions = make([]hw_moudules.SMetricDimension, 0)
|
||||
hwMeta.Dimensions = append(hwMeta.Dimensions, hw_moudules.SMetricDimension{Name: "bucket_name", Value: name})
|
||||
metas = append(metas, hwMeta)
|
||||
}
|
||||
|
||||
metricDatas, err := hwReg.GetMetricsData(metas, since, until)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if len(metricDatas) > 0 {
|
||||
for _, metricData := range metricDatas {
|
||||
for metricName, influxDbSpecs := range huaweiOSSMetricSpecs {
|
||||
if metricData.MetricName == metricName {
|
||||
if len(metricData.Datapoints) > 0 {
|
||||
for _, datapoint := range metricData.Datapoints {
|
||||
serverMetric, err := self.collectMetricFromThisServer(server, datapoint,
|
||||
influxDbSpecs)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
dataList = append(dataList, serverMetric)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
return common.SendMetrics(self.Session, dataList, self.Args.Debug, "")
|
||||
}
|
||||
|
||||
func (self *SHwCloudReport) collectRegionMetricOfElb(region cloudprovider.ICloudRegion, servers []jsonutils.JSONObject) error {
|
||||
dataList := make([]influxdb.SMetricData, 0)
|
||||
hwReg := region.(*huawei.SRegion)
|
||||
since, until, err := common.TimeRangeFromArgs(self.Args)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
for _, server := range servers {
|
||||
external_id, _ := server.GetString("external_id")
|
||||
metas := make([]hw_moudules.SMetricMeta, 0)
|
||||
for metricName := range huaweiOSSMetricSpecs {
|
||||
hwMeta := hw_moudules.SMetricMeta{}
|
||||
hwMeta.MetricName = metricName
|
||||
hwMeta.Namespace = "SYS.ELB"
|
||||
hwMeta.Dimensions = make([]hw_moudules.SMetricDimension, 0)
|
||||
hwMeta.Dimensions = append(hwMeta.Dimensions, hw_moudules.SMetricDimension{Name: "lb_instance_id", Value: external_id})
|
||||
metas = append(metas, hwMeta)
|
||||
}
|
||||
|
||||
metricDatas, err := hwReg.GetMetricsData(metas, since, until)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if len(metricDatas) > 0 {
|
||||
for _, metricData := range metricDatas {
|
||||
for metricName, influxDbSpecs := range huaweiOSSMetricSpecs {
|
||||
if metricData.MetricName == metricName {
|
||||
if len(metricData.Datapoints) > 0 {
|
||||
for _, datapoint := range metricData.Datapoints {
|
||||
serverMetric, err := self.collectMetricFromThisServer(server, datapoint,
|
||||
influxDbSpecs)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
dataList = append(dataList, serverMetric)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
return common.SendMetrics(self.Session, dataList, self.Args.Debug, "")
|
||||
}
|
||||
|
||||
func (self *SHwCloudReport) collectMetricFromThisServer(server jsonutils.JSONObject, datapoint hw_moudules.SDatapoint,
|
||||
influxDbSpecs []string) (influxdb.SMetricData, error) {
|
||||
metric, err := self.NewMetricFromJson(server)
|
||||
//metric, err := common.JsonToMetric(server.(*jsonutils.JSONDict), "", common.ServerTags, make([]string, 0))
|
||||
if err != nil {
|
||||
return influxdb.SMetricData{}, err
|
||||
}
|
||||
metric.Timestamp = time.Unix(datapoint.Timestamp/1000, 0)
|
||||
fieldValue := datapoint.Average
|
||||
//根据条件拼装metric的tag和metirc信息
|
||||
influxDbSpec := influxDbSpecs[2]
|
||||
measurement := common.SubstringBefore(influxDbSpec, ".")
|
||||
var pairsKey string
|
||||
if strings.Contains(influxDbSpec, ",") {
|
||||
pairsKey = common.SubstringBetween(influxDbSpec, ".", ",")
|
||||
} else {
|
||||
pairsKey = common.SubstringAfter(influxDbSpec, ".")
|
||||
}
|
||||
if influxDbSpecs[1] == UNIT_BYTEPS {
|
||||
fieldValue = fieldValue * 8
|
||||
}
|
||||
tag := common.SubstringAfter(influxDbSpec, ",")
|
||||
if tag != "" && strings.Contains(influxDbSpec, "=") {
|
||||
metric.Tags = append(metric.Tags, influxdb.SKeyValue{
|
||||
Key: common.SubstringBefore(tag, "="),
|
||||
Value: common.SubstringAfter(tag, "="),
|
||||
})
|
||||
}
|
||||
cpu_cout, err := server.Get("vcpu_count")
|
||||
if err == nil {
|
||||
metric.Metrics = append(metric.Metrics, influxdb.SKeyValue{
|
||||
Key: "cpu_count",
|
||||
Value: strconv.FormatInt(cpu_cout.(*jsonutils.JSONInt).Value(), 10),
|
||||
})
|
||||
}
|
||||
metric.Metrics = append(metric.Metrics, influxdb.SKeyValue{
|
||||
Key: pairsKey,
|
||||
Value: strconv.FormatFloat(fieldValue, 'E', -1, 64),
|
||||
})
|
||||
metric.Name = measurement
|
||||
return metric, nil
|
||||
}
|
||||
|
||||
func (self *SHwCloudReport) GetMetricData(region cloudprovider.ICloudRegion, metrics []hw_moudules.SMetricMeta,
|
||||
since time.Time, until time.Time) ([]hw_moudules.SMetricData, error) {
|
||||
switch self.SProvider.Provider {
|
||||
case compute.CLOUD_PROVIDER_HCSO:
|
||||
hwReg := region.(*hcso.SRegion)
|
||||
return hwReg.GetMetricsData(metrics, since, until)
|
||||
default:
|
||||
hwReg := region.(*huawei.SRegion)
|
||||
return hwReg.GetMetricsData(metrics, since, until)
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,176 +0,0 @@
|
||||
// Copyright 2019 Yunion
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package huaweimon
|
||||
|
||||
const (
|
||||
PERIOD = 60
|
||||
UNIT_AVERAGE = "Average"
|
||||
DEFAULT_STATISTICS = "Average,Minimum,Maximum"
|
||||
UNIT_PERCENT = "Percent"
|
||||
UNIT_BPS = "bps"
|
||||
UNIT_MBPS = "Mbps"
|
||||
UNIT_BYTEPS = "Bps"
|
||||
UNIT_CPS = "cps"
|
||||
UNIT_COUNT = "count"
|
||||
UNIT_MEM = "byte"
|
||||
UNIT_MSEC = "ms"
|
||||
UNIT_COUNT_SEC = "count/s"
|
||||
|
||||
//ESC监控指标
|
||||
INFLUXDB_FIELD_CPU_USAGE = "vm_cpu.usage_active"
|
||||
INFLUXDB_FIELD_MEM_USAGE = "vm_mem.used_percent"
|
||||
INFLUXDB_FIELD_DISK_READ_BPS = "vm_diskio.read_bps"
|
||||
INFLUXDB_FIELD_DISK_WRITE_BPS = "vm_diskio.write_bps"
|
||||
INFLUXDB_FIELD_DISK_READ_IOPS = "vm_diskio.read_iops"
|
||||
INFLUXDB_FIELD_DISK_WRITE_IOPS = "vm_diskio.write_iops"
|
||||
INFLUXDB_FIELD_NET_BPS_RX = "vm_netio.bps_recv"
|
||||
INFLUXDB_FIELD_NET_BPS_RX_INTERNET = INFLUXDB_FIELD_NET_BPS_RX + ",net_type=internet"
|
||||
INFLUXDB_FIELD_NET_BPS_RX_INTRANET = INFLUXDB_FIELD_NET_BPS_RX + ",net_type=intranet"
|
||||
INFLUXDB_FIELD_NET_BPS_TX = "vm_netio.bps_sent"
|
||||
INFLUXDB_FIELD_NET_BPS_TX_INTERNET = INFLUXDB_FIELD_NET_BPS_TX + ",net_type=internet"
|
||||
INFLUXDB_FIELD_NET_BPS_TX_INTRANET = INFLUXDB_FIELD_NET_BPS_TX + ",net_type=intranet"
|
||||
INFLUXDB_FIELD_WANOUTTRAFFIC = "vm_eipio.bps_out"
|
||||
INFLUXDB_FIELD_WANINTRAFFIC = "vm_eipio.bps_in"
|
||||
INFLUXDB_FIELD_WANOUTPKG = "vm_eipio.pps_out"
|
||||
INFLUXDB_FIELD_WANINPKG = "vm_eipio.pps_in"
|
||||
|
||||
//RDS监控指标
|
||||
INFLUXDB_FIELD_RDS_CPU_USAGE = "rds_cpu.usage_active"
|
||||
INFLUXDB_FIELD_RDS_MEM_USAGE = "rds_mem.used_percent"
|
||||
INFLUXDB_FIELD_RDS_NET_BPS_RX = "rds_netio.bps_recv"
|
||||
INFLUXDB_FIELD_RDS_NET_BPS_RX_MYSQL = INFLUXDB_FIELD_RDS_NET_BPS_RX + ",server_type=mysql"
|
||||
INFLUXDB_FIELD_RDS_NET_BPS_RX_SQLSERVER = INFLUXDB_FIELD_RDS_NET_BPS_RX + ",server_type=sqlserver"
|
||||
INFLUXDB_FIELD_RDS_NET_BPS_TX = "rds_netio.bps_sent"
|
||||
INFLUXDB_FIELD_RDS_NET_BPS_TX_MYSQL = INFLUXDB_FIELD_RDS_NET_BPS_TX + ",server_type=mysql"
|
||||
INFLUXDB_FIELD_RDS_NET_BPS_TX_SQLSERVER = INFLUXDB_FIELD_RDS_NET_BPS_TX + ",server_type=sqlserver"
|
||||
INFLUXDB_FIELD_RDS_DISK_USAGE = "rds_disk.used_percent"
|
||||
INFLUXDB_FIELD_RDS_DISK_READ_BPS = "rds_diskio.read_bps"
|
||||
INFLUXDB_FIELD_RDS_DISK_WRITE_BPS = "rds_diskio.write_bps"
|
||||
INFLUXDB_FIELD_RDS_CONN_COUNT = "rds_conn.used_count"
|
||||
INFLUXDB_FIELD_RDS_CONN_USAGE = "rds_conn.used_percent"
|
||||
|
||||
INFLUXDB_FIELD_RDS_QPS = "rds_qps.query_qps"
|
||||
INFLUXDB_FIELD_RDS_TPS = "rds_tps.trans_qps"
|
||||
INFLUXDB_FIELD_RDS_INNODB_REDA_BPS = "rds_innodb.read_bps"
|
||||
INFLUXDB_FIELD_RDS_INNODB_WRITE_BPS = "rds_innodb.write_bps"
|
||||
|
||||
//REDIS监控指标
|
||||
INFLUXDB_FIELD_REDIS_CPU_USAGE = "dcs_cpu.usage_percent"
|
||||
INFLUXDB_FIELD_REDIS_MEM_USAGE = "dcs_mem.used_percent"
|
||||
INFLUXDB_FIELD_REDIS_NET_BPS_RX = "dcs_netio.bps_recv"
|
||||
INFLUXDB_FIELD_REDIS_NET_BPS_TX = "dcs_netio.bps_sent"
|
||||
INFLUXDB_FIFLD_REDIS_CONN_USAGE = "dcs_conn.used_conn"
|
||||
INFLUXDB_FIFLD_REDIS_OPT_SES = "dcs_instantopt.opt_sec"
|
||||
INFLUXDB_FIFLD_REDIS_CACHE_KEYS = "dcs_cachekeys.key_count"
|
||||
INFLUXDB_FIFLD_REDIS_CACHE_EXP_KEYS = INFLUXDB_FIFLD_REDIS_CACHE_KEYS + ",exp=expire"
|
||||
INFLUXDB_FIFLD_REDIS_DATA_MEM_USAGE = "dcs_datamem.used_byte"
|
||||
|
||||
//对象存储OSS监控指标
|
||||
INFLUXDB_FIELD_OSS_NET_BPS_RX = "oss_netio.bps_recv"
|
||||
INFLUXDB_FIELD_OSS_NET_BPS_RX_INTERNET = INFLUXDB_FIELD_OSS_NET_BPS_RX + ",net_type=internet"
|
||||
INFLUXDB_FIELD_OSS_NET_BPS_RX_INTRANET = INFLUXDB_FIELD_OSS_NET_BPS_RX + ",net_type=intranet"
|
||||
INFLUXDB_FIELD_OSS_NET_BPS_TX = "oss_netio.bps_sent"
|
||||
INFLUXDB_FIELD_OSS_NET_BPS_TX_INTERNET = INFLUXDB_FIELD_OSS_NET_BPS_TX + ",net_type=internet"
|
||||
INFLUXDB_FIELD_OSS_NET_BPS_TX_INTRANET = INFLUXDB_FIELD_OSS_NET_BPS_TX + ",net_type=intranet"
|
||||
INFLUXDB_FIELD_OSS_LATECY = "oss_latency.req_late"
|
||||
INFLUXDB_FIELD_OSS_LATECY_GET = INFLUXDB_FIELD_OSS_LATECY + ",request=get"
|
||||
INFLUXDB_FIELD_OSS_LATECY_POST = INFLUXDB_FIELD_OSS_LATECY + ",request=post"
|
||||
INFLUXDB_FIELD_OSS_REQ_COUNT = "oss_req.req_count"
|
||||
INFLUXDB_FIELD_OSS_REQ_COUNT_GET = INFLUXDB_FIELD_OSS_REQ_COUNT + ",request=get"
|
||||
INFLUXDB_FIELD_OSS_REQ_COUNT_POST = INFLUXDB_FIELD_OSS_REQ_COUNT + ",request=post"
|
||||
INFLUXDB_FIELD_OSS_REQ_COUNT_5XX = INFLUXDB_FIELD_OSS_REQ_COUNT + ",request=5xx"
|
||||
INFLUXDB_FIELD_OSS_REQ_COUNT_4XX = INFLUXDB_FIELD_OSS_REQ_COUNT + ",request=4xx"
|
||||
|
||||
//负载均衡监控指标
|
||||
INFLUXDB_FIELD_ELB_NET_BPS_RX = "haproxy.bin"
|
||||
INFLUXDB_FIELD_ELB_NET_BPS_TX = "haproxy.bout"
|
||||
INFLUXDB_FIELD_ELB_REQ_RATE = "haproxy.req_rate,request=http"
|
||||
INFLUXDB_FIELD_ELB_CONN_RATE = "haproxy.conn_rate,request=tcp"
|
||||
INFLUXDB_FIELD_ELB_DREQ_COUNT = "haproxy.dreq,request=http"
|
||||
INFLUXDB_FIELD_ELB_DCONN_COUNT = "haproxy.dcon,request=tcp"
|
||||
INFLUXDB_FIELD_ELB_HRSP_COUNT = "haproxy.hrsp_Nxx"
|
||||
INFLUXDB_FIELD_ELB_HRSP_COUNT_2XX = INFLUXDB_FIELD_ELB_HRSP_COUNT + ",request=2xx"
|
||||
INFLUXDB_FIELD_ELB_HRSP_COUNT_3XX = INFLUXDB_FIELD_ELB_HRSP_COUNT + ",request=3xx"
|
||||
INFLUXDB_FIELD_ELB_HRSP_COUNT_4XX = INFLUXDB_FIELD_ELB_HRSP_COUNT + ",request=4xx"
|
||||
INFLUXDB_FIELD_ELB_HRSP_COUNT_5XX = INFLUXDB_FIELD_ELB_HRSP_COUNT + ",request=5xx"
|
||||
INFLUXDB_FIELD_ELB_CHC_STATUS = "haproxy.check_status"
|
||||
INFLUXDB_FIELD_ELB_CHC_CODE = "haproxy.check_code"
|
||||
INFLUXDB_FIELD_ELB_LAST_CHC = "haproxy.last_chk"
|
||||
|
||||
KEY_VMS = "vms"
|
||||
KEY_CPUS = "cpus"
|
||||
KEY_MEMS = "mems"
|
||||
KEY_DISKS = "disks"
|
||||
)
|
||||
|
||||
var huaweiMetricSpecs = map[string][]string{
|
||||
"cpu_util": {DEFAULT_STATISTICS, UNIT_PERCENT, INFLUXDB_FIELD_CPU_USAGE}, //CPU使用率,该指标用于统计测量对象的CPU使用率,以百分为单位。
|
||||
"network_incoming_bytes_aggregate_rate": {DEFAULT_STATISTICS, UNIT_BYTEPS, INFLUXDB_FIELD_NET_BPS_RX_INTERNET}, //带外网络流入速率,该指标用于在虚拟化层统计每秒流入测量对象的网络流量,以字节/秒为单位。
|
||||
"network_outgoing_bytes_aggregate_rate": {DEFAULT_STATISTICS, UNIT_BYTEPS, INFLUXDB_FIELD_NET_BPS_TX_INTERNET}, //带外网络流出速率,该指标用于在虚拟化层统计每秒流出测量对象的网络流量,以字节/秒为单位。
|
||||
"disk_read_bytes_rate": {DEFAULT_STATISTICS, UNIT_BYTEPS, INFLUXDB_FIELD_DISK_READ_BPS}, //磁盘读速率,该指标用于统计每秒从测量对象读出数据量,以字节/秒为单位。
|
||||
"disk_write_bytes_rate": {DEFAULT_STATISTICS, UNIT_BYTEPS, INFLUXDB_FIELD_DISK_WRITE_BPS}, //磁盘写速率,该指标用于统计每秒写到测量对象的数据量,以字节/秒为单位。
|
||||
"disk_read_requests_rate": {DEFAULT_STATISTICS, UNIT_CPS, INFLUXDB_FIELD_DISK_READ_IOPS}, //该指标用于统计每秒从测量对象读取数据的请求次数,以请求/秒为单位。
|
||||
"disk_write_requests_rate": {DEFAULT_STATISTICS, UNIT_CPS, INFLUXDB_FIELD_DISK_WRITE_IOPS}, //该指标用于统计每秒从测量对象写数据的请求次数,以请求/秒为单位
|
||||
}
|
||||
|
||||
var huaweiRdsMetricSpecs = map[string][]string{
|
||||
"rds001_cpu_util": {DEFAULT_STATISTICS, UNIT_PERCENT, INFLUXDB_FIELD_RDS_CPU_USAGE},
|
||||
"rds002_mem_util": {DEFAULT_STATISTICS, UNIT_PERCENT, INFLUXDB_FIELD_RDS_MEM_USAGE},
|
||||
"rds004_bytes_in": {DEFAULT_STATISTICS, UNIT_BYTEPS, INFLUXDB_FIELD_RDS_NET_BPS_RX},
|
||||
"rds005_bytes_out": {DEFAULT_STATISTICS, UNIT_BYTEPS, INFLUXDB_FIELD_RDS_NET_BPS_TX},
|
||||
"rds039_disk_util": {DEFAULT_STATISTICS, UNIT_PERCENT, INFLUXDB_FIELD_RDS_DISK_USAGE},
|
||||
"rds049_disk_read_throughput": {DEFAULT_STATISTICS, UNIT_BYTEPS, INFLUXDB_FIELD_RDS_DISK_READ_BPS},
|
||||
|
||||
"rds050_disk_write_throughput": {DEFAULT_STATISTICS, UNIT_BYTEPS, INFLUXDB_FIELD_RDS_DISK_WRITE_BPS},
|
||||
|
||||
"rds006_conn_count": {DEFAULT_STATISTICS, UNIT_PERCENT, INFLUXDB_FIELD_RDS_CONN_COUNT},
|
||||
|
||||
"rds008_qps": {DEFAULT_STATISTICS, UNIT_PERCENT, INFLUXDB_FIELD_RDS_QPS},
|
||||
"rds009_tps": {DEFAULT_STATISTICS, UNIT_PERCENT, INFLUXDB_FIELD_RDS_TPS},
|
||||
|
||||
"rds013_innodb_reads": {DEFAULT_STATISTICS, UNIT_BYTEPS, INFLUXDB_FIELD_RDS_INNODB_REDA_BPS},
|
||||
"rds014_innodb_writes": {DEFAULT_STATISTICS, UNIT_BYTEPS, INFLUXDB_FIELD_RDS_INNODB_WRITE_BPS},
|
||||
}
|
||||
|
||||
var huaweiRedisMetricSpecs = map[string][]string{
|
||||
"cpu_usage": {DEFAULT_STATISTICS, UNIT_PERCENT, INFLUXDB_FIELD_REDIS_CPU_USAGE},
|
||||
"memory_usage": {DEFAULT_STATISTICS, UNIT_PERCENT, INFLUXDB_FIELD_REDIS_MEM_USAGE},
|
||||
"instantaneous_input_kbps": {DEFAULT_STATISTICS, UNIT_BPS, INFLUXDB_FIELD_REDIS_NET_BPS_RX},
|
||||
"instantaneous_output_kbps": {DEFAULT_STATISTICS, UNIT_BPS, INFLUXDB_FIELD_REDIS_NET_BPS_TX},
|
||||
"connected_clients": {DEFAULT_STATISTICS, UNIT_COUNT, INFLUXDB_FIFLD_REDIS_CONN_USAGE},
|
||||
"instantaneous_ops": {DEFAULT_STATISTICS, UNIT_COUNT, INFLUXDB_FIFLD_REDIS_OPT_SES},
|
||||
"keys": {DEFAULT_STATISTICS, UNIT_COUNT, INFLUXDB_FIFLD_REDIS_CACHE_KEYS},
|
||||
"expires": {DEFAULT_STATISTICS, UNIT_COUNT, INFLUXDB_FIFLD_REDIS_CACHE_EXP_KEYS},
|
||||
"used_memory_dataset": {DEFAULT_STATISTICS, UNIT_MEM, INFLUXDB_FIFLD_REDIS_DATA_MEM_USAGE},
|
||||
}
|
||||
|
||||
var huaweiOSSMetricSpecs = map[string][]string{
|
||||
"download_bytes": {DEFAULT_STATISTICS, UNIT_MEM, INFLUXDB_FIELD_OSS_NET_BPS_TX},
|
||||
"upload_bytes": {DEFAULT_STATISTICS, UNIT_MEM, INFLUXDB_FIELD_OSS_NET_BPS_RX},
|
||||
"first_byte_latency": {DEFAULT_STATISTICS, UNIT_MSEC, INFLUXDB_FIELD_OSS_LATECY_GET},
|
||||
"get_request_count": {DEFAULT_STATISTICS, UNIT_COUNT, INFLUXDB_FIELD_OSS_REQ_COUNT_GET},
|
||||
"request_count_4xx": {DEFAULT_STATISTICS, UNIT_COUNT, INFLUXDB_FIELD_OSS_REQ_COUNT_4XX},
|
||||
"request_count_5xx": {DEFAULT_STATISTICS, UNIT_COUNT, INFLUXDB_FIELD_OSS_REQ_COUNT_5XX},
|
||||
}
|
||||
|
||||
var huaweiElbMetricSpecs = map[string][]string{
|
||||
"m7_in_Bps": {DEFAULT_STATISTICS, UNIT_BYTEPS, INFLUXDB_FIELD_ELB_NET_BPS_RX},
|
||||
"m8_out_Bps": {DEFAULT_STATISTICS, UNIT_BYTEPS, INFLUXDB_FIELD_ELB_NET_BPS_TX},
|
||||
"mb_l7_qps": {DEFAULT_STATISTICS, UNIT_COUNT_SEC, INFLUXDB_FIELD_ELB_REQ_RATE},
|
||||
"mc_l7_http_2xx": {DEFAULT_STATISTICS, UNIT_COUNT_SEC, INFLUXDB_FIELD_ELB_HRSP_COUNT_2XX},
|
||||
"md_l7_http_3xx": {DEFAULT_STATISTICS, UNIT_COUNT_SEC, INFLUXDB_FIELD_ELB_HRSP_COUNT_3XX},
|
||||
"me_l7_http_4xx": {DEFAULT_STATISTICS, UNIT_COUNT_SEC, INFLUXDB_FIELD_ELB_HRSP_COUNT_4XX},
|
||||
"mf_l7_http_5xx": {DEFAULT_STATISTICS, UNIT_COUNT_SEC, INFLUXDB_FIELD_ELB_HRSP_COUNT_5XX},
|
||||
}
|
||||
@@ -1,15 +0,0 @@
|
||||
// Copyright 2019 Yunion
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package jdmon // import "yunion.io/x/onecloud/pkg/cloudmon/collectors/jdmon"
|
||||
@@ -1,83 +0,0 @@
|
||||
// Copyright 2019 Yunion
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package jdmon
|
||||
|
||||
import (
|
||||
"yunion.io/x/jsonutils"
|
||||
|
||||
"yunion.io/x/onecloud/pkg/apis/compute"
|
||||
"yunion.io/x/onecloud/pkg/cloudmon/collectors/common"
|
||||
"yunion.io/x/onecloud/pkg/cloudmon/options"
|
||||
"yunion.io/x/onecloud/pkg/mcclient"
|
||||
)
|
||||
|
||||
func init() {
|
||||
factory := SJdCloudReportFactory{}
|
||||
common.RegisterFactory(&factory)
|
||||
}
|
||||
|
||||
type SJdCloudReportFactory struct {
|
||||
common.CommonReportFactory
|
||||
}
|
||||
|
||||
func (self *SJdCloudReportFactory) NewCloudReport(provider *common.SProvider, session *mcclient.ClientSession,
|
||||
args *options.ReportOptions, operatorType string) common.ICloudReport {
|
||||
return &SJdCloudReport{
|
||||
common.CloudReportBase{
|
||||
SProvider: provider,
|
||||
Session: session,
|
||||
Args: args,
|
||||
Operator: operatorType,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func (self *SJdCloudReportFactory) GetId() string {
|
||||
return compute.CLOUD_PROVIDER_JDCLOUD
|
||||
}
|
||||
|
||||
type SJdCloudReport struct {
|
||||
common.CloudReportBase
|
||||
}
|
||||
|
||||
func (self *SJdCloudReport) Report() error {
|
||||
var servers []jsonutils.JSONObject
|
||||
var err error
|
||||
servers, err = self.GetResourceByOperator()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
providerInstance, err := self.InitProviderInstance()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
regionList, regionServerMap, err := self.GetAllRegionOfServers(servers, providerInstance)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
for _, region := range regionList {
|
||||
servers := regionServerMap[region.GetGlobalId()]
|
||||
switch common.MonType(self.Operator) {
|
||||
case common.SERVER:
|
||||
err = self.collectRegionMetricOfServer(region, servers)
|
||||
case common.RDS:
|
||||
err = self.collectRegionMetricOfRds(region, servers)
|
||||
}
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
@@ -1,196 +0,0 @@
|
||||
// Copyright 2019 Yunion
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package jdmon
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"yunion.io/x/jsonutils"
|
||||
"yunion.io/x/log"
|
||||
"yunion.io/x/pkg/util/timeutils"
|
||||
|
||||
"yunion.io/x/onecloud/pkg/cloudmon/collectors/common"
|
||||
"yunion.io/x/onecloud/pkg/cloudprovider"
|
||||
"yunion.io/x/onecloud/pkg/multicloud/jdcloud"
|
||||
"yunion.io/x/onecloud/pkg/util/influxdb"
|
||||
)
|
||||
|
||||
const (
|
||||
SERVICE_CODE_VM = "vm"
|
||||
SERVICE_CODE_RDS_SQLSERVER = "sqlserver"
|
||||
SERVICE_CODE_RDS_MYSQL = "database"
|
||||
SERVICE_CODE_RDS_PERCONA = "percona"
|
||||
SERVICE_CODE_RDS_MARIADB = "mariadb"
|
||||
SERVICE_CODE_RDS_POSTGRESQL = "pg"
|
||||
)
|
||||
|
||||
var (
|
||||
rdsEngineMap = map[string]string{
|
||||
"SQL Server": SERVICE_CODE_RDS_SQLSERVER,
|
||||
"MySQL": SERVICE_CODE_RDS_MYSQL,
|
||||
"Percona": SERVICE_CODE_RDS_PERCONA,
|
||||
"MariaDB": SERVICE_CODE_RDS_MARIADB,
|
||||
"PostgreSQL": SERVICE_CODE_RDS_POSTGRESQL,
|
||||
}
|
||||
)
|
||||
|
||||
func (self *SJdCloudReport) collectRegionMetricOfServer(region cloudprovider.ICloudRegion,
|
||||
servers []jsonutils.JSONObject) error {
|
||||
dataList := make([]influxdb.SMetricData, 0)
|
||||
jdReg := region.(*jdcloud.SRegion)
|
||||
since, until, err := common.TimeRangeFromArgs(self.Args)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
sinceStr := since.Format(timeutils.FullIsoTimeFormat)
|
||||
untilStr := until.Format(timeutils.FullIsoTimeFormat)
|
||||
for _, server := range servers {
|
||||
metrics := self.GetInstanceMetric(server, jdReg, jdMetricSpecs, sinceStr, untilStr, SERVICE_CODE_VM)
|
||||
if len(metrics) != 0 {
|
||||
dataList = append(dataList, metrics...)
|
||||
}
|
||||
}
|
||||
return common.SendMetrics(self.Session, dataList, self.Args.Debug, "")
|
||||
}
|
||||
|
||||
func (self *SJdCloudReport) GetInstanceMetric(instance jsonutils.JSONObject, jdReg *jdcloud.SRegion,
|
||||
metricMap map[string][]string,
|
||||
startTime string, endTime string, serviceCode string) []influxdb.SMetricData {
|
||||
dataList := make([]influxdb.SMetricData, 0)
|
||||
name, _ := instance.GetString("name")
|
||||
instanceId, _ := instance.GetString("external_id")
|
||||
for metricName, influxDbSpecs := range metricMap {
|
||||
request := jdcloud.NewDescribeMetricDataRequestWithAllParams(jdReg.GetId(), metricName, &startTime, &endTime,
|
||||
nil, &serviceCode, instanceId)
|
||||
response, err := jdReg.GetMetricsData(request)
|
||||
if err != nil {
|
||||
log.Errorf("get instance:%s metric err:%v", name, err)
|
||||
continue
|
||||
}
|
||||
metricData, err := self.collectMetricFromThisServer(instance, response, influxDbSpecs)
|
||||
if err != nil {
|
||||
log.Errorf("collectMetricFromThisServer:%s err:%v", name, err)
|
||||
continue
|
||||
}
|
||||
dataList = append(dataList, metricData...)
|
||||
}
|
||||
return dataList
|
||||
}
|
||||
|
||||
func (self *SJdCloudReport) collectMetricFromThisServer(server jsonutils.JSONObject,
|
||||
metricRep *jdcloud.DescribeMetricDataResponse,
|
||||
influxDbSpecs []string) ([]influxdb.SMetricData, error) {
|
||||
datas := make([]influxdb.SMetricData, 0)
|
||||
for _, metricData := range metricRep.Result.MetricDatas {
|
||||
for _, datapoint := range metricData.Data {
|
||||
//metric, err := common.JsonToMetric(server.(*jsonutils.JSONDict), "", common.ServerTags, make([]string, 0))
|
||||
metric, err := self.NewMetricFromJson(server)
|
||||
if err != nil {
|
||||
return datas, err
|
||||
}
|
||||
metric.Timestamp = time.Unix(datapoint.Timestamp/1000, 0)
|
||||
fieldValue := self.parseDataValue(datapoint.Value)
|
||||
//根据条件拼装metric的tag和metirc信息
|
||||
influxDbSpec := influxDbSpecs[2]
|
||||
measurement := common.SubstringBefore(influxDbSpec, ".")
|
||||
var pairsKey string
|
||||
if strings.Contains(influxDbSpec, ",") {
|
||||
pairsKey = common.SubstringBetween(influxDbSpec, ".", ",")
|
||||
} else {
|
||||
pairsKey = common.SubstringAfter(influxDbSpec, ".")
|
||||
}
|
||||
if influxDbSpecs[1] == UNIT_BYTEPS {
|
||||
fieldValue = fieldValue * 8
|
||||
}
|
||||
if influxDbSpecs[1] == UNIT_KBPS {
|
||||
fieldValue = fieldValue * 1000
|
||||
}
|
||||
tag := common.SubstringAfter(influxDbSpec, ",")
|
||||
if tag != "" && strings.Contains(influxDbSpec, "=") {
|
||||
metric.Tags = append(metric.Tags, influxdb.SKeyValue{
|
||||
Key: common.SubstringBefore(tag, "="),
|
||||
Value: common.SubstringAfter(tag, "="),
|
||||
})
|
||||
}
|
||||
metric.Metrics = append(metric.Metrics, influxdb.SKeyValue{
|
||||
Key: pairsKey,
|
||||
Value: strconv.FormatFloat(fieldValue, 'E', -1, 64),
|
||||
})
|
||||
metric.Name = measurement
|
||||
datas = append(datas, metric)
|
||||
}
|
||||
}
|
||||
return datas, nil
|
||||
}
|
||||
|
||||
func (self *SJdCloudReport) parseDataValue(value interface{}) float64 {
|
||||
str, ok := value.(string)
|
||||
if !ok {
|
||||
log.Errorf("parseDataValue err:%v", value)
|
||||
return 0
|
||||
}
|
||||
number := json.Number(str)
|
||||
fvalue, err := number.Float64()
|
||||
if err == nil {
|
||||
return fvalue
|
||||
}
|
||||
|
||||
ivalue, err := number.Int64()
|
||||
if err == nil {
|
||||
ret := float64(ivalue)
|
||||
return ret
|
||||
}
|
||||
log.Errorln("parseDataValue data type err")
|
||||
return 0
|
||||
}
|
||||
|
||||
func (self *SJdCloudReport) collectRegionMetricOfRds(region cloudprovider.ICloudRegion,
|
||||
servers []jsonutils.JSONObject) error {
|
||||
dataList := make([]influxdb.SMetricData, 0)
|
||||
|
||||
jdReg := region.(*jdcloud.SRegion)
|
||||
since, until, err := common.TimeRangeFromArgs(self.Args)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
sinceStr := since.Format(timeutils.FullIsoTimeFormat)
|
||||
untilStr := until.Format(timeutils.FullIsoTimeFormat)
|
||||
|
||||
for _, server := range servers {
|
||||
engine, _ := server.GetString("engine")
|
||||
metrics := make([]influxdb.SMetricData, 0)
|
||||
if serviceCode, ok := rdsEngineMap[engine]; ok {
|
||||
switch serviceCode {
|
||||
case SERVICE_CODE_RDS_SQLSERVER:
|
||||
metrics = self.GetInstanceMetric(server, jdReg, jdRdsSqlserverMetricSpecs, sinceStr, untilStr, serviceCode)
|
||||
case SERVICE_CODE_RDS_MYSQL:
|
||||
metrics = self.GetInstanceMetric(server, jdReg, jdRdsMysqlMetricSpecs, sinceStr, untilStr, serviceCode)
|
||||
case SERVICE_CODE_RDS_PERCONA:
|
||||
metrics = self.GetInstanceMetric(server, jdReg, jdRdsPerconaMetricSpecs, sinceStr, untilStr, serviceCode)
|
||||
case SERVICE_CODE_RDS_MARIADB:
|
||||
metrics = self.GetInstanceMetric(server, jdReg, jdRdsMariadbMetricSpecs, sinceStr, untilStr, serviceCode)
|
||||
case SERVICE_CODE_RDS_POSTGRESQL:
|
||||
metrics = self.GetInstanceMetric(server, jdReg, jdRdsPostgresqlMetricSpecs, sinceStr, untilStr, serviceCode)
|
||||
}
|
||||
if len(metrics) != 0 {
|
||||
dataList = append(dataList, metrics...)
|
||||
}
|
||||
}
|
||||
}
|
||||
return common.SendMetrics(self.Session, dataList, self.Args.Debug, "")
|
||||
}
|
||||
@@ -1,130 +0,0 @@
|
||||
// Copyright 2019 Yunion
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package jdmon
|
||||
|
||||
const (
|
||||
PERIOD = 60
|
||||
UNIT_AVERAGE = "Average"
|
||||
DEFAULT_STATISTICS = "Average,Minimum,Maximum"
|
||||
UNIT_PERCENT = "Percent"
|
||||
UNIT_BPS = "bps"
|
||||
UNIT_KBPS = "Kbps"
|
||||
UNIT_MBPS = "Mbps"
|
||||
UNIT_BYTEPS = "Bps"
|
||||
UNIT_CPS = "cps"
|
||||
UNIT_COUNT = "count"
|
||||
UNIT_MEM = "byte"
|
||||
UNIT_MSEC = "ms"
|
||||
UNIT_COUNT_SEC = "count/s"
|
||||
|
||||
//ESC监控指标
|
||||
INFLUXDB_FIELD_CPU_USAGE = "vm_cpu.usage_active"
|
||||
INFLUXDB_FIELD_MEM_USAGE = "vm_mem.used_percent"
|
||||
INFLUXDB_FIELD_DISK_READ_BPS = "vm_diskio.read_bps"
|
||||
INFLUXDB_FIELD_DISK_WRITE_BPS = "vm_diskio.write_bps"
|
||||
INFLUXDB_FIELD_DISK_READ_IOPS = "vm_diskio.read_iops"
|
||||
INFLUXDB_FIELD_DISK_WRITE_IOPS = "vm_diskio.write_iops"
|
||||
INFLUXDB_FIELD_NET_BPS_RX = "vm_netio.bps_recv"
|
||||
INFLUXDB_FIELD_NET_BPS_RX_INTERNET = INFLUXDB_FIELD_NET_BPS_RX + ",net_type=internet"
|
||||
INFLUXDB_FIELD_NET_BPS_RX_INTRANET = INFLUXDB_FIELD_NET_BPS_RX + ",net_type=intranet"
|
||||
INFLUXDB_FIELD_NET_BPS_TX = "vm_netio.bps_sent"
|
||||
INFLUXDB_FIELD_NET_BPS_TX_INTERNET = INFLUXDB_FIELD_NET_BPS_TX + ",net_type=internet"
|
||||
INFLUXDB_FIELD_NET_BPS_TX_INTRANET = INFLUXDB_FIELD_NET_BPS_TX + ",net_type=intranet"
|
||||
INFLUXDB_FIELD_WANOUTTRAFFIC = "vm_eipio.bps_out"
|
||||
INFLUXDB_FIELD_WANINTRAFFIC = "vm_eipio.bps_in"
|
||||
INFLUXDB_FIELD_WANOUTPKG = "vm_eipio.pps_out"
|
||||
INFLUXDB_FIELD_WANINPKG = "vm_eipio.pps_in"
|
||||
|
||||
//RDS监控指标
|
||||
INFLUXDB_FIELD_RDS_CPU_USAGE = "rds_cpu.usage_active"
|
||||
INFLUXDB_FIELD_RDS_MEM_USAGE = "rds_mem.used_percent"
|
||||
INFLUXDB_FIELD_RDS_NET_BPS_RX = "rds_netio.bps_recv"
|
||||
INFLUXDB_FIELD_RDS_NET_BPS_RX_PERCONA = INFLUXDB_FIELD_RDS_NET_BPS_RX + ",server_type=percona"
|
||||
INFLUXDB_FIELD_RDS_NET_BPS_RX_MARIADB = INFLUXDB_FIELD_RDS_NET_BPS_RX + ",server_type=mariadb"
|
||||
INFLUXDB_FIELD_RDS_NET_BPS_RX_POSTGRESQL = INFLUXDB_FIELD_RDS_NET_BPS_RX + ",server_type=postgresql"
|
||||
INFLUXDB_FIELD_RDS_NET_BPS_RX_MYSQL = INFLUXDB_FIELD_RDS_NET_BPS_RX + ",server_type=mysql"
|
||||
INFLUXDB_FIELD_RDS_NET_BPS_RX_SQLSERVER = INFLUXDB_FIELD_RDS_NET_BPS_RX + ",server_type=sqlserver"
|
||||
INFLUXDB_FIELD_RDS_NET_BPS_TX = "rds_netio.bps_sent"
|
||||
INFLUXDB_FIELD_RDS_NET_BPS_TX_PERCONA = INFLUXDB_FIELD_RDS_NET_BPS_TX + ",server_type=percona"
|
||||
INFLUXDB_FIELD_RDS_NET_BPS_TX_MARIADB = INFLUXDB_FIELD_RDS_NET_BPS_TX + ",server_type=mariadb"
|
||||
INFLUXDB_FIELD_RDS_NET_BPS_TX_POSTGRESQL = INFLUXDB_FIELD_RDS_NET_BPS_TX + ",server_type=postgresql"
|
||||
INFLUXDB_FIELD_RDS_NET_BPS_TX_MYSQL = INFLUXDB_FIELD_RDS_NET_BPS_TX + ",server_type=mysql"
|
||||
INFLUXDB_FIELD_RDS_NET_BPS_TX_SQLSERVER = INFLUXDB_FIELD_RDS_NET_BPS_TX + ",server_type=sqlserver"
|
||||
INFLUXDB_FIELD_RDS_DISK_USAGE = "rds_disk.used_percent"
|
||||
INFLUXDB_FIELD_RDS_DISK_READ_BPS = "rds_diskio.read_bps"
|
||||
INFLUXDB_FIELD_RDS_DISK_WRITE_BPS = "rds_diskio.write_bps"
|
||||
INFLUXDB_FIELD_RDS_CONN_COUNT = "rds_conn.used_count"
|
||||
INFLUXDB_FIELD_RDS_CONN_USAGE = "rds_conn.used_percent"
|
||||
|
||||
INFLUXDB_FIELD_RDS_QPS = "rds_qps.query_qps"
|
||||
INFLUXDB_FIELD_RDS_TPS = "rds_tps.trans_qps"
|
||||
INFLUXDB_FIELD_RDS_INNODB_REDA_BPS = "rds_innodb.read_bps"
|
||||
INFLUXDB_FIELD_RDS_INNODB_WRITE_BPS = "rds_innodb.write_bps"
|
||||
|
||||
KEY_VMS = "vms"
|
||||
KEY_CPUS = "cpus"
|
||||
KEY_MEMS = "mems"
|
||||
KEY_DISKS = "disks"
|
||||
)
|
||||
|
||||
var (
|
||||
jdMetricSpecs = map[string][]string{
|
||||
"cpu_util": {DEFAULT_STATISTICS, UNIT_PERCENT, INFLUXDB_FIELD_CPU_USAGE}, //CPU使用率,该指标用于统计测量对象的CPU使用率,以百分为单位。
|
||||
"memory.usage": {DEFAULT_STATISTICS, UNIT_PERCENT, INFLUXDB_FIELD_MEM_USAGE}, //CPU使用率,该指标用于统计测量对象的CPU使用率,以百分为单位。
|
||||
"vm.disk.dev.used": {DEFAULT_STATISTICS, UNIT_PERCENT, INFLUXDB_FIELD_MEM_USAGE}, //CPU使用率,该指标用于统计测量对象的CPU使用率,以百分为单位。
|
||||
"vm.network.dev.bytes.in": {DEFAULT_STATISTICS, UNIT_BYTEPS, INFLUXDB_FIELD_NET_BPS_RX}, //带外网络流入速率,该指标用于在虚拟化层统计每秒流入测量对象的网络流量,以字节/秒为单位。
|
||||
"vm.network.dev.bytes.out": {DEFAULT_STATISTICS, UNIT_BYTEPS, INFLUXDB_FIELD_NET_BPS_TX}, //带外网络流出速率,该指标用于在虚拟化层统计每秒流出测量对象的网络流量,以字节/秒为单位。
|
||||
"vm.disk.dev.bytes.read": {DEFAULT_STATISTICS, UNIT_BYTEPS, INFLUXDB_FIELD_DISK_READ_BPS}, //磁盘读速率,该指标用于统计每秒从测量对象读出数据量,以字节/秒为单位。
|
||||
"vm.disk.dev.bytes.write": {DEFAULT_STATISTICS, UNIT_BYTEPS, INFLUXDB_FIELD_DISK_WRITE_BPS}, //磁盘写速率,该指标用于统计每秒写到测量对象的数据量,以字节/秒为单位。
|
||||
"vm.disk.dev.io.read": {DEFAULT_STATISTICS, UNIT_CPS, INFLUXDB_FIELD_DISK_READ_IOPS}, //该指标用于统计每秒从测量对象读取数据的请求次数,以请求/秒为单位。
|
||||
"vm.disk.dev.io.write": {DEFAULT_STATISTICS, UNIT_CPS, INFLUXDB_FIELD_DISK_WRITE_IOPS}, //该指标用于统计每秒从测量对象写数据的请求次数,以请求/秒为单位
|
||||
}
|
||||
|
||||
jdRdsSqlserverMetricSpecs = map[string][]string{
|
||||
"database.sqlserver.kvm.cpu.util": {DEFAULT_STATISTICS, UNIT_PERCENT, INFLUXDB_FIELD_RDS_CPU_USAGE},
|
||||
"database.sqlserver.kvm.memory.usage": {DEFAULT_STATISTICS, UNIT_PERCENT, INFLUXDB_FIELD_RDS_MEM_USAGE},
|
||||
"database.sqlserver.kvm.disk1.usedpercent": {DEFAULT_STATISTICS, UNIT_PERCENT, INFLUXDB_FIELD_RDS_DISK_USAGE},
|
||||
"database.sqlserver.kvm.network.bytes.incoming": {DEFAULT_STATISTICS, UNIT_KBPS, INFLUXDB_FIELD_RDS_NET_BPS_RX_SQLSERVER},
|
||||
"database.sqlserver.kvm.network.bytes.outgoing": {DEFAULT_STATISTICS, UNIT_KBPS, INFLUXDB_FIELD_RDS_NET_BPS_TX_SQLSERVER},
|
||||
}
|
||||
jdRdsMysqlMetricSpecs = map[string][]string{
|
||||
"database.docker.cpu.util": {DEFAULT_STATISTICS, UNIT_PERCENT, INFLUXDB_FIELD_RDS_CPU_USAGE},
|
||||
"database.docker.memory.pused": {DEFAULT_STATISTICS, UNIT_PERCENT, INFLUXDB_FIELD_RDS_MEM_USAGE},
|
||||
"database.docker.disk1.used": {DEFAULT_STATISTICS, UNIT_PERCENT, INFLUXDB_FIELD_RDS_DISK_USAGE},
|
||||
"database.docker.network.incoming": {DEFAULT_STATISTICS, UNIT_KBPS, INFLUXDB_FIELD_RDS_NET_BPS_RX_MYSQL},
|
||||
"database.docker.network.outgoing": {DEFAULT_STATISTICS, UNIT_KBPS, INFLUXDB_FIELD_RDS_NET_BPS_TX_MYSQL},
|
||||
}
|
||||
jdRdsPerconaMetricSpecs = map[string][]string{
|
||||
"database.docker.cpu.util": {DEFAULT_STATISTICS, UNIT_PERCENT, INFLUXDB_FIELD_RDS_CPU_USAGE},
|
||||
"database.docker.memory.pused": {DEFAULT_STATISTICS, UNIT_PERCENT, INFLUXDB_FIELD_RDS_MEM_USAGE},
|
||||
"database.docker.disk1.used": {DEFAULT_STATISTICS, UNIT_PERCENT, INFLUXDB_FIELD_RDS_DISK_USAGE},
|
||||
"database.docker.network.incoming": {DEFAULT_STATISTICS, UNIT_KBPS, INFLUXDB_FIELD_RDS_NET_BPS_RX_PERCONA},
|
||||
"database.docker.network.outgoing": {DEFAULT_STATISTICS, UNIT_KBPS, INFLUXDB_FIELD_RDS_NET_BPS_TX_PERCONA},
|
||||
}
|
||||
jdRdsMariadbMetricSpecs = map[string][]string{
|
||||
"database.docker.cpu.util": {DEFAULT_STATISTICS, UNIT_PERCENT, INFLUXDB_FIELD_RDS_CPU_USAGE},
|
||||
"database.docker.memory.pused": {DEFAULT_STATISTICS, UNIT_PERCENT, INFLUXDB_FIELD_RDS_MEM_USAGE},
|
||||
"database.docker.disk1.used": {DEFAULT_STATISTICS, UNIT_PERCENT, INFLUXDB_FIELD_RDS_DISK_USAGE},
|
||||
"database.docker.network.incoming": {DEFAULT_STATISTICS, UNIT_KBPS, INFLUXDB_FIELD_RDS_NET_BPS_RX_MARIADB},
|
||||
"database.docker.network.outgoing": {DEFAULT_STATISTICS, UNIT_KBPS, INFLUXDB_FIELD_RDS_NET_BPS_TX_MARIADB},
|
||||
}
|
||||
jdRdsPostgresqlMetricSpecs = map[string][]string{
|
||||
"database.docker.cpu.util": {DEFAULT_STATISTICS, UNIT_PERCENT, INFLUXDB_FIELD_RDS_CPU_USAGE},
|
||||
"database.docker.memory.pused": {DEFAULT_STATISTICS, UNIT_PERCENT, INFLUXDB_FIELD_RDS_MEM_USAGE},
|
||||
"database.docker.disk1.used": {DEFAULT_STATISTICS, UNIT_PERCENT, INFLUXDB_FIELD_RDS_DISK_USAGE},
|
||||
"database.docker.network.bytes.incoming": {DEFAULT_STATISTICS, UNIT_BPS, INFLUXDB_FIELD_RDS_NET_BPS_RX_POSTGRESQL},
|
||||
"database.docker.network.bytes.outgoing": {DEFAULT_STATISTICS, UNIT_BPS, INFLUXDB_FIELD_RDS_NET_BPS_TX_POSTGRESQL},
|
||||
}
|
||||
)
|
||||
@@ -1,16 +0,0 @@
|
||||
package collectors
|
||||
|
||||
import (
|
||||
"yunion.io/x/onecloud/pkg/cloudmon/collectors/common"
|
||||
"yunion.io/x/onecloud/pkg/cloudmon/options"
|
||||
"yunion.io/x/onecloud/pkg/mcclient"
|
||||
"yunion.io/x/onecloud/pkg/util/shellutils"
|
||||
)
|
||||
|
||||
func init() {
|
||||
shellutils.R(&options.ReportOptions{}, "report-k8s", "Report k8s", reporK8s)
|
||||
}
|
||||
|
||||
func reporK8s(session *mcclient.ClientSession, args *options.ReportOptions) error {
|
||||
return common.ReportCloudMetricOfoperatorType(string(common.K8S), session, args)
|
||||
}
|
||||
@@ -1,15 +0,0 @@
|
||||
// Copyright 2019 Yunion
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package qcmon // import "yunion.io/x/onecloud/pkg/cloudmon/collectors/qcmon"
|
||||
@@ -1,186 +0,0 @@
|
||||
// Copyright 2019 Yunion
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package qcmon
|
||||
|
||||
import (
|
||||
"yunion.io/x/jsonutils"
|
||||
|
||||
"yunion.io/x/onecloud/pkg/apis/compute"
|
||||
"yunion.io/x/onecloud/pkg/cloudmon/collectors/common"
|
||||
"yunion.io/x/onecloud/pkg/cloudmon/options"
|
||||
"yunion.io/x/onecloud/pkg/mcclient"
|
||||
)
|
||||
|
||||
func init() {
|
||||
factory := SQCloudReportFactory{}
|
||||
common.RegisterFactory(&factory)
|
||||
|
||||
cluster := &QcloudK8sClusterHelper{
|
||||
K8sClusterMetricBaseHelper: &common.K8sClusterMetricBaseHelper{
|
||||
ModuleHelper: map[common.K8sClusterModuleType]common.IK8sClusterModuleHelper{},
|
||||
},
|
||||
}
|
||||
cluster.RegisterModuleHelper(new(QcloudK8sClusterDeployHelper))
|
||||
//cluster.RegisterModuleHelper(new(QcloudK8sClusterContainerHelper))
|
||||
cluster.RegisterModuleHelper(new(QcloudK8sClusterPodHelper))
|
||||
cluster.RegisterModuleHelper(new(QcloudK8sClusterNodeHelper))
|
||||
|
||||
common.RegisterK8sClusterHelper(cluster)
|
||||
|
||||
}
|
||||
|
||||
type SQCloudReportFactory struct {
|
||||
common.CommonReportFactory
|
||||
}
|
||||
|
||||
func (self *SQCloudReportFactory) NewCloudReport(provider *common.SProvider, session *mcclient.ClientSession,
|
||||
args *options.ReportOptions, operatorType string) common.ICloudReport {
|
||||
return &SQCloudReport{
|
||||
common.CloudReportBase{
|
||||
SProvider: provider,
|
||||
Session: session,
|
||||
Args: args,
|
||||
Operator: operatorType,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func (self *SQCloudReportFactory) GetId() string {
|
||||
return compute.CLOUD_PROVIDER_QCLOUD
|
||||
}
|
||||
|
||||
type SQCloudReport struct {
|
||||
common.CloudReportBase
|
||||
}
|
||||
|
||||
func (self *SQCloudReport) Report() error {
|
||||
var servers []jsonutils.JSONObject
|
||||
var err error
|
||||
servers, err = self.GetResourceByOperator()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
providerInstance, err := self.InitProviderInstance()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
regionList, regionServerMap, err := self.GetAllRegionOfServers(servers, providerInstance)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
for _, region := range regionList {
|
||||
servers := regionServerMap[region.GetGlobalId()]
|
||||
var err error
|
||||
switch common.MonType(self.Operator) {
|
||||
case common.K8S:
|
||||
err = self.collectRegionMetricOfK8S(region, servers)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
self.Impl = self
|
||||
err = self.CollectRegionMetricOfK8sModules(region, servers)
|
||||
default:
|
||||
err = self.collectRegionMetricOfHost(region, servers)
|
||||
}
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type QcloudK8sClusterHelper struct {
|
||||
*common.K8sClusterMetricBaseHelper
|
||||
}
|
||||
|
||||
func (q QcloudK8sClusterHelper) HelperBrand() string {
|
||||
return compute.CLOUD_PROVIDER_QCLOUD
|
||||
}
|
||||
|
||||
type QcloudK8sClusterDeployHelper struct {
|
||||
common.K8sClusterModuleQueryHelper
|
||||
}
|
||||
|
||||
func (q QcloudK8sClusterDeployHelper) MyModuleType() common.K8sClusterModuleType {
|
||||
return common.K8S_MODULE_DEPLOY
|
||||
}
|
||||
|
||||
func (q QcloudK8sClusterDeployHelper) MyResDimensionId() common.DimensionId {
|
||||
return common.DimensionId{
|
||||
LocalId: "name",
|
||||
ExtId: "workload_name",
|
||||
}
|
||||
}
|
||||
|
||||
func (q QcloudK8sClusterDeployHelper) MyNamespaceAndMetrics() (string, map[string][]string) {
|
||||
return K8S_METRIC_NAMESPACE, tecentK8SDeployMetricSpecs
|
||||
}
|
||||
|
||||
type QcloudK8sClusterPodHelper struct {
|
||||
common.K8sClusterModuleQueryHelper
|
||||
}
|
||||
|
||||
func (q QcloudK8sClusterPodHelper) MyNamespaceAndMetrics() (string, map[string][]string) {
|
||||
return K8S_METRIC_NAMESPACE, tecentK8SPodMetricSpecs
|
||||
}
|
||||
|
||||
func (q QcloudK8sClusterPodHelper) MyModuleType() common.K8sClusterModuleType {
|
||||
return common.K8S_MODULE_POD
|
||||
}
|
||||
|
||||
func (q QcloudK8sClusterPodHelper) MyResDimensionId() common.DimensionId {
|
||||
return common.DimensionId{
|
||||
LocalId: "nodeName,name",
|
||||
ExtId: "node,pod_name",
|
||||
}
|
||||
}
|
||||
|
||||
type QcloudK8sClusterContainerHelper struct {
|
||||
common.K8sClusterModuleQueryHelper
|
||||
}
|
||||
|
||||
func (q QcloudK8sClusterContainerHelper) MyNamespaceAndMetrics() (string, map[string][]string) {
|
||||
return K8S_METRIC_NAMESPACE, tecentK8SContainerMetricSpecs
|
||||
}
|
||||
|
||||
func (q QcloudK8sClusterContainerHelper) MyModuleType() common.K8sClusterModuleType {
|
||||
return common.K8S_MODULE_CONTAINER
|
||||
}
|
||||
|
||||
func (q QcloudK8sClusterContainerHelper) MyResDimensionId() common.DimensionId {
|
||||
return common.DimensionId{
|
||||
LocalId: "labels.k8s-app,name",
|
||||
ExtId: "workload_name,container_name",
|
||||
}
|
||||
}
|
||||
|
||||
type QcloudK8sClusterNodeHelper struct {
|
||||
common.K8sClusterModuleQueryHelper
|
||||
}
|
||||
|
||||
func (q QcloudK8sClusterNodeHelper) MyModuleType() common.K8sClusterModuleType {
|
||||
return common.K8S_MODULE_NODE
|
||||
}
|
||||
|
||||
func (q QcloudK8sClusterNodeHelper) MyResDimensionId() common.DimensionId {
|
||||
return common.DimensionId{
|
||||
LocalId: "name",
|
||||
ExtId: "node",
|
||||
}
|
||||
}
|
||||
|
||||
func (q QcloudK8sClusterNodeHelper) MyNamespaceAndMetrics() (string, map[string][]string) {
|
||||
return K8S_METRIC_NAMESPACE, tecentK8SNodeMetricSpecs
|
||||
}
|
||||
@@ -1,372 +0,0 @@
|
||||
// Copyright 2019 Yunion
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package qcmon
|
||||
|
||||
import (
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"yunion.io/x/jsonutils"
|
||||
"yunion.io/x/log"
|
||||
|
||||
"yunion.io/x/onecloud/pkg/cloudmon/collectors/common"
|
||||
"yunion.io/x/onecloud/pkg/cloudprovider"
|
||||
"yunion.io/x/onecloud/pkg/multicloud/qcloud"
|
||||
"yunion.io/x/onecloud/pkg/util/influxdb"
|
||||
)
|
||||
|
||||
func (self *SQCloudReport) CollectRegionMetric(region cloudprovider.ICloudRegion,
|
||||
servers []jsonutils.JSONObject) error {
|
||||
var err error
|
||||
switch self.Operator {
|
||||
case string(common.SERVER):
|
||||
err = self.collectRegionMetricOfHost(region, servers)
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
func (self *SQCloudReport) collectRegionMetricOfHost(region cloudprovider.ICloudRegion, servers []jsonutils.JSONObject) error {
|
||||
dataList := make([]influxdb.SMetricData, 0)
|
||||
tecentReg := region.(*qcloud.SRegion)
|
||||
since, until, err := common.TimeRangeFromArgs(self.Args)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
dimensions := self.getDimensions(servers)
|
||||
//dimensions := []qcloud.SQcMetricDimension{qcloud.SQcMetricDimension{Name: "InstanceId", Value: external_id}}
|
||||
namespace, metricSpecs := self.getMetricSpecs(servers)
|
||||
for metricName, influxDbSpecs := range metricSpecs {
|
||||
for index, tmp := 0, 0; index < len(dimensions); index += 10 {
|
||||
tmp = index + 10
|
||||
if tmp > len(dimensions) {
|
||||
tmp = len(dimensions)
|
||||
}
|
||||
rtnArray, err := tecentReg.GetMonitorData(metricName, namespace, since, until,
|
||||
dimensions[index:tmp])
|
||||
if err != nil {
|
||||
log.Errorln(err)
|
||||
continue
|
||||
}
|
||||
for _, rtnMetric := range rtnArray {
|
||||
if len(rtnMetric.Timestamps) == 0 {
|
||||
break
|
||||
}
|
||||
for _, server := range servers {
|
||||
name, _ := server.GetString("name")
|
||||
external_id, _ := server.GetString("external_id")
|
||||
if external_id == rtnMetric.Dimensions[0].Value {
|
||||
if self.Operator == string(common.SERVER) {
|
||||
metric, err := common.FillVMCapacity(server.(*jsonutils.JSONDict))
|
||||
if err != nil {
|
||||
log.Errorf("provider: %s FillVMCapacity: %s, err: %#v", self.SProvider.Name, name, err)
|
||||
} else {
|
||||
dataList = append(dataList, metric)
|
||||
}
|
||||
}
|
||||
if len(rtnMetric.Timestamps) == 0 {
|
||||
break
|
||||
}
|
||||
serverMetric, err := self.collectMetricFromThisServer(server, rtnMetric, influxDbSpecs)
|
||||
if err != nil {
|
||||
log.Errorf("provider: %s collectMetricFromThisServer: %s, err: %#v", self.SProvider.Name, name, err)
|
||||
continue
|
||||
}
|
||||
dataList = append(dataList, serverMetric...)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return common.SendMetrics(self.Session, dataList, self.Args.Debug, "")
|
||||
}
|
||||
|
||||
func (self *SQCloudReport) collectRegionMetricOfK8S(region cloudprovider.ICloudRegion, servers []jsonutils.JSONObject) error {
|
||||
tecentReg := region.(*qcloud.SRegion)
|
||||
since, until, err := common.TimeRangeFromArgs(self.Args)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
namespace, metricSpecs := self.getMetricSpecs(servers)
|
||||
metricNames := make([]string, 0)
|
||||
for metricName, _ := range metricSpecs {
|
||||
metricNames = append(metricNames, metricName)
|
||||
}
|
||||
for i, _ := range servers {
|
||||
dataList := make([]influxdb.SMetricData, 0)
|
||||
server := servers[i]
|
||||
name, _ := server.GetString("name")
|
||||
dimensionId := self.getDimensionId()
|
||||
id, _ := server.GetString(dimensionId.LocalId)
|
||||
dimensions := []qcloud.SQcMetricDimension{
|
||||
qcloud.SQcMetricDimension{
|
||||
Name: dimensionId.ExtId,
|
||||
Value: id,
|
||||
},
|
||||
}
|
||||
rtnArray, err := tecentReg.GetK8sMonitorData(metricNames, namespace, since, until, dimensions)
|
||||
if err != nil {
|
||||
log.Errorln(err)
|
||||
continue
|
||||
}
|
||||
if len(rtnArray) == 0 {
|
||||
continue
|
||||
}
|
||||
for _, data := range rtnArray {
|
||||
for metricName, influxDbSpecs := range metricSpecs {
|
||||
if data.MetricName == metricName {
|
||||
serverMetric, err := self.collectMetricFromThisK8s(server, data, influxDbSpecs)
|
||||
if err != nil {
|
||||
log.Errorf("provider: %s collectK8s:%s metric err: %#v", self.SProvider.Name, name, err)
|
||||
continue
|
||||
}
|
||||
dataList = append(dataList, serverMetric...)
|
||||
}
|
||||
}
|
||||
}
|
||||
err = common.SendMetrics(self.Session, dataList, self.Args.Debug, "")
|
||||
if err != nil {
|
||||
log.Errorf("K8s: %s SendMetrics err: %#v", name, err)
|
||||
continue
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (self *SQCloudReport) collectMetricFromThisServer(server jsonutils.JSONObject, rtnMetric qcloud.SDataPoint,
|
||||
influxDbSpecs []string) ([]influxdb.SMetricData, error) {
|
||||
datas := make([]influxdb.SMetricData, 0)
|
||||
for index, timestamp := range rtnMetric.Timestamps {
|
||||
metric, err := self.NewMetricFromJson(server)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
//根据条件拼装metric的tag和metirc信息
|
||||
influxDbSpec := influxDbSpecs[2]
|
||||
measurement := common.SubstringBefore(influxDbSpec, ".")
|
||||
metric.Name = measurement
|
||||
var pairsKey string
|
||||
if strings.Contains(influxDbSpec, ",") {
|
||||
pairsKey = common.SubstringBetween(influxDbSpec, ".", ",")
|
||||
} else {
|
||||
pairsKey = common.SubstringAfter(influxDbSpec, ".")
|
||||
}
|
||||
tag := common.SubstringAfter(influxDbSpec, ",")
|
||||
if tag != "" && strings.Contains(influxDbSpec, "=") {
|
||||
metric.Tags = append(metric.Tags, influxdb.SKeyValue{
|
||||
Key: common.SubstringBefore(tag, "="),
|
||||
Value: common.SubstringAfter(tag, "="),
|
||||
})
|
||||
}
|
||||
cpu_cout, err := server.Get("vcpu_count")
|
||||
if err == nil {
|
||||
metric.Metrics = append(metric.Metrics, influxdb.SKeyValue{
|
||||
Key: "cpu_count",
|
||||
Value: strconv.FormatInt(cpu_cout.(*jsonutils.JSONInt).Value(), 10),
|
||||
})
|
||||
}
|
||||
metric.Timestamp = time.Unix(int64(timestamp), 0)
|
||||
fieldValue := rtnMetric.Values[index]
|
||||
if influxDbSpecs[1] == common.UNIT_MBPS {
|
||||
fieldValue = fieldValue * 1000 * 1000
|
||||
}
|
||||
metric.Metrics = append(metric.Metrics, influxdb.SKeyValue{
|
||||
Key: pairsKey,
|
||||
Value: strconv.FormatFloat(fieldValue, 'E', -1, 64),
|
||||
})
|
||||
datas = append(datas, metric)
|
||||
}
|
||||
return datas, nil
|
||||
}
|
||||
|
||||
func (self *SQCloudReport) collectMetricFromThisK8s(server jsonutils.JSONObject, rtnMetric qcloud.SK8SDataPoint,
|
||||
influxDbSpecs []string) ([]influxdb.SMetricData, error) {
|
||||
datas := make([]influxdb.SMetricData, 0)
|
||||
for index, _ := range rtnMetric.Points {
|
||||
for _, pointVal := range rtnMetric.Points[index].Values {
|
||||
|
||||
metric, err := self.NewMetricFromJson(server)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
//根据条件拼装metric的tag和metirc信息
|
||||
influxDbSpec := influxDbSpecs[2]
|
||||
measurement := common.SubstringBefore(influxDbSpec, ".")
|
||||
metric.Name = measurement
|
||||
var pairsKey string
|
||||
if strings.Contains(influxDbSpec, ",") {
|
||||
pairsKey = common.SubstringBetween(influxDbSpec, ".", ",")
|
||||
} else {
|
||||
pairsKey = common.SubstringAfter(influxDbSpec, ".")
|
||||
}
|
||||
tag := common.SubstringAfter(influxDbSpec, ",")
|
||||
if tag != "" && strings.Contains(influxDbSpec, "=") {
|
||||
metric.Tags = append(metric.Tags, influxdb.SKeyValue{
|
||||
Key: common.SubstringBefore(tag, "="),
|
||||
Value: common.SubstringAfter(tag, "="),
|
||||
})
|
||||
}
|
||||
metric.Timestamp = time.Unix(int64(pointVal.Timestamp), 0)
|
||||
fieldValue := pointVal.Value
|
||||
if influxDbSpecs[1] == common.UNIT_MBPS {
|
||||
fieldValue = fieldValue * 1000 * 1000
|
||||
}
|
||||
metric.Metrics = append(metric.Metrics, influxdb.SKeyValue{
|
||||
Key: pairsKey,
|
||||
Value: strconv.FormatFloat(fieldValue, 'E', -1, 64),
|
||||
})
|
||||
self.AddMetricTag(&metric, map[string]string{
|
||||
"source": "cloudmon",
|
||||
})
|
||||
datas = append(datas, metric)
|
||||
}
|
||||
}
|
||||
return datas, nil
|
||||
}
|
||||
|
||||
func (self *SQCloudReport) CollectK8sModuleMetric(region cloudprovider.ICloudRegion, cluster jsonutils.JSONObject,
|
||||
helper common.IK8sClusterModuleHelper) error {
|
||||
tecentReg := region.(*qcloud.SRegion)
|
||||
since, until, err := common.TimeRangeFromArgs(self.Args)
|
||||
id, _ := cluster.GetString("id")
|
||||
resources, err := common.ListK8sClusterModuleResources(helper.MyModuleType(), id, self.Session, nil)
|
||||
if err != nil {
|
||||
log.Errorf("ListK8sClusterModuleResources err: %v", err)
|
||||
return err
|
||||
}
|
||||
ext_id, _ := cluster.GetString("external_cloud_cluster_id")
|
||||
namespace, metricSpecs := helper.MyNamespaceAndMetrics()
|
||||
metricNames := make([]string, 0)
|
||||
for metricName, _ := range metricSpecs {
|
||||
metricNames = append(metricNames, metricName)
|
||||
}
|
||||
for i, _ := range resources {
|
||||
dataList := make([]influxdb.SMetricData, 0)
|
||||
resource := resources[i]
|
||||
name, _ := resource.GetString("name")
|
||||
dimensions := self.getK8sModuleDimensions(helper, resource, ext_id)
|
||||
rtnArray, err := tecentReg.GetK8sMonitorData(metricNames, namespace, since, until, dimensions)
|
||||
if err != nil {
|
||||
log.Errorln(err)
|
||||
continue
|
||||
}
|
||||
if len(rtnArray) == 0 {
|
||||
continue
|
||||
}
|
||||
for _, data := range rtnArray {
|
||||
for metricName, influxDbSpecs := range metricSpecs {
|
||||
if data.MetricName == metricName {
|
||||
serverMetric, err := self.collectMetricFromThisK8s(resource, data, influxDbSpecs)
|
||||
if err != nil {
|
||||
log.Errorf("provider: %s collectK8s:%s metric err: %#v", self.SProvider.Name, name, err)
|
||||
continue
|
||||
}
|
||||
dataList = append(dataList, serverMetric...)
|
||||
}
|
||||
}
|
||||
}
|
||||
err = common.SendMetrics(self.Session, dataList, self.Args.Debug, "")
|
||||
if err != nil {
|
||||
log.Errorf("K8s: %s SendMetrics err: %#v", name, err)
|
||||
continue
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (self *SQCloudReport) getDimensions(res []jsonutils.JSONObject) []qcloud.SQcInstanceMetricDimension {
|
||||
dimensions := make([]qcloud.SQcInstanceMetricDimension, 0)
|
||||
dimensionId := self.getDimensionId()
|
||||
if dimensionId == nil {
|
||||
return dimensions
|
||||
}
|
||||
for _, server := range res {
|
||||
external_id, _ := server.GetString(dimensionId.LocalId)
|
||||
dimensions = append(dimensions, qcloud.SQcInstanceMetricDimension{
|
||||
Dimensions: []qcloud.SQcMetricDimension{qcloud.SQcMetricDimension{
|
||||
Name: dimensionId.ExtId,
|
||||
Value: external_id,
|
||||
}},
|
||||
})
|
||||
}
|
||||
return dimensions
|
||||
}
|
||||
|
||||
func (self *SQCloudReport) getK8sModuleDimensions(helper common.IK8sClusterModuleHelper, module jsonutils.JSONObject,
|
||||
clusterId string) []qcloud.SQcMetricDimension {
|
||||
dimensions := make([]qcloud.SQcMetricDimension, 0)
|
||||
dimensionId := helper.MyResDimensionId()
|
||||
|
||||
localIds := strings.Split(dimensionId.LocalId, ",")
|
||||
extIds := strings.Split(dimensionId.ExtId, ",")
|
||||
if len(localIds) != len(extIds) {
|
||||
return dimensions
|
||||
}
|
||||
dimensions = append(dimensions, qcloud.SQcMetricDimension{
|
||||
Name: "tke_cluster_instance_id",
|
||||
Value: clusterId,
|
||||
})
|
||||
for index, localId := range localIds {
|
||||
localIdKey := strings.Split(localId, ".")
|
||||
val, _ := module.GetString(localIdKey...)
|
||||
dimensions = append(dimensions, qcloud.SQcMetricDimension{
|
||||
Name: extIds[index],
|
||||
Value: val,
|
||||
})
|
||||
|
||||
}
|
||||
return dimensions
|
||||
}
|
||||
|
||||
func (self *SQCloudReport) getDimensionId() *common.DimensionId {
|
||||
switch common.MonType(self.Operator) {
|
||||
case common.SERVER:
|
||||
return &common.DimensionId{
|
||||
LocalId: "external_id",
|
||||
ExtId: "InstanceId",
|
||||
}
|
||||
case common.REDIS:
|
||||
return &common.DimensionId{
|
||||
LocalId: "external_id",
|
||||
ExtId: "instanceid",
|
||||
}
|
||||
case common.RDS:
|
||||
return &common.DimensionId{
|
||||
LocalId: "external_id",
|
||||
ExtId: "InstanceId",
|
||||
}
|
||||
case common.K8S:
|
||||
return &common.DimensionId{
|
||||
LocalId: "external_cloud_cluster_id",
|
||||
ExtId: "tke_cluster_instance_id",
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (self *SQCloudReport) getMetricSpecs(res []jsonutils.JSONObject) (string, map[string][]string) {
|
||||
switch common.MonType(self.Operator) {
|
||||
case common.SERVER:
|
||||
return SERVER_METRIC_NAMESPACE, tecentMetricSpecs
|
||||
case common.REDIS:
|
||||
return REDIS_METRIC_NAMESPACE, tecentRedisMetricSpecs
|
||||
case common.RDS:
|
||||
return RDS_METRIC_NAMESPACE, tecentRdsMetricSpecs
|
||||
case common.K8S:
|
||||
return K8S_METRIC_NAMESPACE, tecentK8SClusterMetricSpecs
|
||||
default:
|
||||
return SERVER_METRIC_NAMESPACE, tecentMetricSpecs
|
||||
}
|
||||
}
|
||||
@@ -1,105 +0,0 @@
|
||||
// Copyright 2019 Yunion
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package qcmon
|
||||
|
||||
import "yunion.io/x/onecloud/pkg/cloudmon/collectors/common"
|
||||
|
||||
const (
|
||||
SERVER_METRIC_NAMESPACE = "QCE/CVM"
|
||||
REDIS_METRIC_NAMESPACE = "QCE/REDIS"
|
||||
RDS_METRIC_NAMESPACE = "QCE/CDB"
|
||||
K8S_METRIC_NAMESPACE = "QCE/TKE"
|
||||
|
||||
KEY_VMS = "vms"
|
||||
KEY_CPUS = "cpus"
|
||||
KEY_MEMS = "mems"
|
||||
KEY_DISKS = "disks"
|
||||
|
||||
KEY_LIMIT = "limit"
|
||||
KEY_ADMIN = "admin"
|
||||
KEY_USABLE = "usable"
|
||||
)
|
||||
|
||||
var tecentMetricSpecs = map[string][]string{
|
||||
"CPUUsage": {common.DEFAULT_STATISTICS, common.UNIT_PERCENT, common.INFLUXDB_FIELD_CPU_USAGE},
|
||||
"MemUsage": {common.DEFAULT_STATISTICS, common.UNIT_PERCENT, common.INFLUXDB_FIELD_MEM_USAGE},
|
||||
"lanOuttraffic": {common.DEFAULT_STATISTICS, common.UNIT_MBPS, common.INFLUXDB_FIELD_NET_BPS_TX_INTRANET},
|
||||
"WanOuttraffic": {common.DEFAULT_STATISTICS, common.UNIT_MBPS, common.INFLUXDB_FIELD_NET_BPS_TX_INTERNET},
|
||||
"lanIntraffic": {common.DEFAULT_STATISTICS, common.UNIT_MBPS, common.INFLUXDB_FIELD_NET_BPS_RX_INTRANET},
|
||||
"WanIntraffic": {common.DEFAULT_STATISTICS, common.UNIT_MBPS, common.INFLUXDB_FIELD_NET_BPS_RX_INTERNET},
|
||||
}
|
||||
|
||||
var tecentRedisMetricSpecs = map[string][]string{
|
||||
"CpuUsMin": {common.DEFAULT_STATISTICS, common.UNIT_PERCENT, common.INFLUXDB_FIELD_REDIS_CPU_USAGE},
|
||||
"StorageUsMin": {common.DEFAULT_STATISTICS, common.UNIT_PERCENT, common.INFLUXDB_FIELD_REDIS_MEM_USAGE},
|
||||
"InFlowMin": {common.DEFAULT_STATISTICS, common.UNIT_BPS, common.INFLUXDB_FIELD_REDIS_NET_BPS_RX},
|
||||
"OutFlowMin": {common.DEFAULT_STATISTICS, common.UNIT_BPS, common.INFLUXDB_FIELD_REDIS_NET_BPS_TX},
|
||||
"ConnectionsUsMin": {common.DEFAULT_STATISTICS, common.UNIT_COUNT, common.INFLUXDB_FIFLD_REDIS_CONN_USAGE},
|
||||
"QpsMin": {common.DEFAULT_STATISTICS, common.UNIT_COUNT, common.INFLUXDB_FIFLD_REDIS_OPT_SES},
|
||||
"KeysMin": {common.DEFAULT_STATISTICS, common.UNIT_COUNT, common.INFLUXDB_FIFLD_REDIS_CACHE_KEYS},
|
||||
"ExpiredKeysMin": {common.DEFAULT_STATISTICS, common.UNIT_COUNT, common.INFLUXDB_FIFLD_REDIS_CACHE_EXP_KEYS},
|
||||
"StorageMin": {common.DEFAULT_STATISTICS, common.UNIT_MEM, common.INFLUXDB_FIFLD_REDIS_DATA_MEM_USAGE},
|
||||
}
|
||||
|
||||
var tecentRdsMetricSpecs = map[string][]string{
|
||||
"CPUUseRate": {common.DEFAULT_STATISTICS, common.UNIT_PERCENT, common.INFLUXDB_FIELD_RDS_CPU_USAGE},
|
||||
"MemoryUseRate": {common.DEFAULT_STATISTICS, common.UNIT_PERCENT, common.INFLUXDB_FIELD_RDS_MEM_USAGE},
|
||||
"BytesSent": {common.DEFAULT_STATISTICS, common.UNIT_BYTEPS, common.INFLUXDB_FIELD_RDS_NET_BPS_TX_INTRANET},
|
||||
"BytesReceived": {common.DEFAULT_STATISTICS, common.UNIT_BYTEPS, common.INFLUXDB_FIELD_RDS_NET_BPS_RX_INTRANET},
|
||||
"VolumeRate": {common.DEFAULT_STATISTICS, common.UNIT_PERCENT, common.INFLUXDB_FIELD_RDS_DISK_USAGE},
|
||||
"ThreadsConnected": {common.DEFAULT_STATISTICS, common.UNIT_COUNT, common.INFLUXDB_FIELD_RDS_CONN_COUNT},
|
||||
"ConnectionUseRate": {common.DEFAULT_STATISTICS, common.UNIT_PERCENT, common.INFLUXDB_FIELD_RDS_CONN_USAGE},
|
||||
"QPS": {common.DEFAULT_STATISTICS, common.UNIT_COUNT_SEC, common.INFLUXDB_FIELD_RDS_QPS},
|
||||
"TPS": {common.DEFAULT_STATISTICS, common.UNIT_COUNT_SEC, common.INFLUXDB_FIELD_RDS_TPS},
|
||||
"InnodbDataRead": {common.DEFAULT_STATISTICS, common.UNIT_BYTEPS, common.INFLUXDB_FIELD_RDS_INNODB_REDA_BPS},
|
||||
"InnodbDataWritten": {common.DEFAULT_STATISTICS, common.UNIT_BYTEPS, common.INFLUXDB_FIELD_RDS_INNODB_WRITE_BPS},
|
||||
}
|
||||
|
||||
var tecentK8SClusterMetricSpecs = map[string][]string{
|
||||
"K8sClusterRateCpuCoreUsedCluster": {common.DEFAULT_STATISTICS, common.UNIT_PERCENT, common.INFLUXDB_FIELD_K8S_CLUSTER_CPU_USAGE},
|
||||
"K8sClusterRateMemRequestBytesCluster": {common.DEFAULT_STATISTICS, common.UNIT_PERCENT, common.INFLUXDB_FIELD_K8S_CLUSTER_MEM_USAGE},
|
||||
"K8sClusterAllocatablePodsTotal": {common.DEFAULT_STATISTICS, common.UNIT_COUNT, common.INFLUXDB_FIELD_K8S_CLUSTER_ALLOCATABLE_POD},
|
||||
"K8sClusterCpuCoreTotal": {common.DEFAULT_STATISTICS, common.UNIT_COUNT, common.INFLUXDB_FIELD_K8S_CLUSTER_TOTAL_CPUCORE},
|
||||
"K8sClusterRateCpuCoreRequestCluster": {common.DEFAULT_STATISTICS, common.UNIT_PERCENT, common.INFLUXDB_FIELD_K8S_CLUSTER_CPU_ALLOCATED},
|
||||
}
|
||||
|
||||
var tecentK8SDeployMetricSpecs = map[string][]string{
|
||||
"K8sWorkloadRateCpuCoreUsedCluster": {common.DEFAULT_STATISTICS, common.UNIT_PERCENT, common.INFLUXDB_FIELD_K8S_DEPLOY_CPU_USAGE},
|
||||
"K8sWorkloadRateMemUsageBytesCluster": {common.DEFAULT_STATISTICS, common.UNIT_PERCENT, common.INFLUXDB_FIELD_K8S_DEPLOY_MEM_USAGE},
|
||||
"K8sWorkloadPodRestartTotal": {common.DEFAULT_STATISTICS, common.UNIT_COUNT, common.INFLUXDB_FIELD_K8S_DEPLOY_RESTART_TOTAL},
|
||||
}
|
||||
|
||||
var tecentK8SPodMetricSpecs = map[string][]string{
|
||||
"K8sPodRateCpuCoreUsedLimit": {common.DEFAULT_STATISTICS, common.UNIT_PERCENT, common.INFLUXDB_FIELD_K8S_POD_CPU_USAGE},
|
||||
"K8sPodRateMemUsageLimit": {common.DEFAULT_STATISTICS, common.UNIT_PERCENT, common.INFLUXDB_FIELD_K8S_POD_MEM_USAGE},
|
||||
"K8sPodRestartTotal": {common.DEFAULT_STATISTICS, common.UNIT_COUNT, common.INFLUXDB_FIELD_K8S_POD_RESTART_TOTAL},
|
||||
}
|
||||
|
||||
var tecentK8SContainerMetricSpecs = map[string][]string{
|
||||
"K8sContainerRateCpuCoreUsedLimit": {common.DEFAULT_STATISTICS, common.UNIT_PERCENT, common.INFLUXDB_FIELD_K8S_CONTAINER_CPU_USAGE},
|
||||
"K8sContainerRateMemUsageLimit": {common.DEFAULT_STATISTICS, common.UNIT_PERCENT, common.INFLUXDB_FIELD_K8S_CONTAINER_MEM_USAGE},
|
||||
"K8sWorkloadNetworkReceiveBytesBw": {common.DEFAULT_STATISTICS, common.UNIT_MBPS, common.INFLUXDB_FIELD_K8S_DEPLOY_NET_BPS_RX},
|
||||
"K8sWorkloadNetworkTransmitBytesBw": {common.DEFAULT_STATISTICS, common.UNIT_MBPS, common.INFLUXDB_FIELD_K8S_DEPLOY_NET_BPS_TX},
|
||||
}
|
||||
|
||||
var tecentK8SNodeMetricSpecs = map[string][]string{
|
||||
"K8sNodeCpuUsage": {common.DEFAULT_STATISTICS, common.UNIT_PERCENT, common.INFLUXDB_FIELD_K8S_NODE_CPU_USAGE},
|
||||
"K8sNodeMemUsage": {common.DEFAULT_STATISTICS, common.UNIT_PERCENT, common.INFLUXDB_FIELD_K8S_NODE_MEM_USAGE},
|
||||
"K8sNodeLanIntraffic": {common.DEFAULT_STATISTICS, common.UNIT_MBPS, common.INFLUXDB_FIELD_K8S_NODE_NET_BPS_RX_INTRANET},
|
||||
"K8sNodeWanIntraffic": {common.DEFAULT_STATISTICS, common.UNIT_MBPS, common.INFLUXDB_FIELD_K8S_NODE_NET_BPS_RX_INTERNET},
|
||||
"K8sNodeLanOuttraffic": {common.DEFAULT_STATISTICS, common.UNIT_MBPS, common.INFLUXDB_FIELD_K8S_NODE_NET_BPS_TX_INTRANET},
|
||||
"K8sNodeWanOuttraffic": {common.DEFAULT_STATISTICS, common.UNIT_MBPS, common.INFLUXDB_FIELD_K8S_NODE_NET_BPS_TX_INTERNET},
|
||||
"K8sNodePodRestartTotal": {common.DEFAULT_STATISTICS, common.UNIT_MBPS, common.INFLUXDB_FIELD_K8S_NODE_POD_RESTART_TOTAL},
|
||||
}
|
||||
@@ -1,30 +0,0 @@
|
||||
// Copyright 2019 Yunion
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package collectors
|
||||
|
||||
import (
|
||||
"yunion.io/x/onecloud/pkg/cloudmon/collectors/common"
|
||||
"yunion.io/x/onecloud/pkg/cloudmon/options"
|
||||
"yunion.io/x/onecloud/pkg/mcclient"
|
||||
"yunion.io/x/onecloud/pkg/util/shellutils"
|
||||
)
|
||||
|
||||
func init() {
|
||||
shellutils.R(&options.ReportOptions{}, "report-redis", "Report Redis", reportRedis)
|
||||
}
|
||||
|
||||
func reportRedis(session *mcclient.ClientSession, args *options.ReportOptions) error {
|
||||
return common.ReportCloudMetricOfoperatorType(string(common.REDIS), session, args)
|
||||
}
|
||||
@@ -1,31 +0,0 @@
|
||||
// Copyright 2019 Yunion
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package collectors
|
||||
|
||||
import (
|
||||
"yunion.io/x/onecloud/pkg/cloudmon/collectors/common"
|
||||
"yunion.io/x/onecloud/pkg/cloudmon/options"
|
||||
"yunion.io/x/onecloud/pkg/mcclient"
|
||||
"yunion.io/x/onecloud/pkg/util/shellutils"
|
||||
)
|
||||
|
||||
func init() {
|
||||
shellutils.R(&options.ReportOptions{}, "report-server", "Report Server", reportServer)
|
||||
}
|
||||
|
||||
//入口函数[aliyun、huawei]
|
||||
func reportServer(session *mcclient.ClientSession, args *options.ReportOptions) error {
|
||||
return common.ReportCloudMetricOfoperatorType(string(common.SERVER), session, args)
|
||||
}
|
||||
@@ -1,5 +0,0 @@
|
||||
package collectors
|
||||
|
||||
const (
|
||||
REDIS_CRON_JOB_NAME = "redis_cron"
|
||||
)
|
||||
@@ -1,15 +0,0 @@
|
||||
// Copyright 2019 Yunion
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package storagemon // import "yunion.io/x/onecloud/pkg/cloudmon/collectors/storagemon"
|
||||
@@ -1,60 +0,0 @@
|
||||
// Copyright 2019 Yunion
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package storagemon
|
||||
|
||||
import (
|
||||
"yunion.io/x/onecloud/pkg/cloudmon/collectors/common"
|
||||
"yunion.io/x/onecloud/pkg/cloudmon/options"
|
||||
"yunion.io/x/onecloud/pkg/mcclient"
|
||||
modules "yunion.io/x/onecloud/pkg/mcclient/modules/compute"
|
||||
)
|
||||
|
||||
func init() {
|
||||
factory := SStorageReportFactory{}
|
||||
common.RegisterFactory(&factory)
|
||||
}
|
||||
|
||||
type SStorageReportFactory struct {
|
||||
common.CommonReportFactory
|
||||
}
|
||||
|
||||
func (self *SStorageReportFactory) NewCloudReport(provider *common.SProvider, session *mcclient.ClientSession,
|
||||
args *options.ReportOptions,
|
||||
operatorType string) common.ICloudReport {
|
||||
return &SStorageReport{
|
||||
common.CloudReportBase{
|
||||
SProvider: nil,
|
||||
Session: session,
|
||||
Args: args,
|
||||
Operator: string(common.STORAGE),
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func (S SStorageReportFactory) GetId() string {
|
||||
return string(common.STORAGE)
|
||||
}
|
||||
|
||||
type SStorageReport struct {
|
||||
common.CloudReportBase
|
||||
}
|
||||
|
||||
func (self *SStorageReport) Report() error {
|
||||
accounts, err := self.GetAllStorage(&modules.Storages)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return self.collectMetric(accounts)
|
||||
}
|
||||
@@ -1,64 +0,0 @@
|
||||
// Copyright 2019 Yunion
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package storagemon
|
||||
|
||||
import (
|
||||
"strconv"
|
||||
"time"
|
||||
|
||||
"yunion.io/x/jsonutils"
|
||||
"yunion.io/x/pkg/errors"
|
||||
|
||||
"yunion.io/x/onecloud/pkg/cloudmon/collectors/common"
|
||||
"yunion.io/x/onecloud/pkg/util/influxdb"
|
||||
)
|
||||
|
||||
func (self *SStorageReport) collectMetric(storages []jsonutils.JSONObject) error {
|
||||
dataList := make([]influxdb.SMetricData, 0)
|
||||
for _, storage := range storages {
|
||||
metric, err := self.collectMetricFromStorage(storage)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
metric.Timestamp = time.Now()
|
||||
metric.Name = STORAGE_MEASUREMENT
|
||||
dataList = append(dataList, metric)
|
||||
}
|
||||
return common.SendMetrics(self.Session, dataList, self.Args.Debug, "")
|
||||
}
|
||||
|
||||
func (self *SStorageReport) collectMetricFromStorage(storage jsonutils.JSONObject) (influxdb.SMetricData, error) {
|
||||
metric, err := self.NewMetricFromJson(storage)
|
||||
if err != nil {
|
||||
return metric, errors.Wrap(err, "collectMetricFromStorage NewMetricFromJson err")
|
||||
}
|
||||
capacity, _ := storage.Float("capacity")
|
||||
actUsedCapacity, _ := storage.Float("actual_capacity_used")
|
||||
var actFreeCapacity = float64(0)
|
||||
var capacityUsage = float64(0)
|
||||
if capacity != 0 {
|
||||
actFreeCapacity = capacity - actUsedCapacity
|
||||
capacityUsage = actUsedCapacity / capacity * 100
|
||||
}
|
||||
metric.Metrics = append(metric.Metrics, influxdb.SKeyValue{
|
||||
Key: STORAGE_FIELD_USAGE,
|
||||
Value: strconv.FormatFloat(capacityUsage, 'f', 2, 64),
|
||||
}, influxdb.SKeyValue{
|
||||
Key: STORAGE_FIELD_FREE,
|
||||
Value: strconv.FormatFloat(actFreeCapacity, 'f', -1, 64),
|
||||
})
|
||||
return metric, nil
|
||||
|
||||
}
|
||||
@@ -1,30 +0,0 @@
|
||||
// Copyright 2019 Yunion
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package collectors
|
||||
|
||||
import (
|
||||
"yunion.io/x/onecloud/pkg/cloudmon/collectors/common"
|
||||
"yunion.io/x/onecloud/pkg/cloudmon/options"
|
||||
"yunion.io/x/onecloud/pkg/mcclient"
|
||||
"yunion.io/x/onecloud/pkg/util/shellutils"
|
||||
)
|
||||
|
||||
func init() {
|
||||
shellutils.R(&options.ReportOptions{}, "report-storage", "Report Storage", reportStorage)
|
||||
}
|
||||
|
||||
func reportStorage(session *mcclient.ClientSession, args *options.ReportOptions) error {
|
||||
return common.ReportCustomizeCloudMetric(string(common.STORAGE), session, args)
|
||||
}
|
||||
@@ -1,94 +0,0 @@
|
||||
// Copyright 2019 Yunion
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package collectors
|
||||
|
||||
import (
|
||||
"yunion.io/x/jsonutils"
|
||||
"yunion.io/x/log"
|
||||
"yunion.io/x/pkg/errors"
|
||||
"yunion.io/x/pkg/utils"
|
||||
|
||||
o "yunion.io/x/onecloud/pkg/cloudmon/options"
|
||||
"yunion.io/x/onecloud/pkg/mcclient"
|
||||
"yunion.io/x/onecloud/pkg/mcclient/modulebase"
|
||||
"yunion.io/x/onecloud/pkg/util/influxdb"
|
||||
)
|
||||
|
||||
func jsonToMetric(obj *jsonutils.JSONDict, name string, tags []string, metrics []string) (influxdb.SMetricData, error) {
|
||||
metric := influxdb.SMetricData{Name: name}
|
||||
objMap, err := obj.GetMap()
|
||||
if err != nil {
|
||||
return metric, errors.Wrap(err, "obj.GetMap")
|
||||
}
|
||||
tagPairs := make([]influxdb.SKeyValue, 0)
|
||||
metricPairs := make([]influxdb.SKeyValue, 0)
|
||||
for k, v := range objMap {
|
||||
val, _ := v.GetString()
|
||||
if utils.IsInStringArray(k, tags) {
|
||||
tagPairs = append(tagPairs, influxdb.SKeyValue{
|
||||
Key: k, Value: val,
|
||||
})
|
||||
} else if utils.IsInStringArray(k, metrics) {
|
||||
metricPairs = append(metricPairs, influxdb.SKeyValue{
|
||||
Key: k, Value: val,
|
||||
})
|
||||
}
|
||||
}
|
||||
metric.Tags = tagPairs
|
||||
metric.Metrics = metricPairs
|
||||
return metric, nil
|
||||
}
|
||||
|
||||
func sendMetrics(s *mcclient.ClientSession, metrics []influxdb.SMetricData, debug bool) error {
|
||||
urls, err := s.GetServiceURLs("influxdb", o.Options.SessionEndpointType, "")
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "GetServiceURLs")
|
||||
}
|
||||
return influxdb.SendMetrics(urls, o.Options.InfluxDatabase, metrics, debug)
|
||||
}
|
||||
|
||||
type TListFunc func(*mcclient.ClientSession, jsonutils.JSONObject) (*modulebase.ListResult, error)
|
||||
type TProcessFunc func(jsonutils.JSONObject) error
|
||||
|
||||
func listAll(s *mcclient.ClientSession, listFunc TListFunc, kwargs jsonutils.JSONObject, processFunc TProcessFunc) error {
|
||||
type sListParams struct {
|
||||
Limit int
|
||||
Offset int
|
||||
}
|
||||
offset := 0
|
||||
total := -1
|
||||
for total < 0 || offset < total {
|
||||
params := jsonutils.Marshal(sListParams{
|
||||
Limit: 100,
|
||||
Offset: offset,
|
||||
})
|
||||
if kwargs != nil {
|
||||
params.(*jsonutils.JSONDict).Update(kwargs)
|
||||
}
|
||||
result, err := listFunc(s, jsonutils.Marshal(params))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
total = result.Total
|
||||
for i := range result.Data {
|
||||
offset += 1
|
||||
err = processFunc(result.Data[i])
|
||||
if err != nil {
|
||||
log.Errorf("fail to processData %s: %s", result.Data[i], err)
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
@@ -1,15 +0,0 @@
|
||||
// Copyright 2019 Yunion
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package vmwaremon // import "yunion.io/x/onecloud/pkg/cloudmon/collectors/vmwaremon"
|
||||
@@ -1,102 +0,0 @@
|
||||
// Copyright 2019 Yunion
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package vmwaremon
|
||||
|
||||
import (
|
||||
"yunion.io/x/jsonutils"
|
||||
"yunion.io/x/log"
|
||||
|
||||
"yunion.io/x/onecloud/pkg/apis/compute"
|
||||
"yunion.io/x/onecloud/pkg/cloudmon/collectors/common"
|
||||
"yunion.io/x/onecloud/pkg/cloudmon/options"
|
||||
"yunion.io/x/onecloud/pkg/mcclient"
|
||||
modules "yunion.io/x/onecloud/pkg/mcclient/modules/compute"
|
||||
)
|
||||
|
||||
func init() {
|
||||
factory := SEsxiCloudReportFactory{}
|
||||
common.RegisterFactory(&factory)
|
||||
}
|
||||
|
||||
type SEsxiCloudReportFactory struct {
|
||||
common.CommonReportFactory
|
||||
}
|
||||
|
||||
func (self *SEsxiCloudReportFactory) NewCloudReport(provider *common.SProvider, session *mcclient.ClientSession,
|
||||
args *options.ReportOptions, operatorType string) common.ICloudReport {
|
||||
return &SEsxiCloudReport{
|
||||
common.CloudReportBase{
|
||||
SProvider: provider,
|
||||
Session: session,
|
||||
Args: args,
|
||||
Operator: operatorType,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func (self *SEsxiCloudReportFactory) GetId() string {
|
||||
return compute.CLOUD_PROVIDER_VMWARE
|
||||
}
|
||||
|
||||
type SEsxiCloudReport struct {
|
||||
common.CloudReportBase
|
||||
}
|
||||
|
||||
func (self *SEsxiCloudReport) Report() error {
|
||||
var err error
|
||||
switch self.Operator {
|
||||
case string(common.SERVER):
|
||||
//servers, err := self.getAllserverOfThisProvider(&modules.Servers)
|
||||
servers, err := self.GetAllserverOfThisProvider(&modules.Servers, nil)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = self.CollectServerMetricByProvider(servers)
|
||||
case string(common.HOST):
|
||||
hosts, err := self.GetAllHostOfThisProvider(&modules.Hosts)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
//err = common.CollectRegionMetricAsync(40, nil, hosts, self)
|
||||
err = self.CollectRegionHostMetricAsync(hosts)
|
||||
}
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (self *SEsxiCloudReport) CollectServerMetricByProvider(servers []jsonutils.JSONObject) error {
|
||||
return self.collectRegionMetricOfServerBatch("", servers)
|
||||
|
||||
}
|
||||
|
||||
func (self *SEsxiCloudReport) CollectRegionHostMetricAsync(servers []jsonutils.JSONObject) error {
|
||||
log.Errorf("cloudproviderid: %s,%s count:%d", self.SProvider.Id, self.getMonType(), len(servers))
|
||||
if self.Args.Batch == 0 {
|
||||
self.Args.Batch = 100
|
||||
}
|
||||
for i := 0; i < len(servers); i += self.Args.Batch {
|
||||
tmp := i + self.Args.Batch
|
||||
if tmp > len(servers) {
|
||||
tmp = len(servers)
|
||||
}
|
||||
err := self.collectRegionMetricOfServerBatch("", servers[i:tmp])
|
||||
if err != nil {
|
||||
log.Errorln(err)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
@@ -1,350 +0,0 @@
|
||||
// Copyright 2019 Yunion
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package vmwaremon
|
||||
|
||||
import (
|
||||
"context"
|
||||
"net/url"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/vmware/govmomi/performance"
|
||||
"github.com/vmware/govmomi/vim25/types"
|
||||
"golang.org/x/sync/errgroup"
|
||||
|
||||
"yunion.io/x/jsonutils"
|
||||
"yunion.io/x/log"
|
||||
"yunion.io/x/pkg/errors"
|
||||
"yunion.io/x/pkg/utils"
|
||||
|
||||
"yunion.io/x/onecloud/pkg/cloudmon/collectors/common"
|
||||
"yunion.io/x/onecloud/pkg/cloudprovider"
|
||||
"yunion.io/x/onecloud/pkg/multicloud/esxi"
|
||||
"yunion.io/x/onecloud/pkg/util/influxdb"
|
||||
)
|
||||
|
||||
func (self *SEsxiCloudReport) CollectRegionMetric(region cloudprovider.ICloudRegion,
|
||||
servers []jsonutils.JSONObject) error {
|
||||
var err error
|
||||
switch self.Operator {
|
||||
case string(common.SERVER):
|
||||
err = self.collectRegionMetricOfServer(servers)
|
||||
case string(common.HOST):
|
||||
err = self.collectRegionMetricOfHost(servers)
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
func (self *SEsxiCloudReport) getMonType() string {
|
||||
switch self.Operator {
|
||||
case string(common.SERVER):
|
||||
return common.TYPE_VIRTUALMACHINE
|
||||
case string(common.HOST):
|
||||
return common.TYPE_HOSTSYSTEM
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (self *SEsxiCloudReport) collectRegionMetricOfServerBatch(hostExtId string, servers []jsonutils.JSONObject) error {
|
||||
since, until, err := common.TimeRangeFromArgs(self.Args)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
client, err := self.newEsxiClient()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
metrics := make([]string, 0)
|
||||
for metric, _ := range esxiMetricSpecs {
|
||||
metrics = append(metrics, metric)
|
||||
}
|
||||
now := time.Now()
|
||||
perfEntityMetrics, err := client.GetMonitorDataList(hostExtId, servers, self.getMonType(), metrics, since,
|
||||
until)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "SEsxiCloudReport GetMonitorDataList error")
|
||||
}
|
||||
|
||||
log.Infof("get %s metriclist cost: %f s", self.getMonType(), time.Now().Sub(now).Seconds())
|
||||
|
||||
writeGroup, _ := errgroup.WithContext(context.Background())
|
||||
for i, _ := range servers {
|
||||
tmpSer := servers[i]
|
||||
writeGroup.Go(func() error {
|
||||
extId, _ := tmpSer.GetString("external_id")
|
||||
dataList := make([]influxdb.SMetricData, 0)
|
||||
if entityMetric, ok := perfEntityMetrics[extId]; ok {
|
||||
if self.Operator == string(common.SERVER) {
|
||||
metric, err := common.FillVMCapacity(tmpSer.(*jsonutils.JSONDict))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
dataList = append(dataList, metric)
|
||||
}
|
||||
serverMetric := self.collectMetricFromThisServer_(tmpSer, self.getMonType(), entityMetric)
|
||||
dataList = append(dataList, serverMetric...)
|
||||
writStartTime := time.Now()
|
||||
common.SendMetrics(self.Session, dataList, self.Args.Debug, "")
|
||||
log.Errorf("influxdb write cost:%f s", time.Now().Sub(writStartTime).Seconds())
|
||||
}
|
||||
return nil
|
||||
})
|
||||
}
|
||||
err = writeGroup.Wait()
|
||||
log.Infof("collect %s num:%d", self.getMonType(), len(servers))
|
||||
return nil
|
||||
}
|
||||
|
||||
func (self *SEsxiCloudReport) collectRegionMetricOfServer(servers []jsonutils.JSONObject) error {
|
||||
dataList := make([]influxdb.SMetricData, 0)
|
||||
since, until, err := common.TimeRangeFromArgs(self.Args)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
client, err := self.newEsxiClient()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
for _, server := range servers {
|
||||
perfEntityMetrics, metricIdNamedTable, err := client.GetMonitorData(server, common.TYPE_VIRTUALMACHINE,
|
||||
esxiMetricSpecsSync, since, until)
|
||||
if err != nil {
|
||||
log.Errorln(err)
|
||||
continue
|
||||
}
|
||||
for _, perfEntityMetric := range perfEntityMetrics {
|
||||
perfMetricSeries := perfEntityMetric.Value
|
||||
perfSampleInfos := perfEntityMetric.SampleInfo
|
||||
for _, perfMetricSerie := range perfMetricSeries {
|
||||
if perfMetricIntSerie, ok := perfMetricSerie.(*types.PerfMetricIntSeries); ok {
|
||||
metric, err := common.FillVMCapacity(server.(*jsonutils.JSONDict))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
dataList = append(dataList, metric)
|
||||
serverMetric := self.collectMetricFromThisServer(server, common.TYPE_VIRTUALMACHINE, perfMetricIntSerie,
|
||||
perfSampleInfos, metricIdNamedTable)
|
||||
dataList = append(dataList, serverMetric...)
|
||||
}
|
||||
}
|
||||
}
|
||||
err = common.SendMetrics(self.Session, dataList, self.Args.Debug, "")
|
||||
if err != nil {
|
||||
log.Errorln(err)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (self *SEsxiCloudReport) collectRegionMetricOfHost(hosts []jsonutils.JSONObject) error {
|
||||
dataList := make([]influxdb.SMetricData, 0)
|
||||
since, until, err := common.TimeRangeFromArgs(self.Args)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
client, err := self.newEsxiClient()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
for _, host := range hosts {
|
||||
perfEntityMetrics, metricIdNamedTable, err := client.GetMonitorData(host, common.TYPE_HOSTSYSTEM, esxiMetricSpecsSync,
|
||||
since, until)
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
for _, perfEntityMetric := range perfEntityMetrics {
|
||||
perfMetricSeries := perfEntityMetric.Value
|
||||
perfSampleInfos := perfEntityMetric.SampleInfo
|
||||
for _, perfMetricSerie := range perfMetricSeries {
|
||||
if perfMetricIntSerie, ok := perfMetricSerie.(*types.PerfMetricIntSeries); ok {
|
||||
serverMetric := self.collectMetricFromThisServer(host, common.TYPE_HOSTSYSTEM, perfMetricIntSerie,
|
||||
perfSampleInfos, metricIdNamedTable)
|
||||
dataList = append(dataList, serverMetric...)
|
||||
}
|
||||
}
|
||||
}
|
||||
err = common.SendMetrics(self.Session, dataList, self.Args.Debug, "")
|
||||
if err != nil {
|
||||
log.Errorln(err)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (self *SEsxiCloudReport) collectMetricFromThisServer_(server jsonutils.JSONObject, monType string,
|
||||
entityMetric performance.EntityMetric) []influxdb.SMetricData {
|
||||
datas := make([]influxdb.SMetricData, 0)
|
||||
for _, metricSeries := range entityMetric.Value {
|
||||
if _, ok := esxiMetricSpecs[metricSeries.Name]; !ok {
|
||||
continue
|
||||
}
|
||||
for i, value := range metricSeries.Value {
|
||||
metric := influxdb.SMetricData{}
|
||||
if monType == common.TYPE_HOSTSYSTEM {
|
||||
metric, _ = common.JsonToMetric(server.(*jsonutils.JSONDict), "", common.HostTags, make([]string, 0))
|
||||
} else {
|
||||
metric, _ = common.JsonToMetric(server.(*jsonutils.JSONDict), "", common.ServerTags, make([]string, 0))
|
||||
}
|
||||
|
||||
if len(entityMetric.SampleInfo) > 0 {
|
||||
metric.Timestamp = entityMetric.SampleInfo[i].Timestamp
|
||||
}
|
||||
influxDbSpecs := esxiMetricSpecs[metricSeries.Name]
|
||||
metric.Name = common.GetMeasurement(monType, influxDbSpecs[2])
|
||||
var pairsKey string
|
||||
if strings.Contains(influxDbSpecs[2], ",") {
|
||||
pairsKey = common.SubstringBetween(influxDbSpecs[2], ".", ",")
|
||||
} else {
|
||||
pairsKey = common.SubstringAfter(influxDbSpecs[2], ".")
|
||||
}
|
||||
tag := common.SubstringAfter(influxDbSpecs[2], ",")
|
||||
if tag != "" && strings.Contains(influxDbSpecs[2], "=") {
|
||||
metric.Tags = append(metric.Tags, influxdb.SKeyValue{
|
||||
Key: common.SubstringBefore(tag, "="),
|
||||
Value: common.SubstringAfter(tag, "="),
|
||||
})
|
||||
}
|
||||
value = formateValue(value, influxDbSpecs)
|
||||
metric.Metrics = append(metric.Metrics, influxdb.SKeyValue{
|
||||
Key: pairsKey,
|
||||
Value: strconv.FormatInt(value, 10),
|
||||
})
|
||||
if monType == common.TYPE_HOSTSYSTEM {
|
||||
self.AddMetricTag(&metric, common.OtherHostTag)
|
||||
} else {
|
||||
}
|
||||
datas = append(datas, metric)
|
||||
}
|
||||
}
|
||||
return datas
|
||||
}
|
||||
|
||||
func (self *SEsxiCloudReport) collectMetricFromThisServer(server jsonutils.JSONObject, monType string,
|
||||
perfMetricIntSerie *types.PerfMetricIntSeries, perfSampleInfos []types.PerfSampleInfo,
|
||||
metricIdNamedTable map[int32]string) []influxdb.SMetricData {
|
||||
datas := make([]influxdb.SMetricData, 0)
|
||||
for i, value := range perfMetricIntSerie.Value {
|
||||
metric := influxdb.SMetricData{}
|
||||
if monType == common.TYPE_HOSTSYSTEM {
|
||||
metric, _ = common.JsonToMetric(server.(*jsonutils.JSONDict), "", common.HostTags, make([]string, 0))
|
||||
} else {
|
||||
metric, _ = common.JsonToMetric(server.(*jsonutils.JSONDict), "", common.ServerTags, make([]string, 0))
|
||||
}
|
||||
counterId := perfMetricIntSerie.Id.CounterId
|
||||
instance := perfMetricIntSerie.Id.Instance
|
||||
if instance != "" {
|
||||
metric.Tags = append(metric.Tags, influxdb.SKeyValue{
|
||||
Key: "perf_instance",
|
||||
Value: instance,
|
||||
})
|
||||
}
|
||||
if len(perfSampleInfos) > 0 {
|
||||
metric.Timestamp = perfSampleInfos[i].Timestamp
|
||||
}
|
||||
|
||||
influxDbSpecs := esxiMetricSpecsSync[metricIdNamedTable[counterId]]
|
||||
metric.Name = common.GetMeasurement(monType, influxDbSpecs[2])
|
||||
var pairsKey string
|
||||
if strings.Contains(influxDbSpecs[2], ",") {
|
||||
pairsKey = common.SubstringBetween(influxDbSpecs[2], ".", ",")
|
||||
} else {
|
||||
pairsKey = common.SubstringAfter(influxDbSpecs[2], ".")
|
||||
}
|
||||
tag := common.SubstringAfter(influxDbSpecs[2], ",")
|
||||
if tag != "" && strings.Contains(influxDbSpecs[2], "=") {
|
||||
metric.Tags = append(metric.Tags, influxdb.SKeyValue{
|
||||
Key: common.SubstringBefore(tag, "="),
|
||||
Value: common.SubstringAfter(tag, "="),
|
||||
})
|
||||
}
|
||||
value = formateValue(value, influxDbSpecs)
|
||||
metric.Metrics = append(metric.Metrics, influxdb.SKeyValue{
|
||||
Key: pairsKey,
|
||||
Value: strconv.FormatInt(value, 10),
|
||||
})
|
||||
if monType == common.TYPE_HOSTSYSTEM {
|
||||
self.AddMetricTag(&metric, common.OtherHostTag)
|
||||
} else {
|
||||
self.AddMetricTag(&metric, common.OtherVmTags)
|
||||
}
|
||||
datas = append(datas, metric)
|
||||
}
|
||||
return datas
|
||||
}
|
||||
|
||||
func formateValue(value int64, influxDbSpecs []string) int64 {
|
||||
if influxDbSpecs[1] == UNIT_KBPS && strings.Contains(influxDbSpecs[2], "bps") {
|
||||
value = value * 1000
|
||||
}
|
||||
if influxDbSpecs[1] == UNIT_KBPS && strings.Contains(influxDbSpecs[2], "bytes") {
|
||||
value = value * 1000
|
||||
}
|
||||
if influxDbSpecs[1] == UNIT_PERCENT && strings.Contains(influxDbSpecs[2], "usage_active") {
|
||||
value = value / 100
|
||||
}
|
||||
if influxDbSpecs[1] == UNIT_PERCENT && strings.Contains(influxDbSpecs[2], "used_percent") {
|
||||
value = value / 100
|
||||
}
|
||||
return value
|
||||
}
|
||||
|
||||
func (self *SEsxiCloudReport) newEsxiClient() (*esxi.SESXiClient, error) {
|
||||
parts, err := url.Parse(self.SProvider.AccessUrl)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
host, port, err := parseHostPort(parts.Host, 443)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
secretDe, _ := utils.DescryptAESBase64(self.SProvider.Id, self.SProvider.Secret)
|
||||
esxiCfg := esxi.NewESXiClientConfig(host, port, self.SProvider.Account, secretDe)
|
||||
proCfg := cloudprovider.ProviderConfig{
|
||||
Id: self.SProvider.Id,
|
||||
Name: self.SProvider.Name,
|
||||
Account: self.SProvider.Account,
|
||||
Secret: secretDe,
|
||||
URL: self.SProvider.AccessUrl,
|
||||
Vendor: self.SProvider.Provider,
|
||||
}
|
||||
esxiCfg.CloudproviderConfig(proCfg)
|
||||
client, err := esxi.NewESXiClient(esxiCfg)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return client, nil
|
||||
}
|
||||
|
||||
func parseHostPort(host string, defPort int) (string, int, error) {
|
||||
colonPos := strings.IndexByte(host, ':')
|
||||
if colonPos > 0 {
|
||||
h := host[:colonPos]
|
||||
p, err := strconv.Atoi(host[colonPos+1:])
|
||||
if err != nil {
|
||||
log.Errorf("Invalid host %s", host)
|
||||
return "", 0, err
|
||||
}
|
||||
if p == 0 {
|
||||
p = defPort
|
||||
}
|
||||
return h, p, nil
|
||||
} else {
|
||||
return host, defPort, nil
|
||||
}
|
||||
}
|
||||
@@ -1,146 +0,0 @@
|
||||
// Copyright 2019 Yunion
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package vmwaremon
|
||||
|
||||
const (
|
||||
PERIOD = 60
|
||||
UNIT_AVERAGE = "Average"
|
||||
DEFAULT_STATISTICS = "Average,Minimum,Maximum"
|
||||
UNIT_PERCENT = "Percent"
|
||||
UNIT_KBPS = "kiloBytesPerSecond"
|
||||
UNIT_BPS = "bps"
|
||||
UNIT_MBPS = "Mbps"
|
||||
UNIT_BYTEPS = "Bps"
|
||||
UNIT_CPS = "cps"
|
||||
UNIT_COUNT = "count"
|
||||
UNIT_MEM = "byte"
|
||||
UNIT_MSEC = "ms"
|
||||
UNIT_COUNT_SEC = "count/s"
|
||||
|
||||
//ESC监控指标
|
||||
INFLUXDB_FIELD_CPU_USAGE = "vm_cpu.usage_active"
|
||||
INFLUXDB_FIELD_MEM_USAGE = "vm_mem.used_percent"
|
||||
INFLUXDB_FIELD_DISK_READ_BPS = "vm_diskio.read_bps"
|
||||
INFLUXDB_FIELD_DISK_READ_BPS_VIRTUAL = INFLUXDB_FIELD_DISK_READ_BPS + ",disk_type=virtual"
|
||||
INFLUXDB_FIELD_DISK_WRITE_BPS = "vm_diskio.write_bps"
|
||||
INFLUXDB_FIELD_DISK_WRITE_BPS_VIRTUAL = INFLUXDB_FIELD_DISK_WRITE_BPS + ",disk_type=virtual"
|
||||
INFLUXDB_FIELD_DISK_READ_IOPS = "vm_diskio.read_iops"
|
||||
INFLUXDB_FIELD_DISK_WRITE_IOPS = "vm_diskio.write_iops"
|
||||
INFLUXDB_FIELD_NET_BPS_RX = "vm_netio.bps_recv"
|
||||
INFLUXDB_FIELD_NET_BPS_RX_INTERNET = INFLUXDB_FIELD_NET_BPS_RX + ",net_type=internet"
|
||||
INFLUXDB_FIELD_NET_BPS_RX_INTRANET = INFLUXDB_FIELD_NET_BPS_RX + ",net_type=intranet"
|
||||
INFLUXDB_FIELD_NET_BPS_TX = "vm_netio.bps_sent"
|
||||
INFLUXDB_FIELD_NET_BPS_TX_INTERNET = INFLUXDB_FIELD_NET_BPS_TX + ",net_type=internet"
|
||||
INFLUXDB_FIELD_NET_BPS_TX_INTRANET = INFLUXDB_FIELD_NET_BPS_TX + ",net_type=intranet"
|
||||
INFLUXDB_FIELD_WANOUTTRAFFIC = "vm_eipio.bps_out"
|
||||
INFLUXDB_FIELD_WANINTRAFFIC = "vm_eipio.bps_in"
|
||||
INFLUXDB_FIELD_WANOUTPKG = "vm_eipio.pps_out"
|
||||
INFLUXDB_FIELD_WANINPKG = "vm_eipio.pps_in"
|
||||
|
||||
//RDS监控指标
|
||||
INFLUXDB_FIELD_RDS_CPU_USAGE = "rds_cpu.usage_active"
|
||||
INFLUXDB_FIELD_RDS_MEM_USAGE = "rds_mem.used_percent"
|
||||
INFLUXDB_FIELD_RDS_NET_BPS_RX = "rds_netio.bps_recv"
|
||||
INFLUXDB_FIELD_RDS_NET_BPS_RX_MYSQL = INFLUXDB_FIELD_RDS_NET_BPS_RX + ",server_type=mysql"
|
||||
INFLUXDB_FIELD_RDS_NET_BPS_RX_SQLSERVER = INFLUXDB_FIELD_RDS_NET_BPS_RX + ",server_type=sqlserver"
|
||||
INFLUXDB_FIELD_RDS_NET_BPS_TX = "rds_netio.bps_send"
|
||||
INFLUXDB_FIELD_RDS_NET_BPS_TX_MYSQL = INFLUXDB_FIELD_RDS_NET_BPS_TX + ",server_type=mysql"
|
||||
INFLUXDB_FIELD_RDS_NET_BPS_TX_SQLSERVER = INFLUXDB_FIELD_RDS_NET_BPS_TX + ",server_type=sqlserver"
|
||||
INFLUXDB_FIELD_RDS_DISK_USAGE = "rds_disk.used_percent"
|
||||
INFLUXDB_FIELD_RDS_DISK_READ_BPS = "rds_diskio.read_bps"
|
||||
INFLUXDB_FIELD_RDS_DISK_WRITE_BPS = "rds_diskio.write_bps"
|
||||
INFLUXDB_FIELD_RDS_CONN_COUNT = "rds_conn.used_count"
|
||||
INFLUXDB_FIELD_RDS_CONN_USAGE = "rds_conn.used_percent"
|
||||
|
||||
INFLUXDB_FIELD_RDS_QPS = "rds_qps.query_qps"
|
||||
INFLUXDB_FIELD_RDS_TPS = "rds_tps.trans_qps"
|
||||
INFLUXDB_FIELD_RDS_INNODB_REDA_BPS = "rds_innodb.read_bps"
|
||||
INFLUXDB_FIELD_RDS_INNODB_WRITE_BPS = "rds_innodb.write_bps"
|
||||
|
||||
//REDIS监控指标
|
||||
INFLUXDB_FIELD_REDIS_CPU_USAGE = "dcs_cpu.usage_percent"
|
||||
INFLUXDB_FIELD_REDIS_MEM_USAGE = "dcs_mem.used_percent"
|
||||
INFLUXDB_FIELD_REDIS_NET_BPS_RX = "dcs_netio.bps_recv"
|
||||
INFLUXDB_FIELD_REDIS_NET_BPS_TX = "dcs_netio.bps_sent"
|
||||
INFLUXDB_FIFLD_REDIS_CONN_USAGE = "dcs_conn.used_conn"
|
||||
INFLUXDB_FIFLD_REDIS_OPT_SES = "dcs_instantopt.opt_sec"
|
||||
INFLUXDB_FIFLD_REDIS_CACHE_KEYS = "dcs_cachekeys.key_count"
|
||||
INFLUXDB_FIFLD_REDIS_CACHE_EXP_KEYS = INFLUXDB_FIFLD_REDIS_CACHE_KEYS + ",exp=expire"
|
||||
INFLUXDB_FIFLD_REDIS_DATA_MEM_USAGE = "dcs_datamem.used_byte"
|
||||
|
||||
//对象存储OSS监控指标
|
||||
INFLUXDB_FIELD_OSS_NET_BPS_RX = "oss_netio.bps_recv"
|
||||
INFLUXDB_FIELD_OSS_NET_BPS_RX_INTERNET = INFLUXDB_FIELD_OSS_NET_BPS_RX + ",net_type=internet"
|
||||
INFLUXDB_FIELD_OSS_NET_BPS_RX_INTRANET = INFLUXDB_FIELD_OSS_NET_BPS_RX + ",net_type=intranet"
|
||||
INFLUXDB_FIELD_OSS_NET_BPS_TX = "oss_netio.bps_sent"
|
||||
INFLUXDB_FIELD_OSS_NET_BPS_TX_INTERNET = INFLUXDB_FIELD_OSS_NET_BPS_TX + ",net_type=internet"
|
||||
INFLUXDB_FIELD_OSS_NET_BPS_TX_INTRANET = INFLUXDB_FIELD_OSS_NET_BPS_TX + ",net_type=intranet"
|
||||
INFLUXDB_FIELD_OSS_LATECY = "oss_latency.req_late"
|
||||
INFLUXDB_FIELD_OSS_LATECY_GET = INFLUXDB_FIELD_OSS_LATECY + ",request=get"
|
||||
INFLUXDB_FIELD_OSS_LATECY_POST = INFLUXDB_FIELD_OSS_LATECY + ",request=post"
|
||||
INFLUXDB_FIELD_OSS_REQ_COUNT = "oss_req.req_count"
|
||||
INFLUXDB_FIELD_OSS_REQ_COUNT_GET = INFLUXDB_FIELD_OSS_REQ_COUNT + ",request=get"
|
||||
INFLUXDB_FIELD_OSS_REQ_COUNT_POST = INFLUXDB_FIELD_OSS_REQ_COUNT + ",request=post"
|
||||
INFLUXDB_FIELD_OSS_REQ_COUNT_5XX = INFLUXDB_FIELD_OSS_REQ_COUNT + ",request=5xx"
|
||||
INFLUXDB_FIELD_OSS_REQ_COUNT_4XX = INFLUXDB_FIELD_OSS_REQ_COUNT + ",request=4xx"
|
||||
|
||||
//负载均衡监控指标
|
||||
INFLUXDB_FIELD_ELB_NET_BPS_RX = "haproxy.bin"
|
||||
INFLUXDB_FIELD_ELB_NET_BPS_TX = "haproxy.bout"
|
||||
INFLUXDB_FIELD_ELB_REQ_RATE = "haproxy.req_rate,request=http"
|
||||
INFLUXDB_FIELD_ELB_CONN_RATE = "haproxy.conn_rate,request=tcp"
|
||||
INFLUXDB_FIELD_ELB_DREQ_COUNT = "haproxy.dreq,request=http"
|
||||
INFLUXDB_FIELD_ELB_DCONN_COUNT = "haproxy.dcon,request=tcp"
|
||||
INFLUXDB_FIELD_ELB_HRSP_COUNT = "haproxy.hrsp_Nxx"
|
||||
INFLUXDB_FIELD_ELB_HRSP_COUNT_2XX = INFLUXDB_FIELD_ELB_HRSP_COUNT + ",request=2xx"
|
||||
INFLUXDB_FIELD_ELB_HRSP_COUNT_3XX = INFLUXDB_FIELD_ELB_HRSP_COUNT + ",request=3xx"
|
||||
INFLUXDB_FIELD_ELB_HRSP_COUNT_4XX = INFLUXDB_FIELD_ELB_HRSP_COUNT + ",request=4xx"
|
||||
INFLUXDB_FIELD_ELB_HRSP_COUNT_5XX = INFLUXDB_FIELD_ELB_HRSP_COUNT + ",request=5xx"
|
||||
INFLUXDB_FIELD_ELB_CHC_STATUS = "haproxy.check_status"
|
||||
INFLUXDB_FIELD_ELB_CHC_CODE = "haproxy.check_code"
|
||||
INFLUXDB_FIELD_ELB_LAST_CHC = "haproxy.last_chk"
|
||||
|
||||
KEY_VMS = "vms"
|
||||
KEY_CPUS = "cpus"
|
||||
KEY_MEMS = "mems"
|
||||
KEY_DISKS = "disks"
|
||||
|
||||
KEY_LIMIT = "limit"
|
||||
KEY_ADMIN = "admin"
|
||||
KEY_USABLE = "usable"
|
||||
)
|
||||
|
||||
//multiCloud查询指标列表组装
|
||||
var esxiMetricSpecs = map[string][]string{
|
||||
"cpu.usage.average": {DEFAULT_STATISTICS, UNIT_PERCENT, INFLUXDB_FIELD_CPU_USAGE},
|
||||
"mem.usage.average": {DEFAULT_STATISTICS, UNIT_PERCENT, INFLUXDB_FIELD_MEM_USAGE},
|
||||
"net.received.average": {DEFAULT_STATISTICS, UNIT_KBPS, INFLUXDB_FIELD_NET_BPS_RX},
|
||||
"net.transmitted.average": {DEFAULT_STATISTICS, UNIT_KBPS, INFLUXDB_FIELD_NET_BPS_TX},
|
||||
"disk.read.average": {DEFAULT_STATISTICS, UNIT_KBPS, INFLUXDB_FIELD_DISK_READ_BPS},
|
||||
"disk.write.average": {DEFAULT_STATISTICS, UNIT_KBPS, INFLUXDB_FIELD_DISK_WRITE_BPS},
|
||||
"virtualDisk.read.average": {DEFAULT_STATISTICS, UNIT_KBPS, INFLUXDB_FIELD_DISK_READ_BPS_VIRTUAL},
|
||||
"virtualDisk.write.average": {DEFAULT_STATISTICS, UNIT_KBPS, INFLUXDB_FIELD_DISK_WRITE_BPS_VIRTUAL},
|
||||
}
|
||||
|
||||
var esxiMetricSpecsSync = map[string][]string{
|
||||
"cpu_usage": {DEFAULT_STATISTICS, UNIT_PERCENT, INFLUXDB_FIELD_CPU_USAGE},
|
||||
"mem_usage": {DEFAULT_STATISTICS, UNIT_PERCENT, INFLUXDB_FIELD_MEM_USAGE},
|
||||
"net_received": {DEFAULT_STATISTICS, UNIT_KBPS, INFLUXDB_FIELD_NET_BPS_RX},
|
||||
"net_transmitted": {DEFAULT_STATISTICS, UNIT_KBPS, INFLUXDB_FIELD_NET_BPS_TX},
|
||||
"disk_read": {DEFAULT_STATISTICS, UNIT_KBPS, INFLUXDB_FIELD_DISK_READ_BPS},
|
||||
"disk_write": {DEFAULT_STATISTICS, UNIT_KBPS, INFLUXDB_FIELD_DISK_WRITE_BPS},
|
||||
"virtualDisk_read": {DEFAULT_STATISTICS, UNIT_KBPS, INFLUXDB_FIELD_DISK_READ_BPS_VIRTUAL},
|
||||
"virtualDisk_write": {DEFAULT_STATISTICS, UNIT_KBPS, INFLUXDB_FIELD_DISK_WRITE_BPS_VIRTUAL},
|
||||
}
|
||||
@@ -1,15 +0,0 @@
|
||||
// Copyright 2019 Yunion
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package zstackmon // import "yunion.io/x/onecloud/pkg/cloudmon/collectors/zstackmon"
|
||||
@@ -1,110 +0,0 @@
|
||||
// Copyright 2019 Yunion
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package zstackmon
|
||||
|
||||
import (
|
||||
"yunion.io/x/log"
|
||||
|
||||
"yunion.io/x/onecloud/pkg/apis/compute"
|
||||
"yunion.io/x/onecloud/pkg/cloudmon/collectors/common"
|
||||
"yunion.io/x/onecloud/pkg/cloudmon/options"
|
||||
"yunion.io/x/onecloud/pkg/mcclient"
|
||||
modules "yunion.io/x/onecloud/pkg/mcclient/modules/compute"
|
||||
)
|
||||
|
||||
func init() {
|
||||
factory := SZStackCloudReportFactory{}
|
||||
common.RegisterFactory(&factory)
|
||||
}
|
||||
|
||||
type SZStackCloudReportFactory struct {
|
||||
common.CommonReportFactory
|
||||
}
|
||||
|
||||
func (self *SZStackCloudReportFactory) NewCloudReport(provider *common.SProvider, session *mcclient.ClientSession,
|
||||
args *options.ReportOptions, operatorType string) common.ICloudReport {
|
||||
return &SZStackCloudReport{
|
||||
common.CloudReportBase{
|
||||
SProvider: provider,
|
||||
Session: session,
|
||||
Args: args,
|
||||
Operator: operatorType,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func (self *SZStackCloudReportFactory) GetId() string {
|
||||
return compute.CLOUD_PROVIDER_ZSTACK
|
||||
}
|
||||
|
||||
type SZStackCloudReport struct {
|
||||
common.CloudReportBase
|
||||
}
|
||||
|
||||
func (self *SZStackCloudReport) Report() error {
|
||||
switch self.Operator {
|
||||
case string(common.SERVER):
|
||||
return self.getServerMetrics()
|
||||
case string(common.HOST):
|
||||
return self.getHoseMetrics()
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (self *SZStackCloudReport) getServerMetrics() error {
|
||||
servers, err := self.GetResourceByOperator()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
providerInstance, err := self.InitProviderInstance()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
regionList, regionServerMap, err := self.GetAllRegionOfServers(servers, providerInstance)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
for _, region := range regionList {
|
||||
err = common.CollectRegionMetricAsync(self.Args.Batch, region, regionServerMap[region.GetGlobalId()], self)
|
||||
if err != nil {
|
||||
log.Errorln(err)
|
||||
continue
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (self *SZStackCloudReport) getHoseMetrics() error {
|
||||
hosts, err := self.GetAllHostOfThisProvider(&modules.Hosts)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
providerInstance, err := self.InitProviderInstance()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
regionList, regionServerMap, err := self.GetAllRegionOfServers(hosts, providerInstance)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
for _, region := range regionList {
|
||||
err = common.CollectRegionMetricAsync(self.Args.Batch, region, regionServerMap[region.GetGlobalId()], self)
|
||||
if err != nil {
|
||||
log.Errorln(err)
|
||||
continue
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
@@ -1,149 +0,0 @@
|
||||
// Copyright 2019 Yunion
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package zstackmon
|
||||
|
||||
import (
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"yunion.io/x/jsonutils"
|
||||
"yunion.io/x/log"
|
||||
|
||||
"yunion.io/x/onecloud/pkg/cloudmon/collectors/common"
|
||||
"yunion.io/x/onecloud/pkg/cloudprovider"
|
||||
"yunion.io/x/onecloud/pkg/multicloud/zstack"
|
||||
"yunion.io/x/onecloud/pkg/util/influxdb"
|
||||
)
|
||||
|
||||
func (self *SZStackCloudReport) CollectRegionMetric(region cloudprovider.ICloudRegion,
|
||||
servers []jsonutils.JSONObject) error {
|
||||
var err error
|
||||
switch self.Operator {
|
||||
case string(common.SERVER):
|
||||
err = self.collectRegionMetricOfServer(region, servers)
|
||||
case string(common.HOST):
|
||||
err = self.collectRegionMetricOfHost(region, servers)
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
func (self *SZStackCloudReport) collectRegionMetricOfServer(region cloudprovider.ICloudRegion,
|
||||
servers []jsonutils.JSONObject) error {
|
||||
dataList := make([]influxdb.SMetricData, 0)
|
||||
zstackReg := region.(*zstack.SRegion)
|
||||
since, until, err := common.TimeRangeFromArgs(self.Args)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
for metricName, influxDbSpecs := range zstackMetricSpecs {
|
||||
rtn, err := zstackReg.GetMonitorData(metricName, NAMESPACE_VM, since, until)
|
||||
if err != nil {
|
||||
log.Errorln(err)
|
||||
continue
|
||||
}
|
||||
if len(rtn.DataPoints) > 0 {
|
||||
for _, dataPoint := range rtn.DataPoints {
|
||||
for _, server := range servers {
|
||||
external_id, _ := server.GetString("external_id")
|
||||
if dataPoint.Labels.VMUuid == external_id {
|
||||
metric, err := common.FillVMCapacity(server.(*jsonutils.JSONDict))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
dataList = append(dataList, metric)
|
||||
serverMetric, err := self.collectMetricFromThisServer(server, common.TYPE_VIRTUALMACHINE, dataPoint, influxDbSpecs)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
dataList = append(dataList, serverMetric)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return common.SendMetrics(self.Session, dataList, self.Args.Debug, "")
|
||||
}
|
||||
|
||||
func (self *SZStackCloudReport) collectRegionMetricOfHost(region cloudprovider.ICloudRegion,
|
||||
hosts []jsonutils.JSONObject) error {
|
||||
dataList := make([]influxdb.SMetricData, 0)
|
||||
zstackReg := region.(*zstack.SRegion)
|
||||
since, until, err := common.TimeRangeFromArgs(self.Args)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
for metricName, influxDbSpecs := range zstackMetricSpecs {
|
||||
rtn, err := zstackReg.GetMonitorData(metricName, NAMESPACE_HOST, since, until)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if len(rtn.DataPoints) > 0 {
|
||||
for _, dataPoint := range rtn.DataPoints {
|
||||
for _, host := range hosts {
|
||||
external_id, _ := host.GetString("external_id")
|
||||
if dataPoint.Labels.HostUuid == external_id {
|
||||
serverMetric, err := self.collectMetricFromThisServer(host, common.TYPE_HOSTSYSTEM, dataPoint, influxDbSpecs)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
dataList = append(dataList, serverMetric)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return common.SendMetrics(self.Session, dataList, self.Args.Debug, "")
|
||||
}
|
||||
|
||||
func (self *SZStackCloudReport) collectMetricFromThisServer(server jsonutils.JSONObject,
|
||||
monType string, dataPoint zstack.DataPoint, influxDbSpecs []string) (influxdb.SMetricData, error) {
|
||||
metric := influxdb.SMetricData{}
|
||||
if monType == common.TYPE_HOSTSYSTEM {
|
||||
metric, _ = common.JsonToMetric(server.(*jsonutils.JSONDict), "", common.HostTags, make([]string, 0))
|
||||
} else {
|
||||
metric, _ = common.JsonToMetric(server.(*jsonutils.JSONDict), "", common.ServerTags, make([]string, 0))
|
||||
}
|
||||
fieldValue := dataPoint.Value
|
||||
metric.Timestamp = time.Unix(dataPoint.TimeStemp, 0)
|
||||
//根据条件拼装metric的tag和metirc信息
|
||||
metric.Name = common.GetMeasurement(monType, influxDbSpecs[2])
|
||||
var pairsKey string
|
||||
if strings.Contains(influxDbSpecs[2], ",") {
|
||||
pairsKey = common.SubstringBetween(influxDbSpecs[2], ".", ",")
|
||||
} else {
|
||||
pairsKey = common.SubstringAfter(influxDbSpecs[2], ".")
|
||||
}
|
||||
if influxDbSpecs[1] == UNIT_MEM {
|
||||
fieldValue = fieldValue * 8
|
||||
}
|
||||
tag := common.SubstringAfter(influxDbSpecs[2], ",")
|
||||
if tag != "" && strings.Contains(influxDbSpecs[2], "=") {
|
||||
metric.Tags = append(metric.Tags, influxdb.SKeyValue{
|
||||
Key: common.SubstringBefore(tag, "="),
|
||||
Value: common.SubstringAfter(tag, "="),
|
||||
})
|
||||
}
|
||||
metric.Metrics = append(metric.Metrics, influxdb.SKeyValue{
|
||||
Key: pairsKey,
|
||||
Value: strconv.FormatFloat(fieldValue, 'E', -1, 64),
|
||||
})
|
||||
if monType == common.TYPE_HOSTSYSTEM {
|
||||
self.AddMetricTag(&metric, common.OtherHostTag)
|
||||
} else {
|
||||
self.AddMetricTag(&metric, common.OtherVmTags)
|
||||
}
|
||||
return metric, nil
|
||||
}
|
||||
@@ -1,137 +0,0 @@
|
||||
// Copyright 2019 Yunion
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package zstackmon
|
||||
|
||||
const (
|
||||
PERIOD = 60
|
||||
UNIT_AVERAGE = "Average"
|
||||
DEFAULT_STATISTICS = "Average,Minimum,Maximum"
|
||||
UNIT_PERCENT = "Percent"
|
||||
UNIT_BPS = "bps"
|
||||
UNIT_MBPS = "Mbps"
|
||||
UNIT_BYTEPS = "Bps"
|
||||
UNIT_CPS = "cps"
|
||||
UNIT_COUNT = "count"
|
||||
UNIT_MEM = "byte"
|
||||
UNIT_MSEC = "ms"
|
||||
UNIT_COUNT_SEC = "count/s"
|
||||
|
||||
TYPE_VIRTUALMACHINE = "VirtualMachine"
|
||||
TYPE_HOSTSYSTEM = "HostSystem"
|
||||
|
||||
//ESC监控指标
|
||||
INFLUXDB_FIELD_CPU_USAGE = "vm_cpu.usage_active"
|
||||
INFLUXDB_FIELD_MEM_USAGE = "vm_mem.used_percent"
|
||||
INFLUXDB_FIELD_DISK_READ_BPS = "vm_diskio.read_bps"
|
||||
INFLUXDB_FIELD_DISK_WRITE_BPS = "vm_diskio.write_bps"
|
||||
INFLUXDB_FIELD_DISK_READ_IOPS = "vm_diskio.read_iops"
|
||||
INFLUXDB_FIELD_DISK_WRITE_IOPS = "vm_diskio.write_iops"
|
||||
INFLUXDB_FIELD_NET_BPS_RX = "vm_netio.bps_recv"
|
||||
INFLUXDB_FIELD_NET_BPS_RX_INTERNET = INFLUXDB_FIELD_NET_BPS_RX + ",net_type=internet"
|
||||
INFLUXDB_FIELD_NET_BPS_RX_INTRANET = INFLUXDB_FIELD_NET_BPS_RX + ",net_type=intranet"
|
||||
INFLUXDB_FIELD_NET_BPS_TX = "vm_netio.bps_sent"
|
||||
INFLUXDB_FIELD_NET_BPS_TX_INTERNET = INFLUXDB_FIELD_NET_BPS_TX + ",net_type=internet"
|
||||
INFLUXDB_FIELD_NET_BPS_TX_INTRANET = INFLUXDB_FIELD_NET_BPS_TX + ",net_type=intranet"
|
||||
INFLUXDB_FIELD_WANOUTTRAFFIC = "vm_eipio.bps_out"
|
||||
INFLUXDB_FIELD_WANINTRAFFIC = "vm_eipio.bps_in"
|
||||
INFLUXDB_FIELD_WANOUTPKG = "vm_eipio.pps_out"
|
||||
INFLUXDB_FIELD_WANINPKG = "vm_eipio.pps_in"
|
||||
|
||||
//RDS监控指标
|
||||
INFLUXDB_FIELD_RDS_CPU_USAGE = "rds_cpu.usage_active"
|
||||
INFLUXDB_FIELD_RDS_MEM_USAGE = "rds_mem.used_percent"
|
||||
INFLUXDB_FIELD_RDS_NET_BPS_RX = "rds_netio.bps_recv"
|
||||
INFLUXDB_FIELD_RDS_NET_BPS_RX_MYSQL = INFLUXDB_FIELD_RDS_NET_BPS_RX + ",server_type=mysql"
|
||||
INFLUXDB_FIELD_RDS_NET_BPS_RX_SQLSERVER = INFLUXDB_FIELD_RDS_NET_BPS_RX + ",server_type=sqlserver"
|
||||
INFLUXDB_FIELD_RDS_NET_BPS_TX = "rds_netio.bps_send"
|
||||
INFLUXDB_FIELD_RDS_NET_BPS_TX_MYSQL = INFLUXDB_FIELD_RDS_NET_BPS_TX + ",server_type=mysql"
|
||||
INFLUXDB_FIELD_RDS_NET_BPS_TX_SQLSERVER = INFLUXDB_FIELD_RDS_NET_BPS_TX + ",server_type=sqlserver"
|
||||
INFLUXDB_FIELD_RDS_DISK_USAGE = "rds_disk.used_percent"
|
||||
INFLUXDB_FIELD_RDS_DISK_READ_BPS = "rds_diskio.read_bps"
|
||||
INFLUXDB_FIELD_RDS_DISK_WRITE_BPS = "rds_diskio.write_bps"
|
||||
INFLUXDB_FIELD_RDS_CONN_COUNT = "rds_conn.used_count"
|
||||
INFLUXDB_FIELD_RDS_CONN_USAGE = "rds_conn.used_percent"
|
||||
|
||||
INFLUXDB_FIELD_RDS_QPS = "rds_qps.query_qps"
|
||||
INFLUXDB_FIELD_RDS_TPS = "rds_tps.trans_qps"
|
||||
INFLUXDB_FIELD_RDS_INNODB_REDA_BPS = "rds_innodb.read_bps"
|
||||
INFLUXDB_FIELD_RDS_INNODB_WRITE_BPS = "rds_innodb.write_bps"
|
||||
|
||||
//REDIS监控指标
|
||||
INFLUXDB_FIELD_REDIS_CPU_USAGE = "dcs_cpu.usage_percent"
|
||||
INFLUXDB_FIELD_REDIS_MEM_USAGE = "dcs_mem.used_percent"
|
||||
INFLUXDB_FIELD_REDIS_NET_BPS_RX = "dcs_netio.bps_recv"
|
||||
INFLUXDB_FIELD_REDIS_NET_BPS_TX = "dcs_netio.bps_sent"
|
||||
INFLUXDB_FIFLD_REDIS_CONN_USAGE = "dcs_conn.used_conn"
|
||||
INFLUXDB_FIFLD_REDIS_OPT_SES = "dcs_instantopt.opt_sec"
|
||||
INFLUXDB_FIFLD_REDIS_CACHE_KEYS = "dcs_cachekeys.key_count"
|
||||
INFLUXDB_FIFLD_REDIS_CACHE_EXP_KEYS = INFLUXDB_FIFLD_REDIS_CACHE_KEYS + ",exp=expire"
|
||||
INFLUXDB_FIFLD_REDIS_DATA_MEM_USAGE = "dcs_datamem.used_byte"
|
||||
|
||||
//对象存储OSS监控指标
|
||||
INFLUXDB_FIELD_OSS_NET_BPS_RX = "oss_netio.bps_recv"
|
||||
INFLUXDB_FIELD_OSS_NET_BPS_RX_INTERNET = INFLUXDB_FIELD_OSS_NET_BPS_RX + ",net_type=internet"
|
||||
INFLUXDB_FIELD_OSS_NET_BPS_RX_INTRANET = INFLUXDB_FIELD_OSS_NET_BPS_RX + ",net_type=intranet"
|
||||
INFLUXDB_FIELD_OSS_NET_BPS_TX = "oss_netio.bps_sent"
|
||||
INFLUXDB_FIELD_OSS_NET_BPS_TX_INTERNET = INFLUXDB_FIELD_OSS_NET_BPS_TX + ",net_type=internet"
|
||||
INFLUXDB_FIELD_OSS_NET_BPS_TX_INTRANET = INFLUXDB_FIELD_OSS_NET_BPS_TX + ",net_type=intranet"
|
||||
INFLUXDB_FIELD_OSS_LATECY = "oss_latency.req_late"
|
||||
INFLUXDB_FIELD_OSS_LATECY_GET = INFLUXDB_FIELD_OSS_LATECY + ",request=get"
|
||||
INFLUXDB_FIELD_OSS_LATECY_POST = INFLUXDB_FIELD_OSS_LATECY + ",request=post"
|
||||
INFLUXDB_FIELD_OSS_REQ_COUNT = "oss_req.req_count"
|
||||
INFLUXDB_FIELD_OSS_REQ_COUNT_GET = INFLUXDB_FIELD_OSS_REQ_COUNT + ",request=get"
|
||||
INFLUXDB_FIELD_OSS_REQ_COUNT_POST = INFLUXDB_FIELD_OSS_REQ_COUNT + ",request=post"
|
||||
INFLUXDB_FIELD_OSS_REQ_COUNT_5XX = INFLUXDB_FIELD_OSS_REQ_COUNT + ",request=5xx"
|
||||
INFLUXDB_FIELD_OSS_REQ_COUNT_4XX = INFLUXDB_FIELD_OSS_REQ_COUNT + ",request=4xx"
|
||||
|
||||
//负载均衡监控指标
|
||||
INFLUXDB_FIELD_ELB_NET_BPS_RX = "haproxy.bin"
|
||||
INFLUXDB_FIELD_ELB_NET_BPS_TX = "haproxy.bout"
|
||||
INFLUXDB_FIELD_ELB_REQ_RATE = "haproxy.req_rate,request=http"
|
||||
INFLUXDB_FIELD_ELB_CONN_RATE = "haproxy.conn_rate,request=tcp"
|
||||
INFLUXDB_FIELD_ELB_DREQ_COUNT = "haproxy.dreq,request=http"
|
||||
INFLUXDB_FIELD_ELB_DCONN_COUNT = "haproxy.dcon,request=tcp"
|
||||
INFLUXDB_FIELD_ELB_HRSP_COUNT = "haproxy.hrsp_Nxx"
|
||||
INFLUXDB_FIELD_ELB_HRSP_COUNT_2XX = INFLUXDB_FIELD_ELB_HRSP_COUNT + ",request=2xx"
|
||||
INFLUXDB_FIELD_ELB_HRSP_COUNT_3XX = INFLUXDB_FIELD_ELB_HRSP_COUNT + ",request=3xx"
|
||||
INFLUXDB_FIELD_ELB_HRSP_COUNT_4XX = INFLUXDB_FIELD_ELB_HRSP_COUNT + ",request=4xx"
|
||||
INFLUXDB_FIELD_ELB_HRSP_COUNT_5XX = INFLUXDB_FIELD_ELB_HRSP_COUNT + ",request=5xx"
|
||||
INFLUXDB_FIELD_ELB_CHC_STATUS = "haproxy.check_status"
|
||||
INFLUXDB_FIELD_ELB_CHC_CODE = "haproxy.check_code"
|
||||
INFLUXDB_FIELD_ELB_LAST_CHC = "haproxy.last_chk"
|
||||
|
||||
KEY_VMS = "vms"
|
||||
KEY_CPUS = "cpus"
|
||||
KEY_MEMS = "mems"
|
||||
KEY_DISKS = "disks"
|
||||
|
||||
KEY_LIMIT = "limit"
|
||||
KEY_ADMIN = "admin"
|
||||
KEY_USABLE = "usable"
|
||||
|
||||
NAMESPACE_VM = "ZStack/VM"
|
||||
NAMESPACE_HOST = "ZStack/Host"
|
||||
)
|
||||
|
||||
//multiCloud查询指标列表组装
|
||||
var zstackMetricSpecs = map[string][]string{
|
||||
"CPUAverageUsedUtilization": {DEFAULT_STATISTICS, UNIT_PERCENT, INFLUXDB_FIELD_CPU_USAGE},
|
||||
"DiskReadBytes": {DEFAULT_STATISTICS, UNIT_MEM, INFLUXDB_FIELD_DISK_READ_BPS},
|
||||
"DiskWriteBytes": {DEFAULT_STATISTICS, UNIT_MEM, INFLUXDB_FIELD_DISK_WRITE_BPS},
|
||||
"NetworkInBytes": {DEFAULT_STATISTICS, UNIT_MEM, INFLUXDB_FIELD_NET_BPS_RX},
|
||||
"NetworkOutBytes": {DEFAULT_STATISTICS, UNIT_MEM, INFLUXDB_FIELD_NET_BPS_TX},
|
||||
"DiskReadOps": {DEFAULT_STATISTICS, UNIT_MEM, INFLUXDB_FIELD_DISK_READ_IOPS},
|
||||
"DiskWriteOps": {DEFAULT_STATISTICS, UNIT_MEM, INFLUXDB_FIELD_DISK_WRITE_IOPS},
|
||||
}
|
||||
@@ -0,0 +1,125 @@
|
||||
// Copyright 2019 Yunion
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package misc
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"yunion.io/x/jsonutils"
|
||||
"yunion.io/x/log"
|
||||
"yunion.io/x/pkg/errors"
|
||||
|
||||
"yunion.io/x/onecloud/pkg/apis"
|
||||
api "yunion.io/x/onecloud/pkg/apis/monitor"
|
||||
"yunion.io/x/onecloud/pkg/cloutpost/options"
|
||||
"yunion.io/x/onecloud/pkg/mcclient"
|
||||
"yunion.io/x/onecloud/pkg/mcclient/auth"
|
||||
"yunion.io/x/onecloud/pkg/mcclient/modules/monitor"
|
||||
"yunion.io/x/onecloud/pkg/util/influxdb"
|
||||
)
|
||||
|
||||
const (
|
||||
ALERT_METRIC_DATABASE = "monitor"
|
||||
ALERT_RECORD_HISTORY_MEASUREMENT = "alert_record_history"
|
||||
)
|
||||
|
||||
func AlertHistoryReport(ctx context.Context, userCred mcclient.TokenCredential, isStart bool) {
|
||||
err := func() error {
|
||||
alerts := []api.CommonAlertDetails{}
|
||||
s := auth.GetAdminSession(ctx, options.Options.Region)
|
||||
for {
|
||||
params := map[string]interface{}{
|
||||
"limit": 1024,
|
||||
"offset": len(alerts),
|
||||
"scope": "system",
|
||||
}
|
||||
resp, err := monitor.CommonAlertManager.List(s, jsonutils.Marshal(params))
|
||||
if err != nil {
|
||||
return errors.Wrapf(err, "CommonAlertManager.List")
|
||||
}
|
||||
part := []api.CommonAlertDetails{}
|
||||
err = jsonutils.Update(&part, resp.Data)
|
||||
if err != nil {
|
||||
return errors.Wrapf(err, "jsonutils.Update")
|
||||
}
|
||||
alerts = append(alerts, part...)
|
||||
if len(alerts) >= resp.Total {
|
||||
break
|
||||
}
|
||||
}
|
||||
metrics := []influxdb.SMetricData{}
|
||||
for i := range alerts {
|
||||
records := []api.AlertRecordDetails{}
|
||||
for {
|
||||
query := map[string]interface{}{
|
||||
"limit": 40,
|
||||
"offset": len(records),
|
||||
"alert_id": alerts[i].Id,
|
||||
"state": "alerting",
|
||||
"order_by": "res_num",
|
||||
"order": "desc",
|
||||
"filter": fmt.Sprintf("created_at.ge('%s')", time.Now().Add(time.Hour*-24)),
|
||||
}
|
||||
ret, err := monitor.AlertRecordManager.List(s, jsonutils.Marshal(query))
|
||||
if err != nil {
|
||||
log.Errorf("AlertRecordManager.List error: %v", err)
|
||||
break
|
||||
}
|
||||
part := []api.AlertRecordDetails{}
|
||||
err = jsonutils.Update(&part, ret.Data)
|
||||
if err != nil {
|
||||
break
|
||||
}
|
||||
records = append(records, part...)
|
||||
}
|
||||
metric := influxdb.SMetricData{}
|
||||
metric.Name = ALERT_RECORD_HISTORY_MEASUREMENT
|
||||
maxIdx, maxValue := -1, int64(0)
|
||||
for j := range records {
|
||||
if records[j].ResNum > maxValue {
|
||||
maxValue = records[j].ResNum
|
||||
maxIdx = j
|
||||
}
|
||||
}
|
||||
if maxIdx == -1 {
|
||||
break
|
||||
}
|
||||
for k, v := range records[maxIdx].GetMetricTags() {
|
||||
metric.Tags = append(metric.Tags, influxdb.SKeyValue{
|
||||
Key: k,
|
||||
Value: v,
|
||||
})
|
||||
}
|
||||
metric.Timestamp = records[maxIdx].CreatedAt
|
||||
metric.Metrics = []influxdb.SKeyValue{
|
||||
{
|
||||
Key: "res_num",
|
||||
Value: fmt.Sprintf("%d", records[maxIdx].ResNum),
|
||||
},
|
||||
}
|
||||
metrics = append(metrics, metric)
|
||||
}
|
||||
urls, err := s.GetServiceURLs(apis.SERVICE_TYPE_INFLUXDB, options.Options.SessionEndpointType, "")
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "GetServiceURLs")
|
||||
}
|
||||
return influxdb.SendMetrics(urls, ALERT_METRIC_DATABASE, metrics, false)
|
||||
}()
|
||||
if err != nil {
|
||||
log.Errorf("AlertHistoryReport error: %v", err)
|
||||
}
|
||||
}
|
||||
@@ -12,4 +12,4 @@
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package collectors // import "yunion.io/x/onecloud/pkg/cloudmon/collectors"
|
||||
package misc // import "yunion.io/x/onecloud/pkg/cloudmon/misc"
|
||||
@@ -12,9 +12,10 @@
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package collectors
|
||||
package misc
|
||||
|
||||
import (
|
||||
"context"
|
||||
"strconv"
|
||||
"time"
|
||||
|
||||
@@ -23,99 +24,77 @@ import (
|
||||
"yunion.io/x/pkg/errors"
|
||||
"yunion.io/x/pkg/util/netutils"
|
||||
|
||||
"yunion.io/x/onecloud/pkg/apis"
|
||||
api "yunion.io/x/onecloud/pkg/apis/compute"
|
||||
"yunion.io/x/onecloud/pkg/cloudmon/collectors/common"
|
||||
"yunion.io/x/onecloud/pkg/cloudmon/options"
|
||||
"yunion.io/x/onecloud/pkg/mcclient"
|
||||
modules "yunion.io/x/onecloud/pkg/mcclient/modules/compute"
|
||||
"yunion.io/x/onecloud/pkg/mcclient/auth"
|
||||
"yunion.io/x/onecloud/pkg/mcclient/modules/compute"
|
||||
"yunion.io/x/onecloud/pkg/util/influxdb"
|
||||
"yunion.io/x/onecloud/pkg/util/rbacutils"
|
||||
"yunion.io/x/onecloud/pkg/util/shellutils"
|
||||
"yunion.io/x/onecloud/pkg/util/sysutils"
|
||||
)
|
||||
|
||||
func init() {
|
||||
factory := PingProbeColectorFactory{}
|
||||
common.RegisterFactory(&factory)
|
||||
}
|
||||
|
||||
type PingProbeColectorFactory struct {
|
||||
common.CommonReportFactory
|
||||
}
|
||||
|
||||
func (p PingProbeColectorFactory) NewCloudReport(provider *common.SProvider, session *mcclient.ClientSession, args *options.ReportOptions, operatorType string) common.ICloudReport {
|
||||
return &SPingProbeColectorReport{
|
||||
common.CloudReportBase{
|
||||
SProvider: nil,
|
||||
Session: session,
|
||||
Args: args,
|
||||
Operator: string(common.PING_PROBE),
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func (p PingProbeColectorFactory) GetId() string {
|
||||
return string(common.PING_PROBE)
|
||||
}
|
||||
|
||||
type SPingProbeColectorReport struct {
|
||||
common.CloudReportBase
|
||||
}
|
||||
|
||||
func (self *SPingProbeColectorReport) Report() error {
|
||||
err := pingProbeColector(self.Session, self.Args)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "pingProbeColector err")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func pingProbeColector(s *mcclient.ClientSession, args *options.ReportOptions) error {
|
||||
if args.DisablePingProbe {
|
||||
return nil
|
||||
}
|
||||
isRoot := sysutils.IsRootPermission()
|
||||
if !isRoot {
|
||||
return errors.Error("require root permissions")
|
||||
}
|
||||
metrics := make([]influxdb.SMetricData, 0)
|
||||
params := jsonutils.NewDict()
|
||||
params.Add(jsonutils.NewString(api.CLOUD_ENV_ON_PREMISE), "cloud_env")
|
||||
params.Add(jsonutils.NewString(string(rbacutils.ScopeSystem)), "scope")
|
||||
params.Add(jsonutils.JSONTrue, "is_classic")
|
||||
listAll(s, modules.Networks.List, params, func(data jsonutils.JSONObject) error {
|
||||
m, err := pingProbeNetwork(s, data, &args.PingProbeOptions)
|
||||
if err != nil {
|
||||
return err
|
||||
func PingProbe(ctx context.Context, userCred mcclient.TokenCredential, isStart bool) {
|
||||
err := func() error {
|
||||
if options.Options.DisablePingProbe {
|
||||
return nil
|
||||
}
|
||||
if len(m) > 0 {
|
||||
isRoot := sysutils.IsRootPermission()
|
||||
if !isRoot {
|
||||
return errors.Error("require root permissions")
|
||||
}
|
||||
s := auth.GetAdminSession(ctx, options.Options.Region)
|
||||
networks := []api.NetworkDetails{}
|
||||
for {
|
||||
params := map[string]interface{}{
|
||||
"offset": len(networks),
|
||||
"limit": "10",
|
||||
"cloud_env": api.CLOUD_ENV_ON_PREMISE,
|
||||
"scope": rbacutils.ScopeSystem,
|
||||
"is_classic": true,
|
||||
}
|
||||
resp, err := compute.Networks.List(s, jsonutils.Marshal(params))
|
||||
if err != nil {
|
||||
return errors.Wrapf(err, "Networks.List")
|
||||
}
|
||||
part := []api.NetworkDetails{}
|
||||
err = jsonutils.Update(&part, resp.Data)
|
||||
if err != nil {
|
||||
return errors.Wrapf(err, "jsonutils.Update")
|
||||
}
|
||||
networks = append(networks, part...)
|
||||
if len(networks) >= resp.Total {
|
||||
break
|
||||
}
|
||||
}
|
||||
metrics := make([]influxdb.SMetricData, 0)
|
||||
for i := range networks {
|
||||
network := sNetwork{networks[i]}
|
||||
m, err := pingProbeNetwork(s, network)
|
||||
if err != nil {
|
||||
log.Errorf("pingProbeNetwork")
|
||||
continue
|
||||
}
|
||||
metrics = append(metrics, m...)
|
||||
}
|
||||
return nil
|
||||
})
|
||||
return sendMetrics(s, metrics, args.Debug)
|
||||
urls, err := s.GetServiceURLs(apis.SERVICE_TYPE_INFLUXDB, options.Options.SessionEndpointType, "")
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "GetServiceURLs")
|
||||
}
|
||||
return influxdb.SendMetrics(urls, options.Options.InfluxDatabase, metrics, false)
|
||||
}()
|
||||
if err != nil {
|
||||
log.Errorf("PingProb error: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
type sNetwork struct {
|
||||
Id string
|
||||
Name string
|
||||
GuestGateway string
|
||||
GuestIpStart string
|
||||
GuestIpEnd string
|
||||
Region string
|
||||
RegionId string
|
||||
ServerType string
|
||||
Vpc string
|
||||
VpcId string
|
||||
Wire string
|
||||
WireId string
|
||||
Zone string
|
||||
ZoneId string
|
||||
CloudEnv string
|
||||
api.NetworkDetails
|
||||
}
|
||||
|
||||
func getNetworkAddrMap(s *mcclient.ClientSession, netId string) (map[string]api.SNetworkUsedAddress, error) {
|
||||
addrListJson, err := modules.Networks.GetSpecific(s, netId, "addresses", nil)
|
||||
addrListJson, err := compute.Networks.GetSpecific(s, netId, "addresses", nil)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "GetSpecific addresses")
|
||||
}
|
||||
@@ -131,31 +110,20 @@ func getNetworkAddrMap(s *mcclient.ClientSession, netId string) (map[string]api.
|
||||
return addrMap, nil
|
||||
}
|
||||
|
||||
func pingProbeNetwork(s *mcclient.ClientSession, data jsonutils.JSONObject,
|
||||
args *options.PingProbeOptions) ([]influxdb.SMetricData, error) {
|
||||
func pingProbeNetwork(s *mcclient.ClientSession, net sNetwork) ([]influxdb.SMetricData, error) {
|
||||
metrics := make([]influxdb.SMetricData, 0)
|
||||
net := &sNetwork{}
|
||||
err := data.Unmarshal(&net)
|
||||
if err != nil {
|
||||
log.Errorf("Unmarshal network %s: %s", data, err)
|
||||
return nil, errors.Wrap(err, "Unmarshal network")
|
||||
}
|
||||
if net.CloudEnv != api.CLOUD_ENV_ON_PREMISE {
|
||||
log.Errorf("not an onpremise network: %s", data)
|
||||
return nil, errors.Wrap(errors.ErrInvalidStatus, "not onpremise network")
|
||||
}
|
||||
if net.GuestGateway == "" {
|
||||
log.Errorf("no valid gateway %s", data)
|
||||
return nil, errors.Wrap(errors.ErrInvalidStatus, "unreachable network, empty gateway")
|
||||
}
|
||||
addrStart, err := netutils.NewIPV4Addr(net.GuestIpStart)
|
||||
if err != nil {
|
||||
log.Errorf("unmarshal start address %s: %s", net.GuestIpStart, err)
|
||||
return nil, errors.Wrapf(err, "NewIPV4Addr %s", net.GuestIpStart)
|
||||
}
|
||||
addrEnd, err := netutils.NewIPV4Addr(net.GuestIpEnd)
|
||||
if err != nil {
|
||||
log.Errorf("unmarshal end address %s: %s", net.GuestIpEnd, err)
|
||||
return nil, errors.Wrapf(err, "NewIPV4Addr %s", net.GuestIpEnd)
|
||||
}
|
||||
log.Infof("ping address %s - %s", addrStart, addrEnd)
|
||||
@@ -164,7 +132,7 @@ func pingProbeNetwork(s *mcclient.ClientSession, data jsonutils.JSONObject,
|
||||
addrStr := addr.String()
|
||||
pingAddrs = append(pingAddrs, addrStr)
|
||||
}
|
||||
pingResults, err := Ping(pingAddrs, args.ProbeCount, time.Second*time.Duration(args.TimeoutSecond), args.Debug)
|
||||
pingResults, err := Ping(pingAddrs)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "Ping")
|
||||
}
|
||||
@@ -188,7 +156,7 @@ func pingProbeNetwork(s *mcclient.ClientSession, data jsonutils.JSONObject,
|
||||
}
|
||||
params := jsonutils.NewDict()
|
||||
params.Add(jsonutils.NewString(status), "status")
|
||||
_, err := modules.ReservedIPs.Update(s, netAddr.OwnerId, params)
|
||||
_, err := compute.ReservedIPs.Update(s, netAddr.OwnerId, params)
|
||||
if err != nil {
|
||||
log.Errorf("update reserved ip %s status fail: %s", addrStr, err)
|
||||
}
|
||||
@@ -246,7 +214,7 @@ func pingProbeNetwork(s *mcclient.ClientSession, data jsonutils.JSONObject,
|
||||
params.Add(jsonutils.NewStringArray([]string{addrStr}), "ips")
|
||||
params.Add(jsonutils.NewString("ping detect online free IP"), "notes")
|
||||
params.Add(jsonutils.NewString(api.RESERVEDIP_STATUS_ONLINE), "status")
|
||||
_, err := modules.Networks.PerformAction(s, net.Id, "reserve-ip", params)
|
||||
_, err = compute.Networks.PerformAction(s, net.Id, "reserve-ip", params)
|
||||
if err != nil {
|
||||
log.Errorf("failed to reserve ip %s: %s", addrStr, err)
|
||||
}
|
||||
@@ -256,7 +224,3 @@ func pingProbeNetwork(s *mcclient.ClientSession, data jsonutils.JSONObject,
|
||||
}
|
||||
return metrics, nil
|
||||
}
|
||||
|
||||
func init() {
|
||||
shellutils.R(&options.ReportOptions{}, "ping-probe", "Ping probe IPv4 address", pingProbeColector)
|
||||
}
|
||||
@@ -12,7 +12,7 @@
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package collectors
|
||||
package misc
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
@@ -22,6 +22,8 @@ import (
|
||||
"github.com/tatsushid/go-fastping"
|
||||
|
||||
"yunion.io/x/pkg/errors"
|
||||
|
||||
"yunion.io/x/onecloud/pkg/cloudmon/options"
|
||||
)
|
||||
|
||||
type SPingResult struct {
|
||||
@@ -70,11 +72,13 @@ func (pr SPingResult) String() string {
|
||||
return fmt.Sprintf("%d packets transmitted, %d received, %d%% packet loss, rtt min/avg/max = %d/%d/%d ms", pr.count, len(pr.rtt), pr.Loss(), min/time.Millisecond, avg/time.Millisecond, max/time.Millisecond)
|
||||
}
|
||||
|
||||
func Ping(addrList []string, count int, timeout time.Duration, debug bool) (map[string]*SPingResult, error) {
|
||||
func Ping(addrList []string) (map[string]*SPingResult, error) {
|
||||
p := fastping.NewPinger()
|
||||
count := options.Options.PingProbeOptions.ProbeCount
|
||||
timeout := time.Second * time.Duration(options.Options.PingProbeOptions.TimeoutSecond)
|
||||
p.MaxRTT = timeout
|
||||
p.Size = 64
|
||||
p.Debug = debug
|
||||
p.Debug = options.Options.PingProbeOptions.Debug
|
||||
result := make(map[string]*SPingResult)
|
||||
for _, addr := range addrList {
|
||||
result[addr] = NewPingResult(addr, count)
|
||||
@@ -12,23 +12,25 @@
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package collectors
|
||||
package misc
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"yunion.io/x/jsonutils"
|
||||
"yunion.io/x/log"
|
||||
"yunion.io/x/pkg/errors"
|
||||
|
||||
"yunion.io/x/onecloud/pkg/cloudmon/collectors/common"
|
||||
"yunion.io/x/onecloud/pkg/apis"
|
||||
"yunion.io/x/onecloud/pkg/cloudmon/options"
|
||||
"yunion.io/x/onecloud/pkg/mcclient"
|
||||
modules "yunion.io/x/onecloud/pkg/mcclient/modules/compute"
|
||||
"yunion.io/x/onecloud/pkg/mcclient/auth"
|
||||
"yunion.io/x/onecloud/pkg/mcclient/modules/compute"
|
||||
"yunion.io/x/onecloud/pkg/mcclient/modules/image"
|
||||
"yunion.io/x/onecloud/pkg/util/influxdb"
|
||||
"yunion.io/x/onecloud/pkg/util/shellutils"
|
||||
)
|
||||
|
||||
var config map[string]string = map[string]string{
|
||||
@@ -37,93 +39,66 @@ var config map[string]string = map[string]string{
|
||||
}
|
||||
var measureMent string = "usage"
|
||||
|
||||
func init() {
|
||||
shellutils.R(&options.ReportOptions{}, "report-usage", "Report Usage", reportUsage)
|
||||
factory := UsageColectorFactory{}
|
||||
common.RegisterFactory(&factory)
|
||||
}
|
||||
|
||||
type UsageColectorFactory struct {
|
||||
common.CommonReportFactory
|
||||
}
|
||||
|
||||
func (p UsageColectorFactory) NewCloudReport(provider *common.SProvider, session *mcclient.ClientSession, args *options.ReportOptions, operatorType string) common.ICloudReport {
|
||||
return &SUsageColectorReport{
|
||||
common.CloudReportBase{
|
||||
SProvider: nil,
|
||||
Session: session,
|
||||
Args: args,
|
||||
Operator: string(common.USAGE),
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func (p UsageColectorFactory) GetId() string {
|
||||
return string(common.USAGE)
|
||||
}
|
||||
|
||||
type SUsageColectorReport struct {
|
||||
common.CloudReportBase
|
||||
}
|
||||
|
||||
func (self *SUsageColectorReport) Report() error {
|
||||
err := reportUsage(self.Session, self.Args)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "usageCollector err")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func reportUsage(session *mcclient.ClientSession, args *options.ReportOptions) error {
|
||||
dataList := make([]influxdb.SMetricData, 0)
|
||||
nowTime := time.Now()
|
||||
//镜像使用量信息
|
||||
imageUsageFields, err := getImageUsageFields(session)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
//查询到的Usage信息统一放置在metric中
|
||||
imageUsageFieldsDict := imageUsageFields.(*jsonutils.JSONDict)
|
||||
capabilitesQuery := jsonutils.NewDict()
|
||||
capabilitesQuery.Add(jsonutils.NewString("system"), "scope")
|
||||
capabilites, err := modules.Capabilities.List(session, capabilitesQuery)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
//通过capabilities中的信息遍历hypevisors和brands
|
||||
for i := 0; i < len(capabilites.Data); i++ {
|
||||
capabilitesObj := capabilites.Data[i]
|
||||
capDict, ok := capabilitesObj.(*jsonutils.JSONDict)
|
||||
if !ok {
|
||||
return errors.ErrClient
|
||||
func UsegReport(ctx context.Context, userCred mcclient.TokenCredential, isStart bool) {
|
||||
err := func() error {
|
||||
dataList := make([]influxdb.SMetricData, 0)
|
||||
nowTime := time.Now()
|
||||
s := auth.GetAdminSession(ctx, options.Options.Region)
|
||||
//镜像使用量信息
|
||||
imageUsageFields, err := getImageUsageFields(s)
|
||||
if err != nil {
|
||||
return errors.Wrapf(err, "getImageUsageFields")
|
||||
}
|
||||
for _, capKey := range capDict.SortedKeys() {
|
||||
if _, ok := config[capKey]; ok {
|
||||
hypeOrBrandObj, _ := capDict.Get(capKey)
|
||||
if hypeOrBrandObj != nil {
|
||||
hypeOrBrandArr, _ := hypeOrBrandObj.(*jsonutils.JSONArray)
|
||||
for i := 0; i < len(hypeOrBrandArr.Value()); i++ {
|
||||
hypeOrBrand := hypeOrBrandArr.Value()[i].(*jsonutils.JSONString)
|
||||
dataList, err = packMetricList(session, dataList, imageUsageFieldsDict, config[capKey],
|
||||
hypeOrBrand.String(), nowTime)
|
||||
if err != nil {
|
||||
return err
|
||||
//查询到的Usage信息统一放置在metric中
|
||||
imageUsageFieldsDict := imageUsageFields.(*jsonutils.JSONDict)
|
||||
capabilitesQuery := jsonutils.NewDict()
|
||||
capabilitesQuery.Add(jsonutils.NewString("system"), "scope")
|
||||
capabilites, err := compute.Capabilities.List(s, capabilitesQuery)
|
||||
if err != nil {
|
||||
return errors.Wrapf(err, "Capabilities.List")
|
||||
}
|
||||
//通过capabilities中的信息遍历hypevisors和brands
|
||||
for i := 0; i < len(capabilites.Data); i++ {
|
||||
capabilitesObj := capabilites.Data[i]
|
||||
capDict, ok := capabilitesObj.(*jsonutils.JSONDict)
|
||||
if !ok {
|
||||
return errors.ErrClient
|
||||
}
|
||||
for _, capKey := range capDict.SortedKeys() {
|
||||
if _, ok := config[capKey]; ok {
|
||||
hypeOrBrandObj, _ := capDict.Get(capKey)
|
||||
if hypeOrBrandObj != nil {
|
||||
hypeOrBrandArr, _ := hypeOrBrandObj.(*jsonutils.JSONArray)
|
||||
for i := 0; i < len(hypeOrBrandArr.Value()); i++ {
|
||||
hypeOrBrand := hypeOrBrandArr.Value()[i].(*jsonutils.JSONString)
|
||||
dataList, err = packMetricList(s, dataList, imageUsageFieldsDict, config[capKey],
|
||||
hypeOrBrand.String(), nowTime)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
//查询host-type==""的情况,对应onecloud-控制面板-全部 要展示的内容
|
||||
dataList, err = packMetricList(session, dataList, imageUsageFieldsDict, "host-type", "", nowTime)
|
||||
//获取域/项目 虚拟机usage
|
||||
data, err := getDomainAndProjectServerUsage(session, nowTime)
|
||||
//查询host-type==""的情况,对应onecloud-控制面板-全部 要展示的内容
|
||||
dataList, err = packMetricList(s, dataList, imageUsageFieldsDict, "host-type", "", nowTime)
|
||||
//获取域/项目 虚拟机usage
|
||||
data, err := getDomainAndProjectServerUsage(s, nowTime)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "getDomainAndProjectServerUsage err")
|
||||
}
|
||||
dataList = append(dataList, data...)
|
||||
//写入influDb
|
||||
urls, err := s.GetServiceURLs(apis.SERVICE_TYPE_INFLUXDB, options.Options.SessionEndpointType, "")
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "GetServiceURLs")
|
||||
}
|
||||
return influxdb.SendMetrics(urls, options.Options.InfluxDatabase, dataList, false)
|
||||
}()
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "getDomainAndProjectServerUsage err")
|
||||
log.Errorf("report usage error: %v", err)
|
||||
}
|
||||
dataList = append(dataList, data...)
|
||||
//写入influDb
|
||||
return sendMetrics(session, dataList, args.Debug)
|
||||
}
|
||||
|
||||
//根据capabilities中的hypevisors和brands中的对应属性,组装Metric
|
||||
@@ -146,7 +121,7 @@ func packMetricList(session *mcclient.ClientSession, dataList []influxdb.SMetric
|
||||
//查询到的镜像的使用信息放到SMetricData中的metric
|
||||
metric, _ = jsonTometricData(imageUsageFieldsDict, metric, "metric")
|
||||
//compute主机使用量
|
||||
respObj, err := modules.Usages.GetGeneralUsage(session, query)
|
||||
respObj, err := compute.Usages.GetGeneralUsage(session, query)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -220,7 +195,7 @@ func getDomainAndProjectServerUsage(session *mcclient.ClientSession, nowTime tim
|
||||
"domain-statistics": "domain_id.project_domain",
|
||||
"project-statistics": "tenant_id.tenant",
|
||||
} {
|
||||
jsonObject, err := modules.Servers.GetById(session, urlKey, param)
|
||||
jsonObject, err := compute.Servers.GetById(session, urlKey, param)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "get server-%s err", urlKey)
|
||||
}
|
||||
@@ -15,18 +15,12 @@
|
||||
package options
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"yunion.io/x/pkg/errors"
|
||||
"yunion.io/x/structarg"
|
||||
|
||||
common_options "yunion.io/x/onecloud/pkg/cloudcommon/options"
|
||||
"yunion.io/x/onecloud/pkg/util/shellutils"
|
||||
)
|
||||
|
||||
type CloudMonOptions struct {
|
||||
common_options.CommonOptions
|
||||
ReportOptions
|
||||
PingProbeOptions
|
||||
|
||||
EndpointType string `default:"internalURL" help:"Defaults to internalURL" choices:"publicURL|internalURL|adminURL"`
|
||||
ApiVersion string `help:"override default modules service api version"`
|
||||
@@ -36,73 +30,40 @@ type CloudMonOptions struct {
|
||||
CertFile string `help:"certificate file"`
|
||||
KeyFile string `help:"private key file"`
|
||||
|
||||
ResourcesSyncInterval int64 `help:"Increment Sync Interval unit:minute" default:"10"`
|
||||
CollectMetricInterval int64 `help:"Increment Sync Interval unit:minute" default:"6"`
|
||||
SkipMetricPullProviders string `help:"Skip indicate provider metric pull" default:""`
|
||||
|
||||
InfluxDatabase string `help:"influxdb database name, default telegraf" default:"telegraf"`
|
||||
}
|
||||
|
||||
type SubCloudMonOptions struct {
|
||||
CloudMonOptions
|
||||
Subcommand string `help:"climc subcommand" subcommand:"true"`
|
||||
}
|
||||
|
||||
type ReportOptions struct {
|
||||
Batch int `help:"batch"`
|
||||
Count int `help:"count" json:"count"`
|
||||
CloudproviderSyncInterval int64 `help:"CloudproviderSyncInterval unit:minute" default:"30"`
|
||||
AlertRecordHistoryInterval int64 `help:"AlertRecordHistoryInterval unit:day" default:"1"`
|
||||
// 定时执行间隔,同时也会影响metric拉取间隔
|
||||
Interval string `help:"interval" default:"6" unit:"minute"`
|
||||
Timeout int64 `help:"command timeout unit:second" default:"10"`
|
||||
SinceTime string `help:"sinceTime"`
|
||||
EndTime string `help:"endTime"`
|
||||
Provider []string `help:"List objects from the provider" choices:"VMware|Aliyun|Qcloud|Azure|Aws|Huawei
|
||||
|ZStack|Google|Apsara|JDcloud|Ecloud|HCSO|BingoCloud" json:"provider,omitempty"`
|
||||
MetricInterval string `help:"metric interval eg:PT1M"`
|
||||
PingProbeOptions
|
||||
}
|
||||
|
||||
type PingProbeOptions struct {
|
||||
Debug bool `help:"debug"`
|
||||
ProbeCount int `help:"probe count, default is 3" default:"3"`
|
||||
TimeoutSecond int `help:"probe timeout in second, default is 1 second" default:"1"`
|
||||
|
||||
DisablePingProbe bool `help:"enable ping probe"`
|
||||
}
|
||||
|
||||
func GetArgumentParser() (*structarg.ArgumentParser, error) {
|
||||
parse, e := structarg.NewArgumentParser(&SubOptions,
|
||||
"cloudmon",
|
||||
`Command-line interface to collect cloud monitoring data.`,
|
||||
`See "cloudmon help COMMAND" for help on a specific command.`)
|
||||
if e != nil {
|
||||
return nil, e
|
||||
}
|
||||
subcmd := parse.GetSubcommand()
|
||||
if subcmd == nil {
|
||||
return nil, errors.Error("No subcommand argument")
|
||||
}
|
||||
type HelpOptions struct {
|
||||
SUBCOMMAND string `help:"Sub-command name"`
|
||||
}
|
||||
shellutils.R(&HelpOptions{}, "help", "Show help information of any subcommand", func(suboptions *HelpOptions) error {
|
||||
helpstr, e := subcmd.SubHelpString(suboptions.SUBCOMMAND)
|
||||
if e != nil {
|
||||
return e
|
||||
} else {
|
||||
fmt.Print(helpstr)
|
||||
return nil
|
||||
}
|
||||
})
|
||||
for _, v := range shellutils.CommandTable {
|
||||
_, e := subcmd.AddSubParser(v.Options, v.Command, v.Desc, v.Callback)
|
||||
|
||||
if e != nil {
|
||||
return nil, e
|
||||
}
|
||||
}
|
||||
return parse, nil
|
||||
DisablePingProbe bool `help:"enable ping probe"`
|
||||
PingProbIntervalHours int64 `help:"PingProb Interval unit:hour" default:"6"`
|
||||
}
|
||||
|
||||
var (
|
||||
Options CloudMonOptions
|
||||
SubOptions SubCloudMonOptions
|
||||
Options CloudMonOptions
|
||||
)
|
||||
|
||||
func OnOptionsChange(oldO, newO interface{}) bool {
|
||||
oldOpts := oldO.(*CloudMonOptions)
|
||||
newOpts := newO.(*CloudMonOptions)
|
||||
|
||||
changed := false
|
||||
if common_options.OnCommonOptionsChange(&oldOpts.CommonOptions, &newOpts.CommonOptions) {
|
||||
changed = true
|
||||
}
|
||||
|
||||
if oldOpts.DisablePingProbe != newOpts.DisablePingProbe {
|
||||
if !oldOpts.IsSlaveNode {
|
||||
changed = true
|
||||
}
|
||||
}
|
||||
|
||||
return changed
|
||||
}
|
||||
|
||||
@@ -0,0 +1,35 @@
|
||||
// Copyright 2019 Yunion
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package providerdriver
|
||||
|
||||
import (
|
||||
api "yunion.io/x/onecloud/pkg/apis/compute"
|
||||
)
|
||||
|
||||
type AliyunCollect struct {
|
||||
SCollectByMetricTypeDriver
|
||||
}
|
||||
|
||||
func (self *AliyunCollect) GetProvider() string {
|
||||
return api.CLOUD_PROVIDER_ALIYUN
|
||||
}
|
||||
|
||||
func (self *AliyunCollect) IsSupportMetrics() bool {
|
||||
return true
|
||||
}
|
||||
|
||||
func init() {
|
||||
Register(&AliyunCollect{})
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
// Copyright 2019 Yunion
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package providerdriver
|
||||
|
||||
import (
|
||||
api "yunion.io/x/onecloud/pkg/apis/compute"
|
||||
)
|
||||
|
||||
type ApsaraCollect struct {
|
||||
SCollectByMetricTypeDriver
|
||||
}
|
||||
|
||||
func (self *ApsaraCollect) GetProvider() string {
|
||||
return api.CLOUD_PROVIDER_APSARA
|
||||
}
|
||||
|
||||
func (self *ApsaraCollect) IsSupportMetrics() bool {
|
||||
return true
|
||||
}
|
||||
|
||||
func init() {
|
||||
Register(&ApsaraCollect{})
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
// Copyright 2019 Yunion
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package providerdriver
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
api "yunion.io/x/onecloud/pkg/apis/compute"
|
||||
)
|
||||
|
||||
type AwsCollect struct {
|
||||
SCollectByResourceIdDriver
|
||||
}
|
||||
|
||||
func (self *AwsCollect) GetProvider() string {
|
||||
return api.CLOUD_PROVIDER_AWS
|
||||
}
|
||||
|
||||
func (self *AwsCollect) GetDelayDuration() time.Duration {
|
||||
return time.Minute * 5
|
||||
}
|
||||
|
||||
func (self *AwsCollect) IsSupportMetrics() bool {
|
||||
return true
|
||||
}
|
||||
|
||||
func init() {
|
||||
Register(&AwsCollect{})
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
// Copyright 2019 Yunion
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package providerdriver
|
||||
|
||||
import (
|
||||
api "yunion.io/x/onecloud/pkg/apis/compute"
|
||||
)
|
||||
|
||||
type AzureCollect struct {
|
||||
SCollectByResourceIdDriver
|
||||
}
|
||||
|
||||
func (self *AzureCollect) GetProvider() string {
|
||||
return api.CLOUD_PROVIDER_AZURE
|
||||
}
|
||||
|
||||
func (self *AzureCollect) IsSupportMetrics() bool {
|
||||
return true
|
||||
}
|
||||
|
||||
func init() {
|
||||
Register(&AzureCollect{})
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
+16
-18
@@ -12,26 +12,24 @@
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package collectors
|
||||
package providerdriver
|
||||
|
||||
import (
|
||||
"testing"
|
||||
"time"
|
||||
api "yunion.io/x/onecloud/pkg/apis/compute"
|
||||
)
|
||||
|
||||
func TestPing(t *testing.T) {
|
||||
result, err := Ping([]string{
|
||||
"114.114.114.114",
|
||||
"118.187.65.237",
|
||||
"10.168.26.254",
|
||||
"10.168.26.26",
|
||||
"192.30.253.113",
|
||||
}, 5, time.Second, true)
|
||||
if err != nil {
|
||||
// ignore error
|
||||
t.Logf("ping error %s", err)
|
||||
}
|
||||
for k, v := range result {
|
||||
t.Logf("%s: %s", k, v.String())
|
||||
}
|
||||
type BingoCloudCollect struct {
|
||||
SBaseCollectDriver
|
||||
}
|
||||
|
||||
func (self *BingoCloudCollect) GetProvider() string {
|
||||
return api.CLOUD_PROVIDER_BINGO_CLOUD
|
||||
}
|
||||
|
||||
func (self *BingoCloudCollect) IsSupportMetrics() bool {
|
||||
return true
|
||||
}
|
||||
|
||||
func init() {
|
||||
Register(&BingoCloudCollect{})
|
||||
}
|
||||
+15
-8
@@ -12,13 +12,20 @@
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package storagemon
|
||||
package providerdriver
|
||||
|
||||
const (
|
||||
STORAGE_ID = "storage"
|
||||
|
||||
CLOUDACCOUNT_FIELD = "balance"
|
||||
STORAGE_MEASUREMENT = "storage"
|
||||
STORAGE_FIELD_USAGE = "usage_active"
|
||||
STORAGE_FIELD_FREE = "free"
|
||||
import (
|
||||
api "yunion.io/x/onecloud/pkg/apis/compute"
|
||||
)
|
||||
|
||||
type CephCollect struct {
|
||||
SBaseCollectDriver
|
||||
}
|
||||
|
||||
func (self *CephCollect) GetProvider() string {
|
||||
return api.CLOUD_PROVIDER_CEPH
|
||||
}
|
||||
|
||||
func init() {
|
||||
Register(&CephCollect{})
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
// Copyright 2019 Yunion
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package providerdriver
|
||||
|
||||
import (
|
||||
api "yunion.io/x/onecloud/pkg/apis/compute"
|
||||
)
|
||||
|
||||
type CloudpodsCollect struct {
|
||||
SBaseCollectDriver
|
||||
}
|
||||
|
||||
func (self *CloudpodsCollect) GetProvider() string {
|
||||
return api.CLOUD_PROVIDER_CLOUDPODS
|
||||
}
|
||||
|
||||
func init() {
|
||||
Register(&CloudpodsCollect{})
|
||||
}
|
||||
@@ -12,4 +12,20 @@
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package alimon // import "yunion.io/x/onecloud/pkg/cloudmon/collectors/alimon"
|
||||
package providerdriver
|
||||
|
||||
import (
|
||||
api "yunion.io/x/onecloud/pkg/apis/compute"
|
||||
)
|
||||
|
||||
type CtyunCollect struct {
|
||||
SBaseCollectDriver
|
||||
}
|
||||
|
||||
func (self *CtyunCollect) GetProvider() string {
|
||||
return api.CLOUD_PROVIDER_CTYUN
|
||||
}
|
||||
|
||||
func init() {
|
||||
Register(&CtyunCollect{})
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
package providerdriver // import "yunion.io/x/onecloud/pkg/cloudmon/providerdriver"
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user