From ba4ca2f5843a3800a737bff808b8fb56f69f9496 Mon Sep 17 00:00:00 2001 From: Dylan <64976002+galt-tr@users.noreply.github.com> Date: Fri, 9 Feb 2024 11:55:27 -0500 Subject: [PATCH] Enable support for disabling RPC verification and writing to a log file (#46) * Remove gocore logger * Updates to fix CI * Fix linter --- app/config/config.go | 2 + app/config/datastore.go | 5 +- app/config/envs/local.json | 3 +- app/config/envs/mainnet.json | 5 +- app/config/envs/production.json | 4 +- app/config/envs/stn.json | 2 + app/config/envs/test.json | 2 + app/config/envs/testnet.json | 2 + app/config/load.go | 16 ++++-- app/config/logger.go | 68 ++++++++++++++++++++++++-- app/models/model/model.go | 4 +- app/models/model/model_options_test.go | 5 +- cmd/main.go | 11 +++-- go.mod | 2 +- 14 files changed, 113 insertions(+), 18 deletions(-) diff --git a/app/config/config.go b/app/config/config.go index 60e6cc7..dee9196 100644 --- a/app/config/config.go +++ b/app/config/config.go @@ -57,6 +57,8 @@ type ( Config struct { AlertWebhookURL string `json:"alert_webhook_url" mapstructure:"alert_webhook_url"` // AlertWebhookURL is the URL for the alert webhook Datastore DatastoreConfig `json:"datastore" mapstructure:"datastore"` // Datastore's configuration + DisableRPCVerification bool `json:"disable_rpc_verification" mapstructure:"disable_rpc_verification"` // DisableRPCVerification will disable the rpc verification check on startup. Useful if bitcoind isn't running yet + LogOutputFile string `json:"log_output_file" mapstructure:"log_output_file"` // LogOutputFile will set an output file for the logger to write to as opposed to stdout BitcoinConfigPath string `json:"bitcoin_config_path" mapstructure:"bitcoin_config_path"` // BitcoinConfigPath is the path to the bitcoin.conf file P2P P2PConfig `json:"p2p" mapstructure:"p2p"` // P2P is the configuration for the P2P server RPCConnections []RPCConfig `json:"rpc_connections" mapstructure:"rpc_connections"` // RPCConnections is a list of RPC connections diff --git a/app/config/datastore.go b/app/config/datastore.go index 94614a6..2ca3590 100644 --- a/app/config/datastore.go +++ b/app/config/datastore.go @@ -3,6 +3,8 @@ package config import ( "context" + "github.com/mrz1836/go-logger" + "github.com/mrz1836/go-datastore" ) @@ -11,7 +13,8 @@ func (c *Config) loadDatastore(ctx context.Context, models []interface{}) error // Sync collecting the options var options []datastore.ClientOps - + //TODO: pass in our own logger, but for now this doesn't work so i'm just going to silently log for now + options = append(options, datastore.WithLogger(logger.NewGormLogger(false, 0))) // Select the datastore if c.Datastore.Engine == datastore.SQLite { options = append(options, datastore.WithSQLite(&datastore.SQLiteConfig{ diff --git a/app/config/envs/local.json b/app/config/envs/local.json index 9a88751..3ae7a09 100644 --- a/app/config/envs/local.json +++ b/app/config/envs/local.json @@ -1,8 +1,9 @@ { "alert_webhook_url": "", "bitcoin_config_path": "", + "disable_rpc_verification": false, + "log_output_file": "", "request_logging": true, - "bitcoin_config_path": "/home/galt/.bitcoin/bitcoin.conf", "alert_processing_interval": "5m", "web_server": { "idle_timeout": "60s", diff --git a/app/config/envs/mainnet.json b/app/config/envs/mainnet.json index c5f889a..8438305 100644 --- a/app/config/envs/mainnet.json +++ b/app/config/envs/mainnet.json @@ -1,7 +1,10 @@ { "alert_webhook_url": "", "bitcoin_config_path": "", + "log_output_file": "", + "disable_rpc_verification": false, "request_logging": true, + "alert_processing_interval": "5m", "web_server": { "idle_timeout": "60s", "port": "3000", @@ -55,7 +58,7 @@ "p2p": { "ip": "0.0.0.0", "port": "9906", - "alert_system_protocol_id": "/bitcoin/alert-system/1.0.1", + "alert_system_protocol_id": "/bitcoin/alert-system/1.0.0", "bootstrap_peer": "", "private_key_path": "", "topic_name": "bitcoin_alert_system" diff --git a/app/config/envs/production.json b/app/config/envs/production.json index dbf27b5..243f98d 100644 --- a/app/config/envs/production.json +++ b/app/config/envs/production.json @@ -1,6 +1,8 @@ { "alert_webhook_url": "", "bitcoin_config_path": "", + "log_output_file": "", + "disable_rpc_verification": false, "request_logging": true, "web_server": { "idle_timeout": "60s", @@ -55,7 +57,7 @@ "p2p": { "ip": "0.0.0.0", "port": "9906", - "alert_system_protocol_id": "/bitcoin/alert-system/1.0.1", + "alert_system_protocol_id": "/bitcoin/alert-system/1.0.0", "bootstrap_peer": "", "private_key_path": "", "topic_name": "bitcoin_alert_system" diff --git a/app/config/envs/stn.json b/app/config/envs/stn.json index f505a0d..846c4a4 100644 --- a/app/config/envs/stn.json +++ b/app/config/envs/stn.json @@ -1,6 +1,8 @@ { "alert_webhook_url": "", "bitcoin_config_path": "", + "log_output_file": "", + "disable_rpc_verification": false, "request_logging": true, "alert_processing_interval": "5m", "web_server": { diff --git a/app/config/envs/test.json b/app/config/envs/test.json index 654afa1..9eab6bc 100644 --- a/app/config/envs/test.json +++ b/app/config/envs/test.json @@ -1,6 +1,8 @@ { "alert_webhook_url": "https://webhook.url", "bitcoin_config_path": "", + "log_output_file": "", + "disable_rpc_verification": false, "request_logging": true, "web_server": { "idle_timeout": "60s", diff --git a/app/config/envs/testnet.json b/app/config/envs/testnet.json index 7768954..2a41992 100644 --- a/app/config/envs/testnet.json +++ b/app/config/envs/testnet.json @@ -1,6 +1,8 @@ { "alert_webhook_url": "", "bitcoin_config_path": "", + "log_output_file": "", + "disable_rpc_verification": false, "request_logging": true, "alert_processing_interval": "5m", "web_server": { diff --git a/app/config/load.go b/app/config/load.go index 0000589..5b1aac6 100644 --- a/app/config/load.go +++ b/app/config/load.go @@ -7,6 +7,7 @@ import ( "errors" "fmt" "io/fs" + "log" "net" "net/http" "os" @@ -14,7 +15,6 @@ import ( "sync" "github.com/mrz1836/go-datastore" - "github.com/ordishs/gocore" "github.com/spf13/viper" ) @@ -214,9 +214,19 @@ func LoadConfigFile() (_appConfig *Config, err error) { return nil, err } - // Load the logger service (gocore.Logger meets the LoggerInterface) + // Load the logger service (ExtendedLogger meets the LoggerInterface) + writer := os.Stdout + if _appConfig.LogOutputFile != "" { + writer, err = os.OpenFile(_appConfig.LogOutputFile, os.O_RDWR|os.O_CREATE|os.O_APPEND, 0600) + if err != nil { + return nil, err + } + } + + logger := log.New(writer, "bitcoin-alert-system: ", log.LstdFlags) _appConfig.Services.Log = &ExtendedLogger{ - Logger: gocore.Log(ApplicationName), + Logger: logger, + writer: writer, } // Set default alert processing interval if it doesn't exist diff --git a/app/config/logger.go b/app/config/logger.go index 22554e5..427d931 100644 --- a/app/config/logger.go +++ b/app/config/logger.go @@ -1,6 +1,10 @@ package config -import "github.com/ordishs/gocore" +import ( + "fmt" + "log" + "os" +) // LoggerInterface is the interface for the logger // This is used to allow the logger to be mocked and tested @@ -21,15 +25,73 @@ type LoggerInterface interface { Warn(args ...interface{}) Warnf(msg string, args ...interface{}) Printf(format string, v ...interface{}) // Custom method for go-api-router + CloseWriter() error // GetLogLevel() gocore.logLevel } // ExtendedLogger is the extended logger to satisfy the LoggerInterface type ExtendedLogger struct { - *gocore.Logger + *log.Logger + logLevel int + writer *os.File +} + +// CloseWriter close the log writer +func (es *ExtendedLogger) CloseWriter() error { + return es.writer.Close() } // Printf will print the log message to the console func (es *ExtendedLogger) Printf(format string, v ...interface{}) { - es.Infof(format, v...) + es.Logger.Printf(format, v...) +} + +// Debugf will print debug messages to the console +func (es *ExtendedLogger) Debugf(format string, v ...interface{}) { + es.Logger.Printf(fmt.Sprintf("\033[1;34m| DEBUG | %s\033[0m", format), v...) +} + +// Debug will print debug messages to the console +func (es *ExtendedLogger) Debug(v ...interface{}) { + es.Logger.Printf("%v", v...) +} + +// Error will print debug messages to the console +func (es *ExtendedLogger) Error(v ...interface{}) { + es.Logger.Printf("%v", v...) +} + +// Errorf will print debug messages to the console +func (es *ExtendedLogger) Errorf(format string, v ...interface{}) { + es.Logger.Printf(fmt.Sprintf("\033[1;31m| ERROR |: %s\033[0m", format), v...) +} + +// ErrorWithStack will print debug messages to the console +func (es *ExtendedLogger) ErrorWithStack(format string, v ...interface{}) { + es.Logger.Printf(format, v...) +} + +// Info will print info messages to the console +func (es *ExtendedLogger) Info(v ...interface{}) { + es.Logger.Printf("%v", v...) +} + +// Infof will print info messages to the console +func (es *ExtendedLogger) Infof(format string, v ...interface{}) { + es.Logger.Printf(fmt.Sprintf("\033[1;32m| INFO | %s\033[0m", format), v...) +} + +// LogLevel returns the logging level +func (es *ExtendedLogger) LogLevel() int { + return es.logLevel +} + +// Warn will print warning messages to the console +func (es *ExtendedLogger) Warn(v ...interface{}) { + es.Logger.Printf("%v", v...) +} + +// Warnf will print warning messages to the console +func (es *ExtendedLogger) Warnf(format string, v ...interface{}) { + es.Logger.Printf(format, v...) } diff --git a/app/models/model/model.go b/app/models/model/model.go index 3756b4a..98c1b73 100644 --- a/app/models/model/model.go +++ b/app/models/model/model.go @@ -3,12 +3,12 @@ package model import ( "context" + "log" "time" "github.com/bitcoin-sv/alert-system/app/config" "github.com/mrz1836/go-datastore" customTypes "github.com/mrz1836/go-datastore/custom_types" - "github.com/ordishs/gocore" ) // Model is the generic model field(s) and interface(s) @@ -71,7 +71,7 @@ func NewBaseModel(name Name, opts ...Options) (m *Model) { // Set default logger IF NOT SET via options if m.logger == nil { m.logger = &config.ExtendedLogger{ - Logger: gocore.Log(config.ApplicationName), + Logger: &log.Logger{}, } } diff --git a/app/models/model/model_options_test.go b/app/models/model/model_options_test.go index f935c5f..555d58e 100644 --- a/app/models/model/model_options_test.go +++ b/app/models/model/model_options_test.go @@ -1,10 +1,11 @@ package model import ( + "log" + "os" "testing" "github.com/bitcoin-sv/alert-system/app/config" - "github.com/ordishs/gocore" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) @@ -82,7 +83,7 @@ func TestWithLogger(t *testing.T) { t.Run("valid logger", func(t *testing.T) { l := &config.ExtendedLogger{ - Logger: gocore.Log("test"), + Logger: log.New(os.Stdout, "alert-system: ", log.LstdFlags), } require.NotNil(t, l) opt := WithLogger(l) diff --git a/cmd/main.go b/cmd/main.go index ec5a963..7be271e 100644 --- a/cmd/main.go +++ b/cmd/main.go @@ -34,9 +34,11 @@ func main() { } // Ensure that RPC connection is valid - if _, err = _appConfig.Services.Node.BestBlockHash(context.Background()); err != nil { - _appConfig.Services.Log.Errorf("error talking to Bitcoin node with supplied RPC credentials: %s", err.Error()) - return + if !_appConfig.DisableRPCVerification { + if _, err = _appConfig.Services.Node.BestBlockHash(context.Background()); err != nil { + _appConfig.Services.Log.Errorf("error talking to Bitcoin node with supplied RPC credentials: %s", err.Error()) + return + } } // Create the p2p server @@ -77,6 +79,9 @@ func main() { } close(idleConnectionsClosed) + if err = appConfig.Services.Log.CloseWriter(); err != nil { + log.Printf("error closing logger: %s", err) + } }(_appConfig) // Start the p2p server diff --git a/go.mod b/go.mod index a55c98c..59a5556 100644 --- a/go.mod +++ b/go.mod @@ -18,6 +18,7 @@ require ( github.com/libsv/go-p2p v0.1.9 github.com/mrz1836/go-api-router v0.7.1 github.com/mrz1836/go-datastore v0.5.13 + github.com/mrz1836/go-logger v0.3.2 github.com/multiformats/go-multiaddr v0.12.2 github.com/newrelic/go-agent/v3/integrations/nrhttprouter v1.0.2 github.com/ordishs/gocore v1.0.57 @@ -115,7 +116,6 @@ require ( github.com/mitchellh/mapstructure v1.5.0 // indirect github.com/montanaflynn/stats v0.7.1 // indirect github.com/mr-tron/base58 v1.2.0 // indirect - github.com/mrz1836/go-logger v0.3.2 // indirect github.com/mrz1836/go-parameters v0.4.1 // indirect github.com/multiformats/go-base32 v0.1.0 // indirect github.com/multiformats/go-base36 v0.2.0 // indirect