Add file logger support (#269)
This commit is contained in:
parent
fffd60d675
commit
0c4603d825
|
@ -7,7 +7,6 @@ import (
|
|||
"runtime"
|
||||
|
||||
"github.com/status-im/status-go/geth/api"
|
||||
"github.com/status-im/status-go/geth/log"
|
||||
"github.com/status-im/status-go/geth/params"
|
||||
"gopkg.in/urfave/cli.v1"
|
||||
)
|
||||
|
@ -87,7 +86,14 @@ var (
|
|||
LogLevelFlag = cli.StringFlag{
|
||||
Name: "log",
|
||||
Usage: `Log level, one of: "ERROR", "WARN", "INFO", "DEBUG", and "TRACE"`,
|
||||
Value: "INFO",
|
||||
Value: "",
|
||||
}
|
||||
|
||||
// LogFileFlag defines a log filename
|
||||
LogFileFlag = cli.StringFlag{
|
||||
Name: "logfile",
|
||||
Usage: `Path to the log file`,
|
||||
Value: "",
|
||||
}
|
||||
)
|
||||
|
||||
|
@ -107,6 +113,7 @@ func init() {
|
|||
DataDirFlag,
|
||||
NetworkIDFlag,
|
||||
LogLevelFlag,
|
||||
LogFileFlag,
|
||||
}
|
||||
app.Before = func(ctx *cli.Context) error {
|
||||
runtime.GOMAXPROCS(runtime.NumCPU())
|
||||
|
@ -151,10 +158,11 @@ func makeNodeConfig(ctx *cli.Context) (*params.NodeConfig, error) {
|
|||
|
||||
nodeConfig.NodeKeyFile = ctx.GlobalString(NodeKeyFileFlag.Name)
|
||||
|
||||
if logLevel := ctx.GlobalString(LogLevelFlag.Name); len(logLevel) > 0 {
|
||||
nodeConfig.LogEnabled = true
|
||||
if logLevel := ctx.GlobalString(LogLevelFlag.Name); logLevel != "" {
|
||||
nodeConfig.LogLevel = logLevel
|
||||
log.SetLevel(logLevel)
|
||||
}
|
||||
if logFile := ctx.GlobalString(LogFileFlag.Name); logFile != "" {
|
||||
nodeConfig.LogFile = logFile
|
||||
}
|
||||
|
||||
return nodeConfig, nil
|
||||
|
|
|
@ -33,7 +33,6 @@ var nodeConfigJSON = `{
|
|||
"DataDir": "` + TestDataDir + `",
|
||||
"HTTPPort": ` + strconv.Itoa(TestConfig.Node.HTTPPort) + `,
|
||||
"WSPort": ` + strconv.Itoa(TestConfig.Node.WSPort) + `,
|
||||
"LogEnabled": true,
|
||||
"LogLevel": "INFO"
|
||||
}`
|
||||
|
||||
|
|
|
@ -43,7 +43,6 @@ func (s *APITestSuite) TestCHTUpdate() {
|
|||
configJSON := `{
|
||||
"NetworkId": ` + strconv.Itoa(params.RopstenNetworkID) + `,
|
||||
"DataDir": "` + tmpDir + `",
|
||||
"LogEnabled": true,
|
||||
"LogLevel": "INFO",
|
||||
"RPCEnabled": true
|
||||
}`
|
||||
|
|
|
@ -2,16 +2,28 @@ package log
|
|||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"strings"
|
||||
|
||||
"github.com/ethereum/go-ethereum/log"
|
||||
)
|
||||
|
||||
// logger is package scope instance of log.Logger
|
||||
var logger = log.New("geth", "StatusIM")
|
||||
// Logger is a wrapper around log.Logger.
|
||||
type Logger struct {
|
||||
log.Logger
|
||||
Level log.Lvl
|
||||
Handler log.Handler
|
||||
}
|
||||
|
||||
// logger is package scope instance of Logger
|
||||
var logger = Logger{
|
||||
Logger: log.New("geth", "StatusIM"),
|
||||
Level: log.LvlError,
|
||||
Handler: log.StreamHandler(os.Stdout, log.TerminalFormat(true)),
|
||||
}
|
||||
|
||||
func init() {
|
||||
SetLevel("INFO")
|
||||
setHandler(logger.Level, logger.Handler)
|
||||
}
|
||||
|
||||
// SetLevel inits status and ethereum-go logging packages,
|
||||
|
@ -20,17 +32,36 @@ func init() {
|
|||
// Our log levels are in form "DEBUG|ERROR|WARN|etc", while
|
||||
// ethereum-go expects names in lower case: "debug|error|warn|etc".
|
||||
func SetLevel(level string) {
|
||||
lvl, err := log.LvlFromString(strings.ToLower(level))
|
||||
if err != nil {
|
||||
fmt.Printf("Incorrect log level: %s, using defaults\n", level)
|
||||
lvl = log.LvlInfo
|
||||
}
|
||||
lvl := levelFromString(level)
|
||||
|
||||
setHandler(lvl, log.StdoutHandler)
|
||||
logger.Level = lvl
|
||||
setHandler(lvl, logger.Handler)
|
||||
}
|
||||
|
||||
// setHandler is a init helper that allows (re)initialization
|
||||
// with different handler. Useful for testing.
|
||||
// SetLogFile configures logger to write output into file.
|
||||
// This call preserves current logging level.
|
||||
func SetLogFile(filename string) error {
|
||||
handler, err := log.FileHandler(filename, log.TerminalFormat(false))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
logger.Handler = handler
|
||||
setHandler(logger.Level, handler)
|
||||
return nil
|
||||
}
|
||||
|
||||
func levelFromString(level string) log.Lvl {
|
||||
lvl, err := log.LvlFromString(strings.ToLower(level))
|
||||
if err != nil {
|
||||
fmt.Fprintf(os.Stderr, "Incorrect log level: %s, using defaults\n", level)
|
||||
lvl = log.LvlInfo
|
||||
}
|
||||
return lvl
|
||||
}
|
||||
|
||||
// setHandler is a helper that allows log (re)initialization
|
||||
// with different level and handler. Useful for testing.
|
||||
func setHandler(lvl log.Lvl, handler log.Handler) {
|
||||
h := log.LvlFilterHandler(lvl, handler)
|
||||
logger.SetHandler(h)
|
||||
|
|
|
@ -2,9 +2,11 @@ package log
|
|||
|
||||
import (
|
||||
"bytes"
|
||||
"io/ioutil"
|
||||
"testing"
|
||||
|
||||
"github.com/ethereum/go-ethereum/log"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
const (
|
||||
|
@ -44,8 +46,28 @@ func TestLogLevels(t *testing.T) {
|
|||
Warn(warn)
|
||||
Error(err)
|
||||
|
||||
if buf.String() != test.out {
|
||||
t.Errorf("Expecting log output to be '%s', got '%s'", test.out, buf.String())
|
||||
}
|
||||
require.Equal(t, test.out, buf.String())
|
||||
}
|
||||
}
|
||||
|
||||
func TestLogFile(t *testing.T) {
|
||||
file, err := ioutil.TempFile("", "statusim_log_test")
|
||||
require.NoError(t, err)
|
||||
|
||||
defer file.Close()
|
||||
|
||||
// setup log
|
||||
SetLevel("INFO")
|
||||
SetLogFile(file.Name())
|
||||
|
||||
// test log output to file
|
||||
Info(info)
|
||||
Debug(debug)
|
||||
|
||||
data, err := ioutil.ReadAll(file)
|
||||
require.NoError(t, err)
|
||||
|
||||
got := string(data)
|
||||
require.Contains(t, got, info)
|
||||
require.NotContains(t, got, debug)
|
||||
}
|
||||
|
|
|
@ -70,6 +70,8 @@ func (m *NodeManager) startNode(config *params.NodeConfig) (<-chan struct{}, err
|
|||
return nil, ErrNodeExists
|
||||
}
|
||||
|
||||
m.initLog(config)
|
||||
|
||||
ethNode, err := MakeNode(config)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
@ -580,3 +582,16 @@ func (m *NodeManager) RPCServer() (*rpc.Server, error) {
|
|||
|
||||
return m.rpcServer, nil
|
||||
}
|
||||
|
||||
// initLog initializes global logger parameters based on
|
||||
// provided node configurations.
|
||||
func (m *NodeManager) initLog(config *params.NodeConfig) {
|
||||
log.SetLevel(config.LogLevel)
|
||||
|
||||
if config.LogFile != "" {
|
||||
err := log.SetLogFile(config.LogFile)
|
||||
if err != nil {
|
||||
fmt.Println("Failed to open log file, using stdout")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -287,9 +287,6 @@ type NodeConfig struct {
|
|||
// handshake phase, counted separately for inbound and outbound connections.
|
||||
MaxPendingPeers int
|
||||
|
||||
// LogToFile specified whether logs should be saved into file
|
||||
LogEnabled bool
|
||||
|
||||
// LogFile is filename where exposed logs get written to
|
||||
LogFile string
|
||||
|
||||
|
|
|
@ -52,10 +52,10 @@ const (
|
|||
DatabaseCache = 16
|
||||
|
||||
// LogFile defines where to write logs to
|
||||
LogFile = "geth.log"
|
||||
LogFile = ""
|
||||
|
||||
// LogLevel defines the minimum log level to report
|
||||
LogLevel = "INFO"
|
||||
LogLevel = "ERROR"
|
||||
|
||||
// LogLevelSuccinct defines the log level when only errors are reported.
|
||||
// Useful when the default INFO level becomes too verbose.
|
||||
|
|
|
@ -18,9 +18,8 @@
|
|||
"TLSEnabled": false,
|
||||
"MaxPeers": 25,
|
||||
"MaxPendingPeers": 0,
|
||||
"LogEnabled": false,
|
||||
"LogFile": "geth.log",
|
||||
"LogLevel": "INFO",
|
||||
"LogFile": "",
|
||||
"LogLevel": "ERROR",
|
||||
"LogToStderr": true,
|
||||
"UpstreamConfig": {
|
||||
"Enabled": false,
|
||||
|
|
|
@ -18,9 +18,8 @@
|
|||
"TLSEnabled": false,
|
||||
"MaxPeers": 25,
|
||||
"MaxPendingPeers": 0,
|
||||
"LogEnabled": false,
|
||||
"LogFile": "geth.log",
|
||||
"LogLevel": "INFO",
|
||||
"LogFile": "",
|
||||
"LogLevel": "ERROR",
|
||||
"LogToStderr": true,
|
||||
"UpstreamConfig": {
|
||||
"Enabled": false,
|
||||
|
|
|
@ -18,9 +18,8 @@
|
|||
"TLSEnabled": false,
|
||||
"MaxPeers": 25,
|
||||
"MaxPendingPeers": 0,
|
||||
"LogEnabled": false,
|
||||
"LogFile": "geth.log",
|
||||
"LogLevel": "INFO",
|
||||
"LogFile": "",
|
||||
"LogLevel": "ERROR",
|
||||
"LogToStderr": true,
|
||||
"UpstreamConfig": {
|
||||
"Enabled": false,
|
||||
|
|
|
@ -11,7 +11,6 @@ import (
|
|||
|
||||
gethcommon "github.com/ethereum/go-ethereum/common"
|
||||
"github.com/status-im/status-go/geth/common"
|
||||
"github.com/status-im/status-go/geth/log"
|
||||
"github.com/status-im/status-go/geth/params"
|
||||
assertions "github.com/stretchr/testify/require"
|
||||
"github.com/stretchr/testify/suite"
|
||||
|
@ -54,8 +53,6 @@ func init() {
|
|||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
log.SetLevel("ERROR")
|
||||
}
|
||||
|
||||
// BaseTestSuite defines a base tests suit which others suites can embedded to
|
||||
|
@ -131,8 +128,7 @@ func MakeTestNodeConfig(networkID int) (*params.NodeConfig, error) {
|
|||
"DataDir": "` + filepath.Join(TestDataDir, TestNetworkNames[networkID]) + `",
|
||||
"HTTPPort": ` + strconv.Itoa(TestConfig.Node.HTTPPort) + `,
|
||||
"WSPort": ` + strconv.Itoa(TestConfig.Node.WSPort) + `,
|
||||
"LogEnabled": true,
|
||||
"LogLevel": "ERROR"
|
||||
"LogLevel": "INFO"
|
||||
}`
|
||||
nodeConfig, err := params.LoadNodeConfig(configJSON)
|
||||
if err != nil {
|
||||
|
|
Loading…
Reference in New Issue