From 78b41d9911486369f5212a36f93b160e64f7e49e Mon Sep 17 00:00:00 2001 From: hippo-an Date: Wed, 13 Nov 2024 16:36:57 +0900 Subject: [PATCH 1/6] update validation for perf eval execution --- internal/app/evaluate_performance_handler.go | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/internal/app/evaluate_performance_handler.go b/internal/app/evaluate_performance_handler.go index 05745ec..6bfbfa9 100644 --- a/internal/app/evaluate_performance_handler.go +++ b/internal/app/evaluate_performance_handler.go @@ -183,24 +183,24 @@ func (s *AntServer) runLoadTest(c echo.Context) error { req.TestName = uuid.New().String() } - if _, err := strconv.Atoi(strings.TrimSpace(req.VirtualUsers)); err != nil { + if v, err := strconv.Atoi(strings.TrimSpace(req.VirtualUsers)); err != nil && (v < 1 || v > 100) { log.Error().Msgf("virtual user count is invalid") - return errorResponseJson(http.StatusBadRequest, "virtual user is not correct. check and retry.") + return errorResponseJson(http.StatusBadRequest, "virtual user is not correct. the range must be in 1 to 100") } - if _, err := strconv.Atoi(strings.TrimSpace(req.Duration)); err != nil { + if v, err := strconv.Atoi(strings.TrimSpace(req.Duration)); err != nil && (v < 1 || v > 300) { log.Error().Msgf("duration is invalid") - return errorResponseJson(http.StatusBadRequest, "duration is not correct. check and retry.") + return errorResponseJson(http.StatusBadRequest, "duration is not correct. the range must be in 1 to 300") } - if _, err := strconv.Atoi(strings.TrimSpace(req.RampUpTime)); err != nil { + if v, err := strconv.Atoi(strings.TrimSpace(req.RampUpTime)); err != nil && (v < 1 || v > 60) { log.Error().Msgf("ramp up time is invalid") - return errorResponseJson(http.StatusBadRequest, "ramp up time is not correct. check and retry.") + return errorResponseJson(http.StatusBadRequest, "ramp up time is not correct. the range must be in 1 to 60") } - if _, err := strconv.Atoi(strings.TrimSpace(req.RampUpSteps)); err != nil { + if v, err := strconv.Atoi(strings.TrimSpace(req.RampUpSteps)); err != nil && (v < 1 || v > 20) { log.Error().Msgf("ramp up steps is invalid") - return errorResponseJson(http.StatusBadRequest, "ramp up steps is not correct. check and retry.") + return errorResponseJson(http.StatusBadRequest, "ramp up steps is not correct. the range must be in 1 to 20") } if len(req.HttpReqs) == 0 { From 2795400afd02d214282b71e542a6c67b65c66a9d Mon Sep 17 00:00:00 2001 From: hippo-an Date: Wed, 13 Nov 2024 17:21:34 +0900 Subject: [PATCH 2/6] update icon code for execution state result --- internal/core/common/constant/constant.go | 7 +++++++ internal/core/load/dtos.go | 1 + .../core/load/performace_evaluation_service.go | 16 +++++++++++++++- 3 files changed, 23 insertions(+), 1 deletion(-) diff --git a/internal/core/common/constant/constant.go b/internal/core/common/constant/constant.go index a72aa24..75d98bf 100644 --- a/internal/core/common/constant/constant.go +++ b/internal/core/common/constant/constant.go @@ -119,3 +119,10 @@ const ( Asc OrderType = "asc" Desc OrderType = "desc" ) + +type IconCode string +const ( + Ok IconCode = "IC0001" + Fail IconCode = "IC0002" + Pending IconCode = "IC0003" +) diff --git a/internal/core/load/dtos.go b/internal/core/load/dtos.go index 30b67af..1dad1bd 100644 --- a/internal/core/load/dtos.go +++ b/internal/core/load/dtos.go @@ -149,6 +149,7 @@ type LoadTestExecutionStateResult struct { ExecutionStatus constant.ExecutionStatus `json:"executionStatus,omitempty"` StartAt time.Time `json:"startAt,omitempty"` FinishAt *time.Time `json:"finishAt,omitempty"` + IconCode constant.IconCode `json:"iconCode"` TotalExpectedExcutionSecond uint64 `json:"totalExpectedExecutionSecond,omitempty"` FailureMessage string `json:"failureMessage,omitempty"` CompileDuration string `json:"compileDuration,omitempty"` diff --git a/internal/core/load/performace_evaluation_service.go b/internal/core/load/performace_evaluation_service.go index 6bef8df..5ba43de 100644 --- a/internal/core/load/performace_evaluation_service.go +++ b/internal/core/load/performace_evaluation_service.go @@ -4,6 +4,7 @@ import ( "context" "time" + "github.com/cloud-barista/cm-ant/internal/core/common/constant" "github.com/cloud-barista/cm-ant/internal/infra/outbound/tumblebug" "github.com/cloud-barista/cm-ant/internal/utils" ) @@ -145,7 +146,7 @@ func mapLoadTestExecutionHttpInfoResult(h LoadTestExecutionHttpInfo) LoadTestExe } func mapLoadTestExecutionStateResult(state LoadTestExecutionState) LoadTestExecutionStateResult { - return LoadTestExecutionStateResult{ + stateResult := &LoadTestExecutionStateResult{ ID: state.ID, LoadTestKey: state.LoadTestKey, ExecutionStatus: state.ExecutionStatus, @@ -158,6 +159,19 @@ func mapLoadTestExecutionStateResult(state LoadTestExecutionState) LoadTestExecu CreatedAt: state.CreatedAt, UpdatedAt: state.UpdatedAt, } + + + if stateResult.ExecutionStatus == constant.Successed { + stateResult.IconCode = constant.Ok + } else if stateResult.ExecutionStatus == constant.TestFailed { + stateResult.IconCode = constant.Fail + } else { + stateResult.IconCode = constant.Pending + } + + return *stateResult + + } func mapLoadGeneratorServerResult(s LoadGeneratorServer) LoadGeneratorServerResult { From c95b0d27ae2a10693703c406b5c0f819b3a2e92f Mon Sep 17 00:00:00 2001 From: hippo-an Date: Thu, 14 Nov 2024 13:57:29 +0900 Subject: [PATCH 3/6] - update model relations for load test execution state and load test execution info - update load generator installation process in async process --- internal/core/load/dtos.go | 1 + .../load/load_generator_install_service.go | 8 +- .../core/load/load_test_execution_service.go | 236 ++++++++++++++---- internal/core/load/models.go | 10 +- .../load/performace_evaluation_service.go | 5 +- internal/core/load/repository.go | 25 +- internal/infra/db/db.go | 36 +-- 7 files changed, 232 insertions(+), 89 deletions(-) diff --git a/internal/core/load/dtos.go b/internal/core/load/dtos.go index 1dad1bd..9e69130 100644 --- a/internal/core/load/dtos.go +++ b/internal/core/load/dtos.go @@ -149,6 +149,7 @@ type LoadTestExecutionStateResult struct { ExecutionStatus constant.ExecutionStatus `json:"executionStatus,omitempty"` StartAt time.Time `json:"startAt,omitempty"` FinishAt *time.Time `json:"finishAt,omitempty"` + ExpectedFinishAt time.Time `json:"expectedFinishAt,omitempty"` IconCode constant.IconCode `json:"iconCode"` TotalExpectedExcutionSecond uint64 `json:"totalExpectedExecutionSecond,omitempty"` FailureMessage string `json:"failureMessage,omitempty"` diff --git a/internal/core/load/load_generator_install_service.go b/internal/core/load/load_generator_install_service.go index 4b2da09..848ec56 100644 --- a/internal/core/load/load_generator_install_service.go +++ b/internal/core/load/load_generator_install_service.go @@ -4,13 +4,13 @@ import ( "context" "errors" "fmt" - "log" "time" "github.com/cloud-barista/cm-ant/internal/config" "github.com/cloud-barista/cm-ant/internal/core/common/constant" "github.com/cloud-barista/cm-ant/internal/infra/outbound/tumblebug" "github.com/cloud-barista/cm-ant/internal/utils" + "github.com/rs/zerolog/log" "gorm.io/gorm" ) @@ -40,7 +40,7 @@ const ( // InstallLoadGenerator installs the load generator either locally or remotely. // Currently remote request is executing via cb-tumblebug. func (l *LoadService) InstallLoadGenerator(param InstallLoadGeneratorParam) (LoadGeneratorInstallInfoResult, error) { - utils.LogInfo("Starting InstallLoadGenerator") + log.Info().Msg("Starting InstallLoadGenerator") ctx, cancel := context.WithTimeout(context.Background(), 5*time.Minute) defer cancel() @@ -56,10 +56,10 @@ func (l *LoadService) InstallLoadGenerator(param InstallLoadGeneratorParam) (Loa err := l.loadRepo.GetOrInsertLoadGeneratorInstallInfoTx(ctx, loadGeneratorInstallInfo) if err != nil { - utils.LogError("Failed to insert LoadGeneratorInstallInfo:", err) + log.Error().Msgf("Failed to insert LoadGeneratorInstallInfo; %v", err) return result, err } - utils.LogInfo("LoadGeneratorInstallInfo fetched successfully") + log.Info().Msg("LoadGeneratorInstallInfo fetched successfully") defer func() { if loadGeneratorInstallInfo.Status == "starting" { diff --git a/internal/core/load/load_test_execution_service.go b/internal/core/load/load_test_execution_service.go index 2254419..52c3c81 100644 --- a/internal/core/load/load_test_execution_service.go +++ b/internal/core/load/load_test_execution_service.go @@ -20,49 +20,23 @@ import ( // Generates a load test key, installs the load generator or retrieves existing installation information, // saves the load test execution state, and then asynchronously runs the load test. func (l *LoadService) RunLoadTest(param RunLoadTestParam) (string, error) { - ctx, cancel := context.WithTimeout(context.Background(), 3*time.Minute) + ctx, cancel := context.WithTimeout(context.Background(), 10*time.Minute) defer cancel() - + loadTestKey := utils.CreateUniqIdBaseOnUnixTime() param.LoadTestKey = loadTestKey log.Info().Msgf("Starting load test with key: %s", loadTestKey) - // check the installation of load generator. - // if it is not installed, then install it to user selected location. - if param.LoadGeneratorInstallInfoId == uint(0) { - log.Info().Msgf("No LoadGeneratorInstallInfoId provided, installing load generator...") - result, err := l.InstallLoadGenerator(param.InstallLoadGenerator) - if err != nil { - log.Error().Msgf("Error installing load generator: %v", err) - return "", err - } - - param.LoadGeneratorInstallInfoId = result.ID - log.Info().Msgf("Load generator installed with ID: %d", result.ID) - } - - if param.LoadGeneratorInstallInfoId == uint(0) { - log.Error().Msgf("LoadGeneratorInstallInfoId is still 0 after installation.") - return "", errors.New("error while load generator installation process") - } - - loadGeneratorInstallInfo, err := l.loadRepo.GetValidLoadGeneratorInstallInfoByIdTx(ctx, param.LoadGeneratorInstallInfoId) - if err != nil { - log.Error().Msgf("Error retrieving load generator installation info: %v", err) - return "", err - } - - log.Info().Msgf("Retrieved load generator installation info with ID: %d", param.LoadGeneratorInstallInfoId) - duration, err := strconv.Atoi(param.Duration) if err != nil { - return "", err + log.Error().Msgf("error while type convert; %s", err.Error()) + return loadTestKey, err } rampUpTime, err := strconv.Atoi(param.RampUpTime) if err != nil { - return "", err + return loadTestKey, err } totalExecutionSecond := uint64(duration + rampUpTime) @@ -70,7 +44,6 @@ func (l *LoadService) RunLoadTest(param RunLoadTestParam) (string, error) { e := startAt.Add(time.Duration(totalExecutionSecond) * time.Second) stateArg := LoadTestExecutionState{ - LoadGeneratorInstallInfoId: loadGeneratorInstallInfo.ID, LoadTestKey: loadTestKey, ExecutionStatus: constant.OnProcessing, StartAt: startAt, @@ -81,8 +54,59 @@ func (l *LoadService) RunLoadTest(param RunLoadTestParam) (string, error) { VmId: param.VmId, } - go l.processLoadTest(param, &loadGeneratorInstallInfo, &stateArg) + err = l.loadRepo.InsertLoadTestExecutionStateTx(ctx, &stateArg) + if err != nil { + log.Error().Msgf("Error saving initial load test execution state: %v", err) + return "", err + } + log.Info().Msgf("Initial load test execution state saved for key: %s", loadTestKey) + + + go l.processLoadTestAsync(param, &stateArg) + + return loadTestKey, nil + +} + + +func (l *LoadService) processLoadTestAsync(param RunLoadTestParam, loadTestExecutionState *LoadTestExecutionState) { + + var globalErr error + defer func () { + if globalErr != nil { + _ = l.loadRepo.UpdateLoadTestExecutionStateTx(context.Background(), loadTestExecutionState) + } + }() + + failed := func (logMsg string, occuredError error) { + log.Error().Msg(logMsg) + loadTestExecutionState.ExecutionStatus = constant.TestFailed + loadTestExecutionState.FailureMessage = logMsg + globalErr = occuredError + finishAt := time.Now() + loadTestExecutionState.FinishAt = &finishAt + } + + if param.LoadGeneratorInstallInfoId == uint(0) { + log.Info().Msgf("No LoadGeneratorInstallInfoId provided, installing load generator...") + + result, err := l.InstallLoadGenerator(param.InstallLoadGenerator) + if err != nil { + failed(fmt.Sprintf("Error installing load generator: %v", err), err) + return + } + + param.LoadGeneratorInstallInfoId = result.ID + log.Info().Msgf("Load generator installed with ID: %d", result.ID) + } + + loadGeneratorInstallInfo, err := l.loadRepo.GetValidLoadGeneratorInstallInfoByIdTx(context.Background(), param.LoadGeneratorInstallInfoId) + if err != nil { + failed(fmt.Sprintf("Error installing load generator: %v", err), err) + return + } + var hs []LoadTestExecutionHttpInfo for _, h := range param.HttpReqs { @@ -98,8 +122,8 @@ func (l *LoadService) RunLoadTest(param RunLoadTestParam) (string, error) { hs = append(hs, hh) } - loadArg := LoadTestExecutionInfo{ - LoadTestKey: loadTestKey, + loadTestExecutionInfoParam := LoadTestExecutionInfo{ + LoadTestKey: param.LoadTestKey, TestName: param.TestName, VirtualUsers: param.VirtualUsers, Duration: param.Duration, @@ -115,19 +139,137 @@ func (l *LoadService) RunLoadTest(param RunLoadTestParam) (string, error) { LoadGeneratorInstallInfoId: loadGeneratorInstallInfo.ID, LoadTestExecutionHttpInfos: hs, + + LoadTestExecutionStateId: loadTestExecutionState.ID, } - log.Info().Msgf("Saving load test execution info for key: %s", loadTestKey) - err = l.loadRepo.SaveForLoadTestExecutionTx(ctx, &loadArg, &stateArg) + err = l.loadRepo.SaveForLoadTestExecutionTx(context.Background(), &loadTestExecutionInfoParam) if err != nil { - log.Error().Msgf("Error saving load test execution info: %v", err) - return "", err + failed(fmt.Sprintf("Error saving load test execution info: %v", err), err) + return } - log.Info().Msgf("Load test started successfully with key: %s", loadTestKey) + loadTestExecutionState.GeneratorInstallInfoId = loadGeneratorInstallInfo.ID + loadTestExecutionState.TestExecutionInfoId = loadTestExecutionInfoParam.ID - return loadTestKey, nil + err = l.loadRepo.UpdateLoadTestExecutionStateTx(context.Background(), loadTestExecutionState) + + if err != nil { + failed(fmt.Sprintf("Error while update load test execution state to save load test execution info id and load generator install info id; %v", err), err) + } + + + if param.CollectAdditionalSystemMetrics { + if strings.TrimSpace(param.AgentHostname) == "" { + mci, err := l.tumblebugClient.GetMciWithContext(context.Background(), param.NsId, param.MciId) + + if err != nil { + failed(fmt.Sprintf("unexpected error occurred while fetching mci for install metrics agent; %s", err), err) + return + } + + if len(mci.Vm) == 0 { + failed("mci vm's length is zero", errors.New("mci vm's length is zero")) + return + } + + if len(mci.Vm) == 1 { + param.AgentHostname = mci.Vm[0].PublicIP + } else { + for _, v := range mci.Vm { + if v.Id == param.VmId { + param.AgentHostname = v.PublicIP + } + } + } + if param.AgentHostname == "" { + err := errors.New("agent host name afeter get mci from tumblebug must be set to not nil") + failed(fmt.Sprintf("invalid agent hostname for test %s; %v", param.LoadTestKey, err), err ) + return + } + } + + arg := MonitoringAgentInstallationParams{ + NsId: param.NsId, + MciId: param.MciId, + VmIds: []string{param.VmId}, + } + + // install and run the agent for collect metrics + _, err := l.InstallMonitoringAgent(arg) + if err != nil { + failed(fmt.Sprintf("unexpected error occurred while installing monitoring agent; %s", err), err ) + return + } + + log.Info().Msgf("metrics agent installed successfully for load test; %s %s %s", arg.NsId, arg.MciId, arg.VmIds) + } + + loadTestDone := make(chan bool) + + var username string + var publicIp string + var port string + for _, s := range loadGeneratorInstallInfo.LoadGeneratorServers { + if s.IsMaster { + username = s.Username + publicIp = s.PublicIp + port = s.SshPort + } + } + + home, err := os.UserHomeDir() + if err != nil { + failed(fmt.Sprintf("user home dir is not valid; %s", err), err ) + return + } + + dataParam := &fetchDataParam{ + LoadTestDone: loadTestDone, + LoadTestKey: param.LoadTestKey, + InstallLocation: loadGeneratorInstallInfo.InstallLocation, + InstallPath: loadGeneratorInstallInfo.InstallPath, + PublicKeyName: loadGeneratorInstallInfo.PublicKeyName, + PrivateKeyName: loadGeneratorInstallInfo.PrivateKeyName, + Username: username, + PublicIp: publicIp, + Port: port, + CollectAdditionalSystemMetrics: param.CollectAdditionalSystemMetrics, + Home: home, + } + + go l.fetchData(dataParam) + + defer func() { + loadTestDone <- true + close(loadTestDone) + updateErr := l.loadRepo.UpdateLoadTestExecutionStateTx(context.Background(), loadTestExecutionState) + if updateErr != nil { + failed(fmt.Sprintf("Error updating load test execution state: %v", updateErr), updateErr) + return + } + + log.Info().Msgf("successfully done load test for %s", dataParam.LoadTestKey) + }() + + compileDuration, executionDuration, loadTestErr := l.executeLoadTest(param, &loadGeneratorInstallInfo) + + loadTestExecutionState.CompileDuration = compileDuration + loadTestExecutionState.ExecutionDuration = executionDuration + + if loadTestErr != nil { + failed(fmt.Sprintf("Error while load testing: %v", loadTestErr), loadTestErr ) + return + } + + updateErr := l.updateLoadTestExecution(loadTestExecutionState) + if updateErr != nil { + failed(fmt.Sprintf("Error while updating load test execution: %v", updateErr), updateErr ) + return + } + + loadTestExecutionState.ExecutionStatus = constant.Successed } // processLoadTest executes the load test. @@ -392,17 +534,21 @@ func (l *LoadService) StopLoadTest(param StopLoadTestParam) error { } state, err := l.loadRepo.GetLoadTestExecutionStateTx(ctx, arg) - + if err != nil { return fmt.Errorf("error occurred while retrieve load test execution state: %w", err) } - + if state.ExecutionStatus == constant.Successed { return errors.New("load test is already completed") } + + installInfo, err := l.loadRepo.GetValidLoadGeneratorInstallInfoByIdTx(ctx, state.GeneratorInstallInfoId) - installInfo := state.LoadGeneratorInstallInfo - + if err != nil { + return fmt.Errorf("error occurred while retrieve load install info: %w", err) + } + killCmd := killCmdGen(param.LoadTestKey) if installInfo.InstallLocation == constant.Remote { diff --git a/internal/core/load/models.go b/internal/core/load/models.go index 14534c8..adb60f1 100644 --- a/internal/core/load/models.go +++ b/internal/core/load/models.go @@ -84,10 +84,9 @@ type LoadTestExecutionState struct { CompileDuration string ExecutionDuration string - LoadTestExecutionInfoId uint - - LoadGeneratorInstallInfoId uint - LoadGeneratorInstallInfo LoadGeneratorInstallInfo + // not to make one to one relationship between LoadTestExecutionInfo and LoadGeneratorInstallInfo + TestExecutionInfoId uint + GeneratorInstallInfoId uint } type LoadTestExecutionInfo struct { @@ -110,8 +109,11 @@ type LoadTestExecutionInfo struct { ExecutionDuration string LoadTestExecutionHttpInfos []LoadTestExecutionHttpInfo + // LoadTestExecutionInfo has one LoadTestExecutionState + LoadTestExecutionStateId uint LoadTestExecutionState LoadTestExecutionState + // LoadTestExecutionInfo has one LoadGeneratorInstallInfo LoadGeneratorInstallInfoId uint LoadGeneratorInstallInfo LoadGeneratorInstallInfo } diff --git a/internal/core/load/performace_evaluation_service.go b/internal/core/load/performace_evaluation_service.go index 5ba43de..8fcf498 100644 --- a/internal/core/load/performace_evaluation_service.go +++ b/internal/core/load/performace_evaluation_service.go @@ -63,7 +63,7 @@ func (l *LoadService) GetAllLoadTestExecutionState(param GetAllLoadTestExecution for _, loadTestExecutionState := range result { state := mapLoadTestExecutionStateResult(loadTestExecutionState) - state.LoadGeneratorInstallInfo = mapLoadGeneratorInstallInfoResult(loadTestExecutionState.LoadGeneratorInstallInfo) + // state.LoadGeneratorInstallInfo = mapLoadGeneratorInstallInfoResult(loadTestExecutionState.LoadGeneratorInstallInfo) states = append(states, state) } @@ -87,7 +87,7 @@ func (l *LoadService) GetLoadTestExecutionState(param GetLoadTestExecutionStateP } res = mapLoadTestExecutionStateResult(state) - res.LoadGeneratorInstallInfo = mapLoadGeneratorInstallInfoResult(state.LoadGeneratorInstallInfo) + // res.LoadGeneratorInstallInfo = mapLoadGeneratorInstallInfoResult(state.LoadGeneratorInstallInfo) return res, nil } @@ -152,6 +152,7 @@ func mapLoadTestExecutionStateResult(state LoadTestExecutionState) LoadTestExecu ExecutionStatus: state.ExecutionStatus, StartAt: state.StartAt, FinishAt: state.FinishAt, + ExpectedFinishAt: state.ExpectedFinishAt, TotalExpectedExcutionSecond: state.TotalExpectedExcutionSecond, FailureMessage: state.FailureMessage, CompileDuration: state.CompileDuration, diff --git a/internal/core/load/repository.go b/internal/core/load/repository.go index e3de251..1d0650d 100644 --- a/internal/core/load/repository.go +++ b/internal/core/load/repository.go @@ -255,8 +255,8 @@ func (r *LoadRepository) InsertLoadTestExecutionStateTx(ctx context.Context, par err := r.execInTransaction(ctx, func(d *gorm.DB) error { err := d. Where( - "load_generator_install_info_id = ? AND load_test_key = ?", - param.LoadGeneratorInstallInfoId, param.LoadTestKey, + "load_test_key = ?", + param.LoadTestKey, ). FirstOrCreate(param).Error @@ -271,7 +271,7 @@ func (r *LoadRepository) InsertLoadTestExecutionStateTx(ctx context.Context, par } -func (r *LoadRepository) SaveForLoadTestExecutionTx(ctx context.Context, loadParam *LoadTestExecutionInfo, stateParam *LoadTestExecutionState) error { +func (r *LoadRepository) SaveForLoadTestExecutionTx(ctx context.Context, loadParam *LoadTestExecutionInfo) error { err := r.execInTransaction(ctx, func(d *gorm.DB) error { err := d. Where( @@ -283,16 +283,6 @@ func (r *LoadRepository) SaveForLoadTestExecutionTx(ctx context.Context, loadPar return err } - stateParam.LoadTestExecutionInfoId = loadParam.ID - err = d. - Where("load_test_key = ?", stateParam.LoadTestKey). - FirstOrCreate(&stateParam). - Error - - if err != nil { - return err - } - return nil }) @@ -338,8 +328,8 @@ func (r *LoadRepository) GetPagingLoadTestExecutionStateTx(ctx context.Context, err := r.execInTransaction(ctx, func(d *gorm.DB) error { q := d.Model(&LoadTestExecutionState{}). - Preload("LoadGeneratorInstallInfo"). - Preload("LoadGeneratorInstallInfo.LoadGeneratorServers"). + // Preload("LoadGeneratorInstallInfo"). + // Preload("LoadGeneratorInstallInfo.LoadGeneratorServers"). Order("load_test_execution_states.created_at desc") if param.LoadTestKey != "" { @@ -371,9 +361,8 @@ func (r *LoadRepository) GetLoadTestExecutionStateTx(ctx context.Context, param err := r.execInTransaction(ctx, func(d *gorm.DB) error { - q := d.Model(&loadTestExecutionState). - Preload("LoadGeneratorInstallInfo"). - Preload("LoadGeneratorInstallInfo.LoadGeneratorServers") + q := d.Model(&loadTestExecutionState) + if param.LoadTestKey != "" { q = q.Where("load_test_execution_states.load_test_key = ?", param.LoadTestKey) diff --git a/internal/infra/db/db.go b/internal/infra/db/db.go index fec3b35..caa2246 100644 --- a/internal/infra/db/db.go +++ b/internal/infra/db/db.go @@ -3,8 +3,6 @@ package db import ( "errors" "fmt" - "log" - "os" "strings" "time" @@ -12,12 +10,20 @@ import ( "github.com/cloud-barista/cm-ant/internal/core/cost" "github.com/cloud-barista/cm-ant/internal/core/load" "github.com/cloud-barista/cm-ant/internal/utils" + "github.com/rs/zerolog/log" "gorm.io/driver/postgres" "gorm.io/driver/sqlite" "gorm.io/gorm" "gorm.io/gorm/logger" ) +type zerologGormLogger struct{} + +func (z zerologGormLogger) Printf(format string, v ...interface{}) { + log.Printf((fmt.Sprintf(format, v...))) +} + + func migrateDB(defaultDb *gorm.DB) error { err := defaultDb.AutoMigrate( &load.MonitoringAgentInfo{}, @@ -32,19 +38,19 @@ func migrateDB(defaultDb *gorm.DB) error { ) if err != nil { - utils.LogErrorf("Failed to auto migrate database tables: %v\n", err) + log.Error().Msgf("Failed to auto migrate database tables: %v", err) return err } - utils.LogInfo("Database tables auto migration completed successfully") + log.Info().Msg("Database tables auto migration completed successfully") return nil } func connectSqliteDB(dbPath string) (*gorm.DB, error) { - utils.LogInfof("SQLite configuration: meta SQLite DB path is %s\n", dbPath) + log.Info().Msgf("SQLite configuration: meta SQLite DB path is %s", dbPath) newLogger := logger.New( - log.New(os.Stdout, "\r", log.LstdFlags), + zerologGormLogger{}, logger.Config{ SlowThreshold: time.Second, // LogLevel: logger.Info, @@ -58,11 +64,11 @@ func connectSqliteDB(dbPath string) (*gorm.DB, error) { Logger: newLogger, }) if err != nil { - log.Printf("[ERROR] Failed to connect to SQLite database: %v\n", err) + log.Error().Msgf("Failed to connect to SQLite database: %v", err) return nil, err } - log.Println("[INFO] Connected to SQLite database successfully") + log.Info().Msg("Connected to SQLite database successfully") return sqliteDb, nil } @@ -87,29 +93,27 @@ func NewDBConnection() (*gorm.DB, error) { // sqlFilePath := sqliteFilePath(d.Host) // sqliteDB, err := connectSqliteDB(sqlFilePath) // if err != nil { - // utils.LogErrorf("Failed to establish SQLite DB connection: %v\n", err) // return nil, err // } // db = sqliteDB - // utils.LogInfof("Initialized SQLite database successfully [%s]\n", d.Driver) // } else if driver == "postgres" { postgresDb, err := connectPostgresDB(d.Host, d.Port, d.User, d.Password, d.Name) if err != nil { - utils.LogErrorf("Failed to establish Postgres DB connection: %v\n", err) + log.Error().Msgf("Failed to establish Postgres DB connection: %v", err) return nil, err } db = postgresDb - utils.LogInfof("Initialized Postgres database successfully [%s]\n", d.Driver) + log.Info().Msgf("Initialized Postgres database successfully [%s]", d.Driver) } else { return nil, errors.New("unsuppored database driver") } err := migrateDB(db) if err != nil { - utils.LogErrorf("Failed to migrate database: %v\n", err) + log.Info().Msgf("Failed to migrate database: %v", err) return nil, err } @@ -126,7 +130,7 @@ func connectPostgresDB(host, port, user, password, name string) (*gorm.DB, error return nil, errors.New("database connection info is incorrect") } newLogger := logger.New( - log.New(os.Stdout, "\r", log.LstdFlags), + zerologGormLogger{}, logger.Config{ SlowThreshold: time.Second, // LogLevel: logger.Info, @@ -143,10 +147,10 @@ func connectPostgresDB(host, port, user, password, name string) (*gorm.DB, error Logger: newLogger, }) if err != nil { - utils.LogErrorf("Failed to connect to Postgresql database: %v\n", err) + log.Info().Msgf("Failed to connect to Postgresql database: %v", err) return nil, err } - utils.LogInfo("Connected to Postgresql database successfully") + log.Info().Msg("Connected to Postgresql database successfully") return db, nil } From a6937053666660aad5c43d66ee9c97866ad3afe1 Mon Sep 17 00:00:00 2001 From: hippo-an Date: Thu, 14 Nov 2024 14:29:00 +0900 Subject: [PATCH 4/6] update for last result and metrics with ns, mci, vm id --- internal/app/evaluate_performance_handler.go | 88 +++++++++++++++ internal/app/evaluate_performance_req.go | 7 ++ internal/app/router.go | 2 + internal/core/load/dtos.go | 11 +- .../core/load/load_test_execution_service.go | 34 +++--- internal/core/load/models.go | 5 +- .../performance_evaluation_result_service.go | 102 +++++++++++++++++- 7 files changed, 226 insertions(+), 23 deletions(-) diff --git a/internal/app/evaluate_performance_handler.go b/internal/app/evaluate_performance_handler.go index 6bfbfa9..8ad0a93 100644 --- a/internal/app/evaluate_performance_handler.go +++ b/internal/app/evaluate_performance_handler.go @@ -703,3 +703,91 @@ func (s *AntServer) uninstallMonitoringAgent(c echo.Context) error { affectedResults, ) } + +// getLastLoadTestResult handler function that retrieves a specific load test result. +// @Id GetLastLoadTestResult +// @Summary Get last load test result by ns, mci, vm +// @Description Retrieve last load test result based on provided parameters. +// @Tags [Load Test Result] +// @Accept json +// @Produce json +// @Param nsId query string true "ns id" +// @Param mciId query string true "mci id" +// @Param vmId query string true "vm id" +// @Param format query string false "Result format (normal or aggregate)" +// @Success 200 {object} app.JsonResult{[normal]=app.AntResponse[[]load.ResultSummary],[aggregate]=app.AntResponse[[]load.LoadTestStatistics]} "Successfully retrieved load test metrics" +// @Failure 400 {object} app.AntResponse[string] "Invalid request parameters" +// @Failure 500 {object} app.AntResponse[string] "Failed to retrieve load test result" +// @Router /api/v1/load/tests/result/last [get] +func (s *AntServer) getLastLoadTestResult(c echo.Context) error { + var req GetLastLoadTestResultReq + if err := c.Bind(&req); err != nil { + return errorResponseJson(http.StatusBadRequest, "Invalid request parameters") + } + + if strings.TrimSpace(req.NsId) == "" || strings.TrimSpace(req.MciId) == "" || strings.TrimSpace(req.VmId) == "" { + return errorResponseJson(http.StatusBadRequest, "pass correct nsId / mciId / vmId") + } + + if req.Format == "" { + req.Format = constant.Normal + } else if req.Format != constant.Normal && req.Format != constant.Aggregate { + req.Format = constant.Normal + } + + arg := load.GetLastLoadTestResultParam{ + NsId: req.NsId, + MciId: req.MciId, + VmId: req.VmId, + Format: req.Format, + } + + result, err := s.services.loadService.GetLastLoadTestResult(arg) + + if err != nil { + return errorResponseJson(http.StatusInternalServerError, "Failed to retrieve load test result") + } + + return successResponseJson(c, "Successfully retrieved load test result", result) +} + +// getLastLoadTestMetrics handler function that retrieves metrics for a specific load test. +// @Id GetLastLoadTestMetrics +// @Summary Get last load test metrics by ns, mci, vm +// @Description Retrieve last load test metrics based on provided parameters. +// @Tags [Load Test Result] +// @Accept json +// @Produce json +// @Param nsId query string true "ns id" +// @Param mciId query string true "mci id" +// @Param vmId query string true "vm id" +// @Param format query string false "Result format (normal for the moment)" +// @success 200 {object} app.AntResponse[[]load.MetricsSummary] "Successfully retrieved load test metrics" +// @Failure 400 {object} app.AntResponse[string] "Invalid request parameters" +// @Failure 500 {object} app.AntResponse[string] "Failed to retrieve load test metrics" +// @Router /api/v1/load/tests/result/metrics/last [get] +func (s *AntServer) getLastLoadTestMetrics(c echo.Context) error { + var req GetLastLoadTestResultReq + if err := c.Bind(&req); err != nil { + return errorResponseJson(http.StatusBadRequest, "Invalid request parameters") + } + + if strings.TrimSpace(req.NsId) == "" || strings.TrimSpace(req.MciId) == "" || strings.TrimSpace(req.VmId) == "" { + return errorResponseJson(http.StatusBadRequest, "pass correct nsId / mciId / vmId") + } + + arg := load.GetLastLoadTestResultParam{ + NsId: req.NsId, + MciId: req.MciId, + VmId: req.VmId, + Format: constant.Normal, + } + + result, err := s.services.loadService.GetLastLoadTestMetrics(arg) + + if err != nil { + return errorResponseJson(http.StatusInternalServerError, "Failed to retrieve load test metrics") + } + + return successResponseJson(c, "Successfully retrieved load test metrics", result) +} diff --git a/internal/app/evaluate_performance_req.go b/internal/app/evaluate_performance_req.go index 69c129e..20d9094 100644 --- a/internal/app/evaluate_performance_req.go +++ b/internal/app/evaluate_performance_req.go @@ -90,3 +90,10 @@ type GetLoadTestResultReq struct { LoadTestKey string `query:"loadTestKey"` Format constant.ResultFormat `query:"format"` } + +type GetLastLoadTestResultReq struct { + NsId string `query:"nsId"` + MciId string `query:"mciId"` + VmId string `query:"vmId"` + Format constant.ResultFormat `query:"format"` +} diff --git a/internal/app/router.go b/internal/app/router.go index 888a855..099bed5 100644 --- a/internal/app/router.go +++ b/internal/app/router.go @@ -54,6 +54,8 @@ func (server *AntServer) InitRouter() error { // load test result loadTestRouter.GET("/result", server.getLoadTestResult) loadTestRouter.GET("/result/metrics", server.getLoadTestMetrics) + loadTestRouter.GET("/result/last", server.getLastLoadTestResult) + loadTestRouter.GET("/result/metrics/last", server.getLastLoadTestMetrics) } } } diff --git a/internal/core/load/dtos.go b/internal/core/load/dtos.go index 9e69130..3832d6b 100644 --- a/internal/core/load/dtos.go +++ b/internal/core/load/dtos.go @@ -149,8 +149,8 @@ type LoadTestExecutionStateResult struct { ExecutionStatus constant.ExecutionStatus `json:"executionStatus,omitempty"` StartAt time.Time `json:"startAt,omitempty"` FinishAt *time.Time `json:"finishAt,omitempty"` - ExpectedFinishAt time.Time `json:"expectedFinishAt,omitempty"` - IconCode constant.IconCode `json:"iconCode"` + ExpectedFinishAt time.Time `json:"expectedFinishAt,omitempty"` + IconCode constant.IconCode `json:"iconCode"` TotalExpectedExcutionSecond uint64 `json:"totalExpectedExecutionSecond,omitempty"` FailureMessage string `json:"failureMessage,omitempty"` CompileDuration string `json:"compileDuration,omitempty"` @@ -264,3 +264,10 @@ type GetLoadTestResultParam struct { LoadTestKey string Format constant.ResultFormat } + +type GetLastLoadTestResultParam struct { + NsId string + MciId string + VmId string + Format constant.ResultFormat +} diff --git a/internal/core/load/load_test_execution_service.go b/internal/core/load/load_test_execution_service.go index 52c3c81..05df68c 100644 --- a/internal/core/load/load_test_execution_service.go +++ b/internal/core/load/load_test_execution_service.go @@ -22,7 +22,7 @@ import ( func (l *LoadService) RunLoadTest(param RunLoadTestParam) (string, error) { ctx, cancel := context.WithTimeout(context.Background(), 10*time.Minute) defer cancel() - + loadTestKey := utils.CreateUniqIdBaseOnUnixTime() param.LoadTestKey = loadTestKey log.Info().Msgf("Starting load test with key: %s", loadTestKey) @@ -52,6 +52,7 @@ func (l *LoadService) RunLoadTest(param RunLoadTestParam) (string, error) { NsId: param.NsId, MciId: param.MciId, VmId: param.VmId, + WithMetrics: param.CollectAdditionalSystemMetrics, } err = l.loadRepo.InsertLoadTestExecutionStateTx(ctx, &stateArg) @@ -61,25 +62,23 @@ func (l *LoadService) RunLoadTest(param RunLoadTestParam) (string, error) { } log.Info().Msgf("Initial load test execution state saved for key: %s", loadTestKey) - go l.processLoadTestAsync(param, &stateArg) return loadTestKey, nil } - func (l *LoadService) processLoadTestAsync(param RunLoadTestParam, loadTestExecutionState *LoadTestExecutionState) { var globalErr error - defer func () { + defer func() { if globalErr != nil { _ = l.loadRepo.UpdateLoadTestExecutionStateTx(context.Background(), loadTestExecutionState) } }() - failed := func (logMsg string, occuredError error) { + failed := func(logMsg string, occuredError error) { log.Error().Msg(logMsg) loadTestExecutionState.ExecutionStatus = constant.TestFailed loadTestExecutionState.FailureMessage = logMsg @@ -106,7 +105,7 @@ func (l *LoadService) processLoadTestAsync(param RunLoadTestParam, loadTestExecu failed(fmt.Sprintf("Error installing load generator: %v", err), err) return } - + var hs []LoadTestExecutionHttpInfo for _, h := range param.HttpReqs { @@ -146,7 +145,7 @@ func (l *LoadService) processLoadTestAsync(param RunLoadTestParam, loadTestExecu err = l.loadRepo.SaveForLoadTestExecutionTx(context.Background(), &loadTestExecutionInfoParam) if err != nil { failed(fmt.Sprintf("Error saving load test execution info: %v", err), err) - return + return } loadTestExecutionState.GeneratorInstallInfoId = loadGeneratorInstallInfo.ID @@ -156,8 +155,7 @@ func (l *LoadService) processLoadTestAsync(param RunLoadTestParam, loadTestExecu if err != nil { failed(fmt.Sprintf("Error while update load test execution state to save load test execution info id and load generator install info id; %v", err), err) - } - + } if param.CollectAdditionalSystemMetrics { if strings.TrimSpace(param.AgentHostname) == "" { @@ -185,7 +183,7 @@ func (l *LoadService) processLoadTestAsync(param RunLoadTestParam, loadTestExecu if param.AgentHostname == "" { err := errors.New("agent host name afeter get mci from tumblebug must be set to not nil") - failed(fmt.Sprintf("invalid agent hostname for test %s; %v", param.LoadTestKey, err), err ) + failed(fmt.Sprintf("invalid agent hostname for test %s; %v", param.LoadTestKey, err), err) return } } @@ -199,7 +197,7 @@ func (l *LoadService) processLoadTestAsync(param RunLoadTestParam, loadTestExecu // install and run the agent for collect metrics _, err := l.InstallMonitoringAgent(arg) if err != nil { - failed(fmt.Sprintf("unexpected error occurred while installing monitoring agent; %s", err), err ) + failed(fmt.Sprintf("unexpected error occurred while installing monitoring agent; %s", err), err) return } @@ -221,7 +219,7 @@ func (l *LoadService) processLoadTestAsync(param RunLoadTestParam, loadTestExecu home, err := os.UserHomeDir() if err != nil { - failed(fmt.Sprintf("user home dir is not valid; %s", err), err ) + failed(fmt.Sprintf("user home dir is not valid; %s", err), err) return } @@ -259,13 +257,13 @@ func (l *LoadService) processLoadTestAsync(param RunLoadTestParam, loadTestExecu loadTestExecutionState.ExecutionDuration = executionDuration if loadTestErr != nil { - failed(fmt.Sprintf("Error while load testing: %v", loadTestErr), loadTestErr ) + failed(fmt.Sprintf("Error while load testing: %v", loadTestErr), loadTestErr) return } updateErr := l.updateLoadTestExecution(loadTestExecutionState) if updateErr != nil { - failed(fmt.Sprintf("Error while updating load test execution: %v", updateErr), updateErr ) + failed(fmt.Sprintf("Error while updating load test execution: %v", updateErr), updateErr) return } @@ -534,21 +532,21 @@ func (l *LoadService) StopLoadTest(param StopLoadTestParam) error { } state, err := l.loadRepo.GetLoadTestExecutionStateTx(ctx, arg) - + if err != nil { return fmt.Errorf("error occurred while retrieve load test execution state: %w", err) } - + if state.ExecutionStatus == constant.Successed { return errors.New("load test is already completed") } - + installInfo, err := l.loadRepo.GetValidLoadGeneratorInstallInfoByIdTx(ctx, state.GeneratorInstallInfoId) if err != nil { return fmt.Errorf("error occurred while retrieve load install info: %w", err) } - + killCmd := killCmdGen(param.LoadTestKey) if installInfo.InstallLocation == constant.Remote { diff --git a/internal/core/load/models.go b/internal/core/load/models.go index adb60f1..1a239a0 100644 --- a/internal/core/load/models.go +++ b/internal/core/load/models.go @@ -83,9 +83,10 @@ type LoadTestExecutionState struct { FailureMessage string CompileDuration string ExecutionDuration string + WithMetrics bool // not to make one to one relationship between LoadTestExecutionInfo and LoadGeneratorInstallInfo - TestExecutionInfoId uint + TestExecutionInfoId uint GeneratorInstallInfoId uint } @@ -111,7 +112,7 @@ type LoadTestExecutionInfo struct { // LoadTestExecutionInfo has one LoadTestExecutionState LoadTestExecutionStateId uint - LoadTestExecutionState LoadTestExecutionState + LoadTestExecutionState LoadTestExecutionState // LoadTestExecutionInfo has one LoadGeneratorInstallInfo LoadGeneratorInstallInfoId uint diff --git a/internal/core/load/performance_evaluation_result_service.go b/internal/core/load/performance_evaluation_result_service.go index aaeba11..d42fcaa 100644 --- a/internal/core/load/performance_evaluation_result_service.go +++ b/internal/core/load/performance_evaluation_result_service.go @@ -1,9 +1,9 @@ package load import ( + "context" "errors" "fmt" - "log" "math" "sort" "strconv" @@ -12,6 +12,7 @@ import ( "github.com/cloud-barista/cm-ant/internal/core/common/constant" "github.com/cloud-barista/cm-ant/internal/utils" + "github.com/rs/zerolog/log" ) type metricsUnits struct { @@ -133,6 +134,105 @@ func (l *LoadService) GetLoadTestMetrics(param GetLoadTestResultParam) ([]Metric return metricsSummaries, nil } +func (l *LoadService) GetLastLoadTestResult(param GetLastLoadTestResultParam) (interface{}, error) { + ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second) + defer cancel() + + stateQueryParam := GetLoadTestExecutionStateParam{ + NsId: param.NsId, + MciId: param.MciId, + VmId: param.VmId, + } + state, err := l.loadRepo.GetLoadTestExecutionStateTx(ctx, stateQueryParam) + + if err != nil { + utils.LogErrorf("Error fetching load test execution state infos: %v", err) + return nil, err + } + + loadTestKey := state.LoadTestKey + fileName := fmt.Sprintf("%s_result.csv", loadTestKey) + resultFolderPath := utils.JoinRootPathWith("/result/" + loadTestKey) + toFilePath := fmt.Sprintf("%s/%s", resultFolderPath, fileName) + resultMap, err := appendResultRawData(toFilePath) + if err != nil { + return nil, err + } + + var resultSummaries []ResultSummary + + for label, results := range resultMap { + resultSummaries = append(resultSummaries, ResultSummary{ + Label: label, + Results: results, + }) + } + + formattedDate, err := resultFormat(param.Format, resultSummaries) + + if err != nil { + return nil, err + } + + return formattedDate, nil +} + +func (l *LoadService) GetLastLoadTestMetrics(param GetLastLoadTestResultParam) ([]MetricsSummary, error) { + ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second) + defer cancel() + + stateQueryParam := GetLoadTestExecutionStateParam{ + NsId: param.NsId, + MciId: param.MciId, + VmId: param.VmId, + } + + state, err := l.loadRepo.GetLoadTestExecutionStateTx(ctx, stateQueryParam) + + if err != nil { + utils.LogErrorf("Error fetching load test execution state infos: %v", err) + return nil, err + } + + loadTestKey := state.LoadTestKey + + if !state.WithMetrics { + log.Error().Msgf("%s does not contain metrics collection", loadTestKey) + return nil, errors.New("metrics does not collected while performance evaluation") + } + + metrics := []string{"cpu", "disk", "memory", "network"} + resultFolderPath := utils.JoinRootPathWith("/result/" + loadTestKey) + + metricsMap := make(map[string][]*MetricsRawData) + + for _, v := range metrics { + + fileName := fmt.Sprintf("%s_%s_result.csv", loadTestKey, v) + toPath := fmt.Sprintf("%s/%s", resultFolderPath, fileName) + + metricsMap, err = appendMetricsRawData(metricsMap, toPath) + if err != nil { + return nil, err + } + + } + + var metricsSummaries []MetricsSummary + + for label, metrics := range metricsMap { + metricsSummaries = append(metricsSummaries, MetricsSummary{ + Label: label, + Metrics: metrics, + }) + } + + if err != nil { + return nil, err + } + + return metricsSummaries, nil +} func calculatePercentile(elapsedList []int, percentile float64) float64 { index := int(math.Ceil(float64(len(elapsedList))*percentile)) - 1 From 5fcbc6cef7f27e6bd1adf27ad4147c8316a7c660 Mon Sep 17 00:00:00 2001 From: hippo-an Date: Thu, 14 Nov 2024 14:29:18 +0900 Subject: [PATCH 5/6] update swagger document for last api update --- api/docs.go | 164 +++++++++++++++++++++++++++++++++++++++++++++++ api/swagger.json | 164 +++++++++++++++++++++++++++++++++++++++++++++++ api/swagger.yaml | 109 +++++++++++++++++++++++++++++++ 3 files changed, 437 insertions(+) diff --git a/api/docs.go b/api/docs.go index a29c798..391b2a5 100644 --- a/api/docs.go +++ b/api/docs.go @@ -840,6 +840,86 @@ const docTemplate = `{ } } }, + "/api/v1/load/tests/result/last": { + "get": { + "description": "Retrieve last load test result based on provided parameters.", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "[Load Test Result]" + ], + "summary": "Get last load test result by ns, mci, vm", + "operationId": "GetLastLoadTestResult", + "parameters": [ + { + "type": "string", + "description": "ns id", + "name": "nsId", + "in": "query", + "required": true + }, + { + "type": "string", + "description": "mci id", + "name": "mciId", + "in": "query", + "required": true + }, + { + "type": "string", + "description": "vm id", + "name": "vmId", + "in": "query", + "required": true + }, + { + "type": "string", + "description": "Result format (normal or aggregate)", + "name": "format", + "in": "query" + } + ], + "responses": { + "200": { + "description": "Successfully retrieved load test metrics", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/app.JsonResult" + }, + { + "type": "object", + "properties": { + "[aggregate]": { + "$ref": "#/definitions/app.AntResponse-array_load_LoadTestStatistics" + }, + "[normal]": { + "$ref": "#/definitions/app.AntResponse-array_load_ResultSummary" + } + } + } + ] + } + }, + "400": { + "description": "Invalid request parameters", + "schema": { + "$ref": "#/definitions/app.AntResponse-string" + } + }, + "500": { + "description": "Failed to retrieve load test result", + "schema": { + "$ref": "#/definitions/app.AntResponse-string" + } + } + } + } + }, "/api/v1/load/tests/result/metrics": { "get": { "description": "Retrieve load test metrics based on provided parameters.", @@ -885,6 +965,71 @@ const docTemplate = `{ } } }, + "/api/v1/load/tests/result/metrics/last": { + "get": { + "description": "Retrieve last load test metrics based on provided parameters.", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "[Load Test Result]" + ], + "summary": "Get last load test metrics by ns, mci, vm", + "operationId": "GetLastLoadTestMetrics", + "parameters": [ + { + "type": "string", + "description": "ns id", + "name": "nsId", + "in": "query", + "required": true + }, + { + "type": "string", + "description": "mci id", + "name": "mciId", + "in": "query", + "required": true + }, + { + "type": "string", + "description": "vm id", + "name": "vmId", + "in": "query", + "required": true + }, + { + "type": "string", + "description": "Result format (normal for the moment)", + "name": "format", + "in": "query" + } + ], + "responses": { + "200": { + "description": "Successfully retrieved load test metrics", + "schema": { + "$ref": "#/definitions/app.AntResponse-array_load_MetricsSummary" + } + }, + "400": { + "description": "Invalid request parameters", + "schema": { + "$ref": "#/definitions/app.AntResponse-string" + } + }, + "500": { + "description": "Failed to retrieve load test metrics", + "schema": { + "$ref": "#/definitions/app.AntResponse-string" + } + } + } + } + }, "/api/v1/load/tests/run": { "post": { "description": "Start a load test using the provided load test configuration.", @@ -1740,6 +1885,19 @@ const docTemplate = `{ "TestFailed" ] }, + "constant.IconCode": { + "type": "string", + "enum": [ + "IC0001", + "IC0002", + "IC0003" + ], + "x-enum-varnames": [ + "Ok", + "Fail", + "Pending" + ] + }, "constant.InstallLocation": { "type": "string", "enum": [ @@ -2258,12 +2416,18 @@ const docTemplate = `{ "executionStatus": { "$ref": "#/definitions/constant.ExecutionStatus" }, + "expectedFinishAt": { + "type": "string" + }, "failureMessage": { "type": "string" }, "finishAt": { "type": "string" }, + "iconCode": { + "$ref": "#/definitions/constant.IconCode" + }, "id": { "type": "integer" }, diff --git a/api/swagger.json b/api/swagger.json index 14deef7..f19292b 100644 --- a/api/swagger.json +++ b/api/swagger.json @@ -832,6 +832,86 @@ } } }, + "/api/v1/load/tests/result/last": { + "get": { + "description": "Retrieve last load test result based on provided parameters.", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "[Load Test Result]" + ], + "summary": "Get last load test result by ns, mci, vm", + "operationId": "GetLastLoadTestResult", + "parameters": [ + { + "type": "string", + "description": "ns id", + "name": "nsId", + "in": "query", + "required": true + }, + { + "type": "string", + "description": "mci id", + "name": "mciId", + "in": "query", + "required": true + }, + { + "type": "string", + "description": "vm id", + "name": "vmId", + "in": "query", + "required": true + }, + { + "type": "string", + "description": "Result format (normal or aggregate)", + "name": "format", + "in": "query" + } + ], + "responses": { + "200": { + "description": "Successfully retrieved load test metrics", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/app.JsonResult" + }, + { + "type": "object", + "properties": { + "[aggregate]": { + "$ref": "#/definitions/app.AntResponse-array_load_LoadTestStatistics" + }, + "[normal]": { + "$ref": "#/definitions/app.AntResponse-array_load_ResultSummary" + } + } + } + ] + } + }, + "400": { + "description": "Invalid request parameters", + "schema": { + "$ref": "#/definitions/app.AntResponse-string" + } + }, + "500": { + "description": "Failed to retrieve load test result", + "schema": { + "$ref": "#/definitions/app.AntResponse-string" + } + } + } + } + }, "/api/v1/load/tests/result/metrics": { "get": { "description": "Retrieve load test metrics based on provided parameters.", @@ -877,6 +957,71 @@ } } }, + "/api/v1/load/tests/result/metrics/last": { + "get": { + "description": "Retrieve last load test metrics based on provided parameters.", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "[Load Test Result]" + ], + "summary": "Get last load test metrics by ns, mci, vm", + "operationId": "GetLastLoadTestMetrics", + "parameters": [ + { + "type": "string", + "description": "ns id", + "name": "nsId", + "in": "query", + "required": true + }, + { + "type": "string", + "description": "mci id", + "name": "mciId", + "in": "query", + "required": true + }, + { + "type": "string", + "description": "vm id", + "name": "vmId", + "in": "query", + "required": true + }, + { + "type": "string", + "description": "Result format (normal for the moment)", + "name": "format", + "in": "query" + } + ], + "responses": { + "200": { + "description": "Successfully retrieved load test metrics", + "schema": { + "$ref": "#/definitions/app.AntResponse-array_load_MetricsSummary" + } + }, + "400": { + "description": "Invalid request parameters", + "schema": { + "$ref": "#/definitions/app.AntResponse-string" + } + }, + "500": { + "description": "Failed to retrieve load test metrics", + "schema": { + "$ref": "#/definitions/app.AntResponse-string" + } + } + } + } + }, "/api/v1/load/tests/run": { "post": { "description": "Start a load test using the provided load test configuration.", @@ -1732,6 +1877,19 @@ "TestFailed" ] }, + "constant.IconCode": { + "type": "string", + "enum": [ + "IC0001", + "IC0002", + "IC0003" + ], + "x-enum-varnames": [ + "Ok", + "Fail", + "Pending" + ] + }, "constant.InstallLocation": { "type": "string", "enum": [ @@ -2250,12 +2408,18 @@ "executionStatus": { "$ref": "#/definitions/constant.ExecutionStatus" }, + "expectedFinishAt": { + "type": "string" + }, "failureMessage": { "type": "string" }, "finishAt": { "type": "string" }, + "iconCode": { + "$ref": "#/definitions/constant.IconCode" + }, "id": { "type": "integer" }, diff --git a/api/swagger.yaml b/api/swagger.yaml index 7dc7e8f..93b05d7 100644 --- a/api/swagger.yaml +++ b/api/swagger.yaml @@ -369,6 +369,16 @@ definitions: - OnFetching - Successed - TestFailed + constant.IconCode: + enum: + - IC0001 + - IC0002 + - IC0003 + type: string + x-enum-varnames: + - Ok + - Fail + - Pending constant.InstallLocation: enum: - local @@ -713,10 +723,14 @@ definitions: type: string executionStatus: $ref: '#/definitions/constant.ExecutionStatus' + expectedFinishAt: + type: string failureMessage: type: string finishAt: type: string + iconCode: + $ref: '#/definitions/constant.IconCode' id: type: integer loadGeneratorInstallInfo: @@ -1409,6 +1423,57 @@ paths: summary: Get load test result tags: - '[Load Test Result]' + /api/v1/load/tests/result/last: + get: + consumes: + - application/json + description: Retrieve last load test result based on provided parameters. + operationId: GetLastLoadTestResult + parameters: + - description: ns id + in: query + name: nsId + required: true + type: string + - description: mci id + in: query + name: mciId + required: true + type: string + - description: vm id + in: query + name: vmId + required: true + type: string + - description: Result format (normal or aggregate) + in: query + name: format + type: string + produces: + - application/json + responses: + "200": + description: Successfully retrieved load test metrics + schema: + allOf: + - $ref: '#/definitions/app.JsonResult' + - properties: + '[aggregate]': + $ref: '#/definitions/app.AntResponse-array_load_LoadTestStatistics' + '[normal]': + $ref: '#/definitions/app.AntResponse-array_load_ResultSummary' + type: object + "400": + description: Invalid request parameters + schema: + $ref: '#/definitions/app.AntResponse-string' + "500": + description: Failed to retrieve load test result + schema: + $ref: '#/definitions/app.AntResponse-string' + summary: Get last load test result by ns, mci, vm + tags: + - '[Load Test Result]' /api/v1/load/tests/result/metrics: get: consumes: @@ -1439,6 +1504,50 @@ paths: summary: Get load test metrics tags: - '[Load Test Result]' + /api/v1/load/tests/result/metrics/last: + get: + consumes: + - application/json + description: Retrieve last load test metrics based on provided parameters. + operationId: GetLastLoadTestMetrics + parameters: + - description: ns id + in: query + name: nsId + required: true + type: string + - description: mci id + in: query + name: mciId + required: true + type: string + - description: vm id + in: query + name: vmId + required: true + type: string + - description: Result format (normal for the moment) + in: query + name: format + type: string + produces: + - application/json + responses: + "200": + description: Successfully retrieved load test metrics + schema: + $ref: '#/definitions/app.AntResponse-array_load_MetricsSummary' + "400": + description: Invalid request parameters + schema: + $ref: '#/definitions/app.AntResponse-string' + "500": + description: Failed to retrieve load test metrics + schema: + $ref: '#/definitions/app.AntResponse-string' + summary: Get last load test metrics by ns, mci, vm + tags: + - '[Load Test Result]' /api/v1/load/tests/run: post: consumes: From b32ffc06cfbe8390d8f5d057fc8e051483c24536 Mon Sep 17 00:00:00 2001 From: hippo-an Date: Thu, 14 Nov 2024 15:08:38 +0900 Subject: [PATCH 6/6] update all default log to zero log --- internal/app/estimate_cost_handler.go | 6 +- internal/app/evaluate_performance_handler.go | 13 +- internal/app/middlewares.go | 3 +- internal/core/cost/cost_collector.go | 29 ++-- internal/core/cost/price_collector.go | 12 +- internal/core/cost/service.go | 9 +- internal/core/load/jmx_parser.go | 4 +- .../load/load_generator_install_service.go | 62 ++++----- .../core/load/load_test_execution_service.go | 16 +-- internal/core/load/metrics_agent_service.go | 45 +++--- .../load/performace_evaluation_service.go | 26 ++-- .../performance_evaluation_result_service.go | 4 +- internal/core/load/rsync_fetch_service.go | 4 +- internal/infra/outbound/spider/price.go | 17 ++- .../infra/outbound/spider/spider_client.go | 16 +-- internal/infra/outbound/tumblebug/mci.go | 46 +++---- .../outbound/tumblebug/tumblebug_client.go | 17 ++- internal/render/templates.go | 4 +- internal/utils/bash.go | 17 +-- internal/utils/ioes.go | 13 +- internal/utils/log.go | 128 +++++++++--------- internal/utils/ssh.go | 4 +- internal/utils/worker.go | 10 +- 23 files changed, 251 insertions(+), 254 deletions(-) diff --git a/internal/app/estimate_cost_handler.go b/internal/app/estimate_cost_handler.go index 0b5846e..d1aa559 100644 --- a/internal/app/estimate_cost_handler.go +++ b/internal/app/estimate_cost_handler.go @@ -9,8 +9,8 @@ import ( "github.com/cloud-barista/cm-ant/internal/config" "github.com/cloud-barista/cm-ant/internal/core/common/constant" "github.com/cloud-barista/cm-ant/internal/core/cost" - "github.com/cloud-barista/cm-ant/internal/utils" "github.com/labstack/echo/v4" + "github.com/rs/zerolog/log" ) // @Id UpdateAndGetEstimateCost @@ -74,12 +74,12 @@ func (a *AntServer) updateAndGetEstimateCost(c echo.Context) error { splitedCommonImage := strings.Split(ci, delim) if len(splitedCommonSpec) != 3 { - utils.LogErrorf("common spec format is not correct; image: %s; spec: %s", ci, cs) + log.Error().Msgf("common spec format is not correct; image: %s; spec: %s", ci, cs) return errorResponseJson(http.StatusBadRequest, fmt.Sprintf("common spec format is not correct; image: %s; spec: %s", ci, cs)) } if len(splitedCommonImage) == 3 && (splitedCommonImage[0] != splitedCommonSpec[0] || splitedCommonImage[1] != splitedCommonSpec[1]) { - utils.LogErrorf("common image and spec recommendation is wrong; image: %s; spec: %s", ci, cs) + log.Error().Msgf("common image and spec recommendation is wrong; image: %s; spec: %s", ci, cs) return errorResponseJson(http.StatusBadRequest, fmt.Sprintf("common image and spec recommendation is wrong; image: %s; spec: %s", ci, cs)) } diff --git a/internal/app/evaluate_performance_handler.go b/internal/app/evaluate_performance_handler.go index 8ad0a93..16c8add 100644 --- a/internal/app/evaluate_performance_handler.go +++ b/internal/app/evaluate_performance_handler.go @@ -8,7 +8,6 @@ import ( "github.com/cloud-barista/cm-ant/internal/core/common/constant" "github.com/cloud-barista/cm-ant/internal/core/load" - "github.com/cloud-barista/cm-ant/internal/utils" "github.com/google/uuid" "github.com/labstack/echo/v4" "github.com/rs/zerolog/log" @@ -74,20 +73,20 @@ func (s *AntServer) getAllLoadGeneratorInstallInfo(c echo.Context) error { func (s *AntServer) installLoadGenerator(c echo.Context) error { var req InstallLoadGeneratorReq - utils.LogInfo("Received request to install load generator") + log.Info().Msg("Received request to install load generator") if err := c.Bind(&req); err != nil { - utils.LogError("Failed to bind request:", err) + log.Error().Msgf("Failed to bind request:", err) return errorResponseJson(http.StatusBadRequest, "load generator installation info is not correct.") } if req.InstallLocation == "" || (req.InstallLocation != constant.Remote && req.InstallLocation != constant.Local) { - utils.LogError("Invalid install location:", req.InstallLocation) + log.Error().Msgf("Invalid install location:", req.InstallLocation) return errorResponseJson(http.StatusBadRequest, "available install locations are remote or local.") } - utils.LogInfo("Calling service layer to install load generator") + log.Info().Msgf("Calling service layer to install load generator") // call service layer install load generator param := load.InstallLoadGeneratorParam{ @@ -97,11 +96,11 @@ func (s *AntServer) installLoadGenerator(c echo.Context) error { result, err := s.services.loadService.InstallLoadGenerator(param) if err != nil { - utils.LogError("Error installing load generator:", err) + log.Error().Msgf("Error installing load generator:", err) return errorResponseJson(http.StatusBadRequest, err.Error()) } - utils.LogInfo("Load generator installed successfully") + log.Info().Msg("Load generator installed successfully") return successResponseJson( c, diff --git a/internal/app/middlewares.go b/internal/app/middlewares.go index a9f157c..8b2ed07 100644 --- a/internal/app/middlewares.go +++ b/internal/app/middlewares.go @@ -9,7 +9,6 @@ import ( "github.com/labstack/echo/v4/middleware" - "github.com/cloud-barista/cm-ant/internal/utils" "github.com/labstack/echo/v4" "github.com/rs/zerolog/log" ) @@ -34,7 +33,7 @@ func setMiddleware(e *echo.Echo) { Skipper: middleware.DefaultSkipper, ErrorMessage: "request timeout", OnTimeoutRouteErrorHandler: func(err error, c echo.Context) { - utils.LogInfo(c.Path()) + log.Info().Msg(c.Path()) }, Timeout: 3000 * time.Second, }, diff --git a/internal/core/cost/cost_collector.go b/internal/core/cost/cost_collector.go index c74c070..c1ec170 100644 --- a/internal/core/cost/cost_collector.go +++ b/internal/core/cost/cost_collector.go @@ -13,6 +13,7 @@ import ( "github.com/cloud-barista/cm-ant/internal/infra/outbound/spider" "github.com/cloud-barista/cm-ant/internal/infra/outbound/tumblebug" "github.com/cloud-barista/cm-ant/internal/utils" + "github.com/rs/zerolog/log" ) type CostCollector interface { @@ -136,7 +137,7 @@ func (a *AwsCostExplorerBaristaCostCollector) GetCostInfos(ctx context.Context, serviceFilterValue, resourceIdFilterValue, err := a.generateFilterValue(param.CostResources, param.AwsAdditionalInfo) if err != nil { - utils.LogError("parsing service and resource id for filtering cost explorer value") + log.Error().Msgf("parsing service and resource id for filtering cost explorer value") return nil, err } @@ -216,33 +217,33 @@ func (a *AwsCostExplorerBaristaCostCollector) GetCostInfos(ctx context.Context, if err != nil { if errors.Is(err, spider.ErrSpiderCostResultEmpty) { - utils.LogError("error from spider: ", err) + log.Error().Msgf("error from spider: ", err) return nil, ErrCostResultEmpty } return nil, err } if res == nil || res.ResultsByTime == nil || len(res.ResultsByTime) == 0 { - utils.LogError("cost result is empty: ") + log.Error().Msgf("cost result is empty: ") return nil, ErrCostResultEmpty } var costInfos = make([]EstimateForecastCostInfo, 0) for _, result := range res.ResultsByTime { if result.Groups == nil { - utils.LogError("groups is nil; it must not be nil") + log.Error().Msgf("groups is nil; it must not be nil") return nil, ErrCostResultFormatInvalid } if result.TimePeriod == nil || result.TimePeriod.Start == nil || result.TimePeriod.End == nil { - utils.LogError("time period is nil; it must not be nil") + log.Error().Msgf("time period is nil; it must not be nil") return nil, ErrCostResultFormatInvalid } for _, group := range result.Groups { if group == nil { - utils.LogError("sinble group is nil; it must not be nil") + log.Error().Msgf("sinble group is nil; it must not be nil") continue } @@ -250,17 +251,17 @@ func (a *AwsCostExplorerBaristaCostCollector) GetCostInfos(ctx context.Context, awsService := constant.AwsService(category) resourceType, ok := serviceToResourceType[awsService] if !ok { - utils.LogErrorf("service : %s does not exist; category: %s", awsService, category) + log.Error().Msgf("service : %s does not exist; category: %s", awsService, category) continue } mt, ok := group.Metrics[metrics] if !ok { - utils.LogError("matric value does not exist:", metrics) + log.Error().Msgf("matric value does not exist:", metrics) continue } cost, err := strconv.ParseFloat(utils.NilSafeStr(mt.Amount), 64) if err != nil { - utils.LogError("cost parsing error:", mt.Amount) + log.Error().Msgf("cost parsing error:", mt.Amount) continue } unit := utils.NilSafeStr(mt.Unit) @@ -274,13 +275,13 @@ func (a *AwsCostExplorerBaristaCostCollector) GetCostInfos(ctx context.Context, startDate, err := time.Parse(time.RFC3339, utils.NilSafeStr(result.TimePeriod.Start)) if err != nil { - utils.LogError("start date parsing error:", result.TimePeriod.Start) + log.Error().Msgf("start date parsing error:", result.TimePeriod.Start) continue } endDate, err := time.Parse(time.RFC3339, utils.NilSafeStr(result.TimePeriod.End)) if err != nil { - utils.LogError("end date parsing error to ") + log.Error().Msgf("end date parsing error to ") continue } @@ -328,7 +329,7 @@ func (a *AwsCostExplorerBaristaCostCollector) UpdateEstimateForecastCost(ctx con mci, err := a.tc.GetMciWithContext(ctx, param.NsId, param.MciId) if err != nil { - utils.LogError("error while get mci from tumblebug; ", err) + log.Error().Msgf("error while get mci from tumblebug; ", err) return res, err } @@ -353,7 +354,7 @@ func (a *AwsCostExplorerBaristaCostCollector) UpdateEstimateForecastCost(ctx con pn := mci.ConnectionConfig.ProviderName if pn == "" || !strings.EqualFold(strings.ToLower(pn), "aws") { - utils.LogWarnf("CSP: %s, does not support yet", pn) + log.Warn().Msgf("CSP: %s, does not support yet", pn) continue } @@ -376,7 +377,7 @@ func (a *AwsCostExplorerBaristaCostCollector) UpdateEstimateForecastCost(ctx con infos, err := a.GetCostInfos(ctx, arg) if err != nil { - utils.LogError("error while get cost info from spider;", err) + log.Error().Msgf("error while get cost info from spider;", err) return res, fmt.Errorf("error from get cost infos +%w", err) } diff --git a/internal/core/cost/price_collector.go b/internal/core/cost/price_collector.go index 6ca512e..5547a9a 100644 --- a/internal/core/cost/price_collector.go +++ b/internal/core/cost/price_collector.go @@ -12,7 +12,7 @@ import ( "github.com/cloud-barista/cm-ant/internal/core/common/constant" "github.com/cloud-barista/cm-ant/internal/infra/outbound/spider" - "github.com/cloud-barista/cm-ant/internal/utils" + "github.com/rs/zerolog/log" ) type PriceCollector interface { @@ -137,23 +137,23 @@ func (s *SpiderPriceCollector) FetchPriceInfos(ctx context.Context, param Recomm currency = s.parseCurrency(policy.Currency) convertedPrice, err := strconv.ParseFloat(policy.Price, 64) if err != nil { - utils.LogWarnf("not allowed for error; %s", err) + log.Warn().Msgf("not allowed for error; %s", err) continue } if convertedPrice == float64(0) { - utils.LogWarn("not allowed for empty price") + log.Warn().Msg("not allowed for empty price") continue } price = s.naChecker(policy.Price) if price == "" { - utils.LogWarn("not allowed for empty price") + log.Warn().Msg("not allowed for empty price") continue } if strings.Contains(strings.ToLower(priceDescription), "dedicated") { - utils.LogWarnf("not allowed for dedicated instance hour; %s", priceDescription) + log.Warn().Msgf("not allowed for dedicated instance hour; %s", priceDescription) continue } @@ -259,7 +259,7 @@ func (s *SpiderPriceCollector) splitMemory(input string) (string, constant.Memor number, err := strconv.ParseFloat(strings.TrimSpace(numberPart), 64) if err != nil { - utils.LogErrorf("error while split memory : %s", err.Error()) + log.Error().Msgf("error while split memory : %s", err.Error()) return "", "" } diff --git a/internal/core/cost/service.go b/internal/core/cost/service.go index 8170b72..e9adb91 100644 --- a/internal/core/cost/service.go +++ b/internal/core/cost/service.go @@ -10,7 +10,6 @@ import ( "time" "github.com/cloud-barista/cm-ant/internal/core/common/constant" - "github.com/cloud-barista/cm-ant/internal/utils" "github.com/rs/zerolog/log" ) @@ -299,14 +298,14 @@ func (c *CostService) UpdateEstimateForecastCost(param UpdateEstimateForecastCos for _, costInfo := range r { u, i, err := c.costRepo.UpsertCostInfo(ctx, costInfo) if err != nil { - utils.LogErrorf("upsert error: %+v", costInfo) + log.Error().Msgf("upsert error: %+v", costInfo) } updatedCount += u insertedCount += i } - utils.LogInfof("updated count: %d; inserted count : %d", updatedCount, insertedCount) + log.Info().Msgf("updated count: %d; inserted count : %d", updatedCount, insertedCount) updateEstimateForecastCostInfoResult.UpdatedDataCount = updatedCount updateEstimateForecastCostInfoResult.InsertedDataCount = insertedCount @@ -356,13 +355,13 @@ func (c *CostService) UpdateEstimateForecastCostRaw(param UpdateEstimateForecast for _, costInfo := range r { u, i, err := c.costRepo.UpsertCostInfo(ctx, costInfo) if err != nil { - utils.LogErrorf("upsert error: %+v", costInfo) + log.Error().Msgf("upsert error: %+v", costInfo) } updatedCount += u insertedCount += i } - utils.LogInfof("updated count: %d; inserted count : %d", updatedCount, insertedCount) + log.Info().Msgf("updated count: %d; inserted count : %d", updatedCount, insertedCount) updateCostInfoResult.UpdatedDataCount = updatedCount updateCostInfoResult.InsertedDataCount = insertedCount diff --git a/internal/core/load/jmx_parser.go b/internal/core/load/jmx_parser.go index c161ac1..d55a914 100644 --- a/internal/core/load/jmx_parser.go +++ b/internal/core/load/jmx_parser.go @@ -5,12 +5,12 @@ import ( "fmt" "html" "io" - "log" "net/url" "strings" "text/template" "github.com/cloud-barista/cm-ant/internal/utils" + "github.com/rs/zerolog/log" ) type jmxTemplateData struct { @@ -205,7 +205,7 @@ func httpReqParseToJmx(httpReqs []RunLoadTestHttpParam) (string, error) { var buf bytes.Buffer err = tmpl.Execute(&buf, jmxHttpTemplateData) if err != nil { - log.Fatalf("Error executing template: %s", err) + log.Error().Msgf("Error executing template: %s", err) } builder.WriteString(buf.String()) } diff --git a/internal/core/load/load_generator_install_service.go b/internal/core/load/load_generator_install_service.go index 848ec56..75ba62c 100644 --- a/internal/core/load/load_generator_install_service.go +++ b/internal/core/load/load_generator_install_service.go @@ -66,7 +66,7 @@ func (l *LoadService) InstallLoadGenerator(param InstallLoadGeneratorParam) (Loa loadGeneratorInstallInfo.Status = "failed" err = l.loadRepo.UpdateLoadGeneratorInstallInfoTx(ctx, loadGeneratorInstallInfo) if err != nil { - utils.LogError("Error updating LoadGeneratorInstallInfo to failed status:", err) + log.Error().Msgf("Error updating LoadGeneratorInstallInfo to failed status; %v", err) } } }() @@ -81,7 +81,7 @@ func (l *LoadService) InstallLoadGenerator(param InstallLoadGeneratorParam) (Loa switch installLocation { case constant.Local: - utils.LogInfo("Starting local installation of JMeter") + log.Info().Msgf("Starting local installation of JMeter") jmeterPath := config.AppConfig.Load.JMeter.Dir jmeterVersion := config.AppConfig.Load.JMeter.Version @@ -94,18 +94,18 @@ func (l *LoadService) InstallLoadGenerator(param InstallLoadGeneratorParam) (Loa }) if err != nil { - utils.LogError("Error while installing JMeter locally:", err) + log.Error().Msgf("Error while installing JMeter locally; %v", err) return result, fmt.Errorf("error while installing jmeter; %s", err) } } - utils.LogInfo("Local installation of JMeter completed successfully") + log.Info().Msg("Local installation of JMeter completed successfully") case constant.Remote: - utils.LogInfo("Starting remote installation of JMeter") + log.Info().Msg("Starting remote installation of JMeter") // get the spec and image information recommendVm, err := l.getRecommendVm(ctx, param.Coordinates) if err != nil { - utils.LogError("Failed to get recommended VM:", err) + log.Error().Msgf("Failed to get recommended VM; %v", err) return result, err } antVmCommonSpec := recommendVm[0].Name @@ -113,38 +113,38 @@ func (l *LoadService) InstallLoadGenerator(param InstallLoadGeneratorParam) (Loa antVmCommonImage, err := utils.ReplaceAtIndex(antVmCommonSpec, imageOs, "+", 2) if err != nil { - utils.LogError("Error replacing VM spec index:", err) + log.Error().Msgf("Error replacing VM spec index; %v", err) return result, err } // check namespace is valid or not err = l.validDefaultNs(ctx, antNsId) if err != nil { - utils.LogError("Error validating default namespace:", err) + log.Error().Msgf("Error validating default namespace; %v", err) return result, err } // get the ant default mci antMci, err := l.getAndDefaultMci(ctx, antVmCommonSpec, antVmCommonImage, recommendVmConnName) if err != nil { - utils.LogError("Error getting or creating default mci:", err) + log.Error().Msgf("Error getting or creating default mci; %v", err) return result, err } // if server is not running state, try to resume and get mci information retryCount := config.AppConfig.Load.Retry for retryCount > 0 && antMci.StatusCount.CountRunning < 1 { - utils.LogInfof("Attempting to resume MCI, retry count: %d", retryCount) + log.Info().Msgf("Attempting to resume MCI, retry count: %d", retryCount) err = l.tumblebugClient.ControlLifecycleWithContext(ctx, antNsId, antMci.Id, "resume") if err != nil { - utils.LogError("Error resuming MCI:", err) + log.Error().Msgf("Error resuming MCI; %v", err) return result, err } time.Sleep(defaultDelay) antMci, err = l.getAndDefaultMci(ctx, antVmCommonSpec, antVmCommonImage, recommendVmConnName) if err != nil { - utils.LogError("Error getting MCI after resume attempt:", err) + log.Error().Msgf("Error getting MCI after resume attempt; %v", err) return result, err } @@ -152,19 +152,19 @@ func (l *LoadService) InstallLoadGenerator(param InstallLoadGeneratorParam) (Loa } if antMci.StatusCount.CountRunning < 1 { - utils.LogError("No running VM on ant default MCI") + log.Error().Msg("No running VM on ant default MCI") return result, errors.New("there is no running vm on ant default mci") } addAuthorizedKeyCommand, err := getAddAuthorizedKeyCommand(antPrivKeyName, antPubKeyName) if err != nil { - utils.LogError("Error getting add authorized key command:", err) + log.Error().Msgf("Error getting add authorized key command; %v", err) return result, err } installationCommand, err := utils.ReadToString(installScriptPath) if err != nil { - utils.LogError("Error reading installation script:", err) + log.Error().Msgf("Error reading installation script; %v", err) return result, err } @@ -174,11 +174,11 @@ func (l *LoadService) InstallLoadGenerator(param InstallLoadGeneratorParam) (Loa _, err = l.tumblebugClient.CommandToMciWithContext(ctx, antNsId, antMci.Id, commandReq) if err != nil { - utils.LogError("Error sending command to MCI:", err) + log.Error().Msgf("Error sending command to MCI; %v", err) return result, err } - utils.LogInfo("Commands sent to MCI successfully") + log.Info().Msg("Commands sent to MCI successfully") marking := make(map[string]LoadGeneratorServer) deleteChecker := make(map[uint]bool) @@ -260,7 +260,7 @@ func (l *LoadService) InstallLoadGenerator(param InstallLoadGeneratorParam) (Loa if len(deleteList) > 0 { err = l.loadRepo.DeleteLoadGeneratorServerTx(ctx, deleteList) if err != nil { - utils.LogError("Error delete load generator list:", err) + log.Error().Msgf("Error delete load generator list; %s", err) return result, err } } @@ -273,11 +273,11 @@ func (l *LoadService) InstallLoadGenerator(param InstallLoadGeneratorParam) (Loa loadGeneratorInstallInfo.Status = "installed" err = l.loadRepo.UpdateLoadGeneratorInstallInfoTx(ctx, loadGeneratorInstallInfo) if err != nil { - utils.LogError("Error updating LoadGeneratorInstallInfo after installed:", err) + log.Error().Msgf("Error updating LoadGeneratorInstallInfo after installed; %v", err) return result, err } - utils.LogInfo("LoadGeneratorInstallInfo updated successfully") + log.Info().Msg("LoadGeneratorInstallInfo updated successfully") loadGeneratorServerResults := make([]LoadGeneratorServerResult, 0) for _, l := range loadGeneratorInstallInfo.LoadGeneratorServers { @@ -317,7 +317,7 @@ func (l *LoadService) InstallLoadGenerator(param InstallLoadGeneratorParam) (Loa result.UpdatedAt = loadGeneratorInstallInfo.UpdatedAt result.LoadGeneratorServers = loadGeneratorServerResults - utils.LogInfo("InstallLoadGenerator completed successfully") + log.Info().Msg("InstallLoadGenerator completed successfully") return result, nil } @@ -480,10 +480,10 @@ func (l *LoadService) UninstallLoadGenerator(param UninstallLoadGeneratorParam) if err != nil { if errors.Is(err, gorm.ErrRecordNotFound) { - utils.LogError("Cannot find valid load generator install info:", err) + log.Error().Msgf("Cannot find valid load generator install info; %v", err) return errors.New("cannot find valid load generator install info") } - utils.LogError("Error retrieving load generator install info:", err) + log.Error().Msgf("Error retrieving load generator install info; %v", err) return err } @@ -496,14 +496,14 @@ func (l *LoadService) UninstallLoadGenerator(param UninstallLoadGeneratorParam) fmt.Sprintf("JMETER_VERSION=%s", config.AppConfig.Load.JMeter.Version), }) if err != nil { - utils.LogErrorf("Error while uninstalling load generator: %s", err) + log.Error().Msgf("Error while uninstalling load generator; %s", err) return fmt.Errorf("error while uninstalling load generator: %s", err) } case constant.Remote: uninstallCommand, err := utils.ReadToString(uninstallScriptPath) if err != nil { - utils.LogError("Error reading uninstall script:", err) + log.Error().Msgf("Error reading uninstall script; %v", err) return err } @@ -514,10 +514,10 @@ func (l *LoadService) UninstallLoadGenerator(param UninstallLoadGeneratorParam) _, err = l.tumblebugClient.CommandToMciWithContext(ctx, antNsId, antMciId, commandReq) if err != nil { if errors.Is(err, context.DeadlineExceeded) { - utils.LogError("VM is not in running state. Cannot connect to the VMs.") + log.Error().Msg("VM is not in running state. Cannot connect to the VMs.") return errors.New("vm is not running state. cannot connect to the vms") } - utils.LogError("Error sending uninstall command to MCI:", err) + log.Error().Msgf("Error sending uninstall command to MCI; %v", err) return err } @@ -534,11 +534,11 @@ func (l *LoadService) UninstallLoadGenerator(param UninstallLoadGeneratorParam) err = l.loadRepo.UpdateLoadGeneratorInstallInfoTx(ctx, &loadGeneratorInstallInfo) if err != nil { - utils.LogError("Error updating load generator install info:", err) + log.Error().Msgf("Error updating load generator install info; %v", err) return err } - utils.LogInfo("Successfully uninstalled load generator.") + log.Info().Msg("Successfully uninstalled load generator.") return nil } @@ -551,7 +551,7 @@ func (l *LoadService) GetAllLoadGeneratorInstallInfo(param GetAllLoadGeneratorIn pagedResult, totalRows, err := l.loadRepo.GetPagingLoadGeneratorInstallInfosTx(ctx, param) if err != nil { - utils.LogError("Error fetching paged load generator install infos:", err) + log.Error().Msgf("Error fetching paged load generator install infos; %v", err) return result, err } @@ -600,7 +600,7 @@ func (l *LoadService) GetAllLoadGeneratorInstallInfo(param GetAllLoadGeneratorIn result.LoadGeneratorInstallInfoResults = infos result.TotalRows = totalRows - utils.LogInfof("Fetched %d load generator install info results.", len(infos)) + log.Info().Msgf("Fetched %d load generator install info results. length: %d", len(infos)) return result, nil } diff --git a/internal/core/load/load_test_execution_service.go b/internal/core/load/load_test_execution_service.go index 05df68c..4c70c23 100644 --- a/internal/core/load/load_test_execution_service.go +++ b/internal/core/load/load_test_execution_service.go @@ -401,13 +401,13 @@ func (l *LoadService) executeLoadTest(param RunLoadTestParam, loadGeneratorInsta resultFileName := fmt.Sprintf("%s_result.csv", loadTestKey) loadGeneratorInstallVersion := loadGeneratorInstallInfo.InstallVersion - utils.LogInfof("Running load test with key: %s", loadTestKey) + log.Info().Msgf("Running load test with key: %s", loadTestKey) compileDuration := "0" executionDuration := "0" start := time.Now() if installLocation == constant.Remote { - utils.LogInfo("Remote execute detected.") + log.Info().Msg("Remote execute detected.") var buf bytes.Buffer err := parseTestPlanStructToString(&buf, param, loadGeneratorInstallInfo) if err != nil { @@ -445,7 +445,7 @@ func (l *LoadService) executeLoadTest(param RunLoadTestParam, loadGeneratorInsta } } else if installLocation == constant.Local { - utils.LogInfo("Local execute detected.") + log.Info().Msg("Local execute detected.") exist := utils.ExistCheck(loadGeneratorInstallPath) @@ -480,14 +480,14 @@ func (l *LoadService) executeLoadTest(param RunLoadTestParam, loadGeneratorInsta func (l *LoadService) updateLoadTestExecution(loadTestExecutionState *LoadTestExecutionState) error { err := l.loadRepo.UpdateLoadTestExecutionInfoDuration(context.Background(), loadTestExecutionState.LoadTestKey, loadTestExecutionState.CompileDuration, loadTestExecutionState.ExecutionDuration) if err != nil { - utils.LogErrorf("Error updating load test execution info: %v", err) + log.Error().Msgf("Error updating load test execution info; %v", err) return err } loadTestExecutionState.ExecutionStatus = constant.OnFetching err = l.loadRepo.UpdateLoadTestExecutionStateTx(context.Background(), loadTestExecutionState) if err != nil { - utils.LogErrorf("Error updating load test execution state: %v", err) + log.Error().Msgf("Error updating load test execution state; %v", err) return err } return nil @@ -496,7 +496,7 @@ func (l *LoadService) updateLoadTestExecution(loadTestExecutionState *LoadTestEx // generateJmeterExecutionCmd generates the JMeter execution command. // Constructs a JMeter command string that includes the test plan path and result file path. func generateJmeterExecutionCmd(loadGeneratorInstallPath, loadGeneratorInstallVersion, testPlanName, resultFileName string) string { - utils.LogInfof("Generating JMeter execution command for test plan: %s, result file: %s", testPlanName, resultFileName) + log.Info().Msgf("Generating JMeter execution command for test plan: %s, result file: %s", testPlanName, resultFileName) var builder strings.Builder testPath := fmt.Sprintf("%s/test_plan/%s", loadGeneratorInstallPath, testPlanName) @@ -508,7 +508,7 @@ func generateJmeterExecutionCmd(loadGeneratorInstallPath, loadGeneratorInstallVe builder.WriteString(fmt.Sprintf(" -l=%s", resultPath)) builder.WriteString(fmt.Sprintf(" && sudo rm %s", testPath)) - utils.LogInfof("JMeter execution command generated: %s", builder.String()) + log.Info().Msgf("JMeter execution command generated: %s", builder.String()) return builder.String() } @@ -575,6 +575,6 @@ func (l *LoadService) StopLoadTest(param StopLoadTestParam) error { func killCmdGen(loadTestKey string) string { grepRegex := fmt.Sprintf("'\\/bin\\/ApacheJMeter\\.jar.*%s'", loadTestKey) - utils.LogInfof("Generating kill command for load test key: %s", loadTestKey) + log.Info().Msgf("Generating kill command for load test key: %s", loadTestKey) return fmt.Sprintf("kill -15 $(ps -ef | grep -E %s | awk '{print $2}')", grepRegex) } diff --git a/internal/core/load/metrics_agent_service.go b/internal/core/load/metrics_agent_service.go index 394ef13..46fdb8c 100644 --- a/internal/core/load/metrics_agent_service.go +++ b/internal/core/load/metrics_agent_service.go @@ -9,33 +9,34 @@ import ( "github.com/cloud-barista/cm-ant/internal/infra/outbound/tumblebug" "github.com/cloud-barista/cm-ant/internal/utils" + "github.com/rs/zerolog/log" ) // InstallMonitoringAgent installs a monitoring agent on specified VMs or all VM on mci. func (l *LoadService) InstallMonitoringAgent(param MonitoringAgentInstallationParams) ([]MonitoringAgentInstallationResult, error) { - utils.LogInfo("Starting installation of monitoring agent...") + log.Info().Msg("Starting installation of monitoring agent...") ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second) defer cancel() var res []MonitoringAgentInstallationResult scriptPath := utils.JoinRootPathWith("/script/install-server-agent.sh") - utils.LogInfof("Reading installation script from %s", scriptPath) + log.Info().Msgf("Reading installation script from %s", scriptPath) installScript, err := os.ReadFile(scriptPath) if err != nil { - utils.LogErrorf("Failed to read installation script: %v", err) + log.Error().Msgf("Failed to read installation script; %v", err) return res, err } username := "cb-user" - utils.LogInfof("Fetching mci object for NS: %s, msi id: %s", param.NsId, param.MciId) + log.Info().Msgf("Fetching mci object for NS: %s, msi id: %s", param.NsId, param.MciId) mci, err := l.tumblebugClient.GetMciWithContext(ctx, param.NsId, param.MciId) if err != nil { - utils.LogErrorf("Failed to fetch mci : %v", err) + log.Error().Msgf("Failed to fetch mci; %v", err) return res, err } if len(mci.Vm) == 0 { - utils.LogErrorf("No VMs found on mci. Provision VM first.") + log.Error().Msg("No VMs found on mci. Provision VM first.") return res, errors.New("there is no vm on mci. provision vm first") } @@ -61,10 +62,10 @@ func (l *LoadService) InstallMonitoringAgent(param MonitoringAgentInstallationPa VmId: vm.Id, VmCount: len(mci.Vm), } - utils.LogInfof("Inserting monitoring agent installation info into database vm id : %s", vm.Id) + log.Info().Msgf("Inserting monitoring agent installation info into database vm id : %s", vm.Id) err = l.loadRepo.InsertMonitoringAgentInfoTx(ctx, &m) if err != nil { - utils.LogErrorf("Failed to insert monitoring agent info for vm id %s : %v", vm.Id, err) + log.Error().Msgf("Failed to insert monitoring agent info for vm id %s : %v", vm.Id, err) errorCollection = append(errorCollection, err) continue } @@ -74,16 +75,16 @@ func (l *LoadService) InstallMonitoringAgent(param MonitoringAgentInstallationPa UserName: username, } - utils.LogInfof("Sending install command to mci. NS: %s, mci: %s, VMID: %s", param.NsId, param.MciId, vm.Id) + log.Info().Msgf("Sending install command to mci. NS: %s, mci: %s, VMID: %s", param.NsId, param.MciId, vm.Id) _, err = l.tumblebugClient.CommandToVmWithContext(ctx, param.NsId, param.MciId, vm.Id, commandReq) if err != nil { if errors.Is(err, context.DeadlineExceeded) { m.Status = "timeout" - utils.LogErrorf("Timeout of context. Already 15 seconds has been passed. vm id : %s", vm.Id) + log.Error().Msgf("Timeout of context. Already 15 seconds has been passed. vm id; %s", vm.Id) } else { m.Status = "failed" - utils.LogErrorf("Error occurred during command execution: %v", err) + log.Error().Msgf("Error occurred during command execution; %v", err) } errorCollection = append(errorCollection, err) } else { @@ -106,7 +107,7 @@ func (l *LoadService) InstallMonitoringAgent(param MonitoringAgentInstallationPa } res = append(res, r) - utils.LogInfof( + log.Info().Msgf( "Complete installing monitoring agent on mics: %s, vm: %s", m.MciId, m.VmId, @@ -128,15 +129,15 @@ func (l *LoadService) GetAllMonitoringAgentInfos(param GetAllMonitoringAgentInfo ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second) defer cancel() - utils.LogInfof("GetAllMonitoringAgentInfos called with param: %+v", param) + log.Info().Msgf("GetAllMonitoringAgentInfos called with param: %+v", param) result, totalRows, err := l.loadRepo.GetPagingMonitoringAgentInfosTx(ctx, param) if err != nil { - utils.LogErrorf("Error fetching monitoring agent infos: %v", err) + log.Error().Msgf("Error fetching monitoring agent infos; %v", err) return res, err } - utils.LogInfof("Fetched %d monitoring agent infos", len(result)) + log.Info().Msgf("Fetched %d monitoring agent infos", len(result)) for _, monitoringAgentInfo := range result { var r MonitoringAgentInstallationResult @@ -166,20 +167,20 @@ func (l *LoadService) UninstallMonitoringAgent(param MonitoringAgentInstallation ctx := context.Background() var effectedResults int64 - utils.LogInfo("Starting uninstallation of monitoring agent...") + log.Info().Msg("Starting uninstallation of monitoring agent...") result, err := l.loadRepo.GetAllMonitoringAgentInfosTx(ctx, param) if err != nil { - utils.LogErrorf("Failed to fetch monitoring agent information: %v", err) + log.Error().Msgf("Failed to fetch monitoring agent information; %v", err) return effectedResults, err } scriptPath := utils.JoinRootPathWith("/script/remove-server-agent.sh") - utils.LogInfof("Reading uninstallation script from %s", scriptPath) + log.Info().Msgf("Reading uninstallation script from %s", scriptPath) uninstallPath, err := os.ReadFile(scriptPath) if err != nil { - utils.LogErrorf("Failed to read uninstallation script: %v", err) + log.Error().Msgf("Failed to read uninstallation script; %v", err) return effectedResults, err } @@ -198,19 +199,19 @@ func (l *LoadService) UninstallMonitoringAgent(param MonitoringAgentInstallation _, err = l.tumblebugClient.CommandToVmWithContext(ctx, monitoringAgentInfo.NsId, monitoringAgentInfo.MciId, monitoringAgentInfo.VmId, commandReq) if err != nil { errorCollection = append(errorCollection, err) - utils.LogErrorf("Failed to uninstall monitoring agent on mci: %s, VM: %s - Error: %v", monitoringAgentInfo.MciId, monitoringAgentInfo.VmId, err) + log.Error().Msgf("Failed to uninstall monitoring agent on mci: %s, VM: %s - Error: %v", monitoringAgentInfo.MciId, monitoringAgentInfo.VmId, err) continue } err = l.loadRepo.DeleteAgentInstallInfoStatusTx(ctx, &monitoringAgentInfo) if err != nil { - utils.LogErrorf("Failed to delete agent installation status for mci: %s, VM: %s - Error: %v", monitoringAgentInfo.MciId, monitoringAgentInfo.VmId, err) + log.Error().Msgf("Failed to delete agent installation status for mci: %s, VM: %s - Error: %v", monitoringAgentInfo.MciId, monitoringAgentInfo.VmId, err) errorCollection = append(errorCollection, err) continue } - utils.LogInfof("Successfully uninstalled monitoring agent on mci: %s, VM: %s", monitoringAgentInfo.MciId, monitoringAgentInfo.VmId) + log.Info().Msgf("Successfully uninstalled monitoring agent on mci: %s, VM: %s", monitoringAgentInfo.MciId, monitoringAgentInfo.VmId) time.Sleep(time.Second) } diff --git a/internal/core/load/performace_evaluation_service.go b/internal/core/load/performace_evaluation_service.go index 8fcf498..f189f35 100644 --- a/internal/core/load/performace_evaluation_service.go +++ b/internal/core/load/performace_evaluation_service.go @@ -6,7 +6,7 @@ import ( "github.com/cloud-barista/cm-ant/internal/core/common/constant" "github.com/cloud-barista/cm-ant/internal/infra/outbound/tumblebug" - "github.com/cloud-barista/cm-ant/internal/utils" + "github.com/rs/zerolog/log" ) // LoadService represents a service for managing load operations. @@ -51,15 +51,15 @@ func (l *LoadService) GetAllLoadTestExecutionState(param GetAllLoadTestExecution ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second) defer cancel() - utils.LogInfof("GetAllLoadExecutionStates called with param: %+v", param) + log.Info().Msgf("GetAllLoadExecutionStates called with param: %+v", param) result, totalRows, err := l.loadRepo.GetPagingLoadTestExecutionStateTx(ctx, param) if err != nil { - utils.LogErrorf("Error fetching load test execution state infos: %v", err) + log.Error().Msgf("Error fetching load test execution state infos; %v", err) return res, err } - utils.LogInfof("Fetched %d monitoring agent infos", len(result)) + log.Info().Msgf("Fetched %d monitoring agent infos", len(result)) for _, loadTestExecutionState := range result { state := mapLoadTestExecutionStateResult(loadTestExecutionState) @@ -78,11 +78,11 @@ func (l *LoadService) GetLoadTestExecutionState(param GetLoadTestExecutionStateP ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second) defer cancel() - utils.LogInfof("GetLoadTestExecutionState called with param: %+v", param) + log.Info().Msgf("GetLoadTestExecutionState called with param: %+v", param) state, err := l.loadRepo.GetLoadTestExecutionStateTx(ctx, param) if err != nil { - utils.LogErrorf("Error fetching load test execution state infos: %v", err) + log.Error().Msgf("Error fetching load test execution state infos; %v", err) return res, err } @@ -97,15 +97,15 @@ func (l *LoadService) GetAllLoadTestExecutionInfos(param GetAllLoadTestExecution ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second) defer cancel() - utils.LogInfof("GetAllLoadTestExecutionInfos called with param: %+v", param) + log.Info().Msgf("GetAllLoadTestExecutionInfos called with param: %+v", param) result, totalRows, err := l.loadRepo.GetPagingLoadTestExecutionHistoryTx(ctx, param) if err != nil { - utils.LogErrorf("Error fetching load test execution infos: %v", err) + log.Error().Msgf("Error fetching load test execution infos; %v", err) return res, err } - utils.LogInfof("Fetched %d load test execution infos:", len(result)) + log.Info().Msgf("Fetched %d load test execution infos:", len(result)) for _, r := range result { rs = append(rs, mapLoadTestExecutionInfoResult(r)) @@ -122,11 +122,11 @@ func (l *LoadService) GetLoadTestExecutionInfo(param GetLoadTestExecutionInfoPar ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second) defer cancel() - utils.LogInfof("GetLoadTestExecutionInfo called with param: %+v", param) + log.Info().Msgf("GetLoadTestExecutionInfo called with param: %+v", param) executionInfo, err := l.loadRepo.GetLoadTestExecutionInfoTx(ctx, param) if err != nil { - utils.LogErrorf("Error fetching load test execution state infos: %v", err) + log.Error().Msgf("Error fetching load test execution state infos; %v", err) return res, err } @@ -152,7 +152,7 @@ func mapLoadTestExecutionStateResult(state LoadTestExecutionState) LoadTestExecu ExecutionStatus: state.ExecutionStatus, StartAt: state.StartAt, FinishAt: state.FinishAt, - ExpectedFinishAt: state.ExpectedFinishAt, + ExpectedFinishAt: state.ExpectedFinishAt, TotalExpectedExcutionSecond: state.TotalExpectedExcutionSecond, FailureMessage: state.FailureMessage, CompileDuration: state.CompileDuration, @@ -161,7 +161,6 @@ func mapLoadTestExecutionStateResult(state LoadTestExecutionState) LoadTestExecu UpdatedAt: state.UpdatedAt, } - if stateResult.ExecutionStatus == constant.Successed { stateResult.IconCode = constant.Ok } else if stateResult.ExecutionStatus == constant.TestFailed { @@ -172,7 +171,6 @@ func mapLoadTestExecutionStateResult(state LoadTestExecutionState) LoadTestExecu return *stateResult - } func mapLoadGeneratorServerResult(s LoadGeneratorServer) LoadGeneratorServerResult { diff --git a/internal/core/load/performance_evaluation_result_service.go b/internal/core/load/performance_evaluation_result_service.go index d42fcaa..a5258b7 100644 --- a/internal/core/load/performance_evaluation_result_service.go +++ b/internal/core/load/performance_evaluation_result_service.go @@ -146,7 +146,7 @@ func (l *LoadService) GetLastLoadTestResult(param GetLastLoadTestResultParam) (i state, err := l.loadRepo.GetLoadTestExecutionStateTx(ctx, stateQueryParam) if err != nil { - utils.LogErrorf("Error fetching load test execution state infos: %v", err) + log.Error().Msgf("Error fetching load test execution state infos; %v", err) return nil, err } @@ -190,7 +190,7 @@ func (l *LoadService) GetLastLoadTestMetrics(param GetLastLoadTestResultParam) ( state, err := l.loadRepo.GetLoadTestExecutionStateTx(ctx, stateQueryParam) if err != nil { - utils.LogErrorf("Error fetching load test execution state infos: %v", err) + log.Error().Msgf("Error fetching load test execution state infos; %v", err) return nil, err } diff --git a/internal/core/load/rsync_fetch_service.go b/internal/core/load/rsync_fetch_service.go index abe3136..7d576fa 100644 --- a/internal/core/load/rsync_fetch_service.go +++ b/internal/core/load/rsync_fetch_service.go @@ -126,7 +126,7 @@ func rsyncFiles(f *fetchDataParam) error { toFilePath) } - utils.LogInfo("cmd for rsync: ", cmd) + log.Info().Msgf("cmd for rsync: %s", cmd) err := utils.InlineCmd(cmd) if err == nil { @@ -134,7 +134,7 @@ func rsyncFiles(f *fetchDataParam) error { return // Success, exit the retry loop } - utils.LogError(fmt.Sprintf("Error during rsync attempt %d for %s: %v", attempt, fileName, err)) + log.Error().Msgf(fmt.Sprintf("Error during rsync attempt %d for %s: %v", attempt, fileName, err)) // Wait before retrying if attempt < maxRetries { diff --git a/internal/infra/outbound/spider/price.go b/internal/infra/outbound/spider/price.go index c24d3ca..6608917 100644 --- a/internal/infra/outbound/spider/price.go +++ b/internal/infra/outbound/spider/price.go @@ -5,10 +5,9 @@ import ( "encoding/json" "errors" "fmt" - "log" "net/http" - "github.com/cloud-barista/cm-ant/internal/utils" + "github.com/rs/zerolog/log" ) const ( @@ -23,14 +22,14 @@ func (s *SpiderClient) GetPriceInfoWithContext(ctx context.Context, regionName s marshalledBody, err := json.Marshal(body) if err != nil { - log.Println("marshalling body error;", err) + log.Error().Msgf("marshalling body error; %v", err) return cloudPriceData, err } resBytes, err := s.requestWithContext(ctx, http.MethodPost, url, marshalledBody, nil) if err != nil { - utils.LogError("error sending get price info data request:", err) + log.Error().Msgf("error sending get price info data request; %v", err) return cloudPriceData, fmt.Errorf("failed to send request: %w", err) } @@ -38,7 +37,7 @@ func (s *SpiderClient) GetPriceInfoWithContext(ctx context.Context, regionName s err = json.Unmarshal(resBytes, &cloudPriceData) if err != nil { - utils.LogError("error unmarshaling response body:", err) + log.Error().Msgf("error unmarshaling response body; %v", err) return cloudPriceData, fmt.Errorf("failed to unmarshal response body: %w", err) } @@ -57,14 +56,14 @@ func (s *SpiderClient) GetCostWithResourceWithContext(ctx context.Context, body marshalledBody, err := json.Marshal(body) if err != nil { - log.Println("marshalling body error;", err) + log.Error().Msgf("marshalling body error; %v", err) return &costWithResourceRes, err } resBytes, err := s.requestWithContext(ctx, http.MethodPost, url, marshalledBody, nil) if err != nil { - utils.LogError("error sending get cost info data request:", err) + log.Error().Msgf("error sending get cost info data request; %v", err) return &costWithResourceRes, fmt.Errorf("failed to send request: %w", err) } @@ -72,7 +71,7 @@ func (s *SpiderClient) GetCostWithResourceWithContext(ctx context.Context, body err = json.Unmarshal(resBytes, &anycallRes) if err != nil { - utils.LogError("error unmarshaling response body:", err) + log.Error().Msgf("error unmarshaling response body; %v", err) return &costWithResourceRes, fmt.Errorf("failed to unmarshal response body: %w", err) } @@ -83,7 +82,7 @@ func (s *SpiderClient) GetCostWithResourceWithContext(ctx context.Context, body err = json.Unmarshal([]byte(anycallRes.OKeyValueList[0].Value), &costWithResourceRes) if err != nil { - utils.LogError("error unmarshaling :", err) + log.Error().Msgf("error unmarshaling; %v", err) return &costWithResourceRes, fmt.Errorf("failed to unmarshal response body: %w", err) } diff --git a/internal/infra/outbound/spider/spider_client.go b/internal/infra/outbound/spider/spider_client.go index ba97371..69a446c 100644 --- a/internal/infra/outbound/spider/spider_client.go +++ b/internal/infra/outbound/spider/spider_client.go @@ -11,7 +11,7 @@ import ( "strings" "github.com/cloud-barista/cm-ant/internal/config" - "github.com/cloud-barista/cm-ant/internal/utils" + "github.com/rs/zerolog/log" ) var ( @@ -62,7 +62,7 @@ func (s *SpiderClient) withUrl(endpoint string) string { func (s *SpiderClient) requestWithContext(ctx context.Context, method, url string, body []byte, header map[string]string) ([]byte, error) { req, err := http.NewRequestWithContext(ctx, method, url, bytes.NewBuffer(body)) if err != nil { - utils.LogErrorf("Failed to create request with context: %v", err) + log.Error().Msgf("Failed to create request with context; %v", err) return nil, fmt.Errorf("failed to create request: %w", err) } @@ -71,17 +71,17 @@ func (s *SpiderClient) requestWithContext(ctx context.Context, method, url strin req.Header.Add(k, v) } - utils.LogInfof("Sending request to client with endpoint [%s - %s]\n", method, url) + log.Info().Msgf("Sending request to client with endpoint [%s - %s]\n", method, url) resp, err := s.client.Do(req) if err != nil { - utils.LogErrorf("Failed to send request: %v", err) + log.Error().Msgf("Failed to send request; %v", err) return nil, fmt.Errorf("failed to send request: %w", err) } defer resp.Body.Close() if resp.StatusCode < http.StatusOK || resp.StatusCode >= http.StatusBadRequest { rb, _ := io.ReadAll(resp.Body) - utils.LogErrorf("Unexpected status code: %d, response: %s", resp.StatusCode, string(rb)) + log.Error().Msgf("Unexpected status code: %d, response: %s", resp.StatusCode, string(rb)) if resp.StatusCode == http.StatusNotFound { return nil, ErrNotFound @@ -96,11 +96,11 @@ func (s *SpiderClient) requestWithContext(ctx context.Context, method, url strin rb, err := io.ReadAll(resp.Body) if err != nil { - utils.LogErrorf("Failed to read response body: %v", err) + log.Error().Msgf("Failed to read response body; %v", err) return nil, fmt.Errorf("failed to read response body: %w", err) } - utils.LogInfo("Request with context completed successfully.") + log.Info().Msg("Request with context completed successfully.") return rb, nil } @@ -114,7 +114,7 @@ func (s *SpiderClient) ReadyzWithContext(ctx context.Context) error { _, err := s.requestWithBaseAuthWithContext(ctx, http.MethodGet, url, nil) if err != nil { - utils.LogError("error sending tumblebug readyz request:", err) + log.Error().Msgf("error sending tumblebug readyz request; %v", err) return err } diff --git a/internal/infra/outbound/tumblebug/mci.go b/internal/infra/outbound/tumblebug/mci.go index 14d4593..2930622 100644 --- a/internal/infra/outbound/tumblebug/mci.go +++ b/internal/infra/outbound/tumblebug/mci.go @@ -7,7 +7,7 @@ import ( "fmt" "net/http" - "github.com/cloud-barista/cm-ant/internal/utils" + "github.com/rs/zerolog/log" ) func (t *TumblebugClient) GetMciWithContext(ctx context.Context, nsId, mciId string) (MciRes, error) { @@ -17,7 +17,7 @@ func (t *TumblebugClient) GetMciWithContext(ctx context.Context, nsId, mciId str resBytes, err := t.requestWithBaseAuthWithContext(ctx, http.MethodGet, url, nil) if err != nil { - utils.LogError("error sending get mci request:", err) + log.Error().Msgf("error sending get mci request; %v", err) if errors.Is(err, ErrInternalServerError) { return mciObject, ErrNotFound @@ -28,7 +28,7 @@ func (t *TumblebugClient) GetMciWithContext(ctx context.Context, nsId, mciId str err = json.Unmarshal(resBytes, &mciObject) if err != nil { - utils.LogError("error unmarshaling response body:", err) + log.Error().Msgf("error unmarshaling response body; %v", err) return mciObject, fmt.Errorf("failed to unmarshal response body: %w", err) } @@ -41,14 +41,14 @@ func (t *TumblebugClient) CommandToMciWithContext(ctx context.Context, nsId, mci marshalledBody, err := json.Marshal(body) if err != nil { - utils.LogError("error marshaling request body:", err) + log.Error().Msgf("error marshaling request body; %v", err) return "", err } resBytes, err := t.requestWithBaseAuthWithContext(ctx, http.MethodPost, url, marshalledBody) if err != nil { - utils.LogError("error sending command to mci request:", err) + log.Error().Msgf("error sending command to mci request; %v", err) return "", fmt.Errorf("failed to send request: %w", err) } @@ -63,14 +63,14 @@ func (t *TumblebugClient) CommandToVmWithContext(ctx context.Context, nsId, mciI marshalledBody, err := json.Marshal(body) if err != nil { - utils.LogError("error marshaling request body:", err) + log.Error().Msgf("error marshaling request body; %v", err) return "", err } resBytes, err := t.requestWithBaseAuthWithContext(ctx, http.MethodPost, url, marshalledBody) if err != nil { - utils.LogError("error sending command to vm request:", err) + log.Error().Msgf("error sending command to vm request; %v", err) return "", fmt.Errorf("failed to send request: %w", err) } @@ -86,14 +86,14 @@ func (t *TumblebugClient) GetNsWithContext(ctx context.Context, nsId string) (Ge resBytes, err := t.requestWithBaseAuthWithContext(ctx, http.MethodGet, url, nil) if err != nil { - utils.LogError("error sending get mci request:", err) + log.Error().Msgf("error sending get mci request; %v", err) return nsRes, fmt.Errorf("failed to send request: %w", err) } err = json.Unmarshal(resBytes, &nsRes) if err != nil { - utils.LogError("error unmarshaling response body:", err) + log.Error().Msgf("error unmarshaling response body; %v", err) return nsRes, fmt.Errorf("failed to unmarshal response body: %w", err) } @@ -106,21 +106,21 @@ func (t *TumblebugClient) GetRecommendVmWithContext(ctx context.Context, body Re marshalledBody, err := json.Marshal(body) if err != nil { - utils.LogError("error marshaling request body:", err) + log.Error().Msgf("error marshaling request body; %v", err) return res, err } resBytes, err := t.requestWithBaseAuthWithContext(ctx, http.MethodPost, url, marshalledBody) if err != nil { - utils.LogError("error sending get recommend vm request:", err) + log.Error().Msgf("error sending get recommend vm request; %v", err) return res, fmt.Errorf("failed to send request: %w", err) } err = json.Unmarshal(resBytes, &res) if err != nil { - utils.LogError("error unmarshaling response body:", err) + log.Error().Msgf("error unmarshaling response body; %v", err) return res, fmt.Errorf("failed to unmarshal response body: %w", err) } @@ -132,14 +132,14 @@ func (t *TumblebugClient) CreateNsWithContext(ctx context.Context, body CreateNs marshalledBody, err := json.Marshal(body) if err != nil { - utils.LogError("error marshaling request body:", err) + log.Error().Msgf("error marshaling request body; %v", err) return err } _, err = t.requestWithBaseAuthWithContext(ctx, http.MethodPost, url, marshalledBody) if err != nil { - utils.LogError("error sending create ns request:", err) + log.Error().Msgf("error sending create ns request; %v", err) return fmt.Errorf("failed to send request: %w", err) } @@ -152,21 +152,21 @@ func (t *TumblebugClient) DynamicVmWithContext(ctx context.Context, nsId, mciId marshalledBody, err := json.Marshal(body) if err != nil { - utils.LogError("error marshaling request body:", err) + log.Error().Msgf("error marshaling request body; %v", err) return res, err } resBytes, err := t.requestWithBaseAuthWithContext(ctx, http.MethodPost, url, marshalledBody) if err != nil { - utils.LogError("error sending dynamic vm request:", err) + log.Error().Msgf("error sending dynamic vm request; %v", err) return res, fmt.Errorf("failed to send request: %w", err) } err = json.Unmarshal(resBytes, &res) if err != nil { - utils.LogError("error unmarshaling response body:", err) + log.Error().Msgf("error unmarshaling response body; %v", err) return res, fmt.Errorf("failed to unmarshal response body: %w", err) } @@ -179,21 +179,21 @@ func (t *TumblebugClient) DynamicMciWithContext(ctx context.Context, nsId string marshalledBody, err := json.Marshal(body) if err != nil { - utils.LogError("error marshaling request body:", err) + log.Error().Msgf("error marshaling request body; %v", err) return res, err } resBytes, err := t.requestWithBaseAuthWithContext(ctx, http.MethodPost, url, marshalledBody) if err != nil { - utils.LogError("error sending dynamic mci request:", err) + log.Error().Msgf("error sending dynamic mci request; %v", err) return res, fmt.Errorf("failed to send request: %w", err) } err = json.Unmarshal(resBytes, &res) if err != nil { - utils.LogError("error unmarshaling response body:", err) + log.Error().Msgf("error unmarshaling response body; %v", err) return res, fmt.Errorf("failed to unmarshal response body: %w", err) } @@ -208,7 +208,7 @@ func (t *TumblebugClient) ControlLifecycleWithContext(ctx context.Context, nsId, _, err := t.requestWithBaseAuthWithContext(ctx, http.MethodGet, url, nil) if err != nil { - utils.LogError("error sending control lifecycle request:", err) + log.Error().Msgf("error sending control lifecycle request; %v", err) return fmt.Errorf("failed to send request: %w", err) } @@ -224,7 +224,7 @@ func (t *TumblebugClient) DeleteAllMciWithContext(ctx context.Context, nsId stri _, err := t.requestWithBaseAuthWithContext(ctx, http.MethodDelete, url, nil) if err != nil { - utils.LogError("error sending delete all mci request:", err) + log.Error().Msgf("error sending delete all mci request; %v", err) return fmt.Errorf("failed to send request: %w", err) } @@ -239,7 +239,7 @@ func (t *TumblebugClient) DeleteAllResourcesWithContext(ctx context.Context, nsI _, err := t.requestWithBaseAuthWithContext(ctx, http.MethodDelete, url, nil) if err != nil { - utils.LogError("error sending delete all mci request:", err) + log.Error().Msgf("error sending delete all mci request; %v", err) return fmt.Errorf("failed to send request: %w", err) } diff --git a/internal/infra/outbound/tumblebug/tumblebug_client.go b/internal/infra/outbound/tumblebug/tumblebug_client.go index 145ded1..9983bfa 100644 --- a/internal/infra/outbound/tumblebug/tumblebug_client.go +++ b/internal/infra/outbound/tumblebug/tumblebug_client.go @@ -7,12 +7,11 @@ import ( "errors" "fmt" "io" - "log" "net/http" "strings" "github.com/cloud-barista/cm-ant/internal/config" - "github.com/cloud-barista/cm-ant/internal/utils" + "github.com/rs/zerolog/log" ) var ( @@ -58,7 +57,7 @@ func (t *TumblebugClient) withUrl(endpoint string) string { func (t *TumblebugClient) requestWithContext(ctx context.Context, method, url string, body []byte, header map[string]string) ([]byte, error) { req, err := http.NewRequestWithContext(ctx, method, url, bytes.NewBuffer(body)) if err != nil { - log.Printf("[ERROR] Failed to create request with context: %v", err) + log.Error().Msgf("failed to create request with context: %v", err) return nil, fmt.Errorf("failed to create request: %w", err) } @@ -67,17 +66,17 @@ func (t *TumblebugClient) requestWithContext(ctx context.Context, method, url st req.Header.Add(k, v) } - utils.LogInfof("Sending request to client with endpoint [%s - %s]\n", method, url) + log.Info().Msgf("Sending request to client with endpoint [%s - %s]", method, url) resp, err := t.client.Do(req) if err != nil { - log.Printf("[ERROR] Failed to send request: %v", err) + log.Error().Msgf("failed to send request: %v", err) return nil, fmt.Errorf("failed to send request: %w", err) } defer resp.Body.Close() if resp.StatusCode < http.StatusOK || resp.StatusCode >= http.StatusBadRequest { rb, _ := io.ReadAll(resp.Body) - log.Printf("[ERROR] Unexpected status code: %d, response: %s", resp.StatusCode, string(rb)) + log.Error().Msgf("unexpected status code: %d, response: %s", resp.StatusCode, string(rb)) if resp.StatusCode == http.StatusNotFound { return nil, ErrNotFound @@ -92,11 +91,11 @@ func (t *TumblebugClient) requestWithContext(ctx context.Context, method, url st rb, err := io.ReadAll(resp.Body) if err != nil { - log.Printf("[ERROR] Failed to read response body: %v", err) + log.Error().Msgf("failed to read response body: %v", err) return nil, fmt.Errorf("failed to read response body: %w", err) } - utils.LogInfo("Request with context completed successfully.") + log.Info().Msg("Request with context completed successfully.") return rb, nil } @@ -110,7 +109,7 @@ func (t *TumblebugClient) ReadyzWithContext(ctx context.Context) error { _, err := t.requestWithBaseAuthWithContext(ctx, http.MethodGet, url, nil) if err != nil { - utils.LogError("error sending tumblebug readyz request:", err) + log.Error().Msgf("error sending tumblebug readyz request; %v", err) return err } diff --git a/internal/render/templates.go b/internal/render/templates.go index dcb904b..f527bc3 100644 --- a/internal/render/templates.go +++ b/internal/render/templates.go @@ -4,12 +4,12 @@ import ( "errors" "fmt" "io" - "log" "path/filepath" "text/template" "github.com/cloud-barista/cm-ant/internal/utils" "github.com/labstack/echo/v4" + "github.com/rs/zerolog/log" ) type Template struct { //the map[key] in key means 'Your html file name' @@ -20,7 +20,7 @@ func NewTemplate() *Template { templates, err := generateTemplateCache() if err != nil { - log.Fatal("template parsing error", err) + log.Error().Msgf("template parsing error; %v", err) } return &Template{ diff --git a/internal/utils/bash.go b/internal/utils/bash.go index f2b23a0..3235ab1 100644 --- a/internal/utils/bash.go +++ b/internal/utils/bash.go @@ -1,9 +1,10 @@ package utils import ( - "log" "os" "os/exec" + + "github.com/rs/zerolog/log" ) func InlineCmd(cmdStr string) error { @@ -11,12 +12,12 @@ func InlineCmd(cmdStr string) error { out, err := cmd.CombinedOutput() if err != nil { - log.Println("error while execute bash call,", err) - log.Println(string(out)) + log.Error().Msgf("error while execute bash call; %v", err) + log.Error().Msg(string(out)) return err } - log.Println(string(out)) + log.Info().Msgf(string(out)) return nil } @@ -30,12 +31,12 @@ func Script(scriptPath string, envs []string, args ...string) error { out, err := cmd.CombinedOutput() if err != nil { - log.Println("error while execute bash call,", err) - log.Println(string(out)) + log.Error().Msgf("error while execute bash call; %v", err) + log.Error().Msgf(string(out)) return err } - log.Println(string(out)) + log.Info().Msgf(string(out)) return nil } @@ -45,7 +46,7 @@ func InlineCmdAsync(cmdStr string) error { var err error if err = cmd.Start(); err != nil { - log.Println("error while async bash call:", err) + log.Error().Msgf("error while async bash call; %v", err) return err } diff --git a/internal/utils/ioes.go b/internal/utils/ioes.go index 5a191b0..73ae165 100644 --- a/internal/utils/ioes.go +++ b/internal/utils/ioes.go @@ -4,9 +4,10 @@ import ( "encoding/csv" "fmt" "io" - "log" "os" "strings" + + "github.com/rs/zerolog/log" ) func WritePropertiesFile(filePath string, properties map[string]interface{}, emptyOmit bool) error { @@ -52,7 +53,7 @@ func CreateFolder(filePath string) error { func ReadCSV(filename string) (*[][]string, error) { file, err := os.Open(filename) if err != nil { - LogErrorf("can not opent files: %s; %s", filename, err) + log.Error().Msgf("can not opent files: %s; %s", filename, err) return nil, err } defer file.Close() @@ -68,7 +69,7 @@ func ReadCSV(filename string) (*[][]string, error) { return &parsedCsv, nil } - log.Println(err) + log.Error().Msgf("failed to read csv file from path %s; %v", filename, err) break } @@ -83,10 +84,10 @@ func ExistCheck(path string) bool { if err != nil { if os.IsNotExist(err) { - LogErrorf("file / folder does not exist: %s", path) + log.Error().Msgf("file / folder does not exist: %s", path) } else { - LogError(err) + log.Error().Msg(err.Error()) } return false @@ -102,7 +103,7 @@ func ExistCheck(path string) bool { func ReadToString(path string) (string, error) { data, err := os.ReadFile(path) if err != nil { - log.Println("file doesn't exist on correct path") + log.Error().Msgf("file doesn't exist on correct path; %v", err) return "", err } diff --git a/internal/utils/log.go b/internal/utils/log.go index ce685bb..243eab4 100644 --- a/internal/utils/log.go +++ b/internal/utils/log.go @@ -1,77 +1,77 @@ package utils -import ( - "fmt" - "log" -) +// import ( +// "fmt" +// "log" +// ) -const ( - colorReset = "\033[0m" - colorRed = "\033[31m" - colorGreen = "\033[32m" - colorYellow = "\033[33m" -) +// const ( +// colorReset = "\033[0m" +// colorRed = "\033[31m" +// colorGreen = "\033[32m" +// colorYellow = "\033[33m" +// ) -// LogLevel type to represent different log levels -type LogLevel string +// // LogLevel type to represent different log levels +// type LogLevel string -const ( - Info LogLevel = "INFO" - Warn LogLevel = "WARN" - Error LogLevel = "ERROR" -) +// const ( +// Info LogLevel = "INFO" +// Warn LogLevel = "WARN" +// Error LogLevel = "ERROR" +// ) -// Utility function for logging messages with color -func Log(level LogLevel, v ...interface{}) { - var color string - switch level { - case Info: - color = colorGreen - case Warn: - color = colorYellow - case Error: - color = colorRed - default: - color = colorReset - } - log.Println(color+fmt.Sprintf("[%s]", level)+colorReset, fmt.Sprint(v...)) -} +// // Utility function for logging messages with color +// func Log(level LogLevel, v ...interface{}) { +// var color string +// switch level { +// case Info: +// color = colorGreen +// case Warn: +// color = colorYellow +// case Error: +// color = colorRed +// default: +// color = colorReset +// } +// log.Println(color+fmt.Sprintf("[%s]", level)+colorReset, fmt.Sprint(v...)) +// } -func Logf(level LogLevel, format string, v ...interface{}) { - var color string - switch level { - case Info: - color = colorGreen - case Error: - color = colorRed - default: - color = colorReset - } - content := fmt.Sprintf(format, v...) - log.Println(color+fmt.Sprintf("[%s]", level)+colorReset, content) -} +// func Logf(level LogLevel, format string, v ...interface{}) { +// var color string +// switch level { +// case Info: +// color = colorGreen +// case Error: +// color = colorRed +// default: +// color = colorReset +// } +// content := fmt.Sprintf(format, v...) +// log.Println(color+fmt.Sprintf("[%s]", level)+colorReset, content) +// } -// Wrapper functions for specific log levels -func LogInfo(v ...interface{}) { - Log(Info, v...) -} +// // Wrapper functions for specific log levels +// func LogInfo(v ...interface{}) { +// Log(Info, v...) +// } -func LogInfof(format string, v ...interface{}) { - Logf(Info, format, v...) -} +// func LogInfof(format string, v ...interface{}) { +// Logf(Info, format, v...) +// } -func LogWarn(v ...interface{}) { - Log(Warn, v...) -} +// func LogWarn(v ...interface{}) { +// Log(Warn, v...) +// } -func LogWarnf(format string, v ...interface{}) { - Logf(Warn, format, v...) -} +// func LogWarnf(format string, v ...interface{}) { +// Logf(Warn, format, v...) +// } -func LogError(v ...interface{}) { - Log(Error, v...) -} +// func LogError(v ...interface{}) { +// Log(Error, v...) +// } -func LogErrorf(format string, v ...interface{}) { - Logf(Error, format, v...) -} +// func LogErrorf(format string, v ...interface{}) { +// Logf(Error, format, v...) +// } diff --git a/internal/utils/ssh.go b/internal/utils/ssh.go index 3386882..2fcf122 100644 --- a/internal/utils/ssh.go +++ b/internal/utils/ssh.go @@ -8,12 +8,12 @@ import ( "errors" "fmt" "io" - "log" "net" "os" "github.com/melbahja/goph" "github.com/pkg/sftp" + "github.com/rs/zerolog/log" "golang.org/x/crypto/ssh" ) @@ -43,7 +43,7 @@ func AddToKnownHost(pemFilePath, publicIp, username string) error { return err } - log.Println(string(out)) + log.Info().Msg(string(out)) return nil } diff --git a/internal/utils/worker.go b/internal/utils/worker.go index 2e7fa40..12f49e3 100644 --- a/internal/utils/worker.go +++ b/internal/utils/worker.go @@ -2,10 +2,11 @@ package utils import ( "fmt" - "log" "os" "strconv" "time" + + "github.com/rs/zerolog/log" ) type Worker interface { @@ -29,17 +30,16 @@ func NewWorker(interval time.Duration) Worker { } func (w *tempFileRemoveWorker) Run() { - - log.Println("TempFileRemoveWorker Started") + log.Info().Msg("TempFileRemoveWorker Started") for { select { case <-w.ShutdownChannel: - log.Println("worker shut down..") + log.Info().Msg("worker shut down..") w.ShutdownChannel <- "Down" return default: - log.Println("worker actions called") + log.Info().Msg("worker actions called") } w.Action()