From 3aa2b264d1b1d1cbbe1976935e6f274e98310afa Mon Sep 17 00:00:00 2001 From: Dmitry Date: Fri, 6 Dec 2024 12:54:25 +0300 Subject: [PATCH] Added supporting OS Windows (#381) * Changed package for logging for supported windows. Added setting of file names depending on OS. Chnaged collect metrics for swap memory. * Changed the application launch algorithm to support Windows. * Fixed CI/CD. Added build for Windows --- .github/workflows/go.yml | 2 +- .gitignore | 2 +- build.sh | 1 + config/config.go | 7 +- errors/releemErrors.go | 11 +- go.mod | 2 +- go.sum | 5 +- main.go | 214 ++++++++++++++++++------------- metrics/agent.go | 15 +-- metrics/awsrdsdiscovery.go | 29 ++--- metrics/awsrdsenhancedmetrics.go | 29 ++--- metrics/awsrdsmetrics.go | 23 +--- metrics/dbCollectQueries.go | 31 ++--- metrics/dbConf.go | 15 +-- metrics/dbInfo.go | 24 ++-- metrics/dbMetrics.go | 14 +- metrics/dbMetricsBase.go | 13 +- metrics/os.go | 36 ++---- metrics/runner.go | 43 +++---- repeater/logger.go | 13 +- repeater/releemConfiguration.go | 20 +-- tasks/tasks.go | 41 +++--- utils/utils.go | 20 +-- 23 files changed, 275 insertions(+), 335 deletions(-) diff --git a/.github/workflows/go.yml b/.github/workflows/go.yml index e895464..af82c7d 100644 --- a/.github/workflows/go.yml +++ b/.github/workflows/go.yml @@ -26,7 +26,7 @@ jobs: - name: Create upload dir run: | mkdir -p ../v2 - cp current_version_agent install.sh mysqlconfigurer.sh releem-agent-x86_64 releem-agent-amd64 releem-agent-aarch64 releem-agent-freebsd-amd64 releem-agent-i686 ../v2/ + cp current_version_agent install.sh mysqlconfigurer.sh releem-agent-x86_64 releem-agent-amd64 releem-agent-aarch64 releem-agent-freebsd-amd64 releem-agent-i686 releem-agent.exe ../v2/ - uses: shallwefootball/s3-upload-action@master name: Upload S3 current_version_agent diff --git a/.gitignore b/.gitignore index 5855407..877ccda 100644 --- a/.gitignore +++ b/.gitignore @@ -2,6 +2,6 @@ test-project/test.sh .DS_Store releem-install.log -releem-agent-* +releem-agent* releem1.conf releem_rds.conf \ No newline at end of file diff --git a/build.sh b/build.sh index 6495599..ac3b207 100644 --- a/build.sh +++ b/build.sh @@ -3,3 +3,4 @@ CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -o releem-agent-amd64 CGO_ENABLED=0 GOOS=linux GOARCH=arm64 go build -o releem-agent-aarch64 CGO_ENABLED=0 GOOS=linux GOARCH=386 go build -o releem-agent-i686 CGO_ENABLED=0 GOOS=freebsd GOARCH=amd64 go build -o releem-agent-freebsd-amd64 +CGO_ENABLED=0 GOOS=windows GOARCH=amd64 go build -o releem-agent.exe diff --git a/config/config.go b/config/config.go index ce71935..8a05f6b 100644 --- a/config/config.go +++ b/config/config.go @@ -4,7 +4,7 @@ import ( "os" "time" - "github.com/advantageous/go-logback/logging" + logging "github.com/google/logger" "github.com/hashicorp/hcl" ) @@ -41,10 +41,7 @@ type Config struct { } func LoadConfig(filename string, logger logging.Logger) (*Config, error) { - if logger == nil { - logger = logging.NewSimpleLogger("config") - } - logger.Printf("Loading config %s", filename) + logger.Infof("Loading config %s", filename) configBytes, err := os.ReadFile(filename) if err != nil { return nil, err diff --git a/errors/releemErrors.go b/errors/releemErrors.go index 8850630..8cce50b 100644 --- a/errors/releemErrors.go +++ b/errors/releemErrors.go @@ -5,7 +5,7 @@ import ( "strings" "github.com/Releem/mysqlconfigurer/config" - "github.com/advantageous/go-logback/logging" + logging "github.com/google/logger" "time" ) @@ -19,7 +19,7 @@ func (repeater ReleemErrorsRepeater) ProcessErrors(message string) interface{} { var env string bodyReader := strings.NewReader(message) - repeater.logger.Debug("Result Send data: ", message) + repeater.logger.V(5).Info("Result Send data: ", message) var api_domain string if repeater.configuration != nil { env = repeater.configuration.Env @@ -53,11 +53,10 @@ func (repeater ReleemErrorsRepeater) ProcessErrors(message string) interface{} { repeater.logger.Error("Request: error making http request: ", err) return nil } - repeater.logger.Debug("Response: status code: ", res.StatusCode) - return nil + repeater.logger.V(5).Info("Response: status code: ", res.StatusCode) + return res } -func NewReleemErrorsRepeater(configuration *config.Config) ReleemErrorsRepeater { - logger := logging.NewSimpleLogger("ReleemRepeaterMetrics") +func NewReleemErrorsRepeater(configuration *config.Config, logger logging.Logger) ReleemErrorsRepeater { return ReleemErrorsRepeater{logger, configuration} } diff --git a/go.mod b/go.mod index 2196dad..f868a2d 100644 --- a/go.mod +++ b/go.mod @@ -4,7 +4,6 @@ go 1.22.0 require ( github.com/Releem/daemon v0.0.0-20241028135502-b7f24658ba58 - github.com/advantageous/go-logback v0.0.0-20161215180304-6db19679ca3e github.com/aws/aws-sdk-go v1.53.7 github.com/aws/aws-sdk-go-v2 v1.27.0 github.com/aws/aws-sdk-go-v2/config v1.27.15 @@ -13,6 +12,7 @@ require ( github.com/aws/aws-sdk-go-v2/service/ec2 v1.161.3 github.com/aws/aws-sdk-go-v2/service/rds v1.79.1 github.com/go-sql-driver/mysql v1.8.1 + github.com/google/logger v1.1.1 github.com/hashicorp/hcl v1.0.0 github.com/pkg/errors v0.9.1 github.com/shirou/gopsutil/v4 v4.24.10 diff --git a/go.sum b/go.sum index 9e9061d..3c8ea8a 100644 --- a/go.sum +++ b/go.sum @@ -2,8 +2,6 @@ filippo.io/edwards25519 v1.1.0 h1:FNf4tywRC1HmFuKW5xopWpigGjJKiJSV0Cqo0cJWDaA= filippo.io/edwards25519 v1.1.0/go.mod h1:BxyFTGdWcka3PhytdK4V28tE5sGfRvvvRV7EaN4VDT4= github.com/Releem/daemon v0.0.0-20241028135502-b7f24658ba58 h1:ISdzv2VqJ4GVjtvT0WAWsg9n2iKOjYMcMpSL3VJSoqg= github.com/Releem/daemon v0.0.0-20241028135502-b7f24658ba58/go.mod h1:GxsvZP6BRrh+rSHnXaXzuShSiiiMEfDxuutowpgCG8w= -github.com/advantageous/go-logback v0.0.0-20161215180304-6db19679ca3e h1:zDwXL5E118a4JRyWUVVzGUg4zDXY2CfllYYu+B6Vgy8= -github.com/advantageous/go-logback v0.0.0-20161215180304-6db19679ca3e/go.mod h1:pynxONZJ8msfhJ8u3t9OQZVPsn9i9AW4VW55zv9K9+I= github.com/aws/aws-sdk-go v1.53.7 h1:ZSsRYHLRxsbO2rJR2oPMz0SUkJLnBkN+1meT95B6Ixs= github.com/aws/aws-sdk-go v1.53.7/go.mod h1:LF8svs817+Nz+DmiMQKTO3ubZ/6IaTpq3TjupRn3Eqk= github.com/aws/aws-sdk-go-v2 v1.27.0 h1:7bZWKoXhzI+mMR/HjdMx8ZCC5+6fY0lS5tr0bbgiLlo= @@ -54,6 +52,8 @@ github.com/go-sql-driver/mysql v1.8.1/go.mod h1:wEBSXgmK//2ZFJyE+qWnIsVGmvmEKlqw github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= +github.com/google/logger v1.1.1 h1:+6Z2geNxc9G+4D4oDO9njjjn2d0wN5d7uOo0vOIW1NQ= +github.com/google/logger v1.1.1/go.mod h1:BkeJZ+1FhQ+/d087r4dzojEg1u2ZX+ZqG1jTUrLM+zQ= github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4= github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= github.com/jmespath/go-jmespath v0.4.0 h1:BEgLn5cpjn8UN1mAw4NjwDrS35OdebyEtFe+9YPoQUg= @@ -81,6 +81,7 @@ github.com/yusufpapurcu/wmi v1.2.4 h1:zFUKzehAFReQwLys1b/iSMl+JQGSCSjtVqQn9bBrPo github.com/yusufpapurcu/wmi v1.2.4/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0= golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201204225414-ed752295db88/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210426230700-d19ff857e887/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.26.0 h1:KHjCJyddX0LoSTb3J+vWpupP9p0oznkqVk/IfjymZbo= diff --git a/main.go b/main.go index 2408e08..eae8aeb 100644 --- a/main.go +++ b/main.go @@ -4,8 +4,10 @@ package main import ( "context" "flag" - "fmt" + "io" + "log" "os" + "runtime" "github.com/Releem/daemon" "github.com/Releem/mysqlconfigurer/config" @@ -14,79 +16,74 @@ import ( r "github.com/Releem/mysqlconfigurer/repeater" "github.com/Releem/mysqlconfigurer/utils" - "github.com/advantageous/go-logback/logging" awsconfig "github.com/aws/aws-sdk-go-v2/config" "github.com/aws/aws-sdk-go-v2/service/cloudwatchlogs" "github.com/aws/aws-sdk-go-v2/service/rds" "github.com/aws/aws-sdk-go/aws/awserr" _ "github.com/go-sql-driver/mysql" + logging "github.com/google/logger" ) const ( // name of the service - name = "releem-agent" - description = "Releem Agent" + serviceName = "releem-agent" + serviceDescription = "Releem Agent" ) -// dependencies that are NOT required by the service, but might be used -var dependencies = []string{"network.target"} - var logger logging.Logger +var SetConfigRun, GetConfigRun *bool +var ConfigFile, AgentEvent, AgentTask *string // Service has embedded daemon type Service struct { daemon.Daemon } +type Programm struct{} -// func IsSocket(path string, logger logging.Logger) bool { -// fileInfo, err := os.Stat(path) -// if err != nil { -// return false -// } -// return fileInfo.Mode().Type() == fs.ModeSocket -// } +func (programm *Programm) Stop() { + // Stop should not block. Return with a few seconds. +} -// Manage by daemon commands or run the daemon -func (service *Service) Manage(logger logging.Logger, configFile string, command []string, TypeConfiguration string, AgentEvent string, AgentTask string) (string, error) { +func (programm *Programm) Start() { + // Start should not block. Do the actual work async. + go programm.Run() +} + +func (programm *Programm) Run() { + + var TypeConfiguration string var gatherers, gatherers_configuration, gatherers_query_optimization []models.MetricsGatherer var Mode models.ModeType - var configuration *config.Config - usage := "Usage: myservice install | remove | start | stop | status" - - defer utils.HandlePanic(configuration, logger) - // if received any kind of command, do it - if len(command) >= 1 { - switch command[0] { - case "install": - return service.Install() - case "remove": - return service.Remove() - case "start": - return service.Start() - case "stop": - return service.Stop() - case "status": - return service.Status() - default: - return usage, nil - } + if *SetConfigRun { + TypeConfiguration = "set" + } else if *GetConfigRun { + TypeConfiguration = "get" + } else { + TypeConfiguration = "default" } // Do something, call your goroutines, etc - logger.Println("Starting releem-agent of version is", config.ReleemAgentVersion) - configuration, err := config.LoadConfig(configFile, logger) + logger.Info("Starting releem-agent of version is ", config.ReleemAgentVersion) + configuration, err := config.LoadConfig(*ConfigFile, logger) if err != nil { - logger.PrintError("Config load failed", err) - os.Exit(0) + logger.Error("Config load failed", err) + return } + defer utils.HandlePanic(configuration, logger) - if len(AgentEvent) > 0 { + if configuration.Debug { + logger.SetLevel(10) + } else { + logger.SetLevel(1) + } + + if len(*AgentEvent) > 0 { Mode.Name = "Event" - Mode.Type = AgentEvent - } else if len(AgentTask) > 0 { + Mode.Type = *AgentEvent + } else if len(*AgentTask) > 0 { Mode.Name = "TaskSet" - Mode.Type = AgentTask + Mode.Type = *AgentTask } else { Mode.Name = "Configurations" Mode.Type = TypeConfiguration @@ -95,15 +92,15 @@ func (service *Service) Manage(logger logging.Logger, configFile string, command // Select how we collect instance metrics depending on InstanceType switch configuration.InstanceType { case "aws/rds": - logger.Println("InstanceType is aws/rds") - logger.Println("Loading AWS configuration") + logger.Info("InstanceType is aws/rds") + logger.Info("Loading AWS configuration") awscfg, err := awsconfig.LoadDefaultConfig(context.TODO(), awsconfig.WithRegion(configuration.AwsRegion)) if err != nil { - logger.PrintError("Load AWS configuration FAILED", err) - return "Error", err + logger.Error("Load AWS configuration FAILED", err) + return } else { - logger.Println("AWS configuration loaded SUCCESS") + logger.Info("AWS configuration loaded SUCCESS") } cwlogsclient := cloudwatchlogs.NewFromConfig(awscfg) @@ -122,34 +119,34 @@ func (service *Service) Manage(logger logging.Logger, configFile string, command if err != nil { if aerr, ok := err.(awserr.Error); ok { logger.Error(aerr.Error()) - return "Error", aerr + return } else { // Print the error, cast err to awserr.Error to get the Code and // Message from an error. logger.Error(err.Error()) - return "Error", err + return } } - logger.Debug("RDS.DescribeDBInstances SUCCESS") + logger.Info("RDS.DescribeDBInstances SUCCESS") // Request detailed instance info if result != nil && len(result.DBInstances) == 1 { - // gatherers = append(gatherers, models.NewAWSRDSMetricsGatherer(nil, cwclient, configuration)) - // gatherers = append(gatherers, models.NewAWSRDSInstanceGatherer(nil, rdsclient, ec2client, configuration)) + // gatherers = append(gatherers, models.NewAWSRDSMetricsGatherer(logger, cwclient, configuration)) + // gatherers = append(gatherers, models.NewAWSRDSInstanceGatherer(logger, rdsclient, ec2client, configuration)) configuration.Hostname = configuration.AwsRDSDB configuration.MysqlHost = *result.DBInstances[0].Endpoint.Address - gatherers = append(gatherers, metrics.NewAWSRDSEnhancedMetricsGatherer(nil, result.DBInstances[0], cwlogsclient, configuration)) + gatherers = append(gatherers, metrics.NewAWSRDSEnhancedMetricsGatherer(logger, result.DBInstances[0], cwlogsclient, configuration)) } else if result != nil && len(result.DBInstances) > 1 { - logger.Println("RDS.DescribeDBInstances: Database has %d instances. Clusters are not supported", len(result.DBInstances)) - return "Error", fmt.Errorf("RDS.DescribeDBInstances: Database has %d instances. Clusters are not supported", len(result.DBInstances)) + logger.Infof("RDS.DescribeDBInstances: Database has %d instances. Clusters are not supported", len(result.DBInstances)) + return } else { - logger.Println("RDS.DescribeDBInstances: No instances") - return "Error", fmt.Errorf("RDS.DescribeDBInstances: No instances") + logger.Info("RDS.DescribeDBInstances: No instances") + return } default: - logger.Println("InstanceType is Local") - gatherers = append(gatherers, metrics.NewOSMetricsGatherer(nil, configuration)) + logger.Info("InstanceType is Local") + gatherers = append(gatherers, metrics.NewOSMetricsGatherer(logger, configuration)) } @@ -168,55 +165,88 @@ func (service *Service) Manage(logger logging.Logger, configFile string, command // repeaters["QueryOptimization"] = models.MetricsRepeater(r.NewReleemConfigurationsRepeater(configuration, models.Mode{Name: "Metrics", Type: "QuerysOptimization"})) // repeaters["QueriesOptimization"] = models.MetricsRepeater(r.NewReleemConfigurationsRepeater(configuration, models.Mode{Name: "TaskSet", Type: "queries_optimization"})) //var repeaters models.MetricsRepeater - repeaters := models.MetricsRepeater(r.NewReleemConfigurationsRepeater(configuration)) + repeaters := models.MetricsRepeater(r.NewReleemConfigurationsRepeater(configuration, logger)) //Init gatherers gatherers = append(gatherers, - metrics.NewDbConfGatherer(nil, configuration), - metrics.NewDbInfoGatherer(nil, configuration), - metrics.NewDbMetricsBaseGatherer(nil, configuration), - metrics.NewAgentMetricsGatherer(nil, configuration)) - gatherers_configuration = append(gatherers_configuration, metrics.NewDbMetricsGatherer(nil, configuration)) - gatherers_query_optimization = append(gatherers_query_optimization, metrics.NewDbCollectQueriesOptimization(nil, configuration)) + metrics.NewDbConfGatherer(logger, configuration), + metrics.NewDbInfoGatherer(logger, configuration), + metrics.NewDbMetricsBaseGatherer(logger, configuration), + metrics.NewAgentMetricsGatherer(logger, configuration)) + gatherers_configuration = append(gatherers_configuration, metrics.NewDbMetricsGatherer(logger, configuration)) + gatherers_query_optimization = append(gatherers_query_optimization, metrics.NewDbCollectQueriesOptimization(logger, configuration)) - metrics.RunWorker(gatherers, gatherers_configuration, gatherers_query_optimization, repeaters, nil, configuration, configFile, Mode) + metrics.RunWorker(gatherers, gatherers_configuration, gatherers_query_optimization, repeaters, logger, configuration, Mode) - // never happen, but need to complete code - return usage, nil } -func main() { - var TypeConfiguration string - logger = logging.NewSimpleLogger("Main") - - configFile := flag.String("config", "/opt/releem/releem.conf", "Releem agent config") - SetConfigRun := flag.Bool("f", false, "Releem agent generate config") - GetConfigRun := flag.Bool("c", false, "Releem agent get config") +// Manage by daemon commands or run the daemon +func (service *Service) Manage(command []string) (string, error) { + usage := "Usage: myservice install | remove | start | stop | status" + // if received any kind of command, do it + if len(command) >= 1 { + switch command[0] { + case "install": + return service.Install() + case "remove": + return service.Remove() + case "start": + return service.Start() + case "stop": + return service.Stop() + case "status": + return service.Status() + default: + return usage, nil + } + } - AgentEvent := flag.String("event", "", "Releem agent type event") - AgentTask := flag.String("task", "", "Releem agent task name") + return service.Run(&Programm{}) + // never happen, but need to complete code +} +func defaultConfigPath() string { + switch runtime.GOOS { + case "windows": + return "C:\\ProgramData\\ReleemAgent\\releem.conf" + default: // для Linux и других UNIX-подобных систем + return "/opt/releem/releem.conf" + } +} +func defaultDependencies() []string { + switch runtime.GOOS { + case "windows": + return []string{} + default: // для Linux и других UNIX-подобных систем + return []string{"network.target"} + } +} +func main() { + logger = *logging.Init("releem-agent", true, false, io.Discard) + defer logger.Close() + logging.SetFlags(log.LstdFlags | log.Lshortfile) + + defaultPath := defaultConfigPath() + SetConfigRun = flag.Bool("f", false, "Releem agent generate config") + GetConfigRun = flag.Bool("c", false, "Releem agent get config") + ConfigFile = flag.String("config", defaultPath, "Releem agent config") + AgentEvent = flag.String("event", "", "Releem agent type event") + AgentTask = flag.String("task", "", "Releem agent task name") flag.Parse() command := flag.Args() - if *SetConfigRun { - TypeConfiguration = "set" - } else if *GetConfigRun { - TypeConfiguration = "get" - } else { - TypeConfiguration = "default" - } - srv, err := daemon.New(name, description, daemon.SystemDaemon, dependencies...) + dependencies := defaultDependencies() + srv, err := daemon.New(serviceName, serviceDescription, daemon.SystemDaemon, dependencies...) if err != nil { - logger.PrintError("Error: ", err) + logger.Error("Error: ", err) os.Exit(1) } service := &Service{srv} - status, err := service.Manage(logger, *configFile, command, TypeConfiguration, *AgentEvent, *AgentTask) + status, err := service.Manage(command) if err != nil { - logger.Println(status, "\nError: ", err) + logger.Info(status, "\nError: ", err) os.Exit(1) } - logger.Println(status) + logger.Info(status) } diff --git a/metrics/agent.go b/metrics/agent.go index baf7f4a..86a2660 100644 --- a/metrics/agent.go +++ b/metrics/agent.go @@ -6,28 +6,17 @@ import ( "github.com/Releem/mysqlconfigurer/config" "github.com/Releem/mysqlconfigurer/models" "github.com/Releem/mysqlconfigurer/utils" - "github.com/advantageous/go-logback/logging" + logging "github.com/google/logger" ) type AgentMetricsGatherer struct { logger logging.Logger - debug bool configuration *config.Config } func NewAgentMetricsGatherer(logger logging.Logger, configuration *config.Config) *AgentMetricsGatherer { - - if logger == nil { - if configuration.Debug { - logger = logging.NewSimpleDebugLogger("Agent") - } else { - logger = logging.NewSimpleLogger("Agent") - } - } - return &AgentMetricsGatherer{ logger: logger, - debug: configuration.Debug, configuration: configuration, } } @@ -53,7 +42,7 @@ func (Agent *AgentMetricsGatherer) GetMetrics(metrics *models.Metrics) error { metrics.ReleemAgent.Info = output metrics.ReleemAgent.Conf = *Agent.configuration - Agent.logger.Debug("CollectMetrics ", output) + Agent.logger.V(5).Info("CollectMetrics Agent ", output) return nil } diff --git a/metrics/awsrdsdiscovery.go b/metrics/awsrdsdiscovery.go index 183c474..04309b7 100644 --- a/metrics/awsrdsdiscovery.go +++ b/metrics/awsrdsdiscovery.go @@ -7,7 +7,7 @@ import ( "github.com/Releem/mysqlconfigurer/config" "github.com/Releem/mysqlconfigurer/models" "github.com/Releem/mysqlconfigurer/utils" - "github.com/advantageous/go-logback/logging" + logging "github.com/google/logger" "github.com/aws/aws-sdk-go-v2/service/ec2" "github.com/aws/aws-sdk-go-v2/service/ec2/types" @@ -24,15 +24,6 @@ type AWSRDSInstanceGatherer struct { } func NewAWSRDSInstanceGatherer(logger logging.Logger, rdsclient *rds.Client, ec2client *ec2.Client, configuration *config.Config) *AWSRDSInstanceGatherer { - - if logger == nil { - if configuration.Debug { - logger = logging.NewSimpleDebugLogger("AWSRDSInstance") - } else { - logger = logging.NewSimpleLogger("AWSRDSInstance") - } - } - return &AWSRDSInstanceGatherer{ logger: logger, debug: configuration.Debug, @@ -66,16 +57,16 @@ func (awsrdsinstance *AWSRDSInstanceGatherer) GetMetrics(metrics *models.Metrics awsrdsinstance.logger.Error(err.Error()) } } else { - awsrdsinstance.logger.Println("RDS.DescribeDBInstances SUCCESS") + awsrdsinstance.logger.Info("RDS.DescribeDBInstances SUCCESS") // Request detailed instance info if len(result.DBInstances) == 1 { r := result.DBInstances[0] - awsrdsinstance.logger.Debug("DBInstance ", r.DBInstanceIdentifier) - awsrdsinstance.logger.Debug("DBInstanceClass ", r.DBInstanceClass) - awsrdsinstance.logger.Debug("ProcessorFeatures ", r.ProcessorFeatures) + awsrdsinstance.logger.V(5).Info("DBInstance ", r.DBInstanceIdentifier) + awsrdsinstance.logger.V(5).Info("DBInstanceClass ", r.DBInstanceClass) + awsrdsinstance.logger.V(5).Info("ProcessorFeatures ", r.ProcessorFeatures) // Prepare request to Ec2 to determine CPU count and Ram for InstanceClass instanceName := strings.TrimPrefix(*r.DBInstanceClass, "db.") @@ -96,8 +87,8 @@ func (awsrdsinstance *AWSRDSInstanceGatherer) GetMetrics(metrics *models.Metrics awsrdsinstance.logger.Error(infoerr.Error()) } } else { - awsrdsinstance.logger.Debugf("EC2.DescribeInstanceType SUCCESS") - awsrdsinstance.logger.Debugf("EC2.DescribeInstanceType %v", typeinfo) + awsrdsinstance.logger.V(5).Infof("EC2.DescribeInstanceType SUCCESS") + awsrdsinstance.logger.V(5).Infof("EC2.DescribeInstanceType %v", typeinfo) } if len(typeinfo.InstanceTypes) > 0 { @@ -108,15 +99,15 @@ func (awsrdsinstance *AWSRDSInstanceGatherer) GetMetrics(metrics *models.Metrics info["Host"] = models.MetricGroupValue{"InstanceType": "aws/rds"} } else if len(result.DBInstances) > 1 { - awsrdsinstance.logger.Println("RDS.DescribeDBInstances: Database has %d instances. Clusters are not supported", len(result.DBInstances)) + awsrdsinstance.logger.Infof("RDS.DescribeDBInstances: Database has %d instances. Clusters are not supported", len(result.DBInstances)) } else { - awsrdsinstance.logger.Println("RDS.DescribeDBInstances: No instances") + awsrdsinstance.logger.Info("RDS.DescribeDBInstances: No instances") } } metrics.System.Info = info - awsrdsinstance.logger.Debug("collectMetrics ", metrics.System) + awsrdsinstance.logger.V(5).Info("CollectMetrics awsrdsinstance", info) return nil } diff --git a/metrics/awsrdsenhancedmetrics.go b/metrics/awsrdsenhancedmetrics.go index 5640d00..d273775 100644 --- a/metrics/awsrdsenhancedmetrics.go +++ b/metrics/awsrdsenhancedmetrics.go @@ -10,7 +10,7 @@ import ( "github.com/Releem/mysqlconfigurer/config" "github.com/Releem/mysqlconfigurer/models" "github.com/Releem/mysqlconfigurer/utils" - "github.com/advantageous/go-logback/logging" + logging "github.com/google/logger" "github.com/aws/aws-sdk-go-v2/service/cloudwatchlogs" "github.com/aws/aws-sdk-go-v2/service/rds/types" @@ -184,15 +184,6 @@ func parseOSMetrics(b []byte, disallowUnknownFields bool) (*osMetrics, error) { } func NewAWSRDSEnhancedMetricsGatherer(logger logging.Logger, dbinstance types.DBInstance, cwlogsclient *cloudwatchlogs.Client, configuration *config.Config) *AWSRDSEnhancedMetricsGatherer { - - if logger == nil { - if configuration.Debug { - logger = logging.NewSimpleDebugLogger("AWSEnhancedMetrics") - } else { - logger = logging.NewSimpleLogger("AWSEnhancedMetrics") - } - } - return &AWSRDSEnhancedMetricsGatherer{ logger: logger, debug: configuration.Debug, @@ -218,18 +209,17 @@ func (awsrdsenhancedmetrics *AWSRDSEnhancedMetricsGatherer) GetMetrics(metrics * result, err := awsrdsenhancedmetrics.cwlogsclient.GetLogEvents(context.TODO(), &input) if err != nil { - awsrdsenhancedmetrics.logger.Critical("failed to read log stream %s:%s: %s", rdsMetricsLogGroupName, aws.StringValue(awsrdsenhancedmetrics.dbinstance.DbiResourceId), err) + awsrdsenhancedmetrics.logger.Fatalf("failed to read log stream %s:%s: %s", rdsMetricsLogGroupName, aws.StringValue(awsrdsenhancedmetrics.dbinstance.DbiResourceId), err) return err } - awsrdsenhancedmetrics.logger.Debug("CloudWatchLogs.GetLogEvents SUCCESS") + awsrdsenhancedmetrics.logger.V(5).Info("CloudWatchLogs.GetLogEvents SUCCESS") if len(result.Events) < 1 { - awsrdsenhancedmetrics.logger.Warn("CloudWatchLogs.GetLogEvents No data") + awsrdsenhancedmetrics.logger.Warning("CloudWatchLogs.GetLogEvents No data") return errors.New("CloudWatchLogs.GetLogEvents No data") } - // l.Debugf("Message:\n%s", *event.Message) osMetrics, err := parseOSMetrics([]byte(*result.Events[0].Message), true) if err != nil { @@ -257,22 +247,22 @@ func (awsrdsenhancedmetrics *AWSRDSEnhancedMetricsGatherer) GetMetrics(metrics * // Swap metricsMap["Swap"] = osMetrics.Swap - awsrdsenhancedmetrics.logger.Debug("Swap ", osMetrics.Swap) + awsrdsenhancedmetrics.logger.V(5).Info("Swap ", osMetrics.Swap) //CPU Counts info["CPU"] = models.MetricGroupValue{"Counts": osMetrics.NumVCPUs} // FileSys metricsMap["FileSystem"] = osMetrics.FileSys - awsrdsenhancedmetrics.logger.Debug("FileSystem ", osMetrics.FileSys) + awsrdsenhancedmetrics.logger.V(5).Info("FileSystem ", osMetrics.FileSys) //DiskIO metricsMap["DiskIO"] = osMetrics.DiskIO - awsrdsenhancedmetrics.logger.Debug("DiskIO ", osMetrics.DiskIO) + awsrdsenhancedmetrics.logger.V(5).Info("DiskIO ", osMetrics.DiskIO) // CPU load avarage metricsMap["CPU"] = osMetrics.LoadAverageMinute //StructToMap(Avg.String()) - awsrdsenhancedmetrics.logger.Debug("CPU ", osMetrics.LoadAverageMinute) + awsrdsenhancedmetrics.logger.V(5).Info("CPU ", osMetrics.LoadAverageMinute) info["Host"] = models.MetricGroupValue{ "InstanceType": "aws/rds", @@ -284,8 +274,7 @@ func (awsrdsenhancedmetrics *AWSRDSEnhancedMetricsGatherer) GetMetrics(metrics * metrics.System.Info = info metrics.System.Metrics = metricsMap - awsrdsenhancedmetrics.logger.Debug("collectMetrics ", metrics.System) + awsrdsenhancedmetrics.logger.V(5).Info("CollectMetrics awsrdsenhancedmetrics ", metrics.System) return nil - } diff --git a/metrics/awsrdsmetrics.go b/metrics/awsrdsmetrics.go index 5ef8811..6b19b4b 100644 --- a/metrics/awsrdsmetrics.go +++ b/metrics/awsrdsmetrics.go @@ -8,7 +8,7 @@ import ( "github.com/Releem/mysqlconfigurer/config" "github.com/Releem/mysqlconfigurer/models" "github.com/Releem/mysqlconfigurer/utils" - "github.com/advantageous/go-logback/logging" + logging "github.com/google/logger" "github.com/aws/aws-sdk-go-v2/aws" "github.com/aws/aws-sdk-go-v2/service/cloudwatch" @@ -55,15 +55,6 @@ var rdsMetrics = []rdsMetric{ } func NewAWSRDSMetricsGatherer(logger logging.Logger, cwclient *cloudwatch.Client, configuration *config.Config) *AWSRDSMetricsGatherer { - - if logger == nil { - if configuration.Debug { - logger = logging.NewSimpleDebugLogger("AWSMetrics") - } else { - logger = logging.NewSimpleLogger("AWSMetrics") - } - } - return &AWSRDSMetricsGatherer{ logger: logger, debug: configuration.Debug, @@ -119,24 +110,24 @@ func (awsrdsmetrics *AWSRDSMetricsGatherer) GetMetrics(metrics *models.Metrics) awsrdsmetrics.logger.Error(err.Error()) } } else { - awsrdsmetrics.logger.Println("CloudWatch.GetMetricData SUCCESS") + awsrdsmetrics.logger.Info("CloudWatch.GetMetricData SUCCESS") } // Prepare results for _, r := range result.MetricDataResults { - awsrdsmetrics.logger.Debug("Metric ID ", *r.Id) - awsrdsmetrics.logger.Debug("Metric Label ", *r.Label) + awsrdsmetrics.logger.V(5).Info("Metric ID ", *r.Id) + awsrdsmetrics.logger.V(5).Info("Metric Label ", *r.Label) if len(r.Values) > 0 { output[*r.Label] = fmt.Sprintf("%f", r.Values[0]) - awsrdsmetrics.logger.Debug("Metric Timestamp ", r.Timestamps[0]) + awsrdsmetrics.logger.V(5).Info("Metric Timestamp ", r.Timestamps[0]) } else { - awsrdsmetrics.logger.Debug("CloudWatch.GetMetricData no Values for ", *r.Label) + awsrdsmetrics.logger.V(5).Info("CloudWatch.GetMetricData no Values for ", *r.Label) } } // temperary metrics.System.Metrics = output - awsrdsmetrics.logger.Debug("collectMetrics ", metrics.System.Metrics) + awsrdsmetrics.logger.V(5).Info("CollectMetrics awsrdsmetrics", output) return nil } diff --git a/metrics/dbCollectQueries.go b/metrics/dbCollectQueries.go index 36661db..93f0a1c 100644 --- a/metrics/dbCollectQueries.go +++ b/metrics/dbCollectQueries.go @@ -10,7 +10,7 @@ import ( u "github.com/Releem/mysqlconfigurer/utils" "github.com/Releem/mysqlconfigurer/config" - "github.com/advantageous/go-logback/logging" + logging "github.com/google/logger" ) type DbCollectQueriesOptimization struct { @@ -19,15 +19,6 @@ type DbCollectQueriesOptimization struct { } func NewDbCollectQueriesOptimization(logger logging.Logger, configuration *config.Config) *DbCollectQueriesOptimization { - - if logger == nil { - if configuration.Debug { - logger = logging.NewSimpleDebugLogger("DbCollectQueriesOptimization") - } else { - logger = logging.NewSimpleLogger("DbCollectQueriesOptimization") - } - } - return &DbCollectQueriesOptimization{ logger: logger, configuration: configuration, @@ -384,8 +375,8 @@ func (DbCollectQueriesOptimization *DbCollectQueriesOptimization) GetMetrics(met rows.Close() } - DbCollectQueriesOptimization.logger.Debug("collectMetrics ", metrics.DB.Queries) - DbCollectQueriesOptimization.logger.Debug("collectMetrics ", metrics.DB.QueriesOptimization) + DbCollectQueriesOptimization.logger.V(5).Info("collectMetrics ", metrics.DB.Queries) + DbCollectQueriesOptimization.logger.V(5).Info("collectMetrics ", metrics.DB.QueriesOptimization) return nil @@ -430,13 +421,13 @@ func CollectionExplain(digests map[string]models.MetricGroupValue, field_sorting if (strings.Contains(digests[k]["query_text"].(string), "SELECT") || strings.Contains(digests[k]["query_text"].(string), "select")) && strings.Contains(digests[k]["query_text"].(string), "SQL_NO_CACHE") && !(strings.Contains(digests[k]["query_text"].(string), "WHERE") || strings.Contains(digests[k]["query_text"].(string), "where")) { - logger.Debug("Query From mysqldump", digests[k]["query_text"].(string)) + logger.V(5).Info("Query From mysqldump", digests[k]["query_text"].(string)) continue } if strings.HasSuffix(digests[k]["query_text"].(string), "...") { digests[k]["explain"] = "need_full_query" - logger.Debug("need_full_query") //, digests[k]["query_text"].(string)) + logger.V(5).Info("need_full_query") //, digests[k]["query_text"].(string)) continue } if schema_name_conn != digests[k]["schema_name"].(string) { @@ -451,14 +442,14 @@ func CollectionExplain(digests map[string]models.MetricGroupValue, field_sorting //Try exec EXPLAIN for origin query err := db.QueryRow("EXPLAIN FORMAT=JSON " + digests[k]["query_text"].(string)).Scan(&explain) if err != nil { - logger.PrintError("Explain Error", err) + logger.Error("Explain Error", err) if strings.Contains(err.Error(), "command denied to user") { continue } logger.Error(digests[k]["query_text"].(string)) } else { - logger.Debug(i, "OK") + logger.V(5).Info(i, "OK") digests[k]["explain"] = explain i = i + 1 continue @@ -468,13 +459,13 @@ func CollectionExplain(digests map[string]models.MetricGroupValue, field_sorting query_text = strings.Replace(digests[k]["query_text"].(string), "\"", "'", -1) err_1 := db.QueryRow("EXPLAIN FORMAT=JSON " + query_text).Scan(&explain) if err_1 != nil { - logger.PrintError("Explain Error", err_1) + logger.Error("Explain Error", err_1) if strings.Contains(err_1.Error(), "command denied to user") { continue } logger.Error(query_text) } else { - logger.Debug(i, "OK") + logger.V(5).Info(i, "OK") digests[k]["explain"] = explain i = i + 1 continue @@ -484,14 +475,14 @@ func CollectionExplain(digests map[string]models.MetricGroupValue, field_sorting query_text = strings.Replace(digests[k]["query_text"].(string), "\"", "`", -1) err_2 := db.QueryRow("EXPLAIN FORMAT=JSON " + query_text).Scan(&explain) if err_2 != nil { - logger.PrintError("Explain Error", err_2) + logger.Error("Explain Error", err_2) if strings.Contains(err_2.Error(), "command denied to user") { continue } logger.Error(query_text) } else { - logger.Debug(i, "OK") + logger.V(5).Info(i, "OK") digests[k]["explain"] = explain i = i + 1 continue diff --git a/metrics/dbConf.go b/metrics/dbConf.go index a04fc65..1209959 100644 --- a/metrics/dbConf.go +++ b/metrics/dbConf.go @@ -4,7 +4,7 @@ import ( "github.com/Releem/mysqlconfigurer/config" "github.com/Releem/mysqlconfigurer/models" "github.com/Releem/mysqlconfigurer/utils" - "github.com/advantageous/go-logback/logging" + logging "github.com/google/logger" ) type DbConfGatherer struct { @@ -13,15 +13,6 @@ type DbConfGatherer struct { } func NewDbConfGatherer(logger logging.Logger, configuration *config.Config) *DbConfGatherer { - - if logger == nil { - if configuration.Debug { - logger = logging.NewSimpleDebugLogger("DbConf") - } else { - logger = logging.NewSimpleLogger("DbConf") - } - } - return &DbConfGatherer{ logger: logger, configuration: configuration, @@ -36,7 +27,6 @@ func (DbConf *DbConfGatherer) GetMetrics(metrics *models.Metrics) error { rows, err := models.DB.Query("SHOW VARIABLES") if err != nil { DbConf.logger.Error(err) - DbConf.logger.Debug("collectMetrics ", output) return nil } defer rows.Close() @@ -54,7 +44,6 @@ func (DbConf *DbConfGatherer) GetMetrics(metrics *models.Metrics) error { rows, err = models.DB.Query("SHOW GLOBAL VARIABLES") if err != nil { DbConf.logger.Error(err) - DbConf.logger.Debug("collectMetrics ", output) return nil } defer rows.Close() @@ -67,7 +56,7 @@ func (DbConf *DbConfGatherer) GetMetrics(metrics *models.Metrics) error { output[row.Name] = row.Value } metrics.DB.Conf.Variables = output - DbConf.logger.Debug("collectMetrics ", output) + DbConf.logger.V(5).Info("CollectMetrics DbConf ", output) return nil diff --git a/metrics/dbInfo.go b/metrics/dbInfo.go index 70e4fd0..2cebd8e 100644 --- a/metrics/dbInfo.go +++ b/metrics/dbInfo.go @@ -3,11 +3,12 @@ package metrics import ( "os" "regexp" + "runtime" "github.com/Releem/mysqlconfigurer/config" "github.com/Releem/mysqlconfigurer/models" "github.com/Releem/mysqlconfigurer/utils" - "github.com/advantageous/go-logback/logging" + logging "github.com/google/logger" ) type DbInfoGatherer struct { @@ -16,15 +17,6 @@ type DbInfoGatherer struct { } func NewDbInfoGatherer(logger logging.Logger, configuration *config.Config) *DbInfoGatherer { - - if logger == nil { - if configuration.Debug { - logger = logging.NewSimpleDebugLogger("DbInfo") - } else { - logger = logging.NewSimpleLogger("DbInfo") - } - } - return &DbInfoGatherer{ logger: logger, configuration: configuration, @@ -52,7 +44,7 @@ func (DbInfo *DbInfoGatherer) GetMetrics(metrics *models.Metrics) error { mysql_version = row.Value } info["Version"] = mysql_version - err = os.WriteFile(DbInfo.configuration.ReleemConfDir+"/mysql_version", []byte(mysql_version), 0644) + err = os.WriteFile(DbInfo.configuration.ReleemConfDir+MysqlVersionFile(), []byte(mysql_version), 0644) if err != nil { DbInfo.logger.Error("WriteFile: Error write to file: ", err) } @@ -60,7 +52,15 @@ func (DbInfo *DbInfoGatherer) GetMetrics(metrics *models.Metrics) error { info["MemoryLimit"] = DbInfo.configuration.GetMemoryLimit() metrics.DB.Info = info - DbInfo.logger.Debug("collectMetrics ", metrics.DB.Info) + DbInfo.logger.V(5).Info("CollectMetrics DbInfo ", info) return nil } +func MysqlVersionFile() string { + switch runtime.GOOS { + case "windows": + return "\\MysqlVersion.txt" + default: // для Linux и других UNIX-подобных систем + return "/mysql_version" + } +} diff --git a/metrics/dbMetrics.go b/metrics/dbMetrics.go index 94abc6d..d12ef70 100644 --- a/metrics/dbMetrics.go +++ b/metrics/dbMetrics.go @@ -6,7 +6,7 @@ import ( "github.com/Releem/mysqlconfigurer/config" "github.com/Releem/mysqlconfigurer/models" "github.com/Releem/mysqlconfigurer/utils" - "github.com/advantageous/go-logback/logging" + logging "github.com/google/logger" ) type DbMetricsGatherer struct { @@ -15,15 +15,6 @@ type DbMetricsGatherer struct { } func NewDbMetricsGatherer(logger logging.Logger, configuration *config.Config) *DbMetricsGatherer { - - if logger == nil { - if configuration.Debug { - logger = logging.NewSimpleDebugLogger("DbMetrics") - } else { - logger = logging.NewSimpleLogger("DbMetrics") - } - } - return &DbMetricsGatherer{ logger: logger, configuration: configuration, @@ -105,8 +96,7 @@ func (DbMetrics *DbMetricsGatherer) GetMetrics(metrics *models.Metrics) error { metrics.DB.Metrics.TotalMyisamIndexes = metrics.DB.Metrics.Engine["MyISAM"]["Index Size"].(int) } } - - DbMetrics.logger.Debug("collectMetrics ", metrics.DB.Metrics) + DbMetrics.logger.V(5).Info("CollectMetrics DbMetrics ", metrics.DB.Metrics) return nil } diff --git a/metrics/dbMetricsBase.go b/metrics/dbMetricsBase.go index b441acb..cb93442 100644 --- a/metrics/dbMetricsBase.go +++ b/metrics/dbMetricsBase.go @@ -8,7 +8,7 @@ import ( "github.com/Releem/mysqlconfigurer/config" "github.com/Releem/mysqlconfigurer/models" "github.com/Releem/mysqlconfigurer/utils" - "github.com/advantageous/go-logback/logging" + logging "github.com/google/logger" ) type DbMetricsBaseGatherer struct { @@ -17,15 +17,6 @@ type DbMetricsBaseGatherer struct { } func NewDbMetricsBaseGatherer(logger logging.Logger, configuration *config.Config) *DbMetricsBaseGatherer { - - if logger == nil { - if configuration.Debug { - logger = logging.NewSimpleDebugLogger("DbMetricsBase") - } else { - logger = logging.NewSimpleLogger("DbMetricsBase") - } - } - return &DbMetricsBaseGatherer{ logger: logger, configuration: configuration, @@ -164,7 +155,7 @@ func (DbMetricsBase *DbMetricsBaseGatherer) GetMetrics(metrics *models.Metrics) rows.Close() metrics.DB.Metrics.Databases = output } - DbMetricsBase.logger.Debug("collectMetrics ", metrics.DB.Metrics) + DbMetricsBase.logger.V(5).Info("CollectMetrics DbMetricsBase ", metrics.DB.Metrics) return nil } diff --git a/metrics/os.go b/metrics/os.go index 9fc84e1..f949105 100644 --- a/metrics/os.go +++ b/metrics/os.go @@ -7,7 +7,7 @@ import ( "github.com/Releem/mysqlconfigurer/config" "github.com/Releem/mysqlconfigurer/models" "github.com/Releem/mysqlconfigurer/utils" - "github.com/advantageous/go-logback/logging" + logging "github.com/google/logger" "github.com/shirou/gopsutil/v4/cpu" "github.com/shirou/gopsutil/v4/disk" "github.com/shirou/gopsutil/v4/host" @@ -22,15 +22,6 @@ type OSMetricsGatherer struct { } func NewOSMetricsGatherer(logger logging.Logger, configuration *config.Config) *OSMetricsGatherer { - - if logger == nil { - if configuration.Debug { - logger = logging.NewSimpleDebugLogger("OS") - } else { - logger = logging.NewSimpleLogger("OS") - } - } - return &OSMetricsGatherer{ logger: logger, debug: configuration.Debug, @@ -119,10 +110,13 @@ func (OS *OSMetricsGatherer) GetMetrics(metrics *models.Metrics) error { // OS RAM VirtualMemory, _ := mem.VirtualMemory() - //info["VirtualMemory"] = StructToMap(VirtualMemory.String()) metricsMap["PhysicalMemory"] = StructToMap(VirtualMemory.String()) info["PhysicalMemory"] = models.MetricGroupValue{"total": VirtualMemory.Total} - info["PhysicalMemory"] = utils.MapJoin(info["PhysicalMemory"].(models.MetricGroupValue), models.MetricGroupValue{"swapTotal": VirtualMemory.SwapTotal}) + + // OS SwapMemory + SwapMemory, _ := mem.SwapMemory() + metricsMap["SwapMemory"] = StructToMap(SwapMemory.String()) + info["PhysicalMemory"] = utils.MapJoin(info["PhysicalMemory"].(models.MetricGroupValue), models.MetricGroupValue{"swapTotal": SwapMemory.Total}) //CPU Counts CpuCounts, _ := cpu.Counts(true) @@ -133,10 +127,6 @@ func (OS *OSMetricsGatherer) GetMetrics(metrics *models.Metrics) error { hostInfoMap := utils.MapJoin(StructToMap(hostInfo.String()), models.MetricGroupValue{"InstanceType": "local"}) info["Host"] = hostInfoMap - // IOCounters, _ := disk.IOCounters() - // //info["IOCounters"] = StructToMap(IOCounters.String()) - // OS.logger.Debug("IOCounters ", IOCounters) - //Get partitions, for each pert get usage and io stat var UsageArray, PartitionsArray, IOCountersArray []models.MetricGroupValue var readCount, writeCount uint64 @@ -165,25 +155,25 @@ func (OS *OSMetricsGatherer) GetMetrics(metrics *models.Metrics) error { writeCount = writeCount + IOCounters[PartName].WriteCount PartitionCheck[part.Device] = 1 } - OS.logger.Debug("IOCounters ", IOCounters) + OS.logger.V(5).Info("IOCounters ", IOCounters) IOCountersArray = append(IOCountersArray, models.MetricGroupValue{PartName: StructToMap(IOCounters[PartName].String())}) } } - OS.logger.Debug("PartitionCheck ", PartitionCheck) + OS.logger.V(5).Info("PartitionCheck ", PartitionCheck) info["Partitions"] = PartitionsArray - OS.logger.Debug("Partitions ", PartitionsArray) + OS.logger.V(5).Info("Partitions ", PartitionsArray) // info["Usage"] = UsageArray metricsMap["FileSystem"] = UsageArray - OS.logger.Debug("Usage ", UsageArray) + OS.logger.V(5).Info("Usage ", UsageArray) metricsMap["DiskIO"] = IOCountersArray - OS.logger.Debug("IOCountersArray ", IOCountersArray) + OS.logger.V(5).Info("IOCountersArray ", IOCountersArray) // CPU load avarage Avg, _ := load.Avg() metricsMap["CPU"] = StructToMap(Avg.String()) - OS.logger.Debug("Avg ", Avg) + OS.logger.V(5).Info("Avg ", Avg) // CpuUtilisation := float64(metrics.System.Metrics.CPU["load1"].(float64) / float64(info["CPU"].(models.MetricGroupValue)["Counts"].(int))) // metrics.System.Metrics.CPU["CpuUtilisation"] = CpuUtilisation @@ -194,7 +184,7 @@ func (OS *OSMetricsGatherer) GetMetrics(metrics *models.Metrics) error { metrics.System.Info = info metrics.System.Metrics = metricsMap - OS.logger.Debug("collectMetrics ", metrics.System) + OS.logger.V(5).Info("CollectMetrics OS ", metrics.System) return nil } diff --git a/metrics/runner.go b/metrics/runner.go index 36f0d6b..115449c 100644 --- a/metrics/runner.go +++ b/metrics/runner.go @@ -11,7 +11,7 @@ import ( "github.com/Releem/mysqlconfigurer/models" "github.com/Releem/mysqlconfigurer/tasks" "github.com/Releem/mysqlconfigurer/utils" - "github.com/advantageous/go-logback/logging" + logging "github.com/google/logger" ) var Ready bool @@ -26,16 +26,9 @@ func makeTerminateChannel() <-chan os.Signal { } func RunWorker(gatherers []models.MetricsGatherer, gatherers_configuration []models.MetricsGatherer, gatherers_query_optimization []models.MetricsGatherer, repeaters models.MetricsRepeater, logger logging.Logger, - configuration *config.Config, configFile string, Mode models.ModeType) { + configuration *config.Config, Mode models.ModeType) { var GenerateTimer, timer, QueryOptimizationTimer *time.Timer defer utils.HandlePanic(configuration, logger) - if logger == nil { - if configuration.Debug { - logger = logging.NewSimpleDebugLogger("Worker") - } else { - logger = logging.NewSimpleLogger("Worker") - } - } if (Mode.Name == "Configurations" && Mode.Type != "default") || Mode.Name == "Event" || Mode.Name == "TaskSet" { GenerateTimer = time.NewTimer(0 * time.Second) @@ -44,7 +37,7 @@ func RunWorker(gatherers []models.MetricsGatherer, gatherers_configuration []mod GenerateTimer = time.NewTimer(configuration.GenerateConfigPeriod * time.Second) timer = time.NewTimer(1 * time.Second) } - QueryOptimizationTimer = time.NewTimer(60 * time.Second) + QueryOptimizationTimer = time.NewTimer(5 * time.Minute) QueryOptimizationCollectSqlText := time.NewTimer(1 * time.Second) models.SqlText = make(map[string]map[string]string) models.SqlTextMutex = sync.RWMutex{} @@ -54,13 +47,15 @@ func RunWorker(gatherers []models.MetricsGatherer, gatherers_configuration []mod QueryOptimizationCollectSqlText.Stop() } terminator := makeTerminateChannel() + +loop: for { select { case <-terminator: logger.Info("Exiting") - os.Exit(0) + break loop case <-timer.C: - logger.Println("Starting collection of data for saving a metrics...") + logger.Info("Starting collection of data for saving a metrics...") timer.Reset(configuration.MetricsPeriod * time.Second) go func() { defer utils.HandlePanic(configuration, logger) @@ -68,7 +63,7 @@ func RunWorker(gatherers []models.MetricsGatherer, gatherers_configuration []mod if metrics != nil { task := utils.ProcessRepeaters(metrics, repeaters, configuration, logger, models.ModeType{Name: "Metrics", Type: ""}) if task == "Task" { - logger.Println(" * A task has been found for the agent...") + logger.Info(" * A task has been found for the agent...") f := tasks.ProcessTaskFunc(metrics, repeaters, gatherers, logger, configuration) time.AfterFunc(5*time.Second, f) } @@ -76,15 +71,15 @@ func RunWorker(gatherers []models.MetricsGatherer, gatherers_configuration []mod utils.EnableEventsStatementsConsumers(configuration, logger, metrics.DB.Metrics.Status["Uptime"].(string)) } } - logger.Println("Saved a metrics...") + logger.Info("Saved a metrics...") }() - logger.Println("End collection of metrics for saving a metrics...") + logger.Info("End collection of metrics for saving a metrics...") case <-GenerateTimer.C: - logger.Println("Starting collection of data for generating a config...") + logger.Info("Starting collection of data for generating a config...") GenerateTimer.Reset(configuration.GenerateConfigPeriod * time.Second) go func() { var metrics *models.Metrics - logger.Println(" * Collecting metrics to recommend a config...") + logger.Info(" * Collecting metrics to recommend a config...") defer utils.HandlePanic(configuration, logger) if Mode.Name == "TaskSet" && Mode.Type == "queries_optimization" { metrics = utils.CollectMetrics(append(gatherers, gatherers_query_optimization...), logger, configuration) @@ -92,10 +87,10 @@ func RunWorker(gatherers []models.MetricsGatherer, gatherers_configuration []mod metrics = utils.CollectMetrics(append(gatherers, gatherers_configuration...), logger, configuration) } if metrics != nil { - logger.Println(" * Sending metrics to Releem Cloud Platform...") + logger.Info(" * Sending metrics to Releem Cloud Platform...") utils.ProcessRepeaters(metrics, repeaters, configuration, logger, Mode) if Mode.Name == "Configurations" { - logger.Println("Recommended MySQL configuration downloaded to ", configuration.GetReleemConfDir()) + logger.Info("Recommended MySQL configuration downloaded to ", configuration.GetReleemConfDir()) } if configuration.QueryOptimization && configuration.InstanceType == "aws/rds" { utils.EnableEventsStatementsConsumers(configuration, logger, "0") @@ -105,20 +100,20 @@ func RunWorker(gatherers []models.MetricsGatherer, gatherers_configuration []mod logger.Info("Exiting") os.Exit(0) } - logger.Println("Saved a config...") + logger.Info("Saved a config...") }() - logger.Println("End collection of metrics for saving a metrics...") + logger.Info("End collection of metrics for saving a metrics...") case <-QueryOptimizationTimer.C: - logger.Println("Starting collection of data for queries optimization...") + logger.Info("Starting collection of data for queries optimization...") QueryOptimizationTimer.Reset(configuration.QueryOptimizationPeriod * time.Second) go func() { defer utils.HandlePanic(configuration, logger) - logger.Println("QueryOptimization") + logger.Info("QueryOptimization") metrics := utils.CollectMetrics(append(gatherers, gatherers_query_optimization...), logger, configuration) if metrics != nil { utils.ProcessRepeaters(metrics, repeaters, configuration, logger, models.ModeType{Name: "Metrics", Type: "QueryOptimization"}) } - logger.Println("Saved a queries...") + logger.Info("Saved a queries...") }() case <-QueryOptimizationCollectSqlText.C: QueryOptimizationCollectSqlText.Reset(configuration.QueryOptimizationCollectSqlTextPeriod * time.Second) diff --git a/repeater/logger.go b/repeater/logger.go index ae3e48e..dedf6e5 100644 --- a/repeater/logger.go +++ b/repeater/logger.go @@ -1,22 +1,27 @@ package repeater import ( + "io" + "log" + "github.com/Releem/mysqlconfigurer/models" - lg "github.com/advantageous/go-logback/logging" + logging "github.com/google/logger" ) type LogMetricsRepeater struct { - logger lg.Logger + logger logging.Logger } func (lr LogMetricsRepeater) ProcessMetrics(metrics models.Metric) error { for _, m := range metrics { - lr.logger.Printf("%s", m) + lr.logger.Infof("%s", m) } return nil } func NewLogMetricsRepeater() LogMetricsRepeater { - logger := lg.NewSimpleLogger("log-repeater") + logger := *logging.Init("releem-agent", true, false, io.Discard) + defer logger.Close() + logging.SetFlags(log.LstdFlags | log.Lshortfile) return LogMetricsRepeater{logger} } diff --git a/repeater/releemConfiguration.go b/repeater/releemConfiguration.go index 5eadff9..d51d006 100644 --- a/repeater/releemConfiguration.go +++ b/repeater/releemConfiguration.go @@ -10,7 +10,7 @@ import ( "github.com/Releem/mysqlconfigurer/config" "github.com/Releem/mysqlconfigurer/models" "github.com/Releem/mysqlconfigurer/utils" - "github.com/advantageous/go-logback/logging" + logging "github.com/google/logger" "time" ) @@ -22,13 +22,13 @@ type ReleemConfigurationsRepeater struct { func (repeater ReleemConfigurationsRepeater) ProcessMetrics(context models.MetricContext, metrics models.Metrics, Mode models.ModeType) (interface{}, error) { defer utils.HandlePanic(repeater.configuration, repeater.logger) - repeater.logger.Debug(Mode.Name, Mode.Type) + repeater.logger.V(5).Info(Mode.Name, Mode.Type) var buffer bytes.Buffer encoder := json.NewEncoder(&buffer) if err := encoder.Encode(metrics); err != nil { repeater.logger.Error("Failed to encode metrics: ", err) } - repeater.logger.Debug("Result Send data: ", buffer.String()) + repeater.logger.V(5).Info("Result Send data: ", buffer.String()) var api_domain, subdomain string env := context.GetEnv() @@ -71,7 +71,7 @@ func (repeater ReleemConfigurationsRepeater) ProcessMetrics(context models.Metri } else if Mode.Name == "TaskStatus" { api_domain = api_domain + "task/task_status" } - repeater.logger.Debug(api_domain) + repeater.logger.V(5).Info(api_domain) req, err := http.NewRequest(http.MethodPost, api_domain, &buffer) if err != nil { @@ -99,8 +99,8 @@ func (repeater ReleemConfigurationsRepeater) ProcessMetrics(context models.Metri repeater.logger.Error("Response: status code: ", res.StatusCode) repeater.logger.Error("Response: body:\n", string(body_res)) } else { - repeater.logger.Debug("Response: status code: ", res.StatusCode) - repeater.logger.Debug("Response: body:\n", string(body_res)) + repeater.logger.V(5).Info("Response: status code: ", res.StatusCode) + repeater.logger.V(5).Info("Response: body:\n", string(body_res)) if Mode.Name == "Configurations" { err = os.WriteFile(context.GetReleemConfDir()+"/z_aiops_mysql.cnf", body_res, 0644) @@ -127,12 +127,6 @@ func (repeater ReleemConfigurationsRepeater) ProcessMetrics(context models.Metri return nil, err } -func NewReleemConfigurationsRepeater(configuration *config.Config) ReleemConfigurationsRepeater { - var logger logging.Logger - if configuration.Debug { - logger = logging.NewSimpleDebugLogger("ReleemRepeaterConfigurations") - } else { - logger = logging.NewSimpleLogger("ReleemRepeaterConfigurations") - } +func NewReleemConfigurationsRepeater(configuration *config.Config, logger logging.Logger) ReleemConfigurationsRepeater { return ReleemConfigurationsRepeater{logger, configuration} } diff --git a/tasks/tasks.go b/tasks/tasks.go index 0634bc1..fbcb326 100644 --- a/tasks/tasks.go +++ b/tasks/tasks.go @@ -5,6 +5,7 @@ import ( "context" "encoding/json" "os/exec" + "runtime" "strconv" "strings" "time" @@ -12,10 +13,10 @@ import ( "github.com/Releem/mysqlconfigurer/config" "github.com/Releem/mysqlconfigurer/models" "github.com/Releem/mysqlconfigurer/utils" - "github.com/advantageous/go-logback/logging" "github.com/aws/aws-sdk-go-v2/service/rds" "github.com/aws/aws-sdk-go-v2/service/rds/types" "github.com/aws/aws-sdk-go/aws" + logging "github.com/google/logger" config_aws "github.com/aws/aws-sdk-go-v2/config" ) @@ -47,7 +48,7 @@ func ProcessTask(metrics *models.Metrics, repeaters models.MetricsRepeater, gath metrics.ReleemAgent.Tasks = output utils.ProcessRepeaters(metrics, repeaters, configuration, logger, models.ModeType{Name: "TaskStatus", Type: ""}) - logger.Println(" * Task with id -", TaskID, "and type id -", TaskTypeID, "is being started...") + logger.Info(" * Task with id - ", TaskID, " and type id - ", TaskTypeID, " is being started...") if TaskTypeID == 0 { output["task_exit_code"], output["task_status"], task_output = execCmd(configuration.ReleemDir+"/mysqlconfigurer.sh -a", []string{"RELEEM_RESTART_SERVICE=1"}, logger) @@ -72,7 +73,7 @@ func ProcessTask(metrics *models.Metrics, repeaters models.MetricsRepeater, gath rollback_exit_code = 0 } output["task_output"] = output["task_output"].(string) + stdout.String() + stderr.String() - logger.Println(" * Task rollbacked with code", rollback_exit_code) + logger.Info(" * Task rollbacked with code ", rollback_exit_code) } } else if TaskTypeID == 1 { @@ -93,8 +94,15 @@ func ProcessTask(metrics *models.Metrics, repeaters models.MetricsRepeater, gath output["task_output"] = output["task_output"].(string) + task_output } } else { - output["task_exit_code"], output["task_status"], task_output = execCmd(configuration.ReleemDir+"/mysqlconfigurer.sh -s automatic", []string{"RELEEM_RESTART_SERVICE=0"}, logger) - output["task_output"] = output["task_output"].(string) + task_output + switch runtime.GOOS { + case "windows": + output["task_exit_code"] = 0 + output["task_status"] = 1 + output["task_output"] = output["task_output"].(string) + "Windows is not supported apply configuration.\n" + default: // для Linux и других UNIX-подобных систем + output["task_exit_code"], output["task_status"], task_output = execCmd(configuration.ReleemDir+"/mysqlconfigurer.sh -s automatic", []string{"RELEEM_RESTART_SERVICE=0"}, logger) + output["task_output"] = output["task_output"].(string) + task_output + } if output["task_exit_code"] == 0 { output["task_exit_code"], output["task_status"], task_output = ApplyConfLocal(metrics, repeaters, gatherers, logger, configuration) @@ -128,12 +136,11 @@ func ProcessTask(metrics *models.Metrics, repeaters models.MetricsRepeater, gath rollback_exit_code = 0 } output["task_output"] = output["task_output"].(string) + stdout.String() + stderr.String() - logger.Println(" * Task rollbacked with code", rollback_exit_code) + logger.Info(" * Task rollbacked with code ", rollback_exit_code) } } } - logger.Debug(output) - logger.Println(" * Task with id -", TaskID, "and type id -", TaskTypeID, "completed with code", output["task_exit_code"]) + logger.Info(" * Task with id - ", TaskID, " and type id - ", TaskTypeID, " completed with code ", output["task_exit_code"]) metrics.ReleemAgent.Tasks = output utils.ProcessRepeaters(metrics, repeaters, configuration, logger, models.ModeType{Name: "TaskStatus", Type: ""}) @@ -186,7 +193,7 @@ func ApplyConfLocal(metrics *models.Metrics, repeaters models.MetricsRepeater, g } for key := range result_data { - logger.Println(key, result_data[key], metrics.DB.Conf.Variables[key]) + logger.Info(key, result_data[key], metrics.DB.Conf.Variables[key]) if result_data[key] != metrics.DB.Conf.Variables[key] { query_set_var := "set global " + key + "=" + result_data[key].(string) @@ -206,7 +213,7 @@ func ApplyConfLocal(metrics *models.Metrics, repeaters models.MetricsRepeater, g } } } - logger.Println(need_flush, need_restart, need_privileges, error_exist) + logger.Info(need_flush, need_restart, need_privileges, error_exist) if error_exist { task_exit_code = 8 task_status = 4 @@ -260,7 +267,7 @@ func ApplyConfAwsRds(repeaters models.MetricsRepeater, gatherers []models.Metric logger.Errorf("Load AWS configuration FAILED, %v", err) task_output = task_output + err.Error() } else { - logger.Println("AWS configuration loaded SUCCESS") + logger.Info("AWS configuration loaded SUCCESS") } // Создайте клиент RDS @@ -284,7 +291,7 @@ func ApplyConfAwsRds(repeaters models.MetricsRepeater, gatherers []models.Metric logger.Error("No DB instance found.") task_output = task_output + "No DB instance found.\n" } - logger.Printf("DB Instance ID: %s, DB Instance Status: %s, Parameter Group Name: %s, Parameter Group Status: %s\n", *dbInstance.DBInstanceIdentifier, *dbInstance.DBInstanceStatus, *paramGroup.DBParameterGroupName, *paramGroup.ParameterApplyStatus) + logger.Infof("DB Instance ID: %s, DB Instance Status: %s, Parameter Group Name: %s, Parameter Group Status: %s\n", *dbInstance.DBInstanceIdentifier, *dbInstance.DBInstanceStatus, *paramGroup.DBParameterGroupName, *paramGroup.ParameterApplyStatus) if aws.StringValue(dbInstance.DBInstanceStatus) != "available" { logger.Error("DB Instance Status '" + aws.StringValue(dbInstance.DBInstanceStatus) + "' not available(" + aws.StringValue(dbInstance.DBInstanceStatus) + ")") task_output = task_output + "DB Instance Status '" + aws.StringValue(dbInstance.DBInstanceStatus) + "' not available\n" @@ -337,7 +344,7 @@ func ApplyConfAwsRds(repeaters models.MetricsRepeater, gatherers []models.Metric var value string for key := range result_data { if result_data[key] != metrics.DB.Conf.Variables[key] { - logger.Println(key, result_data[key], metrics.DB.Conf.Variables[key]) + logger.Info(key, result_data[key], metrics.DB.Conf.Variables[key]) if key == "innodb_max_dirty_pages_pct" { i, err := strconv.ParseFloat(result_data[key].(string), 32) if err != nil { @@ -382,7 +389,7 @@ func ApplyConfAwsRds(repeaters models.MetricsRepeater, gatherers []models.Metric task_output = task_output + err.Error() return task_exit_code, task_status, task_output } else { - logger.Println("Parameter group modified successfully") + logger.Info("Parameter group modified successfully") } Parameters = []types.Parameter{} } @@ -408,7 +415,7 @@ func ApplyConfAwsRds(repeaters models.MetricsRepeater, gatherers []models.Metric task_output = task_output + err.Error() return task_exit_code, task_status, task_output } else { - logger.Println("Parameter group modified successfully") + logger.Info("Parameter group modified successfully") } } time.Sleep(15 * time.Second) @@ -432,7 +439,7 @@ func ApplyConfAwsRds(repeaters models.MetricsRepeater, gatherers []models.Metric logger.Error("No DB instance found.") task_output = task_output + "No DB instance found.\n" } - logger.Printf("DB Instance ID: %s, DB Instance Status: %s, Parameter Group Name: %s, Parameter Group Status: %s\n", *dbInstance.DBInstanceIdentifier, *dbInstance.DBInstanceStatus, *paramGroup.DBParameterGroupName, *paramGroup.ParameterApplyStatus) + logger.Infof("DB Instance ID: %s, DB Instance Status: %s, Parameter Group Name: %s, Parameter Group Status: %s\n", *dbInstance.DBInstanceIdentifier, *dbInstance.DBInstanceStatus, *paramGroup.DBParameterGroupName, *paramGroup.ParameterApplyStatus) if aws.StringValue(dbInstance.DBInstanceStatus) != "modifying" || aws.StringValue(paramGroup.ParameterApplyStatus) != "applying" { break @@ -448,7 +455,7 @@ func ApplyConfAwsRds(repeaters models.MetricsRepeater, gatherers []models.Metric task_exit_code = 10 task_status = 4 } else if aws.StringValue(dbInstance.DBInstanceStatus) == "available" && aws.StringValue(paramGroup.ParameterApplyStatus) == "in-sync" { - logger.Println("DB Instance Status available, Parameter Group Status in-sync, No pending modifications") + logger.Info("DB Instance Status available, Parameter Group Status in-sync, No pending modifications") } else { task_exit_code = 7 task_status = 4 diff --git a/utils/utils.go b/utils/utils.go index faf2a5f..421ea2a 100644 --- a/utils/utils.go +++ b/utils/utils.go @@ -10,8 +10,8 @@ import ( "github.com/Releem/mysqlconfigurer/config" e "github.com/Releem/mysqlconfigurer/errors" "github.com/Releem/mysqlconfigurer/models" - "github.com/advantageous/go-logback/logging" _ "github.com/go-sql-driver/mysql" + logging "github.com/google/logger" "github.com/pkg/errors" ) @@ -21,7 +21,7 @@ func ProcessRepeaters(metrics *models.Metrics, repeaters models.MetricsRepeater, result, err := repeaters.ProcessMetrics(configuration, *metrics, Mode) if err != nil { - logger.PrintError("Repeater failed", err) + logger.Error("Repeater failed", err) } return result } @@ -42,8 +42,8 @@ func CollectMetrics(gatherers []models.MetricsGatherer, logger logging.Logger, c func HandlePanic(configuration *config.Config, logger logging.Logger) { if r := recover(); r != nil { err := errors.WithStack(fmt.Errorf("%v", r)) - logger.Printf("%+v", err) - sender := e.NewReleemErrorsRepeater(configuration) + logger.Infof("%+v", err) + sender := e.NewReleemErrorsRepeater(configuration, logger) sender.ProcessErrors(fmt.Sprintf("%+v", err)) } } @@ -83,17 +83,17 @@ func ConnectionDatabase(configuration *config.Config, logger logging.Logger, DBn TypeConnection = "tcp" } if err != nil { - logger.PrintError("Connection opening to failed", err) + logger.Error("Connection opening to failed", err) } err = db.Ping() if err != nil { - logger.PrintError("Connection failed", err) + logger.Error("Connection failed", err) } else { if TypeConnection == "unix" { - logger.Println("Connect Success to DB ", DBname, " via unix socket", configuration.MysqlHost) + logger.Info("Connect Success to DB ", DBname, " via unix socket ", configuration.MysqlHost) } else if TypeConnection == "tcp" { - logger.Println("Connect Success to DB ", DBname, " via tcp", configuration.MysqlHost) + logger.Info("Connect Success to DB ", DBname, " via tcp ", configuration.MysqlHost) } } return db @@ -110,13 +110,13 @@ func EnableEventsStatementsConsumers(configuration *config.Config, logger loggin if err != nil { logger.Error(err) } - logger.Println("Found enabled performance_schema statements consumers: ", count_setup_consumers) + logger.Info("Found enabled performance_schema statements consumers: ", count_setup_consumers) if count_setup_consumers < 3 { _, err := models.DB.Query("CALL releem.enable_events_statements_consumers()") if err != nil { logger.Error("Failed to enable events_statements consumers", err) } else { - logger.Println("Enable events_statements_consumers") + logger.Info("Enable events_statements_consumers") } } }