diff --git a/cachestore/client.go b/cachestore/client.go index 2ceda1f4..115fba3b 100644 --- a/cachestore/client.go +++ b/cachestore/client.go @@ -3,6 +3,7 @@ package cachestore import ( "context" + "github.com/BuxOrg/bux/logger" "github.com/coocood/freecache" "github.com/mrz1836/go-cache" "github.com/newrelic/go-agent/v3/newrelic" @@ -20,7 +21,7 @@ type ( debug bool // For extra logs and additional debug information engine Engine // Cachestore engine (redis or mcache) freecache *freecache.Cache // Driver (client) for local in-memory storage - logger Logger // Internal logging + logger logger.Interface // Internal logging newRelicEnabled bool // If NewRelic is enabled (parent application) redis *cache.Client // Current redis client (read & write) redisConfig *RedisConfig // Configuration for a new redis client @@ -43,7 +44,7 @@ func NewClient(ctx context.Context, opts ...ClientOps) (ClientInterface, error) // Set logger if not set if client.options.logger == nil { - client.options.logger = newBasicLogger(client.IsDebug()) + client.options.logger = logger.NewLogger(client.IsDebug()) } // EMPTY! Engine was NOT set, show warning and use in-memory cache diff --git a/cachestore/client_options.go b/cachestore/client_options.go index a35e4201..8dfa32c5 100644 --- a/cachestore/client_options.go +++ b/cachestore/client_options.go @@ -4,6 +4,7 @@ import ( "context" "strings" + "github.com/BuxOrg/bux/logger" "github.com/coocood/freecache" "github.com/mrz1836/go-cache" "github.com/newrelic/go-agent/v3/newrelic" @@ -108,7 +109,7 @@ func WithFreeCacheConnection(client *freecache.Cache) ClientOps { } // WithLogger will set the custom logger interface -func WithLogger(customLogger Logger) ClientOps { +func WithLogger(customLogger logger.Interface) ClientOps { return func(c *clientOptions) { if customLogger != nil { c.logger = customLogger diff --git a/cachestore/client_options_test.go b/cachestore/client_options_test.go index 04f26765..10f135fe 100644 --- a/cachestore/client_options_test.go +++ b/cachestore/client_options_test.go @@ -5,6 +5,7 @@ import ( "testing" "time" + "github.com/BuxOrg/bux/logger" "github.com/BuxOrg/bux/tester" "github.com/coocood/freecache" "github.com/mrz1836/go-cache" @@ -250,7 +251,7 @@ func TestWithLogger(t *testing.T) { t.Run("test applying option", func(t *testing.T) { options := &clientOptions{} - customClient := newBasicLogger(true) + customClient := logger.NewLogger(true) opt := WithLogger(customClient) opt(options) assert.Equal(t, customClient, options.logger) diff --git a/cachestore/interface.go b/cachestore/interface.go index 1692cbfc..7a82e555 100644 --- a/cachestore/interface.go +++ b/cachestore/interface.go @@ -8,12 +8,6 @@ import ( "github.com/mrz1836/go-cache" ) -// Logger is the logger interface for debug messages -type Logger interface { - Info(ctx context.Context, message string, params ...interface{}) - Warn(ctx context.Context, message string, params ...interface{}) -} - // LockService are the locking related methods type LockService interface { ReleaseLock(ctx context.Context, lockKey, secret string) (bool, error) diff --git a/cachestore/logger.go b/cachestore/logger.go deleted file mode 100644 index 4ca65648..00000000 --- a/cachestore/logger.go +++ /dev/null @@ -1,55 +0,0 @@ -package cachestore - -import ( - "context" - "fmt" - - zlogger "github.com/mrz1836/go-logger" - "gorm.io/gorm/logger" -) - -// newBasicLogger will return a basic logger interface -func newBasicLogger(debugging bool) Logger { - logLevel := logger.Warn - if debugging { - logLevel = logger.Info - } - return &basicLogger{LogLevel: logLevel} -} - -// basicLogger is a basic logging implementation -type basicLogger struct { - LogLevel logger.LogLevel -} - -// LogMode log mode -func (l *basicLogger) LogMode(level logger.LogLevel) Logger { - newLogger := *l - newLogger.LogLevel = level - return &newLogger -} - -// Info will print information -func (l *basicLogger) Info(_ context.Context, message string, params ...interface{}) { - if l.LogLevel >= logger.Info { - displayLog(zlogger.INFO, message, params...) - } -} - -// Warn will print a warning -func (l *basicLogger) Warn(_ context.Context, message string, params ...interface{}) { - if l.LogLevel >= logger.Warn { - displayLog(zlogger.WARN, message, params...) - } -} - -// displayLog will display a log using logger -func displayLog(level zlogger.LogLevel, message string, params ...interface{}) { - var keyValues []zlogger.KeyValue - if len(params) > 0 { - for index, val := range params { - keyValues = append(keyValues, zlogger.MakeParameter(fmt.Sprintf("index_%d", index), val)) - } - } - zlogger.Data(2, level, message, keyValues...) -} diff --git a/chainstate/client.go b/chainstate/client.go index 2679bbee..75a51900 100644 --- a/chainstate/client.go +++ b/chainstate/client.go @@ -4,6 +4,7 @@ import ( "context" "time" + "github.com/BuxOrg/bux/logger" "github.com/mrz1836/go-mattercloud" "github.com/mrz1836/go-nownodes" "github.com/mrz1836/go-whatsonchain" @@ -20,11 +21,11 @@ type ( // clientOptions holds all the configuration for the client clientOptions struct { - config *syncConfig // Configuration for broadcasting and other chain-state actions - debug bool // For extra logs and additional debug information - logger Logger // Internal logger interface - newRelicEnabled bool // If NewRelic is enabled (parent application) - userAgent string // Custom user agent for outgoing HTTP Requests + config *syncConfig // Configuration for broadcasting and other chain-state actions + debug bool // For extra logs and additional debug information + logger logger.Interface // Internal logger interface + newRelicEnabled bool // If NewRelic is enabled (parent application) + userAgent string // Custom user agent for outgoing HTTP Requests } // syncConfig holds all the configuration about the different sync processes @@ -69,7 +70,7 @@ func NewClient(ctx context.Context, opts ...ClientOps) (ClientInterface, error) // Set logger if not set if client.options.logger == nil { - client.options.logger = newBasicLogger(client.IsDebug()) + client.options.logger = logger.NewLogger(client.IsDebug()) } // Start Minercraft diff --git a/chainstate/client_options.go b/chainstate/client_options.go index 5ef99436..702b0eb5 100644 --- a/chainstate/client_options.go +++ b/chainstate/client_options.go @@ -4,6 +4,7 @@ import ( "context" "time" + "github.com/BuxOrg/bux/logger" "github.com/mrz1836/go-mattercloud" "github.com/mrz1836/go-nownodes" "github.com/mrz1836/go-whatsonchain" @@ -213,7 +214,7 @@ func WithCustomMiners(miners []*minercraft.Miner) ClientOps { } // WithLogger will set a custom logger -func WithLogger(customLogger Logger) ClientOps { +func WithLogger(customLogger logger.Interface) ClientOps { return func(c *clientOptions) { if customLogger != nil { c.logger = customLogger diff --git a/chainstate/client_options_test.go b/chainstate/client_options_test.go index fba09864..c4b08c66 100644 --- a/chainstate/client_options_test.go +++ b/chainstate/client_options_test.go @@ -6,6 +6,7 @@ import ( "testing" "time" + "github.com/BuxOrg/bux/logger" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" "github.com/tonicpow/go-minercraft" @@ -469,7 +470,7 @@ func TestWithLogger(t *testing.T) { options := &clientOptions{ config: &syncConfig{}, } - customClient := newBasicLogger(true) + customClient := logger.NewLogger(true) opt := WithLogger(customClient) opt(options) assert.Equal(t, customClient, options.logger) diff --git a/chainstate/interface.go b/chainstate/interface.go index 7d19bdfc..52fd21ad 100644 --- a/chainstate/interface.go +++ b/chainstate/interface.go @@ -16,11 +16,6 @@ type HTTPInterface interface { Do(req *http.Request) (*http.Response, error) } -// Logger is the logger interface for debug messages -type Logger interface { - Info(ctx context.Context, message string, params ...interface{}) -} - // ChainService is the chain related methods type ChainService interface { Broadcast(ctx context.Context, id, txHex string, timeout time.Duration) error diff --git a/chainstate/logger.go b/chainstate/logger.go deleted file mode 100644 index 4899d270..00000000 --- a/chainstate/logger.go +++ /dev/null @@ -1,48 +0,0 @@ -package chainstate - -import ( - "context" - "fmt" - - zlogger "github.com/mrz1836/go-logger" - "gorm.io/gorm/logger" -) - -// newBasicLogger will return a basic logger interface -func newBasicLogger(debugging bool) Logger { - logLevel := logger.Warn - if debugging { - logLevel = logger.Info - } - return &basicLogger{LogLevel: logLevel} -} - -// basicLogger is a basic logging implementation -type basicLogger struct { - LogLevel logger.LogLevel -} - -// LogMode log mode -func (l *basicLogger) LogMode(level logger.LogLevel) Logger { - newLogger := *l - newLogger.LogLevel = level - return &newLogger -} - -// Info print information -func (l *basicLogger) Info(_ context.Context, message string, params ...interface{}) { - if l.LogLevel >= logger.Info { - displayLog(zlogger.INFO, message, params...) - } -} - -// displayLog will display a log using logger -func displayLog(level zlogger.LogLevel, message string, params ...interface{}) { - var keyValues []zlogger.KeyValue - if len(params) > 0 { - for index, val := range params { - keyValues = append(keyValues, zlogger.MakeParameter(fmt.Sprintf("index_%d", index), val)) - } - } - zlogger.Data(2, level, message, keyValues...) -} diff --git a/client.go b/client.go index 4af5efaa..1cfd05a7 100644 --- a/client.go +++ b/client.go @@ -14,7 +14,6 @@ import ( "github.com/newrelic/go-agent/v3/newrelic" "github.com/tonicpow/go-paymail" "github.com/tonicpow/go-paymail/server" - glogger "gorm.io/gorm/logger" ) type ( @@ -33,7 +32,7 @@ type ( encryptionKey string // Encryption key for encrypting sensitive information (IE: paymail xPub) (hex encoded key) itc bool // (Incoming Transactions Check) True will check incoming transactions via Miners (real-world) iuc bool // (Input UTXO Check) True will check input utxos when saving transactions - logger glogger.Interface // Internal logging + logger logger.Interface // Internal logging models *modelOptions // Configuration options for the loaded models newRelic *newRelicOptions // Configuration options for NewRelic notifications *notificationsOptions // Configuration options for Notifications @@ -279,7 +278,7 @@ func (c *Client) Datastore() datastore.ClientInterface { } // Logger will return the Logger if it exists -func (c *Client) Logger() glogger.Interface { +func (c *Client) Logger() logger.Interface { return c.options.logger } @@ -407,7 +406,7 @@ func (c *Client) Notifications() notifications.ClientInterface { return nil } -// SetNotificationsClient will overwrite the Notifications client with the given client +// SetNotificationsClient will overwrite the notification's client with the given client func (c *Client) SetNotificationsClient(client notifications.ClientInterface) { c.options.notifications.client = client } diff --git a/client_options.go b/client_options.go index da73793c..80d1700f 100644 --- a/client_options.go +++ b/client_options.go @@ -8,6 +8,7 @@ import ( "github.com/BuxOrg/bux/cachestore" "github.com/BuxOrg/bux/chainstate" "github.com/BuxOrg/bux/datastore" + "github.com/BuxOrg/bux/logger" "github.com/BuxOrg/bux/notifications" "github.com/BuxOrg/bux/taskmanager" "github.com/coocood/freecache" @@ -18,7 +19,6 @@ import ( "github.com/tonicpow/go-paymail/server" "github.com/vmihailenco/taskq/v3" "go.mongodb.org/mongo-driver/mongo" - "gorm.io/gorm/logger" ) // ClientOps allow functional options to be supplied that overwrite default client options. @@ -178,18 +178,10 @@ func WithNewRelic(app *newrelic.Application) ClientOps { c.newRelic.app = app // Enable New relic on other services - if c.chainstate != nil { - c.chainstate.options = append(c.chainstate.options, chainstate.WithNewRelic()) - } - if c.cacheStore != nil { - c.cacheStore.options = append(c.cacheStore.options, cachestore.WithNewRelic()) - } - if c.dataStore != nil { - c.dataStore.options = append(c.dataStore.options, datastore.WithNewRelic()) - } - if c.taskManager != nil { - c.taskManager.options = append(c.taskManager.options, taskmanager.WithNewRelic()) - } + c.cacheStore.options = append(c.cacheStore.options, cachestore.WithNewRelic()) + c.chainstate.options = append(c.chainstate.options, chainstate.WithNewRelic()) + c.dataStore.options = append(c.dataStore.options, datastore.WithNewRelic()) + c.taskManager.options = append(c.taskManager.options, taskmanager.WithNewRelic()) // Enable the service c.newRelic.enabled = true @@ -249,19 +241,11 @@ func WithLogger(customLogger logger.Interface) ClientOps { if customLogger != nil { c.logger = customLogger - // Enable debugging on other services - if c.chainstate != nil { - c.chainstate.options = append(c.chainstate.options, chainstate.WithLogger(c.logger)) - } - if c.taskManager != nil { - c.taskManager.options = append(c.taskManager.options, taskmanager.WithLogger(c.logger)) - } - if c.dataStore != nil { - c.dataStore.options = append(c.dataStore.options, datastore.WithLogger(c.logger)) - } - if c.cacheStore != nil { - c.cacheStore.options = append(c.cacheStore.options, cachestore.WithLogger(c.logger)) - } + // Enable the logger on all services + c.cacheStore.options = append(c.cacheStore.options, cachestore.WithLogger(c.logger)) + c.chainstate.options = append(c.chainstate.options, chainstate.WithLogger(c.logger)) + c.dataStore.options = append(c.dataStore.options, datastore.WithLogger(&datastore.DatabaseLogWrapper{Interface: c.logger})) + c.taskManager.options = append(c.taskManager.options, taskmanager.WithLogger(c.logger)) } } } diff --git a/datastore/client.go b/datastore/client.go index 898b48b6..1c44968f 100644 --- a/datastore/client.go +++ b/datastore/client.go @@ -4,10 +4,11 @@ import ( "context" "strings" + "github.com/BuxOrg/bux/logger" "github.com/newrelic/go-agent/v3/newrelic" "go.mongodb.org/mongo-driver/mongo" "gorm.io/gorm" - "gorm.io/gorm/logger" + glogger "gorm.io/gorm/logger" ) type ( @@ -19,19 +20,20 @@ type ( // clientOptions holds all the configuration for the client clientOptions struct { - autoMigrate bool // Setting for Auto Migration of SQL tables - db *gorm.DB // Database connection for Read-Only requests (can be same as Write) - debug bool // Setting for global debugging - engine Engine // Datastore engine (MySQL, PostgreSQL, SQLite) - logger logger.Interface // Custom logger interface - migratedModels []string // List of models (types) that have been migrated - migrateModels []interface{} // Models for migrations - mongoDB *mongo.Database // Database connection for a MongoDB datastore - mongoDBConfig *MongoDBConfig // Configuration for a MongoDB datastore - newRelicEnabled bool // If NewRelic is enabled (parent application) - sqlConfigs []*SQLConfig // Configuration for a MySQL or PostgreSQL datastore - sqLite *SQLiteConfig // Configuration for a SQLite datastore - tablePrefix string // Model table prefix + autoMigrate bool // Setting for Auto Migration of SQL tables + db *gorm.DB // Database connection for Read-Only requests (can be same as Write) + debug bool // Setting for global debugging + engine Engine // Datastore engine (MySQL, PostgreSQL, SQLite) + logger logger.Interface // Custom logger interface (from BUX) + loggerDB glogger.Interface // Custom logger interface (for GORM) + migratedModels []string // List of models (types) that have been migrated + migrateModels []interface{} // Models for migrations + mongoDB *mongo.Database // Database connection for a MongoDB datastore + mongoDBConfig *MongoDBConfig // Configuration for a MongoDB datastore + newRelicEnabled bool // If NewRelic is enabled (parent application) + sqlConfigs []*SQLConfig // Configuration for a MySQL or PostgreSQL datastore + sqLite *SQLiteConfig // Configuration for a SQLite datastore + tablePrefix string // Model table prefix } ) @@ -49,11 +51,14 @@ func NewClient(ctx context.Context, opts ...ClientOps) (ClientInterface, error) opt(client.options) } - // Set logger if not set now + // Set logger (if not set already) if client.options.logger == nil { - client.options.logger = newBasicLogger(client.IsDebug()) + client.options.logger = logger.NewLogger(client.IsDebug()) } + // Create GORM logger + client.options.loggerDB = &DatabaseLogWrapper{client.options.logger} + // EMPTY! Engine was NOT set and will use the default (file based) if client.Engine().IsEmpty() { @@ -85,7 +90,7 @@ func NewClient(ctx context.Context, opts ...ClientOps) (ClientInterface, error) var err error if client.Engine() == MySQL || client.Engine() == PostgreSQL { if client.options.db, err = openSQLDatabase( - client.options.logger, client.options.sqlConfigs..., + client.options.loggerDB, client.options.sqlConfigs..., ); err != nil { return nil, err } @@ -97,7 +102,7 @@ func NewClient(ctx context.Context, opts ...ClientOps) (ClientInterface, error) } } else { // SQLite if client.options.db, err = openSQLiteDatabase( - client.options.logger, client.options.sqLite, + client.options.loggerDB, client.options.sqLite, ); err != nil { return nil, err } diff --git a/datastore/client_options.go b/datastore/client_options.go index 9d3dd393..89aca7ee 100644 --- a/datastore/client_options.go +++ b/datastore/client_options.go @@ -4,9 +4,9 @@ import ( "context" "database/sql" + "github.com/BuxOrg/bux/logger" "github.com/newrelic/go-agent/v3/newrelic" "go.mongodb.org/mongo-driver/mongo" - "gorm.io/gorm/logger" ) // ClientOps allow functional options to be supplied diff --git a/datastore/client_options_test.go b/datastore/client_options_test.go index 3f84c135..5a680095 100644 --- a/datastore/client_options_test.go +++ b/datastore/client_options_test.go @@ -6,6 +6,7 @@ import ( "os" "testing" + "github.com/BuxOrg/bux/logger" "github.com/newrelic/go-agent/v3/newrelic" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" @@ -329,9 +330,9 @@ func TestWithLogger(t *testing.T) { assert.Nil(t, options.logger) }) - t.Run("test applying nil", func(t *testing.T) { + t.Run("test applying valid logger", func(t *testing.T) { options := &clientOptions{} - l := newBasicLogger(true) + l := logger.NewLogger(true) opt := WithLogger(l) opt(options) assert.Equal(t, l, options.logger) diff --git a/datastore/logger.go b/datastore/logger.go index eb759af8..a1d8713e 100644 --- a/datastore/logger.go +++ b/datastore/logger.go @@ -1,87 +1,27 @@ package datastore import ( - "context" - "fmt" - "time" - - zlogger "github.com/mrz1836/go-logger" - "gorm.io/gorm/logger" - "gorm.io/gorm/utils" + "github.com/BuxOrg/bux/logger" + glogger "gorm.io/gorm/logger" ) -// newBasicLogger will return a basic logger interface -func newBasicLogger(debugging bool) logger.Interface { - logLevel := logger.Warn - if debugging { - logLevel = logger.Info - } - return &basicLogger{LogLevel: logLevel} -} - -// basicLogger is a basic implementation of the logger interface if no custom logger is provided -type basicLogger struct { - LogLevel logger.LogLevel -} - -// LogMode log mode -func (l *basicLogger) LogMode(level logger.LogLevel) logger.Interface { - newLogger := *l - newLogger.LogLevel = level - return &newLogger -} - -// Info print information -func (l *basicLogger) Info(_ context.Context, message string, params ...interface{}) { - if l.LogLevel >= logger.Info { - displayLog(zlogger.INFO, message, params...) - } +// DatabaseLogWrapper is a special wrapper for the GORM logger +type DatabaseLogWrapper struct { + logger.Interface } -// Warn print warn messages -func (l *basicLogger) Warn(_ context.Context, message string, params ...interface{}) { - if l.LogLevel >= logger.Warn { - displayLog(zlogger.WARN, message, params...) +// LogMode will set the log level/mode +func (d *DatabaseLogWrapper) LogMode(level glogger.LogLevel) glogger.Interface { + newLogger := *d + if level == glogger.Info { + newLogger.SetMode(logger.Info) + } else if level == glogger.Warn { + newLogger.SetMode(logger.Warn) + } else if level == glogger.Error { + newLogger.SetMode(logger.Error) + } else if level == glogger.Silent { + newLogger.SetMode(logger.Silent) } -} -// Error print error messages -func (l *basicLogger) Error(_ context.Context, message string, params ...interface{}) { - if l.LogLevel >= logger.Error { - displayLog(zlogger.ERROR, message, params...) - } -} - -// Trace print sql message (Gorm Specific) -func (l *basicLogger) Trace(_ context.Context, begin time.Time, fc func() (sql string, rowsAffected int64), err error) { - if l.LogLevel >= logger.Silent { - return - } - - elapsed := time.Since(begin) - sql, rows := fc() - level := zlogger.DEBUG - - params := []zlogger.KeyValue{ - zlogger.MakeParameter("executing_file", utils.FileWithLineNum()), - zlogger.MakeParameter("elapsed", fmt.Sprintf("%.3fms", float64(elapsed.Nanoseconds())/1e6)), - zlogger.MakeParameter("rows", rows), - zlogger.MakeParameter("sql", sql), - } - if err != nil { - params = append(params, zlogger.MakeParameter("error_message", err.Error())) - level = zlogger.ERROR - } - zlogger.Data(2, level, "sql trace", params...) -} - -// displayLog will display a log using logger -func displayLog(level zlogger.LogLevel, message string, params ...interface{}) { - var keyValues []zlogger.KeyValue - if len(params) > 0 { - for index, val := range params { - keyValues = append(keyValues, zlogger.MakeParameter(fmt.Sprintf("index_%d", index), val)) - } - } - zlogger.Data(2, level, message, keyValues...) + return &newLogger } diff --git a/datastore/migrate.go b/datastore/migrate.go index 01434526..3980c758 100644 --- a/datastore/migrate.go +++ b/datastore/migrate.go @@ -52,7 +52,7 @@ func (c *Client) AutoMigrateDatabase(ctx context.Context, models ...interface{}) } // Migrate database for SQL (using GORM) - return autoMigrateSQLDatabase(ctx, c.Engine(), c.options.db, c.IsDebug(), c.options.logger, models...) + return autoMigrateSQLDatabase(ctx, c.Engine(), c.options.db, c.IsDebug(), c.options.loggerDB, models...) } // IsAutoMigrate returns whether auto migration is on diff --git a/datastore/models.go b/datastore/models.go index 4c3cc021..5bfbea59 100644 --- a/datastore/models.go +++ b/datastore/models.go @@ -174,7 +174,7 @@ func (c *Client) GetModel( c.options.db = nrgorm.SetTxnToGorm(newrelic.FromContext(ctx), c.options.db) // Create a new context, and new db tx - ctxDB, cancel := createCtx(ctx, c.options.db, timeout, c.IsDebug(), c.options.logger) + ctxDB, cancel := createCtx(ctx, c.options.db, timeout, c.IsDebug(), c.options.loggerDB) defer cancel() // Check for errors or no records found @@ -225,7 +225,7 @@ func (c *Client) find(ctx context.Context, result interface{}, conditions map[st c.options.db = nrgorm.SetTxnToGorm(newrelic.FromContext(ctx), c.options.db) // Create a new context, and new db tx - ctxDB, cancel := createCtx(ctx, c.options.db, timeout, c.IsDebug(), c.options.logger) + ctxDB, cancel := createCtx(ctx, c.options.db, timeout, c.IsDebug(), c.options.loggerDB) defer cancel() // Create the offset diff --git a/datastore/sql.go b/datastore/sql.go index d7bf8023..aadc704c 100644 --- a/datastore/sql.go +++ b/datastore/sql.go @@ -10,7 +10,7 @@ import ( "gorm.io/driver/postgres" "gorm.io/driver/sqlite" "gorm.io/gorm" - "gorm.io/gorm/logger" + glogger "gorm.io/gorm/logger" "gorm.io/gorm/schema" "gorm.io/plugin/dbresolver" ) @@ -34,7 +34,7 @@ const ( ) // openSQLDatabase will open a new SQL database -func openSQLDatabase(optionalLogger logger.Interface, configs ...*SQLConfig) (db *gorm.DB, err error) { +func openSQLDatabase(optionalLogger glogger.Interface, configs ...*SQLConfig) (db *gorm.DB, err error) { // Try to find a source var sourceConfig *SQLConfig @@ -126,7 +126,7 @@ func openSQLDatabase(optionalLogger logger.Interface, configs ...*SQLConfig) (db } // openSQLiteDatabase will open a SQLite database connection -func openSQLiteDatabase(optionalLogger logger.Interface, config *SQLiteConfig) (db *gorm.DB, err error) { +func openSQLiteDatabase(optionalLogger glogger.Interface, config *SQLiteConfig) (db *gorm.DB, err error) { // Check for an existing connection var dialector gorm.Dialector @@ -270,7 +270,7 @@ func getSourceDatabase(configs []*SQLConfig) (*SQLConfig, []*SQLConfig) { } // getGormSessionConfig returns the gorm session config -func getGormSessionConfig(preparedStatement, debug bool, optionalLogger logger.Interface) *gorm.Session { +func getGormSessionConfig(preparedStatement, debug bool, optionalLogger glogger.Interface) *gorm.Session { config := &gorm.Session{ AllowGlobalUpdate: false, @@ -289,14 +289,14 @@ func getGormSessionConfig(preparedStatement, debug bool, optionalLogger logger.I // Optional logger vs basic if optionalLogger == nil { - logLevel := logger.Silent + logLevel := glogger.Silent if debug { - logLevel = logger.Info + logLevel = glogger.Info } - config.Logger = logger.New( + config.Logger = glogger.New( log.New(os.Stdout, "\r\n ", log.LstdFlags), // io writer - logger.Config{ + glogger.Config{ SlowThreshold: 5 * time.Second, // Slow SQL threshold LogLevel: logLevel, // Log level IgnoreRecordNotFoundError: true, // Ignore ErrRecordNotFound error for logger @@ -311,7 +311,7 @@ func getGormSessionConfig(preparedStatement, debug bool, optionalLogger logger.I // getGormConfig will return a valid gorm.Config // // See: https://gorm.io/docs/gorm_config.html -func getGormConfig(tablePrefix string, preparedStatement, debug bool, optionalLogger logger.Interface) *gorm.Config { +func getGormConfig(tablePrefix string, preparedStatement, debug bool, optionalLogger glogger.Interface) *gorm.Config { // Set the prefix if len(tablePrefix) > 0 { @@ -344,14 +344,14 @@ func getGormConfig(tablePrefix string, preparedStatement, debug bool, optionalLo // Optional logger vs basic if optionalLogger == nil { - logLevel := logger.Silent + logLevel := glogger.Silent if debug { - logLevel = logger.Info + logLevel = glogger.Info } - config.Logger = logger.New( + config.Logger = glogger.New( log.New(os.Stdout, "\r\n ", log.LstdFlags), // io writer - logger.Config{ + glogger.Config{ SlowThreshold: 5 * time.Second, // Slow SQL threshold LogLevel: logLevel, // Log level IgnoreRecordNotFoundError: true, // Ignore ErrRecordNotFound error for logger diff --git a/datastore/transaction.go b/datastore/transaction.go index e85b8175..6aa2b32c 100644 --- a/datastore/transaction.go +++ b/datastore/transaction.go @@ -12,7 +12,7 @@ func (c *Client) NewTx(ctx context.Context, fn func(*Transaction) error) error { // All GORM databases if c.options.db != nil { - sessionDb := c.options.db.Session(getGormSessionConfig(c.options.db.PrepareStmt, c.IsDebug(), c.options.logger)) + sessionDb := c.options.db.Session(getGormSessionConfig(c.options.db.PrepareStmt, c.IsDebug(), c.options.loggerDB)) return fn(&Transaction{ sqlTx: sessionDb.Begin(), }) diff --git a/interface.go b/interface.go index 706bb584..b33181d2 100644 --- a/interface.go +++ b/interface.go @@ -8,11 +8,11 @@ import ( "github.com/BuxOrg/bux/cachestore" "github.com/BuxOrg/bux/chainstate" "github.com/BuxOrg/bux/datastore" + "github.com/BuxOrg/bux/logger" "github.com/BuxOrg/bux/notifications" "github.com/BuxOrg/bux/taskmanager" "github.com/BuxOrg/bux/utils" "github.com/tonicpow/go-paymail" - "gorm.io/gorm/logger" ) // AccessKeyService is the access key actions diff --git a/logger/logger.go b/logger/logger.go index 48ce8cc4..9353287b 100644 --- a/logger/logger.go +++ b/logger/logger.go @@ -6,55 +6,82 @@ import ( "time" zlogger "github.com/mrz1836/go-logger" - glogger "gorm.io/gorm/logger" - "gorm.io/gorm/utils" +) + +// Interface is a logger interface +type Interface interface { + SetMode(LogLevel) Interface + GetMode() LogLevel + Info(context.Context, string, ...interface{}) + Warn(context.Context, string, ...interface{}) + Error(context.Context, string, ...interface{}) + Trace(ctx context.Context, begin time.Time, fc func() (sql string, rowsAffected int64), err error) +} + +// LogLevel is the log level +type LogLevel int + +const ( + // Silent silent log level + Silent LogLevel = iota + 1 + // Error error log level + Error + // Warn warn log level + Warn + // Info info log level + Info ) // NewLogger will return a basic logger interface -func NewLogger(debugging bool) glogger.Interface { - logLevel := glogger.Warn +func NewLogger(debugging bool) Interface { + logLevel := Warn if debugging { - logLevel = glogger.Info + logLevel = Info } - return &basicLogger{LogLevel: logLevel} + return &basicLogger{logLevel: logLevel} } // basicLogger is a basic implementation of the logger interface if no custom logger is provided type basicLogger struct { - LogLevel glogger.LogLevel + logLevel LogLevel } -// LogMode log mode -func (l *basicLogger) LogMode(level glogger.LogLevel) glogger.Interface { +// SetMode will set the log mode +func (l *basicLogger) SetMode(level LogLevel) Interface { newLogger := *l - newLogger.LogLevel = level + newLogger.logLevel = level return &newLogger } +// GetMode will get the log mode +func (l *basicLogger) GetMode() LogLevel { + return l.logLevel +} + // Info print information func (l *basicLogger) Info(_ context.Context, message string, params ...interface{}) { - if l.LogLevel >= glogger.Info { + if l.logLevel >= Info { displayLog(zlogger.INFO, message, params...) } } // Warn print warn messages func (l *basicLogger) Warn(_ context.Context, message string, params ...interface{}) { - if l.LogLevel >= glogger.Warn { + if l.logLevel >= Warn { displayLog(zlogger.WARN, message, params...) } } // Error print error messages func (l *basicLogger) Error(_ context.Context, message string, params ...interface{}) { - if l.LogLevel >= glogger.Error { + if l.logLevel >= Error { displayLog(zlogger.ERROR, message, params...) } } -// Trace print sql message (Gorm Specific) +// Trace is for GORM and SQL tracing func (l *basicLogger) Trace(_ context.Context, begin time.Time, fc func() (sql string, rowsAffected int64), err error) { - if l.LogLevel >= glogger.Silent { + if l.logLevel >= Silent { return } @@ -63,7 +90,7 @@ func (l *basicLogger) Trace(_ context.Context, begin time.Time, fc func() (sql s level := zlogger.DEBUG params := []zlogger.KeyValue{ - zlogger.MakeParameter("executing_file", utils.FileWithLineNum()), + // zlogger.MakeParameter("executing_file", utils.FileWithLineNum()), // @mrz turned off for removing the gorm dependency zlogger.MakeParameter("elapsed", fmt.Sprintf("%.3fms", float64(elapsed.Nanoseconds())/1e6)), zlogger.MakeParameter("rows", rows), zlogger.MakeParameter("sql", sql), diff --git a/logger/logger_test.go b/logger/logger_test.go index a9f1a71a..71e79a63 100644 --- a/logger/logger_test.go +++ b/logger/logger_test.go @@ -4,7 +4,6 @@ import ( "testing" "github.com/stretchr/testify/require" - glogger "gorm.io/gorm/logger" ) func TestNewLogger(t *testing.T) { @@ -26,7 +25,7 @@ func TestBasicLogger_LogMode(t *testing.T) { l := NewLogger(true) require.NotNil(t, l) - l2 := l.LogMode(glogger.Info) + l2 := l.SetMode(Info) require.NotNil(t, l2) }) } diff --git a/taskmanager/client.go b/taskmanager/client.go index 8565e78d..c3f6ee75 100644 --- a/taskmanager/client.go +++ b/taskmanager/client.go @@ -4,6 +4,7 @@ import ( "context" "errors" + "github.com/BuxOrg/bux/logger" "github.com/newrelic/go-agent/v3/newrelic" "github.com/vmihailenco/taskq/v3" ) @@ -17,12 +18,12 @@ type ( // clientOptions holds all the configuration for the client clientOptions struct { - cronService CronService // Internal cron job client - debug bool // For extra logs and additional debug information - engine Engine // Taskmanager engine (taskq or machinery) - logger Logger // Internal logging - newRelicEnabled bool // If NewRelic is enabled (parent application) - taskq *taskqOptions // All configuration and options for using TaskQ + cronService CronService // Internal cron job client + debug bool // For extra logs and additional debug information + engine Engine // Taskmanager engine (taskq or machinery) + logger logger.Interface // Internal logging + newRelicEnabled bool // If NewRelic is enabled (parent application) + taskq *taskqOptions // All configuration and options for using TaskQ } // taskqOptions holds all the configuration for the TaskQ engine @@ -49,6 +50,11 @@ func NewClient(_ context.Context, opts ...ClientOps) (ClientInterface, error) { opt(client.options) } + // Set logger if not set + if client.options.logger == nil { + client.options.logger = logger.NewLogger(client.IsDebug()) + } + // EMPTY! Engine was NOT set if client.Engine().IsEmpty() { return nil, ErrNoEngine @@ -71,11 +77,6 @@ func NewClient(_ context.Context, opts ...ClientOps) (ClientInterface, error) { client.localCron() } - // Set logger if not set - if client.options.logger == nil { - client.options.logger = newLogger() - } - // Return the client return client, nil } diff --git a/taskmanager/client_options.go b/taskmanager/client_options.go index 6b624e02..19cadd6c 100644 --- a/taskmanager/client_options.go +++ b/taskmanager/client_options.go @@ -3,6 +3,7 @@ package taskmanager import ( "context" + "github.com/BuxOrg/bux/logger" "github.com/newrelic/go-agent/v3/newrelic" "github.com/vmihailenco/taskq/v3" ) @@ -64,7 +65,7 @@ func WithTaskQ(config *taskq.QueueOptions, factory Factory) ClientOps { } // WithLogger will set the custom logger interface -func WithLogger(customLogger Logger) ClientOps { +func WithLogger(customLogger logger.Interface) ClientOps { return func(c *clientOptions) { if customLogger != nil { c.logger = customLogger diff --git a/taskmanager/client_options_test.go b/taskmanager/client_options_test.go index c3d0d92f..76d0461c 100644 --- a/taskmanager/client_options_test.go +++ b/taskmanager/client_options_test.go @@ -3,6 +3,7 @@ package taskmanager import ( "testing" + "github.com/BuxOrg/bux/logger" "github.com/stretchr/testify/assert" ) @@ -91,7 +92,7 @@ func TestWithLogger(t *testing.T) { t.Run("test applying option", func(t *testing.T) { options := &clientOptions{} - customClient := newLogger() + customClient := logger.NewLogger(true) opt := WithLogger(customClient) opt(options) assert.Equal(t, customClient, options.logger) diff --git a/taskmanager/interface.go b/taskmanager/interface.go index 6924068f..4209327b 100644 --- a/taskmanager/interface.go +++ b/taskmanager/interface.go @@ -6,11 +6,6 @@ import ( "github.com/vmihailenco/taskq/v3" ) -// Logger is the logger interface for debug messages -type Logger interface { - Info(ctx context.Context, message string, params ...interface{}) -} - // TaskService is the task related methods type TaskService interface { RegisterTask(task *Task) error diff --git a/taskmanager/logger.go b/taskmanager/logger.go deleted file mode 100644 index b97c3541..00000000 --- a/taskmanager/logger.go +++ /dev/null @@ -1,32 +0,0 @@ -package taskmanager - -import ( - "context" - "fmt" - - zlogger "github.com/mrz1836/go-logger" -) - -// newLogger will return a basic logger interface -func newLogger() Logger { - return &basicLogger{} -} - -// basicLogger is a basic logging implementation -type basicLogger struct{} - -// Info will print information -func (l *basicLogger) Info(_ context.Context, message string, params ...interface{}) { - displayLog(zlogger.INFO, message, params...) -} - -// displayLog will display a log using logger -func displayLog(level zlogger.LogLevel, message string, params ...interface{}) { - var keyValues []zlogger.KeyValue - if len(params) > 0 { - for index, val := range params { - keyValues = append(keyValues, zlogger.MakeParameter(fmt.Sprintf("index_%d", index), val)) - } - } - zlogger.Data(2, level, message, keyValues...) -} diff --git a/tasks.go b/tasks.go index 2d6dc55b..47b4741c 100644 --- a/tasks.go +++ b/tasks.go @@ -6,7 +6,7 @@ import ( "time" "github.com/BuxOrg/bux/datastore" - "gorm.io/gorm/logger" + "github.com/BuxOrg/bux/logger" ) // TaskCleanupDraftTransactions will clean up all old expired draft transactions