From f6e50e47cd1edd7f15bc13cd19e6e99610a2fad9 Mon Sep 17 00:00:00 2001 From: MikeAlejoBR Date: Wed, 18 Dec 2024 11:56:03 +0100 Subject: [PATCH] feature: improve Sources' logging These changes make sure that we are informed about useful events while Sorces is running, especially those ones that modify our database. By having these logs, we might be able to increase the default logging level to "INFO" and reduce the noise in our logs, while maintaining a good level of debuggability. RHCLOUD-36959 --- dao/application_authentication_dao.go | 24 +++++++- dao/application_dao.go | 71 +++++++++++++++++++--- dao/authentication_db_dao.go | 40 ++++++++++-- dao/common.go | 2 +- dao/endpoint_dao.go | 45 +++++++++++--- dao/rhc_connection_dao.go | 27 ++++++++- dao/secret_db_dao.go | 30 ++++++++- dao/source_dao.go | 87 +++++++++++++++++++++++++-- dao/tenant_dao.go | 6 ++ dao/user_dao.go | 6 ++ service/subresource_destroyer.go | 3 + 11 files changed, 308 insertions(+), 33 deletions(-) diff --git a/dao/application_authentication_dao.go b/dao/application_authentication_dao.go index e8d795af3..ff5210a39 100644 --- a/dao/application_authentication_dao.go +++ b/dao/application_authentication_dao.go @@ -4,8 +4,10 @@ import ( "fmt" "github.com/RedHatInsights/sources-api-go/config" + "github.com/RedHatInsights/sources-api-go/logger" m "github.com/RedHatInsights/sources-api-go/model" "github.com/RedHatInsights/sources-api-go/util" + "github.com/sirupsen/logrus" "gorm.io/gorm" "gorm.io/gorm/clause" ) @@ -157,14 +159,26 @@ func (a *applicationAuthenticationDaoImpl) Create(appAuth *m.ApplicationAuthenti appAuth.TenantID = *a.TenantID err := DB.Debug().Create(appAuth).Error if err != nil { + logger.Log.WithFields(logrus.Fields{"tenant_id": *a.TenantID}).Errorf(`Unable to create application authentication: %s`, err) + return util.NewErrBadRequest("failed to create application_authentication: " + err.Error()) + } else { + logger.Log.WithFields(logrus.Fields{"tenant_id": *a.TenantID, "application_authentication_id": appAuth.ID}).Info("Application authentication created") + return nil } - return err } func (a *applicationAuthenticationDaoImpl) Update(appAuth *m.ApplicationAuthentication) error { - result := a.getDb().Updates(appAuth) - return result.Error + err := a.getDb().Updates(appAuth).Error + + if err != nil { + logger.Log.WithFields(logrus.Fields{"tenant_id": *a.TenantID, "application_authentication_id": appAuth.ID}).Errorf(`Unable to update application authentication: %s`, err) + + return err + } else { + logger.Log.WithFields(logrus.Fields{"tenant_id": *a.TenantID, "application_authentication_id": appAuth.ID}).Info("Application authentication updated") + return nil + } } func (a *applicationAuthenticationDaoImpl) Delete(id *int64) (*m.ApplicationAuthentication, error) { @@ -177,6 +191,8 @@ func (a *applicationAuthenticationDaoImpl) Delete(id *int64) (*m.ApplicationAuth Delete(&applicationAuthentication) if result.Error != nil { + logger.Log.WithFields(logrus.Fields{"tenant_id": *a.TenantID, "application_authentication_id": id}).Errorf(`Unable to delete application authentication: %s`, result.Error) + return nil, fmt.Errorf(`failed to delete application authentication with id "%d": %s`, id, result.Error) } @@ -184,6 +200,8 @@ func (a *applicationAuthenticationDaoImpl) Delete(id *int64) (*m.ApplicationAuth return nil, util.NewErrNotFound("application authentication") } + logger.Log.WithFields(logrus.Fields{"tenant_id": *a.TenantID, "application_authentication_id": id}).Info("Application authentication deleted") + return &applicationAuthentication, nil } diff --git a/dao/application_dao.go b/dao/application_dao.go index e51680d59..038ace6ed 100644 --- a/dao/application_dao.go +++ b/dao/application_dao.go @@ -7,9 +7,11 @@ import ( "strings" "time" + "github.com/RedHatInsights/sources-api-go/logger" m "github.com/RedHatInsights/sources-api-go/model" "github.com/RedHatInsights/sources-api-go/util" "github.com/jackc/pgconn" + "github.com/sirupsen/logrus" "gorm.io/gorm" "gorm.io/gorm/clause" ) @@ -156,23 +158,41 @@ func (a *applicationDaoImpl) GetByIdWithPreload(id *int64, preloads ...string) ( func (a *applicationDaoImpl) Create(app *m.Application) error { app.TenantID = *a.TenantID - result := DB.Debug().Create(app) + err := DB.Debug().Create(app).Error // Check if specific error code is returned var pgErr *pgconn.PgError - if errors.As(result.Error, &pgErr) { + if errors.As(err, &pgErr) { // unique constraint violation for index (source id + app type id + tenant id) if pgErr.Code == PgUniqueConstraintViolation && strings.Contains(pgErr.Detail, "Key (source_id, application_type_id, tenant_id)") { message := fmt.Sprintf("Application of application type = %d already exists for the source id = %d", app.ApplicationTypeID, app.SourceID) return util.NewErrBadRequest(message) } } - return result.Error + + if err != nil { + logger.Log.WithFields(logrus.Fields{"tenant_id": *a.TenantID, "source_id": app.SourceID}).Errorf("Unable to create application: %s", err) + + return err + } else { + logger.Log.WithFields(logrus.Fields{"tenant_id": *a.TenantID, "source_id": app.SourceID, "application_id": app.ID}).Info("Application created") + + return nil + } } func (a *applicationDaoImpl) Update(app *m.Application) error { - result := a.getDb().Omit(clause.Associations).Updates(app) - return result.Error + err := a.getDb().Omit(clause.Associations).Updates(app).Error + + if err != nil { + logger.Log.WithFields(logrus.Fields{"tenant_id": *a.TenantID, "source_id": app.SourceID, "application_id": app.ID}).Errorf("Unable to update application: %s", err) + + return err + } else { + logger.Log.WithFields(logrus.Fields{"tenant_id": *a.TenantID, "source_id": app.SourceID, "application_id": app.ID}).Info("Application updated") + + return nil + } } func (a *applicationDaoImpl) Delete(id *int64) (*m.Application, error) { @@ -184,6 +204,8 @@ func (a *applicationDaoImpl) Delete(id *int64) (*m.Application, error) { Delete(&application) if result.Error != nil { + logger.Log.WithFields(logrus.Fields{"tenant_id": *a.TenantID, "application_id": *id}).Errorf("Unable to delete application: %s", result.Error) + return nil, fmt.Errorf(`failed to delete application with id "%d": %s`, id, result.Error) } @@ -191,6 +213,8 @@ func (a *applicationDaoImpl) Delete(id *int64) (*m.Application, error) { return nil, util.NewErrNotFound("application") } + logger.Log.WithFields(logrus.Fields{"tenant_id": *a.TenantID, "application_id": *id}).Info("Application deleted") + return &application, nil } @@ -282,7 +306,15 @@ func (a *applicationDaoImpl) Pause(id int64) error { Update("paused_at", time.Now()). Error - return err + if err != nil { + logger.Log.WithFields(logrus.Fields{"tenant_id": *a.TenantID, "application_id": id}).Errorf("Unable to pause application: %s", err) + + return err + } else { + logger.Log.WithFields(logrus.Fields{"tenant_id": *a.TenantID, "application_id": id}).Info("Application paused") + + return nil + } } func (a *applicationDaoImpl) Unpause(id int64) error { @@ -291,7 +323,15 @@ func (a *applicationDaoImpl) Unpause(id int64) error { Update("paused_at", nil). Error - return err + if err != nil { + logger.Log.WithFields(logrus.Fields{"tenant_id": *a.TenantID, "application_id": id}).Errorf("Unable to resume application: %s", err) + + return err + } else { + logger.Log.WithFields(logrus.Fields{"tenant_id": *a.TenantID, "application_id": id}).Info("Application resumed") + + return nil + } } func (a *applicationDaoImpl) DeleteCascade(applicationId int64) ([]m.ApplicationAuthentication, *m.Application, error) { @@ -327,6 +367,8 @@ func (a *applicationDaoImpl) DeleteCascade(applicationId int64) ([]m.Application Error if err != nil { + logger.Log.WithFields(logrus.Fields{"tenant_id": *a.TenantID, "application_id": applicationId}).Errorf("Unable to cascade delete application: unable to delete application authentications: %s", err) + return err } } @@ -346,9 +388,22 @@ func (a *applicationDaoImpl) DeleteCascade(applicationId int64) ([]m.Application Error } - return err + if err != nil { + logger.Log.WithFields(logrus.Fields{"tenant_id": *a.TenantID, "source_id": application.SourceID, "application_id": applicationId}).Errorf("Unable to cascade delete application: %s", err) + + return err + } else { + return nil + } }) + // Log all the changes for observability, traceability and debugging purposes. + for _, appAuth := range applicationAuthentications { + logger.Log.WithFields(logrus.Fields{"tenant_id": *a.TenantID, "source_id": application.SourceID, "application_id": applicationId, "application_authentication_id": appAuth.ID}).Info("Application authentication deleted") + } + + logger.Log.WithFields(logrus.Fields{"tenant_id": *a.TenantID, "source_id": application.SourceID, "application_id": applicationId}).Info("Application deleted") + if err != nil { return nil, nil, err } diff --git a/dao/authentication_db_dao.go b/dao/authentication_db_dao.go index 6f09efffd..ca3a01513 100644 --- a/dao/authentication_db_dao.go +++ b/dao/authentication_db_dao.go @@ -5,8 +5,10 @@ import ( "fmt" "strings" + "github.com/RedHatInsights/sources-api-go/logger" m "github.com/RedHatInsights/sources-api-go/model" "github.com/RedHatInsights/sources-api-go/util" + "github.com/sirupsen/logrus" "gorm.io/gorm" "gorm.io/gorm/clause" ) @@ -302,10 +304,20 @@ func (add *authenticationDaoDbImpl) Create(authentication *m.Authentication) err authentication.TenantID = *add.TenantID // the TenantID gets injected in the middleware - return DB. + err := DB. Debug(). Create(authentication). Error + + if err != nil { + logger.Log.WithFields(logrus.Fields{"tenant_id": *add.TenantID, "resource_type": authentication.ResourceType, "resource_id": authentication.ResourceID}).Errorf("Unable to create authentication: %s", err) + + return err + } else { + logger.Log.WithFields(logrus.Fields{"tenant_id": *add.TenantID, "resource_type": authentication.ResourceType, "resource_id": authentication.ResourceID, "authentication_id": authentication.ID}).Info("Authentication created") + + return nil + } } // BulkCreate method _without_ checking if the resource exists. Basically since this is the bulk-create method the @@ -316,10 +328,20 @@ func (add *authenticationDaoDbImpl) BulkCreate(auth *m.Authentication) error { } func (add *authenticationDaoDbImpl) Update(authentication *m.Authentication) error { - return add.getDb(). + err := add.getDb(). Omit(clause.Associations). Updates(authentication). Error + + if err != nil { + logger.Log.WithFields(logrus.Fields{"tenant_id": *add.TenantID, "resource_type": authentication.ResourceType, "resource_id": authentication.ResourceID}).Errorf("Unable to update authentication: %s", err) + + return err + } else { + logger.Log.WithFields(logrus.Fields{"tenant_id": *add.TenantID, "resource_type": authentication.ResourceType, "resource_id": authentication.ResourceID, "authentication_id": authentication.ID}).Info("Authentication updated") + + return nil + } } func (add *authenticationDaoDbImpl) Delete(id string) (*m.Authentication, error) { @@ -339,10 +361,14 @@ func (add *authenticationDaoDbImpl) Delete(id string) (*m.Authentication, error) Error if err != nil { + logger.Log.WithFields(logrus.Fields{"tenant_id": *add.TenantID, "resource_type": authentication.ResourceType, "resource_id": authentication.ResourceID}).Errorf("Unable to delete authentication: %s", err) + return nil, fmt.Errorf(`failed to delete authentication with id "%s"`, id) - } + } else { + logger.Log.WithFields(logrus.Fields{"tenant_id": *add.TenantID, "resource_type": authentication.ResourceType, "resource_id": authentication.ResourceID, "authentication_id": authentication.ID}).Info("Authentication deleted") - return &authentication, nil + return &authentication, nil + } } func (add *authenticationDaoDbImpl) Tenant() *int64 { @@ -477,9 +503,15 @@ func (add *authenticationDaoDbImpl) BulkDelete(authentications []m.Authenticatio Error if err != nil { + logger.Log.WithFields(logrus.Fields{"tenant_id": *add.TenantID, "authentication_ids": authIds}).Errorf("Unable to bulk delete authentications: %s", err) + return nil, err } } + for _, auth := range dbAuths { + logger.Log.WithFields(logrus.Fields{"tenant_id": *add.TenantID, "resource_type": auth.ResourceType, "resource_id": auth.ResourceID, "authentication_id": auth}).Info("Authentication deleted") + } + return dbAuths, nil } diff --git a/dao/common.go b/dao/common.go index eca549763..fb83ccb1b 100644 --- a/dao/common.go +++ b/dao/common.go @@ -19,7 +19,7 @@ func GetFromResourceType(resourceType string, tenantID int64) (m.EventModelDao, case "source": resource = GetSourceDao(&RequestParams{TenantID: &tenantID}) case "endpoint": - resource = GetEndpointDao(nil) + resource = GetEndpointDao(&tenantID) case "application": resource = GetApplicationDao(&RequestParams{TenantID: &tenantID}) case "authentication": diff --git a/dao/endpoint_dao.go b/dao/endpoint_dao.go index 099e4b07e..9a8db699c 100644 --- a/dao/endpoint_dao.go +++ b/dao/endpoint_dao.go @@ -4,8 +4,10 @@ import ( "encoding/json" "fmt" + "github.com/RedHatInsights/sources-api-go/logger" m "github.com/RedHatInsights/sources-api-go/model" "github.com/RedHatInsights/sources-api-go/util" + "github.com/sirupsen/logrus" "gorm.io/gorm/clause" ) @@ -112,16 +114,33 @@ func (a *endpointDaoImpl) GetById(id *int64) (*m.Endpoint, error) { return &endpoint, nil } -func (a *endpointDaoImpl) Create(app *m.Endpoint) error { - app.TenantID = *a.TenantID +func (a *endpointDaoImpl) Create(endpoint *m.Endpoint) error { + endpoint.TenantID = *a.TenantID - result := DB.Debug().Create(app) - return result.Error + err := DB.Debug().Create(endpoint).Error + if err != nil { + logger.Log.WithFields(logrus.Fields{"tenant_id": *a.TenantID, "source_id": endpoint.SourceID}).Errorf("Unable to create endpoint: %s", err) + + return err + } else { + logger.Log.WithFields(logrus.Fields{"tenant_id": *a.TenantID, "source_id": endpoint.SourceID, "endpoint_id": endpoint.ID}).Info("Endpoint created") + + return nil + } } -func (a *endpointDaoImpl) Update(app *m.Endpoint) error { - result := DB.Omit(clause.Associations).Updates(app) - return result.Error +func (a *endpointDaoImpl) Update(endpoint *m.Endpoint) error { + err := DB.Omit(clause.Associations).Updates(endpoint).Error + + if err != nil { + logger.Log.WithFields(logrus.Fields{"tenant_id": *a.TenantID, "source_id": endpoint.SourceID, "endpoint_id": endpoint.ID}).Errorf("Unable to update endpoint: %s", err) + + return err + } else { + logger.Log.WithFields(logrus.Fields{"tenant_id": *a.TenantID, "source_id": endpoint.SourceID, "endpoint_id": endpoint.ID}).Info("Endpoint updated") + + return nil + } } func (a *endpointDaoImpl) Delete(id *int64) (*m.Endpoint, error) { @@ -135,6 +154,8 @@ func (a *endpointDaoImpl) Delete(id *int64) (*m.Endpoint, error) { Delete(&endpoint) if result.Error != nil { + logger.Log.WithFields(logrus.Fields{"tenant_id": *a.TenantID, "source_id": endpoint.SourceID, "endpoint_id": *id}).Errorf("Unable to delete endpoint: %s", result.Error) + return nil, fmt.Errorf(`failed to delete endpoint with id "%d": %s`, id, result.Error) } @@ -142,6 +163,8 @@ func (a *endpointDaoImpl) Delete(id *int64) (*m.Endpoint, error) { return nil, util.NewErrNotFound("endpoint") } + logger.Log.WithFields(logrus.Fields{"tenant_id": *a.TenantID, "source_id": endpoint.SourceID, "endpoint_id": *id}).Info("Endpoint deleted") + return &endpoint, nil } @@ -199,10 +222,18 @@ func (a *endpointDaoImpl) FetchAndUpdateBy(resource util.Resource, updateAttribu Where("id = ?", resource.ResourceID). Updates(updateAttributes) + if result.Error != nil { + logger.Log.WithFields(logrus.Fields{"tenant_id": *a.TenantID, "resource_type": resource.ResourceType, "resource_id": resource.ResourceID}).Errorf("Unable to update endpoint: %s", result.Error) + + return nil, result.Error + } + if result.RowsAffected == 0 { return nil, fmt.Errorf("endpoint not found %v", resource) } + logger.Log.WithFields(logrus.Fields{"tenant_id": *a.TenantID, "resource_type": resource.ResourceType, "resource_id": resource.ResourceID}).Info("Endpoint updated") + a.TenantID = &resource.TenantID endpoint, err := a.GetByIdWithPreload(&resource.ResourceID, "Source") if err != nil { diff --git a/dao/rhc_connection_dao.go b/dao/rhc_connection_dao.go index 549a2fcb9..dc92fa382 100644 --- a/dao/rhc_connection_dao.go +++ b/dao/rhc_connection_dao.go @@ -6,8 +6,10 @@ import ( "fmt" "github.com/RedHatInsights/sources-api-go/dao/mappers" + "github.com/RedHatInsights/sources-api-go/logger" m "github.com/RedHatInsights/sources-api-go/model" "github.com/RedHatInsights/sources-api-go/util" + "github.com/sirupsen/logrus" "gorm.io/gorm" "gorm.io/gorm/clause" ) @@ -168,6 +170,8 @@ func (s *rhcConnectionDaoImpl) Create(rhcConnection *m.RhcConnection) (*m.RhcCon Error if err != nil { + logger.Log.WithFields(logrus.Fields{"tenant_id": *s.TenantID, "source_id": rhcConnection.Sources[0].ID}).Errorf("Unable to create RHC connection: %s", err) + return err } @@ -202,9 +206,13 @@ func (s *rhcConnectionDaoImpl) Create(rhcConnection *m.RhcConnection) (*m.RhcCon Create(&sourceRhcConnection). Error if err != nil { + logger.Log.WithFields(logrus.Fields{"tenant_id": *s.TenantID, "source_id": rhcConnection.Sources[0].ID}).Errorf("Unable to create RHC connection association: %s", err) + return err } + logger.Log.WithFields(logrus.Fields{"tenant_id": *s.TenantID, "source_id": rhcConnection.Sources[0].ID, "rhc_connection_id": rhcConnection.ID}).Info("RHC Connection created") + return nil }) @@ -219,7 +227,16 @@ func (s *rhcConnectionDaoImpl) Update(rhcConnection *m.RhcConnection) error { Select("*"). Updates(rhcConnection). Error - return err + + if err != nil { + logger.Log.WithFields(logrus.Fields{"tenant_id": *s.TenantID, "source_ids": rhcConnection.Sources, "rhc_connection_id": rhcConnection.ID}).Errorf("Unable to update RHC connection: %s", err) + + return err + } else { + logger.Log.WithFields(logrus.Fields{"tenant_id": *s.TenantID, "source_ids": rhcConnection.Sources, "rhc_connection_id": rhcConnection.ID}).Info("RHC connection updated") + + return nil + } } func (s *rhcConnectionDaoImpl) Delete(id *int64) (*m.RhcConnection, error) { @@ -239,10 +256,14 @@ func (s *rhcConnectionDaoImpl) Delete(id *int64) (*m.RhcConnection, error) { Delete(&rhcConnection) if result.Error != nil { + logger.Log.WithFields(logrus.Fields{"tenant_id": *s.TenantID, "source_ids": rhcConnection.Sources, "rhc_connection_id": *id}).Errorf("Unable to delete RHC connection: %s", err) + return nil, fmt.Errorf(`failed to delete rhcConnection with id "%d": %s`, id, result.Error) - } + } else { + logger.Log.WithFields(logrus.Fields{"tenant_id": *s.TenantID, "source_ids": rhcConnection.Sources, "rhc_connection_id": rhcConnection.ID}).Info("RHC connection deleted") - return &rhcConnection, nil + return &rhcConnection, nil + } } func (s *rhcConnectionDaoImpl) ListForSource(sourceId *int64, limit, offset int, filters []util.Filter) ([]m.RhcConnection, int64, error) { diff --git a/dao/secret_db_dao.go b/dao/secret_db_dao.go index c7e832fbb..a438f5e03 100644 --- a/dao/secret_db_dao.go +++ b/dao/secret_db_dao.go @@ -3,8 +3,10 @@ package dao import ( "fmt" + "github.com/RedHatInsights/sources-api-go/logger" m "github.com/RedHatInsights/sources-api-go/model" "github.com/RedHatInsights/sources-api-go/util" + "github.com/sirupsen/logrus" "gorm.io/gorm" "gorm.io/gorm/clause" ) @@ -55,10 +57,20 @@ func (secret *secretDaoDbImpl) Create(authentication *m.Authentication) error { authentication.ResourceType = secretResourceType authentication.ResourceID = *secret.TenantID - return DB. + err := DB. Debug(). Create(authentication). Error + + if err != nil { + logger.Log.WithFields(logrus.Fields{"tenant_id": *secret.TenantID}).Errorf("Unable to create secret: %s", err) + + return err + } else { + logger.Log.WithFields(logrus.Fields{"tenant_id": *secret.TenantID, "secret_id": authentication.ID}).Info("Secret created") + + return nil + } } func (secret *secretDaoDbImpl) Delete(id *int64) error { @@ -78,9 +90,13 @@ func (secret *secretDaoDbImpl) Delete(id *int64) error { Error if err != nil { + logger.Log.WithFields(logrus.Fields{"tenant_id": *secret.TenantID, "secret_id": *id}).Errorf("Unable to delete secret: %s", err) + return fmt.Errorf(`failed to delete secret with id "%d"`, &id) } + logger.Log.WithFields(logrus.Fields{"tenant_id": *secret.TenantID, "secret_id": *id}).Info("Secret deleted") + return nil } @@ -119,8 +135,18 @@ func (secret *secretDaoDbImpl) List(limit, offset int, filters []util.Filter) ([ } func (secret *secretDaoDbImpl) Update(authentication *m.Authentication) error { - return secret.getDb(). + err := secret.getDb(). Omit(clause.Associations). Updates(authentication). Error + + if err != nil { + logger.Log.WithFields(logrus.Fields{"tenant_id": *secret.TenantID, "secret_id": authentication.ID}).Errorf("Unable to update secret: %s", err) + + return err + } else { + logger.Log.WithFields(logrus.Fields{"tenant_id": *secret.TenantID, "secret_id": authentication.ID}).Info("Secret updated") + + return nil + } } diff --git a/dao/source_dao.go b/dao/source_dao.go index 607c9af0c..ed8ca1476 100644 --- a/dao/source_dao.go +++ b/dao/source_dao.go @@ -5,8 +5,10 @@ import ( "fmt" "time" + "github.com/RedHatInsights/sources-api-go/logger" m "github.com/RedHatInsights/sources-api-go/model" "github.com/RedHatInsights/sources-api-go/util" + "github.com/sirupsen/logrus" "gorm.io/gorm" "gorm.io/gorm/clause" ) @@ -188,12 +190,30 @@ func (s *sourceDaoImpl) GetByIdWithPreload(id *int64, preloads ...string) (*m.So func (s *sourceDaoImpl) Create(src *m.Source) error { src.TenantID = *s.TenantID // the TenantID gets injected in the middleware result := DB.Debug().Create(src) - return result.Error + + if result.Error != nil { + logger.Log.WithFields(logrus.Fields{"tenant_id": *s.TenantID}).Errorf(`Unable to create source: %s`, result.Error) + + return result.Error + } else { + logger.Log.WithFields(logrus.Fields{"tenant_id": *s.TenantID, "source_id": src.ID}).Info("Source created") + + return nil + } } func (s *sourceDaoImpl) Update(src *m.Source) error { result := s.getDb().Omit(clause.Associations).Updates(src) - return result.Error + + if result.Error != nil { + logger.Log.WithFields(logrus.Fields{"tenant_id": s.TenantID, "source_id": src.ID}).Errorf(`Unable to update source: %s`, result.Error) + + return result.Error + } else { + logger.Log.WithFields(logrus.Fields{"tenant_id": s.TenantID, "source_id": src.ID}).Info("Source updated") + + return nil + } } func (s *sourceDaoImpl) Delete(id *int64) (*m.Source, error) { @@ -205,6 +225,8 @@ func (s *sourceDaoImpl) Delete(id *int64) (*m.Source, error) { Delete(&source) if result.Error != nil { + logger.Log.WithFields(logrus.Fields{"tenant_id": *s.TenantID, "source_id": id}).Errorf(`Unable to delete source: %s`, result.Error) + return nil, fmt.Errorf(`failed to source endpoint with id "%d": %s`, id, result.Error) } @@ -212,6 +234,8 @@ func (s *sourceDaoImpl) Delete(id *int64) (*m.Source, error) { return nil, util.NewErrNotFound("source") } + logger.Log.WithFields(logrus.Fields{"tenant_id": *s.TenantID, "source_id": id}).Info("Source deleted") + return &source, nil } @@ -347,6 +371,8 @@ func (s *sourceDaoImpl) Pause(id int64) error { Error if err != nil { + logger.Log.WithFields(logrus.Fields{"tenant_id": *s.TenantID, "source_id": id}).Errorf(`Unable to pause source: %s`, err) + return err } @@ -357,7 +383,15 @@ func (s *sourceDaoImpl) Pause(id int64) error { Update("paused_at", time.Now()). Error - return err + if err != nil { + logger.Log.WithFields(logrus.Fields{"tenant_id": *s.TenantID, "source_id": id}).Errorf(`Unable to pause source's applications': %s`, err) + + return err + } + + logger.Log.WithFields(logrus.Fields{"tenant_id": *s.TenantID, "source_id": id}).Info("Source and its applications paused") + + return nil }) return err @@ -372,6 +406,8 @@ func (s *sourceDaoImpl) Unpause(id int64) error { Error if err != nil { + logger.Log.WithFields(logrus.Fields{"tenant_id": *s.TenantID, "source_id": id}).Errorf(`Unable to resume source: %s`, err) + return err } @@ -382,7 +418,15 @@ func (s *sourceDaoImpl) Unpause(id int64) error { Update("paused_at", nil). Error - return err + if err != nil { + logger.Log.WithFields(logrus.Fields{"tenant_id": *s.TenantID, "source_id": id}).Errorf(`Unable to resume source's applications': %s`, err) + + return err + } + + logger.Log.WithFields(logrus.Fields{"tenant_id": *s.TenantID, "source_id": id}).Info("Source and its applications resumed") + + return nil }) return err @@ -424,6 +468,8 @@ func (s *sourceDaoImpl) DeleteCascade(sourceId int64) ([]m.ApplicationAuthentica Error if err != nil { + logger.Log.WithFields(logrus.Fields{"tenant_id": *s.TenantID, "source_id": sourceId}).Errorf("Unable to cascade delete source: unable to delete application authentications: %s", err) + return err } } @@ -447,6 +493,8 @@ func (s *sourceDaoImpl) DeleteCascade(sourceId int64) ([]m.ApplicationAuthentica Error if err != nil { + logger.Log.WithFields(logrus.Fields{"tenant_id": *s.TenantID, "source_id": sourceId}).Errorf("Unable to cascade delete source: unable to delete applications: %s", err) + return err } } @@ -470,6 +518,8 @@ func (s *sourceDaoImpl) DeleteCascade(sourceId int64) ([]m.ApplicationAuthentica Error if err != nil { + logger.Log.WithFields(logrus.Fields{"tenant_id": *s.TenantID, "source_id": sourceId}).Errorf("Unable to cascade delete source: unable to delete endpoints: %s", err) + return err } } @@ -493,6 +543,8 @@ func (s *sourceDaoImpl) DeleteCascade(sourceId int64) ([]m.ApplicationAuthentica Error if err != nil { + logger.Log.WithFields(logrus.Fields{"tenant_id": *s.TenantID, "source_id": sourceId}).Errorf("Unable to cascade delete source: unable to delete RHC connections: %s", err) + return err } } @@ -515,13 +567,38 @@ func (s *sourceDaoImpl) DeleteCascade(sourceId int64) ([]m.ApplicationAuthentica Error } - return err + if err != nil { + logger.Log.WithFields(logrus.Fields{"tenant_id": *s.TenantID, "source_id": sourceId}).Errorf("Unable to cascade delete source: %s", err) + + return err + } else { + return nil + } }) if err != nil { return nil, nil, nil, nil, nil, err } + // Log all the changes for observability, traceability and debugging purposes. + for _, appAuth := range applicationAuthentications { + logger.Log.WithFields(logrus.Fields{"tenant_id": *s.TenantID, "source_id": sourceId, "application_authentication_id": appAuth.ID}).Info("Application authentication deleted") + } + + for _, app := range applications { + logger.Log.WithFields(logrus.Fields{"tenant_id": *s.TenantID, "source_id": sourceId, "application_id": app.ID}).Info("Application deleted") + } + + for _, endpoint := range endpoints { + logger.Log.WithFields(logrus.Fields{"tenant_id": *s.TenantID, "source_id": sourceId, "endpoint_id": endpoint.ID}).Info("Endpoint deleted") + } + + for _, rhcConnection := range rhcConnections { + logger.Log.WithFields(logrus.Fields{"tenant_id": *s.TenantID, "source_id": sourceId, "rhc_connection_id": rhcConnection.ID}).Info("RHC connection deleted") + } + + logger.Log.WithFields(logrus.Fields{"tenant_id": *s.TenantID, "source_id": sourceId}).Info("Source deleted") + return applicationAuthentications, applications, endpoints, rhcConnections, source, nil } diff --git a/dao/tenant_dao.go b/dao/tenant_dao.go index 31b81b285..a7f98f66c 100644 --- a/dao/tenant_dao.go +++ b/dao/tenant_dao.go @@ -50,6 +50,8 @@ func (t *tenantDaoImpl) GetOrCreateTenant(identity *identity.Identity) (*m.Tenan // If the error isn't a "Not Found" one, something went wrong. if err != nil && !errors.Is(err, gorm.ErrRecordNotFound) { + logger.Log.WithFields(logrus.Fields{"org_id": identity.OrgID, "account_number": identity.AccountNumber}).Errorf("Unable to find tenant by its org ID: %s", err) + return nil, fmt.Errorf("unexpected error when fetching a tenant by its OrgId: %w", err) } @@ -68,6 +70,8 @@ func (t *tenantDaoImpl) GetOrCreateTenant(identity *identity.Identity) (*m.Tenan // Again, if the error isn't a "Not Found" one, something went wrong. if err != nil && !errors.Is(err, gorm.ErrRecordNotFound) { + logger.Log.WithFields(logrus.Fields{"org_id": identity.OrgID, "account_number": identity.AccountNumber}).Errorf("Unable to find tenant by its account number: %s", err) + return nil, fmt.Errorf("unexpected error when fetching a tenant by its EBS account number: %w", err) } } @@ -83,6 +87,8 @@ func (t *tenantDaoImpl) GetOrCreateTenant(identity *identity.Identity) (*m.Tenan Error if err != nil { + logger.Log.WithFields(logrus.Fields{"org_id": identity.OrgID, "account_number": identity.AccountNumber}).Errorf("Unable to create tenant: %s", err) + return nil, fmt.Errorf("unable to create the tenant: %w", err) } diff --git a/dao/user_dao.go b/dao/user_dao.go index 0df84c636..6795b0b88 100644 --- a/dao/user_dao.go +++ b/dao/user_dao.go @@ -4,7 +4,9 @@ import ( "fmt" "github.com/RedHatInsights/sources-api-go/config" + "github.com/RedHatInsights/sources-api-go/logger" m "github.com/RedHatInsights/sources-api-go/model" + "github.com/sirupsen/logrus" "gorm.io/gorm/clause" ) @@ -55,9 +57,13 @@ func (u *userDaoImpl) FindOrCreate(userID string) (*m.User, error) { err = stmt.Create(&user).Error if err != nil { + logger.Log.WithFields(logrus.Fields{"tenant_id": *u.TenantID, "user_id": user.UserID}).Errorf("Unable to create user: %s", err) + return nil, err } } + logger.Log.WithFields(logrus.Fields{"tenant_id": *u.TenantID, "user_id": user.UserID, "user_sources_id": user.Id}).Info("User created") + return &user, nil } diff --git a/service/subresource_destroyer.go b/service/subresource_destroyer.go index d43631390..39644bef6 100644 --- a/service/subresource_destroyer.go +++ b/service/subresource_destroyer.go @@ -8,6 +8,7 @@ import ( "github.com/RedHatInsights/sources-api-go/kafka" logging "github.com/RedHatInsights/sources-api-go/logger" "github.com/RedHatInsights/sources-api-go/model" + "github.com/sirupsen/logrus" ) // DeleteCascade removes the resource type and all its dependants, raising an event for every deleted resource. Returns @@ -52,6 +53,8 @@ func DeleteCascade(tenantId *int64, userId *int64, resourceType string, resource go func() { // Raise an event for the deleted application authentications. for _, appAuth := range applicationAuthentications { + logging.Log.WithFields(logrus.Fields{"tenant_id": *tenantId, "application_authentication_id": appAuth.ID}).Info("Application authentication deleted") + err = RaiseEvent("ApplicationAuthentication.destroy", &appAuth, headers) if err != nil { logging.Log.Errorf(`Event "ApplicationAuthentication.destroy" could not be raised for application authentication %v: %s`, appAuth.ToEvent(), err)