Implement Logger (#228)

* Added new base logger

* updated example and test configs

* updated exchange helpers restful router & server

* logPath is now passed to the logger to remove dependency on common package

* updated everything besides exchanges to use new logger

* alphapoint to bitmex done

* updated bitmex bitstamp bittrex btcc and also performance changes to logger

* btcmarkets coinbase coinut exmo gateio wrappers updated

* gateio and gemini logger updated

* hitbtc huobi itbit & kraken updated

* All exchanges updatd

* return correct error for disabled websocket

* don't disconnect client on invalid json

* updated router internal logging

* log.Fatal to t.Error for tests

* Changed from fatal to error failure to set maxprocs

* output ANSI codes for everything but windows for now due to lack of windows support

* added error handling to logger and unit tests

* clear wording on print -> log.print

* added benchmark test

* cleaned up import sections

* Updated logger based on PR requests (added default config options on failure/setting errors)

* ah this should fix travici enc config issue

* Load entire config and clear out logging to hopefully fix travisci issue

* wording & test error handling

* fixed formatting issues based on feedback

* fixed formatting issues based on feedback

* changed CheckDir to use mkdirall instead of mkdir and other changes based on feedback
This commit is contained in:
Andrew
2019-01-08 21:56:22 +11:00
committed by Adrian Gallagher
parent bfbd496c3a
commit d01e7bad72
103 changed files with 1028 additions and 657 deletions

View File

@@ -5,7 +5,6 @@ import (
"errors"
"flag"
"fmt"
"log"
"os"
"path"
"runtime"
@@ -18,6 +17,7 @@ import (
"github.com/thrasher-/gocryptotrader/currency/forexprovider"
"github.com/thrasher-/gocryptotrader/currency/forexprovider/base"
"github.com/thrasher-/gocryptotrader/currency/pair"
log "github.com/thrasher-/gocryptotrader/logger"
"github.com/thrasher-/gocryptotrader/portfolio"
)
@@ -99,6 +99,7 @@ type Config struct {
Name string `json:"name"`
EncryptConfig int `json:"encryptConfig"`
GlobalHTTPTimeout time.Duration `json:"globalHTTPTimeout"`
Logging log.Logging `json:"logging"`
Currency CurrencyConfig `json:"currencyConfig"`
Communications CommunicationsConfig `json:"communications"`
Portfolio portfolio.Base `json:"portfolioAddresses"`
@@ -521,7 +522,7 @@ func (c *Config) CheckPairConsistency(exchName string) error {
if len(pairs) == 0 {
exchCfg.EnabledPairs = pair.RandomPairFromPairs(availPairs).Pair().String()
log.Printf("Exchange %s: No enabled pairs found in available pairs, randomly added %v\n", exchName, exchCfg.EnabledPairs)
log.Debugf("Exchange %s: No enabled pairs found in available pairs, randomly added %v\n", exchName, exchCfg.EnabledPairs)
} else {
exchCfg.EnabledPairs = common.JoinStrings(pair.PairsToStringArray(pairs), ",")
}
@@ -531,7 +532,7 @@ func (c *Config) CheckPairConsistency(exchName string) error {
return err
}
log.Printf("Exchange %s: Removing enabled pair(s) %v from enabled pairs as it isn't an available pair", exchName, pair.PairsToStringArray(pairsRemoved))
log.Debugf("Exchange %s: Removing enabled pair(s) %v from enabled pairs as it isn't an available pair", exchName, pair.PairsToStringArray(pairsRemoved))
return nil
}
@@ -730,11 +731,11 @@ func (c *Config) CheckExchangeConfigValues() error {
if exch.AuthenticatedAPISupport { // non-fatal error
if exch.APIKey == "" || exch.APISecret == "" || exch.APIKey == "Key" || exch.APISecret == "Secret" {
c.Exchanges[i].AuthenticatedAPISupport = false
log.Printf(WarningExchangeAuthAPIDefaultOrEmptyValues, exch.Name)
log.Warn(WarningExchangeAuthAPIDefaultOrEmptyValues, exch.Name)
} else if exch.Name == "ITBIT" || exch.Name == "Bitstamp" || exch.Name == "COINUT" || exch.Name == "CoinbasePro" {
if exch.ClientID == "" || exch.ClientID == "ClientID" {
c.Exchanges[i].AuthenticatedAPISupport = false
log.Printf(WarningExchangeAuthAPIDefaultOrEmptyValues, exch.Name)
log.Warn(WarningExchangeAuthAPIDefaultOrEmptyValues, exch.Name)
}
}
}
@@ -742,18 +743,18 @@ func (c *Config) CheckExchangeConfigValues() error {
lastUpdated := common.UnixTimestampToTime(exch.PairsLastUpdated)
lastUpdated = lastUpdated.AddDate(0, 0, configPairsLastUpdatedWarningThreshold)
if lastUpdated.Unix() <= time.Now().Unix() {
log.Printf(WarningPairsLastUpdatedThresholdExceeded, exch.Name, configPairsLastUpdatedWarningThreshold)
log.Warn(WarningPairsLastUpdatedThresholdExceeded, exch.Name, configPairsLastUpdatedWarningThreshold)
}
}
if exch.HTTPTimeout <= 0 {
log.Printf("Exchange %s HTTP Timeout value not set, defaulting to %v.", exch.Name, configDefaultHTTPTimeout)
log.Warnf("Exchange %s HTTP Timeout value not set, defaulting to %v.", exch.Name, configDefaultHTTPTimeout)
c.Exchanges[i].HTTPTimeout = configDefaultHTTPTimeout
}
err := c.CheckPairConsistency(exch.Name)
if err != nil {
log.Printf("Exchange %s: CheckPairConsistency error: %s", exch.Name, err)
log.Errorf("Exchange %s: CheckPairConsistency error: %s", exch.Name, err)
}
if len(exch.BankAccounts) == 0 {
@@ -853,13 +854,13 @@ func (c *Config) CheckCurrencyConfigValues() error {
for i := range c.Currency.ForexProviders {
if c.Currency.ForexProviders[i].Enabled == true {
if c.Currency.ForexProviders[i].APIKey == "Key" {
log.Printf("WARNING -- %s forex provider API key not set. Please set this in your config.json file", c.Currency.ForexProviders[i].Name)
log.Warnf("%s forex provider API key not set. Please set this in your config.json file", c.Currency.ForexProviders[i].Name)
c.Currency.ForexProviders[i].Enabled = false
c.Currency.ForexProviders[i].PrimaryProvider = false
continue
}
if c.Currency.ForexProviders[i].APIKeyLvl == -1 && c.Currency.ForexProviders[i].Name != "CurrencyConverter" {
log.Printf("WARNING -- %s APIKey Level not set, functions limited. Please set this in your config.json file",
log.Warnf("%s APIKey Level not set, functions limited. Please set this in your config.json file",
c.Currency.ForexProviders[i].Name)
}
count++
@@ -872,7 +873,7 @@ func (c *Config) CheckCurrencyConfigValues() error {
c.Currency.ForexProviders[x].Enabled = true
c.Currency.ForexProviders[x].APIKey = ""
c.Currency.ForexProviders[x].PrimaryProvider = true
log.Printf("WARNING -- No forex providers set, defaulting to free provider CurrencyConverterAPI.")
log.Warn("No forex providers set, defaulting to free provider CurrencyConverterAPI.")
}
}
}
@@ -959,6 +960,44 @@ func (c *Config) RetrieveConfigCurrencyPairs(enabledOnly bool) error {
return nil
}
// CheckLoggerConfig checks to see logger values are present and valid in config
// if not creates a default instance of the logger
func (c *Config) CheckLoggerConfig() (err error) {
m.Lock()
defer m.Unlock()
// check if enabled is nil or level is a blank string
if c.Logging.Enabled == nil || c.Logging.Level == "" {
// Creates a new pointer to bool and sets it as true
t := func(t bool) *bool { return &t }(true)
log.Warn("Missing or invalid config settings using safe defaults")
// Set logger to safe defaults
c.Logging = log.Logging{
Enabled: t,
Level: "DEBUG|INFO|WARN|ERROR|FATAL",
ColourOutput: false,
File: "debug.txt",
Rotate: false,
}
log.Logger = &c.Logging
} else {
log.Logger = &c.Logging
}
if len(c.Logging.File) > 0 {
logPath := path.Join(common.GetDefaultDataDir(runtime.GOOS), "logs")
err = common.CheckDir(logPath, true)
if err != nil {
return
}
log.LogPath = logPath
}
return
}
// GetFilePath returns the desired config file or the default config file name
// based on if the application is being run under test or normal mode.
func GetFilePath(file string) (string, error) {
@@ -996,13 +1035,13 @@ func GetFilePath(file string) (string, error) {
if err != nil {
return "", err
}
log.Printf("Renamed old config file %s to %s", oldDirs[x], newDirs[0])
log.Debugf("Renamed old config file %s to %s", oldDirs[x], newDirs[0])
} else {
err = os.Rename(oldDirs[x], newDirs[1])
if err != nil {
return "", err
}
log.Printf("Renamed old config file %s to %s", oldDirs[x], newDirs[1])
log.Debugf("Renamed old config file %s to %s", oldDirs[x], newDirs[1])
}
}
}
@@ -1086,7 +1125,7 @@ func (c *Config) ReadConfig(configPath string) error {
}
key, err := PromptForConfigKey(IsInitialSetup)
if err != nil {
log.Printf("PromptForConfigKey err: %s", err)
log.Errorf("PromptForConfigKey err: %s", err)
errCounter++
continue
}
@@ -1095,7 +1134,7 @@ func (c *Config) ReadConfig(configPath string) error {
f = append(f, file...)
data, err := DecryptConfigFile(f, key)
if err != nil {
log.Printf("DecryptConfigFile err: %s", err)
log.Errorf("DecryptConfigFile err: %s", err)
errCounter++
continue
}
@@ -1103,7 +1142,7 @@ func (c *Config) ReadConfig(configPath string) error {
err = ConfirmConfigJSON(data, &c)
if err != nil {
if errCounter < configMaxAuthFailres {
log.Printf("Invalid password.")
log.Errorf("Invalid password.")
}
errCounter++
continue
@@ -1164,7 +1203,7 @@ func (c *Config) CheckConfig() error {
if c.Webserver.Enabled {
err = c.CheckWebserverConfigValues()
if err != nil {
log.Print(fmt.Errorf(ErrCheckingConfigValues, err))
log.Errorf(ErrCheckingConfigValues, err)
c.Webserver.Enabled = false
}
}
@@ -1175,7 +1214,7 @@ func (c *Config) CheckConfig() error {
}
if c.GlobalHTTPTimeout <= 0 {
log.Printf("Global HTTP Timeout value not set, defaulting to %v.", configDefaultHTTPTimeout)
log.Warnf("Global HTTP Timeout value not set, defaulting to %v.", configDefaultHTTPTimeout)
c.GlobalHTTPTimeout = configDefaultHTTPTimeout
}

View File

@@ -8,9 +8,9 @@ import (
"errors"
"fmt"
"io"
"log"
"github.com/thrasher-/gocryptotrader/common"
log "github.com/thrasher-/gocryptotrader/logger"
"golang.org/x/crypto/scrypt"
)

View File

@@ -5,6 +5,7 @@ import (
"github.com/thrasher-/gocryptotrader/common"
"github.com/thrasher-/gocryptotrader/currency/pair"
log "github.com/thrasher-/gocryptotrader/logger"
)
func TestGetCurrencyConfig(t *testing.T) {
@@ -905,3 +906,21 @@ func TestUpdateConfig(t *testing.T) {
t.Fatalf("Test failed. Cryptocurrencies should have been repopulated")
}
}
func TestCheckLoggerConfig(t *testing.T) {
c := GetConfig()
err := c.LoadConfig(ConfigTestFile)
if err != nil {
t.Fatal(err)
}
c.Logging = log.Logging{}
err = c.CheckLoggerConfig()
if err != nil {
t.Errorf("Failed to create default logger reason: %v", err)
}
c.LoadConfig(ConfigTestFile)
err = c.CheckLoggerConfig()
if err != nil {
t.Errorf("Failed to create logger with user settings: reason: %v", err)
}
}