From 8f771747710cfa7d0b01e36d2acb212b52c18772 Mon Sep 17 00:00:00 2001 From: zhaoxiangchun <1422928955@qq.com> Date: Wed, 10 Nov 2021 17:37:07 +0800 Subject: [PATCH] feat(cloudmon): modify cloudmon deployment --- cmd/cloudmon/main.go | 150 +---------------- cmd/cloudmon/main_exec.go | 154 ++++++++++++++++++ .../alertrecordhistoryreport.go | 11 +- .../collectors/alertrecordhistoryservice.go | 5 +- .../collectors/alimon/alicloudreport.go | 20 +-- .../collectors/apsaramon/apsaracloudreport.go | 4 +- .../collectors/awsmon/awscloudreport.go | 4 +- .../collectors/azuremon/azurereport.go | 4 +- .../cloudaccountmon/cloudaccountreport.go | 4 +- .../collectors/cloudaccountservice.go | 5 +- pkg/cloudmon/collectors/cloudmoninit.go | 1 + pkg/cloudmon/collectors/common/basemon.go | 3 +- pkg/cloudmon/collectors/common/cloudreport.go | 19 ++- .../collectors/common/multiCloudMonUtils.go | 150 ++++++++++++++--- .../collectors/ecloudmon/ecloudreport.go | 4 +- pkg/cloudmon/collectors/elbservice.go | 5 +- pkg/cloudmon/collectors/gcpmon/gcpreport.go | 4 +- pkg/cloudmon/collectors/hostservice.go | 5 +- .../collectors/huaweimon/huaweicloudreport.go | 4 +- .../collectors/jdmon/jdcloudreport.go | 4 +- pkg/cloudmon/collectors/ossservice.go | 5 +- pkg/cloudmon/collectors/pinger.go | 43 ++++- pkg/cloudmon/collectors/qcmon/qcloudreport.go | 4 +- pkg/cloudmon/collectors/rdsservice.go | 5 +- pkg/cloudmon/collectors/redisservice.go | 5 +- pkg/cloudmon/collectors/serverservice.go | 5 +- pkg/cloudmon/collectors/service_const.go | 5 + .../collectors/storagemon/storagereport.go | 12 +- pkg/cloudmon/collectors/storageservice.go | 5 +- pkg/cloudmon/collectors/usageservice.go | 6 +- .../collectors/vmwaremon/vmwarereport.go | 4 +- .../collectors/zstackmon/zstackreport.go | 4 +- pkg/cloudmon/options/options.go | 46 ++++-- pkg/cloudmon/service/doc.go | 1 + pkg/cloudmon/service/service.go | 130 +++++++++++++++ 35 files changed, 593 insertions(+), 247 deletions(-) create mode 100644 cmd/cloudmon/main_exec.go create mode 100644 pkg/cloudmon/collectors/service_const.go create mode 100644 pkg/cloudmon/service/doc.go create mode 100644 pkg/cloudmon/service/service.go diff --git a/cmd/cloudmon/main.go b/cmd/cloudmon/main.go index 7cd396063e..2d4319fe26 100644 --- a/cmd/cloudmon/main.go +++ b/cmd/cloudmon/main.go @@ -15,155 +15,9 @@ 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/collectors/common" - "yunion.io/x/onecloud/pkg/cloudmon/options" - "yunion.io/x/onecloud/pkg/mcclient" + "yunion.io/x/onecloud/pkg/cloudmon/service" ) -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.Timeout, - 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, - options.ApiVersion) - - return session, nil -} - func main() { - parser, err := options.GetArgumentParser() - if err != nil { - showErrorAndExit(err) - } - - err = parser.ParseArgs2(os.Args[1:], false, false) - - opts := parser.Options().(*options.CloudMonOptions) - - 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.(*common.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.(*common.ReportOptions).Provider, suboptions.(*common.ReportOptions).Timeout) - os.Exit(3) - case <-endChan: - } - } - }() - - var session *mcclient.ClientSession - session, err = newClientSession(opts) - if err != nil { - showErrorAndExit(err) - } - err = subcmd.Invoke(session, suboptions) - endChan <- 1 - } - if err != nil { - showErrorAndExit(err) - } + service.StartService() } diff --git a/cmd/cloudmon/main_exec.go b/cmd/cloudmon/main_exec.go new file mode 100644 index 0000000000..d0f7a5c663 --- /dev/null +++ b/cmd/cloudmon/main_exec.go @@ -0,0 +1,154 @@ +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, + options.ApiVersion) + + 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.CloudMonOptions) + + 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) + if err != nil { + showErrorAndExit(err) + } + err = subcmd.Invoke(session, suboptions) + endChan <- 1 + } + if err != nil { + showErrorAndExit(err) + } +} diff --git a/pkg/cloudmon/collectors/alertrecordhistorymon/alertrecordhistoryreport.go b/pkg/cloudmon/collectors/alertrecordhistorymon/alertrecordhistoryreport.go index d230ed2bfb..7f1b25dd57 100644 --- a/pkg/cloudmon/collectors/alertrecordhistorymon/alertrecordhistoryreport.go +++ b/pkg/cloudmon/collectors/alertrecordhistorymon/alertrecordhistoryreport.go @@ -27,6 +27,7 @@ import ( "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" "yunion.io/x/onecloud/pkg/mcclient/modules" ) @@ -39,8 +40,16 @@ func init() { 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 *common.ReportOptions, + args *options.ReportOptions, operatorType string) common.ICloudReport { return &SAlertRecordHistoryReport{ common.CloudReportBase{ diff --git a/pkg/cloudmon/collectors/alertrecordhistoryservice.go b/pkg/cloudmon/collectors/alertrecordhistoryservice.go index 5139efa01a..76ecba4754 100644 --- a/pkg/cloudmon/collectors/alertrecordhistoryservice.go +++ b/pkg/cloudmon/collectors/alertrecordhistoryservice.go @@ -16,14 +16,15 @@ 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(&common.ReportOptions{}, "report-alertrecord", "Report alertrecord history", reportAlertrecord) + shellutils.R(&options.ReportOptions{}, "report-alertrecord", "Report alertrecord history", reportAlertrecord) } -func reportAlertrecord(session *mcclient.ClientSession, args *common.ReportOptions) error { +func reportAlertrecord(session *mcclient.ClientSession, args *options.ReportOptions) error { return common.ReportCustomizeCloudMetric(string(common.ALERT_RECORD), session, args) } diff --git a/pkg/cloudmon/collectors/alimon/alicloudreport.go b/pkg/cloudmon/collectors/alimon/alicloudreport.go index 8e39d31653..8e100750ef 100644 --- a/pkg/cloudmon/collectors/alimon/alicloudreport.go +++ b/pkg/cloudmon/collectors/alimon/alicloudreport.go @@ -19,8 +19,8 @@ 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" - "yunion.io/x/onecloud/pkg/mcclient/modules" ) func init() { @@ -29,10 +29,11 @@ func init() { } type SAliCloudReportFactory struct { + common.CommonReportFactory } func (self *SAliCloudReportFactory) NewCloudReport(provider *common.SProvider, session *mcclient.ClientSession, - args *common.ReportOptions, operatorType string) common.ICloudReport { + args *options.ReportOptions, operatorType string) common.ICloudReport { return &SAliCloudReport{ common.CloudReportBase{ SProvider: provider, @@ -54,18 +55,9 @@ type SAliCloudReport struct { func (self *SAliCloudReport) Report() error { var servers []jsonutils.JSONObject var err error - switch self.Operator { - case "redis": - servers, err = self.GetAllserverOfThisProvider(&modules.ElasticCache) - case "rds": - servers, err = self.GetAllserverOfThisProvider(&modules.DBInstance) - case "oss": - servers, err = self.GetAllserverOfThisProvider(&modules.Buckets) - case "elb": - servers, err = self.GetAllserverOfThisProvider(&modules.Loadbalancers) - default: - servers, err = self.GetAllserverOfThisProvider(&modules.Servers) - } + + servers, err = self.GetResourceByOperator() + providerInstance, err := self.InitProviderInstance() if err != nil { return err diff --git a/pkg/cloudmon/collectors/apsaramon/apsaracloudreport.go b/pkg/cloudmon/collectors/apsaramon/apsaracloudreport.go index f75b3e489b..ee901e3dab 100644 --- a/pkg/cloudmon/collectors/apsaramon/apsaracloudreport.go +++ b/pkg/cloudmon/collectors/apsaramon/apsaracloudreport.go @@ -19,6 +19,7 @@ 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" "yunion.io/x/onecloud/pkg/mcclient/modules" ) @@ -29,10 +30,11 @@ func init() { } type SApsaraCloudReportFactory struct { + common.CommonReportFactory } func (self *SApsaraCloudReportFactory) NewCloudReport(provider *common.SProvider, session *mcclient.ClientSession, - args *common.ReportOptions, operatorType string) common.ICloudReport { + args *options.ReportOptions, operatorType string) common.ICloudReport { return &SApsaraCloudReport{ common.CloudReportBase{ SProvider: provider, diff --git a/pkg/cloudmon/collectors/awsmon/awscloudreport.go b/pkg/cloudmon/collectors/awsmon/awscloudreport.go index c884caeb54..aca42de013 100644 --- a/pkg/cloudmon/collectors/awsmon/awscloudreport.go +++ b/pkg/cloudmon/collectors/awsmon/awscloudreport.go @@ -17,6 +17,7 @@ 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" "yunion.io/x/onecloud/pkg/mcclient/modules" ) @@ -27,10 +28,11 @@ func init() { } type SAwsCloudReportFactory struct { + common.CommonReportFactory } func (self *SAwsCloudReportFactory) NewCloudReport(provider *common.SProvider, session *mcclient.ClientSession, - args *common.ReportOptions, operatorType string) common.ICloudReport { + args *options.ReportOptions, operatorType string) common.ICloudReport { return &SAwsCloudReport{ common.CloudReportBase{ SProvider: provider, diff --git a/pkg/cloudmon/collectors/azuremon/azurereport.go b/pkg/cloudmon/collectors/azuremon/azurereport.go index 67e04c781f..74ec4bd148 100644 --- a/pkg/cloudmon/collectors/azuremon/azurereport.go +++ b/pkg/cloudmon/collectors/azuremon/azurereport.go @@ -17,6 +17,7 @@ package azuremon 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" ) @@ -26,10 +27,11 @@ func init() { } type SAzureCloudReportFactory struct { + common.CommonReportFactory } func (self *SAzureCloudReportFactory) NewCloudReport(provider *common.SProvider, session *mcclient.ClientSession, - args *common.ReportOptions, operatorType string) common.ICloudReport { + args *options.ReportOptions, operatorType string) common.ICloudReport { return &SAzureCloudReport{ common.CloudReportBase{ SProvider: provider, diff --git a/pkg/cloudmon/collectors/cloudaccountmon/cloudaccountreport.go b/pkg/cloudmon/collectors/cloudaccountmon/cloudaccountreport.go index 3839f03d29..197ccbe855 100644 --- a/pkg/cloudmon/collectors/cloudaccountmon/cloudaccountreport.go +++ b/pkg/cloudmon/collectors/cloudaccountmon/cloudaccountreport.go @@ -16,6 +16,7 @@ package cloudaccountmon 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/mcclient/modules" ) @@ -26,10 +27,11 @@ func init() { } type SCloudAccountFactory struct { + common.CommonReportFactory } func (self *SCloudAccountFactory) NewCloudReport(provider *common.SProvider, session *mcclient.ClientSession, - args *common.ReportOptions, + args *options.ReportOptions, operatorType string) common.ICloudReport { return &SCloudAccountReport{ common.CloudReportBase{ diff --git a/pkg/cloudmon/collectors/cloudaccountservice.go b/pkg/cloudmon/collectors/cloudaccountservice.go index 54f3c8af5e..2cd19fc34a 100644 --- a/pkg/cloudmon/collectors/cloudaccountservice.go +++ b/pkg/cloudmon/collectors/cloudaccountservice.go @@ -16,14 +16,15 @@ 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(&common.ReportOptions{}, "report-cloudaccount", "Report cloud account", reportCloudAccount) + shellutils.R(&options.ReportOptions{}, "report-cloudaccount", "Report cloud account", reportCloudAccount) } -func reportCloudAccount(session *mcclient.ClientSession, args *common.ReportOptions) error { +func reportCloudAccount(session *mcclient.ClientSession, args *options.ReportOptions) error { return common.ReportCustomizeCloudMetric(string(common.CLOUDACCOUNT), session, args) } diff --git a/pkg/cloudmon/collectors/cloudmoninit.go b/pkg/cloudmon/collectors/cloudmoninit.go index 896c1ae43e..256538983d 100644 --- a/pkg/cloudmon/collectors/cloudmoninit.go +++ b/pkg/cloudmon/collectors/cloudmoninit.go @@ -39,4 +39,5 @@ import ( _ "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 ) diff --git a/pkg/cloudmon/collectors/common/basemon.go b/pkg/cloudmon/collectors/common/basemon.go index 4737afbcfb..bf7ffd28ef 100644 --- a/pkg/cloudmon/collectors/common/basemon.go +++ b/pkg/cloudmon/collectors/common/basemon.go @@ -28,6 +28,7 @@ import ( "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" @@ -39,7 +40,7 @@ import ( type CloudReportBase struct { SProvider *SProvider Session *mcclient.ClientSession - Args *ReportOptions + Args *options.ReportOptions Operator string } diff --git a/pkg/cloudmon/collectors/common/cloudreport.go b/pkg/cloudmon/collectors/common/cloudreport.go index fdc18773bd..64aaf0a7bf 100644 --- a/pkg/cloudmon/collectors/common/cloudreport.go +++ b/pkg/cloudmon/collectors/common/cloudreport.go @@ -16,6 +16,8 @@ package common import ( "fmt" + "strconv" + "time" "github.com/aws/aws-sdk-go/aws/request" @@ -23,6 +25,7 @@ import ( "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" @@ -32,10 +35,24 @@ func init() { cloudReportTable = make(map[string]ICloudReportFactory) } +type IRoutineFactory interface { + MyRoutineFunc() RoutineFunc +} + type ICloudReportFactory interface { - NewCloudReport(provider *SProvider, session *mcclient.ClientSession, args *ReportOptions, + NewCloudReport(provider *SProvider, session *mcclient.ClientSession, args *options.ReportOptions, operatorType string) ICloudReport GetId() string + MyRoutineInteval(monOptions options.CloudMonOptions) time.Duration +} + +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 { diff --git a/pkg/cloudmon/collectors/common/multiCloudMonUtils.go b/pkg/cloudmon/collectors/common/multiCloudMonUtils.go index dc052828f3..f82ccc9a62 100644 --- a/pkg/cloudmon/collectors/common/multiCloudMonUtils.go +++ b/pkg/cloudmon/collectors/common/multiCloudMonUtils.go @@ -28,9 +28,11 @@ import ( "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" "yunion.io/x/onecloud/pkg/mcclient/modules" "yunion.io/x/onecloud/pkg/util/influxdb" ) @@ -47,6 +49,10 @@ const ( CLOUDACCOUNT MonType = "cloudaccount" STORAGE MonType = "storage" ALERT_RECORD MonType = "alertRecord" + + PING_PROBE MonType = "ping_probe" + + ALL_RESOURCE MonType = "all" ) const ( @@ -62,6 +68,16 @@ const ( 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} + + ResMonTypeList = []string{string(SERVER), string(HOST), string(REDIS), string(RDS), string(OSS), string(ELB)} + CustomizeMonTypeList = []string{string(CLOUDACCOUNT), string(STORAGE), string(ALERT_RECORD), string(PING_PROBE)} +) + var OtherVmTags = map[string]string{ "source": "cloudmon", "res_type": "guest", @@ -74,24 +90,6 @@ var OtherHostTag = map[string]string{ "is_vm": "false", } -type ReportOptions struct { - Batch int `help:"batch"` - Count int `help:"count" json:"count"` - Interval string `help:"interval"` - 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" 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"` -} - var InstanceProviders = "Aliyun,Azure,Aws,Qcloud,VMWare,Huawei,Openstack,Ucloud,ZStack" //server的key-value对应保存时的Tags和Pairs @@ -320,7 +318,7 @@ func ParseTimeStr(startTime, endTime string) (since, util time.Time, err error) return since, util, nil } -func TimeRangeFromArgs(args *ReportOptions) (since, until time.Time, err error) { +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 { @@ -414,7 +412,8 @@ func SendMetrics(s *mcclient.ClientSession, metrics []influxdb.SMetricData, debu return influxdb.SendMetrics(urls, database, metrics, debug) } -func ReportCloudMetricOfoperatorType(operatorType string, session *mcclient.ClientSession, args *ReportOptions) error { +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) @@ -475,11 +474,7 @@ func ReportCloudMetricOfoperatorType(operatorType string, session *mcclient.Clie return providerGroup.Wait() } -func newGroupFunc(func()) { - -} - -func ReportCustomizeCloudMetric(operatorType string, session *mcclient.ClientSession, args *ReportOptions) error { +func ReportCustomizeCloudMetric(operatorType string, session *mcclient.ClientSession, args *o.ReportOptions) error { cloudReportFactory, err := GetCloudReportFactory(operatorType) if err != nil { return errors.Wrap(err, "GetCloudReportFactory") @@ -514,3 +509,108 @@ func CollectRegionMetricAsync(asynCount int, region cloudprovider.ICloudRegion, } 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.Errorf("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.Errorf("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 { + log.Errorf("provider: %s report metric err: %v", provider.Name, err) + return + } + log.Errorf("operator: %s report() end.", factory.GetId()) +} diff --git a/pkg/cloudmon/collectors/ecloudmon/ecloudreport.go b/pkg/cloudmon/collectors/ecloudmon/ecloudreport.go index 7b89615374..5c4be138ea 100644 --- a/pkg/cloudmon/collectors/ecloudmon/ecloudreport.go +++ b/pkg/cloudmon/collectors/ecloudmon/ecloudreport.go @@ -17,6 +17,7 @@ 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" "yunion.io/x/onecloud/pkg/mcclient/modules" ) @@ -27,10 +28,11 @@ func init() { } type SECloudReportFactory struct { + common.CommonReportFactory } func (self *SECloudReportFactory) NewCloudReport(provider *common.SProvider, session *mcclient.ClientSession, - args *common.ReportOptions, operatorType string) common.ICloudReport { + args *options.ReportOptions, operatorType string) common.ICloudReport { return &SECloudReport{ common.CloudReportBase{ SProvider: provider, diff --git a/pkg/cloudmon/collectors/elbservice.go b/pkg/cloudmon/collectors/elbservice.go index 07016fb44a..bb891695c0 100644 --- a/pkg/cloudmon/collectors/elbservice.go +++ b/pkg/cloudmon/collectors/elbservice.go @@ -16,15 +16,16 @@ 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(&common.ReportOptions{}, "report-elb", "Report Elb", reportElb) + shellutils.R(&options.ReportOptions{}, "report-elb", "Report Elb", reportElb) } //入口函数[aliyun、huawei] -func reportElb(session *mcclient.ClientSession, args *common.ReportOptions) error { +func reportElb(session *mcclient.ClientSession, args *options.ReportOptions) error { return common.ReportCloudMetricOfoperatorType(string(common.ELB), session, args) } diff --git a/pkg/cloudmon/collectors/gcpmon/gcpreport.go b/pkg/cloudmon/collectors/gcpmon/gcpreport.go index ca599f1d9c..9303e8a858 100644 --- a/pkg/cloudmon/collectors/gcpmon/gcpreport.go +++ b/pkg/cloudmon/collectors/gcpmon/gcpreport.go @@ -17,6 +17,7 @@ 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" "yunion.io/x/onecloud/pkg/mcclient/modules" ) @@ -27,10 +28,11 @@ func init() { } type SGoogleCloudReportFactory struct { + common.CommonReportFactory } func (self *SGoogleCloudReportFactory) NewCloudReport(provider *common.SProvider, session *mcclient.ClientSession, - args *common.ReportOptions, operatorType string) common.ICloudReport { + args *options.ReportOptions, operatorType string) common.ICloudReport { return &SGoogleCloudReport{ common.CloudReportBase{ SProvider: provider, diff --git a/pkg/cloudmon/collectors/hostservice.go b/pkg/cloudmon/collectors/hostservice.go index 5d0d103e36..989b690fd8 100644 --- a/pkg/cloudmon/collectors/hostservice.go +++ b/pkg/cloudmon/collectors/hostservice.go @@ -16,15 +16,16 @@ 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(&common.ReportOptions{}, "report-host", "Report Host", reportHost) + shellutils.R(&options.ReportOptions{}, "report-host", "Report Host", reportHost) } //入口函数[aliyun、huawei] -func reportHost(session *mcclient.ClientSession, args *common.ReportOptions) error { +func reportHost(session *mcclient.ClientSession, args *options.ReportOptions) error { return common.ReportCloudMetricOfoperatorType(string(common.HOST), session, args) } diff --git a/pkg/cloudmon/collectors/huaweimon/huaweicloudreport.go b/pkg/cloudmon/collectors/huaweimon/huaweicloudreport.go index df2e0652f1..4f331a2d5c 100644 --- a/pkg/cloudmon/collectors/huaweimon/huaweicloudreport.go +++ b/pkg/cloudmon/collectors/huaweimon/huaweicloudreport.go @@ -19,6 +19,7 @@ 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" "yunion.io/x/onecloud/pkg/mcclient/modules" ) @@ -34,10 +35,11 @@ func init() { } type SHwCloudReportFactory struct { + common.CommonReportFactory } func (self *SHwCloudReportFactory) NewCloudReport(provider *common.SProvider, session *mcclient.ClientSession, - args *common.ReportOptions, operatorType string) common.ICloudReport { + args *options.ReportOptions, operatorType string) common.ICloudReport { return &SHwCloudReport{ common.CloudReportBase{ SProvider: provider, diff --git a/pkg/cloudmon/collectors/jdmon/jdcloudreport.go b/pkg/cloudmon/collectors/jdmon/jdcloudreport.go index 6ae44a0111..422fbc81de 100644 --- a/pkg/cloudmon/collectors/jdmon/jdcloudreport.go +++ b/pkg/cloudmon/collectors/jdmon/jdcloudreport.go @@ -19,6 +19,7 @@ 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" "yunion.io/x/onecloud/pkg/mcclient/modules" ) @@ -29,10 +30,11 @@ func init() { } type SJdCloudReportFactory struct { + common.CommonReportFactory } func (self *SJdCloudReportFactory) NewCloudReport(provider *common.SProvider, session *mcclient.ClientSession, - args *common.ReportOptions, operatorType string) common.ICloudReport { + args *options.ReportOptions, operatorType string) common.ICloudReport { return &SJdCloudReport{ common.CloudReportBase{ SProvider: provider, diff --git a/pkg/cloudmon/collectors/ossservice.go b/pkg/cloudmon/collectors/ossservice.go index 1a1885313a..d08e9850eb 100644 --- a/pkg/cloudmon/collectors/ossservice.go +++ b/pkg/cloudmon/collectors/ossservice.go @@ -16,13 +16,14 @@ 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(&common.ReportOptions{}, "report-oss", "Report Oss", reportOss) + shellutils.R(&options.ReportOptions{}, "report-oss", "Report Oss", reportOss) } -func reportOss(session *mcclient.ClientSession, args *common.ReportOptions) error { +func reportOss(session *mcclient.ClientSession, args *options.ReportOptions) error { return common.ReportCloudMetricOfoperatorType(string(common.OSS), session, args) } diff --git a/pkg/cloudmon/collectors/pinger.go b/pkg/cloudmon/collectors/pinger.go index dcf2b40544..1cedf339e2 100644 --- a/pkg/cloudmon/collectors/pinger.go +++ b/pkg/cloudmon/collectors/pinger.go @@ -25,6 +25,7 @@ import ( 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" "yunion.io/x/onecloud/pkg/mcclient/modules" "yunion.io/x/onecloud/pkg/util/influxdb" @@ -33,7 +34,43 @@ import ( "yunion.io/x/onecloud/pkg/util/sysutils" ) -func pingProbeCoolector(s *mcclient.ClientSession, args *common.ReportOptions) error { +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 { isRoot := sysutils.IsRootPermission() if !isRoot { return errors.Error("require root permissions") @@ -92,7 +129,7 @@ func getNetworkAddrMap(s *mcclient.ClientSession, netId string) (map[string]api. } func pingProbeNetwork(s *mcclient.ClientSession, data jsonutils.JSONObject, - args *common.PingProbeOptions) ([]influxdb.SMetricData, error) { + args *options.PingProbeOptions) ([]influxdb.SMetricData, error) { metrics := make([]influxdb.SMetricData, 0) net := &sNetwork{} err := data.Unmarshal(&net) @@ -218,5 +255,5 @@ func pingProbeNetwork(s *mcclient.ClientSession, data jsonutils.JSONObject, } func init() { - shellutils.R(&common.ReportOptions{}, "ping-probe", "Ping probe IPv4 address", pingProbeCoolector) + shellutils.R(&options.ReportOptions{}, "ping-probe", "Ping probe IPv4 address", pingProbeColector) } diff --git a/pkg/cloudmon/collectors/qcmon/qcloudreport.go b/pkg/cloudmon/collectors/qcmon/qcloudreport.go index fb7c473ae4..4a9abd378a 100644 --- a/pkg/cloudmon/collectors/qcmon/qcloudreport.go +++ b/pkg/cloudmon/collectors/qcmon/qcloudreport.go @@ -19,6 +19,7 @@ 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" "yunion.io/x/onecloud/pkg/mcclient/modules" ) @@ -29,10 +30,11 @@ func init() { } type SQCloudReportFactory struct { + common.CommonReportFactory } func (self *SQCloudReportFactory) NewCloudReport(provider *common.SProvider, session *mcclient.ClientSession, - args *common.ReportOptions, operatorType string) common.ICloudReport { + args *options.ReportOptions, operatorType string) common.ICloudReport { return &SQCloudReport{ common.CloudReportBase{ SProvider: provider, diff --git a/pkg/cloudmon/collectors/rdsservice.go b/pkg/cloudmon/collectors/rdsservice.go index d591c018fd..c25c0bdc67 100644 --- a/pkg/cloudmon/collectors/rdsservice.go +++ b/pkg/cloudmon/collectors/rdsservice.go @@ -16,14 +16,15 @@ 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(&common.ReportOptions{}, "report-rds", "Report Rds", reporRds) + shellutils.R(&options.ReportOptions{}, "report-rds", "Report Rds", reporRds) } -func reporRds(session *mcclient.ClientSession, args *common.ReportOptions) error { +func reporRds(session *mcclient.ClientSession, args *options.ReportOptions) error { return common.ReportCloudMetricOfoperatorType(string(common.RDS), session, args) } diff --git a/pkg/cloudmon/collectors/redisservice.go b/pkg/cloudmon/collectors/redisservice.go index 7d97080bce..1c09f350b6 100644 --- a/pkg/cloudmon/collectors/redisservice.go +++ b/pkg/cloudmon/collectors/redisservice.go @@ -16,14 +16,15 @@ 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(&common.ReportOptions{}, "report-redis", "Report Redis", reportRedis) + shellutils.R(&options.ReportOptions{}, "report-redis", "Report Redis", reportRedis) } -func reportRedis(session *mcclient.ClientSession, args *common.ReportOptions) error { +func reportRedis(session *mcclient.ClientSession, args *options.ReportOptions) error { return common.ReportCloudMetricOfoperatorType(string(common.REDIS), session, args) } diff --git a/pkg/cloudmon/collectors/serverservice.go b/pkg/cloudmon/collectors/serverservice.go index bbfe5653e5..7fcc88ab8d 100644 --- a/pkg/cloudmon/collectors/serverservice.go +++ b/pkg/cloudmon/collectors/serverservice.go @@ -16,15 +16,16 @@ 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(&common.ReportOptions{}, "report-server", "Report Server", reportServer) + shellutils.R(&options.ReportOptions{}, "report-server", "Report Server", reportServer) } //入口函数[aliyun、huawei] -func reportServer(session *mcclient.ClientSession, args *common.ReportOptions) error { +func reportServer(session *mcclient.ClientSession, args *options.ReportOptions) error { return common.ReportCloudMetricOfoperatorType(string(common.SERVER), session, args) } diff --git a/pkg/cloudmon/collectors/service_const.go b/pkg/cloudmon/collectors/service_const.go new file mode 100644 index 0000000000..712cd053f2 --- /dev/null +++ b/pkg/cloudmon/collectors/service_const.go @@ -0,0 +1,5 @@ +package collectors + +const ( + REDIS_CRON_JOB_NAME = "redis_cron" +) diff --git a/pkg/cloudmon/collectors/storagemon/storagereport.go b/pkg/cloudmon/collectors/storagemon/storagereport.go index 2b8ddbe09b..e62a44db9c 100644 --- a/pkg/cloudmon/collectors/storagemon/storagereport.go +++ b/pkg/cloudmon/collectors/storagemon/storagereport.go @@ -16,20 +16,22 @@ package storagemon 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/mcclient/modules" ) func init() { - factory := SCloudAccountFactory{} + factory := SStorageReportFactory{} common.RegisterFactory(&factory) } -type SCloudAccountFactory struct { +type SStorageReportFactory struct { + common.CommonReportFactory } -func (self *SCloudAccountFactory) NewCloudReport(provider *common.SProvider, session *mcclient.ClientSession, - args *common.ReportOptions, +func (self *SStorageReportFactory) NewCloudReport(provider *common.SProvider, session *mcclient.ClientSession, + args *options.ReportOptions, operatorType string) common.ICloudReport { return &SStorageReport{ common.CloudReportBase{ @@ -41,7 +43,7 @@ func (self *SCloudAccountFactory) NewCloudReport(provider *common.SProvider, ses } } -func (S SCloudAccountFactory) GetId() string { +func (S SStorageReportFactory) GetId() string { return string(common.STORAGE) } diff --git a/pkg/cloudmon/collectors/storageservice.go b/pkg/cloudmon/collectors/storageservice.go index b2c555804b..6564598ff2 100644 --- a/pkg/cloudmon/collectors/storageservice.go +++ b/pkg/cloudmon/collectors/storageservice.go @@ -16,14 +16,15 @@ 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(&common.ReportOptions{}, "report-storage", "Report Storage", reportStorage) + shellutils.R(&options.ReportOptions{}, "report-storage", "Report Storage", reportStorage) } -func reportStorage(session *mcclient.ClientSession, args *common.ReportOptions) error { +func reportStorage(session *mcclient.ClientSession, args *options.ReportOptions) error { return common.ReportCustomizeCloudMetric(string(common.STORAGE), session, args) } diff --git a/pkg/cloudmon/collectors/usageservice.go b/pkg/cloudmon/collectors/usageservice.go index d9476d3974..968ac60b77 100644 --- a/pkg/cloudmon/collectors/usageservice.go +++ b/pkg/cloudmon/collectors/usageservice.go @@ -22,7 +22,7 @@ import ( "yunion.io/x/jsonutils" "yunion.io/x/pkg/errors" - "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/mcclient/modules" "yunion.io/x/onecloud/pkg/util/influxdb" @@ -36,10 +36,10 @@ var config map[string]string = map[string]string{ var measureMent string = "usage" func init() { - shellutils.R(&common.ReportOptions{}, "report-usage", "Report Usage", reportUsage) + shellutils.R(&options.ReportOptions{}, "report-usage", "Report Usage", reportUsage) } -func reportUsage(session *mcclient.ClientSession, args *common.ReportOptions) error { +func reportUsage(session *mcclient.ClientSession, args *options.ReportOptions) error { dataList := make([]influxdb.SMetricData, 0) nowTime := time.Now() //镜像使用量信息 diff --git a/pkg/cloudmon/collectors/vmwaremon/vmwarereport.go b/pkg/cloudmon/collectors/vmwaremon/vmwarereport.go index 085ebcef4f..e84c455108 100644 --- a/pkg/cloudmon/collectors/vmwaremon/vmwarereport.go +++ b/pkg/cloudmon/collectors/vmwaremon/vmwarereport.go @@ -20,6 +20,7 @@ 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" "yunion.io/x/onecloud/pkg/mcclient/modules" ) @@ -30,10 +31,11 @@ func init() { } type SEsxiCloudReportFactory struct { + common.CommonReportFactory } func (self *SEsxiCloudReportFactory) NewCloudReport(provider *common.SProvider, session *mcclient.ClientSession, - args *common.ReportOptions, operatorType string) common.ICloudReport { + args *options.ReportOptions, operatorType string) common.ICloudReport { return &SEsxiCloudReport{ common.CloudReportBase{ SProvider: provider, diff --git a/pkg/cloudmon/collectors/zstackmon/zstackreport.go b/pkg/cloudmon/collectors/zstackmon/zstackreport.go index fffdbe8235..4ecc29c250 100644 --- a/pkg/cloudmon/collectors/zstackmon/zstackreport.go +++ b/pkg/cloudmon/collectors/zstackmon/zstackreport.go @@ -19,6 +19,7 @@ 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" "yunion.io/x/onecloud/pkg/mcclient/modules" ) @@ -29,10 +30,11 @@ func init() { } type SZStackCloudReportFactory struct { + common.CommonReportFactory } func (self *SZStackCloudReportFactory) NewCloudReport(provider *common.SProvider, session *mcclient.ClientSession, - args *common.ReportOptions, operatorType string) common.ICloudReport { + args *options.ReportOptions, operatorType string) common.ICloudReport { return &SZStackCloudReport{ common.CloudReportBase{ SProvider: provider, diff --git a/pkg/cloudmon/options/options.go b/pkg/cloudmon/options/options.go index 139afe80b3..d4dc20c3d5 100644 --- a/pkg/cloudmon/options/options.go +++ b/pkg/cloudmon/options/options.go @@ -20,34 +20,46 @@ import ( "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 { - structarg.BaseOptions + common_options.CommonOptions + ReportOptions - Region string `help:"Region name"` EndpointType string `default:"internalURL" help:"Defaults to internalURL" choices:"publicURL|internalURL|adminURL"` ApiVersion string `help:"override default modules service api version"` - Debug bool `help:"Show debug information"` - Timeout int `default:"600" help:"Number of seconds to wait for a response"` - Insecure bool `default:"true" help:"Allow skip server cert verification if URL is https" short-token:"k"` - CertFile string `help:"certificate file"` - KeyFile string `help:"private key file"` - - AuthURL string `help:"Keystone auth URL" alias:"auth-uri"` - AdminUser string `help:"Admin username"` - AdminDomain string `help:"Admin user domain"` - AdminPassword string `help:"Admin password" alias:"admin-passwd"` - AdminProject string `help:"Admin project" default:"system" alias:"admin-tenant-name"` - AdminProjectDomain string `help:"Domain of Admin project"` - - SessionEndpointType string `help:"Client session end point type"` + ReqTimeout int `default:"600" help:"Number of seconds to wait for a response"` + Insecure bool `default:"true" help:"Allow skip server cert verification if URL is https" short-token:"k"` + CertFile string `help:"certificate file"` + KeyFile string `help:"private key file"` InfluxDatabase string `help:"influxdb database name, default telegraf" default:"telegraf"` - SUBCOMMAND string `help:"climc subcommand" subcommand:"true"` + Subcommand string `help:"climc subcommand" subcommand:"false"` +} + +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" 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"` } func GetArgumentParser() (*structarg.ArgumentParser, error) { diff --git a/pkg/cloudmon/service/doc.go b/pkg/cloudmon/service/doc.go new file mode 100644 index 0000000000..dd6e4f74f3 --- /dev/null +++ b/pkg/cloudmon/service/doc.go @@ -0,0 +1 @@ +package service // import "yunion.io/x/onecloud/pkg/cloudmon/service" diff --git a/pkg/cloudmon/service/service.go b/pkg/cloudmon/service/service.go new file mode 100644 index 0000000000..69e0d9de74 --- /dev/null +++ b/pkg/cloudmon/service/service.go @@ -0,0 +1,130 @@ +package service + +import ( + "context" + "os" + "time" + + "yunion.io/x/jsonutils" + "yunion.io/x/log" + "yunion.io/x/pkg/errors" + "yunion.io/x/pkg/utils" + + common_app "yunion.io/x/onecloud/pkg/cloudcommon/app" + common_options "yunion.io/x/onecloud/pkg/cloudcommon/options" + _ "yunion.io/x/onecloud/pkg/cloudmon/collectors" + "yunion.io/x/onecloud/pkg/cloudmon/collectors/common" + "yunion.io/x/onecloud/pkg/cloudmon/options" + "yunion.io/x/onecloud/pkg/mcclient/auth" + "yunion.io/x/onecloud/pkg/mcclient/modules" +) + +var ( + cloudproviderChanMap = make(map[string]chan struct{}) + cutomizeOperatorChanmap = make(map[string]chan struct{}) +) + +func StartService() { + opts := &options.Options + common_options.ParseOptions(opts, os.Args, "cloudmon.conf", "cloudmon") + + commonOpts := &opts.CommonOptions + common_app.InitAuth(commonOpts, func() { + log.Infof("Auth complete") + }) + ctx := context.Background() + duration := time.Duration(opts.CloudproviderSyncInterval) * time.Minute + log.Errorf("CloudproviderSyncInterval: %d", opts.CloudproviderSyncInterval) + nextSync := time.Now() + for i, _ := range common.CustomizeMonTypeList { + monType := common.CustomizeMonTypeList[i] + cutomizeOperatorChanmap[monType] = make(chan struct{}) + cloudReportFactory, err := common.GetCloudReportFactory(monType) + if err != nil { + log.Errorf("CustomizeMonType: %s GetCloudReportFactory err: $v", monType, err) + continue + } + if routineF, ok := cloudReportFactory.(common.IRoutineFactory); ok { + routineF.MyRoutineFunc()(ctx, cloudReportFactory, nil, cutomizeOperatorChanmap[monType], + cloudReportFactory.MyRoutineInteval(*opts), common.CustomizeRunFunc) + continue + } + common.MakePullMetricRoutineWithDur(ctx, cloudReportFactory, nil, cutomizeOperatorChanmap[monType], + cloudReportFactory.MyRoutineInteval(*opts), common.CustomizeRunFunc) + } + + for { + if nextSync.Before(time.Now()) { + cloudproviderList, err := getCloudproviderList(ctx) + if err != nil { + log.Errorf("err: %v", err) + return + } + cloudproviderList = syncCloudproviderChanMap(cloudproviderList) + log.Errorf("cloudproviderList: %d", len(cloudproviderList)) + for i := 0; i < len(cloudproviderList); i++ { + provider := cloudproviderList[i] + status, err := provider.GetString("status") + if err != nil { + log.Errorf("provider: %v get status error: %v", provider, err) + continue + } + if status == "connected" { + id, _ := provider.GetString("id") + err := common.ReportConnectCloudproviderMetric(ctx, provider, cloudproviderChanMap[id]) + if err != nil { + log.Errorf("ReportConnectCloudproviderMetric err: %v", err) + } + } + } + nextSync = time.Now().Add(duration) + } + time.Sleep(time.Minute) + } + +} + +func getCloudproviderList(ctx context.Context) ([]jsonutils.JSONObject, error) { + session := auth.GetAdminSessionWithPublic(context.Background(), "", "") + query := jsonutils.NewDict() + query.Add(jsonutils.NewString("10"), common.KEY_LIMIT) + query.Add(jsonutils.NewString("true"), common.KEY_ADMIN) + //query.Add(jsonutils.NewString("true"), KEY_USABLE) + if len(common.SupportMetricBrands) == 0 { + return nil, errors.Errorf("SupportMetricBrands is empty") + } + cloudProviderList := make([]jsonutils.JSONObject, 0) + for _, val := range common.SupportMetricBrands { + + query.Add(jsonutils.NewString(val), "provider") + tmpList, err := common.ListAllResources(&modules.Cloudproviders, session, query) + if err != nil { + return nil, errors.Wrap(err, "list Cloudproviders err") + } + cloudProviderList = append(cloudProviderList, tmpList...) + } + return cloudProviderList, nil +} + +func syncCloudproviderChanMap(cloudproviderList []jsonutils.JSONObject) []jsonutils.JSONObject { + newCloudprovider := make([]jsonutils.JSONObject, 0) + providerIds := make([]string, 0) + for i, _ := range cloudproviderList { + id, _ := cloudproviderList[i].GetString("id") + providerIds = append(providerIds, id) + if _, ok := cloudproviderChanMap[id]; ok { + continue + } + newCloudprovider = append(newCloudprovider, cloudproviderList[i]) + cloudproviderChanMap[id] = make(chan struct{}) + } + for id, channel := range cloudproviderChanMap { + if utils.IsInStringArray(id, providerIds) { + continue + } + delete(cloudproviderChanMap, id) + close(channel) + } + return newCloudprovider + +}