refactor(cloudmon): metric collect

This commit is contained in:
ioito
2022-07-29 15:59:26 +08:00
parent 9b5fa4d2c3
commit 2e94335a2f
185 changed files with 6533 additions and 9823 deletions
-158
View File
@@ -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
View File
@@ -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)
+28
View File
@@ -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
}
+25
View File
@@ -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
+37
View File
@@ -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 {
+32
View File
@@ -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"`
+44
View File
@@ -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"`
+34
View File
@@ -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"`
+7
View File
@@ -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
}
+31
View File
@@ -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"`
+1
View File
@@ -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"
+5
View File
@@ -377,3 +377,8 @@ type OpsLogListInput struct {
Until time.Time `json:"until"`
}
type IdNameDetails struct {
Id string `json:"id"`
Name string `json:"name"`
}
+2
View File
@@ -159,6 +159,8 @@ type AlertListInput struct {
}
type AlertDetails struct {
SAlert
apis.StatusStandaloneResourceDetails
apis.ScopedResourceBaseInfo
}
+15
View File
@@ -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
+58 -13
View File
@@ -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},
}
-15
View File
@@ -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
}
-158
View File
@@ -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},
}
-15
View File
@@ -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
-15
View File
@@ -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
View File
@@ -1 +0,0 @@
package bingomon // import "yunion.io/x/onecloud/pkg/cloudmon/collectors/bingomon"
-88
View File
@@ -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"
-45
View File
@@ -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
)
-351
View File
@@ -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)
}
-155
View File
@@ -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"
)
-15
View File
@@ -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())
}
-15
View File
@@ -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},
}
-15
View File
@@ -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 ""
}
-131
View File
@@ -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},
}
-15
View File
@@ -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},
}
-15
View File
@@ -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
}
-196
View File
@@ -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, "")
}
-130
View File
@@ -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},
}
)
-16
View File
@@ -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)
}
-15
View File
@@ -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
}
}
-105
View File
@@ -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},
}
-30
View File
@@ -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)
}
-31
View File
@@ -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)
}
-5
View File
@@ -1,5 +0,0 @@
package collectors
const (
REDIS_CRON_JOB_NAME = "redis_cron"
)
-15
View File
@@ -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
}
-30
View File
@@ -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)
}
-94
View File
@@ -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
}
-15
View File
@@ -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},
}
-15
View File
@@ -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},
}
+125
View File
@@ -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)
}
+26 -65
View File
@@ -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
}
+35
View File
@@ -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{})
}
+35
View File
@@ -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{})
}
+41
View File
@@ -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{})
}
+35
View File
@@ -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
@@ -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{})
}
@@ -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{})
}
+31
View File
@@ -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{})
}
+1
View File
@@ -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